summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore18
-rwxr-xr-xBUILD/SETUP.sh2
-rwxr-xr-xBUILD/compile-alpha-ccc2
-rwxr-xr-xBUILD/compile-alpha-debug2
-rwxr-xr-xBUILD/compile-dist2
-rwxr-xr-xBUILD/compile-pentium-pgcc2
-rwxr-xr-xBUILD/compile-solaris-sparc2
-rwxr-xr-xBUILD/compile-solaris-sparc-debug2
-rwxr-xr-xBUILD/compile-solaris-sparc-purify2
-rwxr-xr-xCMakeLists.txt2
-rw-r--r--INSTALL-WIN-SOURCE289
-rw-r--r--Makefile.am1
-rw-r--r--README33
-rwxr-xr-xclient/CMakeLists.txt1
-rw-r--r--client/Makefile.am5
-rw-r--r--client/client_priv.h2
-rw-r--r--client/mysql.cc61
-rw-r--r--client/mysqlbinlog.cc187
-rw-r--r--client/mysqldump.c118
-rw-r--r--client/mysqlslap.c18
-rw-r--r--client/mysqltest.cc76
-rw-r--r--client/readline.cc2
-rw-r--r--client/sql_string.cc6
-rw-r--r--client/sql_string.h2
-rw-r--r--cmd-line-utils/libedit/chartype.h2
-rw-r--r--cmd-line-utils/libedit/np/unvis.c2
-rw-r--r--cmd-line-utils/libedit/np/vis.c2
-rw-r--r--cmd-line-utils/libedit/sys.h22
-rw-r--r--configure.in3
-rw-r--r--dbug/dbug.c6
-rw-r--r--extra/comp_err.c87
-rw-r--r--include/Makefile.am16
-rw-r--r--include/config-netware.h1
-rw-r--r--include/config-win.h10
-rw-r--r--include/decimal.h12
-rw-r--r--include/heap.h4
-rw-r--r--include/m_ctype.h6
-rw-r--r--include/m_string.h2
-rw-r--r--include/ma_dyncol.h147
-rw-r--r--include/maria.h74
-rw-r--r--include/my_base.h10
-rw-r--r--include/my_bitmap.h4
-rw-r--r--include/my_compare.h26
-rw-r--r--include/my_decimal_limits.h31
-rw-r--r--include/my_dir.h4
-rw-r--r--include/my_global.h49
-rw-r--r--include/my_pthread.h119
-rw-r--r--include/my_sys.h48
-rw-r--r--include/my_time.h63
-rw-r--r--include/my_tree.h10
-rw-r--r--include/myisam.h2
-rw-r--r--include/myisamchk.h5
-rw-r--r--include/mysql.h3
-rw-r--r--include/mysql.h.pp10
-rw-r--r--include/mysql/plugin.h10
-rw-r--r--include/mysql/plugin_auth.h.pp23
-rw-r--r--include/mysql/service_progress_report.h82
-rw-r--r--include/mysql/services.h1
-rw-r--r--include/mysql_com.h17
-rw-r--r--include/queues.h61
-rw-r--r--include/service_versions.h1
-rw-r--r--include/sql_common.h6
-rw-r--r--include/thr_alarm.h6
-rw-r--r--include/thr_lock.h3
-rwxr-xr-xlibmysql/CMakeLists.txt3
-rw-r--r--libmysql/Makefile.shared4
-rw-r--r--libmysql/libmysql.c9
-rw-r--r--libmysqld/CMakeLists.txt11
-rw-r--r--libmysqld/Makefile.am9
-rw-r--r--libservices/CMakeLists.txt3
-rw-r--r--libservices/Makefile.am3
-rw-r--r--libservices/progress_report_service.c (renamed from storage/maria/compat_aliases.h)16
-rw-r--r--mysql-test/Makefile.am6
-rw-r--r--mysql-test/collections/mysql-next-mr-wl2540.push6
-rw-r--r--mysql-test/collections/mysql-trunk.daily7
-rw-r--r--mysql-test/collections/mysql-trunk.weekly2
-rw-r--r--mysql-test/extra/binlog_tests/binlog.test11
-rw-r--r--mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test10
-rw-r--r--mysql-test/extra/rpl_tests/rpl_deadlock.test4
-rw-r--r--mysql-test/extra/rpl_tests/rpl_flsh_tbls.test1
-rw-r--r--mysql-test/extra/rpl_tests/rpl_log.test1
-rw-r--r--mysql-test/extra/rpl_tests/rpl_reset_slave.test3
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_annotate.test156
-rw-r--r--mysql-test/include/binlog_start_pos.inc28
-rw-r--r--mysql-test/include/check_no_concurrent_insert.inc2
-rw-r--r--mysql-test/include/check_shared_row_lock.inc3
-rw-r--r--mysql-test/include/common-tests.inc8
-rw-r--r--mysql-test/include/have_binlog_checksum_off.inc4
-rw-r--r--mysql-test/include/have_example_plugin.inc2
-rw-r--r--mysql-test/include/icp_tests.inc894
-rw-r--r--mysql-test/include/index_merge1.inc11
-rw-r--r--mysql-test/include/index_merge2.inc2
-rw-r--r--mysql-test/include/mix1.inc5
-rw-r--r--mysql-test/include/mrr_tests.inc118
-rw-r--r--mysql-test/include/mtr_warnings.sql12
-rw-r--r--mysql-test/include/ps_conv.inc49
-rw-r--r--mysql-test/include/ps_query.inc1
-rw-r--r--mysql-test/include/show_binlog_events.inc2
-rw-r--r--mysql-test/include/show_binlog_events2.inc2
-rw-r--r--mysql-test/include/subselect_mat_cost.inc152
-rw-r--r--mysql-test/include/type_hrtime.inc128
-rwxr-xr-xmysql-test/include/world.inc5343
-rwxr-xr-xmysql-test/include/world_schema.inc25
-rw-r--r--mysql-test/include/world_schema1.inc18
-rwxr-xr-xmysql-test/lib/v1/mysql-test-run.pl15
-rwxr-xr-xmysql-test/mysql-test-run.pl44
-rw-r--r--mysql-test/r/adddate_454.result10
-rw-r--r--mysql-test/r/alter_table_online.result74
-rw-r--r--mysql-test/r/archive.result11
-rw-r--r--mysql-test/r/archive_gis.result24
-rw-r--r--mysql-test/r/bigint.result4
-rw-r--r--mysql-test/r/case.result7
-rw-r--r--mysql-test/r/cast.result307
-rw-r--r--mysql-test/r/comments.result14
-rw-r--r--mysql-test/r/compare.result2
-rw-r--r--mysql-test/r/compress.result61
-rw-r--r--mysql-test/r/create.result13
-rw-r--r--mysql-test/r/ctype_collate.result12
-rw-r--r--mysql-test/r/ctype_cp932_binlog_stm.result4
-rw-r--r--mysql-test/r/ctype_recoding.result16
-rw-r--r--mysql-test/r/ctype_utf8.result2
-rw-r--r--mysql-test/r/date_formats.result22
-rw-r--r--mysql-test/r/datetime_456.result8
-rw-r--r--mysql-test/r/delete.result8
-rw-r--r--mysql-test/r/derived.result27
-rw-r--r--mysql-test/r/derived_opt.result355
-rw-r--r--mysql-test/r/derived_view.result2160
-rw-r--r--mysql-test/r/distinct.result103
-rw-r--r--mysql-test/r/dyncol.result1337
-rw-r--r--mysql-test/r/error_simulation.result8
-rw-r--r--mysql-test/r/errors.result10
-rw-r--r--mysql-test/r/explain.result78
-rw-r--r--mysql-test/r/flush.result2
-rw-r--r--mysql-test/r/foreign_key.result4
-rw-r--r--mysql-test/r/fulltext.result8
-rw-r--r--mysql-test/r/fulltext_left_join.result14
-rw-r--r--mysql-test/r/fulltext_order_by.result36
-rw-r--r--mysql-test/r/func_compress.result1
-rw-r--r--mysql-test/r/func_concat.result2
-rw-r--r--mysql-test/r/func_default.result2
-rw-r--r--mysql-test/r/func_gconcat.result12
-rw-r--r--mysql-test/r/func_group.result236
-rw-r--r--mysql-test/r/func_group_innodb.result4
-rw-r--r--mysql-test/r/func_if.result13
-rw-r--r--mysql-test/r/func_in.result70
-rw-r--r--mysql-test/r/func_math.result30
-rw-r--r--mysql-test/r/func_op.result3
-rw-r--r--mysql-test/r/func_sapdb.result24
-rw-r--r--mysql-test/r/func_str.result257
-rw-r--r--mysql-test/r/func_test.result2
-rw-r--r--mysql-test/r/func_time.result420
-rw-r--r--mysql-test/r/func_time_hires.result208
-rw-r--r--mysql-test/r/func_timestamp.result4
-rw-r--r--mysql-test/r/gis-precise.result454
-rw-r--r--mysql-test/r/gis-rt-precise.result62
-rw-r--r--mysql-test/r/gis-rtree.result452
-rw-r--r--mysql-test/r/gis.result472
-rw-r--r--mysql-test/r/grant_cache_no_prot.result4
-rw-r--r--mysql-test/r/grant_cache_ps_prot.result4
-rw-r--r--mysql-test/r/greedy_optimizer.result383
-rw-r--r--mysql-test/r/group_by.result116
-rw-r--r--mysql-test/r/group_min_max.result288
-rw-r--r--mysql-test/r/handlersocket.result13
-rw-r--r--mysql-test/r/having.result14
-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.result36
-rw-r--r--mysql-test/r/ignore_db_dirs_basic.result47
-rw-r--r--mysql-test/r/in_datetime_241.result5
-rw-r--r--mysql-test/r/index_intersect.result1046
-rw-r--r--mysql-test/r/index_intersect_innodb.result1045
-rw-r--r--mysql-test/r/index_merge_innodb.result73
-rw-r--r--mysql-test/r/index_merge_myisam.result127
-rw-r--r--mysql-test/r/information_schema.result17
-rw-r--r--mysql-test/r/information_schema_all_engines.result100
-rw-r--r--mysql-test/r/innodb.result12
-rw-r--r--mysql-test/r/innodb_bug878769.result57
-rw-r--r--mysql-test/r/innodb_icp.result855
-rw-r--r--mysql-test/r/innodb_mrr.result771
-rw-r--r--mysql-test/r/innodb_mrr_cpk.result151
-rw-r--r--mysql-test/r/innodb_no_mrricp.result3316
-rw-r--r--mysql-test/r/insert_select.result1
-rw-r--r--mysql-test/r/insert_update.result2
-rw-r--r--mysql-test/r/join.result226
-rw-r--r--mysql-test/r/join_cache.result5639
-rw-r--r--mysql-test/r/join_nested.result185
-rw-r--r--mysql-test/r/join_nested_jcl6.result1972
-rw-r--r--mysql-test/r/join_outer.result261
-rw-r--r--mysql-test/r/join_outer_innodb.result26
-rw-r--r--mysql-test/r/join_outer_jcl6.result1843
-rw-r--r--mysql-test/r/key.result2
-rw-r--r--mysql-test/r/key_cache.result6
-rw-r--r--mysql-test/r/key_diff.result2
-rw-r--r--mysql-test/r/kill.result24
-rw-r--r--mysql-test/r/loaddata.result6
-rw-r--r--mysql-test/r/lock_multi.result1
-rw-r--r--mysql-test/r/lock_multi_bug38499.result4
-rw-r--r--mysql-test/r/log_slow.result6
-rw-r--r--mysql-test/r/log_state.result2
-rw-r--r--mysql-test/r/log_tables.result60
-rw-r--r--[-rwxr-xr-x]mysql-test/r/lowercase_mixed_tmpdir_innodb.result0
-rw-r--r--mysql-test/r/maria_icp.result861
-rw-r--r--mysql-test/r/maria_mrr.result438
-rw-r--r--mysql-test/r/merge.result2
-rw-r--r--mysql-test/r/metadata.result10
-rw-r--r--mysql-test/r/mix2_myisam.result8
-rw-r--r--mysql-test/r/mrr_icp_extra.result892
-rw-r--r--mysql-test/r/multi_update.result62
-rw-r--r--mysql-test/r/myisam-big.result40
-rw-r--r--mysql-test/r/myisam.result44
-rw-r--r--mysql-test/r/myisam_icp.result947
-rw-r--r--mysql-test/r/myisam_icp_notembedded.result19
-rw-r--r--mysql-test/r/myisam_mrr.result637
-rw-r--r--mysql-test/r/mysql.result10
-rw-r--r--mysql-test/r/mysqlbinlog.result27
-rw-r--r--mysql-test/r/mysqldump-max.result57
-rw-r--r--mysql-test/r/mysqldump.result8
-rw-r--r--mysql-test/r/named_pipe.result61
-rw-r--r--mysql-test/r/negation_elimination.result119
-rw-r--r--mysql-test/r/null.result4
-rw-r--r--mysql-test/r/null_key.result45
-rw-r--r--mysql-test/r/old-mode.result3
-rw-r--r--mysql-test/r/optimizer_switch.result102
-rw-r--r--mysql-test/r/order_by.result235
-rw-r--r--mysql-test/r/parser.result4
-rw-r--r--mysql-test/r/parser_precedence.result1
-rw-r--r--mysql-test/r/partition.result24
-rw-r--r--mysql-test/r/partition_error.result12
-rw-r--r--mysql-test/r/partition_pruning.result25
-rw-r--r--mysql-test/r/plugin.result6
-rw-r--r--mysql-test/r/pool_of_threads.result64
-rw-r--r--mysql-test/r/ps.result98
-rw-r--r--mysql-test/r/ps_11bugs.result6
-rw-r--r--mysql-test/r/ps_1general.result4
-rw-r--r--mysql-test/r/ps_2myisam.result412
-rw-r--r--mysql-test/r/ps_3innodb.result412
-rw-r--r--mysql-test/r/ps_4heap.result412
-rw-r--r--mysql-test/r/ps_5merge.result824
-rw-r--r--mysql-test/r/query_cache.result57
-rw-r--r--mysql-test/r/query_cache_28249.result4
-rw-r--r--mysql-test/r/range.result173
-rw-r--r--mysql-test/r/range_mrr_icp.result1958
-rw-r--r--mysql-test/r/range_vs_index_merge.result1763
-rw-r--r--mysql-test/r/range_vs_index_merge_innodb.result1765
-rw-r--r--mysql-test/r/read_only_innodb.result22
-rw-r--r--mysql-test/r/row.result6
-rw-r--r--mysql-test/r/select.result426
-rw-r--r--mysql-test/r/select_debug.result18
-rw-r--r--mysql-test/r/select_jcl6.result5133
-rw-r--r--mysql-test/r/select_pkeycache.result426
-rw-r--r--mysql-test/r/select_safe.result10
-rw-r--r--mysql-test/r/shm.result61
-rw-r--r--mysql-test/r/sp-threads.result10
-rw-r--r--mysql-test/r/sp-vars.result4
-rw-r--r--mysql-test/r/sp.result47
-rw-r--r--mysql-test/r/ssl.result61
-rw-r--r--mysql-test/r/ssl_compress.result61
-rw-r--r--mysql-test/r/status.result102
-rw-r--r--mysql-test/r/status_user.result42
-rw-r--r--mysql-test/r/strict.result87
-rw-r--r--mysql-test/r/subselect.result1236
-rw-r--r--mysql-test/r/subselect2.result67
-rw-r--r--mysql-test/r/subselect3.result588
-rw-r--r--mysql-test/r/subselect3_jcl6.result1510
-rw-r--r--mysql-test/r/subselect4.result2056
-rw-r--r--mysql-test/r/subselect_cache.result3420
-rw-r--r--mysql-test/r/subselect_extra.result480
-rw-r--r--mysql-test/r/subselect_extra_no_semijoin.result484
-rw-r--r--mysql-test/r/subselect_innodb.result96
-rw-r--r--mysql-test/r/subselect_mat.result2285
-rw-r--r--mysql-test/r/subselect_mat_cost.result565
-rw-r--r--mysql-test/r/subselect_mat_cost_bugs.result393
-rw-r--r--mysql-test/r/subselect_no_mat.result6296
-rw-r--r--mysql-test/r/subselect_no_opts.result6288
-rw-r--r--mysql-test/r/subselect_no_scache.result6303
-rw-r--r--mysql-test/r/subselect_no_semijoin.result6289
-rw-r--r--mysql-test/r/subselect_notembedded.result1
-rw-r--r--mysql-test/r/subselect_nulls.result117
-rw-r--r--mysql-test/r/subselect_partial_match.result985
-rw-r--r--mysql-test/r/subselect_sj.result2775
-rw-r--r--mysql-test/r/subselect_sj2.result1101
-rw-r--r--mysql-test/r/subselect_sj2_jcl6.result1211
-rw-r--r--mysql-test/r/subselect_sj2_mat.result1393
-rw-r--r--mysql-test/r/subselect_sj_aria.result59
-rw-r--r--mysql-test/r/subselect_sj_jcl6.result3029
-rw-r--r--mysql-test/r/subselect_sj_mat.result2044
-rw-r--r--mysql-test/r/subselect_sj_nonmerged.result122
-rw-r--r--mysql-test/r/sysdate_is_now.result2
-rw-r--r--mysql-test/r/system_mysql_db.result10
-rw-r--r--mysql-test/r/table_elim.result96
-rw-r--r--mysql-test/r/table_elim_debug.result2
-rw-r--r--mysql-test/r/table_options.result46
-rw-r--r--mysql-test/r/timezone.result7
-rw-r--r--mysql-test/r/timezone4.result2
-rw-r--r--mysql-test/r/trigger.result44
-rw-r--r--mysql-test/r/type_bit.result2
-rw-r--r--mysql-test/r/type_bit_innodb.result2
-rw-r--r--mysql-test/r/type_blob.result58
-rw-r--r--mysql-test/r/type_date.result27
-rw-r--r--mysql-test/r/type_datetime.result90
-rw-r--r--mysql-test/r/type_datetime_hires.result340
-rw-r--r--mysql-test/r/type_decimal.result2
-rw-r--r--mysql-test/r/type_float.result2
-rw-r--r--mysql-test/r/type_newdecimal.result41
-rw-r--r--mysql-test/r/type_time.result35
-rw-r--r--mysql-test/r/type_time_hires.result340
-rw-r--r--mysql-test/r/type_timestamp.result41
-rw-r--r--mysql-test/r/type_timestamp_hires.result280
-rw-r--r--mysql-test/r/type_year.result27
-rw-r--r--mysql-test/r/union.result15
-rw-r--r--mysql-test/r/update.result14
-rw-r--r--mysql-test/r/update_ignore_216.result9
-rw-r--r--mysql-test/r/user_limits-2.result2
-rw-r--r--mysql-test/r/user_limits.result37
-rw-r--r--mysql-test/r/varbinary.result2
-rw-r--r--mysql-test/r/variables-big.result20
-rw-r--r--mysql-test/r/variables.result43
-rw-r--r--mysql-test/r/view.result702
-rw-r--r--mysql-test/r/warnings.result2
-rw-r--r--mysql-test/r/windows.result2
-rw-r--r--mysql-test/r/xa_binlog.result32
-rw-r--r--mysql-test/std_data/t917689.ARZbin0 -> 8687 bytes
-rw-r--r--mysql-test/std_data/words3.dat66
-rw-r--r--mysql-test/suite/binlog/r/binlog_checksum.result23
-rw-r--r--mysql-test/suite/binlog/r/binlog_ioerr.result28
-rw-r--r--mysql-test/suite/binlog/r/binlog_killed.result16
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_annotate.result1219
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_binlog.result612
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_binlog.result512
-rw-r--r--mysql-test/suite/binlog/t/binlog_checksum.test37
-rw-r--r--mysql-test/suite/binlog/t/binlog_incident.test3
-rw-r--r--mysql-test/suite/binlog/t/binlog_ioerr.test30
-rw-r--r--mysql-test/suite/binlog/t/binlog_killed.test46
-rw-r--r--mysql-test/suite/binlog/t/binlog_killed_simulate.test3
-rw-r--r--mysql-test/suite/binlog/t/binlog_mysqlbinlog2.test34
-rw-r--r--mysql-test/suite/binlog/t/binlog_row_annotate-master.opt1
-rw-r--r--mysql-test/suite/binlog/t/binlog_row_annotate.test189
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_row.test2
-rw-r--r--mysql-test/suite/engines/funcs/r/an_calendar.result6
-rw-r--r--mysql-test/suite/engines/funcs/r/datetime_function.result8
-rw-r--r--mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/de_calendar_range.result12
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_2_unique_constraints_duplicate_update.result30
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_duplicate_update.result7
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_error.result4
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_ignore.result4
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_duplicate_update.result7
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_error.result4
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_ignore.result6
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_duplicate_update.result29
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_error.result16
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_ignore.result16
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_duplicate_update.result29
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_error.result16
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_ignore.result24
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_number_pk_constraint_duplicate_update.result29
-rw-r--r--mysql-test/suite/engines/funcs/r/in_number_boundary_error.result12
-rw-r--r--mysql-test/suite/engines/funcs/r/in_number_decimal_boundary_error.result8
-rw-r--r--mysql-test/suite/engines/funcs/r/ld_all_number_string_calendar_types.result672
-rw-r--r--mysql-test/suite/engines/funcs/r/sq_all.result12
-rw-r--r--mysql-test/suite/engines/funcs/r/up_calendar_range.result16
-rw-r--r--mysql-test/suite/engines/funcs/t/se_join_left.test630
-rw-r--r--mysql-test/suite/engines/funcs/t/se_join_left_outer.test420
-rw-r--r--mysql-test/suite/engines/funcs/t/se_join_natural_left.test420
-rw-r--r--mysql-test/suite/engines/funcs/t/se_join_natural_left_outer.test420
-rw-r--r--mysql-test/suite/engines/iuds/r/delete_time.result4
-rw-r--r--mysql-test/suite/engines/iuds/r/insert_decimal.result2
-rw-r--r--mysql-test/suite/engines/iuds/r/insert_number.result178
-rw-r--r--mysql-test/suite/engines/iuds/r/insert_time.result79
-rw-r--r--mysql-test/suite/engines/iuds/r/type_bit_iuds.result176
-rw-r--r--mysql-test/suite/engines/iuds/r/update_delete_calendar.result59
-rw-r--r--mysql-test/suite/engines/iuds/r/update_delete_number.result10
-rw-r--r--mysql-test/suite/engines/iuds/r/update_time.result6
-rw-r--r--mysql-test/suite/funcs_1/datadict/datadict_priv.inc8
-rw-r--r--mysql-test/suite/funcs_1/datadict/processlist_priv.inc2
-rw-r--r--mysql-test/suite/funcs_1/datadict/processlist_val.inc10
-rw-r--r--mysql-test/suite/funcs_1/r/innodb_func_view.result228
-rw-r--r--mysql-test/suite/funcs_1/r/innodb_views.result3
-rw-r--r--mysql-test/suite/funcs_1/r/is_cml_innodb.result22
-rw-r--r--mysql-test/suite/funcs_1/r/is_cml_memory.result14
-rw-r--r--mysql-test/suite/funcs_1/r/is_cml_myisam.result22
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns.result42
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_innodb.result654
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_is.result1113
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_is_embedded.result1113
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_memory.result624
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_myisam.result704
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_myisam_embedded.result704
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_mysql.result442
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result445
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_is_embedded.result460
-rw-r--r--mysql-test/suite/funcs_1/r/memory_func_view.result228
-rw-r--r--mysql-test/suite/funcs_1/r/memory_views.result3
-rw-r--r--mysql-test/suite/funcs_1/r/myisam_func_view.result228
-rw-r--r--mysql-test/suite/funcs_1/r/myisam_views-big.result3
-rw-r--r--mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result250
-rw-r--r--mysql-test/suite/funcs_1/r/processlist_priv_ps.result250
-rw-r--r--mysql-test/suite/funcs_1/r/processlist_val_no_prot.result97
-rw-r--r--mysql-test/suite/funcs_1/r/processlist_val_ps.result97
-rw-r--r--mysql-test/suite/funcs_1/r/storedproc.result14
-rw-r--r--mysql-test/suite/funcs_1/t/storedproc.test2
-rw-r--r--mysql-test/suite/funcs_1/views/views_master.inc7
-rw-r--r--mysql-test/suite/handler/aria.result273
-rw-r--r--mysql-test/suite/handler/handler.inc185
-rw-r--r--mysql-test/suite/handler/heap.result827
-rw-r--r--mysql-test/suite/handler/heap.test88
-rw-r--r--mysql-test/suite/handler/init.inc2
-rw-r--r--mysql-test/suite/handler/innodb.result273
-rw-r--r--mysql-test/suite/handler/interface.result4
-rw-r--r--mysql-test/suite/handler/interface.test6
-rw-r--r--mysql-test/suite/handler/myisam.result273
-rw-r--r--mysql-test/suite/innodb/r/innodb-autoinc-61209.result30
-rw-r--r--mysql-test/suite/innodb/r/innodb-autoinc.result178
-rw-r--r--mysql-test/suite/innodb/r/innodb.result6
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug54044.result1
-rw-r--r--mysql-test/suite/innodb/r/innodb_gis.result24
-rw-r--r--mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result6
-rw-r--r--mysql-test/suite/innodb/r/innodb_mysql.result147
-rw-r--r--mysql-test/suite/innodb/t/innodb-autoinc-61209.test55
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug51920.test2
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug54044.test7
-rw-r--r--mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1.test6
-rw-r--r--mysql-test/suite/innodb/t/innodb_mysql.test96
-rw-r--r--mysql-test/suite/innodb_plugin/r/binlog_consistent.result99
-rw-r--r--mysql-test/suite/innodb_plugin/r/group_commit.result65
-rw-r--r--mysql-test/suite/innodb_plugin/r/group_commit_binlog_pos.result35
-rw-r--r--mysql-test/suite/innodb_plugin/r/group_commit_binlog_pos_no_optimize_thread.result36
-rw-r--r--mysql-test/suite/innodb_plugin/r/group_commit_crash.result125
-rw-r--r--mysql-test/suite/innodb_plugin/r/group_commit_crash_no_optimize_thread.result125
-rw-r--r--mysql-test/suite/innodb_plugin/r/group_commit_no_optimize_thread.result65
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb-autoinc.result178
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb.result2
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb_bug54044.result1
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb_gis.result24
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result8
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb_mysql.result30
-rw-r--r--mysql-test/suite/innodb_plugin/t/binlog_consistent.test88
-rw-r--r--mysql-test/suite/innodb_plugin/t/group_commit.test117
-rw-r--r--mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos-master.opt1
-rw-r--r--mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos.test89
-rw-r--r--mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos_no_optimize_thread-master.opt1
-rw-r--r--mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos_no_optimize_thread.test90
-rw-r--r--mysql-test/suite/innodb_plugin/t/group_commit_crash-master.opt1
-rw-r--r--mysql-test/suite/innodb_plugin/t/group_commit_crash.test82
-rw-r--r--mysql-test/suite/innodb_plugin/t/group_commit_crash_no_optimize_thread-master.opt1
-rw-r--r--mysql-test/suite/innodb_plugin/t/group_commit_crash_no_optimize_thread.test82
-rw-r--r--mysql-test/suite/innodb_plugin/t/group_commit_no_optimize_thread-master.opt1
-rw-r--r--mysql-test/suite/innodb_plugin/t/group_commit_no_optimize_thread.test117
-rw-r--r--mysql-test/suite/innodb_plugin/t/innodb.test3
-rw-r--r--mysql-test/suite/innodb_plugin/t/innodb_bug54044.test7
-rw-r--r--mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1.test8
-rw-r--r--mysql-test/suite/maria/r/compat_aliases.result59
-rw-r--r--mysql-test/suite/maria/r/maria-autozerofill.result2
-rw-r--r--mysql-test/suite/maria/r/maria-connect.result8
-rw-r--r--mysql-test/suite/maria/r/maria-gis-recovery.result64
-rw-r--r--mysql-test/suite/maria/r/maria-gis-rtree-dynamic.result4
-rw-r--r--mysql-test/suite/maria/r/maria-gis-rtree-trans.result4
-rw-r--r--mysql-test/suite/maria/r/maria-gis-rtree.result4
-rw-r--r--mysql-test/suite/maria/r/maria-recover.result2
-rw-r--r--mysql-test/suite/maria/r/maria.result50
-rw-r--r--mysql-test/suite/maria/r/maria3.result2
-rw-r--r--mysql-test/suite/maria/r/ps_maria.result412
-rw-r--r--mysql-test/suite/maria/t/compat_aliases.test59
-rw-r--r--mysql-test/suite/maria/t/maria-autozerofill.test2
-rw-r--r--mysql-test/suite/maria/t/maria-connect.test7
-rw-r--r--mysql-test/suite/maria/t/maria-gis-recovery-master.opt1
-rw-r--r--mysql-test/suite/maria/t/maria-gis-recovery.test64
-rw-r--r--mysql-test/suite/maria/t/maria-recover.test4
-rw-r--r--mysql-test/suite/maria/t/maria.test13
-rw-r--r--mysql-test/suite/maria/t/maria3.test2
-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.result1110
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1.result1110
-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.result51
-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.test489
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra1.test488
-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.test60
-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.def6
-rw-r--r--mysql-test/suite/parts/inc/part_supported_sql_funcs_delete.inc4
-rw-r--r--mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc5
-rw-r--r--mysql-test/suite/parts/inc/partition_supported_sql_funcs.inc4
-rw-r--r--mysql-test/suite/parts/r/part_supported_sql_func_innodb.result1055
-rw-r--r--mysql-test/suite/parts/r/part_supported_sql_func_myisam.result1055
-rw-r--r--mysql-test/suite/parts/r/partition_bit_innodb.result2
-rw-r--r--mysql-test/suite/parts/r/partition_bit_myisam.result2
-rw-r--r--mysql-test/suite/parts/r/partition_repair_myisam.result3
-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/parts/r/rpl_partition.result6
-rw-r--r--mysql-test/suite/parts/t/part_supported_sql_func_innodb.test4
-rw-r--r--mysql-test/suite/parts/t/partition_repair_myisam.test3
-rw-r--r--mysql-test/suite/parts/t/rpl_partition.test6
-rw-r--r--mysql-test/suite/pbxt/r/cast.result12
-rw-r--r--mysql-test/suite/pbxt/r/date_formats.result22
-rw-r--r--mysql-test/suite/pbxt/r/derived.result28
-rw-r--r--mysql-test/suite/pbxt/r/distinct.result19
-rw-r--r--mysql-test/suite/pbxt/r/errors.result2
-rw-r--r--mysql-test/suite/pbxt/r/explain.result2
-rw-r--r--mysql-test/suite/pbxt/r/func_group.result9
-rw-r--r--mysql-test/suite/pbxt/r/func_op.result3
-rw-r--r--mysql-test/suite/pbxt/r/func_sapdb.result20
-rw-r--r--mysql-test/suite/pbxt/r/func_str.result250
-rw-r--r--mysql-test/suite/pbxt/r/func_timestamp.result4
-rw-r--r--mysql-test/suite/pbxt/r/grant_cache.result4
-rw-r--r--mysql-test/suite/pbxt/r/greedy_optimizer.result383
-rw-r--r--mysql-test/suite/pbxt/r/group_by.result9
-rw-r--r--mysql-test/suite/pbxt/r/group_min_max.result19
-rw-r--r--mysql-test/suite/pbxt/r/join.result17
-rw-r--r--mysql-test/suite/pbxt/r/join_nested.result94
-rw-r--r--mysql-test/suite/pbxt/r/join_outer.result17
-rw-r--r--mysql-test/suite/pbxt/r/key_cache.result2
-rw-r--r--mysql-test/suite/pbxt/r/key_diff.result16
-rw-r--r--mysql-test/suite/pbxt/r/lock_multi.result2
-rw-r--r--mysql-test/suite/pbxt/r/metadata.result2
-rw-r--r--mysql-test/suite/pbxt/r/negation_elimination.result8
-rw-r--r--mysql-test/suite/pbxt/r/null_key.result33
-rw-r--r--mysql-test/suite/pbxt/r/order_by.result4
-rw-r--r--mysql-test/suite/pbxt/r/partition_pruning.result8
-rw-r--r--mysql-test/suite/pbxt/r/pbxt_locking.result12
-rw-r--r--mysql-test/suite/pbxt/r/pbxt_xa_binlog.result32
-rw-r--r--mysql-test/suite/pbxt/r/ps_11bugs.result6
-rw-r--r--mysql-test/suite/pbxt/r/ps_1general.result4
-rw-r--r--mysql-test/suite/pbxt/r/range.result44
-rw-r--r--mysql-test/suite/pbxt/r/read_only.result4
-rw-r--r--mysql-test/suite/pbxt/r/select.result61
-rw-r--r--mysql-test/suite/pbxt/r/select_found.result2
-rw-r--r--mysql-test/suite/pbxt/r/select_safe.result8
-rw-r--r--mysql-test/suite/pbxt/r/skip_name_resolve.result6
-rw-r--r--mysql-test/suite/pbxt/r/status.result10
-rw-r--r--mysql-test/suite/pbxt/r/subselect.result227
-rw-r--r--mysql-test/suite/pbxt/r/type_bit.result2
-rw-r--r--mysql-test/suite/pbxt/r/type_datetime.result32
-rw-r--r--mysql-test/suite/pbxt/r/type_decimal.result2
-rw-r--r--mysql-test/suite/pbxt/r/type_float.result2
-rw-r--r--mysql-test/suite/pbxt/r/type_newdecimal.result22
-rw-r--r--mysql-test/suite/pbxt/r/type_time.result12
-rw-r--r--mysql-test/suite/pbxt/r/type_timestamp.result28
-rw-r--r--mysql-test/suite/pbxt/r/union.result9
-rw-r--r--mysql-test/suite/pbxt/r/update.result6
-rw-r--r--mysql-test/suite/pbxt/t/derived.test6
-rw-r--r--mysql-test/suite/pbxt/t/distinct.test6
-rw-r--r--mysql-test/suite/pbxt/t/func_group.test3
-rw-r--r--mysql-test/suite/pbxt/t/func_op.test3
-rw-r--r--mysql-test/suite/pbxt/t/grant_cache.test13
-rw-r--r--mysql-test/suite/pbxt/t/greedy_optimizer.test5
-rw-r--r--mysql-test/suite/pbxt/t/group_by.test3
-rw-r--r--mysql-test/suite/pbxt/t/join.test7
-rw-r--r--mysql-test/suite/pbxt/t/join_nested.test11
-rw-r--r--mysql-test/suite/pbxt/t/join_outer.test5
-rw-r--r--mysql-test/suite/pbxt/t/key_diff.test14
-rw-r--r--mysql-test/suite/pbxt/t/lock_multi.test16
-rw-r--r--mysql-test/suite/pbxt/t/mysqlshow.test1
-rw-r--r--mysql-test/suite/pbxt/t/pbxt_xa_binlog.test32
-rw-r--r--mysql-test/suite/pbxt/t/select.test6
-rw-r--r--mysql-test/suite/pbxt/t/subselect.test41
-rw-r--r--mysql-test/suite/pbxt/t/type_timestamp.test13
-rw-r--r--mysql-test/suite/pbxt/t/union.test3
-rw-r--r--mysql-test/suite/rpl/extension/README.checksum23
-rw-r--r--mysql-test/suite/rpl/extension/checksum.pl164
-rw-r--r--mysql-test/suite/rpl/include/hrtime.inc27
-rw-r--r--mysql-test/suite/rpl/r/rpl_change_master.result1
-rw-r--r--mysql-test/suite/rpl/r/rpl_checksum.result135
-rw-r--r--mysql-test/suite/rpl/r/rpl_checksum_cache.result119
-rw-r--r--mysql-test/suite/rpl/r/rpl_corruption.result51
-rw-r--r--mysql-test/suite/rpl/r/rpl_deadlock_innodb.result4
-rw-r--r--mysql-test/suite/rpl/r/rpl_hrtime.result67
-rw-r--r--mysql-test/suite/rpl/r/rpl_hrtime_row.result28
-rw-r--r--mysql-test/suite/rpl/r/rpl_innodb_bug28430.result6
-rw-r--r--mysql-test/suite/rpl/r/rpl_rewrt_db.result6
-rw-r--r--mysql-test/suite/rpl/r/rpl_rotate_logs.result4
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_annotate_do.result141
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_annotate_dont.result123
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_conflicts.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_index_choice.result140
-rw-r--r--mysql-test/suite/rpl/r/rpl_stm_000001.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_switch_stm_row_mixed.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_variables_stm.result4
-rw-r--r--mysql-test/suite/rpl/t/rpl_change_master.test1
-rw-r--r--mysql-test/suite/rpl/t/rpl_checksum-master.opt1
-rw-r--r--mysql-test/suite/rpl/t/rpl_checksum.test264
-rw-r--r--mysql-test/suite/rpl/t/rpl_checksum_cache.test255
-rw-r--r--mysql-test/suite/rpl/t/rpl_corruption-master.opt1
-rw-r--r--mysql-test/suite/rpl/t/rpl_corruption-slave.opt1
-rw-r--r--mysql-test/suite/rpl/t/rpl_corruption.test165
-rw-r--r--mysql-test/suite/rpl/t/rpl_hrtime.test7
-rw-r--r--mysql-test/suite/rpl/t/rpl_hrtime_row.test3
-rw-r--r--mysql-test/suite/rpl/t/rpl_innodb_bug28430.test6
-rw-r--r--mysql-test/suite/rpl/t/rpl_known_bugs_detection.test3
-rw-r--r--mysql-test/suite/rpl/t/rpl_rotate_logs.test5
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_annotate_do-slave.opt1
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_annotate_do.test16
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_annotate_dont-slave.opt1
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_annotate_dont.test9
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test1
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_flsh_tbls.test3
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_index_choice.test243
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test18
-rw-r--r--mysql-test/suite/rpl/t/rpl_start_stop_slave.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_stm_000001.test7
-rw-r--r--mysql-test/suite/rpl/t/rpl_stm_flsh_tbls.test3
-rw-r--r--mysql-test/suite/rpl_ndb/t/rpl_ndb_multi.test2
-rw-r--r--mysql-test/suite/sys_vars/r/binlog_checksum_basic.result14
-rw-r--r--mysql-test/suite/sys_vars/r/concurrent_insert_func.result4
-rw-r--r--mysql-test/suite/sys_vars/r/master_verify_checksum_basic.result11
-rw-r--r--mysql-test/suite/sys_vars/r/slave_sql_verify_checksum_basic.result11
-rw-r--r--mysql-test/suite/sys_vars/t/binlog_checksum_basic.test25
-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/master_verify_checksum_basic.test19
-rw-r--r--mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test2
-rw-r--r--mysql-test/suite/sys_vars/t/slave_sql_verify_checksum_basic.test18
-rw-r--r--mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test8
-rw-r--r--mysql-test/suite/vcol/inc/vcol_select.inc6
-rw-r--r--mysql-test/suite/vcol/inc/vcol_view.inc10
-rw-r--r--mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result2
-rw-r--r--mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result2
-rw-r--r--mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result20
-rw-r--r--mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result20
-rw-r--r--mysql-test/suite/vcol/r/vcol_keys_innodb.result8
-rw-r--r--mysql-test/suite/vcol/r/vcol_keys_myisam.result8
-rw-r--r--mysql-test/suite/vcol/r/vcol_misc.result116
-rw-r--r--mysql-test/suite/vcol/r/vcol_select_innodb.result25
-rw-r--r--mysql-test/suite/vcol/r/vcol_select_myisam.result39
-rw-r--r--mysql-test/suite/vcol/r/vcol_supported_sql_funcs_innodb.result12
-rw-r--r--mysql-test/suite/vcol/r/vcol_supported_sql_funcs_myisam.result12
-rw-r--r--mysql-test/suite/vcol/r/vcol_view_innodb.result11
-rw-r--r--mysql-test/suite/vcol/r/vcol_view_myisam.result11
-rw-r--r--mysql-test/suite/vcol/t/vcol_misc.test69
-rw-r--r--mysql-test/t/adddate_454.test9
-rw-r--r--mysql-test/t/alter_table_online.test108
-rw-r--r--mysql-test/t/archive.test11
-rw-r--r--mysql-test/t/case.test12
-rw-r--r--mysql-test/t/cast.test133
-rw-r--r--mysql-test/t/comments.test11
-rw-r--r--mysql-test/t/ctype_cp1251.test1
-rw-r--r--mysql-test/t/ctype_cp932_binlog_stm.test4
-rw-r--r--mysql-test/t/ctype_recoding.test18
-rw-r--r--mysql-test/t/date_formats.test6
-rw-r--r--mysql-test/t/datetime_456.test8
-rw-r--r--mysql-test/t/derived.test6
-rw-r--r--mysql-test/t/derived_opt.test276
-rw-r--r--mysql-test/t/derived_view.test1520
-rw-r--r--mysql-test/t/distinct.test68
-rw-r--r--mysql-test/t/dyncol.test548
-rw-r--r--mysql-test/t/error_simulation.test8
-rw-r--r--mysql-test/t/errors.test9
-rw-r--r--mysql-test/t/explain.test38
-rw-r--r--mysql-test/t/flush.test2
-rw-r--r--mysql-test/t/flush_read_lock_kill.test2
-rw-r--r--mysql-test/t/fulltext.test2
-rw-r--r--mysql-test/t/fulltext_left_join.test13
-rw-r--r--mysql-test/t/fulltext_order_by.test4
-rw-r--r--mysql-test/t/func_group.test152
-rw-r--r--mysql-test/t/func_if.test3
-rw-r--r--mysql-test/t/func_in.test19
-rw-r--r--mysql-test/t/func_op.test3
-rw-r--r--mysql-test/t/func_sapdb.test4
-rw-r--r--mysql-test/t/func_str.test6
-rw-r--r--mysql-test/t/func_time.test158
-rw-r--r--mysql-test/t/func_time_hires.test108
-rw-r--r--mysql-test/t/gis-precise.test327
-rw-r--r--mysql-test/t/gis-rt-precise.test64
-rw-r--r--mysql-test/t/gis-rtree.test12
-rw-r--r--mysql-test/t/gis.test569
-rw-r--r--mysql-test/t/greedy_optimizer.test5
-rw-r--r--mysql-test/t/group_by.test89
-rw-r--r--mysql-test/t/group_min_max.test115
-rw-r--r--mysql-test/t/handlersocket.test11
-rw-r--r--mysql-test/t/having.test10
-rw-r--r--mysql-test/t/heap_btree.test16
-rw-r--r--mysql-test/t/heap_hash.test19
-rw-r--r--mysql-test/t/ignore_db_dirs_basic-master.opt11
-rw-r--r--mysql-test/t/ignore_db_dirs_basic.test38
-rw-r--r--mysql-test/t/in_datetime_241.test9
-rw-r--r--mysql-test/t/index_intersect.test453
-rw-r--r--mysql-test/t/index_intersect_innodb.test7
-rw-r--r--mysql-test/t/index_merge_innodb.test76
-rw-r--r--mysql-test/t/index_merge_myisam.test106
-rw-r--r--mysql-test/t/information_schema.test3
-rw-r--r--mysql-test/t/information_schema_all_engines.test7
-rw-r--r--mysql-test/t/innodb.test8
-rw-r--r--mysql-test/t/innodb_bug878769.test56
-rw-r--r--mysql-test/t/innodb_icp.test17
-rw-r--r--mysql-test/t/innodb_mrr.test462
-rw-r--r--mysql-test/t/innodb_mrr_cpk.test141
-rw-r--r--mysql-test/t/innodb_no_mrricp.test10
-rw-r--r--mysql-test/t/insert_notembedded.test2
-rw-r--r--mysql-test/t/join.test158
-rw-r--r--mysql-test/t/join_cache.test3640
-rw-r--r--mysql-test/t/join_nested.test71
-rw-r--r--mysql-test/t/join_nested_jcl6.test111
-rw-r--r--mysql-test/t/join_outer.test179
-rw-r--r--mysql-test/t/join_outer_jcl6.test24
-rw-r--r--mysql-test/t/kill.test32
-rw-r--r--mysql-test/t/lock_multi.test23
-rw-r--r--mysql-test/t/lock_multi_bug38499.test12
-rw-r--r--mysql-test/t/log_tables.test20
-rw-r--r--mysql-test/t/maria_icp.test17
-rw-r--r--mysql-test/t/maria_mrr.test213
-rw-r--r--mysql-test/t/merge-big.test2
-rw-r--r--mysql-test/t/metadata.test8
-rw-r--r--mysql-test/t/mrr_icp_extra.test239
-rw-r--r--mysql-test/t/multi_update.test58
-rw-r--r--mysql-test/t/myisam-big.test64
-rw-r--r--mysql-test/t/myisam.test8
-rw-r--r--mysql-test/t/myisam_icp.test286
-rw-r--r--mysql-test/t/myisam_icp_notembedded.test139
-rw-r--r--mysql-test/t/myisam_mrr.test325
-rw-r--r--mysql-test/t/mysql.test9
-rw-r--r--mysql-test/t/mysqlbinlog-master.opt1
-rw-r--r--mysql-test/t/mysqlbinlog.test99
-rw-r--r--mysql-test/t/mysqldump-max.test82
-rw-r--r--mysql-test/t/negation_elimination.test29
-rw-r--r--mysql-test/t/null_key.test13
-rw-r--r--mysql-test/t/old-mode.test10
-rw-r--r--mysql-test/t/optimizer_switch.test118
-rw-r--r--mysql-test/t/order_by.test89
-rw-r--r--mysql-test/t/parser_precedence.test2
-rw-r--r--mysql-test/t/partition.test19
-rw-r--r--mysql-test/t/partition_pruning.test3
-rw-r--r--mysql-test/t/pool_of_threads.test4
-rw-r--r--mysql-test/t/ps.test61
-rw-r--r--mysql-test/t/query_cache.test33
-rw-r--r--mysql-test/t/query_cache_28249.test4
-rw-r--r--mysql-test/t/range.test68
-rw-r--r--mysql-test/t/range_mrr_icp.test7
-rwxr-xr-xmysql-test/t/range_vs_index_merge.test1208
-rwxr-xr-xmysql-test/t/range_vs_index_merge_innodb.test7
-rw-r--r--mysql-test/t/read_only_innodb.test29
-rw-r--r--mysql-test/t/select.test176
-rw-r--r--mysql-test/t/select_debug.test19
-rw-r--r--mysql-test/t/select_jcl6.test24
-rw-r--r--mysql-test/t/select_safe.test2
-rw-r--r--mysql-test/t/sp.test40
-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.test29
-rw-r--r--mysql-test/t/status_user.test20
-rw-r--r--mysql-test/t/strict.test2
-rw-r--r--mysql-test/t/subselect.test1292
-rw-r--r--mysql-test/t/subselect2.test56
-rw-r--r--mysql-test/t/subselect3.test478
-rw-r--r--mysql-test/t/subselect3_jcl6.test22
-rw-r--r--mysql-test/t/subselect4.test1697
-rw-r--r--mysql-test/t/subselect_cache.test1707
-rw-r--r--mysql-test/t/subselect_extra.test395
-rw-r--r--mysql-test/t/subselect_extra_no_semijoin.test9
-rw-r--r--mysql-test/t/subselect_innodb.test89
-rw-r--r--mysql-test/t/subselect_mat.test256
-rw-r--r--mysql-test/t/subselect_mat_cost-master.opt1
-rw-r--r--mysql-test/t/subselect_mat_cost.test429
-rw-r--r--mysql-test/t/subselect_mat_cost_bugs.test426
-rw-r--r--mysql-test/t/subselect_no_mat.test17
-rw-r--r--mysql-test/t/subselect_no_opts.test14
-rw-r--r--mysql-test/t/subselect_no_scache.test15
-rw-r--r--mysql-test/t/subselect_no_semijoin.test12
-rw-r--r--mysql-test/t/subselect_notembedded.test5
-rw-r--r--mysql-test/t/subselect_nulls.test99
-rw-r--r--mysql-test/t/subselect_partial_match.test803
-rw-r--r--mysql-test/t/subselect_sj.test2486
-rw-r--r--mysql-test/t/subselect_sj2.test1233
-rw-r--r--mysql-test/t/subselect_sj2_jcl6.test113
-rw-r--r--mysql-test/t/subselect_sj2_mat.test265
-rw-r--r--mysql-test/t/subselect_sj_aria.test76
-rw-r--r--mysql-test/t/subselect_sj_jcl6.test216
-rw-r--r--mysql-test/t/subselect_sj_mat.test1683
-rw-r--r--mysql-test/t/subselect_sj_nonmerged.test121
-rw-r--r--mysql-test/t/system_mysql_db_fix40123.test4
-rw-r--r--mysql-test/t/system_mysql_db_fix50030.test6
-rw-r--r--mysql-test/t/system_mysql_db_fix50117.test6
-rw-r--r--mysql-test/t/table_elim.test7
-rw-r--r--mysql-test/t/table_elim_debug.test3
-rw-r--r--mysql-test/t/timezone.test2
-rw-r--r--mysql-test/t/trigger.test40
-rw-r--r--mysql-test/t/trigger_notembedded.test2
-rw-r--r--mysql-test/t/type_blob.test12
-rw-r--r--mysql-test/t/type_date.test8
-rw-r--r--mysql-test/t/type_datetime.test19
-rw-r--r--mysql-test/t/type_datetime_hires.test71
-rw-r--r--mysql-test/t/type_time.test23
-rw-r--r--mysql-test/t/type_time_hires.test12
-rw-r--r--mysql-test/t/type_timestamp.test20
-rw-r--r--mysql-test/t/type_timestamp_hires.test16
-rw-r--r--mysql-test/t/type_year.test18
-rw-r--r--mysql-test/t/union.test4
-rw-r--r--mysql-test/t/update_ignore_216.test13
-rw-r--r--mysql-test/t/user_limits-2.test11
-rw-r--r--mysql-test/t/user_limits-master.opt1
-rw-r--r--mysql-test/t/user_limits.test41
-rw-r--r--mysql-test/t/variables-big.test4
-rw-r--r--mysql-test/t/variables-master.opt1
-rw-r--r--mysql-test/t/variables.test42
-rw-r--r--mysql-test/t/view.test573
-rw-r--r--[-rwxr-xr-x]mysql-test/t/windows.test0
-rw-r--r--mysql-test/t/xa_binlog.test32
-rw-r--r--mysql-test/valgrind.supp36
-rw-r--r--mysys/CMakeLists.txt4
-rw-r--r--mysys/Makefile.am4
-rw-r--r--mysys/charset.c3
-rw-r--r--mysys/default_modify.c8
-rw-r--r--mysys/hash.c19
-rw-r--r--mysys/ma_dyncol.c2111
-rw-r--r--mysys/mf_getdate.c2
-rw-r--r--mysys/mf_iocache.c3
-rw-r--r--mysys/my_bitmap.c90
-rw-r--r--mysys/my_chsize.c19
-rw-r--r--mysys/my_compare.c2
-rw-r--r--mysys/my_create.c15
-rw-r--r--mysys/my_dup.c6
-rw-r--r--mysys/my_file.c1
-rw-r--r--mysys/my_fopen.c48
-rw-r--r--mysys/my_fstream.c17
-rw-r--r--mysys/my_getsystime.c235
-rw-r--r--mysys/my_handler_errors.h4
-rw-r--r--mysys/my_init.c53
-rw-r--r--mysys/my_lib.c26
-rw-r--r--mysys/my_lock.c137
-rw-r--r--mysys/my_mmap.c6
-rw-r--r--mysys/my_open.c228
-rw-r--r--mysys/my_pread.c65
-rw-r--r--mysys/my_quick.c22
-rw-r--r--mysys/my_read.c7
-rw-r--r--mysys/my_seek.c17
-rw-r--r--mysys/my_static.c7
-rw-r--r--mysys/my_static.h2
-rw-r--r--mysys/my_sync.c20
-rw-r--r--mysys/my_uuid.c12
-rw-r--r--mysys/my_wincond.c220
-rw-r--r--mysys/my_winerr.c123
-rw-r--r--mysys/my_winfile.c681
-rw-r--r--mysys/my_winthread.c15
-rw-r--r--mysys/my_write.c41
-rw-r--r--mysys/mysys_priv.h24
-rw-r--r--mysys/queues.c635
-rw-r--r--mysys/string.c12
-rw-r--r--mysys/thr_alarm.c203
-rw-r--r--mysys/thr_lock.c59
-rw-r--r--mysys/thr_rwlock.c160
-rw-r--r--mysys/tree.c5
-rw-r--r--mysys/waiting_threads.c34
-rw-r--r--netware/Makefile.am1
-rw-r--r--netware/my_manage.c10
-rw-r--r--netware/mysql_install_db.c14
-rw-r--r--netware/mysql_tzinfo_to_sql.def11
-rw-r--r--netware/mysqld_safe.c778
-rw-r--r--plugin/auth_pam/auth_pam.c4
-rw-r--r--plugin/feedback/sender_thread.cc2
-rw-r--r--plugin/handler_socket/AUTHORS22
-rw-r--r--plugin/handler_socket/ChangeLog19
-rw-r--r--plugin/handler_socket/Makefile.am88
-rw-r--r--plugin/handler_socket/README82
-rwxr-xr-xplugin/handler_socket/autogen.sh117
-rw-r--r--plugin/handler_socket/client/Makefile.am24
-rw-r--r--plugin/handler_socket/client/hsclient.cpp88
-rw-r--r--plugin/handler_socket/client/hslongrun.cpp1041
-rwxr-xr-xplugin/handler_socket/client/hspool_test.pl224
-rw-r--r--plugin/handler_socket/client/hstest.cpp1532
-rwxr-xr-xplugin/handler_socket/client/hstest.pl228
-rwxr-xr-xplugin/handler_socket/client/hstest_hs.sh4
-rwxr-xr-xplugin/handler_socket/client/hstest_hs_more50.sh4
-rwxr-xr-xplugin/handler_socket/client/hstest_md.sh7
-rwxr-xr-xplugin/handler_socket/client/hstest_my.sh3
-rwxr-xr-xplugin/handler_socket/client/hstest_my_more50.sh3
-rw-r--r--plugin/handler_socket/configure.ac144
-rw-r--r--plugin/handler_socket/docs-en/about-handlersocket.en.txt72
-rw-r--r--plugin/handler_socket/docs-en/configuration-options.en.txt99
-rw-r--r--plugin/handler_socket/docs-en/installation.en.txt91
-rw-r--r--plugin/handler_socket/docs-en/perl-client.en.txt126
-rw-r--r--plugin/handler_socket/docs-en/protocol.en.txt198
-rw-r--r--plugin/handler_socket/docs-ja/about-handlersocket.ja.txt51
-rw-r--r--plugin/handler_socket/docs-ja/installation.ja.txt87
-rw-r--r--plugin/handler_socket/docs-ja/perl-client.ja.txt118
-rw-r--r--plugin/handler_socket/docs-ja/protocol.ja.txt94
-rw-r--r--plugin/handler_socket/handlersocket/COPYRIGHT.txt27
-rw-r--r--plugin/handler_socket/handlersocket/Makefile.am8
-rw-r--r--plugin/handler_socket/handlersocket/Makefile.plain.template31
-rw-r--r--plugin/handler_socket/handlersocket/database.cpp1187
-rw-r--r--plugin/handler_socket/handlersocket/database.hpp142
-rw-r--r--plugin/handler_socket/handlersocket/handlersocket.cpp216
-rw-r--r--plugin/handler_socket/handlersocket/handlersocket.spec.template29
-rw-r--r--plugin/handler_socket/handlersocket/hstcpsvr.cpp149
-rw-r--r--plugin/handler_socket/handlersocket/hstcpsvr.hpp58
-rw-r--r--plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp959
-rw-r--r--plugin/handler_socket/handlersocket/hstcpsvr_worker.hpp35
-rw-r--r--plugin/handler_socket/handlersocket/mysql_incl.hpp50
-rw-r--r--plugin/handler_socket/libhsclient/COPYRIGHT.txt27
-rw-r--r--plugin/handler_socket/libhsclient/Makefile.am12
-rw-r--r--plugin/handler_socket/libhsclient/Makefile.plain27
-rw-r--r--plugin/handler_socket/libhsclient/allocator.hpp64
-rw-r--r--plugin/handler_socket/libhsclient/auto_addrinfo.hpp52
-rw-r--r--plugin/handler_socket/libhsclient/auto_file.hpp64
-rw-r--r--plugin/handler_socket/libhsclient/auto_ptrcontainer.hpp67
-rw-r--r--plugin/handler_socket/libhsclient/config.cpp67
-rw-r--r--plugin/handler_socket/libhsclient/config.hpp32
-rw-r--r--plugin/handler_socket/libhsclient/escape.cpp127
-rw-r--r--plugin/handler_socket/libhsclient/escape.hpp66
-rw-r--r--plugin/handler_socket/libhsclient/fatal.cpp37
-rw-r--r--plugin/handler_socket/libhsclient/fatal.hpp22
-rw-r--r--plugin/handler_socket/libhsclient/hstcpcli.cpp441
-rw-r--r--plugin/handler_socket/libhsclient/hstcpcli.hpp62
-rw-r--r--plugin/handler_socket/libhsclient/libhsclient.spec.template39
-rw-r--r--plugin/handler_socket/libhsclient/mutex.hpp51
-rw-r--r--plugin/handler_socket/libhsclient/socket.cpp186
-rw-r--r--plugin/handler_socket/libhsclient/socket.hpp51
-rw-r--r--plugin/handler_socket/libhsclient/string_buffer.hpp118
-rw-r--r--plugin/handler_socket/libhsclient/string_ref.hpp63
-rw-r--r--plugin/handler_socket/libhsclient/string_util.cpp182
-rw-r--r--plugin/handler_socket/libhsclient/string_util.hpp53
-rw-r--r--plugin/handler_socket/libhsclient/thread.hpp84
-rw-r--r--plugin/handler_socket/libhsclient/util.hpp25
-rw-r--r--plugin/handler_socket/misc/microbench-hs.log130
-rw-r--r--plugin/handler_socket/misc/microbench-my.log125
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/COPYRIGHT.txt27
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/Changes6
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/HandlerSocket.xs637
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/MANIFEST8
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.in18
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.installed20
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/README30
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket.pm68
-rwxr-xr-xplugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm362
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec.template127
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/ppport.h6375
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/t/HandlerSocket.t15
-rw-r--r--plugin/handler_socket/plug.in20
-rw-r--r--plugin/handler_socket/regtest/common/binary_my.cnf4
-rw-r--r--plugin/handler_socket/regtest/common/compat.sh29
-rw-r--r--plugin/handler_socket/regtest/common/hstest.pm66
-rwxr-xr-xplugin/handler_socket/regtest/test_01_lib/run.sh27
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test01.expected100
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test01.pl38
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test02.expected100
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test02.pl49
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test03.expected771
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test03.pl61
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test04.expectedbin0 -> 9589 bytes
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test04.pl63
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test05.expected771
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test05.pl59
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test06.expected644
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test06.pl90
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test07.expected304
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test07.pl98
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test08.expected2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test08.pl48
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test09.expected12
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test09.pl67
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test10.expected771
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test10.pl93
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test11.expected37
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test11.pl112
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test12.expected273
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test12.pl134
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test13.expected92
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test13.pl92
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test14.expected144
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test14.pl80
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test15.expected764
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test15.pl114
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test16.expected66
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test16.pl88
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test17.expectedbin0 -> 4105 bytes
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test17.pl125
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test18.expected22
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test18.pl63
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test19.expected14894
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test19.pl190
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test20.expected2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test20.pl33
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test21.expected11
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test21.pl58
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test22.expected9
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test22.pl61
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test23.expected101
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test23.pl53
-rw-r--r--regex/Makefile.am4
-rwxr-xr-xscripts/CMakeLists.txt7
-rw-r--r--scripts/Makefile.am8
-rw-r--r--scripts/make_binary_distribution.sh8
-rwxr-xr-xscripts/make_win_bin_dist1
-rw-r--r--scripts/mysql_config.sh2
-rw-r--r--scripts/mysql_install_db.sh9
-rw-r--r--scripts/mysql_system_tables.sql12
-rw-r--r--scripts/mysql_system_tables_fix.sql15
-rw-r--r--scripts/mysqlhotcopy.sh2
-rwxr-xr-xscripts/mytop.sh2459
-rw-r--r--sql-bench/Makefile.am2
-rw-r--r--sql-bench/crash-me.sh45
-rw-r--r--sql-bench/limits/mysql.cfg27
-rwxr-xr-xsql-bench/test-table-elimination.sh8
-rw-r--r--sql-common/client.c136
-rw-r--r--sql-common/client_plugin.c4
-rw-r--r--sql-common/my_time.c318
-rw-r--r--[-rwxr-xr-x]sql/CMakeLists.txt15
-rw-r--r--sql/Makefile.am23
-rw-r--r--sql/debug_sync.cc7
-rw-r--r--sql/derror.cc2
-rw-r--r--sql/discover.cc2
-rw-r--r--sql/event_data_objects.cc10
-rw-r--r--sql/event_db_repository.cc23
-rw-r--r--sql/event_parse_data.cc14
-rw-r--r--sql/event_queue.cc53
-rw-r--r--sql/event_queue.h2
-rw-r--r--[-rwxr-xr-x]sql/event_scheduler.cc2
-rw-r--r--sql/field.cc2803
-rw-r--r--sql/field.h725
-rw-r--r--sql/field_conv.cc146
-rw-r--r--sql/filesort.cc410
-rw-r--r--sql/gcalc_slicescan.cc1996
-rw-r--r--sql/gcalc_slicescan.h600
-rw-r--r--sql/gcalc_tools.cc1425
-rw-r--r--sql/gcalc_tools.h347
-rw-r--r--sql/gstream.cc23
-rw-r--r--sql/gstream.h9
-rw-r--r--sql/ha_ndbcluster.cc3
-rw-r--r--sql/ha_ndbcluster.h10
-rw-r--r--sql/ha_ndbcluster_binlog.cc2
-rw-r--r--sql/ha_partition.cc39
-rw-r--r--sql/ha_partition.h11
-rw-r--r--sql/handler.cc485
-rw-r--r--sql/handler.h530
-rw-r--r--sql/item.cc1784
-rw-r--r--sql/item.h772
-rw-r--r--sql/item_buff.cc24
-rw-r--r--sql/item_cmpfunc.cc2124
-rw-r--r--sql/item_cmpfunc.h356
-rw-r--r--sql/item_create.cc617
-rw-r--r--sql/item_create.h10
-rw-r--r--sql/item_func.cc471
-rw-r--r--sql/item_func.h132
-rw-r--r--sql/item_geofunc.cc1015
-rw-r--r--sql/item_geofunc.h259
-rw-r--r--sql/item_row.cc38
-rw-r--r--sql/item_row.h3
-rw-r--r--sql/item_strfunc.cc796
-rw-r--r--sql/item_strfunc.h94
-rw-r--r--sql/item_subselect.cc4408
-rw-r--r--sql/item_subselect.h925
-rw-r--r--sql/item_sum.cc79
-rw-r--r--sql/item_sum.h1
-rw-r--r--sql/item_timefunc.cc1238
-rw-r--r--sql/item_timefunc.h538
-rw-r--r--sql/item_xmlfunc.cc1
-rw-r--r--sql/item_xmlfunc.h8
-rw-r--r--sql/key.cc326
-rw-r--r--sql/lex.h10
-rw-r--r--sql/lock.cc353
-rw-r--r--sql/log.cc1673
-rw-r--r--sql/log.h196
-rw-r--r--sql/log_event.cc975
-rw-r--r--sql/log_event.h215
-rw-r--r--sql/log_event_old.cc20
-rw-r--r--sql/log_event_old.h3
-rw-r--r--sql/multi_range_read.cc1828
-rw-r--r--sql/multi_range_read.h637
-rw-r--r--sql/my_decimal.cc123
-rw-r--r--sql/my_decimal.h66
-rw-r--r--sql/mysql_priv.h404
-rw-r--r--sql/mysqld.cc404
-rw-r--r--sql/net_serv.cc38
-rw-r--r--sql/opt_index_cond_pushdown.cc430
-rw-r--r--sql/opt_range.cc4707
-rw-r--r--sql/opt_range.h289
-rw-r--r--sql/opt_range_mrr.cc346
-rw-r--r--sql/opt_subselect.cc5538
-rw-r--r--sql/opt_subselect.h381
-rw-r--r--sql/opt_sum.cc49
-rw-r--r--sql/opt_table_elimination.cc20
-rw-r--r--sql/parse_file.cc55
-rw-r--r--sql/parse_file.h1
-rw-r--r--sql/plistsort.c166
-rw-r--r--sql/procedure.h4
-rw-r--r--sql/protocol.cc109
-rw-r--r--sql/protocol.h13
-rw-r--r--sql/records.cc30
-rw-r--r--sql/repl_failsafe.cc6
-rw-r--r--sql/rpl_mi.cc3
-rw-r--r--sql/rpl_mi.h6
-rw-r--r--sql/rpl_record.cc22
-rw-r--r--sql/rpl_record.h3
-rw-r--r--sql/rpl_record_old.cc17
-rw-r--r--sql/rpl_record_old.h3
-rw-r--r--sql/rpl_rli.cc19
-rw-r--r--sql/rpl_rli.h38
-rw-r--r--sql/rpl_utility.cc63
-rw-r--r--sql/scheduler.cc9
-rw-r--r--sql/set_var.cc210
-rw-r--r--sql/set_var.h19
-rw-r--r--sql/share/Makefile.am1
-rw-r--r--sql/share/errmsg.txt62
-rw-r--r--sql/signal_handler.cc40
-rw-r--r--sql/slave.cc387
-rw-r--r--sql/slave.h1
-rw-r--r--sql/sp_head.cc37
-rw-r--r--sql/spatial.cc711
-rw-r--r--sql/spatial.h61
-rw-r--r--sql/sql_acl.cc33
-rw-r--r--sql/sql_array.h72
-rw-r--r--sql/sql_base.cc550
-rw-r--r--sql/sql_binlog.cc5
-rw-r--r--sql/sql_bitmap.h15
-rw-r--r--sql/sql_cache.cc602
-rw-r--r--sql/sql_cache.h31
-rw-r--r--sql/sql_class.cc320
-rw-r--r--sql/sql_class.h554
-rw-r--r--sql/sql_connect.cc21
-rw-r--r--sql/sql_cursor.cc23
-rw-r--r--sql/sql_db.cc3
-rw-r--r--sql/sql_delete.cc126
-rw-r--r--sql/sql_derived.cc987
-rw-r--r--sql/sql_error.cc2
-rw-r--r--sql/sql_expression_cache.cc322
-rw-r--r--sql/sql_expression_cache.h95
-rw-r--r--sql/sql_handler.cc628
-rw-r--r--sql/sql_handler.h61
-rw-r--r--sql/sql_help.cc4
-rw-r--r--sql/sql_insert.cc180
-rw-r--r--sql/sql_join_cache.cc4661
-rw-r--r--sql/sql_join_cache.h1414
-rw-r--r--sql/sql_lex.cc901
-rw-r--r--sql/sql_lex.h105
-rw-r--r--sql/sql_lifo_buffer.h342
-rw-r--r--sql/sql_list.h83
-rw-r--r--sql/sql_load.cc67
-rw-r--r--sql/sql_olap.cc3
-rw-r--r--sql/sql_parse.cc290
-rw-r--r--sql/sql_plugin.cc13
-rw-r--r--sql/sql_plugin_services.h15
-rw-r--r--sql/sql_prepare.cc139
-rw-r--r--sql/sql_profile.cc2
-rw-r--r--sql/sql_rename.cc2
-rw-r--r--sql/sql_repl.cc294
-rw-r--r--sql/sql_select.cc8668
-rw-r--r--sql/sql_select.h1037
-rw-r--r--sql/sql_show.cc571
-rw-r--r--sql/sql_show.h9
-rw-r--r--sql/sql_sort.h6
-rw-r--r--sql/sql_string.cc6
-rw-r--r--sql/sql_string.h19
-rw-r--r--sql/sql_table.cc126
-rw-r--r--sql/sql_test.cc152
-rw-r--r--sql/sql_trigger.cc1
-rw-r--r--sql/sql_trigger.h2
-rw-r--r--sql/sql_union.cc206
-rw-r--r--sql/sql_update.cc153
-rw-r--r--sql/sql_view.cc94
-rw-r--r--sql/sql_yacc.yy373
-rw-r--r--sql/structs.h36
-rw-r--r--sql/table.cc913
-rw-r--r--sql/table.h288
-rw-r--r--sql/time.cc359
-rw-r--r--sql/tztime.cc92
-rw-r--r--sql/tztime.h6
-rw-r--r--sql/uniques.cc122
-rw-r--r--sql/unireg.cc1
-rw-r--r--sql/unireg.h7
-rw-r--r--storage/archive/ha_archive.cc18
-rw-r--r--storage/federatedx/ha_federatedx.cc3
-rw-r--r--storage/heap/_check.c23
-rw-r--r--storage/heap/ha_heap.cc46
-rw-r--r--storage/heap/ha_heap.h2
-rw-r--r--storage/heap/heapdef.h1
-rw-r--r--storage/heap/hp_clear.c2
-rw-r--r--storage/heap/hp_create.c32
-rw-r--r--storage/heap/hp_delete.c10
-rw-r--r--storage/heap/hp_hash.c70
-rw-r--r--storage/heap/hp_rfirst.c16
-rw-r--r--storage/heap/hp_rkey.c5
-rw-r--r--storage/heap/hp_rlast.c8
-rw-r--r--storage/heap/hp_rnext.c16
-rw-r--r--storage/heap/hp_rprev.c16
-rw-r--r--storage/heap/hp_rsame.c2
-rw-r--r--storage/heap/hp_scan.c2
-rw-r--r--storage/heap/hp_test2.c12
-rw-r--r--storage/heap/hp_update.c4
-rw-r--r--storage/heap/hp_write.c61
-rw-r--r--storage/innobase/handler/ha_innodb.cc139
-rw-r--r--storage/innobase/handler/ha_innodb.h4
-rw-r--r--storage/innodb_plugin/btr/btr0sea.c6
-rw-r--r--storage/innodb_plugin/ha/ha0ha.c6
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc488
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.h15
-rw-r--r--storage/innodb_plugin/handler/i_s.cc2
-rw-r--r--storage/innodb_plugin/include/ha0ha.h10
-rw-r--r--storage/innodb_plugin/include/ha0ha.ic4
-rw-r--r--storage/innodb_plugin/include/trx0trx.h11
-rw-r--r--storage/innodb_plugin/trx/trx0trx.c2
-rw-r--r--storage/maria/CMakeLists.txt3
-rw-r--r--storage/maria/Makefile.am6
-rw-r--r--storage/maria/compat_aliases.cc250
-rw-r--r--storage/maria/ha_maria.cc265
-rw-r--r--storage/maria/ha_maria.h44
-rw-r--r--storage/maria/lockman.c6
-rw-r--r--storage/maria/ma_bitmap.c2
-rw-r--r--storage/maria/ma_blockrec.c9
-rw-r--r--storage/maria/ma_check.c72
-rw-r--r--storage/maria/ma_check_standalone.h7
-rw-r--r--storage/maria/ma_checkpoint.c88
-rw-r--r--storage/maria/ma_create.c17
-rw-r--r--storage/maria/ma_dbug.c2
-rw-r--r--storage/maria/ma_dynrec.c1
-rw-r--r--storage/maria/ma_extra.c18
-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_info.c6
-rw-r--r--storage/maria/ma_key.c78
-rw-r--r--storage/maria/ma_loghandler.c29
-rw-r--r--storage/maria/ma_loghandler.h3
-rw-r--r--storage/maria/ma_norec.c66
-rw-r--r--storage/maria/ma_open.c39
-rw-r--r--storage/maria/ma_recovery.c22
-rw-r--r--storage/maria/ma_rkey.c83
-rw-r--r--storage/maria/ma_rnext.c24
-rw-r--r--storage/maria/ma_rnext_same.c20
-rw-r--r--storage/maria/ma_rprev.c26
-rw-r--r--storage/maria/ma_rrnd.c4
-rw-r--r--storage/maria/ma_rt_index.c28
-rw-r--r--storage/maria/ma_search.c8
-rw-r--r--storage/maria/ma_sort.c31
-rw-r--r--storage/maria/ma_static.c4
-rw-r--r--storage/maria/ma_test1.c19
-rw-r--r--storage/maria/ma_test3.c2
-rw-r--r--storage/maria/ma_unique.c14
-rw-r--r--storage/maria/ma_write.c21
-rw-r--r--storage/maria/maria_chk.c4
-rw-r--r--storage/maria/maria_def.h107
-rw-r--r--storage/maria/maria_pack.c36
-rw-r--r--storage/maria/tablockman.c2
-rw-r--r--storage/maria/unittest/ma_loghandler_examples.c3
-rwxr-xr-xstorage/maria/unittest/ma_test_all-t3
-rw-r--r--storage/maria/unittest/trnman-t.c12
-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.cc177
-rw-r--r--storage/myisam/ha_myisam.h38
-rw-r--r--storage/myisam/mi_check.c18
-rw-r--r--storage/myisam/mi_create.c2
-rw-r--r--storage/myisam/mi_dbug.c5
-rw-r--r--storage/myisam/mi_extra.c11
-rw-r--r--storage/myisam/mi_key.c68
-rw-r--r--storage/myisam/mi_locking.c8
-rw-r--r--storage/myisam/mi_open.c52
-rw-r--r--storage/myisam/mi_rkey.c182
-rw-r--r--storage/myisam/mi_rnext.c44
-rw-r--r--storage/myisam/mi_rnext_same.c27
-rw-r--r--storage/myisam/mi_rprev.c47
-rw-r--r--storage/myisam/mi_search.c5
-rw-r--r--storage/myisam/mi_static.c1
-rwxr-xr-xstorage/myisam/mi_test_all.sh1
-rw-r--r--storage/myisam/myisamdef.h20
-rw-r--r--storage/myisam/myisampack.c36
-rw-r--r--storage/myisam/rt_index.c29
-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/Makefile.am2
-rw-r--r--storage/pbxt/src/filesys_xt.cc3
-rw-r--r--storage/pbxt/src/ha_pbxt.cc39
-rwxr-xr-xstorage/pbxt/src/pthread_xt.cc43
-rw-r--r--storage/pbxt/src/thread_xt.cc20
-rw-r--r--storage/pbxt/src/thread_xt.h3
-rw-r--r--storage/pbxt/src/xaction_xt.cc149
-rw-r--r--storage/pbxt/src/xaction_xt.h2
-rw-r--r--storage/xtradb/CMakeLists.txt7
-rw-r--r--storage/xtradb/dict/dict0dict.c13
-rw-r--r--storage/xtradb/handler/ha_innodb.cc1026
-rw-r--r--storage/xtradb/handler/ha_innodb.h92
-rw-r--r--storage/xtradb/handler/i_s.cc2
-rw-r--r--storage/xtradb/include/db0err.h3
-rw-r--r--storage/xtradb/include/dict0dict.h14
-rw-r--r--storage/xtradb/include/dict0dict.ic14
-rw-r--r--storage/xtradb/include/ha_prototypes.h8
-rw-r--r--storage/xtradb/include/log0log.h17
-rw-r--r--storage/xtradb/include/os0file.h8
-rw-r--r--storage/xtradb/include/os0sync.h71
-rw-r--r--storage/xtradb/include/os0sync.ic9
-rw-r--r--storage/xtradb/include/row0mysql.h12
-rw-r--r--storage/xtradb/include/srv0srv.h6
-rw-r--r--storage/xtradb/include/sync0sync.h2
-rw-r--r--storage/xtradb/include/trx0trx.h11
-rw-r--r--storage/xtradb/log/log0log.c97
-rw-r--r--storage/xtradb/os/os0file.c532
-rw-r--r--storage/xtradb/os/os0sync.c559
-rw-r--r--storage/xtradb/row/row0sel.c558
-rw-r--r--storage/xtradb/srv/srv0srv.c20
-rw-r--r--storage/xtradb/srv/srv0start.c31
-rw-r--r--storage/xtradb/trx/trx0trx.c2
-rw-r--r--strings/ctype-simple.c17
-rw-r--r--strings/decimal.c18
-rw-r--r--strings/strmov.c6
-rw-r--r--support-files/Makefile.am3
-rw-r--r--support-files/compiler_warnings.supp8
-rw-r--r--support-files/mysql.spec.sh1
-rwxr-xr-xtests/consistent_snapshot.pl107
-rw-r--r--tests/mysql_client_fw.c2
-rw-r--r--tests/mysql_client_test.c99
-rw-r--r--unittest/mysys/Makefile.am2
-rw-r--r--unittest/mysys/ma_dyncol-t.c795
-rw-r--r--unittest/mysys/thr_template.c6
-rw-r--r--unittest/mysys/waiting_threads-t.c4
-rw-r--r--win/cmake/mysql_version.cmake16
-rw-r--r--win/cmake/package_name.cmake2
1348 files changed, 276550 insertions, 28211 deletions
diff --git a/.bzrignore b/.bzrignore
index be6b6d47d31..d1786cefa90 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -344,6 +344,7 @@ client/rpl_record_old.h
client/rpl_tblmap.h
client/rpl_tblmap.cc
client/rpl_utility.h
+client/rpl_utility.cc
client/select_test
client/sql_string.cpp
client/ssl_test
@@ -681,6 +682,8 @@ libmysqld/unireg.cc
libmysqld/discover_xt.cc
libmysqld/ha_pbxt.cc
libmysqld/myxt_xt.cc
+libmysqld/rpl_reporting.cc
+libmysqld/rpl_utility.cc
libmysqltest/*.ds?
libmysqltest/*.vcproj
libmysqltest/mytest.c
@@ -1943,6 +1946,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
@@ -1954,14 +1961,25 @@ 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
+plugin/handler_socket/client/hsclient
client/strings_def.h
libmysql/strings_def.h
libmysql_r/strings_def.h
storage/maria/aria_log_control
+scripts/mytop
CPackConfig.cmake
CPackSourceConfig.cmake
win/nmake_cache.txt
*.manifest
*.resource.txt
+plugin/handler_socket/perl-Net-HandlerSocket/HandlerSocket.c
+plugin/handler_socket/perl-Net-HandlerSocket/blib
+plugin/handler_socket/perl-Net-HandlerSocket/pm_to_blib
+plugin/handler_socket/perl-Net-HandlerSocket/HandlerSocket.bs
+plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL
+libmysqld/gcalc_slicescan.cc
+libmysqld/gcalc_tools.cc
+sql-bench/test-table-elimination
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index c254304a5a8..c1a05fb1007 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -178,7 +178,7 @@ base_configs="--prefix=$prefix --enable-assembler "
base_configs="$base_configs --with-extra-charsets=complex "
base_configs="$base_configs --enable-thread-safe-client "
base_configs="$base_configs --with-big-tables"
-base_configs="$base_configs --with-plugin-aria --with-aria-tmp-tables --without-plugin-innodb_plugin"
+base_configs="$base_configs --with-plugin-aria --with-aria-tmp-tables"
# Compile our client programs with static libraries to allow them to be moved
base_configs="$base_configs --with-mysqld-ldflags=-static --with-client-ldflags=-static"
diff --git a/BUILD/compile-alpha-ccc b/BUILD/compile-alpha-ccc
index 59ed241d51c..3b22e4f1191 100755
--- a/BUILD/compile-alpha-ccc
+++ b/BUILD/compile-alpha-ccc
@@ -8,7 +8,7 @@ make -k maintainer-clean
path=`dirname $0`
. "$path/autorun.sh"
-CC=ccc CFLAGS="-fast -O3 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O6 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti -mcpu=ev6 -Wa,-mev6" CXXLDFLAGS='/usr/lib/compaq/libots-2.2.7/libots.so /usr/lib/compaq/cpml-5.0.0/libcpml_ev6.a' ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client
+CC=ccc CFLAGS="-fast -O3 -fomit-frame-pointer" CXX=g++ CXXFLAGS="-O6 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti -mcpu=ev6 -Wa,-mev6" CXXLDFLAGS='/usr/lib/compaq/libots-2.2.7/libots.so /usr/lib/compaq/cpml-5.0.0/libcpml_ev6.a' ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client
make
rm */.deps/*
make
diff --git a/BUILD/compile-alpha-debug b/BUILD/compile-alpha-debug
index 94fe8a2b414..2d8869227dc 100755
--- a/BUILD/compile-alpha-debug
+++ b/BUILD/compile-alpha-debug
@@ -8,5 +8,5 @@ make -k maintainer-clean
path=`dirname $0`
. "$path/autorun.sh"
-CFLAGS=-O1 CC=gcc CXX=gcc CXXFLAGS="-O1 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-debug --with-extra-charsets=complex --without-extra-tools
+CFLAGS=-O1 CC=gcc CXX=g++ CXXFLAGS="-O1 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-debug --with-extra-charsets=complex --without-extra-tools
make
diff --git a/BUILD/compile-dist b/BUILD/compile-dist
index 76918a5e746..70d020c0bd9 100755
--- a/BUILD/compile-dist
+++ b/BUILD/compile-dist
@@ -44,7 +44,7 @@ fi
# Default to gcc for CC and CXX
if test -z "$CXX" ; then
export CXX
- CXX=gcc
+ CXX=g++
# Set some required compile options
if test -z "$CXXFLAGS" ; then
export CXXFLAGS
diff --git a/BUILD/compile-pentium-pgcc b/BUILD/compile-pentium-pgcc
index c13a6ff14f7..5b2193c9fe9 100755
--- a/BUILD/compile-pentium-pgcc
+++ b/BUILD/compile-pentium-pgcc
@@ -8,7 +8,7 @@ path=`dirname $0`
. "$path/autorun.sh"
export PATH=/usr/local/pgcc/bin:$PATH
-CFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O6 -mpentiumpro -fomit-frame-pointer -mstack-align-double" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wextern-inline -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O6 -fomit-frame-pointer -mpentiumpro -mstack-align-double" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-all-static --with-client-ldflags=-all-static
+CFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O6 -mpentiumpro -fomit-frame-pointer -mstack-align-double" CXX=g++ CXXFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wextern-inline -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O6 -fomit-frame-pointer -mpentiumpro -mstack-align-double" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-all-static --with-client-ldflags=-all-static
gmake -j 4
diff --git a/BUILD/compile-solaris-sparc b/BUILD/compile-solaris-sparc
index e7b5b025491..ddecb0e3436 100755
--- a/BUILD/compile-solaris-sparc
+++ b/BUILD/compile-solaris-sparc
@@ -24,6 +24,6 @@ PATH=$PATH:/usr/ccs/bin:/usr/local/bin
path=`dirname $0`
. "$path/autorun.sh"
-CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa $EXTRA_FLAGS $EXTRA_CFLAGS" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g $EXTRA_FLAGS $EXTRA_CXXFLAGS" LIBS="-lmtmalloc" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
+CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa $EXTRA_FLAGS $EXTRA_CFLAGS" CXX=g++ CXXFLAGS="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g $EXTRA_FLAGS $EXTRA_CXXFLAGS" LIBS="-lmtmalloc" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
make -j 4
diff --git a/BUILD/compile-solaris-sparc-debug b/BUILD/compile-solaris-sparc-debug
index 43cabd644fa..e960039baff 100755
--- a/BUILD/compile-solaris-sparc-debug
+++ b/BUILD/compile-solaris-sparc-debug
@@ -6,6 +6,6 @@ make -k clean || true
path=`dirname $0`
. "$path/autorun.sh"
-CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-debug
+CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer" CXX=g++ CXXFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-debug
make -j 4
diff --git a/BUILD/compile-solaris-sparc-purify b/BUILD/compile-solaris-sparc-purify
index 989587fbe99..22fe5b5616e 100755
--- a/BUILD/compile-solaris-sparc-purify
+++ b/BUILD/compile-solaris-sparc-purify
@@ -37,7 +37,7 @@ make -k maintainer-clean || true
path=`dirname $0`
. "$path/autorun.sh"
-CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -DHAVE_valgrind -DEXTRA_DEBUG -O2" CXX=gcc CXXLD=g++ CXXFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -DHAVE_valgrind -DEXTRA_DEBUG -O2" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-embedded-server --with-innodb $EXTRA_CONFIG_FLAGS
+CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -DHAVE_valgrind -DEXTRA_DEBUG -O2" CXX=g++ CXXLD=g++ CXXFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -DHAVE_valgrind -DEXTRA_DEBUG -O2" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-embedded-server --with-innodb $EXTRA_CONFIG_FLAGS
make -j 4
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a61e0242cc5..463f01ddc93 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -61,7 +61,7 @@ IF (MSVC_VERSION GREATER 1400)
ENDIF()
-SET(CMAKE_INSTALL_PREFIX "C:/MariaDB${MYSQL_BASE_VERSION}")
+SET(CMAKE_INSTALL_PREFIX "C:/MariaDB${MYSQL_BASE_VERSION}" CACHE PATH "Default installation directory")
SET(INSTALL_ROOT "${CMAKE_INSTALL_PREFIX}")
# Set standard options
ADD_DEFINITIONS(-DHAVE_YASSL)
diff --git a/INSTALL-WIN-SOURCE b/INSTALL-WIN-SOURCE
index 8faf511936b..2e77959d69c 100644
--- a/INSTALL-WIN-SOURCE
+++ b/INSTALL-WIN-SOURCE
@@ -1,289 +1,2 @@
+Up-to-date instructions on MariaDB building on Windows can be found in http://kb.askmonty.org/en/building-mariadb-on-windows.
-2.5.10. Installing MySQL from Source on Windows
-
- These instructions describe how to build binaries from source for
- MySQL 5.1 on Windows. Instructions are provided for building
- binaries from a standard source distribution or from the Bazaar
- tree that contains the latest development source.
-
-Note
-
- The instructions here are strictly for users who want to test
- MySQL on Microsoft Windows from the latest source distribution or
- from the Bazaar tree. For production use, we do not advise using a
- MySQL server built by yourself from source. Normally, it is best
- to use precompiled binary distributions of MySQL that are built
- specifically for optimal performance on Windows by Oracle
- Corporation. Instructions for installing binary distributions are
- available in Section 2.5, "Installing MySQL on Windows."
-
- To build MySQL on Windows from source, you must satisfy the
- following system, compiler, and resource requirements:
-
- * Windows 2000, Windows XP, or newer version.
- Windows Vista is supported when using Visual Studio 2005
- provided you have installed the following updates:
-
- + Microsoft Visual Studio 2005 Professional Edition - ENU
- Service Pack 1 (KB926601)
- (http://support.microsoft.com/?kbid=926601)
-
- + Security Update for Microsoft Visual Studio 2005
- Professional Edition - ENU (KB937061)
- (http://support.microsoft.com/?kbid=937061)
-
- + Update for Microsoft Visual Studio 2005 Professional
- Edition - ENU (KB932232)
- (http://support.microsoft.com/?kbid=932232)
-
- * CMake, which can be downloaded from http://www.cmake.org.
- After installing, modify your path to include the cmake
- binary.
-
- * Microsoft Visual C++ 2005 Express Edition, Visual Studio .Net
- 2003 (7.1), or Visual Studio 2005 (8.0) compiler system.
-
- * If you are using Visual C++ 2005 Express Edition, you must
- also install an appropriate Platform SDK. More information and
- links to downloads for various Windows platforms is available
- from
- http://www.microsoft.com/downloads/details.aspx?familyid=0baf2
- b35-c656-4969-ace8-e4c0c0716adb.
-
- * If you are compiling from a Bazaar tree or making changes to
- the parser, you need bison for Windows, which can be
- downloaded from
- http://gnuwin32.sourceforge.net/packages/bison.htm. Download
- the package labeled "Complete package, excluding sources".
- After installing the package, modify your path to include the
- bison binary and ensure that this binary is accessible from
- Visual Studio.
-
- * Cygwin might be necessary if you want to run the test script
- or package the compiled binaries and support files into a Zip
- archive. (Cygwin is needed only to test or package the
- distribution, not to build it.) Cygwin is available from
- http://cygwin.com.
-
- * 3GB to 5GB of disk space.
-
- The exact system requirements for Visual Studio can be found here:
- http://msdn.microsoft.com/vstudio/Previous/2003/sysreqs/default.as
- px and
- http://msdn.microsoft.com/vstudio/products/sysreqs/default.aspx
-
- You also need a MySQL source distribution for Windows, which can
- be obtained two ways:
-
- * Obtain a source distribution packaged by Oracle Corporation.
- These are available from http://dev.mysql.com/downloads/.
-
- * Package a source distribution yourself from the latest Bazaar
- developer source tree. For instructions on pulling the latest
- source files, see Section 2.3.3, "Installing from the
- Development Source Tree."
-
- If you find something not working as expected, or you have
- suggestions about ways to improve the current build process on
- Windows, please send a message to the win32 mailing list. See
- Section 1.6.1, "MySQL Mailing Lists."
-
-2.5.10.1. Building MySQL from Source Using CMake and Visual Studio
-
- You can build MySQL on Windows by using a combination of cmake and
- Microsoft Visual Studio .NET 2003 (7.1), Microsoft Visual Studio
- 2005 (8.0), Microsoft Visual Studio 2008 (9.0) or Microsoft Visual
- C++ 2005 Express Edition. You must have the appropriate Microsoft
- Platform SDK installed.
-
-Note
-
- To compile from the source code on Windows you must use the
- standard source distribution (for example, mysql-5.1.46.tar.gz).
- You build from the same distribution as used to build MySQL on
- Unix, Linux and other platforms. Do not use the Windows Source
- distributions as they do not contain the necessary configuration
- script and other files.
-
- Follow this procedure to build MySQL:
-
- 1. If you are installing from a packaged source distribution,
- create a work directory (for example, C:\workdir), and unpack
- the source distribution there using WinZip or another Windows
- tool that can read .zip files. This directory is the work
- directory in the following instructions.
-
-Note
- You must run the commands in the win directory from the
- top-level source directory. Do not change into the win
- directory, as the commands will not be executed correctly.
-
- 2. Start a command shell. If you have not configured the PATH and
- other environment variables for all command shells, you may be
- able to start a command shell from the Start Menu within the
- Windows Visual Studio menu that contains the necessary
- environment changes.
-
- 3. Within the command shell, navigate to the work directory and
- run the following command:
-C:\workdir>win\configure.js options
- If you have associated the .js file extension with an
- application such as a text editor, then you may need to use
- the following command to force configure.js to be executed as
- a script:
-C:\workdir>cscript win\configure.js options
- These options are available for configure.js:
-
- + WITH_INNOBASE_STORAGE_ENGINE: Enable the InnoDB storage
- engine.
-
- + WITH_PARTITION_STORAGE_ENGINE: Enable user-defined
- partitioning.
-
- + WITH_ARCHIVE_STORAGE_ENGINE: Enable the ARCHIVE storage
- engine.
-
- + WITH_BLACKHOLE_STORAGE_ENGINE: Enable the BLACKHOLE
- storage engine.
-
- + WITH_EXAMPLE_STORAGE_ENGINE: Enable the EXAMPLE storage
- engine.
-
- + WITH_FEDERATED_STORAGE_ENGINE: Enable the FEDERATED
- storage engine.
-
- + WITH_NDBCLUSTER_STORAGE_ENGINE (experimental): Enable the
- NDBCLUSTER storage engine in the MySQL server; cause
- binaries for the MySQL Cluster management and data node,
- management client, and other programs to be built.
- This option is supported only in MySQL Cluster NDB 7.0
- (NDBCLUSTER storage engine versions 6.4.0 and later)
- using the MySQL Cluster sources. It cannot be used to
- enable clustering support in other MySQL source trees or
- distributions.
-
- + MYSQL_SERVER_SUFFIX=suffix: Server suffix, default none.
-
- + COMPILATION_COMMENT=comment: Server comment, default
- "Source distribution".
-
- + MYSQL_TCP_PORT=port: Server port, default 3306.
-
- + DISABLE_GRANT_OPTIONS: Disables the --bootstrap,
- --skip-grant-tables, and --init-file options for mysqld.
- This option is available as of MySQL 5.1.15.
- For example (type the command on one line):
-C:\workdir>win\configure.js WITH_INNOBASE_STORAGE_ENGINE
- WITH_PARTITION_STORAGE_ENGINE MYSQL_SERVER_SUFFIX=-pro
-
- 4. From the work directory, execute the win\build-vs9.bat
- (Windows Visual Studio 2008), win\build-vs8.bat (Windows
- Visual Studio 2005), or win\build-vs71.bat (Windows Visual
- Stidion 2003) script, depending on the version of Visual
- Studio you have installed. The script invokes CMake, which
- generates the mysql.sln solution file.
- You can also use the corresponding 64-bit file (for example
- win\build-vs8_x64.bat or win\build-vs9_x64.bat) to build the
- 64-bit version of MySQL. However, you cannot build the 64-bit
- version with Visual Studio Express Edition. You must use
- Visual Studio 2005 (8.0) or higher.
-
- 5. From the work directory, open the generated mysql.sln file
- with Visual Studio and select the proper configuration using
- the Configuration menu. The menu provides Debug, Release,
- RelwithDebInfo, MinRelInfo options. Then select Solution >
- Build to build the solution.
- Remember the configuration that you use in this step. It is
- important later when you run the test script because that
- script needs to know which configuration you used.
-
- 6. Test the server. The server built using the preceding
- instructions expects that the MySQL base directory and data
- directory are C:\mysql and C:\mysql\data by default. If you
- want to test your server using the source tree root directory
- and its data directory as the base directory and data
- directory, you need to tell the server their path names. You
- can either do this on the command line with the --basedir and
- --datadir options, or by placing appropriate options in an
- option file. (See Section 4.2.3.3, "Using Option Files.") If
- you have an existing data directory elsewhere that you want to
- use, you can specify its path name instead.
- When the server is running in standalone fashion or as a
- service based on your configuration, try to connect to it from
- the mysql interactive command-line utility.
- You can also run the standard test script, mysql-test-run.pl.
- This script is written in Perl, so you'll need either Cygwin
- or ActiveState Perl to run it. You may also need to install
- the modules required by the script. To run the test script,
- change location into the mysql-test directory under the work
- directory, set the MTR_VS_CONFIG environment variable to the
- configuration you selected earlier (or use the --vs-config
- option), and invoke mysql-test-run.pl. For example (using
- Cygwin and the bash shell):
-shell> cd mysql-test
-shell> export MTR_VS_CONFIG=debug
-shell> ./mysql-test-run.pl --force --timer
-shell> ./mysql-test-run.pl --force --timer --ps-protocol
-
- When you are satisfied that the programs you have built are
- working correctly, stop the server. Now you can install the
- distribution. One way to do this is to use the make_win_bin_dist
- script in the scripts directory of the MySQL source distribution
- (see Section 4.4.2, "make_win_bin_dist --- Package MySQL
- Distribution as ZIP Archive"). This is a shell script, so you must
- have Cygwin installed if you want to use it. It creates a Zip
- archive of the built executables and support files that you can
- unpack in the location at which you want to install MySQL.
-
- It is also possible to install MySQL by copying directories and
- files directly:
-
- 1. Create the directories where you want to install MySQL. For
- example, to install into C:\mysql, use these commands:
-C:\> mkdir C:\mysql
-C:\> mkdir C:\mysql\bin
-C:\> mkdir C:\mysql\data
-C:\> mkdir C:\mysql\share
-C:\> mkdir C:\mysql\scripts
- If you want to compile other clients and link them to MySQL,
- you should also create several additional directories:
-C:\> mkdir C:\mysql\include
-C:\> mkdir C:\mysql\lib
-C:\> mkdir C:\mysql\lib\debug
-C:\> mkdir C:\mysql\lib\opt
- If you want to benchmark MySQL, create this directory:
-C:\> mkdir C:\mysql\sql-bench
- Benchmarking requires Perl support. See Section 2.15, "Perl
- Installation Notes."
-
- 2. From the work directory, copy into the C:\mysql directory the
- following files and directories:
-C:\> cd \workdir
-C:\workdir> mkdir C:\mysql
-C:\workdir> mkdir C:\mysql\bin
-C:\workdir> copy client\Release\*.exe C:\mysql\bin
-C:\workdir> copy sql\Release\mysqld.exe C:\mysql\bin\mysqld.exe
-C:\workdir> xcopy scripts\*.* C:\mysql\scripts /E
-C:\workdir> xcopy share\*.* C:\mysql\share /E
- If you want to compile other clients and link them to MySQL,
- you should also copy several libraries and header files:
-C:\workdir> copy lib\Release\mysqlclient.lib C:\mysql\lib\debug
-C:\workdir> copy lib\Release\libmysql.* C:\mysql\lib\debug
-C:\workdir> copy lib\Release\zlib.* C:\mysql\lib\debug
-C:\workdir> copy lib\Release\mysqlclient.lib C:\mysql\lib\opt
-C:\workdir> copy lib\Release\libmysql.* C:\mysql\lib\opt
-C:\workdir> copy lib\Release\zlib.* C:\mysql\lib\opt
-C:\workdir> copy include\*.h C:\mysql\include
-C:\workdir> copy libmysql\libmysql.def C:\mysql\include
-
-Note
- If you have compiled a Debug, rather than Release solution,
- you can replace Release with Debug in the source file names
- shown above.
- If you want to benchmark MySQL, you should also do this:
-C:\workdir> xcopy sql-bench\*.* C:\mysql\bench /E
-
- After installation, set up and start the server in the same way as
- for binary Windows distributions. This includes creating the
- system tables by running mysql_install_db. For more information,
- see Section 2.5, "Installing MySQL on Windows."
diff --git a/Makefile.am b/Makefile.am
index cc1156fce5a..f0b617fcb66 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -277,7 +277,6 @@ API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql.h \
TEST_PREPROCESSOR_HEADER = $(API_PREPROCESSOR_HEADER) \
$(top_srcdir)/sql/mysql_priv.h
-
#
# Rules for checking that the abi/api has not changed.
diff --git a/README b/README
index b35acd95357..b6a1fe4b82f 100644
--- a/README
+++ b/README
@@ -1954,3 +1954,36 @@ proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
+
+***************************************************************************
+
+%%The following software may be included in this product:
+HandlerSocket plugin for MySQL
+
+Copyright (c) 2010 DeNA Co.,Ltd.
+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 above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of DeNA Co.,Ltd. nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY DeNA Co.,Ltd. "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 DeNA Co.,Ltd. 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.
+
+***************************************************************************
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index 5780da71bef..2d51bc3fd0f 100755
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -59,6 +59,7 @@ MYSQL_ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc
../mysys/my_bitmap.c
../mysys/my_vle.c
../mysys/base64.c
+ ../mysys/checksum.c
DESTINATION bin)
TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient wsock32)
diff --git a/client/Makefile.am b/client/Makefile.am
index 72540de0fe8..f8a0a3f7139 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -24,6 +24,7 @@ endif
INCLUDES = -I$(top_builddir)/include \
-I$(top_srcdir)/include \
-I$(top_srcdir)/regex \
+ @ZLIB_INCLUDES@ \
$(openssl_includes)
LIBS = @CLIENT_LIBS@
@@ -63,7 +64,8 @@ mysqlbinlog_SOURCES = mysqlbinlog.cc \
$(top_srcdir)/mysys/my_bit.c \
$(top_srcdir)/mysys/my_bitmap.c \
$(top_srcdir)/mysys/my_vle.c \
- $(top_srcdir)/mysys/base64.c
+ $(top_srcdir)/mysys/base64.c \
+ $(top_srcdir)/mysys/checksum.c
mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS)
mysqldump_SOURCES= mysqldump.c \
@@ -105,6 +107,7 @@ sql_src=log_event.h mysql_priv.h rpl_constants.h \
log_event.cc my_decimal.h my_decimal.cc \
log_event_old.h log_event_old.cc \
rpl_record_old.h rpl_record_old.cc \
+ rpl_utility.h rpl_utility.cc \
sql_list.h rpl_filter.h sql_list.cc rpl_filter.cc
strings_src=decimal.c strings_def.h
diff --git a/client/client_priv.h b/client/client_priv.h
index 9ad627f0832..d948fb7f98f 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -99,5 +99,7 @@ enum options_client
OPT_REWRITE_DB,
OPT_PLUGIN_DIR,
OPT_DEFAULT_PLUGIN,
+ OPT_REPORT_PROGRESS,
+ OPT_SKIP_ANNOTATE_ROWS_EVENTS,
OPT_MAX_CLIENT_OPTION /* should be always the last */
};
diff --git a/client/mysql.cc b/client/mysql.cc
index 90c14087fed..a811bacdab0 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -49,7 +49,7 @@ and you are welcome to modify and redistribute it under the GPL v2 license\n"
#include <locale.h>
#endif
-const char *VER= "14.16";
+const char *VER= "15.1";
/* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024
@@ -153,7 +153,7 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0,
default_charset_used= 0, opt_secure_auth= 0,
default_pager_set= 0, opt_sigint_ignore= 0,
show_warnings= 0, executing_query= 0,
- ignore_spaces= 0;
+ ignore_spaces= 0, opt_progress_reports;
static my_bool debug_info_flag, debug_check_flag, batch_abort_on_error;
static my_bool column_types_flag;
static my_bool preserve_comments= 0;
@@ -249,6 +249,13 @@ static const char* construct_prompt();
static char *get_arg(char *line, my_bool get_next_arg);
static void init_username();
static void add_int_to_prompt(int toadd);
+#ifndef EMBEDDED_LIBRARY
+static uint last_progress_report_length= 0;
+static void report_progress(const MYSQL *mysql, uint stage, uint max_stage,
+ double progress, const char *proc_info,
+ uint proc_info_length);
+#endif
+static void report_progress_end();
/* A structure which contains information on the commands this program
can understand. */
@@ -1499,6 +1506,10 @@ static struct my_option my_long_options[] =
"built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
&opt_mysql_port,
&opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"progress-reports", OPT_REPORT_PROGRESS,
+ "Get progress reports for long running commands (like ALTER TABLE)",
+ &opt_progress_reports, &opt_progress_reports, 0, GET_BOOL, NO_ARG, 1, 0,
+ 0, 0, 0, 0},
{"prompt", OPT_PROMPT, "Set the mysql prompt to this value.",
&current_prompt, &current_prompt, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -1855,6 +1866,7 @@ static int get_options(int argc, char **argv)
opt_outfile= 0;
opt_reconnect= 0;
connect_flag= 0; /* Not in interactive mode */
+ opt_progress_reports= 0;
}
if (strcmp(default_charset, charset_info->csname) &&
@@ -1882,6 +1894,9 @@ static int get_options(int argc, char **argv)
if (ignore_spaces)
connect_flag|= CLIENT_IGNORE_SPACE;
+ if (opt_progress_reports)
+ connect_flag|= CLIENT_PROGRESS;
+
return(0);
}
@@ -2288,7 +2303,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
break;
}
else if (!*in_string && inchar == '/' && *(pos+1) == '*' &&
- *(pos+2) != '!')
+ !(*(pos+2) == '!' || (*(pos+2) == 'M' && *(pos+3) == '!')))
{
if (preserve_comments)
{
@@ -2766,6 +2781,8 @@ static int reconnect(void)
}
if (!connected)
return put_info("Can't connect to the server\n",INFO_ERROR);
+ my_free(server_version,MYF(MY_ALLOW_ZERO_PTR));
+ server_version= 0;
/* purecov: end */
return 0;
}
@@ -3067,6 +3084,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
timer=start_timer();
executing_query= 1;
error= mysql_real_query_for_lazy(buffer->ptr(),buffer->length());
+ report_progress_end();
#ifdef HAVE_READLINE
if (status.add_to_history)
@@ -4423,9 +4441,17 @@ sql_real_connect(char *host,char *database,char *user,char *password,
}
return -1; // Retryable
}
+
connected=1;
#ifndef EMBEDDED_LIBRARY
mysql.reconnect= debug_info_flag; // We want to know if this happens
+
+ /*
+ CLIENT_PROGRESS is set only if we requsted it in mysql_real_connect()
+ and the server also supports it
+ */
+ if (mysql.client_flag & CLIENT_PROGRESS)
+ mysql_options(&mysql, MYSQL_PROGRESS_CALLBACK, (void*) report_progress);
#else
mysql.reconnect= 1;
#endif
@@ -5073,4 +5099,31 @@ void sql_element_free(void *ptr)
{
my_free(ptr,MYF(0));
}
-#endif /* EMBEDDED_LIBRARY */
+
+static void report_progress(const MYSQL *mysql, uint stage, uint max_stage,
+ double progress, const char *proc_info,
+ uint proc_info_length)
+{
+ uint length= printf("Stage: %d of %d '%.*s' %6.3g%% of stage done",
+ stage, max_stage, proc_info_length, proc_info,
+ progress);
+ if (length < last_progress_report_length)
+ printf("%*s", last_progress_report_length - length, "");
+ putc('\r', stdout);
+ fflush(stdout);
+ last_progress_report_length= length;
+}
+
+static void report_progress_end()
+{
+ if (last_progress_report_length)
+ {
+ printf("%*s\r", last_progress_report_length, "");
+ last_progress_report_length= 0;
+ }
+}
+#else
+static void report_progress_end()
+{
+}
+#endif
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 67fcbab4314..de44ef5d927 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -88,6 +88,7 @@ static const char* database= 0;
static my_bool force_opt= 0, short_form= 0, remote_opt= 0;
static my_bool debug_info_flag, debug_check_flag;
static my_bool force_if_open_opt= 1;
+static my_bool opt_verify_binlog_checksum= 1;
static ulonglong offset = 0;
static const char* host = 0;
static int port= 0;
@@ -112,6 +113,7 @@ static ulonglong rec_count= 0;
static short binlog_flags = 0;
static MYSQL* mysql = NULL;
static const char* dirname_for_local_load= 0;
+static bool opt_skip_annotate_row_events= 0;
/**
Pointer to the Format_description_log_event of the currently active binlog.
@@ -133,6 +135,71 @@ enum Exit_status {
OK_STOP
};
+/**
+ Pointer to the last read Annotate_rows_log_event. Having read an
+ Annotate_rows event, we should not print it immediatedly because all
+ subsequent rbr events can be filtered away, and have to keep it for a while.
+ Also because of that when reading a remote Annotate event we have to keep
+ its binary log representation in a separately allocated buffer.
+*/
+static Annotate_rows_log_event *annotate_event= NULL;
+
+void free_annotate_event()
+{
+ if (annotate_event)
+ {
+ delete annotate_event;
+ annotate_event= 0;
+ }
+}
+
+Log_event* read_remote_annotate_event(uchar* net_buf, ulong event_len,
+ const char **error_msg)
+{
+ uchar *event_buf;
+ Log_event* event;
+
+ if (!(event_buf= (uchar*) my_malloc(event_len + 1, MYF(MY_WME))))
+ {
+ error("Out of memory");
+ return 0;
+ }
+
+ memcpy(event_buf, net_buf, event_len);
+ event_buf[event_len]= 0;
+
+ if (!(event= Log_event::read_log_event((const char*) event_buf, event_len,
+ error_msg, glob_description_event,
+ opt_verify_binlog_checksum)))
+ {
+ my_free(event_buf, MYF(0));
+ return 0;
+ }
+ /*
+ Ensure the event->temp_buf is pointing to the allocated buffer.
+ (TRUE = free temp_buf on the event deletion)
+ */
+ event->register_temp_buf((char*)event_buf, TRUE);
+
+ return event;
+}
+
+void keep_annotate_event(Annotate_rows_log_event* event)
+{
+ free_annotate_event();
+ annotate_event= event;
+}
+
+void print_annotate_event(PRINT_EVENT_INFO *print_event_info)
+{
+ if (annotate_event)
+ {
+ annotate_event->print(result_file, print_event_info);
+ delete annotate_event; // the event should not be printed more than once
+ annotate_event= 0;
+ }
+}
+
static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
const char* logname);
static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
@@ -749,7 +816,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
read them to be able to process the wanted events.
*/
if (((rec_count >= offset) &&
- ((my_time_t)(ev->when) >= start_datetime)) ||
+ (ev->when >= start_datetime)) ||
(ev_type == FORMAT_DESCRIPTION_EVENT))
{
if (ev_type != FORMAT_DESCRIPTION_EVENT)
@@ -773,7 +840,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
server_id && (server_id != ev->server_id))
goto end;
}
- if (((my_time_t)(ev->when) >= stop_datetime)
+ if ((ev->when >= stop_datetime)
|| (pos >= stop_position_mot))
{
/* end the program */
@@ -796,8 +863,19 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
case QUERY_EVENT:
{
Query_log_event *qe= (Query_log_event*)ev;
- if (!qe->is_trans_keyword() && shall_skip_database(qe->db))
- goto end;
+ if (!qe->is_trans_keyword())
+ {
+ if (shall_skip_database(qe->db))
+ goto end;
+ }
+ else
+ {
+ /*
+ In case the event for one of these statements is obtained
+ from binary log 5.0, make it compatible with 5.1
+ */
+ qe->flags|= LOG_EVENT_SUPPRESS_USE_F;
+ }
print_use_stmt(print_event_info, qe);
if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS)
{
@@ -967,6 +1045,19 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
my_free(fname, MYF(MY_WME));
break;
}
+ case ANNOTATE_ROWS_EVENT:
+ if (!opt_skip_annotate_row_events)
+ {
+ /*
+ We don't print Annotate event just now because all subsequent
+ rbr-events can be filtered away. Instead we'll keep the event
+ till it will be printed together with the first not filtered
+ away Table map or the last rbr will be processed.
+ */
+ keep_annotate_event((Annotate_rows_log_event*) ev);
+ destroy_evt= FALSE;
+ }
+ break;
case TABLE_MAP_EVENT:
{
Table_map_log_event *map= ((Table_map_log_event *)ev);
@@ -976,6 +1067,13 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
destroy_evt= FALSE;
goto end;
}
+ /*
+ The Table map is to be printed, so it's just the time when we may
+ print the kept Annotate event (if there is any).
+ print_annotate_event() also deletes the kept Annotate event.
+ */
+ print_annotate_event(print_event_info);
+
size_t len_to= 0;
const char* db_to= binlog_filter->get_rewrite_db(map->get_db_name(), &len_to);
if (len_to && map->rewrite_db(db_to, len_to, glob_description_event))
@@ -1012,6 +1110,13 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
if (print_event_info->m_table_map_ignored.count() > 0)
print_event_info->m_table_map_ignored.clear_tables();
+ /*
+ If there is a kept Annotate event and all corresponding
+ rbr-events were filtered away, the Annotate event was not
+ freed and it is just the time to do it.
+ */
+ free_annotate_event();
+
/*
One needs to take into account an event that gets
filtered but was last event in the statement. If this is
@@ -1245,10 +1350,18 @@ that may lead to an endless loop.",
"Used to reserve file descriptors for use by this program.",
&open_files_limit, &open_files_limit, 0, GET_ULONG,
REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0},
+ {"verify-binlog-checksum", 'c', "Verify checksum binlog events.",
+ (uchar**) &opt_verify_binlog_checksum, (uchar**) &opt_verify_binlog_checksum,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"rewrite-db", OPT_REWRITE_DB,
"Updates to a database with a different name than the original. \
Example: rewrite-db='from->to'.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-annotate-row-events", OPT_SKIP_ANNOTATE_ROWS_EVENTS,
+ "Don't print Annotate_rows events stored in the binary log.",
+ (uchar**) &opt_skip_annotate_row_events,
+ (uchar**) &opt_skip_annotate_row_events,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -1358,7 +1471,7 @@ static my_time_t convert_str_to_timestamp(const char* str)
int was_cut;
MYSQL_TIME l_time;
long dummy_my_timezone;
- my_bool dummy_in_dst_time_gap;
+ uint dummy_in_dst_time_gap;
/* We require a total specification (date AND time) */
if (str_to_datetime(str, (uint) strlen(str), &l_time, 0, &was_cut) !=
MYSQL_TIMESTAMP_DATETIME || was_cut)
@@ -1635,7 +1748,18 @@ static Exit_status check_master_version()
"Master reported NULL for the version.");
goto err;
}
-
+ /*
+ Make a notice to the server that this client
+ is checksum-aware. It does not need the first fake Rotate
+ necessary checksummed.
+ That preference is specified below.
+ */
+ if (mysql_query(mysql, "SET @master_binlog_checksum='NONE'"))
+ {
+ error("Could not notify master about checksum awareness."
+ "Master returned '%s'", mysql_error(mysql));
+ goto err;
+ }
delete glob_description_event;
switch (*version) {
case '3':
@@ -1717,6 +1841,8 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
cast to uint32.
*/
int4store(buf, (uint32)start_position);
+ if (!opt_skip_annotate_row_events)
+ binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
int2store(buf + BIN_LOG_HEADER_SIZE, binlog_flags);
size_t tlen = strlen(logname);
@@ -1749,18 +1875,31 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
break; // end of data
DBUG_PRINT("info",( "len: %lu net->read_pos[5]: %d\n",
len, net->read_pos[5]));
- if (!(ev= Log_event::read_log_event((const char*) net->read_pos + 1 ,
- len - 1, &error_msg,
- glob_description_event)))
+ if (net->read_pos[5] == ANNOTATE_ROWS_EVENT)
{
- error("Could not construct log event object: %s", error_msg);
- DBUG_RETURN(ERROR_STOP);
- }
- /*
- If reading from a remote host, ensure the temp_buf for the
- Log_event class is pointing to the incoming stream.
- */
- ev->register_temp_buf((char *) net->read_pos + 1, FALSE);
+ if (!(ev= read_remote_annotate_event(net->read_pos + 1, len - 1,
+ &error_msg)))
+ {
+ error("Could not construct annotate event object: %s", error_msg);
+ DBUG_RETURN(ERROR_STOP);
+ }
+ }
+ else
+ {
+ if (!(ev= Log_event::read_log_event((const char*) net->read_pos + 1 ,
+ len - 1, &error_msg,
+ glob_description_event,
+ opt_verify_binlog_checksum)))
+ {
+ error("Could not construct log event object: %s", error_msg);
+ DBUG_RETURN(ERROR_STOP);
+ }
+ /*
+ If reading from a remote host, ensure the temp_buf for the
+ Log_event class is pointing to the incoming stream.
+ */
+ ev->register_temp_buf((char *) net->read_pos + 1, FALSE);
+ }
Log_event_type type= ev->get_type_code();
if (glob_description_event->binlog_version >= 3 ||
@@ -1988,7 +2127,8 @@ static Exit_status check_header(IO_CACHE* file,
Format_description_log_event *new_description_event;
my_b_seek(file, tmp_pos); /* seek back to event's start */
if (!(new_description_event= (Format_description_log_event*)
- Log_event::read_log_event(file, glob_description_event)))
+ Log_event::read_log_event(file, glob_description_event,
+ opt_verify_binlog_checksum)))
/* EOF can't be hit here normally, so it's a real error */
{
error("Could not read a Format_description_log_event event at "
@@ -2021,7 +2161,8 @@ static Exit_status check_header(IO_CACHE* file,
{
Log_event *ev;
my_b_seek(file, tmp_pos); /* seek back to event's start */
- if (!(ev= Log_event::read_log_event(file, glob_description_event)))
+ if (!(ev= Log_event::read_log_event(file, glob_description_event,
+ opt_verify_binlog_checksum)))
{
/* EOF can't be hit here normally, so it's a real error */
error("Could not read a Rotate_log_event event at offset %llu;"
@@ -2093,7 +2234,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
return ERROR_STOP;
}
#endif
- if (init_io_cache(file, fileno(stdin), 0, READ_CACHE, (my_off_t) 0,
+ if (init_io_cache(file, my_fileno(stdin), 0, READ_CACHE, (my_off_t) 0,
0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE)))
{
error("Failed to init IO cache.");
@@ -2134,7 +2275,8 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
char llbuff[21];
my_off_t old_off = my_b_tell(file);
- Log_event* ev = Log_event::read_log_event(file, glob_description_event);
+ Log_event* ev = Log_event::read_log_event(file, glob_description_event,
+ opt_verify_binlog_checksum);
if (!ev)
{
/*
@@ -2286,6 +2428,7 @@ int main(int argc, char** argv)
if (result_file != stdout)
my_fclose(result_file, MYF(0));
cleanup();
+ free_annotate_event();
delete binlog_filter;
free_root(&s_mem_root, MYF(0));
free_defaults(defaults_argv);
@@ -2318,4 +2461,4 @@ void *sql_alloc(size_t size)
#include "sql_string.cc"
#include "sql_list.cc"
#include "rpl_filter.cc"
-
+#include "rpl_utility.cc"
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 80af5185ecc..460ff162319 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -84,6 +84,9 @@
#define IGNORE_DATA 0x01 /* don't dump data for this table */
#define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */
+/* Chars needed to store LONGLONG, excluding trailing '\0'. */
+#define LONGLONG_LEN 20
+
/* general_log or slow_log tables under mysql database */
static inline my_bool general_log_or_slow_log_tables(const char *db,
const char *table)
@@ -360,9 +363,9 @@ static struct my_option my_long_options[] =
"This causes the binary log position and filename to be appended to the "
"output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
" to 2, that command will be prefixed with a comment symbol. "
- "This option will turn --lock-all-tables on, unless "
- "--single-transaction is specified too (in which case a "
- "global read lock is only taken a short time at the beginning of the dump; "
+ "This option will turn --lock-all-tables on, unless --single-transaction "
+ "is specified too (on servers before MariaDB 5.3 this will still take a "
+ "global read lock for a short time at the beginning of the dump; "
"don't forget to read about --single-transaction below). In all cases, "
"any action on logs will happen at the exact moment of the dump. "
"Option automatically turns --lock-tables off.",
@@ -1138,6 +1141,44 @@ static int fetch_db_collation(const char *db_name,
}
+/*
+ Check if server supports non-blocking binlog position using the
+ binlog_snapshot_file and binlog_snapshot_position status variables. If it
+ does, also return the position obtained if output pointers are non-NULL.
+ Returns 1 if position available, 0 if not.
+*/
+static int
+check_consistent_binlog_pos(char *binlog_pos_file, char *binlog_pos_offset)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int found;
+
+ if (mysql_query_with_error_report(mysql, &res,
+ "SHOW STATUS LIKE 'binlog_snapshot_%'"))
+ return 1;
+
+ found= 0;
+ while ((row= mysql_fetch_row(res)))
+ {
+ if (0 == strcmp(row[0], "binlog_snapshot_file"))
+ {
+ if (binlog_pos_file)
+ strmake(binlog_pos_file, row[1], FN_REFLEN-1);
+ found++;
+ }
+ else if (0 == strcmp(row[0], "binlog_snapshot_position"))
+ {
+ if (binlog_pos_offset)
+ strmake(binlog_pos_offset, row[1], LONGLONG_LEN);
+ found++;
+ }
+ }
+ mysql_free_result(res);
+
+ return (found == 2);
+}
+
static char *my_case_str(const char *str,
uint str_len,
const char *token,
@@ -4623,41 +4664,65 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
} /* dump_selected_tables */
-static int do_show_master_status(MYSQL *mysql_con)
+static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos)
{
MYSQL_ROW row;
MYSQL_RES *master;
+ char binlog_pos_file[FN_REFLEN];
+ char binlog_pos_offset[LONGLONG_LEN+1];
+ char *file, *offset;
const char *comment_prefix=
(opt_master_data == MYSQL_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : "";
- if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS"))
+
+ if (consistent_binlog_pos)
{
- return 1;
+ if(!check_consistent_binlog_pos(binlog_pos_file, binlog_pos_offset))
+ return 1;
+ file= binlog_pos_file;
+ offset= binlog_pos_offset;
}
else
{
+ if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS"))
+ return 1;
+
row= mysql_fetch_row(master);
if (row && row[0] && row[1])
{
- /* SHOW MASTER STATUS reports file and position */
- print_comment(md_result_file, 0,
- "\n--\n-- Position to start replication or point-in-time "
- "recovery from\n--\n\n");
- fprintf(md_result_file,
- "%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
- comment_prefix, row[0], row[1]);
- check_io(md_result_file);
+ file= row[0];
+ offset= row[1];
}
- else if (!ignore_errors)
+ else
{
- /* SHOW MASTER STATUS reports nothing and --force is not enabled */
- my_printf_error(0, "Error: Binlogging on server not active",
- MYF(0));
mysql_free_result(master);
- maybe_exit(EX_MYSQLERR);
- return 1;
+ if (!ignore_errors)
+ {
+ /* SHOW MASTER STATUS reports nothing and --force is not enabled */
+ my_printf_error(0, "Error: Binlogging on server not active",
+ MYF(0));
+ maybe_exit(EX_MYSQLERR);
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
}
- mysql_free_result(master);
}
+
+ /* SHOW MASTER STATUS reports file and position */
+ if (opt_comments)
+ print_comment(md_result_file, 0,
+ "\n--\n-- Position to start replication or point-in-time "
+ "recovery from\n--\n\n");
+ fprintf(md_result_file,
+ "%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
+ comment_prefix, file, offset);
+ check_io(md_result_file);
+
+ if (!consistent_binlog_pos)
+ mysql_free_result(master);
+
return 0;
}
@@ -5294,6 +5359,7 @@ int main(int argc, char **argv)
{
char bin_log_name[FN_REFLEN];
int exit_code;
+ int consistent_binlog_pos= 0;
MY_INIT("mysqldump");
compatible_mode_normal_str[0]= 0;
@@ -5330,7 +5396,13 @@ int main(int argc, char **argv)
if (!path)
write_header(md_result_file, *argv);
- if ((opt_lock_all_tables || opt_master_data) &&
+ if (opt_single_transaction && opt_master_data)
+ {
+ /* See if we can avoid FLUSH TABLES WITH READ LOCK (MariaDB 5.3+). */
+ consistent_binlog_pos= check_consistent_binlog_pos(NULL, NULL);
+ }
+
+ if ((opt_lock_all_tables || (opt_master_data && !consistent_binlog_pos)) &&
do_flush_tables_read_lock(mysql))
goto err;
if (opt_single_transaction && start_transaction(mysql))
@@ -5348,7 +5420,7 @@ int main(int argc, char **argv)
goto err;
flush_logs= 0; /* not anymore; that would not be sensible */
}
- if (opt_master_data && do_show_master_status(mysql))
+ if (opt_master_data && do_show_master_status(mysql, consistent_binlog_pos))
goto err;
if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */
goto err;
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index 6ae0271eedb..f568ef9d2e2 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -1225,7 +1225,7 @@ get_options(int *argc,char ***argv)
if (opt_csv_str[0] == '-')
{
- csv_file= fileno(stdout);
+ csv_file= my_fileno(stdout);
}
else
{
@@ -1384,9 +1384,9 @@ get_options(int *argc,char ***argv)
fprintf(stderr,"%s: Could not open create file\n", my_progname);
exit(1);
}
- tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ tmp_string= (char *)my_malloc((size_t)sbuf.st_size + 1,
MYF(MY_ZEROFILL|MY_FAE|MY_WME));
- my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0));
+ my_read(data_file, (uchar*) tmp_string, (size_t)sbuf.st_size, MYF(0));
tmp_string[sbuf.st_size]= '\0';
my_close(data_file,MYF(0));
parse_delimiter(tmp_string, &create_statements, delimiter[0]);
@@ -1411,9 +1411,9 @@ get_options(int *argc,char ***argv)
fprintf(stderr,"%s: Could not open query supplied file\n", my_progname);
exit(1);
}
- tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ tmp_string= (char *)my_malloc((size_t)sbuf.st_size + 1,
MYF(MY_ZEROFILL|MY_FAE|MY_WME));
- my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0));
+ my_read(data_file, (uchar*) tmp_string, (size_t)sbuf.st_size, MYF(0));
tmp_string[sbuf.st_size]= '\0';
my_close(data_file,MYF(0));
if (user_supplied_query)
@@ -1442,9 +1442,9 @@ get_options(int *argc,char ***argv)
fprintf(stderr,"%s: Could not open query supplied file\n", my_progname);
exit(1);
}
- tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ tmp_string= (char *)my_malloc((size_t)sbuf.st_size + 1,
MYF(MY_ZEROFILL|MY_FAE|MY_WME));
- my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0));
+ my_read(data_file, (uchar*) tmp_string, (size_t)sbuf.st_size, MYF(0));
tmp_string[sbuf.st_size]= '\0';
my_close(data_file,MYF(0));
if (user_supplied_pre_statements)
@@ -1473,9 +1473,9 @@ get_options(int *argc,char ***argv)
fprintf(stderr,"%s: Could not open query supplied file\n", my_progname);
exit(1);
}
- tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ tmp_string= (char *)my_malloc((size_t)sbuf.st_size + 1,
MYF(MY_ZEROFILL|MY_FAE|MY_WME));
- my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0));
+ my_read(data_file, (uchar*) tmp_string, (size_t)sbuf.st_size, MYF(0));
tmp_string[sbuf.st_size]= '\0';
my_close(data_file,MYF(0));
if (user_supplied_post_statements)
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index fa3ade1a7c1..32f9b56ac77 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -116,7 +116,7 @@ static my_bool display_result_vertically= FALSE, display_result_lower= FALSE,
display_metadata= FALSE, display_result_sorted= FALSE;
static my_bool disable_query_log= 0, disable_result_log= 0;
static my_bool disable_connect_log= 1;
-static my_bool disable_warnings= 0;
+static my_bool disable_warnings= 0, disable_column_names= 0;
static my_bool prepare_warnings_enabled= 0;
static my_bool disable_info= 1;
static char *opt_plugin_dir= 0, *opt_default_auth;
@@ -303,6 +303,7 @@ enum enum_commands {
Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS,
Q_ENABLE_INFO, Q_DISABLE_INFO,
Q_ENABLE_METADATA, Q_DISABLE_METADATA,
+ Q_ENABLE_COLUMN_NAMES, Q_DISABLE_COLUMN_NAMES,
Q_EXEC, Q_DELIMITER,
Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR,
Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS,
@@ -376,6 +377,8 @@ const char *command_names[]=
"disable_info",
"enable_metadata",
"disable_metadata",
+ "enable_column_names",
+ "disable_column_names",
"exec",
"delimiter",
"disable_abort_on_error",
@@ -731,7 +734,8 @@ void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
int len);
void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val);
-void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input);
+void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input,
+ bool keep_header);
static int match_expected_error(struct st_command *command,
unsigned int err_errno,
@@ -2812,6 +2816,7 @@ void do_exec(struct st_command *command)
FILE *res_file;
char *cmd= command->first_argument;
DYNAMIC_STRING ds_cmd;
+ DYNAMIC_STRING ds_sorted, *ds_result;
DBUG_ENTER("do_exec");
DBUG_PRINT("enter", ("cmd: '%s'", cmd));
@@ -2857,6 +2862,13 @@ void do_exec(struct st_command *command)
die("popen(\"%s\", \"r\") failed", command->first_argument);
}
+ ds_result= &ds_res;
+ if (display_result_sorted)
+ {
+ init_dynamic_string(&ds_sorted, "", 1024, 1024);
+ ds_result= &ds_sorted;
+ }
+
while (fgets(buf, sizeof(buf), res_file))
{
if (disable_result_log)
@@ -2866,10 +2878,17 @@ void do_exec(struct st_command *command)
}
else
{
- replace_dynstr_append(&ds_res, buf);
+ replace_dynstr_append(ds_result, buf);
}
}
error= pclose(res_file);
+
+ if (display_result_sorted)
+ {
+ dynstr_append_sorted(&ds_res, &ds_sorted, 0);
+ dynstr_free(&ds_sorted);
+ }
+
if (error > 0)
{
uint status= WEXITSTATUS(error);
@@ -6771,6 +6790,7 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
my_bool *is_null;
ulong *length;
uint i;
+ int error;
/* Allocate array with bind structs, lengths and NULL flags */
my_bind= (MYSQL_BIND*) my_malloc(num_fields * sizeof(MYSQL_BIND),
@@ -6798,7 +6818,7 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
die("mysql_stmt_bind_result failed: %d: %s",
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
- while (mysql_stmt_fetch(stmt) == 0)
+ while ((error=mysql_stmt_fetch(stmt)) == 0)
{
for (i= 0; i < num_fields; i++)
append_field(ds, i, &fields[i], (char*)my_bind[i].buffer,
@@ -6807,8 +6827,11 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
dynstr_append_mem(ds, "\n", 1);
}
+ if (error != MYSQL_NO_DATA)
+ die("mysql_fetch didn't end with MYSQL_NO_DATA from statement: error: %d",
+ error);
if (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
- die("fetch didn't end with MYSQL_NO_DATA from statement: %d %s",
+ die("mysql_fetch didn't end with MYSQL_NO_DATA from statement: %d %s",
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
for (i= 0; i < num_fields; i++)
@@ -6903,6 +6926,8 @@ void append_table_headings(DYNAMIC_STRING *ds,
uint num_fields)
{
uint col_idx;
+ if (disable_column_names)
+ return;
for (col_idx= 0; col_idx < num_fields; col_idx++)
{
if (col_idx)
@@ -7562,7 +7587,8 @@ int util_query(MYSQL* org_mysql, const char* query){
cur_con->util_mysql= mysql;
}
- return mysql_query(mysql, query);
+ int ret= mysql_query(mysql, query);
+ DBUG_RETURN(ret);
}
@@ -7774,7 +7800,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
if (display_result_sorted)
{
/* Sort the result set and append it to result */
- dynstr_append_sorted(save_ds, &ds_sorted);
+ dynstr_append_sorted(save_ds, &ds_sorted, 1);
ds= save_ds;
dynstr_free(&ds_sorted);
}
@@ -8440,6 +8466,14 @@ int main(int argc, char **argv)
display_metadata= 0;
var_set_int("$ENABLED_METADATA", 0);
break;
+ case Q_ENABLE_COLUMN_NAMES:
+ disable_column_names= 0;
+ var_set_int("$ENABLED_COLUMN_NAMES", 0);
+ break;
+ case Q_DISABLE_COLUMN_NAMES:
+ disable_column_names= 1;
+ var_set_int("$ENABLED_COLUMN_NAMES", 1);
+ break;
case Q_SOURCE: do_source(command); break;
case Q_SLEEP: do_sleep(command, 0); break;
case Q_REAL_SLEEP: do_sleep(command, 1); break;
@@ -8827,7 +8861,7 @@ void timer_output(void)
ulonglong timer_now(void)
{
- return my_micro_time() / 1000;
+ return my_interval_timer() / 1000000;
}
@@ -10151,17 +10185,16 @@ void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val)
}
-
/*
Build a list of pointer to each line in ds_input, sort
the list and use the sorted list to append the strings
sorted to the output ds
SYNOPSIS
- dynstr_append_sorted
- ds - string where the sorted output will be appended
- ds_input - string to be sorted
-
+ dynstr_append_sorted()
+ ds string where the sorted output will be appended
+ ds_input string to be sorted
+ keep_header If header should not be sorted
*/
static int comp_lines(const char **a, const char **b)
@@ -10169,7 +10202,8 @@ static int comp_lines(const char **a, const char **b)
return (strcmp(*a,*b));
}
-void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input)
+void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input,
+ bool keep_header)
{
unsigned i;
char *start= ds_input->str;
@@ -10181,11 +10215,14 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input)
my_init_dynamic_array(&lines, sizeof(const char*), 32, 32);
- /* First line is result header, skip past it */
- while (*start && *start != '\n')
- start++;
- start++; /* Skip past \n */
- dynstr_append_mem(ds, ds_input->str, start - ds_input->str);
+ if (keep_header)
+ {
+ /* First line is result header, skip past it */
+ while (*start && *start != '\n')
+ start++;
+ start++; /* Skip past \n */
+ dynstr_append_mem(ds, ds_input->str, start - ds_input->str);
+ }
/* Insert line(s) in array */
while (*start)
@@ -10263,4 +10300,3 @@ char *mysql_authentication_dialog_ask(MYSQL *mysql, int type,
return buf;
}
-
diff --git a/client/readline.cc b/client/readline.cc
index cb020d62241..b44862062e1 100644
--- a/client/readline.cc
+++ b/client/readline.cc
@@ -45,7 +45,7 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
if (!(line_buff=(LINE_BUFFER*)
my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL))))
return 0;
- if (init_line_buffer(line_buff,fileno(file),IO_SIZE,max_size))
+ if (init_line_buffer(line_buff,my_fileno(file),IO_SIZE,max_size))
{
my_free(line_buff,MYF(0));
return 0;
diff --git a/client/sql_string.cc b/client/sql_string.cc
index 720b0332411..57518423f4b 100644
--- a/client/sql_string.cc
+++ b/client/sql_string.cc
@@ -544,11 +544,11 @@ uint32 String::numchars()
return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
}
-int String::charpos(int i,uint32 offset)
+int String::charpos(longlong i,uint32 offset)
{
if (i <= 0)
- return i;
- return str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,i);
+ return (int)i;
+ return (int)str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,(size_t)i);
}
int String::strstr(const String &s,uint32 offset)
diff --git a/client/sql_string.h b/client/sql_string.h
index 423a9c400b3..6adf8f91fd0 100644
--- a/client/sql_string.h
+++ b/client/sql_string.h
@@ -278,7 +278,7 @@ public:
friend int stringcmp(const String *a,const String *b);
friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
uint32 numchars();
- int charpos(int i,uint32 offset=0);
+ int charpos(longlong i,uint32 offset=0);
int reserve(uint32 space_needed)
{
diff --git a/cmd-line-utils/libedit/chartype.h b/cmd-line-utils/libedit/chartype.h
index 40012afb47d..576abe13ad5 100644
--- a/cmd-line-utils/libedit/chartype.h
+++ b/cmd-line-utils/libedit/chartype.h
@@ -49,7 +49,7 @@
TODO : Verify if FreeBSD & AIX stores ISO 10646 in wchar_t. */
#if !defined(__NetBSD__) && !defined(__sun) \
&& !(defined(__APPLE__) && defined(__MACH__)) \
- && !defined(__FreeBSD__) && !defined(_AIX)
+ && !defined(__FreeBSD__) && !defined(_AIX) && !defined(__OpenBSD__)
#ifndef __STDC_ISO_10646__
/* In many places it is assumed that the first 127 code points are ASCII
* compatible, so ensure wchar_t indeed does ISO 10646 and not some other
diff --git a/cmd-line-utils/libedit/np/unvis.c b/cmd-line-utils/libedit/np/unvis.c
index 812d280b2d8..a911720ad35 100644
--- a/cmd-line-utils/libedit/np/unvis.c
+++ b/cmd-line-utils/libedit/np/unvis.c
@@ -64,7 +64,7 @@ static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93";
#include "np/vis.h"
#ifdef __weak_alias
-__weak_alias(strnunvisx,_strnunvisx)
+__weak_alias(strnunvisx,_strnunvisx);
#endif
#if !HAVE_VIS
diff --git a/cmd-line-utils/libedit/np/vis.c b/cmd-line-utils/libedit/np/vis.c
index d7cc37b4f47..884a7894332 100644
--- a/cmd-line-utils/libedit/np/vis.c
+++ b/cmd-line-utils/libedit/np/vis.c
@@ -77,7 +77,7 @@
#include <stdlib.h>
#ifdef __weak_alias
-__weak_alias(strvisx,_strvisx)
+__weak_alias(strvisx,_strvisx);
#endif
#if !HAVE_VIS || !HAVE_SVIS
diff --git a/cmd-line-utils/libedit/sys.h b/cmd-line-utils/libedit/sys.h
index 33638d1565b..af55bcd7202 100644
--- a/cmd-line-utils/libedit/sys.h
+++ b/cmd-line-utils/libedit/sys.h
@@ -40,6 +40,17 @@
#ifndef _h_sys
#define _h_sys
+#ifdef __linux__
+/* Apparently we need _GNU_SOURCE defined to get access to wcsdup on Linux */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#endif
+
+#ifndef __USE_XOPEN
+#define __USE_XOPEN
+#endif
+
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
@@ -92,17 +103,6 @@ size_t strlcpy(char *dst, const char *src, size_t size);
char *fgetln(FILE *fp, size_t *len);
#endif
-#ifdef __linux__
-/* Apparently we need _GNU_SOURCE defined to get access to wcsdup on Linux */
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#endif
-
-#ifndef __USE_XOPEN
-#define __USE_XOPEN
-#endif
-
#include <wchar.h>
#include <wctype.h>
diff --git a/configure.in b/configure.in
index 04faa551d1b..da61cedac7d 100644
--- a/configure.in
+++ b/configure.in
@@ -13,7 +13,7 @@ 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.15-MariaDB], [], [mysql])
+AC_INIT([MariaDB Server], [5.3.13-MariaDB], [], [mysql])
AC_CONFIG_SRCDIR([sql/mysqld.cc])
AC_CANONICAL_SYSTEM
@@ -914,6 +914,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/dbug/dbug.c b/dbug/dbug.c
index 0ea0b0df6ad..29657c9dd03 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -1481,7 +1481,7 @@ next:
subdir=0;
while (ctlp < end && *ctlp != ',')
ctlp++;
- len=ctlp-start;
+ len= (int) (ctlp-start);
if (start[len-1] == '/')
{
len--;
@@ -1544,7 +1544,7 @@ static struct link *ListCopy(struct link *orig)
{
struct link *new_malloc;
struct link *head;
- int len;
+ size_t len;
head= NULL;
while (orig != NULL)
@@ -1999,7 +1999,7 @@ static void DBUGOpenFile(CODE_STATE *cs,
{
if (end)
{
- int len=end-name;
+ int len= (int) (end-name);
memcpy(cs->stack->name, name, len);
cs->stack->name[len]=0;
}
diff --git a/extra/comp_err.c b/extra/comp_err.c
index 2c8d9823201..861ae8020d9 100644
--- a/extra/comp_err.c
+++ b/extra/comp_err.c
@@ -37,6 +37,7 @@
#define HEADER_LENGTH 32 /* Length of header in errmsg.sys */
#define DEFAULT_CHARSET_DIR "../sql/share/charsets"
#define ER_PREFIX "ER_"
+#define ER_PREFIX2 "MARIA_ER_"
#define WARN_PREFIX "WARN_"
static char *OUTFILE= (char*) "errmsg.sys";
static char *HEADERFILE= (char*) "mysqld_error.h";
@@ -60,7 +61,7 @@ const char *empty_string= ""; /* For empty states */
*/
const char *default_language= "eng";
-int er_offset= 1000;
+uint er_offset= 1000;
my_bool info_flag= 0;
/* Storage of one error message row (for one language) */
@@ -88,7 +89,7 @@ struct languages
struct errors
{
const char *er_name; /* Name of the error (ER_HASHCK) */
- int d_code; /* Error code number */
+ uint d_code; /* Error code number */
const char *sql_code1; /* sql state */
const char *sql_code2; /* ODBC state */
struct errors *next_error; /* Pointer to next error */
@@ -130,6 +131,7 @@ static struct my_option my_long_options[]=
};
+static struct errors *generate_empty_message(uint dcode);
static struct languages *parse_charset_string(char *str);
static struct errors *parse_error_string(char *ptr, int er_count);
static struct message *parse_message_string(struct message *new_message,
@@ -206,6 +208,7 @@ static int create_header_files(struct errors *error_head)
uint er_last;
FILE *er_definef, *sql_statef, *er_namef;
struct errors *tmp_error;
+ uint current_d_code;
DBUG_ENTER("create_header_files");
LINT_INIT(er_last);
@@ -231,13 +234,22 @@ static int create_header_files(struct errors *error_head)
fprintf(er_definef, "#define ER_ERROR_FIRST %d\n", error_head->d_code);
+ current_d_code= error_head->d_code -1;
for (tmp_error= error_head; tmp_error; tmp_error= tmp_error->next_error)
{
/*
generating mysqld_error.h
fprintf() will automatically add \r on windows
*/
- fprintf(er_definef, "#define %s %d\n", tmp_error->er_name,
+
+ if (!tmp_error->er_name)
+ continue; /* Placeholder for gap */
+
+ if (tmp_error->d_code > current_d_code + 1)
+ fprintf(er_definef, "\n/* New section */\n\n");
+ current_d_code= tmp_error->d_code;
+
+ fprintf(er_definef, "#define %s %u\n", tmp_error->er_name,
tmp_error->d_code);
er_last= tmp_error->d_code;
@@ -393,7 +405,7 @@ static void clean_up(struct languages *lang_head, struct errors *error_head)
my_free((uchar*) tmp_error->sql_code1, MYF(0));
if (tmp_error->sql_code2[0])
my_free((uchar*) tmp_error->sql_code2, MYF(0));
- my_free((uchar*) tmp_error->er_name, MYF(0));
+ my_free((uchar*) tmp_error->er_name, MYF(MY_ALLOW_ZERO_PTR));
my_free((uchar*) tmp_error, MYF(0));
}
}
@@ -406,7 +418,8 @@ static int parse_input_file(const char *file_name, struct errors **top_error,
char *str, buff[1000];
struct errors *current_error= 0, **tail_error= top_error;
struct message current_message;
- int rcount= 0;
+ uint rcount= 0;
+ my_bool er_offset_found= 0;
DBUG_ENTER("parse_input_file");
*top_error= 0;
@@ -427,11 +440,32 @@ static int parse_input_file(const char *file_name, struct errors **top_error,
}
if (is_prefix(str, "start-error-number"))
{
- if (!(er_offset= parse_error_offset(str)))
+ uint tmp_er_offset;
+ if (!(tmp_er_offset= parse_error_offset(str)))
{
fprintf(stderr, "Failed to parse the error offset string!\n");
DBUG_RETURN(0);
}
+ if (!er_offset_found)
+ {
+ er_offset_found= 1;
+ er_offset= tmp_er_offset;
+ }
+ else
+ {
+ /* Create empty error messages between er_offset and tmp_err_offset */
+ if (tmp_er_offset < er_offset + rcount)
+ {
+ fprintf(stderr, "new start-error-number %u is smaller than current error message: %u\n", tmp_er_offset, er_offset + rcount);
+ DBUG_RETURN(0);
+ }
+ for ( ; er_offset + rcount < tmp_er_offset ; rcount++)
+ {
+ current_error= generate_empty_message(er_offset + rcount);
+ *tail_error= current_error;
+ tail_error= &current_error->next_error;
+ }
+ }
continue;
}
if (is_prefix(str, "default-language"))
@@ -478,7 +512,8 @@ static int parse_input_file(const char *file_name, struct errors **top_error,
DBUG_RETURN(0);
continue;
}
- if (is_prefix(str, ER_PREFIX) || is_prefix(str, WARN_PREFIX))
+ if (is_prefix(str, ER_PREFIX) || is_prefix(str, WARN_PREFIX) ||
+ is_prefix(str, ER_PREFIX2))
{
if (!(current_error= parse_error_string(str, rcount)))
{
@@ -493,12 +528,12 @@ static int parse_input_file(const char *file_name, struct errors **top_error,
continue;
}
if (*str == '#' || *str == '\n')
- continue; /* skip comment or empty lines */
+ continue; /* skip comment or empty lines */
fprintf(stderr, "Wrong input file format. Stop!\nLine: %s\n", str);
DBUG_RETURN(0);
}
- *tail_error= 0; /* Mark end of list */
+ *tail_error= 0; /* Mark end of list */
my_fclose(file, MYF(0));
DBUG_RETURN(rcount);
@@ -607,7 +642,6 @@ static struct message *find_message(struct errors *err, const char *lang,
DBUG_RETURN(tmp);
if (!strcmp(tmp->lang_short_name, default_language))
{
- DBUG_ASSERT(tmp->text[0] != 0);
return_val= tmp;
}
}
@@ -827,6 +861,33 @@ static struct message *parse_message_string(struct message *new_message,
}
+static struct errors *generate_empty_message(uint d_code)
+{
+ struct errors *new_error;
+ struct message message;
+
+ /* create a new element */
+ if (!(new_error= (struct errors *) my_malloc(sizeof(*new_error),
+ MYF(MY_WME))))
+ return(0);
+ if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 1))
+ return(0); /* OOM: Fatal error */
+
+ new_error->er_name= NULL;
+ new_error->d_code= d_code;
+ new_error->sql_code1= empty_string;
+ new_error->sql_code2= empty_string;
+
+ if (!(message.lang_short_name= my_strdup(default_language, MYF(MY_WME))) ||
+ !(message.text= my_strdup("", MYF(MY_WME))))
+ return(0);
+
+ /* Can't fail as msg is preallocated */
+ (void) insert_dynamic(&new_error->msg, (uchar*) &message);
+ return(new_error);
+}
+
+
/*
Parsing the string with error name and codes; returns the pointer to
the errors struct
@@ -839,7 +900,9 @@ static struct errors *parse_error_string(char *str, int er_count)
DBUG_PRINT("enter", ("str: %s", str));
/* create a new element */
- new_error= (struct errors *) my_malloc(sizeof(*new_error), MYF(MY_WME));
+ if (!(new_error= (struct errors *) my_malloc(sizeof(*new_error),
+ MYF(MY_WME))))
+ DBUG_RETURN(0);
if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 0))
DBUG_RETURN(0); /* OOM: Fatal error */
@@ -969,7 +1032,7 @@ static struct languages *parse_charset_string(char *str)
static void print_version(void)
{
DBUG_ENTER("print_version");
- printf("%s (Compile errormessage) Ver %s\n", my_progname, "2.0");
+ printf("%s (Compile errormessage) Ver %s\n", my_progname, "3.0");
DBUG_VOID_RETURN;
}
diff --git a/include/Makefile.am b/include/Makefile.am
index 67ffef3e714..793c73718bd 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -22,6 +22,7 @@ HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \
my_list.h my_alloc.h typelib.h mysql/plugin.h
pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
my_xml.h mysql_embed.h mysql/services.h \
+ mysql/service_progress_report.h \
mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
my_pthread.h my_no_pthread.h \
mysql/plugin_auth.h mysql/client_plugin.h \
@@ -30,10 +31,12 @@ pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
my_getopt.h sslopt-longopts.h my_dir.h \
sslopt-vars.h sslopt-case.h sql_common.h keycache.h \
m_ctype.h my_attribute.h my_compiler.h \
+ my_decimal_limits.h ma_dyncol.h \
$(HEADERS_GEN_CONFIGURE) \
$(HEADERS_GEN_MAKE)
-noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \
+internalincludedir = $(pkgincludedir)/private
+internalinclude_HEADERS = config-win.h config-netware.h lf.h my_bit.h \
heap.h maria.h myisamchk.h my_bitmap.h my_uctype.h \
myisam.h myisampack.h myisammrg.h ft_global.h\
mysys_err.h my_base.h help_start.h help_end.h \
@@ -42,13 +45,16 @@ noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \
thr_lock.h t_ctype.h violite.h my_md5.h base64.h \
service_versions.h \
my_compare.h my_handler.h my_time.h \
- my_vle.h my_user.h my_atomic.h atomic/nolock.h \
- atomic/rwlock.h atomic/x86-gcc.h \
- atomic/generic-msvc.h \
- atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \
+ my_vle.h my_user.h my_atomic.h my_libwrap.h my_stacktrace.h \
wqueue.h waiting_threads.h \
welcome_copyright_notice.h
+atomicincludedir = $(internalincludedir)/atomic
+atomicinclude_HEADERS = atomic/nolock.h \
+ atomic/rwlock.h atomic/x86-gcc.h \
+ atomic/generic-msvc.h \
+ atomic/gcc_builtins.h
+
EXTRA_DIST = mysql.h.pp mysql/plugin_auth.h.pp mysql/client_plugin.h.pp CMakeLists.txt
# Remove built files and the symlinked directories
diff --git a/include/config-netware.h b/include/config-netware.h
index 4759d144040..e231d068c29 100644
--- a/include/config-netware.h
+++ b/include/config-netware.h
@@ -59,6 +59,7 @@ extern "C" {
#undef HAVE_RWLOCK_INIT
#undef HAVE_SCHED_H
#undef HAVE_SYS_MMAN_H
+#undef HAVE_SYS_UN_H
#undef HAVE_SYNCH_H
#undef HAVE_MMAP
#undef HAVE_RINT
diff --git a/include/config-win.h b/include/config-win.h
index 86fcc61aa9b..da93251ec90 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -68,7 +68,6 @@
#endif
/* File and lock constants */
-#define O_SHARE 0x1000 /* Open file in sharing mode */
#ifdef __BORLANDC__
#define F_RDLCK LK_NBLCK /* read lock */
#define F_WRLCK LK_NBRLCK /* write lock */
@@ -332,10 +331,9 @@ inline ulonglong double2ulonglong(double d)
#define FILE_SHARE_DELETE 0 /* Not implemented on Win 98/ME */
#endif
-#ifdef NOT_USED
-#define HAVE_SNPRINTF /* Gave link error */
-#define _snprintf snprintf
-#endif
+
+#define HAVE_SNPRINTF
+#define snprintf _snprintf
#ifdef _MSC_VER
#define HAVE_LDIV /* The optimizer breaks in zortech for ldiv */
@@ -376,7 +374,7 @@ inline ulonglong double2ulonglong(double d)
#define FN_DEVCHAR ':'
#define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */
#define FN_NO_CASE_SENCE /* Files are not case-sensitive */
-#define OS_FILE_LIMIT 2048
+#define OS_FILE_LIMIT UINT_MAX
#define DO_NOT_REMOVE_THREAD_WRAPPERS
#define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V))
diff --git a/include/decimal.h b/include/decimal.h
index 09ff879fa03..5e3fea9f912 100644
--- a/include/decimal.h
+++ b/include/decimal.h
@@ -38,17 +38,17 @@ typedef struct st_decimal_t {
int internal_str2dec(const char *from, decimal_t *to, char **end,
my_bool fixed);
-int decimal2string(decimal_t *from, char *to, int *to_len,
+int decimal2string(const decimal_t *from, char *to, int *to_len,
int fixed_precision, int fixed_decimals,
char filler);
-int decimal2ulonglong(decimal_t *from, ulonglong *to);
+int decimal2ulonglong(const decimal_t *from, ulonglong *to);
int ulonglong2decimal(ulonglong from, decimal_t *to);
-int decimal2longlong(decimal_t *from, longlong *to);
+int decimal2longlong(const decimal_t *from, longlong *to);
int longlong2decimal(longlong from, decimal_t *to);
-int decimal2double(decimal_t *from, double *to);
+int decimal2double(const decimal_t *from, double *to);
int double2decimal(double from, decimal_t *to);
int decimal_actual_fraction(decimal_t *from);
-int decimal2bin(decimal_t *from, uchar *to, int precision, int scale);
+int decimal2bin(const decimal_t *from, uchar *to, int precision, int scale);
int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale);
int decimal_size(int precision, int scale);
@@ -64,7 +64,7 @@ int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to);
int decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to,
int scale_incr);
int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to);
-int decimal_round(decimal_t *from, decimal_t *to, int new_scale,
+int decimal_round(const decimal_t *from, decimal_t *to, int new_scale,
decimal_round_mode mode);
int decimal_is_zero(decimal_t *from);
void max_decimal(int precision, int frac, decimal_t *to);
diff --git a/include/heap.h b/include/heap.h
index b41f1a2519c..d0566919404 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -137,6 +137,8 @@ typedef struct st_heap_share
ulong min_records,max_records; /* Params to open */
ulonglong data_length,index_length,max_table_size;
uint key_stat_version; /* version to indicate insert/delete */
+ uint key_version; /* Updated on key change */
+ uint file_version; /* Update on clear */
uint records; /* records */
uint blength; /* records rounded up to 2^n */
uint deleted; /* Deleted records in database */
@@ -175,6 +177,8 @@ typedef struct st_heap_info
enum ha_rkey_function last_find_flag;
TREE_ELEMENT *parents[MAX_TREE_HEIGHT+1];
TREE_ELEMENT **last_pos;
+ uint key_version; /* Version at last read */
+ uint file_version; /* Version at scan */
uint lastkey_len;
my_bool implicit_emptied;
#ifdef THREAD
diff --git a/include/m_ctype.h b/include/m_ctype.h
index 31dbfd2b476..8badfb53c15 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -151,7 +151,8 @@ enum my_lex_states
MY_LEX_USER_VARIABLE_DELIMITER, MY_LEX_SYSTEM_VAR,
MY_LEX_IDENT_OR_KEYWORD,
MY_LEX_IDENT_OR_HEX, MY_LEX_IDENT_OR_BIN, MY_LEX_IDENT_OR_NCHAR,
- MY_LEX_STRING_OR_DELIMITER
+ MY_LEX_STRING_OR_DELIMITER, MY_LEX_MINUS_OR_COMMENT, MY_LEX_PLACEHOLDER,
+ MY_LEX_COMMA
};
struct charset_info_st;
@@ -362,6 +363,9 @@ extern int my_strnncollsp_simple(CHARSET_INFO *, const uchar *, size_t,
extern void my_hash_sort_simple(CHARSET_INFO *cs,
const uchar *key, size_t len,
ulong *nr1, ulong *nr2);
+extern void my_hash_sort_bin(CHARSET_INFO *cs,
+ const uchar *key, size_t len, ulong *nr1,
+ ulong *nr2);
extern size_t my_lengthsp_8bit(CHARSET_INFO *cs, const char *ptr, size_t length);
diff --git a/include/m_string.h b/include/m_string.h
index 13bdbf32f47..1b32d9df0c1 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -236,7 +236,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/ma_dyncol.h b/include/ma_dyncol.h
new file mode 100644
index 00000000000..6174328d62a
--- /dev/null
+++ b/include/ma_dyncol.h
@@ -0,0 +1,147 @@
+/* Copyright (c) 2011, Monty Program Ab
+ Copyright (c) 2011, Oleksandr Byelkin
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``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> OR
+ CONTRIBUTORS 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.
+*/
+
+#ifndef ma_dyncol_h
+#define ma_dyncol_h
+
+#include <decimal.h>
+#include <my_decimal_limits.h>
+#include <mysql_time.h>
+
+/*
+ Max length for data in a dynamic colums. This comes from how the
+ how the offset are stored.
+*/
+#define MAX_DYNAMIC_COLUMN_LENGTH 0X1FFFFFFFL
+
+/* NO and OK is the same used just to show semantics */
+#define ER_DYNCOL_NO ER_DYNCOL_OK
+
+enum enum_dyncol_func_result
+{
+ ER_DYNCOL_OK= 0,
+ ER_DYNCOL_YES= 1, /* For functions returning 0/1 */
+ ER_DYNCOL_FORMAT= -1, /* Wrong format of the encoded string */
+ ER_DYNCOL_LIMIT= -2, /* Some limit reached */
+ ER_DYNCOL_RESOURCE= -3, /* Out of resourses */
+ ER_DYNCOL_DATA= -4, /* Incorrect input data */
+ ER_DYNCOL_UNKNOWN_CHARSET= -5 /* Unknown character set */
+};
+
+typedef DYNAMIC_STRING DYNAMIC_COLUMN;
+
+enum enum_dynamic_column_type
+{
+ DYN_COL_NULL= 0,
+ DYN_COL_INT,
+ DYN_COL_UINT,
+ DYN_COL_DOUBLE,
+ DYN_COL_STRING,
+ DYN_COL_DECIMAL,
+ DYN_COL_DATETIME,
+ DYN_COL_DATE,
+ DYN_COL_TIME
+};
+
+typedef enum enum_dynamic_column_type DYNAMIC_COLUMN_TYPE;
+
+struct st_dynamic_column_value
+{
+ DYNAMIC_COLUMN_TYPE type;
+ union
+ {
+ long long long_value;
+ unsigned long long ulong_value;
+ double double_value;
+ struct {
+ LEX_STRING value;
+ CHARSET_INFO *charset;
+ } string;
+ struct {
+ decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
+ decimal_t value;
+ } decimal;
+ MYSQL_TIME time_value;
+ } x;
+};
+
+typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE;
+
+enum enum_dyncol_func_result
+dynamic_column_create(DYNAMIC_COLUMN *str,
+ uint column_nr, DYNAMIC_COLUMN_VALUE *value);
+
+enum enum_dyncol_func_result
+dynamic_column_create_many(DYNAMIC_COLUMN *str,
+ uint column_count,
+ uint *column_numbers,
+ DYNAMIC_COLUMN_VALUE *values);
+
+enum enum_dyncol_func_result
+dynamic_column_update(DYNAMIC_COLUMN *org, uint column_nr,
+ DYNAMIC_COLUMN_VALUE *value);
+enum enum_dyncol_func_result
+dynamic_column_update_many(DYNAMIC_COLUMN *str,
+ uint add_column_count,
+ uint *column_numbers,
+ DYNAMIC_COLUMN_VALUE *values);
+
+enum enum_dyncol_func_result
+dynamic_column_delete(DYNAMIC_COLUMN *org, uint column_nr);
+
+enum enum_dyncol_func_result
+dynamic_column_exists(DYNAMIC_COLUMN *org, uint column_nr);
+
+/* List of not NULL columns */
+enum enum_dyncol_func_result
+dynamic_column_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint);
+
+/*
+ if the column do not exists it is NULL
+*/
+enum enum_dyncol_func_result
+dynamic_column_get(DYNAMIC_COLUMN *org, uint column_nr,
+ DYNAMIC_COLUMN_VALUE *store_it_here);
+
+#define dynamic_column_initialize(A) memset((A), 0, sizeof(*(A)))
+#define dynamic_column_column_free(V) dynstr_free(V)
+
+/***************************************************************************
+ Internal functions, don't use if you don't know what you are doing...
+***************************************************************************/
+
+#define dynamic_column_reassociate(V,P,L, A) dynstr_reassociate((V),(P),(L),(A))
+
+#define dynamic_column_value_init(V) (V)->type= DYN_COL_NULL
+
+/*
+ Prepare value for using as decimal
+*/
+void dynamic_column_prepare_decimal(DYNAMIC_COLUMN_VALUE *value);
+
+#endif
diff --git a/include/maria.h b/include/maria.h
index 328cb491bca..0844e3f58c4 100644
--- a/include/maria.h
+++ b/include/maria.h
@@ -24,7 +24,6 @@ extern "C" {
#include <my_base.h>
#include <my_sys.h>
#include <m_ctype.h>
-#include "../storage/maria/ma_pagecache.h"
#include "my_handler.h"
#include "my_compare.h"
#include "ft_global.h"
@@ -271,7 +270,6 @@ extern my_bool maria_flush, maria_single_user, maria_page_checksums;
extern my_bool maria_delay_key_write;
extern my_off_t maria_max_temp_length;
extern ulong maria_bulk_insert_tree_size, maria_data_pointer_size;
-extern PAGECACHE maria_pagecache_var, *maria_pagecache;
extern MY_TMPDIR *maria_tmpdir;
/*
This is used to check if a symlink points into the mysql data home,
@@ -356,71 +354,6 @@ typedef struct st_maria_bit_buff
uint error;
} MARIA_BIT_BUFF;
-
-typedef struct st_maria_sort_info
-{
-#ifdef THREAD
- /* sync things */
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-#endif
- MARIA_HA *info, *new_info;
- HA_CHECK *param;
- char *buff;
- SORT_KEY_BLOCKS *key_block, *key_block_end;
- SORT_FT_BUF *ft_buf;
- my_off_t filelength, dupp, buff_length;
- pgcache_page_no_t page;
- ha_rows max_records;
- uint current_key, total_keys;
- uint got_error, threads_running;
- myf myf_rw;
- enum data_file_type new_data_file_type, org_data_file_type;
-} MARIA_SORT_INFO;
-
-typedef struct st_maria_sort_param
-{
- pthread_t thr;
- IO_CACHE read_cache, tempfile, tempfile_for_exceptions;
- DYNAMIC_ARRAY buffpek;
- MARIA_BIT_BUFF bit_buff; /* For parallel repair of packrec. */
-
- MARIA_KEYDEF *keyinfo;
- MARIA_SORT_INFO *sort_info;
- HA_KEYSEG *seg;
- uchar **sort_keys;
- uchar *rec_buff;
- void *wordlist, *wordptr;
- MEM_ROOT wordroot;
- uchar *record;
- MY_TMPDIR *tmpdir;
-
- /*
- The next two are used to collect statistics, see maria_update_key_parts for
- description.
- */
- ulonglong unique[HA_MAX_KEY_SEG+1];
- ulonglong notnull[HA_MAX_KEY_SEG+1];
-
- MARIA_RECORD_POS pos,max_pos,filepos,start_recpos, current_filepos;
- uint key, key_length,real_key_length,sortbuff_size;
- uint maxbuffers, keys, find_length, sort_keys_length;
- my_bool fix_datafile, master;
- my_bool calc_checksum; /* calculate table checksum */
- size_t rec_buff_size;
-
- int (*key_cmp)(struct st_maria_sort_param *, const void *, const void *);
- int (*key_read)(struct st_maria_sort_param *, uchar *);
- int (*key_write)(struct st_maria_sort_param *, const uchar *);
- void (*lock_in_memory)(HA_CHECK *);
- int (*write_keys)(struct st_maria_sort_param *, register uchar **,
- uint , struct st_buffpek *, IO_CACHE *);
- uint (*read_to_buffer)(IO_CACHE *,struct st_buffpek *, uint);
- int (*write_key)(struct st_maria_sort_param *, IO_CACHE *,uchar *,
- uint, uint);
-} MARIA_SORT_PARAM;
-
-
/* functions in maria_check */
void maria_chk_init(HA_CHECK *param);
void maria_chk_init_for_check(HA_CHECK *param, MARIA_HA *info);
@@ -448,7 +381,6 @@ int maria_filecopy(HA_CHECK *param, File to, File from, my_off_t start,
my_off_t length, const char *type);
int maria_movepoint(MARIA_HA *info, uchar *record, my_off_t oldpos,
my_off_t newpos, uint prot_key);
-int maria_write_data_suffix(MARIA_SORT_INFO *sort_info, my_bool fix_datafile);
int maria_test_if_almost_full(MARIA_HA *info);
int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename);
int maria_disable_indexes(MARIA_HA *info);
@@ -461,13 +393,11 @@ my_bool maria_test_if_sort_rep(MARIA_HA *info, ha_rows rows, ulonglong key_map,
int maria_init_bulk_insert(MARIA_HA *info, ulong cache_size, ha_rows rows);
void maria_flush_bulk_insert(MARIA_HA *info, uint inx);
void maria_end_bulk_insert(MARIA_HA *info);
-int maria_assign_to_pagecache(MARIA_HA *info, ulonglong key_map,
- PAGECACHE *key_cache);
-void maria_change_pagecache(PAGECACHE *old_key_cache,
- PAGECACHE *new_key_cache);
int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves);
void maria_versioning(MARIA_HA *info, my_bool versioning);
void maria_ignore_trids(MARIA_HA *info);
+uint maria_max_key_length(void);
+#define maria_max_key_segments() HA_MAX_KEY_SEG
/* fulltext functions */
FT_INFO *maria_ft_init_search(uint,void *, uint, uchar *, size_t,
diff --git a/include/my_base.h b/include/my_base.h
index 6d58cf8071a..e33a9fbcfb8 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -54,6 +54,7 @@
/* Internal temp table, used for temporary results */
#define HA_OPEN_INTERNAL_TABLE 512
#define HA_OPEN_MERGE_TABLE 1024
+#define HA_OPEN_FOR_STATUS 2048
/* The following is parameter to ha_rkey() how to use key */
@@ -447,7 +448,8 @@ enum ha_base_keytype {
#define HA_ERR_FILE_TOO_SHORT 175 /* File too short */
#define HA_ERR_WRONG_CRC 176 /* Wrong CRC on page */
#define HA_ERR_TOO_MANY_CONCURRENT_TRXS 177 /*Too many active concurrent transactions */
-
+#define HA_ERR_ABORTED_BY_USER 178
+#define HA_ERR_DISK_FULL 179
#define HA_ERR_ROW_NOT_VISIBLE 180 /*Too many active concurrent transactions */
#define HA_ERR_TABLE_IN_FK_CHECK 181 /* Table being used in foreign key check */
#define HA_ERR_LAST 181 /* Copy of last error nr */
@@ -524,7 +526,7 @@ enum en_fieldtype {
};
enum data_file_type {
- STATIC_RECORD, DYNAMIC_RECORD, COMPRESSED_RECORD, BLOCK_RECORD
+ STATIC_RECORD, DYNAMIC_RECORD, COMPRESSED_RECORD, BLOCK_RECORD, NO_RECORD
};
/* For key ranges */
@@ -547,11 +549,13 @@ typedef struct st_key_range
enum ha_rkey_function flag;
} key_range;
+typedef void *range_id_t;
+
typedef struct st_key_multi_range
{
key_range start_key;
key_range end_key;
- char *ptr; /* Free to use by caller (ptr to row etc) */
+ range_id_t ptr; /* Free to use by caller (ptr to row etc) */
uint range_flag; /* key range flags see above */
} KEY_MULTI_RANGE;
diff --git a/include/my_bitmap.h b/include/my_bitmap.h
index a98dd58bd72..99dcdafb784 100644
--- a/include/my_bitmap.h
+++ b/include/my_bitmap.h
@@ -57,6 +57,10 @@ extern my_bool bitmap_test_and_clear(MY_BITMAP *map, uint bitmap_bit);
extern my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit);
extern my_bool bitmap_union_is_set_all(const MY_BITMAP *map1,
const MY_BITMAP *map2);
+extern my_bool bitmap_exists_intersection(const MY_BITMAP **bitmap_array,
+ uint bitmap_count,
+ uint start_bit, uint end_bit);
+
extern uint bitmap_set_next(MY_BITMAP *map);
extern uint bitmap_get_first(const MY_BITMAP *map);
extern uint bitmap_get_first_set(const MY_BITMAP *map);
diff --git a/include/my_compare.h b/include/my_compare.h
index fc607a5b6c6..058d6b6d94a 100644
--- a/include/my_compare.h
+++ b/include/my_compare.h
@@ -92,6 +92,32 @@ extern int ha_key_cmp(register HA_KEYSEG *keyseg, register const uchar *a,
uint32 nextflag, uint *diff_pos);
extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, const uchar *a);
+/**
+ 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).
+ 3=ICP_ABORTED_BY_USER - engine must stop scanning and should return
+ HA_ERR_ABORTED_BY_USER right away
+ -1= ICP_ERROR - Reserved for internal errors in engines. Should not be
+ returned by index_cond_func_xxx
+*/
+
+typedef enum icp_result {
+ ICP_ERROR=-1,
+ ICP_NO_MATCH=0,
+ ICP_MATCH=1,
+ ICP_OUT_OF_RANGE=2,
+ ICP_ABORTED_BY_USER=3,
+} ICP_RESULT;
+
+
#ifdef __cplusplus
}
#endif
diff --git a/include/my_decimal_limits.h b/include/my_decimal_limits.h
new file mode 100644
index 00000000000..ecc544dc164
--- /dev/null
+++ b/include/my_decimal_limits.h
@@ -0,0 +1,31 @@
+#ifndef my_decimal_limits_h
+#define my_decimal_limits_h
+
+#define DECIMAL_LONGLONG_DIGITS 22
+#define DECIMAL_LONG_DIGITS 10
+#define DECIMAL_LONG3_DIGITS 8
+
+/** maximum length of buffer in our big digits (uint32). */
+#define DECIMAL_BUFF_LENGTH 9
+
+/* the number of digits that my_decimal can possibly contain */
+#define DECIMAL_MAX_POSSIBLE_PRECISION (DECIMAL_BUFF_LENGTH * 9)
+
+
+/**
+ maximum guaranteed precision of number in decimal digits (number of our
+ digits * number of decimal digits in one our big digit - number of decimal
+ digits in one our big digit decreased by 1 (because we always put decimal
+ point on the border of our big digits))
+*/
+#define DECIMAL_MAX_PRECISION (DECIMAL_MAX_POSSIBLE_PRECISION - 8*2)
+#define DECIMAL_MAX_SCALE 30
+#define DECIMAL_NOT_SPECIFIED 31
+
+/**
+ maximum length of string representation (number of maximum decimal
+ digits + 1 position for sign + 1 position for decimal point, no terminator)
+*/
+#define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2)
+
+#endif
diff --git a/include/my_dir.h b/include/my_dir.h
index 06509a3af19..90d708ac811 100644
--- a/include/my_dir.h
+++ b/include/my_dir.h
@@ -69,7 +69,11 @@ typedef struct my_stat
#else
+#if(_MSC_VER)
+#define MY_STAT struct _stati64 /* 64 bit file size */
+#else
#define MY_STAT struct stat /* Orginal struct have what we need */
+#endif
#endif /* USE_MY_STAT_STRUCT */
diff --git a/include/my_global.h b/include/my_global.h
index 105a346a69f..da6c918ff4d 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -41,6 +41,8 @@
#undef __WIN__
#undef __WIN32__
#define HAVE_ERRNO_AS_DEFINE
+#define _POSIX_MONOTONIC_CLOCK
+#define _POSIX_THREAD_CPUTIME
#endif /* __CYGWIN__ */
#if defined(__QNXNTO__) && !defined(FD_SETSIZE)
@@ -790,7 +792,41 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define FN_DIRSEP "/" /* Valid directory separators */
#define FN_ROOTDIR "/"
#endif
-#define MY_NFILE 64 /* This is only used to save filenames */
+
+/*
+ MY_FILE_MIN is Windows speciality and is used to quickly detect
+ the mismatch of CRT and mysys file IO usage on Windows at runtime.
+ CRT file descriptors can be in the range 0-2047, whereas descriptors returned
+ by my_open() will start with 2048. If a file descriptor with value less then
+ MY_FILE_MIN is passed to mysys IO function, chances are it stemms from
+ open()/fileno() and not my_open()/my_fileno.
+
+ For Posix, mysys functions are light wrappers around libc, and MY_FILE_MIN
+ is logically 0.
+*/
+
+#ifdef _WIN32
+#define MY_FILE_MIN 2048
+#else
+#define MY_FILE_MIN 0
+#endif
+
+/*
+ MY_NFILE is the default size of my_file_info array.
+
+ It is larger on Windows, because it all file handles are stored in my_file_info
+ Default size is 16384 and this should be enough for most cases.If it is not
+ enough, --max-open-files with larger value can be used.
+
+ For Posix , my_file_info array is only used to store filenames for
+ error reporting and its size is not a limitation for number of open files.
+*/
+#ifdef _WIN32
+#define MY_NFILE (16384 + MY_FILE_MIN)
+#else
+#define MY_NFILE 64
+#endif
+
#ifndef OS_FILE_LIMIT
#define OS_FILE_LIMIT UINT_MAX
#endif
@@ -827,9 +863,8 @@ typedef SOCKET_SIZE_TYPE size_socket;
/* Some things that this system doesn't have */
#define NO_HASH /* Not needed anymore */
-#ifdef __WIN__
-#define NO_DIR_LIBRARY /* Not standar dir-library */
-#define USE_MY_STAT_STRUCT /* For my_lib */
+#ifdef _WIN32
+#define NO_DIR_LIBRARY /* Not standard dir-library */
#endif
/* Some defines of functions for portability */
@@ -860,10 +895,10 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define strtok_r(A,B,C) strtok((A),(B))
#endif
-/* This is from the old m-machine.h file */
-
-#if SIZEOF_LONG_LONG > 4
+#if SIZEOF_LONG_LONG >= 8
#define HAVE_LONG_LONG 1
+#else
+#error WHAT? sizeof(long long) < 8 ???
#endif
/*
diff --git a/include/my_pthread.h b/include/my_pthread.h
index fffb883912a..7057f90a89a 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -48,19 +48,30 @@ typedef struct st_pthread_link {
struct st_pthread_link *next;
} pthread_link;
-typedef struct {
- uint32 waiting;
- CRITICAL_SECTION lock_waiting;
-
- enum {
- SIGNAL= 0,
- BROADCAST= 1,
- MAX_EVENTS= 2
- } EVENTS;
-
- HANDLE events[MAX_EVENTS];
- HANDLE broadcast_block_event;
-
+/**
+ Implementation of Windows condition variables.
+ We use native conditions on Vista and later, and fallback to own
+ implementation on earlier OS version.
+*/
+typedef union
+{
+ /* Native condition (used on Vista and later) */
+ CONDITION_VARIABLE native_cond;
+
+ /* Own implementation (used on XP) */
+ struct
+ {
+ uint32 waiting;
+ CRITICAL_SECTION lock_waiting;
+ enum
+ {
+ SIGNAL= 0,
+ BROADCAST= 1,
+ MAX_EVENTS= 2
+ } EVENTS;
+ HANDLE events[MAX_EVENTS];
+ HANDLE broadcast_block_event;
+ };
} pthread_cond_t;
@@ -75,37 +86,11 @@ typedef volatile LONG my_pthread_once_t;
#define MY_PTHREAD_ONCE_INPROGRESS 1
#define MY_PTHREAD_ONCE_DONE 2
-/*
- Struct and macros to be used in combination with the
- windows implementation of pthread_cond_timedwait
-*/
-
-/*
- Declare a union to make sure FILETIME is properly aligned
- so it can be used directly as a 64 bit value. The value
- stored is in 100ns units.
- */
-union ft64 {
- FILETIME ft;
- __int64 i64;
-};
-
struct timespec {
- union ft64 tv;
- /* The max timeout value in millisecond for pthread_cond_timedwait */
- long max_timeout_msec;
+ time_t tv_sec;
+ long tv_nsec;
};
-#define set_timespec_time_nsec(ABSTIME,TIME,NSEC) do { \
- (ABSTIME).tv.i64= (TIME)+(__int64)(NSEC)/100; \
- (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
-} while(0)
-
-#define set_timespec_nsec(ABSTIME,NSEC) do { \
- union ft64 tv; \
- GetSystemTimeAsFileTime(&tv.ft); \
- set_timespec_time_nsec((ABSTIME), tv.i64, (NSEC)); \
-} while(0)
void win_pthread_init(void);
int win_pthread_setspecific(void *A,void *B,uint length);
@@ -442,7 +427,7 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
#ifndef set_timespec_nsec
#define set_timespec_nsec(ABSTIME,NSEC) \
- set_timespec_time_nsec((ABSTIME),my_getsystime(),(NSEC))
+ set_timespec_time_nsec((ABSTIME), my_hrtime().val*1000 + (NSEC))
#endif /* !set_timespec_nsec */
/* adapt for two different flavors of struct timespec */
@@ -455,11 +440,10 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
#endif /* HAVE_TIMESPEC_TS_SEC */
#ifndef set_timespec_time_nsec
-#define set_timespec_time_nsec(ABSTIME,TIME,NSEC) do { \
- ulonglong nsec= (NSEC); \
- ulonglong now= (TIME) + (nsec/100); \
- (ABSTIME).MY_tv_sec= (now / ULL(10000000)); \
- (ABSTIME).MY_tv_nsec= (now % ULL(10000000) * 100 + (nsec % 100)); \
+#define set_timespec_time_nsec(ABSTIME,NSEC) do { \
+ ulonglong now= (NSEC); \
+ (ABSTIME).MY_tv_sec= (now / 1000000000ULL); \
+ (ABSTIME).MY_tv_nsec= (now % 1000000000ULL); \
} while(0)
#endif /* !set_timespec_time_nsec */
@@ -632,6 +616,45 @@ int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp);
#endif
#define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0)
#else
+#ifdef _WIN32
+/**
+ Implementation of Windows rwlock.
+
+ We use native (slim) rwlocks on Win7 and later, and fallback to portable
+ implementation on earlier Windows.
+
+ slim rwlock are also available on Vista/WS2008, but we do not use it
+ ("trylock" APIs are missing on Vista)
+*/
+typedef union
+{
+ /* Native rwlock (is_srwlock == TRUE) */
+ struct
+ {
+ SRWLOCK srwlock; /* native reader writer lock */
+ BOOL have_exclusive_srwlock; /* used for unlock */
+ };
+
+ /*
+ Portable implementation (is_srwlock == FALSE)
+ Fields are identical with Unix my_rw_lock_t fields.
+ */
+ struct
+ {
+ pthread_mutex_t lock; /* lock for structure */
+ pthread_cond_t readers; /* waiting readers */
+ pthread_cond_t writers; /* waiting writers */
+ int state; /* -1:writer,0:free,>0:readers */
+ int waiters; /* number of waiting writers */
+#ifdef SAFE_MUTEX
+ pthread_t write_thread;
+#endif
+ };
+} my_rw_lock_t;
+
+
+#else /* _WIN32 */
+
/* Use our own version of read/write locks */
typedef struct _my_rw_lock_t {
pthread_mutex_t lock; /* lock for structure */
@@ -641,6 +664,8 @@ typedef struct _my_rw_lock_t {
int waiters; /* number of waiting writers */
} my_rw_lock_t;
+#endif /* _WIN32 */
+
#define rw_lock_t my_rw_lock_t
#define rw_rdlock(A) my_rw_rdlock((A))
#define rw_wrlock(A) my_rw_wrlock((A))
diff --git a/include/my_sys.h b/include/my_sys.h
index 0c1ea1ae2d1..ebe643abce5 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -70,6 +70,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_THREADSAFE 2048 /* my_seek(): lock fd mutex */
#define MY_SYNC 4096 /* my_copy(): sync dst file */
#define MY_SYNC_DIR 32768 /* my_create/delete/rename: sync directory */
+#define MY_SYNC_FILESIZE 65536 /* my_sync(): safe sync when file is extended */
#define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */
#define MY_GIVE_INFO 2 /* Give time info about process*/
@@ -343,11 +344,12 @@ enum file_type
struct st_my_file_info
{
- char * name;
- enum file_type type;
-#if defined(THREAD) && !defined(HAVE_PREAD)
- pthread_mutex_t mutex;
+ char *name;
+#ifdef _WIN32
+ HANDLE fhandle; /* win32 file handle */
+ int oflag; /* open flags, e.g O_APPEND */
#endif
+ enum file_type type;
};
extern struct st_my_file_info *my_file_info;
@@ -562,6 +564,8 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *);
#define my_b_tell(info) ((info)->pos_in_file + \
(size_t) (*(info)->current_pos - (info)->request_pos))
+#define my_b_write_tell(info) ((info)->pos_in_file + \
+ ((info)->write_pos - (info)->write_buffer))
#define my_b_get_buffer_start(info) (info)->request_pos
#define my_b_get_bytes_in_buffer(info) (char*) (info)->read_end - \
@@ -651,12 +655,12 @@ extern void *my_memmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen);
-#ifdef __WIN__
-extern int my_access(const char *path, int amode);
-extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
+#ifdef _WIN32
+extern int my_access(const char *path, int amode);
#else
#define my_access access
#endif
+
extern int check_if_legal_filename(const char *path);
extern int check_if_legal_tablename(const char *path);
@@ -667,6 +671,13 @@ extern int nt_share_delete(const char *name,myf MyFlags);
#define my_delete_allow_opened(fname,flags) my_delete((fname),(flags))
#endif
+#ifdef _WIN32
+/* Windows-only functions (CRT equivalents)*/
+extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
+extern HANDLE my_get_osfhandle(File fd);
+extern void my_osmaperr(unsigned long last_error);
+#endif
+
#ifndef TERMINATE
extern void TERMINATE(FILE *file, uint flag);
#endif
@@ -677,6 +688,7 @@ extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
extern FILE *my_freopen(const char *path, const char *mode, FILE *stream);
extern int my_fclose(FILE *fd,myf MyFlags);
extern int my_fprintf(FILE *stream, const char* format, ...);
+extern File my_fileno(FILE *fd);
extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
extern int my_chmod(const char *name, mode_t mode, myf my_flags);
extern int my_sync(File fd, myf my_flags);
@@ -865,6 +877,8 @@ extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str);
extern my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size);
extern my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n);
extern void dynstr_free(DYNAMIC_STRING *str);
+extern void dynstr_reassociate(DYNAMIC_STRING *str, char **res, size_t *length,
+ size_t *alloc_length);
#ifdef HAVE_MLOCK
extern void *my_malloc_lock(size_t length,myf flags);
extern void my_free_lock(void *ptr,myf flags);
@@ -931,15 +945,23 @@ extern ulong crc32(ulong crc, const uchar *buf, uint len);
extern uint my_set_max_open_files(uint files);
void my_free_open_file_info(void);
-extern time_t my_time(myf flags);
-extern ulonglong my_getsystime(void);
-extern ulonglong my_getcputime(void);
-extern ulonglong my_micro_time();
-extern ulonglong my_micro_time_and_time(time_t *time_arg);
-time_t my_time_possible_from_micro(ulonglong microtime);
extern my_bool my_gethwaddr(uchar *to);
extern int my_getncpus();
+#define HRTIME_RESOLUTION 1000000ULL /* microseconds */
+typedef struct {ulonglong val;} my_hrtime_t;
+void my_time_init();
+extern my_hrtime_t my_hrtime();
+extern ulonglong my_interval_timer(void);
+extern ulonglong my_getcputime(void);
+
+#define microsecond_interval_timer() (my_interval_timer()/1000)
+#define hrtime_to_time(X) ((X).val/HRTIME_RESOLUTION)
+#define hrtime_from_time(X) ((ulonglong)((X)*HRTIME_RESOLUTION))
+#define hrtime_to_double(X) ((X).val/(double)HRTIME_RESOLUTION)
+#define hrtime_sec_part(X) ((ulong)((X).val % HRTIME_RESOLUTION))
+#define my_time(X) hrtime_to_time(my_hrtime())
+
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
diff --git a/include/my_time.h b/include/my_time.h
index 3e198d9c8e1..dbef712a038 100644
--- a/include/my_time.h
+++ b/include/my_time.h
@@ -49,7 +49,7 @@ typedef long my_time_t;
#define TIMESTAMP_MAX_YEAR 2038
#define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1)
#define TIMESTAMP_MAX_VALUE INT_MAX32
-#define TIMESTAMP_MIN_VALUE 1
+#define TIMESTAMP_MIN_VALUE 0
/* two-digit years < this are 20..; >= this are 19.. */
#define YY_PART_YEAR 70
@@ -70,6 +70,7 @@ typedef long my_time_t;
/* Flags to str_to_datetime */
#define TIME_FUZZY_DATE 1
#define TIME_DATETIME_ONLY 2
+#define TIME_TIME_ONLY 4
/* Must be same as MODE_NO_ZERO_IN_DATE */
#define TIME_NO_ZERO_IN_DATE (65536L*2*2*2*2*2*2*2)
/* Must be same as MODE_NO_ZERO_DATE */
@@ -83,28 +84,46 @@ typedef long my_time_t;
#define TIME_MAX_HOUR 838
#define TIME_MAX_MINUTE 59
#define TIME_MAX_SECOND 59
-#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + \
- TIME_MAX_SECOND)
+#define TIME_MAX_SECOND_PART 999999
+#define TIME_SECOND_PART_FACTOR (TIME_MAX_SECOND_PART+1)
+#define TIME_SECOND_PART_DIGITS 6
+#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + TIME_MAX_SECOND)
#define TIME_MAX_VALUE_SECONDS (TIME_MAX_HOUR * 3600L + \
TIME_MAX_MINUTE * 60L + TIME_MAX_SECOND)
my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
ulong flags, int *was_cut);
enum enum_mysql_timestamp_type
+str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
+ ulong flag, int *warning);
+enum enum_mysql_timestamp_type
str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
- uint flags, int *was_cut);
-longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
+ ulong flags, int *was_cut);
+longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
uint flags, int *was_cut);
+
+static inline
+longlong double_to_datetime(double nr, MYSQL_TIME *ltime, uint flags, int *cut)
+{
+ if (nr < 0 || nr > LONGLONG_MAX)
+ nr= (double)LONGLONG_MAX;
+ return number_to_datetime((longlong) floor(nr),
+ (ulong)((nr-floor(nr))*TIME_SECOND_PART_FACTOR),
+ ltime, flags, cut);
+}
+
+int number_to_time(my_bool neg, longlong nr, ulong sec_part,
+ MYSQL_TIME *ltime, int *was_cut);
ulonglong TIME_to_ulonglong_datetime(const MYSQL_TIME *);
ulonglong TIME_to_ulonglong_date(const MYSQL_TIME *);
ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *);
ulonglong TIME_to_ulonglong(const MYSQL_TIME *);
+double TIME_to_double(const MYSQL_TIME *my_time);
+longlong pack_time(MYSQL_TIME *my_time);
+MYSQL_TIME *unpack_time(longlong packed, MYSQL_TIME *my_time);
-my_bool str_to_time(const char *str,uint length, MYSQL_TIME *l_time,
- int *warning);
-
-int check_time_range(struct st_mysql_time *, int *warning);
+int check_time_range(struct st_mysql_time *my_time, uint dec, int *warning);
long calc_daynr(uint year,uint month,uint day);
uint calc_days_in_year(uint year);
@@ -137,8 +156,7 @@ static inline my_bool validate_timestamp_range(const MYSQL_TIME *t)
}
my_time_t
-my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone,
- my_bool *in_dst_time_gap);
+my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, uint *error_code);
void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type);
@@ -151,11 +169,28 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type);
sent using binary protocol fit in this buffer.
*/
#define MAX_DATE_STRING_REP_LENGTH 30
+#define AUTO_SEC_PART_DIGITS 31 /* same as NOT_FIXED_DEC */
-int my_time_to_str(const MYSQL_TIME *l_time, char *to);
+int my_time_to_str(const MYSQL_TIME *l_time, char *to, uint digits);
int my_date_to_str(const MYSQL_TIME *l_time, char *to);
-int my_datetime_to_str(const MYSQL_TIME *l_time, char *to);
-int my_TIME_to_str(const MYSQL_TIME *l_time, char *to);
+int my_datetime_to_str(const MYSQL_TIME *l_time, char *to, uint digits);
+int my_TIME_to_str(const MYSQL_TIME *l_time, char *to, uint digits);
+
+static inline longlong sec_part_shift(longlong second_part, uint digits)
+{
+ return second_part / (longlong)log_10_int[TIME_SECOND_PART_DIGITS - digits];
+}
+static inline longlong sec_part_unshift(longlong second_part, uint digits)
+{
+ return second_part * (longlong)log_10_int[TIME_SECOND_PART_DIGITS - digits];
+}
+static inline ulong sec_part_truncate(ulong second_part, uint digits)
+{
+ /* the cast here should be unnecessary! */
+ return second_part - second_part % (ulong)log_10_int[TIME_SECOND_PART_DIGITS - digits];
+}
+
+#define hrtime_to_my_time(X) ((my_time_t)hrtime_to_time(X))
/*
Available interval types used in any statement.
diff --git a/include/my_tree.h b/include/my_tree.h
index ceeb849ad0c..3aeef20e0ad 100644
--- a/include/my_tree.h
+++ b/include/my_tree.h
@@ -30,7 +30,17 @@ extern "C" {
#define tree_set_pointer(element,ptr) *((uchar **) (element+1))=((uchar*) (ptr))
+/*
+ A tree with its flag set to TREE_ONLY_DUPS behaves differently on inserting
+ an element that is not in the tree:
+ the element is not added at all, but instead tree_insert() returns a special
+ address TREE_ELEMENT_UNIQUE as an indication that the function has not failed
+ due to lack of memory.
+*/
+
+#define TREE_ELEMENT_UNIQUE ((TREE_ELEMENT *) 1)
#define TREE_NO_DUPS 1
+#define TREE_ONLY_DUPS 2
typedef enum { left_root_right, right_root_left } TREE_WALK;
typedef uint32 element_count;
diff --git a/include/myisam.h b/include/myisam.h
index 34ed58d354c..14ef24c99ff 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -300,6 +300,8 @@ extern ulong _mi_calc_blob_length(uint length , const uchar *pos);
extern uint mi_get_pointer_length(ulonglong file_length, uint def);
extern int mi_make_backup_of_index(struct st_myisam_info *info,
time_t backup_time, myf flags);
+#define myisam_max_key_length() HA_MAX_KEY_LENGTH
+#define myisam_max_key_segments() HA_MAX_KEY_SEG
#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for mmap file */
/* this is used to pass to mysql_myisamchk_table */
diff --git a/include/myisamchk.h b/include/myisamchk.h
index e8f1ce576bf..f85824e76bb 100644
--- a/include/myisamchk.h
+++ b/include/myisamchk.h
@@ -155,6 +155,11 @@ typedef struct st_handler_check_param
char temp_filename[FN_REFLEN];
IO_CACHE read_cache;
enum_handler_stats_method stats_method;
+ /* For reporting progress */
+ uint stage, max_stage;
+ uint progress_counter; /* How often to call _report_progress() */
+ ulonglong progress, max_progress;
+
#ifdef THREAD
pthread_mutex_t print_msg_mutex;
my_bool need_print_msg_lock;
diff --git a/include/mysql.h b/include/mysql.h
index 8a94a4d3a09..4849df2c143 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -171,7 +171,8 @@ enum mysql_option
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
- MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH,
+ MYSQL_PROGRESS_CALLBACK
};
/**
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
index 44f07c8a541..bb75af4554a 100644
--- a/include/mysql.h.pp
+++ b/include/mysql.h.pp
@@ -67,8 +67,8 @@ enum mysql_enum_shutdown_level {
SHUTDOWN_WAIT_UPDATES= (unsigned char)(1 << 3),
SHUTDOWN_WAIT_ALL_BUFFERS= ((unsigned char)(1 << 3) << 1),
SHUTDOWN_WAIT_CRITICAL_BUFFERS= ((unsigned char)(1 << 3) << 1) + 1,
- KILL_QUERY= 254,
- KILL_CONNECTION= 255
+ SHUTDOWN_KILL_QUERY= 254,
+ SHUTDOWN_KILL_CONNECTION= 255
};
enum enum_cursor_type
{
@@ -100,7 +100,8 @@ int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
struct my_rnd_struct;
enum Item_result
{
- STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT
+ STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT,
+ TIME_RESULT
};
typedef struct st_udf_args
{
@@ -258,7 +259,8 @@ enum mysql_option
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
- MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH,
+ MYSQL_PROGRESS_CALLBACK
};
struct st_mysql_options_extention;
struct st_mysql_options {
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index b8f4ad6f3fc..d7189ff30b7 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -1,5 +1,5 @@
-/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates
+/* Copyright (c) 2005, 2010, Oracle and/or its affiliates
+ Copyright (C) 2009-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -72,7 +72,7 @@ typedef struct st_mysql_xid MYSQL_XID;
/* MySQL plugin interface version */
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101
/* MariaDB plugin interface version */
-#define MARIA_PLUGIN_INTERFACE_VERSION 0x0100
+#define MARIA_PLUGIN_INTERFACE_VERSION 0x0101
/*
The allowable types of plugins
@@ -765,10 +765,6 @@ char *thd_security_context(MYSQL_THD thd, char *buffer, unsigned int length,
/* Increments the row counter, see THD::row_count */
void thd_inc_row_count(MYSQL_THD thd);
-#define thd_proc_info(thd, msg) set_thd_proc_info(thd, msg, __func__, __FILE__, __LINE__)
-const char *set_thd_proc_info(MYSQL_THD, const char * info, const char *func,
- const char *file, const unsigned int line);
-
/**
Create a temporary file.
diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp
index b0d5daf4c64..e4878d28f94 100644
--- a/include/mysql/plugin_auth.h.pp
+++ b/include/mysql/plugin_auth.h.pp
@@ -31,6 +31,27 @@ void *thd_memdup(void* thd, const void* str, unsigned int size);
MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
const char *str, unsigned int size,
int allocate_lex_string);
+#include <mysql/service_progress_report.h>
+extern struct progress_report_service_st {
+ void (*thd_progress_init_func)(void* thd, unsigned int max_stage);
+ void (*thd_progress_report_func)(void* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+ void (*thd_progress_next_stage_func)(void* thd);
+ void (*thd_progress_end_func)(void* thd);
+ const char *(*set_thd_proc_info_func)(void*, const char *info,
+ const char *func,
+ const char *file,
+ unsigned int line);
+} *progress_report_service;
+void thd_progress_init(void* thd, unsigned int max_stage);
+void thd_progress_report(void* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+void thd_progress_next_stage(void* thd);
+void thd_progress_end(void* thd);
+const char *set_thd_proc_info(void*, const char * info, const char *func,
+ const char *file, unsigned int line);
struct st_mysql_xid {
long formatID;
long gtrid_length;
@@ -166,8 +187,6 @@ int thd_tx_isolation(const void* thd);
char *thd_security_context(void* thd, char *buffer, unsigned int length,
unsigned int max_query_len);
void thd_inc_row_count(void* thd);
-const char *set_thd_proc_info(void*, const char * info, const char *func,
- const char *file, const unsigned int line);
int mysql_tmpfile(const char *prefix);
int thd_killed(const void* thd);
unsigned long thd_get_thread_id(const void* thd);
diff --git a/include/mysql/service_progress_report.h b/include/mysql/service_progress_report.h
new file mode 100644
index 00000000000..670b1c37630
--- /dev/null
+++ b/include/mysql/service_progress_report.h
@@ -0,0 +1,82 @@
+#ifndef MYSQL_SERVICE_PROGRESS_REPORT_INCLUDED
+/* Copyright (C) 2011 Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+ This service allows plugins to report progress of long running operations
+ to the server. The progress report is visible in SHOW PROCESSLIST,
+ INFORMATION_SCHEMA.PROCESSLIST, and is sent to the client
+ if requested.
+
+ The functions are documented at
+ http://kb.askmonty.org/en/progress-reporting#how-to-add-support-for-progress-reporting-to-a-storage-engine
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define thd_proc_info(thd, msg) set_thd_proc_info(thd, msg, \
+ __func__, __FILE__, __LINE__)
+
+extern struct progress_report_service_st {
+ void (*thd_progress_init_func)(MYSQL_THD thd, unsigned int max_stage);
+ void (*thd_progress_report_func)(MYSQL_THD thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+ void (*thd_progress_next_stage_func)(MYSQL_THD thd);
+ void (*thd_progress_end_func)(MYSQL_THD thd);
+ const char *(*set_thd_proc_info_func)(MYSQL_THD, const char *info,
+ const char *func,
+ const char *file,
+ unsigned int line);
+} *progress_report_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define thd_progress_init(thd,max_stage) (progress_report_service->thd_progress_init_func((thd),(max_stage)))
+#define thd_progress_report(thd, progress, max_progress) (progress_report_service->thd_progress_report_func((thd), (progress), (max_progress)))
+#define thd_progress_next_stage(thd) (progress_report_service->thd_progress_next_stage_func(thd))
+#define thd_progress_end(thd) (progress_report_service->thd_progress_end_func(thd))
+#define set_thd_proc_info(thd,info,func,file,line) (progress_report_service->set_thd_proc_info_func((thd),(info),(func),(file),(line)))
+
+#else
+
+/**
+ Report progress for long running operations
+
+ @param thd User thread connection handle
+ @param progress Where we are now
+ @param max_progress Progress will continue up to this
+*/
+void thd_progress_init(MYSQL_THD thd, unsigned int max_stage);
+void thd_progress_report(MYSQL_THD thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+void thd_progress_next_stage(MYSQL_THD thd);
+void thd_progress_end(MYSQL_THD thd);
+const char *set_thd_proc_info(MYSQL_THD, const char * info, const char *func,
+ const char *file, unsigned int line);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_PROGRESS_REPORT_INCLUDED
+#endif
+
diff --git a/include/mysql/services.h b/include/mysql/services.h
index 19003e66b96..b8cdfc3510d 100644
--- a/include/mysql/services.h
+++ b/include/mysql/services.h
@@ -20,6 +20,7 @@ extern "C" {
#include <mysql/service_my_snprintf.h>
#include <mysql/service_thd_alloc.h>
+#include <mysql/service_progress_report.h>
#ifdef __cplusplus
}
diff --git a/include/mysql_com.h b/include/mysql_com.h
index d7441036a98..d811b79889b 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -136,6 +136,7 @@ enum enum_server_command
#define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */
#define REFRESH_DES_KEY_FILE 0x40000L
#define REFRESH_USER_RESOURCES 0x80000L
+#define REFRESH_CHECKPOINT 0x100000L /* Don't do checkpoints */
#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */
#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */
@@ -157,6 +158,7 @@ enum enum_server_command
#define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */
#define CLIENT_PLUGIN_AUTH (1UL << 19) /* Client supports plugin authentication */
+#define CLIENT_PROGRESS (1UL << 29) /* Client support progress indicator */
#define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30)
#define CLIENT_REMEMBER_OPTIONS (1UL << 31)
@@ -188,6 +190,7 @@ enum enum_server_command
CLIENT_MULTI_RESULTS | \
CLIENT_SSL_VERIFY_SERVER_CERT | \
CLIENT_REMEMBER_OPTIONS | \
+ CLIENT_PROGRESS | \
CLIENT_PLUGIN_AUTH)
/*
@@ -382,12 +385,15 @@ enum mysql_enum_shutdown_level {
/* don't flush InnoDB buffers, flush other storage engines' buffers*/
SHUTDOWN_WAIT_CRITICAL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1) + 1,
/* Now the 2 levels of the KILL command */
-#if MYSQL_VERSION_ID >= 50000
- KILL_QUERY= 254,
-#endif
- KILL_CONNECTION= 255
+ SHUTDOWN_KILL_QUERY= 254,
+ SHUTDOWN_KILL_CONNECTION= 255
};
+/* Compatibility */
+#if !defined(MYSQL_SERVER) && defined(USE_OLD_FUNCTIONS)
+#define KILL_QUERY SHUTDOWN_KILL_QUERY
+#define KILL_CONNECTION SHUTDOWN_KILL_CONNECTION
+#endif
enum enum_cursor_type
{
@@ -446,7 +452,8 @@ struct my_rnd_struct;
enum Item_result
{
- STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT
+ STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT,
+ TIME_RESULT
#ifdef MYSQL_SERVER
,IMPOSSIBLE_RESULT /* Yes, we know this is ugly, don't tell us */
#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/service_versions.h b/include/service_versions.h
index 114957cdd86..6f06b609e61 100644
--- a/include/service_versions.h
+++ b/include/service_versions.h
@@ -21,4 +21,5 @@
#define VERSION_my_snprintf 0x0100
#define VERSION_thd_alloc 0x0100
+#define VERSION_progress_report 0x0100
diff --git a/include/sql_common.h b/include/sql_common.h
index 34b131cf331..f54bcb0e61b 100644
--- a/include/sql_common.h
+++ b/include/sql_common.h
@@ -31,6 +31,12 @@ extern const char *not_error_sqlstate;
struct st_mysql_options_extention {
char *plugin_dir;
char *default_auth;
+ void (*report_progress)(const MYSQL *mysql,
+ unsigned int stage,
+ unsigned int max_stage,
+ double progress,
+ const char *proc_info,
+ uint proc_info_length);
};
typedef struct st_mysql_methods
diff --git a/include/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 e13960d1558..5d9cccedda6 100644
--- a/include/thr_lock.h
+++ b/include/thr_lock.h
@@ -126,8 +126,9 @@ 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; /* Used by MariaDB for TABLE ref */
+ void *debug_print_param; /* For error messages */
enum thr_lock_type type;
+ enum thr_lock_type org_type; /* Cache for MariaDB */
uint priority;
} THR_LOCK_DATA;
diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
index aa6ea8dc851..b2ed048d86d 100755
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -68,6 +68,7 @@ SET(CLIENT_SOURCES ../mysys/array.c ../strings/bchange.c ../strings/bmove.c
../strings/ctype-simple.c ../strings/ctype-sjis.c ../strings/ctype-tis620.c
../strings/ctype-uca.c ../strings/ctype-ucs2.c ../strings/ctype-ujis.c
../strings/ctype-utf8.c ../strings/ctype-win1250ch.c ../strings/ctype.c
+ ../strings/decimal.c
../mysys/default.c errmsg.c ../mysys/errors.c ../mysys/my_sync.c
../mysys/hash.c ../mysys/my_sleep.c ../mysys/default_modify.c
get_password.c ../strings/int2str.c ../strings/is_prefix.c
@@ -85,8 +86,10 @@ SET(CLIENT_SOURCES ../mysys/array.c ../strings/bchange.c ../strings/bmove.c
../mysys/my_open.c ../mysys/my_pread.c ../mysys/my_pthread.c ../mysys/my_read.c
../mysys/my_realloc.c ../mysys/my_rename.c ../mysys/my_seek.c
../mysys/my_static.c ../strings/my_strtoll10.c ../mysys/my_symlink.c
+ ../mysys/ma_dyncol.c
../mysys/my_symlink2.c ../mysys/my_thr_init.c ../sql-common/my_time.c
../strings/my_vsnprintf.c ../mysys/my_wincond.c ../mysys/my_winthread.c
+ ../mysys/my_wincond.c ../mysys/my_winthread.c ../mysys/my_winfile.c ../mysys/my_winerr.c
../mysys/my_write.c ../sql/net_serv.cc ../sql-common/pack.c ../sql/password.c
../mysys/safemalloc.c ../mysys/sha1.c ../strings/str2int.c
../strings/str_alloc.c ../strings/strcend.c ../strings/strcont.c ../strings/strend.c
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared
index 089cade996a..02c9fd79747 100644
--- a/libmysql/Makefile.shared
+++ b/libmysql/Makefile.shared
@@ -48,7 +48,7 @@ mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
ctype-ucs2.lo ctype-gb2312.lo ctype-gbk.lo \
ctype-sjis.lo ctype-tis620.lo ctype-ujis.lo \
ctype-uca.lo xml.lo my_strtoll10.lo str_alloc.lo \
- strmov_overlapp.lo
+ strmov_overlapp.lo decimal.lo
mystringsextra= strto.c
mystringsheaders= strings_def.h
@@ -65,7 +65,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
my_symlink.lo my_fstream.lo mf_arr_appstr.lo \
mf_loadpath.lo my_pthread.lo my_thr_init.lo \
thr_mutex.lo mulalloc.lo string.lo \
- default.lo default_modify.lo \
+ default.lo default_modify.lo ma_dyncol.lo \
my_compress.lo array.lo my_once.lo list.lo my_net.lo \
charset.lo charset-def.lo hash.lo mf_iocache.lo \
mf_iocache2.lo my_seek.lo my_sleep.lo \
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 79d353502b8..e8887b81e68 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -3549,7 +3549,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
case MYSQL_TYPE_TIME:
{
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
- str_to_time(value, length, tm, &err);
+ str_to_time(value, length, tm, TIME_FUZZY_DATE, &err);
*param->error= test(err);
break;
}
@@ -3681,7 +3681,8 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
case MYSQL_TYPE_DATETIME:
{
int error;
- value= number_to_datetime(value, (MYSQL_TIME *) buffer, TIME_FUZZY_DATE,
+ value= number_to_datetime(value, 0,
+ (MYSQL_TIME *) buffer, TIME_FUZZY_DATE,
&error);
*param->error= test(error);
break;
@@ -3904,7 +3905,7 @@ static void fetch_datetime_with_conversion(MYSQL_BIND *param,
fetch_string_with_conversion:
*/
char buff[MAX_DATE_STRING_REP_LENGTH];
- uint length= my_TIME_to_str(my_time, buff);
+ uint length= my_TIME_to_str(my_time, buff, field->decimals);
/* Resort to string conversion */
fetch_string_with_conversion(param, (char *)buff, length);
break;
@@ -4381,7 +4382,7 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field)
field->max_length= MAX_DOUBLE_STRING_REP_LENGTH;
break;
case MYSQL_TYPE_TIME:
- field->max_length= 15; /* 19:23:48.123456 */
+ field->max_length= 17; /* -819:23:48.123456 */
param->skip_result= skip_result_with_length;
break;
case MYSQL_TYPE_DATE:
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index a2ba79b42cc..175add71fee 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -123,7 +123,8 @@ SET(LIBMYSQLD_SOURCES libmysqld.c emb_qcache.cc 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
@@ -134,11 +135,17 @@ SET(LIBMYSQLD_SOURCES libmysqld.c emb_qcache.cc lib_sql.cc
../sql/sql_tablespace.cc ../sql/sql_table.cc ../sql/sql_test.cc
../sql/sql_trigger.cc ../sql/sql_udf.cc ../sql/sql_union.cc
../sql/sql_update.cc ../sql/sql_view.cc ../sql/sql_profile.cc
+ ../sql/gcalc_tools.cc ../sql/gcalc_slicescan.cc
../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.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/rpl_utility.cc
+ ../sql/rpl_reporting.cc
+ ../sql/sql_expression_cache.cc
${GEN_SOURCES}
${LIB_SOURCES})
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
index f889b7526b7..84a12731d34 100644
--- a/libmysqld/Makefile.am
+++ b/libmysqld/Makefile.am
@@ -56,14 +56,17 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
item_geofunc.cc item_subselect.cc item_row.cc\
item_xmlfunc.cc \
key.cc lock.cc log.cc sql_state.c \
- log_event.cc rpl_record.cc \
+ log_event.cc rpl_record.cc rpl_utility.cc rpl_reporting.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 \
+ gcalc_slicescan.cc gcalc_tools.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 \
@@ -78,7 +81,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.$(YACC_HEXT): $(top_srcdir)/sql/sql_yacc.yy
diff --git a/libservices/CMakeLists.txt b/libservices/CMakeLists.txt
index ddfa2495ade..d22873661fb 100644
--- a/libservices/CMakeLists.txt
+++ b/libservices/CMakeLists.txt
@@ -15,6 +15,7 @@
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
-SET(MYSQLSERVICES_SOURCES my_snprintf_service.c thd_alloc_service.c)
+SET(MYSQLSERVICES_SOURCES my_snprintf_service.c thd_alloc_service.c
+ progress_report_service.c)
ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
diff --git a/libservices/Makefile.am b/libservices/Makefile.am
index 642081859c1..5002b85e328 100644
--- a/libservices/Makefile.am
+++ b/libservices/Makefile.am
@@ -15,5 +15,6 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
pkglib_LIBRARIES = libmysqlservices.a
-libmysqlservices_a_SOURCES = my_snprintf_service.c thd_alloc_service.c
+libmysqlservices_a_SOURCES = my_snprintf_service.c thd_alloc_service.c \
+ progress_report_service.c
EXTRA_DIST = CMakeLists.txt
diff --git a/storage/maria/compat_aliases.h b/libservices/progress_report_service.c
index 46a4da74eec..cd8db3eeacb 100644
--- a/storage/maria/compat_aliases.h
+++ b/libservices/progress_report_service.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2010 Monty Program Ab
+/* Copyright (C) 2009 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -13,15 +13,5 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-extern struct st_maria_plugin compat_aliases;
-extern char mysql_real_data_home[FN_REFLEN];
-extern TYPELIB maria_recover_typelib;
-extern TYPELIB maria_stats_method_typelib;
-extern TYPELIB maria_translog_purge_type_typelib;
-extern TYPELIB maria_sync_log_dir_typelib;
-extern TYPELIB maria_group_commit_typelib;
-extern struct st_mysql_storage_engine maria_storage_engine;
-extern my_bool use_maria_for_temp_tables;
-extern struct st_mysql_sys_var* system_variables[];
-extern st_mysql_show_var status_variables[];
-void copy_variable_aliases();
+#include <service_versions.h>
+SERVICE_VERSION *progress_report_service= (void*)VERSION_progress_report;
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index 49c7e06ec2d..0809e979ebf 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -114,7 +114,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
@@ -142,6 +144,8 @@ install-data-local:
uninstall-local:
@RM@ -f -r $(DESTDIR)$(testdir)
+uninstall-am: uninstall-local
+
# mtr - a shortcut for executing mysql-test-run.pl
mtr:
$(RM) -f mtr
diff --git a/mysql-test/collections/mysql-next-mr-wl2540.push b/mysql-test/collections/mysql-next-mr-wl2540.push
new file mode 100644
index 00000000000..2eb41427687
--- /dev/null
+++ b/mysql-test/collections/mysql-next-mr-wl2540.push
@@ -0,0 +1,6 @@
+perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_checksum --mysqld=--binlog-checksum=CRC32 --vardir=var-rpl_binlog_checksum --suite=binlog,rpl --skip-test-list=collections/disabled-per-push.list
+perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema --skip-test-list=collections/disabled-per-push.list
+perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema --skip-test-list=collections/disabled-per-push.list
+perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
+perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog --skip-test-list=collections/disabled-per-push.list
+perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
diff --git a/mysql-test/collections/mysql-trunk.daily b/mysql-test/collections/mysql-trunk.daily
new file mode 100644
index 00000000000..47d189a2c65
--- /dev/null
+++ b/mysql-test/collections/mysql-trunk.daily
@@ -0,0 +1,7 @@
+perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed
+perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row
+perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded
+perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_ndb_row --vardir=var-rpl_ndb_row --mysqld=--binlog-format=row --suite=rpl_ndb,ndb
+perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog --skip-ndb
+perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_checksum --mysqld=--binlog-checksum=CRC32 --vardir=var-rpl_binlog_checksum --suite=binlog,rpl
diff --git a/mysql-test/collections/mysql-trunk.weekly b/mysql-test/collections/mysql-trunk.weekly
new file mode 100644
index 00000000000..7186ad422b0
--- /dev/null
+++ b/mysql-test/collections/mysql-trunk.weekly
@@ -0,0 +1,2 @@
+perl mysql-test-run.pl --timer --force --comment=1st --experimental=collections/default.experimental 1st
+perl mysql-test-run.pl --timer --force --comment=all_binlog_checksum --experimental=collections/default.experimental --mysqld=--binlog-checksum=CRC32 --vardir=var-all_binlog_checksum --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
diff --git a/mysql-test/extra/binlog_tests/binlog.test b/mysql-test/extra/binlog_tests/binlog.test
index a776ba5eaf6..a5011a1231d 100644
--- a/mysql-test/extra/binlog_tests/binlog.test
+++ b/mysql-test/extra/binlog_tests/binlog.test
@@ -83,17 +83,22 @@ set @bcs = @@binlog_cache_size;
set global binlog_cache_size=4096;
reset master;
-create table t1 (a int) engine=innodb;
+create table t1 (a int, b char(255)) engine=innodb;
+
+flush status;
+show status like "binlog_cache_use";
-let $1=400;
+let $1=100;
disable_query_log;
begin;
while ($1)
{
- eval insert into t1 values( $1 );
+ eval insert into t1 values( $1, 'just to fill void to make transaction occupying at least two buffers of the trans cache' );
dec $1;
}
commit;
+--echo *** the following must show the counter value = 1 ***
+show status like "binlog_cache_use";
enable_query_log;
--source include/show_binlog_events.inc
diff --git a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test
index 5db79e4f848..c7e7a491ce1 100644
--- a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test
+++ b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test
@@ -311,6 +311,7 @@ select get_lock("a",10);
begin;
insert into t1 values(8);
insert into t2 select * from t1;
+
disconnect con3;
connection con4;
@@ -321,14 +322,19 @@ let $MYSQLD_DATADIR= `select @@datadir`;
# we check that the error code of the "ROLLBACK" event is 0 and not
# ER_SERVER_SHUTDOWN (i.e. disconnection just rolls back transaction
# and does not make slave to stop)
+
+-- source include/binlog_start_pos.inc
+
if (`select @@binlog_format = 'ROW'`)
{
- --exec $MYSQL_BINLOG --start-position=524 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output
+ let $start_pos= `select @binlog_start_pos + 418`;
+ --exec $MYSQL_BINLOG --start-position=$start_pos $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output
}
if (`select @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`)
{
- --exec $MYSQL_BINLOG --start-position=555 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output
+ let $start_pos= `select @binlog_start_pos + 449`;
+ --exec $MYSQL_BINLOG --start-position=$start_pos $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output
}
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
diff --git a/mysql-test/extra/rpl_tests/rpl_deadlock.test b/mysql-test/extra/rpl_tests/rpl_deadlock.test
index bd446c86943..0e862e041e6 100644
--- a/mysql-test/extra/rpl_tests/rpl_deadlock.test
+++ b/mysql-test/extra/rpl_tests/rpl_deadlock.test
@@ -72,7 +72,7 @@ connection slave;
--source include/stop_slave.inc
DELETE FROM t2;
# Set slave position to the BEGIN log event
---replace_result $master_pos_begin MASTER_POS_BEGIN
+--replace_result $master_pos_begin <master_pos_begin>
eval CHANGE MASTER TO MASTER_LOG_POS=$master_pos_begin;
BEGIN;
# Hold lock
@@ -103,7 +103,7 @@ SET global max_relay_log_size=0;
--source include/stop_slave.inc
DELETE FROM t2;
# Set slave position to the BEGIN log event
---replace_result $master_pos_begin MASTER_POS_BEGIN
+--replace_result $master_pos_begin <master_pos_begin>
eval CHANGE MASTER TO MASTER_LOG_POS=$master_pos_begin;
BEGIN;
# Hold lock
diff --git a/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test b/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test
index 06253c5defb..5cbda2d591f 100644
--- a/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test
+++ b/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test
@@ -15,6 +15,7 @@ create table t3 (a int) engine=merge union(t1);
create table t4 (a int);
# We force the slave to open t3 (because we want to try confusing him) with this :
insert into t4 select * from t3;
+--let $rename_event_pos= query_get_value(SHOW MASTER STATUS, Position, 1)
rename table t1 to t5, t2 to t1;
# RENAME may have confused the master (this is a known bug): so FLUSH tables,
# first don't write it to the binlog, to test the NO_WRITE_TO_BINLOG keyword.
diff --git a/mysql-test/extra/rpl_tests/rpl_log.test b/mysql-test/extra/rpl_tests/rpl_log.test
index b812b6ebaee..4de8169a2e6 100644
--- a/mysql-test/extra/rpl_tests/rpl_log.test
+++ b/mysql-test/extra/rpl_tests/rpl_log.test
@@ -14,6 +14,7 @@ source include/stop_slave.inc;
reset master;
reset slave;
source include/start_slave.inc;
+source include/binlog_start_pos.inc;
let $VERSION=`select version()`;
diff --git a/mysql-test/extra/rpl_tests/rpl_reset_slave.test b/mysql-test/extra/rpl_tests/rpl_reset_slave.test
index 04ab8751e39..182fde40193 100644
--- a/mysql-test/extra/rpl_tests/rpl_reset_slave.test
+++ b/mysql-test/extra/rpl_tests/rpl_reset_slave.test
@@ -10,6 +10,9 @@
-- source include/master-slave.inc
sync_slave_with_master;
+--disable_query_log
+call mtr.add_suppression('Slave I/O: Get master BINLOG_CHECKSUM failed with error');
+--enable_query_log
let $status_items= Master_User, Master_Host;
source include/show_slave_status.inc;
diff --git a/mysql-test/extra/rpl_tests/rpl_row_annotate.test b/mysql-test/extra/rpl_tests/rpl_row_annotate.test
new file mode 100644
index 00000000000..f3d8006ce01
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_row_annotate.test
@@ -0,0 +1,156 @@
+########################################################################
+# WL47: Store in binlog text of statements that caused RBR events
+# new event : ANNOTATE_ROWS_EVENT
+# new master option : --binlog-annotate-row-events
+# new slave option : --replicate-annotate-row-events
+########################################################################
+--source include/master-slave.inc
+connect (master2,127.0.0.1,root,,test,$MASTER_MYPORT,);
+
+connection master;
+--disable_query_log
+
+--disable_warnings
+DROP DATABASE IF EXISTS test1;
+--enable_warnings
+
+CREATE DATABASE test1;
+USE test1;
+
+CREATE TABLE t1(a int primary key, b int);
+CREATE TABLE t2(a int, b int);
+CREATE TABLE t3(a int, b int);
+CREATE TABLE t4(a int, b int);
+CREATE TABLE xt1(a int, b int);
+CREATE TABLE xt2(a int, b int);
+
+CREATE TABLE t5 (
+ a INT PRIMARY KEY AUTO_INCREMENT,
+ b VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_bin
+);
+
+SET SESSION binlog_annotate_row_events = OFF;
+
+INSERT INTO t1 VALUES (0,0), (1,1);
+
+SET SESSION binlog_annotate_row_events = ON;
+
+UPDATE t1 SET b = b + 1;
+REPLACE t1 VALUES (1,1), (2,2), (3,3);
+
+INSERT INTO t2 VALUES (1,1), (2,2), (3,3);
+INSERT INTO t3 VALUES (1,1), (2,2), (3,3);
+DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a;
+
+INSERT INTO xt1 VALUES (1,1), (2,2), (3,3);
+INSERT INTO t2 VALUES (1,1), (2,2), (3,3);
+DELETE xt1, t2 FROM xt1 INNER JOIN t2 INNER JOIN t3 WHERE xt1.a=t2.a AND t2.a=t3.a;
+
+INSERT INTO xt1 VALUES (1,1), (2,2), (3,3);
+INSERT INTO xt2 VALUES (1,1), (2,2), (3,3);
+DELETE xt1, xt2 FROM xt1 INNER JOIN xt2 INNER JOIN t3 WHERE xt1.a=xt2.a AND xt2.a=t3.a;
+
+INSERT INTO t5(b) VALUES ('foo'), ('bar'), ('baz');
+SET NAMES latin1;
+INSERT INTO t5(b) VALUES ('gås');
+SET NAMES utf8;
+INSERT INTO t5(b) VALUES ('gås');
+SET NAMES latin1;
+
+FLUSH LOGS;
+
+--echo ########################################################################
+--echo # TABLES ON MASTER
+--echo ########################################################################
+--enable_query_log
+
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+SELECT * FROM t3 ORDER BY a;
+SELECT * FROM t5 ORDER BY a;
+
+sync_slave_with_master;
+--echo ########################################################################
+--echo # TABLES ON SLAVE: should be the same as on master
+--echo ########################################################################
+--disable_query_log
+USE test1;
+--enable_query_log
+
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+SELECT * FROM t3 ORDER BY a;
+SELECT * FROM t5 ORDER BY a;
+
+--echo ########################################################################
+--echo # EVENTS ON SLAVE
+let $annotate= `select @@global.replicate_annotate_row_events`;
+if ($annotate)
+{
+ --echo # The following Annotate_rows events should appear below:
+ --echo # - UPDATE t1 SET b = b + 1;
+ --echo # - REPLACE t1 VALUES (1,1), (2,2), (3,3);
+ --echo # - INSERT INTO t2 VALUES (1,1), (2,2), (3,3)
+ --echo # - INSERT INTO t3 VALUES (1,1), (2,2), (3,3)
+ --echo # - DELETE t1, t2 FROM <...>
+ --echo # - INSERT INTO t2 VALUES (1,1), (2,2), (3,3)
+ --echo # - DELETE xt1, t2 FROM <...>
+ --echo # - INSERT INTO t5(b) VALUES <...> (3 instances)
+}
+if (!$annotate)
+{
+ --echo # No Annotate_rows events should appear below
+}
+--echo ########################################################################
+FLUSH LOGS;
+
+--source include/binlog_start_pos.inc
+let $start_pos= `select @binlog_start_pos`;
+--replace_column 2 # 5 #
+--replace_result $start_pos <start_pos>
+--replace_regex /table_id: [0-9]+/table_id: #/ /\/\* xid=.* \*\//\/* xid= *\//
+--eval show binlog events in 'slave-bin.000001' from $start_pos
+
+--echo #
+--echo ########################################################################
+--echo # INSERTs DELAYED ON MASTERs
+--echo ########################################################################
+connection master;
+SET SESSION binlog_annotate_row_events = ON;
+INSERT DELAYED INTO test1.t4 VALUES (1,1);
+FLUSH TABLES;
+SELECT * FROM test1.t4 ORDER BY a;
+
+sync_slave_with_master;
+connection master;
+sync_slave_with_master;
+
+--echo ########################################################################
+--echo # ON SLAVE
+--echo # No Annotate_rows events should appear below
+--echo ########################################################################
+FLUSH LOGS;
+
+--exec $MYSQL --host=127.0.0.1 --port=$SLAVE_MYPORT test -e "show binlog events in 'slave-bin.000002'" > $MYSQLTEST_VARDIR/tmp/annotated_events.txt
+perl;
+ open F, '<', "$ENV{MYSQLTEST_VARDIR}/tmp/annotated_events.txt" or die;
+ binmode STDOUT;
+ while (defined ($_ = <F>)) {
+ if (/Annotate_rows/) {
+ s/[0-9]+\sAnnotate_rows\s[0-9]+\s[0-9]+/# Annotate_rows # #/;
+ print($_);
+ $_ = <F>;
+ s/[0-9]+\sTable_map\s[0-9]+\s[0-9]+\stable_id:\s[0-9]+/# Table_map # # table_id: #/;
+ print($_);
+ }
+ }
+EOF
+
+# Clean-up
+connection master;
+--disable_query_log
+DROP DATABASE test1;
+sync_slave_with_master;
+--enable_query_log
+
+--source include/rpl_end.inc
diff --git a/mysql-test/include/binlog_start_pos.inc b/mysql-test/include/binlog_start_pos.inc
new file mode 100644
index 00000000000..add5a42a426
--- /dev/null
+++ b/mysql-test/include/binlog_start_pos.inc
@@ -0,0 +1,28 @@
+##############################################################################
+#
+# binlog_start_pos is the postion of the the first event in the binary log
+# which follows the Format description event. Intended to reduce test suite
+# dependance on the Format description event length changes (e.g. in case
+# of adding new events). Evaluated as:
+#
+# binlog_start_pos = 4 /* binlog header */ +
+# (Format_description_log_event length)
+#
+# Format_description_log_event length =
+# 19 /* event common header */ +
+# 57 /* misc stuff in the Format description header */ +
+# number of events +
+# 1 /* Checksum algorithm */ +
+# 4 /* CRC32 length */
+#
+# With current number of events = 160,
+#
+# binlog_start_pos = 4 + 19 + 57 + 160 + 1 + 4 = 245.
+#
+##############################################################################
+
+let $binlog_start_pos=245;
+--disable_query_log
+SET @binlog_start_pos=245;
+--enable_query_log
+
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/check_shared_row_lock.inc b/mysql-test/include/check_shared_row_lock.inc
index efc7e13b3aa..1c9d9b0c3c6 100644
--- a/mysql-test/include/check_shared_row_lock.inc
+++ b/mysql-test/include/check_shared_row_lock.inc
@@ -33,7 +33,8 @@ connection default;
# least it acquires S-locks on some of rows.
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state in ("Sending data","statistics", "preparing") and
+ where state in ("Sending data","statistics", "preparing", "updating",
+ "executing", "Searching rows for update") and
info = "$wait_statement";
--source include/wait_condition.inc
diff --git a/mysql-test/include/common-tests.inc b/mysql-test/include/common-tests.inc
index 882ac689498..4b61826c347 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");
@@ -1536,6 +1536,10 @@ select t2.fld1,t22.fld1 from t2,t2 t22 where t2.fld1 >= 250501 and t2.fld1 <= 25
#
# Test of left join.
#
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
insert into t2 (fld1, companynr) values (999999,99);
select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
@@ -1568,6 +1572,8 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
+SET optimizer_switch=@save_optimizer_switch;
+
#
# Joins with forms.
#
diff --git a/mysql-test/include/have_binlog_checksum_off.inc b/mysql-test/include/have_binlog_checksum_off.inc
new file mode 100644
index 00000000000..c7c444c8785
--- /dev/null
+++ b/mysql-test/include/have_binlog_checksum_off.inc
@@ -0,0 +1,4 @@
+if (`select variable_value not like 'NONE' from information_schema.GLOBAL_VARIABLES
+ where variable_name='binlog_checksum'`){
+ skip Can not run the test when server activated checksumming;
+}
diff --git a/mysql-test/include/have_example_plugin.inc b/mysql-test/include/have_example_plugin.inc
index a344b79700b..2d2a9dc8f7b 100644
--- a/mysql-test/include/have_example_plugin.inc
+++ b/mysql-test/include/have_example_plugin.inc
@@ -3,7 +3,7 @@
# i.e it will support dlopen
#
--source include/have_dynamic_loading.inc
-
+--source include/not_windows_embedded.inc
#
# Check if the variable HA_EXAMPLE_SO is set
#
diff --git a/mysql-test/include/icp_tests.inc b/mysql-test/include/icp_tests.inc
new file mode 100644
index 00000000000..ffe8d7f1eb1
--- /dev/null
+++ b/mysql-test/include/icp_tests.inc
@@ -0,0 +1,894 @@
+--echo #
+--echo # Bug#36981 - "innodb crash when selecting for update"
+--echo #
+
+#
+# Test 1: Test based on the reproduction test case for this bug.
+# This query resulted in a crash in InnoDB due to
+# InnoDB changing from using the index which the push condition
+# where for to use the clustered index due to "SELECT ... FOR UPDATE".
+#
+
+CREATE TABLE t1 (
+ c1 CHAR(1),
+ c2 CHAR(10),
+ KEY (c1)
+);
+
+INSERT INTO t1 VALUES ('3', null);
+
+SELECT * FROM t1 WHERE c1='3' FOR UPDATE;
+
+DROP TABLE t1;
+
+#
+# Test 2: Extended test case to test that the correct rows are returned.
+# This test is for ensuring that if InnoDB refuses to accept
+# the pushed index condition it is still evaluated.
+#
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 SELECT A.a + 10*(B.a + 10*C.a) FROM t1 A, t1 B, t1 C;
+
+CREATE TABLE t3 (
+ c1 CHAR(10) NOT NULL,
+ c2 CHAR(10) NOT NULL,
+ c3 CHAR(200) NOT NULL,
+ KEY (c1)
+);
+
+INSERT INTO t3
+ SELECT CONCAT('c-',1000+t2.a,'=w'), CONCAT('c-',1000+ t2.a,'=w'), 'filler'
+ FROM t2;
+
+INSERT INTO t3
+ SELECT CONCAT('c-',1000+t2.a,'=w'), CONCAT('c-',2000+t2.a,'=w'), 'filler-1'
+ FROM t2;
+
+INSERT INTO t3
+ SELECT CONCAT('c-',1000+t2.a,'=w'), CONCAT('c-',3000+t2.a,'=w'), 'filler-2'
+ FROM t2;
+
+--sorted_result
+SELECT c1,c3 FROM t3 WHERE c1 >= 'c-1994=w' and c1 != 'c-1996=w' FOR UPDATE;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug#42580 - Innodb's ORDER BY ..LIMIT returns no rows for
+--echo # null-safe operator <=> NULL
+--echo #
+
+CREATE TABLE t1(
+ c1 DATE NOT NULL,
+ c2 DATE NULL,
+ c3 DATETIME,
+ c4 TIMESTAMP,
+ PRIMARY KEY(c1),
+ UNIQUE(c2)
+);
+
+--echo
+INSERT INTO t1 VALUES('0000-00-00', '0000-00-00', '2008-01-04', '2008-01-05');
+INSERT INTO t1 VALUES('2007-05-25', '2007-05-25', '2007-05-26', '2007-05-26');
+INSERT INTO t1 VALUES('2008-01-01', NULL , '2008-01-02', '2008-01-03');
+INSERT INTO t1 VALUES('2008-01-17', NULL , NULL , '2009-01-29');
+INSERT INTO t1 VALUES('2009-01-29', '2009-01-29', '2009-01-29', '2009-01-29');
+
+--echo
+SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c1,c2;
+--echo
+SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c1,c2 LIMIT 2;
+
+--echo
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#43617 - Innodb returns wrong results with timestamp's range value
+--echo # in IN clause
+--echo # (Note: Fixed by patch for BUG#42580)
+--echo #
+
+CREATE TABLE t1(
+ c1 TIMESTAMP NOT NULL,
+ c2 TIMESTAMP NULL,
+ c3 DATE,
+ c4 DATETIME,
+ PRIMARY KEY(c1),
+ UNIQUE INDEX(c2)
+);
+
+INSERT INTO t1 VALUES
+ ('0000-00-00 00:00:00','0000-00-00 00:00:00','2008-01-04','2008-01-05 00:00:00'),
+ ('1971-01-01 00:00:01','1980-01-01 00:00:01','2009-01-01','2009-01-02 00:00:00'),
+ ('1999-01-01 00:00:00','1999-01-01 00:00:00', NULL, NULL),
+ ('2007-05-23 09:15:28','2007-05-23 09:15:28','2007-05-24','2007-05-24 09:15:28'),
+ ('2007-05-27 00:00:00','2007-05-25 00:00:00','2007-05-26','2007-05-26 00:00:00'),
+ ('2008-01-01 00:00:00', NULL, '2008-01-02','2008-01-03 00:00:00'),
+ ('2009-01-29 11:11:27','2009-01-29 11:11:27','2009-01-29','2009-01-29 11:11:27'),
+ ('2038-01-09 03:14:07','2038-01-09 03:14:07','2009-01-05','2009-01-06 00:00:00');
+
+--echo
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2;
+
+--echo
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 LIMIT 2;
+
+--echo
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC;
+
+--echo
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC LIMIT 2;
+
+--echo
+DROP TABLE t1;
+
+--echo #
+--echo # BUG#43618: MyISAM&Maria returns wrong results with 'between'
+--echo # on timestamp
+--echo #
+
+CREATE TABLE t1(
+ ts TIMESTAMP NOT NULL,
+ c char NULL,
+ PRIMARY KEY(ts)
+);
+
+INSERT INTO t1 VALUES
+ ('1971-01-01','a'),
+ ('2007-05-25','b'),
+ ('2008-01-01','c'),
+ ('2038-01-09','d');
+
+--disable_warnings
+
+--echo
+--echo # Execute select with invalid timestamp, desc ordering
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+
+--echo
+--echo # Should use index condition
+EXPLAIN
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+--echo
+
+--enable_warnings
+
+DROP TABLE t1;
+
+--echo #
+--echo # BUG#49906: Assertion failed - Field_varstring::val_str in field.cc
+--echo # (Note: Fixed by patch for LP BUG#625841)
+--echo #
+
+CREATE TABLE t1 (
+ f1 VARCHAR(1024),
+ f2 VARCHAR(10),
+ INDEX test_idx USING BTREE (f2,f1(5))
+);
+
+INSERT INTO t1 VALUES ('a','c'), ('b','d');
+
+SELECT f1
+FROM t1
+WHERE f2 LIKE 'd'
+ORDER BY f1;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#52660 - "Perf. regr. using ICP for MyISAM on range queries on
+--echo # an index containing TEXT"
+--echo #
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 SELECT A.a + 10*(B.a) FROM t1 A, t1 B;
+
+CREATE TABLE t3 (
+ c1 TINYTEXT NOT NULL,
+ i1 INT NOT NULL,
+ KEY (c1(6),i1)
+);
+
+INSERT INTO t3 SELECT CONCAT('c-',1000+t2.a,'=w'), 1 FROM t2;
+
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # Bug#40992 - InnoDB: Crash when engine_condition_pushdown is on
+--echo #
+
+CREATE TABLE t (
+ dummy INT PRIMARY KEY,
+ a INT UNIQUE,
+ b INT
+);
+
+INSERT INTO t VALUES (1,1,1),(3,3,3),(5,5,5);
+
+SELECT * FROM t WHERE a > 2 FOR UPDATE;
+
+DROP TABLE t;
+
+
+--echo #
+--echo # Bug#35080 - Innodb crash at mem_block_get_len line 72
+--echo #
+
+CREATE TABLE t1 (
+ t1_autoinc INT(11) NOT NULL AUTO_INCREMENT,
+ uuid VARCHAR(36) DEFAULT NULL,
+ PRIMARY KEY (t1_autoinc),
+ KEY k (uuid)
+);
+
+CREATE TABLE t2 (
+ t2_autoinc INT(11) NOT NULL AUTO_INCREMENT,
+ uuid VARCHAR(36) DEFAULT NULL,
+ date DATETIME DEFAULT NULL,
+ PRIMARY KEY (t2_autoinc),
+ KEY k (uuid)
+);
+
+CREATE VIEW v1 AS
+ SELECT t1_autoinc, uuid
+ FROM t1
+ WHERE (ISNULL(uuid) OR (uuid like '%-%'));
+
+CREATE VIEW v2 AS
+ SELECT t2_autoinc, uuid, date
+ FROM t2
+ WHERE (ISNULL(uuid) OR (LENGTH(uuid) = 36));
+
+CREATE PROCEDURE delete_multi (IN uuid CHAR(36))
+ DELETE v1, v2 FROM v1 INNER JOIN v2
+ ON v1.uuid = v2.uuid
+ WHERE v1.uuid = @uuid;
+
+SET @uuid = UUID();
+
+INSERT INTO v1 (uuid) VALUES (@uuid);
+INSERT INTO v2 (uuid, date) VALUES (@uuid, '2009-09-09');
+
+CALL delete_multi(@uuid);
+
+DROP procedure delete_multi;
+DROP table t1,t2;
+DROP view v1,v2;
+
+--echo #
+--echo # Bug#41996 - multi-table delete crashes server (InnoDB table)
+--echo #
+
+CREATE TABLE t1 (
+ b BIGINT,
+ i INT,
+ KEY (b)
+);
+
+INSERT INTO t1 VALUES (2, 2);
+
+DELETE t1 FROM t1 a, t1 WHERE a.i=t1.b;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#43448 - Server crashes on multi table delete with Innodb
+--echo #
+
+CREATE TABLE t1 (
+ id1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ t CHAR(12)
+);
+
+CREATE TABLE t2 (
+ id2 INT NOT NULL,
+ t CHAR(12)
+);
+
+CREATE TABLE t3(
+ id3 INT NOT NULL,
+ t CHAR(12),
+ INDEX(id3)
+);
+
+delimiter |;
+
+CREATE PROCEDURE insert_data ()
+BEGIN
+ DECLARE i1 INT DEFAULT 20;
+ DECLARE i2 INT;
+ DECLARE i3 INT;
+
+ WHILE (i1 > 0) DO
+ INSERT INTO t1(t) VALUES (i1);
+ SET i2 = 2;
+ WHILE (i2 > 0) DO
+ INSERT INTO t2(id2, t) VALUES (i1, i2);
+ SET i3 = 2;
+ WHILE (i3 > 0) DO
+ INSERT INTO t3(id3, t) VALUES (i1, i2);
+ SET i3 = i3 -1;
+ END WHILE;
+ SET i2 = i2 -1;
+ END WHILE;
+ SET i1 = i1 - 1;
+ END WHILE;
+END |
+
+delimiter ;|
+
+CALL insert_data();
+
+SELECT COUNT(*) FROM t1 WHERE id1 > 10;
+SELECT COUNT(*) FROM t2 WHERE id2 > 10;
+SELECT COUNT(*) FROM t3 WHERE id3 > 10;
+
+DELETE t1, t2, t3
+FROM t1, t2, t3
+WHERE t1.id1 = t2.id2 AND t2.id2 = t3.id3 AND t1.id1 > 3;
+
+SELECT COUNT(*) FROM t1;
+SELECT COUNT(*) FROM t2;
+SELECT COUNT(*) FROM t3;
+
+DROP PROCEDURE insert_data;
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # Bug#57372 "Multi-table updates and deletes fail when running with ICP
+--echo # against InnoDB"
+--echo #
+
+CREATE TABLE t1 (
+ a INT KEY,
+ b INT
+);
+
+CREATE TABLE t2 (
+ a INT KEY,
+ b INT
+);
+
+INSERT INTO t1 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105);
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+
+UPDATE t1, t2
+SET t1.a = t1.a + 100, t2.b = t1.a + 10
+WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b - 100;
+
+--sorted_result
+SELECT * FROM t1;
+--sorted_result
+SELECT * FROM t2;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug#52605 - "Adding LIMIT 1 clause to query with complex range
+--echo # predicate causes wrong results"
+--echo #
+
+CREATE TABLE t1 (
+ pk INT NOT NULL,
+ c1 INT,
+ PRIMARY KEY (pk),
+ KEY k1 (c1)
+);
+
+INSERT INTO t1 VALUES (1,NULL);
+INSERT INTO t1 VALUES (2,6);
+INSERT INTO t1 VALUES (3,NULL);
+INSERT INTO t1 VALUES (4,6);
+INSERT INTO t1 VALUES (5,NULL);
+INSERT INTO t1 VALUES (6,NULL);
+INSERT INTO t1 VALUES (7,9);
+INSERT INTO t1 VALUES (8,0);
+
+SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+
+EXPLAIN SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+
+DROP TABLE t1;
+
+--echo #
+--echo #
+--echo # Bug#59259 "Incorrect rows returned for a correlated subquery
+--echo # when ICP is on"
+--echo #
+
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=off';
+
+EXPLAIN
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+
+set optimizer_switch=@save_optimizer_switch;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug #58816 "Extra temporary duplicate rows in result set when
+--echo # switching ICP off"
+--echo #
+
+set @save_optimizer_switch= @@optimizer_switch;
+
+CREATE TABLE t1 (
+ pk INT NOT NULL,
+ c1 INT NOT NULL,
+ PRIMARY KEY (pk)
+);
+
+INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1);
+
+EXPLAIN SELECT pk, c1 FROM t1 WHERE pk <> 3;
+
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+
+SELECT pk, c1 FROM t1 WHERE pk <> 3;
+
+DROP TABLE t1;
+
+set optimizer_switch= @save_optimizer_switch;
+
+--echo #
+--echo # Bug#58837: ICP crash or valgrind error due to uninitialized
+--echo # value in innobase_index_cond
+--echo #
+
+CREATE TABLE t1 (
+ t1_int INT,
+ t1_time TIME
+);
+
+CREATE TABLE t2 (
+ t2_int int PRIMARY KEY,
+ t2_int2 INT
+);
+
+--disable_warnings
+INSERT INTO t2 VALUES ();
+INSERT INTO t1 VALUES ();
+--enable_warnings
+
+SELECT * FROM t1 AS t1a
+ WHERE NOT EXISTS (SELECT * FROM t1 AS t1b
+ WHERE t1b.t1_int NOT IN
+ (SELECT t2.t2_int FROM t2
+ WHERE t1b.t1_time LIKE t1b.t1_int
+ OR t1b.t1_time <> t2.t2_int2
+ AND 6=7));
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug#59186: Wrong results of join when ICP is enabled
+--echo # (fixed by the patch for LP bug #694092)
+--echo #
+
+CREATE TABLE t1 (
+ pk INTEGER NOT NULL,
+ c1 VARCHAR(3) NOT NULL,
+ PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,'y'),(0,'or');
+
+CREATE TABLE t2 (
+ pk INTEGER NOT NULL,
+ c1 VARCHAR(3) NOT NULL,
+ c2 VARCHAR(6) NOT NULL,
+ PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (6,'y','RPOYT'),(10,'m','JINQE');
+
+EXPLAIN
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+ (t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+ (t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug#58838: "Wrong results with HAVING + LIMIT without GROUP BY when
+--echo # ICP is enabled".
+--echo # (Fixed by the patches for LP bugs #668644, #702322)
+--echo #
+
+CREATE TABLE t1 (
+ pk INT NOT NULL,
+ c1 INT,
+ PRIMARY KEY (pk),
+ KEY col_int_key (c1)
+);
+
+INSERT INTO t1 VALUES (1,37),(2,8),(3,-25),(4,NULL),(5,55);
+
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 0;
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 1;
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 2;
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 5;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#59483 "Crash on INSERT/REPLACE in
+--echo # rec_convert_dtuple_to_rec_comp with ICP on"
+--echo #
+
+CREATE TABLE t1 (
+ pk INTEGER AUTO_INCREMENT PRIMARY KEY,
+ i1 INTEGER,
+ c1 CHAR(6),
+ i2 INTEGER NOT NULL,
+ KEY (i2)
+);
+
+INSERT INTO t1 VALUES
+ (NULL, 4, 'that', 8),
+ (NULL, 1, 'she', 6),
+ (NULL, 6, 'tell', 2);
+
+SELECT * FROM t1 WHERE i2 IN (3, 6) LIMIT 2 FOR UPDATE;
+INSERT INTO t1 (i2) VALUES (1);
+
+DROP TABLE t1;
+
+--echo #
+--echo # Bug #11766678 - 59843:
+--echo # USING UNINITIALISED VALUE IN USES_INDEX_FIELDS_ONLY
+--echo #
+
+CREATE TABLE t1 (
+ col999 FLOAT NOT NULL,
+ COL1000 VARBINARY(179) NOT NULL,
+ col1003 DATE DEFAULT NULL,
+ KEY idx4267 (col1000, col1003)
+);
+
+INSERT INTO t1 VALUES (),();
+SELECT col999 FROM t1 WHERE col1000 = "3" AND col1003 <=> sysdate();
+
+DROP TABLE t1;
+
+--echo #
+--echo # BUG#12822678 - ICP WITH STRAIGHT_JOIN
+--echo #
+
+CREATE TABLE t1 (
+ i1 INTEGER NOT NULL,
+ d1 DOUBLE,
+ KEY k1 (d1)
+);
+INSERT INTO t1 VALUES (10,1), (17,NULL), (22,NULL);
+
+CREATE TABLE t2 (
+ pk INTEGER NOT NULL,
+ i1 INTEGER NOT NULL,
+ PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (4,1);
+
+EXPLAIN
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+ WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+ WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#778434 Wrong result with in_to_exists=on in maria-5.3-mwl89
+--echo #
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0);
+
+CREATE TABLE t2 ( f10 int) ;
+INSERT IGNORE INTO t2 VALUES (0);
+
+CREATE TABLE t3 ( f1 int NOT NULL , f10 int, PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES (6,0),(10,0);
+
+CREATE TABLE t4 ( f11 int) ;
+INSERT IGNORE INTO t4 VALUES
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(NULL),
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+
+set @tmp_778434=@@optimizer_switch;
+SET optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off,semijoin=off';
+
+SELECT * FROM t1 INNER JOIN t2 ON t2.f10 = t1.f11
+WHERE (6, 234) IN (
+ SELECT t3.f1, t3.f1
+ FROM t3 JOIN t4 ON t4.f11 = t3.f10
+);
+
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch= @tmp_778434;
+
+--echo #
+--echo # Bug#885168: ICP for one index + potential ORDER BY for another
+--echo #
+
+CREATE TABLE t1 (a varchar(64), b varchar(10), INDEX(a), INDEX(b)) ;
+INSERT INTO t1 VALUES
+ ('Ohio','Iowa'), ('k','d'), ('bdkpj','mbdkpjdanp'), ('d','xdmbdkpjda'),
+ ('fkxdmbdkpjdanpje','o'), ('f','Pennsylvan'), ('Virginia','ei');
+
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT * FROM t1
+ WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+SELECT * FROM t1
+ WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT * FROM t1
+ WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+SELECT * FROM t1
+ WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#886145: join with ICP + ORDER BY
+--echo #
+
+CREATE TABLE t1 (b int NOT NULL, c int, a varchar(1024), PRIMARY KEY (b));
+INSERT INTO t1 VALUES (1,4,'Ill');
+
+CREATE TABLE t2 (a varchar(1024), KEY (a(512)));
+INSERT INTO t2 VALUES
+ ('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w');
+
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+ HAVING t1.c != 5 ORDER BY t1.c;
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+ HAVING t1.c != 5 ORDER BY t1.c;
+
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+ HAVING t1.c != 5 ORDER BY t1.c;
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+ HAVING t1.c != 5 ORDER BY t1.c;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug#879871: InnoDB: possible ICP + GROUP BY primary index
+--echo #
+
+CREATE TABLE t1 (
+ a int NOT NULL, b int, c varchar(1), d varchar(1),
+ PRIMARY KEY (a), KEY c (c,b)
+);
+INSERT INTO t1 VALUES (10,8,'g','g');
+
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+
+DROP TABLE t1;
+
+
+--echo #
+--echo # Bug#904832: an attempt to perform an index condition pushdown
+--echo # of a condition containing a subquery
+--echo #
+
+CREATE TABLE t1 (
+ a INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
+ b INT, c INT, d DATE NOT NULL, e VARCHAR(1),
+ KEY (c), KEY (d), KEY k2(b), KEY k3(b), KEY k4(b)
+);
+
+INSERT INTO t1 (b,c,d,e) VALUES
+(6,5,'2006-05-25','y'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(1,5,'2008-01-23','t'),(6,5,'2007-06-18','d'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','f'),
+(4,5,'2001-06-05','x'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(1,5,'2008-01-23','t'),(6,5,'2007-06-18','d'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(6,5,'2007-06-18','d'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(1,5,'2008-01-23','t'),(6,5,'2007-06-18','d'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,1,'1900-01-01','r'),
+(8,8,'1900-01-01','m'),(4,1,'2006-03-09','b'),
+(4,1,'2001-06-05','x'),(7,1,'2006-05-28','g');
+
+CREATE TABLE t2 (
+ f INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
+ g INT,
+ h VARCHAR(1),
+ KEY (g)
+);
+
+INSERT INTO t2 (g,h) VALUES
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(5,'l'),(8,'y'),(0,'p'),(0,'f'),(0,'p'),(7,'d'),
+(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'),
+(6,'i'),(1,'x'),(5,'l'),(8,'y'),(0,'p'),(0,'f'),
+(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(7,'d'),(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),
+(9,'u'),(6,'i'),(1,'x'),(5,'l'),(8,'y'),(0,'p'),
+(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),
+(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),(5,'l'),
+(6,'q'),(2,'n'),(4,'r'),(4,'b'),(8,'y'),(0,'p'),
+(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),
+(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),(5,'l'),
+(8,'y'),(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),
+(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),
+(1,'x'),(5,'l'),(8,'y'),(0,'p'),(0,'f'),(0,'p'),
+(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),
+(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),(7,'d'),
+(7,'f'),(5,'j'),(3,'e'),(1,'u'),(0,'f'),(0,'p'),
+(7,'d'),(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),
+(9,'u'),(6,'i'),(1,'x'),(5,'l'),(8,'y'),(0,'p'),
+(0,'f'),(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),
+(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),
+(1,'x'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),(1,'u'),
+(4,'v'),(9,'u'),(6,'i'),(1,'x'),(5,'l'),(8,'y'),
+(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(5,'l'),(6,'q'),(2,'n'),(4,'r'),(4,'b'),(8,'y'),
+(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u');
+
+SET @save_optimize_switch=@@optimizer_switch;
+SET optimizer_switch='materialization=on';
+
+EXPLAIN
+SELECT COUNT(*) FROM t1 AS t, t2
+WHERE c = g
+ AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b)
+ OR a = 0 AND h < 'z' );
+
+SELECT COUNT(*) FROM t1 AS t, t2
+WHERE c = g
+ AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b)
+ OR a = 0 AND h < 'z' );
+SELECT COUNT(*) FROM t1 AS t, t2
+WHERE c = g
+ AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b)
+ OR a = 0 AND h < 'z' );
+
+SET optimizer_switch=@save_optimizer_switch;
+
+DROP TABLE t1,t2;
+
+--echo # check "Handler_pushed" status varuiables
+CREATE TABLE t1 (
+ c1 CHAR(1),
+ c2 CHAR(1),
+ KEY (c1)
+);
+
+INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5');
+
+flush status;
+show status like "Handler_icp%";
+
+SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ;
+
+show status like "Handler_icp%";
+
+SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ;
+
+show status like "Handler_icp%";
+
+DROP TABLE t1;
+
+#
+# MDEV-308 lp:1008516 - Failing assertion: templ->mysql_col_len == len
+#
+create table t1 (a int,b char(5),primary key (a), key (b(1)));
+insert into t1 values ('a','b');
+select 1 from t1 where a and b >= 'aa';
+drop table t1;
+
+--echo #
+--echo # Bug#58015 "Assert in row_sel_field_store_in_mysql_format
+--echo # when running innodb_mrr_icp test"
+--echo #
+
+create table t1 (a char(2) charset utf8,b double, primary key (a(1)),key (b));
+insert into t1 values ('',1);
+select 1 from t1 where b <= 1 and a <> '';
+drop table t1;
+
diff --git a/mysql-test/include/index_merge1.inc b/mysql-test/include/index_merge1.inc
index d137b0957c0..4ad9c2046e0 100644
--- a/mysql-test/include/index_merge1.inc
+++ b/mysql-test/include/index_merge1.inc
@@ -194,7 +194,7 @@ alter table t2 add index i321(key3, key2, key1);
explain select key3 from t2 where key1 = 100 or key2 = 100;
# index_merge vs 'index', 'index' is better.
-explain select key3 from t2 where key1 <100 or key2 < 100;
+explain select key3 from t2 where key1 < 500 or key2 < 500;
# index_merge vs 'all', index_merge is better.
explain select key7 from t2 where key1 <100 or key2 < 100;
@@ -264,7 +264,10 @@ explain select * from t1 where key1=3 or key2=4
union select * from t1 where key1<4 or key3=5;
# index merge in subselect
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
explain select * from (select * from t1 where key1 = 3 or key2 =3) as Z where key8 >5;
+set optimizer_switch=@tmp_optimizer_switch;
# 12. check for long index_merges.
create table t3 like t0;
@@ -334,12 +337,12 @@ update t0 set key2=1, key3=1, key4=1, key5=1,key6=1,key7=1 where key7 < 500;
--replace_column 9 #
--replace_result "4,4,4,4,4,4,4" X "4,4,4,4,4,4" X "i6,i7" "i6,i7?" "i6" "i6,i7?"
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, t0 as B
+ from t0 as A straight_join 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)
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);
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
+ from t0 as A straight_join 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)
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);
@@ -539,7 +542,7 @@ INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
-SET SESSION sort_buffer_size=1;
+SET SESSION sort_buffer_size=1024*8;
EXPLAIN
SELECT * FROM t1 FORCE INDEX(a,b) WHERE a LIKE 'a%' OR b LIKE 'b%'
ORDER BY a,b;
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 f408544ef59..65e488c538f 100644
--- a/mysql-test/include/mix1.inc
+++ b/mysql-test/include/mix1.inc
@@ -1183,8 +1183,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='in_to_exists=on,materialization=off';
explain
-select b from t1 where a not in (select b from t1,t2 group by a) group by a;
+select b from t1 where a not in (select max(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/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql
index b8b4f60224c..8e370871ae0 100644
--- a/mysql-test/include/mtr_warnings.sql
+++ b/mysql-test/include/mtr_warnings.sql
@@ -122,7 +122,6 @@ INSERT INTO global_suppressions VALUES
("Slave: The incident LOST_EVENTS occured on the master"),
("Slave: Unknown error.* 1105"),
("Slave: Can't drop database.* database doesn't exist"),
- ("Sort aborted"),
("Time-out in NDB"),
("Warning:\s+One can only use the --user.*root"),
("Warning:\s+Table:.* on (delete|rename)"),
@@ -180,6 +179,17 @@ INSERT INTO global_suppressions VALUES
("==[0-9]*== Warning: invalid file descriptor -1 in syscall write()"),
("==[0-9]*== Warning: invalid file descriptor -1 in syscall read()"),
+ /*
+ Transient network failures that cause warnings on reconnect.
+ BUG#47743 and BUG#47983.
+ */
+ ("Slave I/O: Get master SERVER_ID failed with error:.*"),
+ ("Slave I/O: Get master clock failed with error:.*"),
+ ("Slave I/O: Get master COLLATION_SERVER failed with error:.*"),
+ ("Slave I/O: Get master TIME_ZONE failed with error:.*"),
+ ("Slave I/O: The slave I/O thread stops because a fatal error is encountered when it tried to SET @master_binlog_checksum on master.*"),
+ ("Slave I/O: Get master BINLOG_CHECKSUM failed with error.*"),
+ ("Slave I/O: Notifying master by SET @master_binlog_checksum= @@global.binlog_checksum failed with error.*"),
("THE_LAST_SUPPRESSION")||
diff --git a/mysql-test/include/ps_conv.inc b/mysql-test/include/ps_conv.inc
index 9ac943d5bdd..2e42542d19a 100644
--- a/mysql-test/include/ps_conv.inc
+++ b/mysql-test/include/ps_conv.inc
@@ -106,7 +106,7 @@ drop table t5 ;
# c1 tinyint, c2 smallint, c3 mediumint, c4 int,
# c5 integer, c6 bigint, c7 float, c8 double,
# c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
-# c13 date, c14 datetime, c15 timestamp(14), c16 time,
+# c13 date, c14 datetime, c15 timestamp, c16 time,
# c17 year, c18 tinyint, c19 bool, c20 char,
# c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
# c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
@@ -672,7 +672,6 @@ select '-- insert into string columns --' as test_sequence ;
--enable_query_log
######## INSERT into .. string columns values(CHAR(n),LONGTEXT) ########
---disable_query_log
insert into t9
( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
values
@@ -860,8 +859,6 @@ values
execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
@arg00, @arg00, @arg00, @arg00 ;
---enable_query_log
-
######## SELECT of all inserted records ########
select c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30
from t9 where c1 >= 20
@@ -980,14 +977,13 @@ delete from t9 ;
######################### test of date/time columns ########################
# #
-# c13 date, c14 datetime, c15 timestamp(14), c16 time, c17 year #
+# c13 date, c14 datetime, c15 timestamp, c16 time, c17 year #
# #
############################################################################
--disable_query_log
select '-- insert into date/time columns --' as test_sequence ;
--enable_query_log
######## INSERT into .. date/time columns values(VARCHAR(19),LONGTEXT) ########
---disable_query_log
set @arg00= '1991-01-01 01:01:01' ;
insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -1143,12 +1139,9 @@ values
( 83, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
---enable_query_log
-
######## SELECT of all inserted records ########
select c1, c13, c14, c15, c16, c17 from t9 order by c1 ;
-
--disable_query_log
select '-- select .. where date/time column = .. --' as test_sequence ;
--enable_query_log
@@ -1156,19 +1149,19 @@ select '-- select .. where date/time column = .. --' as test_sequence ;
set @arg00= '1991-01-01 01:01:01' ;
select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
- c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+ c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01' ;
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
- c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+ c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01'" ;
execute stmt1 ;
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
######## SELECT .. WHERE column(date/time/..)=value(DATETIME/LONGBLOB) ########
@@ -1177,21 +1170,39 @@ select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
- c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime) ;
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
- c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime)" ;
execute stmt1 ;
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
+
+
+######## SELECT .. WHERE column(date/time/..)=value(CHAR(n)/LONGTEXT) ########
+set @arg00= '01:01:01' ;
+select 'true' as found from t9 where c1= 20 and c16= '01:01:01' ;
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= '01:01:01'" ;
+execute stmt1 ;
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
+
+
+######## SELECT .. WHERE column(date/time/..)=value(DATETIME/LONGBLOB) ########
+set @arg00= CAST('01:01:01' as time) ;
+select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time) ;
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time)" ;
+execute stmt1 ;
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
######## SELECT .. WHERE column(year)=value(INT(10)/BIGINT) ########
diff --git a/mysql-test/include/ps_query.inc b/mysql-test/include/ps_query.inc
index ae6027a0e07..8148935cbe1 100644
--- a/mysql-test/include/ps_query.inc
+++ b/mysql-test/include/ps_query.inc
@@ -597,7 +597,6 @@ execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06,
--enable_result_log
drop table t2 ;
-
##### test case derived from client_test.c: test_bug4079()
--error 1242
select 1 < (select a from t1) ;
diff --git a/mysql-test/include/show_binlog_events.inc b/mysql-test/include/show_binlog_events.inc
index 6d8c8196102..a55ac983a52 100644
--- a/mysql-test/include/show_binlog_events.inc
+++ b/mysql-test/include/show_binlog_events.inc
@@ -3,7 +3,7 @@
#
# Useage:
# let $binlog_file= master-bin.000002;
-# let $binlog_start= 106;
+# let $binlog_start= 240;
# let $binlog_limit= 1, 3;
# source include/show_binlog_events.inc;
#
diff --git a/mysql-test/include/show_binlog_events2.inc b/mysql-test/include/show_binlog_events2.inc
index 5dd272c562d..c32d12537fd 100644
--- a/mysql-test/include/show_binlog_events2.inc
+++ b/mysql-test/include/show_binlog_events2.inc
@@ -1,4 +1,4 @@
---let $binlog_start=106
+--let $binlog_start=245
--replace_result $binlog_start <binlog_start>
--replace_column 2 # 5 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
diff --git a/mysql-test/include/subselect_mat_cost.inc b/mysql-test/include/subselect_mat_cost.inc
new file mode 100644
index 00000000000..04b116e9527
--- /dev/null
+++ b/mysql-test/include/subselect_mat_cost.inc
@@ -0,0 +1,152 @@
+-- echo
+-- echo /* A. Subqueries in the SELECT clause. */
+explain
+select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
+select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
+-- echo
+explain
+select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
+select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
+-- echo
+explain
+select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
+select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
+
+-- echo
+-- echo /*
+-- echo B. "Natural" examples of subqueries without grouping that
+-- echo cannot be flattened into semijoin.
+-- echo */
+
+explain
+select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
+select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
+-- echo
+explain
+select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
+select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
+-- echo UNION subqueries are currently limited to only use IN-TO-EXISTS.
+explain
+select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
+select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
+-- echo
+explain
+select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
+select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
+-- echo
+explain
+select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
+select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
+
+-- echo
+-- echo /* C. Subqueries in the WHERE clause with GROUP BY. */
+explain
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
+-- echo
+explain
+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);
+-- echo
+explain
+select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
+select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
+-- echo
+explain
+select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
+select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
+-- echo
+explain
+select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
+select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
+-- echo
+explain
+select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
+select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
+
+-- echo
+-- echo /*
+-- echo D. Subqueries for which materialization is not possible, and the
+-- echo optimizer reverts to in-to-exists.
+-- echo */
+# The first two cases are rejected during the prepare phase by the procedure
+# subquery_types_allow_materialization().
+explain
+select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
+select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
+explain
+select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
+select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
+-- echo
+# The following two subqueries return the result of a string function with a
+# blob argument, where the return type may be != blob. These are rejected during
+# cost-based optimization when attempting to create a temporary table.
+explain
+select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
+select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
+explain
+select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
+select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
+-- echo
+
+
+-- echo
+-- echo /* E. Edge cases. */
+-- echo
+
+-- echo /* E.1 Both materialization and in_to_exists cannot be off. */
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch = 'materialization=off,in_to_exists=off';
+--error ER_ILLEGAL_SUBQUERY_OPTIMIZER_SWITCHES
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
+set @@optimizer_switch = @save_optimizer_switch;
+
+-- echo /* E.2 Outer query without tables, always uses IN-TO-EXISTS. */
+explain
+select '1 - 03' in (select b1 from t2 where b1 > '0');
+select '1 - 03' in (select b1 from t2 where b1 > '0');
+
+-- echo /* E.3 Subqueries without tables. */
+explain
+select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
+select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
+-- echo UNION subqueries are currently limited to only use IN-TO-EXISTS.
+explain
+select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
+select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
+
+-- echo /* E.4 optimize_cond detects FALSE where/having clause. */
+explain
+select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
+select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
+
+-- echo /* E.5 opt_sum_query detects no matching min/max row or substitutes MIN/MAX with a const. */
+-- echo TODO this test produces wrong result due to missing logic to handle the case
+-- echo when JOIN::optimize detects an empty subquery result.
+explain
+select a1 from t1 where a1 in (select max(b1) from t2);
+select a1 from t1 where a1 in (select max(b1) from t2);
+-- echo
+explain
+select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
+select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
+
+-- echo /* E.6 make_join_select detects impossible WHERE. *
+
+-- echo TODO
+
+-- echo /* E.7 constant optimization detects "no matching row in const table". */
+
+-- echo TODO
+
+-- echo /* E.8 Impossible WHERE noticed after reading const tables. */
+explain
+select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
+select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
+
+-- echo
+-- echo /* F. UPDATE/DELETE with subqueries. */
+-- echo
+
+-- echo TODO
+-- echo
diff --git a/mysql-test/include/type_hrtime.inc b/mysql-test/include/type_hrtime.inc
new file mode 100644
index 00000000000..cd631f25632
--- /dev/null
+++ b/mysql-test/include/type_hrtime.inc
@@ -0,0 +1,128 @@
+
+--source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1, t2, t3;
+--enable_warnings
+
+--error ER_TOO_BIG_PRECISION
+eval create table t1 (a $type(7));
+
+eval create table t1 (a $type(3), key(a));
+insert t1 values ('2010-12-11 00:20:03.1234');
+insert t1 values ('2010-12-11 15:47:11.1234');
+insert t1 values (20101211010203.45678);
+insert t1 values (20101211030405.789e0);
+insert t1 values (99991231235959e1);
+select * from t1;
+--replace_regex /121000/121094/ /457000/457031/ /789000/789062/
+select truncate(a, 6) from t1; # Field::val_real()
+select a DIV 1 from t1; # Field::val_int()
+select group_concat(distinct a) from t1; # Field::cmp()
+alter table t1 engine=innodb;
+select * from t1 order by a;
+select * from t1 order by a+0;
+drop table t1;
+eval create table t1 (a $type(4)) engine=innodb;
+insert t1 values ('2010-12-11 01:02:03.456789');
+select * from t1;
+select extract(microsecond from a + interval 100 microsecond) from t1 where a>'2010-11-12 01:02:03.456';
+select a from t1 where a>'2010-11-12 01:02:03.456' group by a;
+
+#
+# metadata
+#
+show create table t1;
+show columns from t1;
+--query_vertical select table_name, column_name, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra from information_schema.columns where table_name='t1'
+
+#
+# update/delete
+#
+select a, a+interval 9876543 microsecond from t1;
+update t1 set a=a+interval 9876543 microsecond;
+select * from t1;
+select a, a + interval 2 year from t1;
+insert t1 select a + interval 2 year from t1;
+select * from t1;
+delete from t1 where a < 20110101;
+select * from t1;
+
+#
+# create ... select
+#
+create table t2 select * from t1;
+create table t3 like t1;
+
+show create table t2;
+show create table t3;
+drop table t2, t3;
+
+# math, aggregation
+insert t1 values ('2010-12-13 14:15:16.222222');
+select a, a+0, a-1, a*1, a/2 from t1;
+select max(a), min(a), sum(a), avg(a) from t1;
+create table t2 select a, a+0, a-1, a*1, a/2 from t1;
+create table t3 select max(a), min(a), sum(a), avg(a) from t1;
+show create table t2;
+show create table t3;
+
+drop table t1, t2, t3;
+
+# insert, alter with conversion
+--vertical_results
+eval create table t1 (f0_$type $type(0), f1_$type $type(1), f2_$type $type(2), f3_$type $type(3), f4_$type $type(4), f5_$type $type(5), f6_$type $type(6));
+insert t1 values ( '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432');
+select * from t1;
+eval select cast(f0_$type as time(4)) time4_f0_$type, cast(f1_$type as datetime(3)) datetime3_f1_$type, cast(f2_$type as date) date_f2_$type, cast(f4_$type as double) double_f3_$type, cast(f4_$type as decimal(40,5)) decimal5_f4_$type, cast(f5_$type as signed) bigint_f5_$type, cast(f6_$type as char(255)) varchar_f6_$type from t1;
+eval create table t2 (time4_f0_$type time(4), datetime3_f1_$type datetime(3), date_f2_$type date, double_f3_$type double, decimal5_f4_$type decimal(40,5), bigint_f5_$type bigint, varchar_f6_$type varchar(255));
+insert t2 select * from t1;
+select * from t2;
+eval alter table t1 change f0_$type time4_f0_$type time(4), change f1_$type datetime3_f1_$type datetime(3), change f2_$type date_f2_$type date, change f3_$type double_f3_$type double, change f4_$type decimal5_f4_$type decimal(40,5), change f5_$type bigint_f5_$type bigint, change f6_$type varchar_f6_$type varchar(255);
+select * from t1;
+eval alter table t1 modify time4_f0_$type $type(0), modify datetime3_f1_$type $type(1), modify date_f2_$type $type(2), modify double_f3_$type $type(3), modify decimal5_f4_$type $type(4), modify bigint_f5_$type $type(5), modify varchar_f6_$type $type(6);
+select * from t1;
+delete from t1;
+insert t1 select * from t2;
+select * from t1;
+drop table t1, t2;
+--horizontal_results
+
+#
+# SP
+#
+eval create table t1 (a $type(6), b $type(6));
+eval create procedure foo(x $type, y $type(4)) insert into t1 values (x, y);
+call foo('2010-02-03 4:5:6.789123', '2010-02-03 4:5:6.789123');
+select * from t1;
+delimiter |;
+eval create procedure bar(a int, c $type(5))
+begin
+ declare b $type(4);
+ set b = c + interval a microsecond;
+ insert t1 values (b, c + interval a microsecond);
+end|
+delimiter ;|
+call bar(1111111, '2011-01-02 3:4:5.123456');
+select * from t1;
+drop procedure foo;
+drop procedure bar;
+eval create function xyz(s char(20)) returns $type(4)
+ return addtime('2010-10-10 10:10:10.101010', s);
+select xyz('1:1:1.010101');
+drop function xyz;
+
+#
+# Views
+#
+
+create view v1 as select * from t1 group by a,b;
+select * from v1;
+show columns from v1;
+create table t2 select * from v1;
+show create table t2;
+select * from t2;
+
+drop view v1;
+drop table t1, t2;
+
diff --git a/mysql-test/include/world.inc b/mysql-test/include/world.inc
new file mode 100755
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 100755
index 00000000000..c683faf0114
--- /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/lib/v1/mysql-test-run.pl b/mysql-test/lib/v1/mysql-test-run.pl
index ef4de686bab..40d92cdb676 100755
--- a/mysql-test/lib/v1/mysql-test-run.pl
+++ b/mysql-test/lib/v1/mysql-test-run.pl
@@ -2387,8 +2387,11 @@ sub remove_stale_vardir () {
mtr_report("WARNING: Using the 'mysql-test/var' symlink");
# Make sure the directory where it points exist
- mtr_error("The destination for symlink $opt_vardir does not exist")
- if ! -d readlink($opt_vardir);
+ if (! -d readlink($opt_vardir))
+ {
+ mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory");
+ unlink($opt_vardir);
+ }
foreach my $bin ( glob("$opt_vardir/*") )
{
@@ -2447,8 +2450,11 @@ sub setup_vardir() {
# it's a symlink
# Make sure the directory where it points exist
- mtr_error("The destination for symlink $opt_vardir does not exist")
- if ! -d readlink($opt_vardir);
+ if (! -d readlink($opt_vardir))
+ {
+ mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory");
+ unlink($opt_vardir);
+ }
}
elsif ( $opt_mem )
{
@@ -5301,6 +5307,7 @@ sub valgrind_arguments {
{
mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option
mtr_add_arg($args, "--leak-check=yes");
+ #mtr_add_arg($args, "--db-attach=yes");
mtr_add_arg($args, "--num-callers=16");
mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir)
if -f "$glob_mysql_test_dir/valgrind.supp";
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 60253a06276..740dea5fa68 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -160,7 +160,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,plugins";
+my $DEFAULT_SUITES="main,binlog,federated,rpl,maria,handler,parts,innodb," .
+ "innodb_plugin,percona,ndb,vcol,oqgraph,sphinx," .
+ "optimizer_unfixed_bugs,plugins";
my $opt_suites;
our $opt_verbose= 0; # Verbose output, enable with --verbose
@@ -337,9 +339,10 @@ sub main {
gcov_prepare($basedir . "/" . $opt_gcov_src_dir);
}
+
if (!$opt_suites) {
$opt_suites= $DEFAULT_SUITES;
-
+
# Check for any extra suites to enable based on the path name
my %extra_suites=
(
@@ -2095,6 +2098,13 @@ sub environment_setup {
push(@ld_library_paths, "$basedir/libmysql/.libs/",
"$basedir/libmysql_r/.libs/",
"$basedir/zlib/.libs/");
+ if ($^O eq "darwin")
+ {
+ # it is MAC OS and we have to add dynamic libraries paths
+ push @ld_library_paths, grep {<$_/*.dylib>}
+ (<$bindir/storage/*/.libs/>,<$bindir/plugin/*/.libs/>,
+ <$bindir/plugin/*/*/.libs/>,<$bindir/storage/*/*/.libs>);
+ }
}
else
{
@@ -2501,7 +2511,7 @@ sub setup_vardir() {
}
else
{
- for (<$bindir/storage/*/.libs/*.so>,<$bindir/plugin/*/.libs/*.so>,<$bindir/sql/.libs/*.so>)
+ for (<$bindir/storage/*/.libs/*.so>,<$bindir/plugin/*/.libs/*.so>,<$bindir/plugin/*/*/.libs/*.so>,<$bindir/sql/.libs/*.so>)
{
my $pname=basename($_);
symlink rel2abs($_), "$plugindir/$pname";
@@ -2512,7 +2522,8 @@ sub setup_vardir() {
else
{
# hm, what paths work for debs and for rpms ?
- for (<$bindir/lib/mysql/plugin/*.so>,
+ for (<$bindir/lib64/mysql/plugin/*.so>,
+ <$bindir/lib/mysql/plugin/*.so>,
<$bindir/lib/plugin/*.dll>)
{
my $pname=basename($_);
@@ -4366,8 +4377,9 @@ sub get_log_from_proc ($$) {
# error log and write all lines that look
# suspicious into $error_log.warnings
#
-sub extract_warning_lines ($) {
- my ($error_log) = @_;
+
+sub extract_warning_lines ($$) {
+ my ($error_log, $append) = @_;
# Open the servers .err log file and read all lines
# belonging to current tets into @lines
@@ -4404,9 +4416,12 @@ sub extract_warning_lines ($) {
# Write all suspicious lines to $error_log.warnings file
my $warning_log = "$error_log.warnings";
- my $Fwarn = IO::File->new($warning_log, "w")
+ my $Fwarn = IO::File->new($warning_log, $append ? "a+" : "w")
or die("Could not open file '$warning_log' for writing: $!");
- print $Fwarn "Suspicious lines from $error_log\n";
+ if (!$append)
+ {
+ print $Fwarn "Suspicious lines from $error_log\n";
+ }
my @patterns =
(
@@ -4465,6 +4480,7 @@ sub extract_warning_lines ($) {
qr|Checking table: '\..mtr.test_suppressions'|,
qr|Table \./test/bug53592 has a primary key in InnoDB data dictionary, but not in MySQL|,
qr|Table '\..mtr.test_suppressions' is marked as crashed and should be repaired|,
+ qr|Can't open shared library.*ha_archive|,
qr|InnoDB: Error: table 'test/bug39438'|,
qr|Access denied for user|,
qr|Aborted connection|,
@@ -4515,7 +4531,7 @@ sub start_check_warnings ($$) {
my $log_error= $mysqld->value('#log-error');
# To be communicated to the test
$ENV{MTR_LOG_ERROR}= $log_error;
- extract_warning_lines($log_error);
+ extract_warning_lines($log_error, 0);
my $args;
mtr_init_args(\$args);
@@ -4670,7 +4686,7 @@ sub check_warnings_post_shutdown {
foreach my $mysqld ( mysqlds())
{
my ($testlist, $match_lines)=
- extract_warning_lines($mysqld->value('#log-error'));
+ extract_warning_lines($mysqld->value('#log-error'), 1);
$testname_hash->{$_}= 1 for @$testlist;
$report.= join('', @$match_lines);
}
@@ -4981,6 +4997,8 @@ sub mysqld_arguments ($$$) {
mtr_add_arg($args, "--loose-skip-safemalloc");
mtr_add_arg($args, "%s--disable-sync-frm");
+ # Retry bind as this may fail on busy server
+ mtr_add_arg($args, "%s--port-open-timeout=10");
if (!using_extern() and $mysql_version_id >= 50106 && !$opt_user_args)
{
@@ -5139,10 +5157,10 @@ sub mysqld_start ($$) {
# Write a message about this to the normal log file
my $trace_name= "$opt_vardir/log/".$mysqld->name().".trace";
mtr_tofile($output,
- "NOTE: When running with --valgrind --debug the output from",
- "mysqld(where the valgrind messages shows up) is stored ",
+ "NOTE: When running with --valgrind --debug the output from ",
+ "mysqld (where the valgrind messages shows up) is stored ",
"together with the trace file to make it ",
- "easier to find the exact position of valgrind errors.",
+ "easier to find the exact position of valgrind errors. ",
"See trace file $trace_name.\n");
$output= $trace_name;
diff --git a/mysql-test/r/adddate_454.result b/mysql-test/r/adddate_454.result
new file mode 100644
index 00000000000..0993cdce32c
--- /dev/null
+++ b/mysql-test/r/adddate_454.result
@@ -0,0 +1,10 @@
+create table t1 (d date);
+insert into t1 values ('2012-00-00');
+select * from t1;
+d
+2012-00-00
+update t1 set d = adddate(d, interval 1 day);
+select * from t1;
+d
+NULL
+drop table t1;
diff --git a/mysql-test/r/alter_table_online.result b/mysql-test/r/alter_table_online.result
new file mode 100644
index 00000000000..83e82191541
--- /dev/null
+++ b/mysql-test/r/alter_table_online.result
@@ -0,0 +1,74 @@
+drop table if exists t1,t2,t3;
+create table t1 (a int not null primary key, b int, c varchar(80), e enum('a','b'));
+insert into t1 (a) values (1),(2),(3);
+alter online table t1 modify b int default 5;
+alter online table t1 change b new_name int;
+alter online table t1 modify e enum('a','b','c');
+alter online table t1 comment "new comment";
+alter online table t1 rename to t2;
+alter online table t2 rename to t1;
+drop table t1;
+create temporary table t1 (a int not null primary key, b int, c varchar(80), e enum('a','b'));
+insert into t1 (a) values (1),(2),(3);
+alter online table t1 modify b int default 5;
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 change b new_name int;
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 modify e enum('a','b','c');
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 comment "new comment";
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 rename to t2;
+ERROR HY000: Can't execute the given 'ALTER' command as online
+drop table t1;
+create table t1 (a int not null primary key, b int, c varchar(80), e enum('a','b'));
+insert into t1 (a) values (1),(2),(3);
+alter online table t1 drop column b, add b int;
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 modify b bigint;
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 modify e enum('c','a','b');
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 modify c varchar(50);
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 modify c varchar(100);
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 add f int;
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 engine=memory;
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter table t1 engine=innodb;
+alter table t1 add index (b);
+alter online table t1 add index c (c);
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 drop index b;
+ERROR HY000: Can't execute the given 'ALTER' command as online
+drop table t1;
+create temporary table t1 (a int not null primary key, b int, c varchar(80), e enum('a','b'));
+insert into t1 (a) values (1),(2),(3);
+alter online table t1 drop column b, add b int;
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 modify b bigint;
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 modify e enum('c','a','b');
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 modify c varchar(50);
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 modify c varchar(100);
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 add f int;
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 engine=memory;
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter table t1 engine=innodb;
+alter table t1 add index (b);
+alter online table t1 add index c (c);
+ERROR HY000: Can't execute the given 'ALTER' command as online
+alter online table t1 drop index b;
+ERROR HY000: Can't execute the given 'ALTER' command as online
+drop table t1;
+create table t1 (a int not null primary key, b int, c varchar(80));
+create table t2 (a int not null primary key, b int, c varchar(80));
+create table t3 (a int not null primary key, b int, c varchar(80)) engine=merge UNION=(t1);
+alter online table t3 union=(t1,t2);
+drop table t1,t2,t3;
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result
index 0ec84efa842..f2cdf2adfca 100644
--- a/mysql-test/r/archive.result
+++ b/mysql-test/r/archive.result
@@ -12801,3 +12801,14 @@ OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
DROP TABLE t1;
+#
+# BUG#917689 Using wrong archive table causes crash
+#
+create table t1 (a int, b char(50)) engine=archive;
+select * from t1;
+ERROR HY000: Table 't1' is marked as crashed and should be repaired
+show warnings;
+Level Code Message
+Error 127 Got error 127 when reading table `test`.`t1`
+Error 1194 Table 't1' is marked as crashed and should be repaired
+drop table t1;
diff --git a/mysql-test/r/archive_gis.result b/mysql-test/r/archive_gis.result
index 178c5716911..ddc1907cced 100644
--- a/mysql-test/r/archive_gis.result
+++ b/mysql-test/r/archive_gis.result
@@ -236,7 +236,7 @@ explain extended select Dimension(g), GeometryType(g), IsEmpty(g), AsText(Envelo
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_geometry ALL NULL NULL NULL NULL 21 100.00
Warnings:
-Note 1003 select dimension(`test`.`gis_geometry`.`g`) AS `Dimension(g)`,geometrytype(`test`.`gis_geometry`.`g`) AS `GeometryType(g)`,isempty(`test`.`gis_geometry`.`g`) AS `IsEmpty(g)`,astext(envelope(`test`.`gis_geometry`.`g`)) AS `AsText(Envelope(g))` from `test`.`gis_geometry`
+Note 1003 select st_dimension(`test`.`gis_geometry`.`g`) AS `Dimension(g)`,st_geometrytype(`test`.`gis_geometry`.`g`) AS `GeometryType(g)`,st_isempty(`test`.`gis_geometry`.`g`) AS `IsEmpty(g)`,st_astext(st_envelope(`test`.`gis_geometry`.`g`)) AS `AsText(Envelope(g))` from `test`.`gis_geometry`
SELECT fid, X(g) FROM gis_point ORDER by fid;
fid X(g)
101 10
@@ -253,7 +253,7 @@ explain extended select X(g),Y(g) FROM gis_point;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_point ALL NULL NULL NULL NULL 4 100.00
Warnings:
-Note 1003 select x(`test`.`gis_point`.`g`) AS `X(g)`,y(`test`.`gis_point`.`g`) AS `Y(g)` from `test`.`gis_point`
+Note 1003 select st_x(`test`.`gis_point`.`g`) AS `X(g)`,st_y(`test`.`gis_point`.`g`) AS `Y(g)` from `test`.`gis_point`
SELECT fid, AsText(StartPoint(g)) FROM gis_line ORDER by fid;
fid AsText(StartPoint(g))
105 POINT(0 0)
@@ -288,7 +288,7 @@ explain extended select AsText(StartPoint(g)),AsText(EndPoint(g)),GLength(g),Num
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_line ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select astext(startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint(g))`,astext(endpoint(`test`.`gis_line`.`g`)) AS `AsText(EndPoint(g))`,glength(`test`.`gis_line`.`g`) AS `GLength(g)`,numpoints(`test`.`gis_line`.`g`) AS `NumPoints(g)`,astext(pointn(`test`.`gis_line`.`g`,2)) AS `AsText(PointN(g, 2))`,isclosed(`test`.`gis_line`.`g`) AS `IsClosed(g)` from `test`.`gis_line`
+Note 1003 select st_astext(st_startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint(g))`,st_astext(st_endpoint(`test`.`gis_line`.`g`)) AS `AsText(EndPoint(g))`,st_length(`test`.`gis_line`.`g`) AS `GLength(g)`,st_numpoints(`test`.`gis_line`.`g`) AS `NumPoints(g)`,st_astext(st_pointn(`test`.`gis_line`.`g`,2)) AS `AsText(PointN(g, 2))`,st_isclosed(`test`.`gis_line`.`g`) AS `IsClosed(g)` from `test`.`gis_line`
SELECT fid, AsText(Centroid(g)) FROM gis_polygon ORDER by fid;
fid AsText(Centroid(g))
108 POINT(15 15)
@@ -318,7 +318,7 @@ explain extended select AsText(Centroid(g)),Area(g),AsText(ExteriorRing(g)),NumI
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_polygon ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select astext(centroid(`test`.`gis_polygon`.`g`)) AS `AsText(Centroid(g))`,area(`test`.`gis_polygon`.`g`) AS `Area(g)`,astext(exteriorring(`test`.`gis_polygon`.`g`)) AS `AsText(ExteriorRing(g))`,numinteriorrings(`test`.`gis_polygon`.`g`) AS `NumInteriorRings(g)`,astext(interiorringn(`test`.`gis_polygon`.`g`,1)) AS `AsText(InteriorRingN(g, 1))` from `test`.`gis_polygon`
+Note 1003 select st_astext(st_centroid(`test`.`gis_polygon`.`g`)) AS `AsText(Centroid(g))`,st_area(`test`.`gis_polygon`.`g`) AS `Area(g)`,st_astext(st_exteriorring(`test`.`gis_polygon`.`g`)) AS `AsText(ExteriorRing(g))`,st_numinteriorrings(`test`.`gis_polygon`.`g`) AS `NumInteriorRings(g)`,st_astext(st_interiorringn(`test`.`gis_polygon`.`g`,1)) AS `AsText(InteriorRingN(g, 1))` from `test`.`gis_polygon`
SELECT fid, IsClosed(g) FROM gis_multi_line ORDER by fid;
fid IsClosed(g)
114 0
@@ -357,7 +357,7 @@ explain extended SELECT fid, NumGeometries(g) from gis_multi_point;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,numgeometries(`test`.`gis_multi_point`.`g`) AS `NumGeometries(g)` from `test`.`gis_multi_point`
+Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_numgeometries(`test`.`gis_multi_point`.`g`) AS `NumGeometries(g)` from `test`.`gis_multi_point`
SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point ORDER by fid;
fid AsText(GeometryN(g, 2))
111 POINT(10 10)
@@ -385,17 +385,17 @@ explain extended SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,astext(geometryn(`test`.`gis_multi_point`.`g`,2)) AS `AsText(GeometryN(g, 2))` from `test`.`gis_multi_point`
+Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_astext(st_geometryn(`test`.`gis_multi_point`.`g`,2)) AS `AsText(GeometryN(g, 2))` from `test`.`gis_multi_point`
SELECT g1.fid as first, g2.fid as second,
Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o,
Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
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;
first second w c o e d t i r
-120 120 1 1 0 1 0 0 1 0
+120 120 1 1 0 1 0 1 1 0
120 121 0 0 1 0 0 0 1 0
121 120 0 0 1 0 0 0 1 0
-121 121 1 1 0 1 0 0 1 0
+121 121 1 1 0 1 0 1 1 0
explain extended SELECT g1.fid as first, g2.fid as second,
Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o,
Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
@@ -403,9 +403,9 @@ 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`
+Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,st_within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,st_contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,mbroverlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,st_equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,mbrdisjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,st_touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,mbrintersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,st_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;
CREATE TABLE t1 (
a INTEGER PRIMARY KEY AUTO_INCREMENT,
@@ -494,7 +494,7 @@ mbroverlaps
down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrtouches
-down2,left2,right2,up2
+big,center,down,down2,left,left2,right,right2,small,up,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrwithin
big,center
@@ -515,7 +515,7 @@ overlaps
down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
touches
-down2,left2,right2,up2
+big,center,down,down2,left,left2,right,right2,small,up,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
within
big,center
diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result
index 8f9b75fc664..ac03f3f924a 100644
--- a/mysql-test/r/bigint.result
+++ b/mysql-test/r/bigint.result
@@ -362,12 +362,12 @@ select cast(19999999999999999999 as signed);
cast(19999999999999999999 as signed)
9223372036854775807
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '19999999999999999999' to INT. Value truncated.
select cast(-19999999999999999999 as signed);
cast(-19999999999999999999 as signed)
-9223372036854775808
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-19999999999999999999' to INT. Value truncated.
select -9223372036854775808;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def -9223372036854775808 8 20 20 N 32897 0 63
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index 811bbee1d91..ef92c7dcc88 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -222,3 +222,10 @@ CREATE TABLE t1(a YEAR);
SELECT 1 FROM t1 WHERE a=1 AND CASE 1 WHEN a THEN 1 ELSE 1 END;
1
DROP TABLE t1;
+create table t1 (f1 time);
+insert t1 values ('00:00:00'),('00:01:00');
+select case t1.f1 when '00:00:00' then 1 end from t1;
+case t1.f1 when '00:00:00' then 1 end
+1
+NULL
+drop table t1;
diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result
index d7a7503707b..37550ce77f2 100644
--- a/mysql-test/r/cast.result
+++ b/mysql-test/r/cast.result
@@ -1,9 +1,13 @@
select CAST(1-2 AS UNSIGNED);
CAST(1-2 AS UNSIGNED)
18446744073709551615
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER)
-1
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select CAST('10 ' as unsigned integer);
CAST('10 ' as unsigned integer)
10
@@ -12,9 +16,15 @@ Warning 1292 Truncated incorrect INTEGER value: '10 '
select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
cast(-5 as unsigned) | 1 cast(-5 as unsigned) & -1
18446744073709551611 18446744073709551611
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
cast(-5 as unsigned) -1 cast(-5 as unsigned) + 1
18446744073709551610 18446744073709551612
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select ~5, cast(~5 as signed);
~5 cast(~5 as signed)
18446744073709551610 -6
@@ -23,12 +33,129 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select ~(5) AS `~5`,cast(~(5) as signed) AS `cast(~5 as signed)`
+select cast(18446744073709551615 as signed);
+cast(18446744073709551615 as signed)
+-1
select cast(5 as unsigned) -6.0;
cast(5 as unsigned) -6.0
-1.0
select cast(NULL as signed), cast(1/0 as signed);
cast(NULL as signed) cast(1/0 as signed)
NULL NULL
+select cast(1 as double(5,2));
+cast(1 as double(5,2))
+1.00
+select cast("5.2222" as double(5,2));
+cast("5.2222" as double(5,2))
+5.22
+select cast(12.444 as double(5,2));
+cast(12.444 as double(5,2))
+12.44
+select cast(cast(12.444 as decimal(10,3)) as double(5,2));
+cast(cast(12.444 as decimal(10,3)) as double(5,2))
+12.44
+select cast(null as double(5,2));
+cast(null as double(5,2))
+NULL
+select cast(12.444 as double);
+cast(12.444 as double)
+12.444
+select cast(cast("20:01:01" as time) as datetime);
+cast(cast("20:01:01" as time) as datetime)
+0000-00-00 20:01:01
+select cast(cast("8:46:06.23434" AS time) as decimal(32,10));
+cast(cast("8:46:06.23434" AS time) as decimal(32,10))
+84606.0000000000
+select cast(cast("2011-04-05 8:46:06.23434" AS datetime) as decimal(32,6));
+cast(cast("2011-04-05 8:46:06.23434" AS datetime) as decimal(32,6))
+20110405084606.000000
+#
+# Check handling of cast with microseconds
+#
+select cast(cast(20010203101112.121314 as double) as datetime);
+cast(cast(20010203101112.121314 as double) as datetime)
+2001-02-03 10:11:12
+select cast(cast(010203101112.12 as double) as datetime);
+cast(cast(010203101112.12 as double) as datetime)
+0001-02-03 10:11:12
+select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime);
+cast(cast(20010203101112.121314 as decimal(32,6)) as datetime)
+2001-02-03 10:11:12
+select cast(20010203101112.121314 as datetime);
+cast(20010203101112.121314 as datetime)
+2001-02-03 10:11:12
+select cast(110203101112.121314 as datetime);
+cast(110203101112.121314 as datetime)
+0011-02-03 10:11:12
+select cast(cast(010203101112.12 as double) as datetime);
+cast(cast(010203101112.12 as double) as datetime)
+0001-02-03 10:11:12
+select cast("2011-02-03 10:11:12.123456" as datetime);
+cast("2011-02-03 10:11:12.123456" as datetime)
+2011-02-03 10:11:12
+select cast("2011-02-03 10:11:12.123456" as datetime(0));
+cast("2011-02-03 10:11:12.123456" as datetime(0))
+2011-02-03 10:11:12
+select cast("2011-02-03 10:11:12.123456" as datetime(5));
+cast("2011-02-03 10:11:12.123456" as datetime(5))
+2011-02-03 10:11:12.12345
+select cast("2011-02-03 10:11:12.123456" as datetime(6));
+cast("2011-02-03 10:11:12.123456" as datetime(6))
+2011-02-03 10:11:12.123456
+select cast("2011-02-03 10:11:12" as datetime(6));
+cast("2011-02-03 10:11:12" as datetime(6))
+2011-02-03 10:11:12.000000
+select cast(cast(20010203101112.5 as double) as datetime(1));
+cast(cast(20010203101112.5 as double) as datetime(1))
+2001-02-03 10:11:12.5
+select cast(cast(010203101112.12 as double) as datetime(2));
+cast(cast(010203101112.12 as double) as datetime(2))
+0001-02-03 10:11:12.12
+select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime(6));
+cast(cast(20010203101112.121314 as decimal(32,6)) as datetime(6))
+2001-02-03 10:11:12.121314
+select cast(20010203101112.121314 as datetime(6));
+cast(20010203101112.121314 as datetime(6))
+2001-02-03 10:11:12.121314
+select cast(110203101112.121314 as datetime(6));
+cast(110203101112.121314 as datetime(6))
+0011-02-03 10:11:12.121314
+select cast(cast(010203101112.12 as double) as datetime(6));
+cast(cast(010203101112.12 as double) as datetime(6))
+0001-02-03 10:11:12.120000
+select cast("2011-02-03 10:11:12.123456" as time);
+cast("2011-02-03 10:11:12.123456" as time)
+10:11:12
+select cast("2011-02-03 10:11:12.123456" as time(6));
+cast("2011-02-03 10:11:12.123456" as time(6))
+10:11:12.123456
+select cast("10:11:12.123456" as time);
+cast("10:11:12.123456" as time)
+10:11:12
+select cast("10:11:12.123456" as time(0));
+cast("10:11:12.123456" as time(0))
+10:11:12
+select cast("10:11:12.123456" as time(5));
+cast("10:11:12.123456" as time(5))
+10:11:12.12345
+select cast("10:11:12.123456" as time(6));
+cast("10:11:12.123456" as time(6))
+10:11:12.123456
+select cast("10:11:12" as time(6));
+cast("10:11:12" as time(6))
+10:11:12.000000
+select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time);
+cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time)
+08:46:06
+select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time(6));
+cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time(6))
+08:46:06.000000
+select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time);
+cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time)
+08:46:06
+select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time(6));
+cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time(6))
+08:46:06.123456
select cast(NULL as unsigned), cast(1/0 as unsigned);
cast(NULL as unsigned) cast(1/0 as unsigned)
NULL NULL
@@ -111,6 +238,113 @@ select 10E+0+'a';
10
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'a'
+select cast("a" as double(5,2));
+cast("a" as double(5,2))
+0.00
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
+select cast(1000 as decimal(5,2));
+cast(1000 as decimal(5,2))
+999.99
+Warnings:
+Error 1264 Out of range value for column 'cast(1000 as decimal(5,2))' at row 1
+select cast(-1000 as decimal(5,2));
+cast(-1000 as decimal(5,2))
+-999.99
+Warnings:
+Error 1264 Out of range value for column 'cast(-1000 as decimal(5,2))' at row 1
+select cast(1000 as double(5,2));
+cast(1000 as double(5,2))
+999.99
+Warnings:
+Warning 1264 Out of range value for column 'cast(1000 as double(5,2))' at row 1
+select cast(-1000 as double(5,2));
+cast(-1000 as double(5,2))
+-999.99
+Warnings:
+Warning 1264 Out of range value for column 'cast(-1000 as double(5,2))' at row 1
+select cast(010203101112.121314 as datetime);
+cast(010203101112.121314 as datetime)
+0001-02-03 10:11:12
+select cast(120010203101112.121314 as datetime);
+cast(120010203101112.121314 as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '120010203101112.121314'
+select cast(cast(1.1 as decimal) as datetime);
+cast(cast(1.1 as decimal) as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '1'
+select cast(cast(-1.1 as decimal) as datetime);
+cast(cast(-1.1 as decimal) as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '-1'
+select cast('0' as date);
+cast('0' as date)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '0'
+select cast('' as date);
+cast('' as date)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+select cast('0' as datetime);
+cast('0' as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '0'
+select cast('' as datetime);
+cast('' as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+select cast('0' as time);
+cast('0' as time)
+00:00:00
+select cast('' as time);
+cast('' as time)
+NULL
+Warnings:
+Warning 1292 Truncated incorrect time value: ''
+select cast(NULL as DATE);
+cast(NULL as DATE)
+NULL
+select cast(NULL as DATETIME);
+cast(NULL as DATETIME)
+NULL
+select cast(NULL as TIME);
+cast(NULL as TIME)
+NULL
+select cast(NULL as BINARY);
+cast(NULL as BINARY)
+NULL
+select cast(cast(120010203101112.121314 as double) as datetime);
+cast(cast(120010203101112.121314 as double) as datetime)
+NULL
+select cast(cast(1.1 as double) as datetime);
+cast(cast(1.1 as double) as datetime)
+0000-00-00 00:00:01
+select cast(cast(-1.1 as double) as datetime);
+cast(cast(-1.1 as double) as datetime)
+NULL
+explain extended select cast(10 as double(5,2));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(10 as double(5,2)) AS `cast(10 as double(5,2))`
+explain extended select cast(10 as double);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(10 as double) AS `cast(10 as double)`
+explain extended select cast(10 as decimal(5,2));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(10 as decimal(5,2)) AS `cast(10 as decimal(5,2))`
select cast('18446744073709551616' as unsigned);
cast('18446744073709551616' as unsigned)
18446744073709551615
@@ -146,6 +380,18 @@ cast('' as signed)
0
Warnings:
Warning 1292 Truncated incorrect INTEGER value: ''
+select cast(1 as double(5,6));
+ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '').
+select cast(1 as decimal(5,6));
+ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '').
+select cast(1 as double(66,6));
+ERROR 42000: Too big precision 66 specified for '1'. Maximum is 65.
+select cast(1 as decimal(66,6));
+ERROR 42000: Too big precision 66 specified for '1'. Maximum is 65.
+select cast(1 as decimal(64,63));
+ERROR 42000: Too big scale 63 specified for '1'. Maximum is 30.
+select cast(1 as double(64,63));
+ERROR 42000: Too big scale 63 specified for '1'. Maximum is 30.
set names binary;
select cast(_latin1'test' as char character set latin2);
cast(_latin1'test' as char character set latin2)
@@ -254,13 +500,7 @@ cast("2001-1-1" as datetime) = "2001-01-01 00:00:00"
1
select cast("1:2:3" as TIME) = "1:02:03";
cast("1:2:3" as TIME) = "1:02:03"
-0
-select cast(NULL as DATE);
-cast(NULL as DATE)
-NULL
-select cast(NULL as BINARY);
-cast(NULL as BINARY)
-NULL
+1
CREATE TABLE t1 (a enum ('aac','aab','aaa') not null);
INSERT INTO t1 VALUES ('aaa'),('aab'),('aac');
SELECT a, CAST(a AS CHAR) FROM t1 ORDER BY CAST(a AS UNSIGNED) ;
@@ -337,6 +577,21 @@ Warning 1105 Cast to signed converted positive out-of-range integer to it's nega
select cast(1.0e+300 as signed int);
cast(1.0e+300 as signed int)
9223372036854775807
+create table t1 select cast(1 as unsigned), cast(1 as signed), cast(1 as double(5,2)), cast(1 as decimal(5,3)), cast("A" as binary), cast("A" as char(100)), cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME), cast("1:2:3" as TIME);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `cast(1 as unsigned)` int(1) unsigned NOT NULL DEFAULT '0',
+ `cast(1 as signed)` int(1) NOT NULL DEFAULT '0',
+ `cast(1 as double(5,2))` double(5,2) DEFAULT NULL,
+ `cast(1 as decimal(5,3))` decimal(5,3) NOT NULL DEFAULT '0.000',
+ `cast("A" as binary)` varbinary(1) NOT NULL DEFAULT '',
+ `cast("A" as char(100))` varbinary(100) NOT NULL DEFAULT '',
+ `cast("2001-1-1" as DATE)` date DEFAULT NULL,
+ `cast("2001-1-1" as DATETIME)` datetime DEFAULT NULL,
+ `cast("1:2:3" as TIME)` time DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
CREATE TABLE t1 (f1 double);
INSERT INTO t1 SET f1 = -1.0e+30 ;
INSERT INTO t1 SET f1 = +1.0e+30 ;
@@ -464,9 +719,10 @@ Warnings:
Warning 1301 Result of cast_as_binary() was larger than max_allowed_packet (2048) - truncated
SELECT CONVERT('a', CHAR(2049));
CONVERT('a', CHAR(2049))
-NULL
-Warnings:
-Warning 1301 Result of cast_as_char() was larger than max_allowed_packet (2048) - truncated
+a
+SELECT length(CONVERT(repeat('a',2048), CHAR(2049)));
+length(CONVERT(repeat('a',2048), CHAR(2049)))
+2048
SET @@GLOBAL.max_allowed_packet=default;
#
# Bug#13519724 63793: CRASH IN DTCOLLATION::SET(DTCOLLATION &SET)
@@ -478,3 +734,34 @@ AND CAST(a AS BINARY)=x'65736D697468';
a
DROP TABLE t1;
End of 5.1 tests
+select cast("2101-00-01 02:03:04" as datetime);
+cast("2101-00-01 02:03:04" as datetime)
+2101-00-01 02:03:04
+select cast(cast("2101-00-01 02:03:04" as datetime) as time);
+cast(cast("2101-00-01 02:03:04" as datetime) as time)
+02:03:04
+SELECT CAST(CAST('20:05:05' AS TIME) as date);
+CAST(CAST('20:05:05' AS TIME) as date)
+0000-00-00
+set sql_mode= TRADITIONAL;
+select cast("2101-00-01 02:03:04" as datetime);
+cast("2101-00-01 02:03:04" as datetime)
+2101-00-01 02:03:04
+select cast(cast("2101-00-01 02:03:04" as datetime) as time);
+cast(cast("2101-00-01 02:03:04" as datetime) as time)
+02:03:04
+SELECT CAST(CAST('20:05:05' AS TIME) as date);
+CAST(CAST('20:05:05' AS TIME) as date)
+0000-00-00
+set sql_mode=DEFAULT;
+create table t1 (f1 time, f2 date, f3 datetime);
+insert into t1 values ('11:22:33','2011-12-13','2011-12-13 11:22:33');
+select cast(f1 as unsigned), cast(f2 as unsigned), cast(f3 as unsigned) from t1;
+cast(f1 as unsigned) cast(f2 as unsigned) cast(f3 as unsigned)
+112233 20111213 20111213112233
+drop table t1;
+SELECT CAST(TIME('10:20:30') AS DATE) + INTERVAL 1 DAY;
+CAST(TIME('10:20:30') AS DATE) + INTERVAL 1 DAY
+NULL
+Warnings:
+Warning 1292 Truncated incorrect date value: '0000-00-00'
diff --git a/mysql-test/r/comments.result b/mysql-test/r/comments.result
index 99fab38d7a7..77c520b0c64 100644
--- a/mysql-test/r/comments.result
+++ b/mysql-test/r/comments.result
@@ -26,6 +26,20 @@ select 1 # The rest of the row will be ignored
1
1
/* line with only comment */;
+select 1 /*M! +1 */;
+1 +1
+2
+select 1 /*M!50000 +1 */;
+1 +1
+2
+select 1 /*M!50300 +1 */;
+1 +1
+2
+select 2 /*M!99999 +1 */;
+2
+2
+select 2 /*M!0000 +1 */;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '0000 +1 */' at line 1
select 1/*!2*/;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2*/' at line 1
select 1/*!000002*/;
diff --git a/mysql-test/r/compare.result b/mysql-test/r/compare.result
index 5168eb38586..fe3a27ea0a3 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..3a3586fdb32 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");
@@ -1353,6 +1353,8 @@ fld1 fld1
250503 250505
250504 250505
250505 250505
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
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
@@ -1395,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
@@ -1419,15 +1421,16 @@ 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
+SET optimizer_switch=@save_optimizer_switch;
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
@@ -1435,7 +1438,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 720e7c1d24e..07b3f85d924 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
@@ -1556,6 +1556,7 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 7
drop table t1,t2;
CREATE TABLE t1(c1 VARCHAR(33), KEY USING BTREE (c1));
@@ -1760,7 +1761,10 @@ t1 CREATE TABLE `t1` (
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext,
- `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
drop table t1;
create temporary table t1 like information_schema.processlist;
@@ -1775,7 +1779,10 @@ t1 CREATE TEMPORARY TABLE `t1` (
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext,
- `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
drop table t1;
create table t1 like information_schema.character_sets;
diff --git a/mysql-test/r/ctype_collate.result b/mysql-test/r/ctype_collate.result
index b42094550bd..f5c17ebfdf8 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
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
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
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_cp932_binlog_stm.result b/mysql-test/r/ctype_cp932_binlog_stm.result
index 1841cc3ef69..6e4432c3091 100644
--- a/mysql-test/r/ctype_cp932_binlog_stm.result
+++ b/mysql-test/r/ctype_cp932_binlog_stm.result
@@ -44,8 +44,8 @@ master-bin.000001 # Query # # use `test`; INSERT INTO t4 VALUES ( NAME_CONST('in
master-bin.000001 # Query # # use `test`; DROP PROCEDURE bug18293
master-bin.000001 # Query # # use `test`; DROP TABLE t4
End of 5.0 tests
-call mtr.add_suppression("Error in Log_event::read_log_event\\\(\\\): 'Sanity check failed', data_len: 258, event_type: 49");
-SHOW BINLOG EVENTS FROM 365;
+call mtr.add_suppression("Error in Log_event::read_log_event\\\(\\\): 'Found invalid");
+SHOW BINLOG EVENTS FROM 504;
ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error
Bug#44352 UPPER/LOWER function doesn't work correctly on cp932 and sjis environment.
CREATE TABLE t1 (a varchar(16)) character set cp932;
diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result
index ee95812c03e..f096620daf0 100644
--- a/mysql-test/r/ctype_recoding.result
+++ b/mysql-test/r/ctype_recoding.result
@@ -267,3 +267,19 @@ drop table t1;
create table t1(a char character set latin1 default _cp1251 0xFF);
ERROR 42000: Invalid default value for 'a'
End of 4.1 tests
+SET CHARACTER SET DEFAULT;
+#
+# LP BUG#944504 Item_func_conv_charset tries to execute subquery constant
+#
+SET optimizer_switch = 'in_to_exists=on';
+SET character_set_connection = utf8;
+CREATE TABLE t1 ( a VARCHAR(1) );
+INSERT INTO t1 VALUES ('m'),('n');
+CREATE VIEW v1 AS SELECT 'w' ;
+SELECT * FROM t1 WHERE a < ALL ( SELECT * FROM v1 );
+ERROR HY000: Illegal mix of collations (utf8_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<='
+drop view v1;
+drop table t1;
+SET character_set_connection = default;
+SET optimizer_switch= default;
+#End of 5.3 tests
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index cef1546fa38..e61d41bda83 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/date_formats.result b/mysql-test/r/date_formats.result
index a919a6f8c5e..dd346cb94dc 100644
--- a/mysql-test/r/date_formats.result
+++ b/mysql-test/r/date_formats.result
@@ -196,16 +196,16 @@ date format datetime
0003-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 0003-01-02 08:11:02
03-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
-2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
-2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
-2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450
+2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12
+2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12
+2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
10:20:10 %H:%i:%s 0000-00-00 10:20:10
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
10:20:10 %T 0000-00-00 10:20:10
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
10:20:10AM %r 0000-00-00 10:20:10
-10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000
+10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
15 September 2001 %d %M %Y 2001-09-15 00:00:00
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
@@ -421,14 +421,14 @@ date format str_to_date
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
Warnings:
-Warning 1292 Incorrect datetime value: '10:20:10AM'
+Warning 1292 Truncated incorrect datetime value: '10:20:10AM'
select date,format,concat(str_to_date(date, format),'') as con from t1;
date format con
10:20:10AM %h:%i:%s 0000-00-00 10:20:10
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
Warnings:
-Warning 1292 Incorrect datetime value: '10:20:10AM'
+Warning 1292 Truncated incorrect datetime value: '10:20:10AM'
drop table t1;
select get_format(DATE, 'USA') as a;
a
@@ -471,14 +471,14 @@ str_to_date("2003-01-02", "%Y-%m-%d") as f3,
str_to_date("02", "%d") as f4, str_to_date("02 10", "%d %H") as f5;
describe t1;
Field Type Null Key Default Extra
-f1 datetime YES NULL
-f2 time YES NULL
+f1 datetime(6) YES NULL
+f2 time(6) YES NULL
f3 date YES NULL
f4 date YES NULL
f5 time YES NULL
select * from t1;
f1 f2 f3 f4 f5
-2003-01-02 10:11:12 10:11:12 2003-01-02 0000-00-02 58:00:00
+2003-01-02 10:11:12.001200 10:11:12.001200 2003-01-02 0000-00-02 58:00:00
drop table t1;
create table t1 select "02 10" as a, "%d %H" as b;
select str_to_date(a,b) from t1;
@@ -487,7 +487,7 @@ str_to_date(a,b)
create table t2 select str_to_date(a,b) from t1;
describe t2;
Field Type Null Key Default Extra
-str_to_date(a,b) datetime YES NULL
+str_to_date(a,b) datetime(6) YES NULL
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S") as f2,
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
@@ -495,7 +495,7 @@ str_to_date("02 10:11:12", "%d %H:%i:%S.%f") as f4,
str_to_date("02 10:11:12", "%d %H:%i:%S") as f5,
str_to_date("02 10", "%d %f") as f6;
f1 f2 f3 f4 f5 f6
-2003-01-02 10:11:12.001200 2003-01-02 10:11:12 2003-01-02 58:11:12 58:11:12 48:00:00.100000
+2003-01-02 10:11:12.001200 2003-01-02 10:11:12 2003-01-02 58:11:12.000000 58:11:12 48:00:00.100000
Warnings:
Warning 1292 Truncated incorrect datetime value: '2003-01-02 10:11:12.0012'
drop table t1, t2;
diff --git a/mysql-test/r/datetime_456.result b/mysql-test/r/datetime_456.result
new file mode 100644
index 00000000000..44351a821bc
--- /dev/null
+++ b/mysql-test/r/datetime_456.result
@@ -0,0 +1,8 @@
+create table t1 (d datetime);
+insert t1 values (addtime('9999-12-31 23:59:59', '00:00:01')),
+(from_days(3652499));
+select * from t1;
+d
+NULL
+0000-00-00 00:00:00
+drop table t1;
diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result
index 7d6fc30be67..d9623ca21b7 100644
--- a/mysql-test/r/delete.result
+++ b/mysql-test/r/delete.result
@@ -126,8 +126,8 @@ a b
2 12
delete ignore t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b <> (select b from t2 where t11.a < t2.a);
Warnings:
-Error 1242 Subquery returns more than 1 row
-Error 1242 Subquery returns more than 1 row
+Warning 1242 Subquery returns more than 1 row
+Warning 1242 Subquery returns more than 1 row
select * from t11;
a b
0 10
@@ -146,8 +146,8 @@ a b
2 12
delete ignore from t11 where t11.b <> (select b from t2 where t11.a < t2.a);
Warnings:
-Error 1242 Subquery returns more than 1 row
-Error 1242 Subquery returns more than 1 row
+Warning 1242 Subquery returns more than 1 row
+Warning 1242 Subquery returns more than 1 row
select * from t11;
a b
0 10
diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result
index 61f1db9989f..a9247ff41bf 100644
--- a/mysql-test/r/derived.result
+++ b/mysql-test/r/derived.result
@@ -1,4 +1,6 @@
drop table if exists t1,t2,t3;
+set @save_derived_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
select * from (select 2 from DUAL) b;
2
2
@@ -58,7 +60,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;
@@ -91,7 +93,7 @@ a b
2 b
explain select * from (select * from t1 union select * from t1) a;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8
2 DERIVED t1 ALL NULL NULL NULL NULL 4
3 UNION t1 ALL NULL NULL NULL NULL 4
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
@@ -113,7 +115,7 @@ a b
3 c
explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
2 DERIVED t2 system NULL NULL NULL NULL 1
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using where
drop table t1, t2;
@@ -142,7 +144,8 @@ a t
20 20
explain select count(*) from t1 as tt1, (select * from t1) as tt2;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+1 PRIMARY tt1 index NULL a 4 NULL 10000 Using index
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10000 Using join buffer (flat, BNL join)
2 DERIVED t1 ALL NULL NULL NULL NULL 10000
drop table t1;
SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a) as a )) as b;
@@ -189,13 +192,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 9 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 9 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;
@@ -204,6 +207,7 @@ x
1
create user mysqltest_1;
create table t1 select 1 as a;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
select 2 as a from (select * from t1) b;
ERROR 3D000: No database selected
use test;
@@ -245,8 +249,8 @@ a a
2 2
explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
-1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 Using join buffer
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+1 PRIMARY <derived4> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
4 DERIVED t1 ALL NULL NULL NULL NULL 2
5 UNION t1 ALL NULL NULL NULL NULL 2
NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL
@@ -311,9 +315,9 @@ a 7.0000
b 3.5000
explain SELECT s.name, AVG(s.val) AS median FROM (SELECT x.name, x.val FROM t1 x, t1 y WHERE x.name=y.name GROUP BY x.name, x.val HAVING SUM(y.val <= x.val) >= COUNT(*)/2 AND SUM(y.val >= x.val) >= COUNT(*)/2) AS s GROUP BY s.name;
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
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 289 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);
@@ -322,7 +326,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
explain select a from (select a from t2 where a>1) tt;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
drop table t2;
CREATE TABLE `t1` ( `itemid` int(11) NOT NULL default '0', `grpid` varchar(15) NOT NULL default '', `vendor` int(11) NOT NULL default '0', `date_` date NOT NULL default '0000-00-00', `price` decimal(12,2) NOT NULL default '0.00', PRIMARY KEY (`itemid`,`grpid`,`vendor`,`date_`), KEY `itemid` (`itemid`,`vendor`), KEY `itemid_2` (`itemid`,`date_`));
@@ -412,3 +416,4 @@ MIN(i)
1
DROP TABLE t1;
# End of 5.0 tests
+set optimizer_switch=@save_derived_optimizer_switch;
diff --git a/mysql-test/r/derived_opt.result b/mysql-test/r/derived_opt.result
new file mode 100644
index 00000000000..b75e735446d
--- /dev/null
+++ b/mysql-test/r/derived_opt.result
@@ -0,0 +1,355 @@
+drop table if exists t1,t2,t3;
+set @exit_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (a int not null, b char (10) not null);
+insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
+CREATE TABLE t2 (a int not null, b char (10) not null);
+insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e');
+CREATE TABLE t3 (a int not null, b char (10) not null);
+insert into t3 values (3,'f'),(4,'y'),(5,'z'),(6,'c');
+select * from t1 as x1, (select * from t1) as x2;
+a b a b
+1 a 1 a
+2 b 1 a
+3 c 1 a
+3 c 1 a
+1 a 2 b
+2 b 2 b
+3 c 2 b
+3 c 2 b
+1 a 3 c
+2 b 3 c
+3 c 3 c
+3 c 3 c
+1 a 3 c
+2 b 3 c
+3 c 3 c
+3 c 3 c
+explain select * from t1 as x1, (select * from t1) as x2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE x1 ALL NULL NULL NULL NULL 4
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
+drop table if exists t2,t3;
+CREATE TABLE t2 (a int not null);
+insert into t2 values(1);
+select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
+a b t2a
+1 a 1
+explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 system NULL NULL NULL NULL 1
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
+drop table t1, t2;
+create table t1(a int not null, t char(8), index(a));
+SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20;
+a t
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+7 7
+8 8
+9 9
+10 10
+11 11
+12 12
+13 13
+14 14
+15 15
+16 16
+17 17
+18 18
+19 19
+20 20
+explain select count(*) from t1 as tt1, (select * from t1) as tt2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+drop table t1;
+create table t1 (mat_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, matintnum CHAR(6) NOT NULL, test MEDIUMINT UNSIGNED NULL);
+create table t2 (mat_id MEDIUMINT UNSIGNED NOT NULL, pla_id MEDIUMINT UNSIGNED NOT NULL);
+insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd', 4), (NULL, 'e', 5), (NULL, 'f', 6), (NULL, 'g', 7), (NULL, 'h', 8), (NULL, 'i', 9);
+insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
+SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+pla_id mat_id
+102 1
+101 1
+100 1
+104 2
+103 2
+105 3
+SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+pla_id test
+102 1
+101 1
+100 1
+104 2
+103 2
+105 3
+explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY m2 ALL NULL NULL NULL NULL 9
+1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
+2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
+2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
+explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY m2 ALL NULL NULL NULL NULL 9
+1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
+2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
+2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
+drop table t1,t2;
+create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1)
+);
+insert into t1 VALUES(1,1,1), (2,2,1);
+select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2;
+count(*)
+2
+explain select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE A ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.A.E2 1 Using where
+3 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 2 Using where
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2);
+select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
+a a
+1 1
+2 1
+1 2
+2 2
+explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+1 PRIMARY <derived4> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
+4 DERIVED t1 ALL NULL NULL NULL NULL 2
+5 UNION t1 ALL NULL NULL NULL NULL 2
+NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL
+2 DERIVED t1 ALL NULL NULL NULL NULL 2
+3 UNION t1 ALL NULL NULL NULL NULL 2
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+drop table t1;
+create table t2 (a int, b int, primary key (a));
+insert into t2 values (1,7),(2,7);
+explain select a from t2 where a>1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+explain select a from (select a from t2 where a>1) tt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+drop table t2;
+create table t1
+(
+c1 tinyint, c2 smallint, c3 mediumint, c4 int,
+c5 integer, c6 bigint, c7 float, c8 double,
+c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
+c13 date, c14 datetime, c15 timestamp, c16 time,
+c17 year, c18 bit, c19 bool, c20 char,
+c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
+c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
+c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
+c32 set('monday', 'tuesday', 'wednesday')
+) engine = MYISAM ;
+create table t2 like t1;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+set @stmt= ' explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25 ' ;
+prepare stmt1 from @stmt ;
+execute stmt1 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+execute stmt1 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+deallocate prepare stmt1;
+drop tables t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
+#
+# LP bug #793436: query with a derived table for which optimizer proves
+# that it contains not more than 1 row
+#
+CREATE TABLE t1 (a int, KEY (a)) ;
+INSERT INTO t1 VALUES (3), (1);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (3);
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1
+1 PRIMARY t1 ref a a 5 const 1 Using index
+2 DERIVED t2 system NULL NULL NULL NULL 1
+SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a;
+a a
+3 3
+DROP TABLE t1,t2;
+#
+# LP bug #800518: crash with a query over a derived table
+# when a min/max optimization is applied
+#
+CREATE TABLE t1 (a int, b int, c varchar(10), INDEX idx(a,b)) ;
+INSERT INTO t1 VALUES
+(100, 3, 'xxx'), (200, 7, 'yyyyyyy'), (100, 1, 't'),
+(200, 4, 'aaaa'), (100, 3, 'eee'), (100, 5, 'zzzzz');
+EXPLAIN
+SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100;
+MAX(b)
+5
+DROP TABLE t1;
+#
+# LP bug #799499: query over a materialized view
+# accessed by a key
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (8);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES
+(262, NULL), (253, 190), (260, NULL), (250, 163), (188, 8),
+(257,200), (256, NULL), (255, 8), (249, NULL), (259, 7);
+CREATE VIEW v1 AS SELECT a, MIN(b) AS b FROM t2 GROUP BY a;
+EXPLAIN
+SELECT * FROM v1, t1 WHERE v1.b=t1.a ORDER BY v1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 Using filesort
+1 PRIMARY <derived2> ref key0 key0 5 const 1 Using where
+2 DERIVED t2 ALL NULL NULL NULL NULL 10 Using temporary; Using filesort
+SELECT * FROM v1, t1 WHERE v1.b=t1.a ORDER BY v1.a;
+a b a
+188 8 8
+255 8 8
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #800085: crash with a query using a simple derived table
+# (fixed by the patch for bug 798621)
+#
+CREATE TABLE t1 (f1 int, f2 varchar(32)) ;
+INSERT INTO t1 VALUES (NULL,'j'), (8,'c');
+CREATE TABLE t2 (f1 int);
+INSERT INTO t2 VALUES (1), (5);
+SELECT DISTINCT t.f1 FROM (SELECT * FROM t1) AS t, t2
+WHERE t.f2='s' AND t.f2 LIKE '%a%' OR t.f1<>0 ORDER BY t.f2;
+f1
+8
+DROP TABLE t1, t2;
+#
+# BUG##806524: Assertion `join->best_read < 1.7976931348623157e+308 with table_elimination=on and derived_merge=on
+#
+CREATE TABLE t1 ( f4 int) ;
+CREATE TABLE t2 ( f4 int) ;
+CREATE TABLE t3 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+CREATE TABLE t4 ( f2 int, f4 int) ;
+SELECT *
+FROM ( SELECT * FROM t1 ) AS alias1
+RIGHT JOIN (
+t2 AS alias2
+LEFT JOIN (
+SELECT t4.*
+FROM ( SELECT * FROM t3 ) AS SQ1_alias1
+RIGHT JOIN t4
+ON t4.f2 = SQ1_alias1.f1
+) AS alias3
+ON alias3.f4 != 0
+) ON alias3.f4 != 0;
+f4 f4 f2 f4
+drop table t1,t2,t3,t4;
+#
+# LP BUG#910123 MariaDB 5.3.3 causes 1093 error on Drupal
+# Fix: force materialization in case of conflict
+#
+SET optimizer_switch='derived_merge=on';
+CREATE TABLE t1 ( i INT );
+INSERT INTO t1 VALUES ( (SELECT 1 FROM ( SELECT * FROM t1 ) as a) );
+drop table t1;
+set optimizer_switch=@save_optimizer_switch;
+#
+# MDEV-3801 Reproducible sub select join crash on 5.3.8 and 5.3.9
+#
+CREATE TABLE t1 (
+pk int(10) unsigned NOT NULL AUTO_INCREMENT,
+a char(2) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY a (a)
+) ENGINE=MyISAM;
+INSERT INTO t1 (a)
+VALUES (NULL),(NULL),(NULL),('AB'),(NULL),('CD'),(NULL),(NULL);
+INSERT INTO t1 SELECT NULL, a1.a FROM t1 a1, t1 a2, t1 a3, t1 a4, t1 a5;
+CREATE TABLE t2 (
+pk int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
+INSERT INTO t2 SELECT NULL FROM t2 a1, t2 a2, t2 a3, t2 a4, t2 a5;
+CREATE TABLE t3 (
+pk int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY
+) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
+INSERT INTO t3 SELECT NULL FROM t3 a1, t3 a2, t3 a3, t3 a4, t3 a5;
+CREATE TABLE t4 (
+a char(2) NOT NULL DEFAULT '',
+PRIMARY KEY (a)
+) ENGINE=MyISAM;
+INSERT INTO t4 VALUES ('CD');
+set @@tmp_table_size=8192;
+EXPLAIN
+SELECT * FROM t3 AS tx JOIN t2 AS ty ON (tx.pk = ty.pk)
+WHERE
+tx.pk IN
+(SELECT *
+FROM (SELECT DISTINCT ta.pk
+FROM t3 AS ta
+JOIN t2 AS tb ON (ta.pk = tb.pk)
+JOIN t1 AS tc ON (tb.pk = tc.pk)
+JOIN t4 AS td ON tc.a = td.a) tu)
+limit 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL #
+1 PRIMARY tx eq_ref PRIMARY PRIMARY 4 tu.pk # Using index
+1 PRIMARY ty eq_ref PRIMARY PRIMARY 4 tu.pk # Using index
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL #
+3 DERIVED td system PRIMARY NULL NULL NULL # Using temporary
+3 DERIVED tc ref PRIMARY,a a 3 const #
+3 DERIVED ta eq_ref PRIMARY PRIMARY 4 test.tc.pk # Using index
+3 DERIVED tb eq_ref PRIMARY PRIMARY 4 test.tc.pk # Using index; Distinct
+SELECT * FROM t3 AS tX JOIN t2 AS tY ON (tX.pk = tY.pk)
+WHERE
+tX.pk IN
+(SELECT *
+FROM (SELECT DISTINCT tA.pk
+FROM t3 AS tA
+JOIN t2 AS tB ON (tA.pk = tB.pk)
+JOIN t1 AS tC ON (tB.pk = tC.pk)
+JOIN t4 AS tD ON tC.a = tD.a) tU)
+limit 10;
+pk pk
+6 6
+16 16
+24 24
+32 32
+40 40
+48 48
+56 56
+64 64
+72 72
+80 80
+drop table t1, t2, t3, t4;
+set optimizer_switch=@exit_optimizer_switch;
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
new file mode 100644
index 00000000000..030b8798fad
--- /dev/null
+++ b/mysql-test/r/derived_view.result
@@ -0,0 +1,2160 @@
+drop table if exists t1,t2;
+drop view if exists v1,v2,v3,v4;
+set @exit_optimizer_switch=@@optimizer_switch;
+set @exit_join_cache_level=@@join_cache_level;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+set @save_optimizer_switch=@@optimizer_switch;
+set join_cache_level=1;
+create table t1(f1 int, f11 int);
+create table t2(f2 int, f22 int);
+insert into t1 values(1,1),(2,2),(3,3),(5,5),(9,9),(7,7);
+insert into t1 values(17,17),(13,13),(11,11),(15,15),(19,19);
+insert into t2 values(1,1),(3,3),(2,2),(4,4),(8,8),(6,6);
+insert into t2 values(12,12),(14,14),(10,10),(18,18),(16,16);
+Tests:
+for merged derived tables
+explain for simple derived
+explain select * from (select * from t1) tt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11
+select * from (select * from t1) tt;
+f1 f11
+1 1
+2 2
+3 3
+5 5
+9 9
+7 7
+17 17
+13 13
+11 11
+15 15
+19 19
+explain for multitable derived
+explain extended select * from (select * from t1 join t2 on f1=f2) tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`f2` = `test`.`t1`.`f1`)
+select * from (select * from t1 join t2 on f1=f2) tt;
+f1 f11 f2 f22
+1 1 1 1
+3 3 3 3
+2 2 2 2
+explain for derived with where
+explain extended
+select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where ((`test`.`t1`.`f11` = 2) and (`test`.`t1`.`f1` in (2,3)))
+select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
+f1 f11
+2 2
+join of derived
+explain extended
+select * from (select * from t1 where f1 in (2,3)) tt join
+(select * from t1 where f1 in (1,2)) aa on tt.f1=aa.f1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` join `test`.`t1` where ((`test`.`t1`.`f1` = `test`.`t1`.`f1`) and (`test`.`t1`.`f1` in (1,2)) and (`test`.`t1`.`f1` in (2,3)))
+select * from (select * from t1 where f1 in (2,3)) tt join
+(select * from t1 where f1 in (1,2)) aa on tt.f1=aa.f1;
+f1 f11 f1 f11
+2 2 2 2
+flush status;
+explain extended
+select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where ((`test`.`t1`.`f11` = 2) and (`test`.`t1`.`f1` in (2,3)))
+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_deleted 0
+Handler_read_rnd_next 0
+flush status;
+select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
+f1 f11
+2 2
+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_deleted 0
+Handler_read_rnd_next 12
+for merged views
+create view v1 as select * from t1;
+create view v2 as select * from t1 join t2 on f1=f2;
+create view v3 as select * from t1 where f1 in (2,3);
+create view v4 as select * from t2 where f2 in (2,3);
+explain for simple views
+explain extended select * from v1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1`
+select * from v1;
+f1 f11
+1 1
+2 2
+3 3
+5 5
+9 9
+7 7
+17 17
+13 13
+11 11
+15 15
+19 19
+explain for multitable views
+explain extended select * from v2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`f2` = `test`.`t1`.`f1`)
+select * from v2;
+f1 f11 f2 f22
+1 1 1 1
+3 3 3 3
+2 2 2 2
+explain for views with where
+explain extended select * from v3 where f11 in (1,3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where ((`test`.`t1`.`f11` in (1,3)) and (`test`.`t1`.`f1` in (2,3)))
+select * from v3 where f11 in (1,3);
+f1 f11
+3 3
+explain for joined views
+explain extended
+select * from v3 join v4 on f1=f2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`f2` = `test`.`t1`.`f1`) and (`test`.`t1`.`f1` in (2,3)) and (`test`.`t1`.`f1` in (2,3)))
+select * from v3 join v4 on f1=f2;
+f1 f11 f2 f22
+3 3 3 3
+2 2 2 2
+flush status;
+explain extended select * from v4 where f2 in (1,3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 11 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t2` where ((`test`.`t2`.`f2` in (1,3)) and (`test`.`t2`.`f2` in (2,3)))
+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_deleted 0
+Handler_read_rnd_next 0
+flush status;
+select * from v4 where f2 in (1,3);
+f2 f22
+3 3
+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_deleted 0
+Handler_read_rnd_next 12
+for materialized derived tables
+explain for simple derived
+explain extended select * from (select * from t1 group by f1) tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` group by `test`.`t1`.`f1`) `tt`
+select * from (select * from t1 having f1=f1) tt;
+f1 f11
+1 1
+2 2
+3 3
+5 5
+9 9
+7 7
+17 17
+13 13
+11 11
+15 15
+19 19
+explain showing created indexes
+explain extended
+select * from t1 join (select * from t2 group by f2) tt on f1=f2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 11 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2 100.00
+2 DERIVED t2 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`tt`.`f2` AS `f2`,`tt`.`f22` AS `f22` from `test`.`t1` join (select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t2` group by `test`.`t2`.`f2`) `tt` where (`tt`.`f2` = `test`.`t1`.`f1`)
+select * from t1 join (select * from t2 group by f2) tt on f1=f2;
+f1 f11 f2 f22
+1 1 1 1
+2 2 2 2
+3 3 3 3
+explain showing late materialization
+flush status;
+explain select * from t1 join (select * from t2 group by f2) tt on f1=f2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2
+2 DERIVED t2 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort
+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_deleted 0
+Handler_read_rnd_next 0
+flush status;
+select * from t1 join (select * from t2 group by f2) tt on f1=f2;
+f1 f11 f2 f22
+1 1 1 1
+2 2 2 2
+3 3 3 3
+show status like 'Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 11
+Handler_read_next 3
+Handler_read_prev 0
+Handler_read_rnd 11
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 36
+for materialized views
+drop view v1,v2,v3;
+create view v1 as select * from t1 group by f1;
+create view v2 as select * from t2 group by f2;
+create view v3 as select t1.f1,t1.f11 from t1 join t1 as t11 where t1.f1=t11.f1
+having t1.f1<100;
+explain for simple derived
+explain extended select * from v1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `v1`.`f1` AS `f1`,`v1`.`f11` AS `f11` from `test`.`v1`
+select * from v1;
+f1 f11
+1 1
+2 2
+3 3
+5 5
+7 7
+9 9
+11 11
+13 13
+15 15
+17 17
+19 19
+explain showing created indexes
+explain extended select * from t1 join v2 on f1=f2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 11 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2 100.00
+2 DERIVED t2 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`v2`.`f2` AS `f2`,`v2`.`f22` AS `f22` from `test`.`t1` join `test`.`v2` where (`v2`.`f2` = `test`.`t1`.`f1`)
+select * from t1 join v2 on f1=f2;
+f1 f11 f2 f22
+1 1 1 1
+2 2 2 2
+3 3 3 3
+explain extended
+select * from t1,v3 as v31,v3 where t1.f1=v31.f1 and t1.f1=v3.f1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 11 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 10 100.00
+1 PRIMARY <derived3> ref key0 key0 5 test.t1.f1 10 100.00
+3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00
+3 DERIVED t11 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00
+2 DERIVED t11 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`v31`.`f1` AS `f1`,`v31`.`f11` AS `f11`,`v3`.`f1` AS `f1`,`v3`.`f11` AS `f11` from `test`.`t1` join `test`.`v3` `v31` join `test`.`v3` where ((`v31`.`f1` = `test`.`t1`.`f1`) and (`v3`.`f1` = `test`.`t1`.`f1`))
+flush status;
+select * from t1,v3 as v31,v3 where t1.f1=v31.f1 and t1.f1=v3.f1;
+f1 f11 f1 f11 f1 f11
+1 1 1 1 1 1
+2 2 2 2 2 2
+3 3 3 3 3 3
+5 5 5 5 5 5
+9 9 9 9 9 9
+7 7 7 7 7 7
+17 17 17 17 17 17
+13 13 13 13 13 13
+11 11 11 11 11 11
+15 15 15 15 15 15
+19 19 19 19 19 19
+show status like 'Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 22
+Handler_read_next 22
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 60
+explain showing late materialization
+flush status;
+explain select * from t1 join v2 on f1=f2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2
+2 DERIVED t2 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort
+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_deleted 0
+Handler_read_rnd_next 0
+flush status;
+select * from t1 join v2 on f1=f2;
+f1 f11 f2 f22
+1 1 1 1
+2 2 2 2
+3 3 3 3
+show status like 'Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 11
+Handler_read_next 3
+Handler_read_prev 0
+Handler_read_rnd 11
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 36
+explain extended select * from v1 join v4 on f1=f2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 11 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.f2 2 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `v1`.`f1` AS `f1`,`v1`.`f11` AS `f11`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`v1` join `test`.`t2` where ((`v1`.`f1` = `test`.`t2`.`f2`) and (`test`.`t2`.`f2` in (2,3)))
+select * from v1 join v4 on f1=f2;
+f1 f11 f2 f22
+3 3 3 3
+2 2 2 2
+merged derived in merged derived
+explain extended select * from (select * from
+(select * from t1 where f1 < 7) tt where f1 > 2) zz;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where ((`test`.`t1`.`f1` > 2) and (`test`.`t1`.`f1` < 7))
+select * from (select * from
+(select * from t1 where f1 < 7) tt where f1 > 2) zz;
+f1 f11
+3 3
+5 5
+materialized derived in merged derived
+explain extended select * from (select * from
+(select * from t1 where f1 < 7 group by f1) tt where f1 > 2) zz;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE <derived3> ALL NULL NULL NULL NULL 11 100.00 Using where
+3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
+Warnings:
+Note 1003 select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where (`test`.`t1`.`f1` < 7) group by `test`.`t1`.`f1`) `tt` where (`tt`.`f1` > 2)
+select * from (select * from
+(select * from t1 where f1 < 7 group by f1) tt where f1 > 2) zz;
+f1 f11
+3 3
+5 5
+merged derived in materialized derived
+explain extended select * from (select * from
+(select * from t1 where f1 < 7) tt where f1 > 2 group by f1) zz;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
+Warnings:
+Note 1003 select `zz`.`f1` AS `f1`,`zz`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where ((`test`.`t1`.`f1` > 2) and (`test`.`t1`.`f1` < 7)) group by `test`.`t1`.`f1`) `zz`
+select * from (select * from
+(select * from t1 where f1 < 7) tt where f1 > 2 group by f1) zz;
+f1 f11
+3 3
+5 5
+materialized derived in materialized derived
+explain extended select * from (select * from
+(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) zz;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00
+2 DERIVED <derived3> ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
+3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
+Warnings:
+Note 1003 select `zz`.`f1` AS `f1`,`zz`.`f11` AS `f11` from (select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where (`test`.`t1`.`f1` < 7) group by `test`.`t1`.`f1`) `tt` where (`tt`.`f1` > 2) group by `tt`.`f1`) `zz`
+select * from (select * from
+(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) zz;
+f1 f11
+3 3
+5 5
+mat in merged derived join mat in merged derived
+explain extended select * from
+(select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) x
+join
+(select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) z
+on x.f1 = z.f1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE <derived3> ALL NULL NULL NULL NULL 11 100.00 Using where
+1 SIMPLE <derived5> ref key0 key0 5 tt.f1 2 100.00
+5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
+3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
+Warnings:
+Note 1003 select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11`,`tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where (`test`.`t1`.`f1` < 7) group by `test`.`t1`.`f1`) `tt` join (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where (`test`.`t1`.`f1` < 7) group by `test`.`t1`.`f1`) `tt` where ((`tt`.`f1` = `tt`.`f1`) and (`tt`.`f1` > 2) and (`tt`.`f1` > 2))
+flush status;
+select * from
+(select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) x
+join
+(select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) z
+on x.f1 = z.f1;
+f1 f11 f1 f11
+3 3 3 3
+5 5 5 5
+show status like 'Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 2
+Handler_read_next 2
+Handler_read_prev 0
+Handler_read_rnd 8
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 39
+flush status;
+merged in merged derived join merged in merged derived
+explain extended select * from
+(select * from
+(select * from t1 where f1 < 7 ) tt where f1 > 2 ) x
+join
+(select * from
+(select * from t1 where f1 < 7 ) tt where f1 > 2 ) z
+on x.f1 = z.f1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` join `test`.`t1` where ((`test`.`t1`.`f1` = `test`.`t1`.`f1`) and (`test`.`t1`.`f1` > 2) and (`test`.`t1`.`f1` < 7) and (`test`.`t1`.`f1` > 2) and (`test`.`t1`.`f1` < 7))
+select * from
+(select * from
+(select * from t1 where f1 < 7 ) tt where f1 > 2 ) x
+join
+(select * from
+(select * from t1 where f1 < 7 ) tt where f1 > 2 ) z
+on x.f1 = z.f1;
+f1 f11 f1 f11
+3 3 3 3
+5 5 5 5
+materialized in materialized derived join
+materialized in materialized derived
+explain extended select * from
+(select * from
+(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) x
+join
+(select * from
+(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) z
+on x.f1 = z.f1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00 Using where
+1 PRIMARY <derived4> ref key0 key0 5 x.f1 2 100.00
+4 DERIVED <derived5> ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
+5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
+2 DERIVED <derived3> ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
+3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
+Warnings:
+Note 1003 select `x`.`f1` AS `f1`,`x`.`f11` AS `f11`,`z`.`f1` AS `f1`,`z`.`f11` AS `f11` from (select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where (`test`.`t1`.`f1` < 7) group by `test`.`t1`.`f1`) `tt` where (`tt`.`f1` > 2) group by `tt`.`f1`) `x` join (select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where (`test`.`t1`.`f1` < 7) group by `test`.`t1`.`f1`) `tt` where (`tt`.`f1` > 2) group by `tt`.`f1`) `z` where (`z`.`f1` = `x`.`f1`)
+select * from
+(select * from
+(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) x
+join
+(select * from
+(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) z
+on x.f1 = z.f1;
+f1 f11 f1 f11
+3 3 3 3
+5 5 5 5
+merged view in materialized derived
+explain extended
+select * from (select * from v4 group by 1) tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00
+2 DERIVED t2 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
+Warnings:
+Note 1003 select `tt`.`f2` AS `f2`,`tt`.`f22` AS `f22` from (select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t2` where (`test`.`t2`.`f2` in (2,3)) group by 1) `tt`
+select * from (select * from v4 group by 1) tt;
+f2 f22
+2 2
+3 3
+materialized view in merged derived
+explain extended
+select * from ( select * from v1 where f1 < 7) tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE <derived3> ALL NULL NULL NULL NULL 11 100.00 Using where
+3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `v1`.`f1` AS `f1`,`v1`.`f11` AS `f11` from `test`.`v1` where (`v1`.`f1` < 7)
+select * from ( select * from v1 where f1 < 7) tt;
+f1 f11
+1 1
+2 2
+3 3
+5 5
+merged view in a merged view in a merged derived
+create view v6 as select * from v4 where f2 < 7;
+explain extended select * from (select * from v6) tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 11 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t2` where ((`test`.`t2`.`f2` < 7) and (`test`.`t2`.`f2` in (2,3)))
+select * from (select * from v6) tt;
+f2 f22
+3 3
+2 2
+materialized view in a merged view in a materialized derived
+create view v7 as select * from v1;
+explain extended select * from (select * from v7 group by 1) tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00
+2 DERIVED <derived4> ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
+4 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `v1`.`f1` AS `f1`,`v1`.`f11` AS `f11` from `test`.`v1` group by 1) `tt`
+select * from (select * from v7 group by 1) tt;
+f1 f11
+1 1
+2 2
+3 3
+5 5
+7 7
+9 9
+11 11
+13 13
+15 15
+17 17
+19 19
+join of above two
+explain extended select * from v6 join v7 on f2=f1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 11 100.00 Using where
+1 SIMPLE <derived5> ref key0 key0 5 test.t2.f2 2 100.00
+5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22`,`v1`.`f1` AS `f1`,`v1`.`f11` AS `f11` from `test`.`t2` join `test`.`v1` where ((`v1`.`f1` = `test`.`t2`.`f2`) and (`test`.`t2`.`f2` < 7) and (`test`.`t2`.`f2` in (2,3)))
+select * from v6 join v7 on f2=f1;
+f2 f22 f1 f11
+3 3 3 3
+2 2 2 2
+test two keys
+explain select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2
+1 PRIMARY xx ALL NULL NULL NULL NULL 11 Using where; Using join buffer (flat, BNL join)
+2 DERIVED t2 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort
+select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1;
+f1 f11 f2 f22 f1 f11
+1 1 1 1 1 1
+2 2 2 2 2 2
+3 3 3 3 3 3
+TODO: Add test with 64 tables mergeable view to test fall back to
+materialization on tables > MAX_TABLES merge
+drop table t1,t2;
+drop view v1,v2,v3,v4,v6,v7;
+#
+# LP bug #794909: crash when defining possible keys for
+# a materialized view/derived_table
+#
+CREATE TABLE t1 (f1 int) ;
+INSERT INTO t1 VALUES (149), (150), (224), (29);
+CREATE TABLE t2 (f1 int, KEY (f1));
+INSERT INTO t2 VALUES (149), (NULL), (224);
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN
+SELECT * FROM v1 JOIN t2 ON v1.f1 = t2.f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index f1 f1 5 NULL 3 Using where; Using index
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.f1 2
+2 DERIVED t1 ALL NULL NULL NULL NULL 4
+SELECT * FROM v1 JOIN t2 ON v1.f1 = t2.f1;
+f1 f1
+149 149
+224 224
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #794890: abort failure on multi-update with view
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (20), (7);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (7), (9), (7);
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT a FROM t1;
+CREATE VIEW v2 AS SELECT t2.a FROM t2, v1 WHERE t2.a=t2.a;
+UPDATE v2 SET a = 2;
+SELECT * FROM t2;
+a
+2
+2
+2
+UPDATE t1,v2 SET t1.a = 3;
+SELECT * FROM t1;
+a
+3
+3
+DELETE t1 FROM t1,v2;
+SELECT * FROM t1;
+a
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+#
+# LP bug #802023: MIN/MAX optimization
+# for mergeable derived tables and views
+#
+CREATE TABLE t1 (a int, b int, c varchar(32), INDEX idx(a,b));
+INSERT INTO t1 VALUES
+(7, 74, 'yyyyyyy'), (9, 97, 'aaaaaaaaa'), (2, 23, 'tt'),
+(5, 55, 'ddddd'), (2, 27, 'ss'), (7, 76, 'xxxxxxx'),
+(7, 79, 'zzzzzzz'), (9, 92, 'bbbbbbbbb'), (2, 25, 'pp'),
+(5, 53, 'eeeee'), (2, 23, 'qq'), (7, 76,'wwwwwww'),
+(7, 74, 'uuuuuuu'), (9, 92, 'ccccccccc'), (2, 25, 'oo');
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT MIN(a) FROM t1 WHERE a >= 5;
+MIN(a)
+5
+EXPLAIN
+SELECT MIN(a) FROM t1 WHERE a >= 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MIN(a) FROM (SELECT * FROM t1) t WHERE a >= 5;
+MIN(a)
+5
+EXPLAIN
+SELECT MIN(a) FROM(SELECT * FROM t1) t WHERE a >= 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MIN(a) FROM v1 WHERE a >= 5;
+MIN(a)
+5
+EXPLAIN
+SELECT MIN(a) FROM v1 WHERE a >= 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MAX(b) FROM t1 WHERE a=7 AND b<75;
+MAX(b)
+74
+EXPLAIN
+SELECT MAX(b) FROM t1 WHERE a=7 AND b<75;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MAX(b) FROM (SELECT * FROM t1) t WHERE a=7 AND b<75;
+MAX(b)
+74
+EXPLAIN
+SELECT MAX(b) FROM (SELECT * FROM t1) t WHERE a=7 AND b<75;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MAX(b) FROM v1 WHERE a=7 AND b<75;
+MAX(b)
+74
+EXPLAIN
+SELECT MAX(b) FROM v1 WHERE a=7 AND b<75;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# LP bug #800535: GROUP BY query with nested left join
+# and a derived table in the nest
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 (a int NOT NULL);
+INSERT INTO t2 VALUES (1), (2);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (3,3), (4,4);
+EXPLAIN EXTENDED
+SELECT t.a FROM t1 LEFT JOIN
+(t2 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+GROUP BY t.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 SIMPLE t ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t`.`a` AS `a` from `test`.`t1` left join (`test`.`t2` `t` join `test`.`t3`) on(((`test`.`t`.`a` >= 1) and (`test`.`t3`.`b` > 5))) where 1 group by `test`.`t`.`a`
+SELECT t.a FROM t1 LEFT JOIN
+(t2 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+GROUP BY t.a;
+a
+NULL
+EXPLAIN EXTENDED
+SELECT t.a FROM t1 LEFT JOIN
+(( SELECT * FROM t2 ) t JOIN t3 ON t3.b > 5) ON t.a >= 1
+GROUP BY t.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`a` >= 1) and (`test`.`t3`.`b` > 5))) where 1 group by `test`.`t2`.`a`
+SELECT t.a FROM t1 LEFT JOIN
+(( SELECT * FROM t2 ) t JOIN t3 ON t3.b > 5) ON t.a >= 1
+GROUP BY t.a;
+a
+NULL
+CREATE VIEW v1 AS SELECT * FROM t2;
+EXPLAIN EXTENDED
+SELECT t.a FROM t1 LEFT JOIN
+(v1 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+GROUP BY t.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`a` >= 1) and (`test`.`t3`.`b` > 5))) where 1 group by `test`.`t2`.`a`
+SELECT t.a FROM t1 LEFT JOIN
+(v1 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+GROUP BY t.a;
+a
+NULL
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #803410: materialized view/dt accessed by two-component key
+#
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('c');
+CREATE TABLE t2 (a varchar(1) , KEY (a)) ;
+INSERT INTO t2 VALUES ('c'), (NULL), ('r');
+CREATE TABLE t3 (a varchar(1), b varchar(1));
+INSERT INTO t3 VALUES
+('e', 'c'), ('c', 'c'), ('c', 'r'), ('g', 'a'), ('b', 'x'), ('b', 'y'),
+('h', 'w'), ('d', 'z'), ('k', 'v'), ('j', 's'), ('m', 'p'), ('l', 'q');
+CREATE VIEW v1 AS SELECT a, MIN(b) AS b FROM t3 GROUP BY a;
+EXPLAIN
+SELECT * FROM t1, t2, v1 WHERE t2.a=t1.a AND t2.a=v1.a AND t2.a=v1.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ref a a 4 const 1 Using index
+1 PRIMARY <derived2> ref key0 key0 10 const,const 1
+2 DERIVED t3 ALL NULL NULL NULL NULL 12 Using temporary; Using filesort
+SELECT * FROM t1, t2, v1 WHERE t2.a=t1.a AND t2.a=v1.a AND t2.a=v1.b;
+a a a b
+c c c c
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #802845: select from derived table with limit 0
+#
+SELECT * FROM (SELECT 1 LIMIT 0) t;
+1
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (7), (1), (3);
+SELECT * FROM (SELECT * FROM t1 LIMIT 0) t;
+a
+DROP TABLE t1;
+#
+# LP bug #803851: materialized view + IN->EXISTS
+#
+SET SESSION optimizer_switch='semijoin=off,derived_with_keys=on,materialization=off';
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (2,2), (3,3), (1,1);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1), (2), (1);
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (3), (1), (2), (1);
+CREATE VIEW v1 AS SELECT a, MAX(b) AS b FROM t1 GROUP BY a;
+EXPLAIN EXTENDED
+SELECT * FROM t3
+WHERE t3.a IN (SELECT v1.a FROM v1, t2 WHERE t2.a = v1.b);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+2 DEPENDENT SUBQUERY <derived3> ref key1 key1 5 func 2 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+3 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(select `v1`.`a` from `test`.`v1` join `test`.`t2` where ((`test`.`t2`.`a` = `v1`.`b`) and (<cache>(`test`.`t3`.`a`) = `v1`.`a`)))))
+SELECT * FROM t3
+WHERE t3.a IN (SELECT v1.a FROM v1, t2 WHERE t2.a = v1.b);
+a
+1
+2
+1
+SET SESSION optimizer_switch=@save_optimizer_switch;
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #804515: materialized derived + ORDER BY
+#
+CREATE TABLE t1 (f1 varchar(1), f2 varchar(1), KEY (f2));
+INSERT INTO t1 VALUES
+('r','x'), ('x','d'), ('x','r'), ('r','f'), ('x','x');
+CREATE TABLE t2 (f1 varchar(1), f2 varchar(1));
+INSERT INTO t2 VALUES ('s','x');
+CREATE TABLE t3 (f1 varchar(1), f2 varchar(1), KEY (f2));
+INSERT INTO t3 VALUES
+(NULL,'x'), (NULL,'f'), ('t','p'), (NULL,'j'), ('g','c');
+CREATE TABLE t4 (f1 int, f2 varchar(1), KEY (f2,f1)) ;
+INSERT INTO t4 VALUES (1,'x'), (5,'r');
+EXPLAIN
+SELECT t.f1 AS f
+FROM (SELECT DISTINCT t1.* FROM t1,t2 WHERE t2.f2 = t1.f2) t,t3,t4
+WHERE t4.f2 = t3.f2 AND t4.f2 = t.f1 ORDER BY f;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using where; Using filesort
+1 PRIMARY t4 ref f2 f2 4 t.f1 1 Using index
+1 PRIMARY t3 ref f2 f2 4 t.f1 2 Using index
+2 DERIVED t2 system NULL NULL NULL NULL 1 Using temporary
+2 DERIVED t1 ref f2 f2 4 const 2 Using where
+SELECT t.f1 AS f
+FROM (SELECT DISTINCT t1.* FROM t1,t2 WHERE t2.f2 = t1.f2) t,t3,t4
+WHERE t4.f2 = t3.f2 AND t4.f2 = t.f1 ORDER BY f;
+f
+x
+DROP TABLE t1,t2,t3,t4;
+#
+# LP bug #806431: join over materialized derived with key
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (0,0),(3,0),(1,0);
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT a,b FROM t1 ;
+SET SESSION optimizer_switch='derived_with_keys=off';
+SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
+a b a b
+0 0 0 0
+0 0 3 0
+0 0 1 0
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t.a 2
+2 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
+a b a b
+0 0 1 0
+0 0 3 0
+0 0 0 0
+SET SESSION optimizer_switch=@save_optimizer_switch;
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# LP bug #806477: left join over merged join with
+# where condition containing f=f
+#
+CREATE TABLE t1 (a int NOT NULL);
+INSERT INTO t1 VALUES (1), (50), (0);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (76,2), (1,NULL);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT t3.b, v1.a
+FROM t3 LEFT JOIN (t2, v1) ON t3.a <> 0
+WHERE v1.a = v1.a OR t3.b <> 0;
+b a
+2 NULL
+EXPLAIN EXTENDED
+SELECT t3.b, v1.a
+FROM t3 LEFT JOIN (t2, v1) ON t3.a <> 0
+WHERE v1.a = v1.a OR t3.b <> 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 0 0.00 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t3`.`b` AS `b`,`test`.`t1`.`a` AS `a` from `test`.`t3` left join (`test`.`t2` join `test`.`t1`) on((`test`.`t3`.`a` <> 0)) where ((`test`.`t1`.`a` = `test`.`t1`.`a`) or (`test`.`t3`.`b` <> 0))
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #806510: subquery with outer reference
+# to a derived_table/view
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (4), (NULL);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (8), (0);
+CREATE TABLE t3 (a int, b int) ;
+INSERT INTO t3 VALUES (7,8);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t1 t
+WHERE EXISTS (SELECT t3.a FROM t3, t2
+WHERE t2.a = t3.b AND t.a != 0);
+a
+4
+EXPLAIN
+SELECT * FROM t1 t
+WHERE EXISTS (SELECT t3.a FROM t3, t2
+WHERE t2.a = t3.b AND t.a != 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM (SELECT * FROM t1) t
+WHERE EXISTS (SELECT t3.a FROM t3, t2
+WHERE t2.a = t3.b AND t.a != 0);
+a
+4
+EXPLAIN
+SELECT * FROM (SELECT * FROM t1) t
+WHERE EXISTS (SELECT t3.a FROM t3, t2
+WHERE t2.a = t3.b AND t.a != 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 1
+3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM v1 t
+WHERE EXISTS (SELECT t3.a FROM t3, t2
+WHERE t2.a = t3.b AND t.a != 0);
+a
+4
+EXPLAIN
+SELECT * FROM v1 t
+WHERE EXISTS (SELECT t3.a FROM t3, t2
+WHERE t2.a = t3.b AND t.a != 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #806097: left join over a view + DISTINCT
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (252,6), (232,0), (174,232);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (232), (174);
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (1), (2);
+CREATE VIEW v1 AS SELECT t2.a FROM t3,t2;
+SELECT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0;
+a
+NULL
+232
+174
+232
+174
+NULL
+SELECT DISTINCT t2.a FROM t1 LEFT JOIN (t3,t2) ON t1.b = 0;
+a
+NULL
+232
+174
+EXPLAIN
+SELECT DISTINCT t2.a FROM t1 LEFT JOIN (t3,t2) ON t1.b = 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+SELECT DISTINCT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0;
+a
+NULL
+232
+174
+EXPLAIN
+SELECT DISTINCT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #806504: right join over a view/derived table
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (0), (0);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+a a b
+NULL 0 0
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t1` semi join (`test`.`t1`) left join `test`.`t2` on((0 <> 0)) where 1
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+a a b
+NULL 0 0
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t1` semi join (`test`.`t1`) left join `test`.`t2` on((0 <> 0)) where 1
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #809206: DISTINCT in derived table / view
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2 (a varchar(32), b int, KEY (a)) ;
+INSERT INTO t2 VALUES
+('j',28), ('c',29), ('i',26), ('c',29), ('k',27),
+('j',28), ('c',29), ('i',25), ('d',26), ('k',27),
+('n',28), ('d',29), ('m',26), ('e',29), ('p',27),
+('w',28), ('x',29), ('y',25), ('z',26), ('s',27);
+CREATE TABLE t3 (a varchar(32));
+INSERT INTO t3 VALUES ('j'), ('c');
+CREATE VIEW v1 AS SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
+SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
+b
+28
+29
+EXPLAIN
+SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 Using temporary
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t2 ref a a 35 test.t3.a 2
+SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t;
+b
+28
+29
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+2 DERIVED t1 system NULL NULL NULL NULL 1 Using temporary
+2 DERIVED t3 ALL NULL NULL NULL NULL 2 Using where
+2 DERIVED t2 ref a a 35 test.t3.a 2
+SELECT * FROM v1;
+b
+28
+29
+EXPLAIN
+SELECT * FROM v1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+2 DERIVED t1 system NULL NULL NULL NULL 1 Using temporary
+2 DERIVED t3 ALL NULL NULL NULL NULL 2 Using where
+2 DERIVED t2 ref a a 35 test.t3.a 2
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #809179: right join over a derived table / view
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (6,5);
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (1,0);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (6,5);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT t.a,t.b FROM t3 RIGHT JOIN (t1 AS t, t2) ON t2.b != 0
+WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+a b
+6 5
+EXPLAIN EXTENDED
+SELECT t.a,t.b FROM t3 RIGHT JOIN (t1 AS t, t2) ON t2.b != 0
+WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select 6 AS `a`,5 AS `b` from `test`.`t1` `t` join `test`.`t2` left join `test`.`t3` on((0 <> 0)) where (not(<expr_cache><6,5>(<in_optimizer>((6,5),<exists>(select 7,5 having (trigcond(((<cache>(6) = 7) or isnull(7))) and trigcond(((<cache>(5) = 5) or isnull(5))) and trigcond(<is_not_null_test>(7)) and trigcond(<is_not_null_test>(5))))))))
+SELECT t.a,t.b FROM t3 RIGHT JOIN ((SELECT * FROM t1) AS t, t2) ON t2.b != 0
+WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+a b
+6 5
+EXPLAIN EXTENDED
+SELECT t.a,t.b FROM t3 RIGHT JOIN ((SELECT * FROM t1) AS t, t2) ON t2.b != 0
+WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select 6 AS `a`,5 AS `b` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on((0 <> 0)) where (not(<expr_cache><6,5>(<in_optimizer>((6,5),<exists>(select 7,5 having (trigcond(((<cache>(6) = 7) or isnull(7))) and trigcond(((<cache>(5) = 5) or isnull(5))) and trigcond(<is_not_null_test>(7)) and trigcond(<is_not_null_test>(5))))))))
+SELECT t.a,t.b FROM t3 RIGHT JOIN (v1 AS t, t2) ON t2.b != 0
+WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+a b
+6 5
+EXPLAIN EXTENDED
+SELECT t.a,t.b FROM t3 RIGHT JOIN (v1 AS t, t2) ON t2.b != 0
+WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select 6 AS `a`,5 AS `b` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on((0 <> 0)) where (not(<expr_cache><6,5>(<in_optimizer>((6,5),<exists>(select 7,5 having (trigcond(((<cache>(6) = 7) or isnull(7))) and trigcond(((<cache>(5) = 5) or isnull(5))) and trigcond(<is_not_null_test>(7)) and trigcond(<is_not_null_test>(5))))))))
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #794901: insert into a multi-table view
+#
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int);
+CREATE VIEW v1 AS SELECT t1.a FROM t1,t2;
+CREATE VIEW v2 AS SELECT a FROM t2 GROUP BY a;
+CREATE VIEW v3 AS SELECT v1.a FROM v1,v2;
+INSERT INTO v3(a) VALUES (1);
+ERROR HY000: The target table v3 of the INSERT is not insertable-into
+DROP VIEW v1,v2,v3;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #793448: materialized view accessed by two-component key
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (9,3), (2,5);
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (9,3), (3,7), (9,1), (2,5), (2,4), (3,8);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,3), (9,7), (9,1), (2,4);
+CREATE VIEW v1(a,b) AS SELECT a, MAX(b) FROM t2 GROUP BY a;
+CREATE VIEW v2(a,b) AS SELECT a,b FROM t2 UNION SELECT a,b FROM t3;
+SELECT * FROM v1;
+a b
+2 5
+3 8
+9 3
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+a
+9
+2
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1)
+3 DERIVED t2 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
+SELECT * FROM v2;
+a b
+9 3
+3 7
+9 1
+2 5
+2 4
+3 8
+10 3
+9 7
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+a
+9
+2
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1)
+3 DERIVED t2 ALL NULL NULL NULL NULL 6
+4 UNION t3 ALL NULL NULL NULL NULL 4
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+DROP VIEW v1,v2;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #804686: query over a derived table using a view
+# with a degenerated where condition
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (0,0), (1,0), (0,0), (1,1), (1,0);
+CREATE VIEW v1 AS SELECT a,b FROM t1;
+CREATE VIEW v2 AS SELECT a, MAX(b) AS b FROM t1 GROUP BY a;
+SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b<>0;
+b
+SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b<>0;
+b
+SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b;
+b
+SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b;
+b
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b` from `test`.`t1` where 0
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+3 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `v2`.`b` AS `b` from `test`.`v2` where 0
+DROP VIEW v1,v2;
+DROP TABLE t1;
+#
+# LP bug #819716: crash with embedded tableless materialized derived
+# with a variable
+#
+set optimizer_switch='derived_merge=off';
+EXPLAIN
+SELECT * FROM (SELECT * FROM (SELECT @b) AS t) AS s;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1
+2 DERIVED <derived3> system NULL NULL NULL NULL 1
+3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+SELECT * FROM (SELECT * FROM (SELECT @b) AS t) AS s;
+@b
+NULL
+set optimizer_switch='derived_merge=on';
+#
+# LP bug #823826: view over join + IS NULL in WHERE
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (1), (1);
+CREATE TABLE t2 (b int) ;
+INSERT INTO t2 VALUES (9), (NULL), (7);
+CREATE VIEW v1 AS SELECT * FROM t1,t2;
+EXPLAIN
+SELECT * FROM (SELECT * FROM t1,t2) t WHERE b IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM (SELECT * FROM t1,t2) t WHERE b IS NULL;
+a b
+1 NULL
+1 NULL
+EXPLAIN
+SELECT * FROM v1 WHERE b IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM v1 WHERE b IS NULL;
+a b
+1 NULL
+1 NULL
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #823835: a duplicate of #823189 with derived table
+#
+CREATE TABLE t1 (a varchar(32)) ;
+INSERT INTO t1 VALUES ('r'), ('p');
+CREATE TABLE t2 (a int NOT NULL, b varchar(32)) ;
+INSERT INTO t2 VALUES (28,'j');
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (0), (0);
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT * FROM t1) AS t
+WHERE EXISTS (SELECT t2.a FROM t3 RIGHT JOIN t2 ON (t3.a = t2.a)
+WHERE t2.b < t.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+3 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 't.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists(select 28 from `test`.`t2` left join `test`.`t3` on((`test`.`t3`.`a` = 28)) where ('j' < `test`.`t1`.`a`)))
+SELECT * FROM (SELECT * FROM t1) AS t
+WHERE EXISTS (SELECT t2.a FROM t3 RIGHT JOIN t2 ON (t3.a = t2.a)
+WHERE t2.b < t.a);
+a
+r
+p
+DROP TABLE t1,t2,t3;
+#
+# LP bug #824463: nested outer join using a merged view
+# as an inner table
+#
+CREATE TABLE t1 (b int, a int) ;
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (5), (6);
+CREATE TABLE t3 (a int , c int) ;
+INSERT INTO t3 VALUES (22,1), (23,-1);
+CREATE TABLE t4 (a int);
+CREATE TABLE t5 (d int) ;
+INSERT INTO t5 VALUES (0), (7), (3), (5);
+CREATE VIEW v2 AS SELECT * FROM t2;
+CREATE VIEW v3 AS SELECT * FROM t3;
+EXPLAIN EXTENDED
+SELECT STRAIGHT_JOIN *
+FROM ( t2 AS s2
+JOIN
+( t3 AS s3
+LEFT JOIN
+( t4 LEFT JOIN t3 ON t4.a != 0 )
+ON s3.a != 0)
+ON s2.a != 0)
+JOIN t5 ON s3.c != 0 AND t5.d = 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE s2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE s3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 0 0.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select straight_join `test`.`s2`.`a` AS `a`,`test`.`s3`.`a` AS `a`,`test`.`s3`.`c` AS `c`,`test`.`t4`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`test`.`t5`.`d` AS `d` from `test`.`t2` `s2` join `test`.`t3` `s3` left join (`test`.`t4` left join `test`.`t3` on((`test`.`t4`.`a` <> 0))) on((`test`.`s3`.`a` <> 0)) join `test`.`t5` where ((`test`.`t5`.`d` = 0) and (`test`.`s3`.`c` <> 0) and (`test`.`s2`.`a` <> 0))
+SELECT STRAIGHT_JOIN *
+FROM ( t2 AS s2
+JOIN
+( t3 AS s3
+LEFT JOIN
+( t4 LEFT JOIN t3 ON t4.a != 0 )
+ON s3.a != 0)
+ON s2.a != 0)
+JOIN t5 ON s3.c != 0 AND t5.d = 0;
+a a c a a c d
+5 22 1 NULL NULL NULL 0
+6 22 1 NULL NULL NULL 0
+5 23 -1 NULL NULL NULL 0
+6 23 -1 NULL NULL NULL 0
+EXPLAIN EXTENDED
+SELECT STRAIGHT_JOIN *
+FROM t2 AS s2 , t5,
+(t3 LEFT JOIN (t4 LEFT JOIN t3 AS s3 ON t4.a != 0) ON t3.a != 0)
+WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE s2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 0 0.00 Using where
+1 SIMPLE s3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select straight_join `test`.`s2`.`a` AS `a`,`test`.`t5`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`test`.`t4`.`a` AS `a`,`test`.`s3`.`a` AS `a`,`test`.`s3`.`c` AS `c` from `test`.`t2` `s2` join `test`.`t5` join `test`.`t3` left join (`test`.`t4` left join `test`.`t3` `s3` on((`test`.`t4`.`a` <> 0))) on((`test`.`t3`.`a` <> 0)) where ((`test`.`t5`.`d` = 0) and (`test`.`s2`.`a` <> 0) and (`test`.`t3`.`c` <> 0))
+SELECT STRAIGHT_JOIN *
+FROM t2 AS s2 , t5,
+(t3 LEFT JOIN (t4 LEFT JOIN t3 AS s3 ON t4.a != 0) ON t3.a != 0)
+WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+a d a c a a c
+5 0 22 1 NULL NULL NULL
+6 0 22 1 NULL NULL NULL
+5 0 23 -1 NULL NULL NULL
+6 0 23 -1 NULL NULL NULL
+EXPLAIN EXTENDED
+SELECT STRAIGHT_JOIN *
+FROM v2 AS s2 , t5,
+(t3 LEFT JOIN (t4 LEFT JOIN v3 AS s3 ON t4.a != 0) ON t3.a != 0)
+WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 0 0.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select straight_join `test`.`t2`.`a` AS `a`,`test`.`t5`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`test`.`t4`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c` from `test`.`t2` join `test`.`t5` join `test`.`t3` left join (`test`.`t4` left join (`test`.`t3`) on((`test`.`t4`.`a` <> 0))) on((`test`.`t3`.`a` <> 0)) where ((`test`.`t5`.`d` = 0) and (`test`.`t2`.`a` <> 0) and (`test`.`t3`.`c` <> 0))
+SELECT STRAIGHT_JOIN *
+FROM v2 AS s2 , t5,
+(t3 LEFT JOIN (t4 LEFT JOIN v3 AS s3 ON t4.a != 0) ON t3.a != 0)
+WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+a d a c a a c
+5 0 22 1 NULL NULL NULL
+6 0 22 1 NULL NULL NULL
+5 0 23 -1 NULL NULL NULL
+6 0 23 -1 NULL NULL NULL
+SELECT STRAIGHT_JOIN *
+FROM ( ( t2 AS s2
+LEFT JOIN
+( t3 AS s3
+LEFT JOIN
+( t4 AS s4 JOIN t3 ON s4.a != 0)
+ON s3.a != 0 )
+ON s2.a != 0)
+LEFT JOIN
+t1 AS s1
+ON s1.a != 0)
+JOIN t5 ON s3.c != 0;
+a a c a a c b a d
+5 22 1 NULL NULL NULL NULL NULL 0
+6 22 1 NULL NULL NULL NULL NULL 0
+5 23 -1 NULL NULL NULL NULL NULL 0
+6 23 -1 NULL NULL NULL NULL NULL 0
+5 22 1 NULL NULL NULL NULL NULL 7
+6 22 1 NULL NULL NULL NULL NULL 7
+5 23 -1 NULL NULL NULL NULL NULL 7
+6 23 -1 NULL NULL NULL NULL NULL 7
+5 22 1 NULL NULL NULL NULL NULL 3
+6 22 1 NULL NULL NULL NULL NULL 3
+5 23 -1 NULL NULL NULL NULL NULL 3
+6 23 -1 NULL NULL NULL NULL NULL 3
+5 22 1 NULL NULL NULL NULL NULL 5
+6 22 1 NULL NULL NULL NULL NULL 5
+5 23 -1 NULL NULL NULL NULL NULL 5
+6 23 -1 NULL NULL NULL NULL NULL 5
+SELECT STRAIGHT_JOIN *
+FROM ( ( v2 AS s2
+LEFT JOIN
+( v3 AS s3
+LEFT JOIN
+( t4 AS s4 JOIN v3 ON s4.a != 0)
+ON s3.a != 0 )
+ON s2.a != 0)
+LEFT JOIN
+t1 AS s1
+ON s1.a != 0)
+JOIN t5 ON s3.c != 0;
+a a c a a c b a d
+5 22 1 NULL NULL NULL NULL NULL 0
+6 22 1 NULL NULL NULL NULL NULL 0
+5 23 -1 NULL NULL NULL NULL NULL 0
+6 23 -1 NULL NULL NULL NULL NULL 0
+5 22 1 NULL NULL NULL NULL NULL 7
+6 22 1 NULL NULL NULL NULL NULL 7
+5 23 -1 NULL NULL NULL NULL NULL 7
+6 23 -1 NULL NULL NULL NULL NULL 7
+5 22 1 NULL NULL NULL NULL NULL 3
+6 22 1 NULL NULL NULL NULL NULL 3
+5 23 -1 NULL NULL NULL NULL NULL 3
+6 23 -1 NULL NULL NULL NULL NULL 3
+5 22 1 NULL NULL NULL NULL NULL 5
+6 22 1 NULL NULL NULL NULL NULL 5
+5 23 -1 NULL NULL NULL NULL NULL 5
+6 23 -1 NULL NULL NULL NULL NULL 5
+DROP VIEW v2,v3;
+DROP TABLE t1,t2,t3,t4,t5;
+#
+# LP bug #872735: derived used in a NOT IN subquery
+#
+CREATE TABLE t1 (b int NOT NULL);
+INSERT INTO t1 VALUES (9), (7);
+CREATE TABLE t2 (a int NOT NULL) ;
+INSERT INTO t2 VALUES (1), (2);
+CREATE TABLE t3 (
+a int NOT NULL , c int NOT NULL, d varchar(1) NOT NULL,
+KEY (c,a) , PRIMARY KEY (a)
+);
+INSERT INTO t3 VALUES
+(14,4,'a'), (15,7,'b'), (16,4,'c'), (17,1,'d'), (18,9,'e'),
+(19,4,'f'), (20,8,'g');
+SET SESSION optimizer_switch='derived_merge=on,subquery_cache=off,materialization=off';
+# The following two EXPLAINs must return the same execution plan
+EXPLAIN
+SELECT * FROM t1 , t2
+WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM t3 t);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t eq_ref PRIMARY,c PRIMARY 4 func 1 Using where
+EXPLAIN
+SELECT * FROM t1 , t2
+WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,c PRIMARY 4 func 1 Using where
+SELECT * FROM t1 , t2
+WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t);
+b a
+9 1
+7 1
+9 2
+7 2
+DROP TABLE t1,t2,t3;
+#
+# LP bug #874006: materialized view used in IN subquery
+#
+CREATE TABLE t3 (a int NOT NULL, b varchar(1), c varchar(1));
+INSERT INTO t3 VALUES (19,NULL,NULL), (20,'r','r');
+CREATE TABLE t1 (a int, b varchar(1) , c varchar(1));
+INSERT INTO t1 VALUES (1,NULL,NULL), (5,'r','r'), (7,'y','y');
+CREATE TABLE t2 (a int NOT NULL , b int, c varchar(1));
+INSERT INTO t2 VALUES (4,3,'r');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 3 Using where; Start temporary; End temporary
+3 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+a b c
+20 r r
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY <derived3> ref key1 key1 10 const,const 0 Start temporary
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+3 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+a b c
+20 r r
+SET optimizer_switch=@save_optimizer_switch;
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #873263: materialized view used in correlated IN subquery
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (5,4), (9,8);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (4,5), (5,1);
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.b,test.t1.a 2 FirstMatch(t1)
+3 DERIVED t2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+a b
+5 4
+DROP VIEW v2;
+DROP TABLE t1,t2;
+#
+# LP bug #877316: query over a view with correlated subquery in WHERE
+#
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (18,2), (19,9);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (10,8), (5,10);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT t1.a FROM t1
+WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < t1.b);
+a
+19
+EXPLAIN
+SELECT t1.a FROM t1
+WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < t1.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT v1.a FROM v1
+WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < v1.b);
+a
+19
+EXPLAIN
+SELECT v1.a FROM v1
+WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < v1.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #878199: join of two materialized views
+#
+CREATE TABLE t1 (a int, b varchar(1)) ;
+INSERT INTO t1 VALUES (7,'c'), (3,'h'), (7,'c');
+CREATE TABLE t2 (b varchar(1)) ;
+INSERT INTO t2 VALUES ('p'), ('c'), ('j'), ('c'), ('p');
+CREATE VIEW v1 AS SELECT * FROM t1 GROUP BY a,b;
+CREATE VIEW v2 AS SELECT * FROM t2 GROUP BY b;
+SET SESSION optimizer_switch = 'derived_with_keys=on';
+SELECT v1.a FROM v1,v2 WHERE v2.b = v1.b ORDER BY 1;
+a
+7
+EXPLAIN
+SELECT v1.a FROM v1,v2 WHERE v2.b = v1.b ORDER BY 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using where; Using filesort
+1 PRIMARY <derived3> ref key0 key0 5 v1.b 2
+3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
+2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+#
+# Bug #743378: join over merged view employing BNL
+#
+CREATE TABLE t1 ( d varchar(1) NOT NULL) ;
+INSERT INTO t1 VALUES ('j'),('v'),('c');
+CREATE TABLE t2 (h time NOT NULL, d varchar(1) NOT NULL) ;
+INSERT INTO t2 VALUES ('05:03:03','w'),('02:59:24','d'),('00:01:58','e');
+CREATE TABLE t3 (
+b int NOT NULL, e varchar(1) NOT NULL, d varchar(1) NOT NULL, KEY (e,b)
+);
+INSERT INTO t3 VALUES (4,'x','x'),(9,'w','w'),(4,'d','d'),(8,'e','e');
+INSERT INTO t3 VALUES (14,'a','a'),(19,'b','b'),(14,'c','c'),(18,'d','d');
+CREATE TABLE t4 (i int NOT NULL, m varchar(1) NOT NULL) ;
+INSERT INTO t4 VALUES (8,'m'),(9,'d'),(2,'s'),(4,'r'),(8,'m');
+CREATE TABLE t5 (
+a int NOT NULL, c int NOT NULL, b int NOT NULL, f date NOT NULL,
+g date NOT NULL, h time NOT NULL, j time NOT NULL, k datetime NOT NULL
+);
+INSERT INTO t5 VALUES
+(1,4,0,'0000-00-00','0000-00-00','21:22:34','21:22:34','2002-02-13 17:30'),
+(2,6,8,'2004-09-18','2004-09-18','10:50:38','10:50:38','2008-09-27 00:34');
+CREATE VIEW v3 AS SELECT t3.*, t4.i FROM t3, t4, t5;
+SET SESSION join_cache_level = 1;
+SET SESSION join_buffer_size = 512;
+EXPLAIN
+SELECT t2.d FROM t1,t2,v3 WHERE v3.e = t2.d AND v3.i < 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t5 ALL NULL NULL NULL NULL 2
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 SIMPLE t3 ref e e 3 test.t2.d 1 Using index
+1 SIMPLE t4 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
+SELECT t2.d FROM t1,t2,v3 WHERE v3.e = t2.d AND v3.i < 3;
+d
+w
+w
+w
+w
+w
+w
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+d
+e
+e
+e
+e
+e
+e
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION join_buffer_size = DEFAULT;
+DROP VIEW v3;
+DROP TABLE t1,t2,t3,t4,t5;
+#
+# Bug #879882: right join within mergeable derived table
+#
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('c'), ('a');
+CREATE TABLE t2 (a int, b int, c varchar(1));
+INSERT INTO t2 VALUES (29,8,'c'), (39,7,'b');
+CREATE TABLE t3 (b int);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b AND t.c = t1.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t3 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on(multiple equal(NULL, `test`.`t2`.`a`)) where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t2`.`b` <> 0))
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b AND t.c = t1.a;
+b c a
+8 c c
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b <> 0 AND t.c = t1.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t3 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on(multiple equal(NULL, `test`.`t2`.`a`)) where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t2`.`b` <> 0))
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b <> 0 AND t.c = t1.a;
+b c a
+8 c c
+INSERT INTO t3 VALUES (100), (200);
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b AND t.c = t1.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on((`test`.`t3`.`b` = `test`.`t2`.`a`)) where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t2`.`b` <> 0))
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b AND t.c = t1.a;
+b c a
+8 c c
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b <> 0 AND t.c = t1.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on((`test`.`t3`.`b` = `test`.`t2`.`a`)) where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t2`.`b` <> 0))
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b <> 0 AND t.c = t1.a;
+b c a
+8 c c
+SET optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# Bug #880724: materialized const view as inner table of outer join
+#
+CREATE TABLE t1 (a int, b varchar(1));
+INSERT INTO t1 VALUES (9,NULL), (6,'r'), (7,'c');
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (6);
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+SET SESSION optimizer_switch = 'derived_with_keys=on';
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT t1.b,v2.a FROM t1 LEFT JOIN v2 ON v2.a = t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 1 Using where
+2 DERIVED t2 system NULL NULL NULL NULL 1
+SELECT t1.b,v2.a FROM t1 LEFT JOIN v2 ON v2.a = t1.a;
+b a
+NULL NULL
+r 6
+c NULL
+CREATE TABLE t3 (a int, b varchar(1));
+INSERT INTO t3 VALUES (8,'x'), (5,'r'), (9,'y');
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b <> ANY (SELECT t1.b FROM t1 LEFT JOIN v2 ON v2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 1 Using where
+3 DERIVED t2 system NULL NULL NULL NULL 1
+SELECT * FROM t3
+WHERE t3.b <> ANY (SELECT t1.b FROM t1 LEFT JOIN v2 ON v2.a = t1.a);
+a b
+8 x
+5 r
+9 y
+SET SESSION join_cache_level = default;
+SET optimizer_switch=@save_optimizer_switch;
+DROP VIEW v2;
+DROP TABLE t1,t2,t3;
+#
+# Bug #881449: OUTER JOIN usin a merged view within IN subquery
+#
+CREATE TABLE t1 (a varchar(1)) ;
+INSERT INTO t1 VALUES ('y'), ('x');
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (1), (2);
+CREATE TABLE t3 (a int, b varchar(1)) ;
+INSERT INTO t3 VALUES (1,'x');
+CREATE VIEW v3 AS SELECT * FROM t3;
+SET SESSION optimizer_switch='semijoin=on';
+EXPLAIN
+SELECT * FROM t1 WHERE a IN (SELECT v3.b FROM t2 RIGHT JOIN v3 ON v3.a = t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 system NULL NULL NULL NULL 1
+1 PRIMARY t2 const PRIMARY PRIMARY 4 const 1 Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1 WHERE a IN (SELECT v3.b FROM t2 RIGHT JOIN v3 ON v3.a = t2.a);
+a
+x
+set optimizer_switch= @save_optimizer_switch;
+DROP VIEW v3;
+DROP TABLE t1,t2,t3;
+#
+# Bug #874035: view as an inner table of a materialized derived
+#
+CREATE TABLE t2 (a int NOT NULL);
+INSERT INTO t2 VALUES (7), (4);
+CREATE TABLE t1 (b int NOT NULL);
+INSERT INTO t1 VALUES (5), (7);
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='derived_merge=off';
+PREPARE st1 FROM
+'SELECT * FROM (SELECT * FROM t2 LEFT JOIN v1 ON t2.a = v1.b) AS t';
+EXECUTE st1;
+a b
+7 7
+4 NULL
+EXECUTE st1;
+a b
+7 7
+4 NULL
+DEALLOCATE PREPARE st1;
+set SESSION optimizer_switch= @save_optimizer_switch;
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #879939: assertion in ha_maria::enable_indexes
+# with derived_with_keys=on
+#
+CREATE TABLE t2 (a varchar(3));
+INSERT INTO t2 VALUES ('USA'), ('USA'), ('USA'), ('USA'), ('USA');
+CREATE TABLE t1 (a varchar(3), b varchar(35));
+INSERT INTO t1 VALUES
+('USA','Lansing'), ('USA','Laredo'), ('USA','Las Vegas'),
+('USA','Lexington-Fayett'), ('USA','Lincoln'), ('USA','Little Rock'),
+('USA','Livonia'), ('USA','Long Beach'), ('USA','Los Angeles'),
+('USA','Louisville'), ('USA','Lowell'), ('USA','Lubbock'),
+('USA','Macon'), ('USA','Madison'), ('USA','Manchester'),
+('USA','McAllen'), ('USA','Memphis'), ('USA','Mesa'),
+('USA','Mesquite'), ('USA','Metairie'), ('USA','Miami');
+CREATE TABLE t3 (a varchar(35));
+INSERT INTO t3 VALUES ('Miami');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'derived_with_keys=on';
+SET @@tmp_table_size=1024*4;
+explain SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 system NULL NULL NULL NULL 1
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5
+1 SIMPLE t1 ALL NULL NULL NULL NULL 21 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
+a b a
+USA Miami Miami
+USA Miami Miami
+USA Miami Miami
+USA Miami Miami
+USA Miami Miami
+SET @@tmp_table_size=1024*1024*16;
+SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
+a b a
+USA Miami Miami
+USA Miami Miami
+USA Miami Miami
+USA Miami Miami
+USA Miami Miami
+SET @@tmp_table_size=default;
+set SESSION optimizer_switch= @save_optimizer_switch;
+drop table t1,t2,t3;
+#
+# BUG#882994: Crash in QUICK_RANGE_SELECT::reset with derived_with_keys
+#
+CREATE TABLE t2 (
+pk varchar(33),
+col_varchar_key varchar(3) NOT NULL,
+col_varchar_nokey varchar(52) NOT NULL);
+INSERT INTO t2 VALUES ('NICSpanish','NIC','Spanish'),
+('NERHausa','NER','Hausa'),('NGAJoruba','NGA','Joruba'),
+('NIUNiue','NIU','Niue'),('NFKEnglish','NFK','English'),
+('NORNorwegian','NOR','Norwegian'),('CIVAkan','CIV','Akan'),
+('OMNArabic','OMN','Arabic'),('PAKPunjabi','PAK','Punjabi'),
+('PLWPalau','PLW','Palau'),('PANSpanish','PAN','Spanish'),
+('PNGPapuan Langua','PNG','Papuan Languages'), ('PRYSpanish','PRY','Spanish'),
+('PERSpanish','PER','Spanish'), ('PCNPitcairnese','PCN','Pitcairnese'),
+('MNPPhilippene La','MNP','Philippene Langu'),('PRTPortuguese','PRT','Portuguese'),
+('PRISpanish','PRI','Spanish'),('POLPolish','POL','Polish'),('GNQFang','GNQ','Fang');
+CREATE TABLE t1 ( col_varchar_nokey varchar(52) NOT NULL ) ;
+INSERT INTO t1 VALUES ('Chinese'),('English'),('French'),('German'),
+('Italian'),('Japanese'),('Korean'),('Polish'),('Portuguese'),('Spanish'),
+('Tagalog'),('Vietnamese');
+CREATE TABLE t3 ( col_varchar_key varchar(52)) ;
+INSERT INTO t3 VALUES ('United States');
+set @tmp_882994= @@max_heap_table_size;
+set max_heap_table_size=1;
+SELECT *
+FROM t3 JOIN
+( SELECT t2.* FROM t1, t2 ) AS alias2
+ON ( alias2.col_varchar_nokey = t3.col_varchar_key )
+ORDER BY CONCAT(alias2.col_varchar_nokey);
+col_varchar_key pk col_varchar_key col_varchar_nokey
+set max_heap_table_size= @tmp_882994;
+drop table t1,t2,t3;
+#
+# LP bug #917990: Bad estimate of #rows for derived table with LIMIT
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES
+(8), (3), (4), (7), (9), (5), (1), (2);
+SELECT * FROM (SELECT * FROM t1 LIMIT 3) t;
+a
+8
+3
+4
+EXPLAIN
+SELECT * FROM (SELECT * FROM t1 LIMIT 3) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
+2 DERIVED t1 ALL NULL NULL NULL NULL 8
+DROP TABLE t1;
+#
+# LP BUG#921878 incorrect check of items during columns union types
+# aggregation for merged derived tables
+#
+SET @save_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='derived_merge=on';
+CREATE TABLE t1 ( a ENUM( 'x', 'y' ) );
+insert into t1 values ('x');
+CREATE TABLE t2 LIKE t1;
+insert into t1 values ('y');
+CREATE TABLE t3 LIKE t1;
+INSERT INTO t3
+SELECT * FROM ( SELECT * FROM t1 ) AS A
+UNION SELECT * FROM t2;
+select * from t3;
+a
+x
+y
+drop table t1,t2,t3;
+set SESSION optimizer_switch= @save_optimizer_switch;
+#
+# LP BUG#944782: derived table from an information schema table
+#
+SET @save_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='derived_merge=on';
+SET SESSION optimizer_switch='derived_with_keys=on';
+CREATE TABLE t1 (c1 int PRIMARY KEY, c2 char(5));
+EXPLAIN
+SELECT COUNT(*) > 0
+FROM INFORMATION_SCHEMA.COLUMNS
+INNER JOIN
+(SELECT TABLE_SCHEMA,
+GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COL_NAMES
+FROM INFORMATION_SCHEMA.STATISTICS
+GROUP BY TABLE_SCHEMA) AS UNIQUES
+ON ( COLUMNS.TABLE_SCHEMA = UNIQUES.TABLE_SCHEMA);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY COLUMNS ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 DERIVED STATISTICS ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases; Using filesort
+SELECT COUNT(*) > 0
+FROM INFORMATION_SCHEMA.COLUMNS
+INNER JOIN
+(SELECT TABLE_SCHEMA,
+GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COL_NAMES
+FROM INFORMATION_SCHEMA.STATISTICS
+GROUP BY TABLE_SCHEMA) AS UNIQUES
+ON ( COLUMNS.TABLE_SCHEMA = UNIQUES.TABLE_SCHEMA);
+COUNT(*) > 0
+1
+DROP TABLE t1;
+SET SESSION optimizer_switch= @save_optimizer_switch;
+#
+# LP BUG#953649: crash when estimating the cost of a look-up
+# into a derived table to be materialized
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (132);
+CREATE TABLE t2 (b int, c varchar(256));
+INSERT INTO t2 VALUES (132,'test1'), (120,'text2'), (132,'text3');
+CREATE VIEW v AS
+SELECT b, GROUP_CONCAT(c) AS gc FROM t2 GROUP BY b;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='derived_merge=off';
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t1, v WHERE a = b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using where
+2 DERIVED t2 ALL NULL NULL NULL NULL 3 Using filesort
+SELECT * FROM t1, v WHERE a = b;
+a b gc
+132 132 test1,text3
+SET SESSION optimizer_switch='derived_merge=on';
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1, v WHERE a = b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <derived2> ref key0 key0 5 const 0
+2 DERIVED t2 ALL NULL NULL NULL NULL 3 Using filesort
+SELECT * FROM t1, v WHERE a = b;
+a b gc
+132 132 test1,text3
+SET SESSION optimizer_switch= @save_optimizer_switch;
+DROP VIEW v;
+DROP TABLE t1,t2;
+#
+# LP BUG#968720 crash due to converting to materialized and
+# natural join made only once
+#
+SET @save968720_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on';
+CREATE TABLE t1 (a int, INDEX(a));
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (a int, INDEX(a));
+INSERT INTO t2 VALUES (1), (2);
+INSERT INTO t1 SELECT a FROM (SELECT a FROM test.t1) AS s1 NATURAL JOIN
+t2 AS s2;
+SELECT * FROM t1;
+a
+1
+1
+DELETE FROM t1;
+INSERT INTO t1 VALUES (1);
+PREPARE stmt FROM "
+INSERT INTO t1 SELECT a FROM (SELECT a FROM test.t1) AS s1 NATURAL JOIN
+t2 AS s2;
+";
+EXECUTE stmt;
+SELECT * FROM t1;
+a
+1
+1
+EXECUTE stmt;
+SELECT * FROM t1;
+a
+1
+1
+1
+1
+drop table t1,t2;
+set optimizer_switch=@save968720_optimizer_switch;
+#
+# LP BUG#978847 Server crashes in Item_ref::real_item on
+# INSERT .. SELECT with FROM subquery and derived_merge=ON
+SET @save978847_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on';
+CREATE TABLE t1 ( a INT, b INT );
+INSERT INTO t1 VALUES (2,1),(3,2);
+select * from t1;
+a b
+2 1
+3 2
+INSERT INTO t1 SELECT * FROM
+( SELECT * FROM t1 ) AS alias;
+select * from t1;
+a b
+2 1
+3 2
+2 1
+3 2
+prepare stmt1 from 'INSERT INTO t1 SELECT SQL_BIG_RESULT * FROM
+ ( SELECT * FROM t1 ) AS alias';
+execute stmt1;
+select * from t1;
+a b
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+execute stmt1;
+select * from t1;
+a b
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+drop table t1;
+set optimizer_switch=@save978847_optimizer_switch;
+#
+# LP bug998516 Server hangs on INSERT .. SELECT with derived_merge,
+# FROM subquery, UNION
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (3),(4);
+INSERT INTO t1 SELECT * FROM ( SELECT * FROM t1 ) AS alias UNION SELECT * FROM t2;
+select * from t1;
+a
+1
+2
+1
+2
+3
+4
+drop table t1,t2;
+#
+# MDEV-3873: Wrong result (extra rows) with NOT IN and
+# a subquery from a MERGE view
+#
+CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4),(7),(0);
+CREATE TABLE t2 (b INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1),(2);
+CREATE TABLE t3 (c INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (4),(6),(3);
+CREATE TABLE t4 (d INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t4 VALUES (4),(5),(3);
+CREATE TABLE tv (e INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO tv VALUES (1),(3);
+CREATE ALGORITHM=TEMPTABLE VIEW v_temptable AS SELECT * FROM tv;
+CREATE ALGORITHM=MERGE VIEW v_merge AS SELECT * FROM tv;
+SELECT * FROM t1, t2
+WHERE a NOT IN ( SELECT e FROM t3 LEFT JOIN v_temptable ON (c = e) WHERE c <> b ) AND a < b;
+a b
+SELECT * FROM t1, t2
+WHERE a NOT IN ( SELECT e FROM t3 LEFT JOIN v_merge ON (c = e) WHERE c <> b ) AND a < b;
+a b
+SELECT * FROM t1, t2
+WHERE a NOT IN ( SELECT e FROM t3 LEFT JOIN (SELECT * FROM tv) as derived ON (c = e) WHERE c <> b ) AND a < b;
+a b
+drop view v_temptable, v_merge;
+drop table t1,t2,t3,t4,tv;
+#
+# MDEV-3912: Wrong result (extra rows) with FROM subquery inside
+# ALL subquery, LEFT JOIN, derived_merge.
+# (duplicate of MDEV-3873 (above))
+#
+SET @save3912_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on,in_to_exists=on';
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4),(8);
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (7),(0);
+CREATE TABLE t3 (c INT, d INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (0,4),(8,6);
+SELECT * FROM t1
+WHERE a >= ALL (
+SELECT d FROM t2 LEFT JOIN ( SELECT * FROM t3 ) AS alias ON ( c = b )
+WHERE b >= a
+);
+a
+8
+set optimizer_switch=@save3912_optimizer_switch;
+drop table t1, t2, t3;
+#
+# end of 5.3 tests
+#
+set optimizer_switch=@exit_optimizer_switch;
+set join_cache_level=@exit_join_cache_level;
diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result
index b1cb70fa43c..dc3b2fb1b47 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
@@ -280,6 +280,8 @@ unique (id, idx)
insert into t1 values (1,'yes'), (2,'no');
insert into t2 values (1,1);
insert into t3 values (1,1);
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
EXPLAIN
SELECT DISTINCT
t1.id
@@ -300,11 +302,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
@@ -326,6 +328,7 @@ AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2));
id
2
drop table t1,t2,t3;
+set join_cache_level=@save_join_cache_level;
create table t1 (a int not null, b int not null, t time);
insert into t1 values (1,1,"00:06:15"),(1,2,"00:06:15"),(1,2,"00:30:15"),(1,3,"00:06:15"),(1,3,"00:30:15");
select a,sec_to_time(sum(time_to_sec(t))) from t1 group by a,b;
@@ -515,7 +518,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
@@ -794,3 +797,85 @@ DROP TABLE t1;
SET @@sort_buffer_size = @old_sort_buffer_size;
SET @@max_heap_table_size = @old_max_heap_table_size;
End of 5.1 tests
+create table t1 (a varchar(100));
+insert t1 values ('2010-10-10'), ('20101010');
+select * from t1 where a = DATE('2010-10-10');
+a
+2010-10-10
+20101010
+select distinct a from t1 where a = DATE('2010-10-10');
+a
+2010-10-10
+20101010
+explain select distinct a from t1 where a = DATE('2010-10-10');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where; Using temporary
+drop table t1;
+# date = string
+create table t1 (a date);
+insert t1 values ('2010-10-10'), ('20101010');
+explain select distinct a from t1 where a = '2010-10-10';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
+drop table t1;
+# double = string
+create table t1 (a double);
+insert t1 values (2), (2);
+explain select distinct a from t1 where a = '2';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
+# double = int
+explain select distinct a from t1 where a = 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
+# string = double
+alter table t1 modify a varchar(100);
+explain select distinct a from t1 where a = 2e0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where; Using temporary
+drop table t1;
+create table t1 (f1 varchar(40));
+insert into t1 values ('2010-10-10 00:00:00.0001'),('2010-10-10 00:00:00.0002'),('2010-10-10 00:00:00.0003');
+select time(f1) from t1 ;
+time(f1)
+00:00:00.000100
+00:00:00.000200
+00:00:00.000300
+select distinct time(f1) from t1 ;
+time(f1)
+00:00:00.000100
+00:00:00.000200
+00:00:00.000300
+drop table t1;
+create table t1(i int, g int);
+insert into t1 values (null, 1), (0, 2);
+select distinct i from t1 group by g;
+i
+NULL
+0
+drop table t1;
+create table t1(i int, g blob);
+insert into t1 values (null, 1), (0, 2);
+select distinct i from t1 group by g;
+i
+NULL
+0
+drop table t1;
+create table t1 (a int) engine=myisam;
+insert into t1 values (0),(7);
+create table t2 (b int) engine=myisam;
+insert into t2 values (7),(0),(3);
+create algorithm=temptable view v as
+select distinct (select max(a) from t1 where alias.b = a) as field1 from t2 as alias group by field1;
+select * from v;
+field1
+NULL
+0
+7
+select distinct (select max(a) from t1 where alias.b = a) as field1 from t2 as alias group by field1;
+field1
+NULL
+0
+7
+drop view v;
+drop table t1, t2;
diff --git a/mysql-test/r/dyncol.result b/mysql-test/r/dyncol.result
new file mode 100644
index 00000000000..d38660adcc6
--- /dev/null
+++ b/mysql-test/r/dyncol.result
@@ -0,0 +1,1337 @@
+#
+# column create
+#
+select hex(COLUMN_CREATE(1, NULL AS char character set utf8));
+hex(COLUMN_CREATE(1, NULL AS char character set utf8))
+000000
+select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8));
+hex(COLUMN_CREATE(1, "afaf" AS char character set utf8))
+0001000100030861666166
+select hex(COLUMN_CREATE(1, 1212 AS char character set utf8));
+hex(COLUMN_CREATE(1, 1212 AS char character set utf8))
+0001000100033F31323132
+select hex(COLUMN_CREATE(1, 12.12 AS char character set utf8));
+hex(COLUMN_CREATE(1, 12.12 AS char character set utf8))
+0001000100033F31322E3132
+select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS char character set utf8));
+hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS char character set utf8))
+0001000100033F3939393939393939393939393939393939393939393939393939393939
+select hex(COLUMN_CREATE(1, NULL AS unsigned int));
+hex(COLUMN_CREATE(1, NULL AS unsigned int))
+000000
+select hex(COLUMN_CREATE(1, 1212 AS unsigned int));
+hex(COLUMN_CREATE(1, 1212 AS unsigned int))
+000100010001BC04
+select hex(COLUMN_CREATE(1, 7 AS unsigned int));
+hex(COLUMN_CREATE(1, 7 AS unsigned int))
+00010001000107
+select hex(COLUMN_CREATE(1, 8 AS unsigned int));
+hex(COLUMN_CREATE(1, 8 AS unsigned int))
+00010001000108
+select hex(COLUMN_CREATE(1, 127 AS unsigned int));
+hex(COLUMN_CREATE(1, 127 AS unsigned int))
+0001000100017F
+select hex(COLUMN_CREATE(1, 128 AS unsigned int));
+hex(COLUMN_CREATE(1, 128 AS unsigned int))
+00010001000180
+select hex(COLUMN_CREATE(1, 12.12 AS unsigned int));
+hex(COLUMN_CREATE(1, 12.12 AS unsigned int))
+0001000100010C
+select hex(COLUMN_CREATE(1, ~0));
+hex(COLUMN_CREATE(1, ~0))
+000100010001FFFFFFFFFFFFFFFF
+select hex(COLUMN_CREATE(1, -1));
+hex(COLUMN_CREATE(1, -1))
+00010001000001
+select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS unsigned int));
+hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS unsigned int))
+000100010001FFFFFFFFFFFFFF7F
+Warnings:
+Error 1916 Got overflow when converting '99999999999999999999999999999' to INT. Value truncated.
+select hex(COLUMN_CREATE(1, NULL AS int));
+hex(COLUMN_CREATE(1, NULL AS int))
+000000
+select hex(COLUMN_CREATE(1, 1212 AS int));
+hex(COLUMN_CREATE(1, 1212 AS int))
+0001000100007809
+select hex(COLUMN_CREATE(1, 7 AS int));
+hex(COLUMN_CREATE(1, 7 AS int))
+0001000100000E
+select hex(COLUMN_CREATE(1, 8 AS int));
+hex(COLUMN_CREATE(1, 8 AS int))
+00010001000010
+select hex(COLUMN_CREATE(1, 127 AS int));
+hex(COLUMN_CREATE(1, 127 AS int))
+000100010000FE
+select hex(COLUMN_CREATE(1, 128 AS int));
+hex(COLUMN_CREATE(1, 128 AS int))
+0001000100000001
+select hex(COLUMN_CREATE(1, 12.12 AS int));
+hex(COLUMN_CREATE(1, 12.12 AS int))
+00010001000018
+select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS int));
+hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS int))
+000100010000FEFFFFFFFFFFFFFF
+Warnings:
+Error 1916 Got overflow when converting '99999999999999999999999999999' to INT. Value truncated.
+select hex(COLUMN_CREATE(1, NULL AS double));
+hex(COLUMN_CREATE(1, NULL AS double))
+000000
+select hex(COLUMN_CREATE(1, 1212 AS double));
+hex(COLUMN_CREATE(1, 1212 AS double))
+0001000100020000000000F09240
+select hex(COLUMN_CREATE(1, 12.12 AS double));
+hex(COLUMN_CREATE(1, 12.12 AS double))
+0001000100023D0AD7A3703D2840
+select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS double));
+hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS double))
+00010001000221D7E6FAE031F445
+select hex(COLUMN_CREATE(1, NULL AS decimal));
+hex(COLUMN_CREATE(1, NULL AS decimal))
+000000
+select hex(COLUMN_CREATE(1, 1212 AS decimal));
+hex(COLUMN_CREATE(1, 1212 AS decimal))
+0001000100040900800004BC
+select hex(COLUMN_CREATE(1, 7 AS decimal));
+hex(COLUMN_CREATE(1, 7 AS decimal))
+000100010004090080000007
+select hex(COLUMN_CREATE(1, 8 AS decimal));
+hex(COLUMN_CREATE(1, 8 AS decimal))
+000100010004090080000008
+select hex(COLUMN_CREATE(1, 127 AS decimal));
+hex(COLUMN_CREATE(1, 127 AS decimal))
+00010001000409008000007F
+select hex(COLUMN_CREATE(1, 128 AS decimal));
+hex(COLUMN_CREATE(1, 128 AS decimal))
+000100010004090080000080
+select hex(COLUMN_CREATE(1, 12.12 AS decimal));
+hex(COLUMN_CREATE(1, 12.12 AS decimal))
+00010001000402028C0C
+select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS decimal));
+hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS decimal))
+0001000100041D00E33B9AC9FF3B9AC9FF3B9AC9FF
+select hex(COLUMN_CREATE(1, NULL AS date));
+hex(COLUMN_CREATE(1, NULL AS date))
+000000
+select hex(COLUMN_CREATE(1, "2011-04-05" AS date));
+hex(COLUMN_CREATE(1, "2011-04-05" AS date))
+00010001000685B60F
+select hex(COLUMN_CREATE(1, NULL AS time));
+hex(COLUMN_CREATE(1, NULL AS time))
+000000
+select hex(COLUMN_CREATE(1, "0:45:49.000001" AS time));
+hex(COLUMN_CREATE(1, "0:45:49.000001" AS time))
+000100010007010010B70000
+select hex(COLUMN_CREATE(1, NULL AS datetime));
+hex(COLUMN_CREATE(1, NULL AS datetime))
+000000
+select hex(COLUMN_CREATE(1, "2011-04-05 0:45:49.000001" AS datetime));
+hex(COLUMN_CREATE(1, "2011-04-05 0:45:49.000001" AS datetime))
+00010001000585B60F010010B70000
+select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8,
+2, 1212 AS unsigned int,
+3, 1212 AS int,
+4, 12.12 AS double,
+4+1, 12.12 AS decimal,
+6, "2011-04-05" AS date,
+7, "- 0:45:49.000001" AS time,
+8, "2011-04-05 0:45:49.000001" AS datetime));
+hex(COLUMN_CREATE(1, "afaf" AS char character set utf8,
+2, 1212 AS unsigned int,
+3, 1212 AS int,
+4, 12.12 AS double,
+4+1, 12.12 AS decimal,
+6, "2011-04-05" AS date,
+7, "- 0:45:49.000001" AS time,
+8, "2011-04-05 0:45:49.000001" AS datetime))
+01080001000300020029000300380004004A0005008C000600AE000700C7000800F5000861666166BC0478093D0AD7A3703D284002028C0C85B60F010010B7000485B60F010010B70000
+explain extended
+select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8,
+2, 1212 AS unsigned int,
+3, 1212 AS int,
+4, 12.12 AS double,
+4+1, 12.12 AS decimal,
+6, "2011-04-05" AS date,
+7, "- 0:45:49.000001" AS time,
+8, "2011-04-05 0:45:49.000001" AS datetime));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select hex(column_create(1,'afaf' AS char charset utf8 ,2,1212 AS unsigned int,3,1212 AS int,4,12.12 AS double,(4 + 1),12.12 AS decimal,6,'2011-04-05' AS date,7,'- 0:45:49.000001' AS time,8,'2011-04-05 0:45:49.000001' AS datetime)) AS `hex(COLUMN_CREATE(1, "afaf" AS char character set utf8,
+2, 1212 AS unsigned int,
+3, 1212 AS int,
+4, 12.12 AS double,
+4+1, 12.12 AS decimal,
+6, "2011-04-05" AS date,
+7, "- 0:45:49.000001" AS time,
+8, "2011-04-05 0:45:49.000001" AS datetime))`
+select hex(column_create(1, 0.0 AS decimal));
+hex(column_create(1, 0.0 AS decimal))
+000100010004
+select hex(column_create(1, 1.0 AS decimal));
+hex(column_create(1, 1.0 AS decimal))
+00010001000401018100
+#
+# column get uint
+#
+select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int);
+column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int)
+1212
+explain extended
+select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(column_get(column_create(1,1212 AS unsigned int),1) as unsigned) AS `column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int)`
+explain extended
+select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(column_get(column_create(1,1212 AS unsigned int),1) as unsigned) AS `column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned)`
+select column_get(column_create(1, 1212 AS decimal), 1 as unsigned int);
+column_get(column_create(1, 1212 AS decimal), 1 as unsigned int)
+1212
+select column_get(column_create(1, 1212 AS double), 1 as unsigned int);
+column_get(column_create(1, 1212 AS double), 1 as unsigned int)
+1212
+select column_get(column_create(1, 1212 AS int), 1 as unsigned int);
+column_get(column_create(1, 1212 AS int), 1 as unsigned int)
+1212
+select column_get(column_create(1, "1212" AS char), 1 as unsigned int);
+column_get(column_create(1, "1212" AS char), 1 as unsigned int)
+1212
+select column_get(column_create(1, "2011-04-05" AS date), 1 as unsigned int);
+column_get(column_create(1, "2011-04-05" AS date), 1 as unsigned int)
+20110405
+select column_get(column_create(1, "8:46:06.23434" AS time), 1 as unsigned int);
+column_get(column_create(1, "8:46:06.23434" AS time), 1 as unsigned int)
+84606
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as unsigned int);
+column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as unsigned int)
+20110405084606
+select column_get(column_create(1, NULL AS unsigned int), 1 as unsigned int);
+column_get(column_create(1, NULL AS unsigned int), 1 as unsigned int)
+NULL
+# column geint truncation & warnings
+select column_get(column_create(1, -1212 AS int), 1 as unsigned int);
+column_get(column_create(1, -1212 AS int), 1 as unsigned int)
+18446744073709550404
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as unsigned int);
+column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as unsigned int)
+18446744073709551615
+Warnings:
+Error 1916 Got overflow when converting '99999999999999999999999999999' to UNSIGNED INT. Value truncated.
+select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as unsigned int);
+column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as unsigned int)
+1000
+select column_get(column_create(1, -1 AS decimal), 1 as unsigned int);
+column_get(column_create(1, -1 AS decimal), 1 as unsigned int)
+0
+Warnings:
+Error 1916 Got overflow when converting '-1' to UNSIGNED INT. Value truncated.
+select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as unsigned int);
+column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as unsigned int)
+18446744073709551615
+Warnings:
+Warning 1916 Got overflow when converting '1e+29' to UNSIGNED INT. Value truncated.
+select column_get(column_create(1, 999.9 AS double), 1 as unsigned int);
+column_get(column_create(1, 999.9 AS double), 1 as unsigned int)
+1000
+select column_get(column_create(1, -1 AS double), 1 as unsigned int);
+column_get(column_create(1, -1 AS double), 1 as unsigned int)
+0
+Warnings:
+Warning 1916 Got overflow when converting '-1' to UNSIGNED INT. Value truncated.
+select column_get(column_create(1, "1212III" AS char), 1 as unsigned int);
+column_get(column_create(1, "1212III" AS char), 1 as unsigned int)
+1212
+Warnings:
+Warning 1918 Encountered illegal value '1212III' when converting to UNSIGNED INT
+#
+# column get int
+#
+select column_get(column_create(1, 1212 AS int), 1 as int);
+column_get(column_create(1, 1212 AS int), 1 as int)
+1212
+explain extended
+select column_get(column_create(1, 1212 AS int), 1 as int);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(column_get(column_create(1,1212 AS int),1) as signed) AS `column_get(column_create(1, 1212 AS int), 1 as int)`
+explain extended
+select column_get(column_create(1, 1212 AS int), 1 as signed int);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(column_get(column_create(1,1212 AS int),1) as signed) AS `column_get(column_create(1, 1212 AS int), 1 as signed int)`
+select column_get(column_create(1, -1212 AS int), 1 as int);
+column_get(column_create(1, -1212 AS int), 1 as int)
+-1212
+select column_get(column_create(1, 1212 AS decimal), 1 as int);
+column_get(column_create(1, 1212 AS decimal), 1 as int)
+1212
+select column_get(column_create(1, 1212 AS double), 1 as int);
+column_get(column_create(1, 1212 AS double), 1 as int)
+1212
+select column_get(column_create(1, 1212 AS unsigned int), 1 as int);
+column_get(column_create(1, 1212 AS unsigned int), 1 as int)
+1212
+select column_get(column_create(1, "1212" AS char), 1 as int);
+column_get(column_create(1, "1212" AS char), 1 as int)
+1212
+select column_get(column_create(1, "-1212" AS char), 1 as int);
+column_get(column_create(1, "-1212" AS char), 1 as int)
+-1212
+select column_get(column_create(1, "2011-04-05" AS date), 1 as int);
+column_get(column_create(1, "2011-04-05" AS date), 1 as int)
+20110405
+select column_get(column_create(1, "8:46:06.23434" AS time), 1 as int);
+column_get(column_create(1, "8:46:06.23434" AS time), 1 as int)
+84606
+select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as int);
+column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as int)
+84606
+select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as int);
+column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as int)
+-8084606
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as int);
+column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as int)
+20110405084606
+select column_get(column_create(1, NULL AS int), 1 as int);
+column_get(column_create(1, NULL AS int), 1 as int)
+NULL
+#column gett truncation & warnings
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as int);
+column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as int)
+-1
+Warnings:
+Warning 1105 Cast to signed converted positive out-of-range integer to it's negative complement
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as int);
+column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as int)
+9223372036854775807
+Warnings:
+Error 1916 Got overflow when converting '99999999999999999999999999999' to INT. Value truncated.
+select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as int);
+column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as int)
+-9223372036854775808
+Warnings:
+Error 1916 Got overflow when converting '-99999999999999999999999999999' to INT. Value truncated.
+select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as int);
+column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as int)
+1000
+select column_get(column_create(1, 999.9 AS double), 1 as int);
+column_get(column_create(1, 999.9 AS double), 1 as int)
+1000
+select column_get(column_create(1, -99999999999999999999999999999 AS double), 1 as int);
+column_get(column_create(1, -99999999999999999999999999999 AS double), 1 as int)
+-9223372036854775808
+Warnings:
+Warning 1916 Got overflow when converting '-1e+29' to INT. Value truncated.
+select column_get(column_create(1, "-1212III" AS char), 1 as int);
+column_get(column_create(1, "-1212III" AS char), 1 as int)
+-1212
+Warnings:
+Warning 1918 Encountered illegal value '-1212III' when converting to INT
+select column_get(column_create(1, "1212III" AS char), 1 as int);
+column_get(column_create(1, "1212III" AS char), 1 as int)
+1212
+Warnings:
+Warning 1918 Encountered illegal value '1212III' when converting to INT
+select column_get(COLUMN_CREATE(1, ~0), 1 as signed);
+column_get(COLUMN_CREATE(1, ~0), 1 as signed)
+-1
+Warnings:
+Warning 1105 Cast to signed converted positive out-of-range integer to it's negative complement
+select column_get(COLUMN_CREATE(1, ~0), 1 as unsigned);
+column_get(COLUMN_CREATE(1, ~0), 1 as unsigned)
+18446744073709551615
+select column_get(COLUMN_CREATE(1, -1), 1 as signed);
+column_get(COLUMN_CREATE(1, -1), 1 as signed)
+-1
+select column_get(COLUMN_CREATE(1, -1), 1 as unsigned);
+column_get(COLUMN_CREATE(1, -1), 1 as unsigned)
+18446744073709551615
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+#
+#column get char
+#
+select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8);
+column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8)
+1212
+explain extended
+select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(column_get(column_create(1,'1212' AS char charset utf8 ),1) as char charset utf8) AS `column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8)`
+select column_get(column_create(1, 1212 AS unsigned int), 1 as char charset utf8);
+column_get(column_create(1, 1212 AS unsigned int), 1 as char charset utf8)
+1212
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as char charset utf8);
+column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as char charset utf8)
+18446744073709551615
+select column_get(column_create(1, 1212 AS int), 1 as char charset utf8);
+column_get(column_create(1, 1212 AS int), 1 as char charset utf8)
+1212
+select column_get(column_create(1, -1212 AS int), 1 as char charset utf8);
+column_get(column_create(1, -1212 AS int), 1 as char charset utf8)
+-1212
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as char charset utf8);
+column_get(column_create(1, 9223372036854775807 AS int), 1 as char charset utf8)
+9223372036854775807
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as char charset utf8);
+column_get(column_create(1, -9223372036854775808 AS int), 1 as char charset utf8)
+-9223372036854775808
+select column_get(column_create(1, 1212.12 AS decimal), 1 as char charset utf8);
+column_get(column_create(1, 1212.12 AS decimal), 1 as char charset utf8)
+1212.12
+select column_get(column_create(1, 1212.12 AS double), 1 as char charset utf8);
+column_get(column_create(1, 1212.12 AS double), 1 as char charset utf8)
+1212.12
+select column_get(column_create(1, "2011-04-05" AS date), 1 as char charset utf8);
+column_get(column_create(1, "2011-04-05" AS date), 1 as char charset utf8)
+2011-04-05
+select column_get(column_create(1, "8:46:06.23434" AS time), 1 as char charset utf8);
+column_get(column_create(1, "8:46:06.23434" AS time), 1 as char charset utf8)
+08:46:06.234340
+select column_get(column_create(1, "8:46:06.23434" AS time(0)), 1 as char charset utf8);
+column_get(column_create(1, "8:46:06.23434" AS time(0)), 1 as char charset utf8)
+08:46:06.234340
+select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as char charset utf8);
+column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as char charset utf8)
+08:46:06.234340
+select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as char charset utf8);
+column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as char charset utf8)
+-808:46:06.234340
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as char charset utf8);
+column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as char charset utf8)
+2011-04-05 08:46:06.234340
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(0)), 1 as char charset utf8);
+column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(0)), 1 as char charset utf8)
+2011-04-05 08:46:06.234340
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as char charset utf8);
+column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as char charset utf8)
+2011-04-05 08:46:06.234340
+select column_get(column_create(1, NULL AS char charset utf8), 1 as char charset utf8);
+column_get(column_create(1, NULL AS char charset utf8), 1 as char charset utf8)
+NULL
+select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary);
+column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary)
+1212
+explain extended
+select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(column_get(column_create(1,'1212' AS char charset utf8 ),1) as char charset binary) AS `column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary)`
+#
+# column get real
+#
+select column_get(column_create(1, 1212.12 AS double), 1 as double);
+column_get(column_create(1, 1212.12 AS double), 1 as double)
+1212.12
+explain extended
+select column_get(column_create(1, 1212.12 AS double), 1 as double);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(column_get(column_create(1,1212.12 AS double),1) as double) AS `column_get(column_create(1, 1212.12 AS double), 1 as double)`
+explain extended
+select column_get(column_create(1, 1212.12 AS double), 1 as double(6,2));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(column_get(column_create(1,1212.12 AS double),1) as double(6,2)) AS `column_get(column_create(1, 1212.12 AS double), 1 as double(6,2))`
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as double);
+column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as double)
+1.84467440737096e+19
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as double);
+column_get(column_create(1, 9223372036854775807 AS int), 1 as double)
+9.22337203685478e+18
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as double);
+column_get(column_create(1, -9223372036854775808 AS int), 1 as double)
+-9.22337203685478e+18
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as double);
+column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as double)
+1e+29
+select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as double);
+column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as double)
+-1e+29
+select column_get(column_create(1, "2011-04-05" AS date), 1 as double);
+column_get(column_create(1, "2011-04-05" AS date), 1 as double)
+20110405
+select column_get(column_create(1, "8:46:06.23434" AS time), 1 as double);
+column_get(column_create(1, "8:46:06.23434" AS time), 1 as double)
+84606.23434
+select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as double);
+column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as double)
+84606.23434
+select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as double);
+column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as double)
+-8084606.23434
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double);
+column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double)
+20110405084606.2
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as double);
+column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as double)
+20110405084606.2
+select round(column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double(20,6)),3);
+round(column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double(20,6)),3)
+20110405084606.234
+select column_get(column_create(1, NULL AS double), 1 as double);
+column_get(column_create(1, NULL AS double), 1 as double)
+NULL
+# column get real truncation & warnings
+select column_get(column_create(1, "1223.5aa" AS char), 1 as double);
+column_get(column_create(1, "1223.5aa" AS char), 1 as double)
+1223.5
+Warnings:
+Warning 1918 Encountered illegal value '1223.5aa' when converting to DOUBLE
+select column_get(column_create(1, "aa" AS char), 1 as double);
+column_get(column_create(1, "aa" AS char), 1 as double)
+0
+Warnings:
+Warning 1918 Encountered illegal value 'aa' when converting to DOUBLE
+select column_get(column_create(1, "1223.5555" AS double), 1 as double(5,2));
+column_get(column_create(1, "1223.5555" AS double), 1 as double(5,2))
+999.99
+Warnings:
+Warning 1264 Out of range value for column 'column_get(column_create(1, "1223.5555" AS double), 1 as double(5,2))' at row 1
+select column_get(column_create(1, "1223.5555" AS double), 1 as double(3,2));
+column_get(column_create(1, "1223.5555" AS double), 1 as double(3,2))
+9.99
+Warnings:
+Warning 1264 Out of range value for column 'column_get(column_create(1, "1223.5555" AS double), 1 as double(3,2))' at row 1
+#
+# column get decimal
+#
+select column_get(column_create(1, 1212.12 AS double), 1 as decimal);
+column_get(column_create(1, 1212.12 AS double), 1 as decimal)
+1212
+select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2));
+column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2))
+1212.12
+explain extended
+select column_get(column_create(1, 1212.12 AS double), 1 as decimal);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(column_get(column_create(1,1212.12 AS double),1) as decimal(10,0)) AS `column_get(column_create(1, 1212.12 AS double), 1 as decimal)`
+explain extended
+select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(column_get(column_create(1,1212.12 AS double),1) as decimal(6,2)) AS `column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2))`
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal(20,0));
+column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal(20,0))
+18446744073709551615
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal(32,0));
+column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal(32,0))
+9223372036854775807
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal(32,0));
+column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal(32,0))
+-9223372036854775808
+select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as decimal(40,10));
+column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as decimal(40,10))
+-99999999999999999999999999999.0000000000
+select column_get(column_create(1, "2011-04-05" AS date), 1 as decimal(32,6));
+column_get(column_create(1, "2011-04-05" AS date), 1 as decimal(32,6))
+20110405.000000
+select column_get(column_create(1, "8:46:06.23434" AS time), 1 as decimal(32,6));
+column_get(column_create(1, "8:46:06.23434" AS time), 1 as decimal(32,6))
+84606.234340
+select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as decimal(32,6));
+column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as decimal(32,6))
+84606.234340
+select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as decimal(32,6));
+column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as decimal(32,6))
+-8084606.234340
+select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime), 1 as decimal(32,6));
+column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime), 1 as decimal(32,6))
+20110405084606.123456
+select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime(6)), 1 as decimal(32,6));
+column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime(6)), 1 as decimal(32,6))
+20110405084606.123456
+select column_get(column_create(1, "2011-04-05 8:46:06.12345678" AS datetime(6)), 1 as decimal(32,8));
+column_get(column_create(1, "2011-04-05 8:46:06.12345678" AS datetime(6)), 1 as decimal(32,8))
+20110405084606.12345600
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2011-04-05 8:46:06.12345678'
+select column_get(column_create(1, NULL as decimal), 1 as decimal(32,10));
+column_get(column_create(1, NULL as decimal), 1 as decimal(32,10))
+NULL
+select column_get(column_create(1, "1223.5555" as decimal(10,5)), 1 as decimal(6,2));
+column_get(column_create(1, "1223.5555" as decimal(10,5)), 1 as decimal(6,2))
+1223.56
+# column get decimal truncation & warnings
+select column_get(column_create(1, "1223.5aa" AS char), 1 as decimal(32,10));
+column_get(column_create(1, "1223.5aa" AS char), 1 as decimal(32,10))
+1223.5000000000
+Warnings:
+Warning 1918 Encountered illegal value '1223.5aa' when converting to DECIMAL
+select column_get(column_create(1, "aa" AS char), 1 as decimal(32,10));
+column_get(column_create(1, "aa" AS char), 1 as decimal(32,10))
+0.0000000000
+Warnings:
+Warning 1918 Encountered illegal value 'aa' when converting to DECIMAL
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal);
+column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal)
+9999999999
+Warnings:
+Error 1264 Out of range value for column 'column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal)' at row 1
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal);
+column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal)
+9999999999
+Warnings:
+Error 1264 Out of range value for column 'column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal)' at row 1
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal);
+column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal)
+-9999999999
+Warnings:
+Error 1264 Out of range value for column 'column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal)' at row 1
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as decimal);
+column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as decimal)
+9999999999
+Warnings:
+Error 1264 Out of range value for column 'column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as decimal)' at row 1
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as decimal);
+column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as decimal)
+9999999999
+Warnings:
+Error 1264 Out of range value for column 'column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as decimal)' at row 1
+select column_get(column_create(1, "1223.5555" as double), 1 as decimal(5,2));
+column_get(column_create(1, "1223.5555" as double), 1 as decimal(5,2))
+999.99
+Warnings:
+Error 1264 Out of range value for column 'column_get(column_create(1, "1223.5555" as double), 1 as decimal(5,2))' at row 1
+select column_get(column_create(1, "-1223.5555" as double), 1 as decimal(5,2));
+column_get(column_create(1, "-1223.5555" as double), 1 as decimal(5,2))
+-999.99
+Warnings:
+Error 1264 Out of range value for column 'column_get(column_create(1, "-1223.5555" as double), 1 as decimal(5,2))' at row 1
+select column_get(column_create(1, "1223.5555" AS double), 1 as decimal(3,2));
+column_get(column_create(1, "1223.5555" AS double), 1 as decimal(3,2))
+9.99
+Warnings:
+Error 1264 Out of range value for column 'column_get(column_create(1, "1223.5555" AS double), 1 as decimal(3,2))' at row 1
+select column_get(column_create(1, "1223.5555" AS decimal(10,5)), 1 as decimal(3,2));
+column_get(column_create(1, "1223.5555" AS decimal(10,5)), 1 as decimal(3,2))
+9.99
+Warnings:
+Error 1264 Out of range value for column 'column_get(column_create(1, "1223.5555" AS decimal(10,5)), 1 as decimal(3,2))' at row 1
+select column_get(column_create(1, 0.0 AS decimal,2, 0.0 as decimal), 1 as decimal);
+column_get(column_create(1, 0.0 AS decimal,2, 0.0 as decimal), 1 as decimal)
+0
+#
+# column get datetime
+#
+select column_get(column_create(1, 20010203101112.121314 as double), 1 as datetime);
+column_get(column_create(1, 20010203101112.121314 as double), 1 as datetime)
+2001-02-03 10:11:12
+select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as datetime);
+column_get(column_create(1, 20010203101112.121314 as decimal), 1 as datetime)
+2001-02-03 10:11:12
+select column_get(column_create(1, 20010203101112 as unsigned int), 1 as datetime);
+column_get(column_create(1, 20010203101112 as unsigned int), 1 as datetime)
+2001-02-03 10:11:12
+select column_get(column_create(1, 20010203101112 as int), 1 as datetime);
+column_get(column_create(1, 20010203101112 as int), 1 as datetime)
+2001-02-03 10:11:12
+select column_get(column_create(1, "20010203101112" as char), 1 as datetime);
+column_get(column_create(1, "20010203101112" as char), 1 as datetime)
+2001-02-03 10:11:12
+select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as datetime);
+column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as datetime)
+2001-02-03 10:11:12
+select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as datetime);
+column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as datetime)
+2001-02-03 10:11:12
+select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as datetime);
+column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as datetime)
+2001-02-03 10:11:12
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime);
+column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime)
+2011-04-05 08:46:06
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(0));
+column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(0))
+2011-04-05 08:46:06
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(6));
+column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(6))
+2011-04-05 08:46:06.234340
+select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as datetime);
+column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as datetime)
+2011-00-00 08:46:06
+select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as datetime);
+column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as datetime)
+2011-00-01 08:46:06
+select column_get(column_create(1, 20010203 as unsigned int), 1 as datetime);
+column_get(column_create(1, 20010203 as unsigned int), 1 as datetime)
+2001-02-03 00:00:00
+select column_get(column_create(1, 20010203 as int), 1 as datetime);
+column_get(column_create(1, 20010203 as int), 1 as datetime)
+2001-02-03 00:00:00
+select column_get(column_create(1, 20010203), 1 as datetime);
+column_get(column_create(1, 20010203), 1 as datetime)
+2001-02-03 00:00:00
+select column_get(column_create(1, 20010203.0), 1 as datetime);
+column_get(column_create(1, 20010203.0), 1 as datetime)
+2001-02-03 00:00:00
+select column_get(column_create(1, 20010203.0 as double), 1 as datetime);
+column_get(column_create(1, 20010203.0 as double), 1 as datetime)
+2001-02-03 00:00:00
+select column_get(column_create(1, "2001-02-03"), 1 as datetime);
+column_get(column_create(1, "2001-02-03"), 1 as datetime)
+2001-02-03 00:00:00
+select column_get(column_create(1, "20010203"), 1 as datetime);
+column_get(column_create(1, "20010203"), 1 as datetime)
+2001-02-03 00:00:00
+select column_get(column_create(1, 0), 1 as datetime);
+column_get(column_create(1, 0), 1 as datetime)
+0000-00-00 00:00:00
+select column_get(column_create(1, "2001021"), 1 as datetime);
+column_get(column_create(1, "2001021"), 1 as datetime)
+2020-01-02 01:00:00
+select column_get(column_create(1, "8:46:06.23434" AS time), 1 as datetime);
+column_get(column_create(1, "8:46:06.23434" AS time), 1 as datetime)
+0000-00-00 08:46:06
+select column_get(column_create(1, "-808:46:06.23434" AS time), 1 as datetime);
+column_get(column_create(1, "-808:46:06.23434" AS time), 1 as datetime)
+NULL
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '-808:46:06'
+set @@sql_mode="allow_invalid_dates";
+select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as datetime);
+column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as datetime)
+2011-02-30 18:46:06
+select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as datetime);
+column_get(column_create(1, "0000-00-000" AS CHAR), 1 as datetime)
+0000-00-00 00:00:00
+select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as datetime);
+column_get(column_create(1, "2001-00-02" AS CHAR), 1 as datetime)
+2001-00-02 00:00:00
+set @@sql_mode="";
+# column get datetime truncation & warnings
+select column_get(column_create(1, "1223.5aa" AS char), 1 as datetime);
+column_get(column_create(1, "1223.5aa" AS char), 1 as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '1223.5aa'
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as datetime);
+column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '1.84467440737096e+19'
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as datetime);
+column_get(column_create(1, 9223372036854775807 AS int), 1 as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '9223372036854775807'
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as datetime);
+column_get(column_create(1, -9223372036854775808 AS int), 1 as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '-9223372036854775808'
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as datetime);
+column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '99999999999999999999999999999'
+select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as datetime);
+column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '1e+29'
+select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as datetime);
+column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '2011-02-32 8:46:06.23434'
+select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as datetime);
+column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '2011-13-01 8:46:06.23434'
+select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as datetime);
+column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '2011-02-30 8:46:06.23434'
+select column_get(column_create(1, "20010231"), 1 as datetime);
+column_get(column_create(1, "20010231"), 1 as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '20010231'
+select column_get(column_create(1, "0" AS CHAR), 1 as datetime);
+column_get(column_create(1, "0" AS CHAR), 1 as datetime)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '0'
+#
+# column get date
+#
+select column_get(column_create(1, 20010203101112.121314 as double), 1 as date);
+column_get(column_create(1, 20010203101112.121314 as double), 1 as date)
+2001-02-03
+select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as date);
+column_get(column_create(1, 20010203101112.121314 as decimal), 1 as date)
+2001-02-03
+select column_get(column_create(1, 20010203101112 as unsigned int), 1 as date);
+column_get(column_create(1, 20010203101112 as unsigned int), 1 as date)
+2001-02-03
+select column_get(column_create(1, 20010203101112 as int), 1 as date);
+column_get(column_create(1, 20010203101112 as int), 1 as date)
+2001-02-03
+select column_get(column_create(1, "20010203101112" as char), 1 as date);
+column_get(column_create(1, "20010203101112" as char), 1 as date)
+2001-02-03
+select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as date);
+column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as date)
+2001-02-03
+select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as date);
+column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as date)
+2001-02-03
+select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as date);
+column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as date)
+2001-02-03
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as date);
+column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as date)
+2011-04-05
+select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as date);
+column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as date)
+2011-00-00
+select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as date);
+column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as date)
+2011-00-01
+select column_get(column_create(1, 20010203 as unsigned int), 1 as date);
+column_get(column_create(1, 20010203 as unsigned int), 1 as date)
+2001-02-03
+select column_get(column_create(1, 20010203 as int), 1 as date);
+column_get(column_create(1, 20010203 as int), 1 as date)
+2001-02-03
+select column_get(column_create(1, 20010203), 1 as date);
+column_get(column_create(1, 20010203), 1 as date)
+2001-02-03
+select column_get(column_create(1, 20010203.0), 1 as date);
+column_get(column_create(1, 20010203.0), 1 as date)
+2001-02-03
+select column_get(column_create(1, 20010203.0 as double), 1 as date);
+column_get(column_create(1, 20010203.0 as double), 1 as date)
+2001-02-03
+select column_get(column_create(1, "2001-02-03"), 1 as date);
+column_get(column_create(1, "2001-02-03"), 1 as date)
+2001-02-03
+select column_get(column_create(1, "20010203"), 1 as date);
+column_get(column_create(1, "20010203"), 1 as date)
+2001-02-03
+select column_get(column_create(1, 0), 1 as date);
+column_get(column_create(1, 0), 1 as date)
+0000-00-00
+select column_get(column_create(1, "2001021"), 1 as date);
+column_get(column_create(1, "2001021"), 1 as date)
+2020-01-02
+set @@sql_mode="allow_invalid_dates";
+select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as date);
+column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as date)
+2011-02-30
+select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as date);
+column_get(column_create(1, "0000-00-000" AS CHAR), 1 as date)
+0000-00-00
+select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as date);
+column_get(column_create(1, "2001-00-02" AS CHAR), 1 as date)
+2001-00-02
+set @@sql_mode="";
+# column get date truncation & warnings
+select column_get(column_create(1, "1223.5aa" AS char), 1 as date);
+column_get(column_create(1, "1223.5aa" AS char), 1 as date)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '1223.5aa'
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as date);
+column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as date)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '1.84467440737096e+19'
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as date);
+column_get(column_create(1, 9223372036854775807 AS int), 1 as date)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '9223372036854775807'
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as date);
+column_get(column_create(1, -9223372036854775808 AS int), 1 as date)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '-9223372036854775808'
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as date);
+column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as date)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '99999999999999999999999999999'
+select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as date);
+column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as date)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '1e+29'
+select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as date);
+column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as date)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '2011-02-32 8:46:06.23434'
+select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as date);
+column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as date)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '2011-13-01 8:46:06.23434'
+select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as date);
+column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as date)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '2011-02-30 8:46:06.23434'
+select column_get(column_create(1, "20010231"), 1 as date);
+column_get(column_create(1, "20010231"), 1 as date)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '20010231'
+select column_get(column_create(1, "0" AS CHAR), 1 as date);
+column_get(column_create(1, "0" AS CHAR), 1 as date)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '0'
+#
+# column get time
+#
+select column_get(column_create(1, 20010203101112.121314 as double), 1 as time);
+column_get(column_create(1, 20010203101112.121314 as double), 1 as time)
+10:11:12
+select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as time);
+column_get(column_create(1, 20010203101112.121314 as decimal), 1 as time)
+10:11:12
+select column_get(column_create(1, 20010203101112 as unsigned int), 1 as time);
+column_get(column_create(1, 20010203101112 as unsigned int), 1 as time)
+10:11:12
+select column_get(column_create(1, 8080102 as unsigned int), 1 as time);
+column_get(column_create(1, 8080102 as unsigned int), 1 as time)
+808:01:02
+select column_get(column_create(1, 20010203101112 as int), 1 as time);
+column_get(column_create(1, 20010203101112 as int), 1 as time)
+10:11:12
+select column_get(column_create(1, -8080102 as int), 1 as time);
+column_get(column_create(1, -8080102 as int), 1 as time)
+-808:01:02
+select column_get(column_create(1, "20010203101112" as char), 1 as time);
+column_get(column_create(1, "20010203101112" as char), 1 as time)
+10:11:12
+select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as time);
+column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as time)
+10:11:12
+select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time);
+column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time)
+10:11:12
+select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time(6));
+column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time(6))
+10:11:12.121314
+select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as time);
+column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as time)
+10:11:12
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as time(6));
+column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as time(6))
+08:46:06.234340
+select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as time(6));
+column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as time(6))
+08:46:06.234340
+select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as time(6));
+column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as time(6))
+08:46:06.234340
+select column_get(column_create(1, "830:46:06.23434" AS CHAR), 1 as time(6));
+column_get(column_create(1, "830:46:06.23434" AS CHAR), 1 as time(6))
+830:46:06.234340
+select column_get(column_create(1, "830:46:06" AS CHAR), 1 as time(6));
+column_get(column_create(1, "830:46:06" AS CHAR), 1 as time(6))
+830:46:06.000000
+select cast("-830:46:06.23434" AS time(6));
+cast("-830:46:06.23434" AS time(6))
+-830:46:06.234340
+select 1,cast("-830:46:06.23434" AS time(6));
+1 cast("-830:46:06.23434" AS time(6))
+1 -830:46:06.234340
+select hex(column_create(1, "-830:46:06.23434" AS CHAR));
+hex(column_create(1, "-830:46:06.23434" AS CHAR))
+000100010003082D3833303A34363A30362E3233343334
+select column_get(column_create(1, "-830:46:06.23434" AS CHAR), 1 as time(6));
+column_get(column_create(1, "-830:46:06.23434" AS CHAR), 1 as time(6))
+-830:46:06.234340
+select column_get(column_create(1, "0" AS CHAR), 1 as time);
+column_get(column_create(1, "0" AS CHAR), 1 as time)
+00:00:00
+select column_get(column_create(1, "6" AS CHAR), 1 as time);
+column_get(column_create(1, "6" AS CHAR), 1 as time)
+00:00:06
+select column_get(column_create(1, "1:6" AS CHAR), 1 as time);
+column_get(column_create(1, "1:6" AS CHAR), 1 as time)
+01:06:00
+select column_get(column_create(1, "2:1:6" AS CHAR), 1 as time);
+column_get(column_create(1, "2:1:6" AS CHAR), 1 as time)
+02:01:06
+select column_get(column_create(1, 0), 1 as time);
+column_get(column_create(1, 0), 1 as time)
+00:00:00
+select column_get(column_create(1, "2001021"), 1 as time);
+column_get(column_create(1, "2001021"), 1 as time)
+200:10:21
+set @@sql_mode="allow_invalid_dates";
+select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as time);
+column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as time)
+18:46:06
+set @@sql_mode="";
+# column get date truncation & warnings
+select column_get(column_create(1, "1223.5aa" AS char), 1 as time);
+column_get(column_create(1, "1223.5aa" AS char), 1 as time)
+00:12:23
+Warnings:
+Warning 1292 Truncated incorrect time value: '1223.5aa'
+select column_get(column_create(1, "1223.5aa" AS char), 1 as time(3));
+column_get(column_create(1, "1223.5aa" AS char), 1 as time(3))
+00:12:23.500
+Warnings:
+Warning 1292 Truncated incorrect time value: '1223.5aa'
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as time);
+column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as time)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '1.84467440737096e+19'
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as time);
+column_get(column_create(1, 9223372036854775807 AS int), 1 as time)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '9223372036854775807'
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as time);
+column_get(column_create(1, -9223372036854775808 AS int), 1 as time)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '-9223372036854775808'
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as time);
+column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as time)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '99999999999999999999999999999'
+select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as time);
+column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as time)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '1e+29'
+select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as time);
+column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as time)
+NULL
+Warnings:
+Warning 1292 Truncated incorrect time value: '2011-02-32 8:46:06.23434'
+select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as time);
+column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as time)
+NULL
+Warnings:
+Warning 1292 Truncated incorrect time value: '2011-13-01 8:46:06.23434'
+select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as time);
+column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as time)
+NULL
+Warnings:
+Warning 1292 Truncated incorrect time value: '2011-02-30 8:46:06.23434'
+select column_get(column_create(1, "2001-02-03"), 1 as time);
+column_get(column_create(1, "2001-02-03"), 1 as time)
+00:20:01
+Warnings:
+Warning 1292 Truncated incorrect time value: '2001-02-03'
+select column_get(column_create(1, "20010203"), 1 as time);
+column_get(column_create(1, "20010203"), 1 as time)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '20010203'
+# column add
+select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer));
+hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer))
+00020001000002001078097809
+select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer));
+hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer))
+0001000100007809
+select hex(column_add(column_create(1, 1212 as integer), 1, NULL as integer));
+hex(column_add(column_create(1, 1212 as integer), 1, NULL as integer))
+000000
+select hex(column_add(column_create(1, 1212 as integer), 2, NULL as integer));
+hex(column_add(column_create(1, 1212 as integer), 2, NULL as integer))
+0001000100007809
+select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer));
+hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer))
+000200010000020008167809
+select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 1 as integer);
+column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 1 as integer)
+11
+select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 2 as integer);
+column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 2 as integer)
+1212
+select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer, 2, 11 as integer));
+hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer, 2, 11 as integer))
+000200010000020010780916
+select hex(column_add(column_create(1, NULL as integer), 1, 1212 as integer, 2, 11 as integer));
+hex(column_add(column_create(1, NULL as integer), 1, 1212 as integer, 2, 11 as integer))
+000200010000020010780916
+select hex(column_add(column_create(1, 1212 as integer, 2, 1212 as integer), 1, 11 as integer));
+hex(column_add(column_create(1, 1212 as integer, 2, 1212 as integer), 1, 11 as integer))
+000200010000020008167809
+select hex(column_add(column_create(1, 1), 1, null));
+hex(column_add(column_create(1, 1), 1, null))
+000000
+select column_list(column_add(column_create(1, 1), 1, null));
+column_list(column_add(column_create(1, 1), 1, null))
+
+select column_list(column_add(column_create(1, 1), 1, ""));
+column_list(column_add(column_create(1, 1), 1, ""))
+1
+select hex(column_add("", 1, 1));
+hex(column_add("", 1, 1))
+00010001000002
+# column delete
+select hex(column_delete(column_create(1, 1212 as integer, 2, 1212 as integer), 1));
+hex(column_delete(column_create(1, 1212 as integer, 2, 1212 as integer), 1))
+0001000200007809
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2));
+hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2))
+0002000100000300080206
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 3));
+hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 3))
+0002000100000200080204
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 4));
+hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 4))
+000300010000020008030010020406
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 1));
+hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 1))
+00010003000006
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 3));
+hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 3))
+00010001000002
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3));
+hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3))
+000000
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3, 10));
+hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3, 10))
+000000
+select hex(column_delete(column_create(1, 1), 1));
+hex(column_delete(column_create(1, 1), 1))
+000000
+select hex(column_delete("", 1));
+hex(column_delete("", 1))
+
+# column exists
+select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 1);
+column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 1)
+1
+select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 4);
+column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 4)
+0
+# column list
+select column_list(column_create(1, 1212 as integer, 2, 1212 as integer));
+column_list(column_create(1, 1212 as integer, 2, 1212 as integer))
+1,2
+select column_list(column_create(1, 1212 as integer));
+column_list(column_create(1, 1212 as integer))
+1
+select column_list(column_create(1, NULL as integer));
+column_list(column_create(1, NULL as integer))
+
+#
+# check error handling
+#
+select HEX(COLUMN_CREATE(1, 5, 1, 5));
+ERROR 22007: Illegal value used as argument of dynamic column function
+select HEX(COLUMN_CREATE("", 1, 5, 1, 5));
+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
+select COLUMN_LIST("a");
+ERROR HY000: Encountered illegal format of dynamic column string
+select column_delete("a", 1);
+ERROR HY000: Encountered illegal format of dynamic column string
+select hex(column_delete("", 1));
+hex(column_delete("", 1))
+
+select hex(column_delete("", -1));
+ERROR 22007: Illegal value used as argument of dynamic column function
+select hex(column_create(-1, 1));
+ERROR 22007: Illegal value used as argument of dynamic column function
+select hex(column_create(65536, 1));
+ERROR 22007: Illegal value used as argument of dynamic column function
+select hex(column_add("", -1, 1));
+ERROR 22007: Illegal value used as argument of dynamic column function
+select hex(column_add("", 65536, 1));
+ERROR 22007: Illegal value used as argument of dynamic column function
+select hex(column_get("", -1 as int));
+hex(column_get("", -1 as int))
+NULL
+#
+# Test with table
+#
+create table t1 (id int primary key, str mediumblob);
+insert into t1 values (1, ''), (2, ''), (3, ''), (4, ''), (5, null);
+select id, str, column_get(str, 1 as int) from t1;
+id str column_get(str, 1 as int)
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+5 NULL NULL
+update t1 set str=column_create(1, id, 2, "a") where id < 3;
+update t1 set str=column_add(str, 1, id, 2, "b") where id >= 4;
+select id, column_get(str, 1 as int), column_get(str, 2 as char) from t1 where column_exists(str,1) or column_exists(str,2);
+id column_get(str, 1 as int) column_get(str, 2 as char)
+1 1 a
+2 2 a
+4 4 b
+update t1 set str=column_create(1, id, 10, "test") where id = 5;
+insert into t1 values (6, column_create(10, "test2"));
+update t1 set str=column_add(str, 2, 'c', 1, column_get(str, 1 as int) + 1, 3, 100) where id > 2;
+select id, length(str), column_get(str, 1 as int), column_get(str, 2 as char), column_get(str, 3 as int) from t1;
+id length(str) column_get(str, 1 as int) column_get(str, 2 as char) column_get(str, 3 as int)
+1 12 1 a NULL
+2 12 2 a NULL
+3 12 NULL c 100
+4 16 5 c 100
+5 24 6 c 100
+6 21 NULL c 100
+select column_get(str, 2 as char), sum(column_get(str, 1 as int)) from t1 group by column_get(str, 2 as char);
+column_get(str, 2 as char) sum(column_get(str, 1 as int))
+a 3
+c 11
+select column_get(str, 2 as char), sum(column_get(str, 1 as int)) from t1 where column_exists(str, 2) <> 0 group by 1;
+column_get(str, 2 as char) sum(column_get(str, 1 as int))
+a 3
+c 11
+select sum(column_get(str, 1 as int)) from t1 group by column_get(str, 2 as char) order by sum(column_get(str, 1 as int)) desc;
+sum(column_get(str, 1 as int))
+11
+3
+select sum(column_get(str, 1 as int)) from t1 group by column_get(str, 2 as char) having sum(column_get(str, 1 as int)) > 2;
+sum(column_get(str, 1 as int))
+3
+11
+select sum(column_get(str, 1 as int)) from t1 where column_get(str, 3 as int) > 50 group by column_get(str, 2 as char);
+sum(column_get(str, 1 as int))
+11
+select id, column_list(str) from t1 where id= 5;
+id column_list(str)
+5 1,2,3,10
+update t1 set str=column_delete(str, 3, 4, 2) where id= 5;
+select id, length(str), column_list(str), column_get(str, 1 as int), column_get(str, 2 as char), column_get(str, 3 as int) from t1;
+id length(str) column_list(str) column_get(str, 1 as int) column_get(str, 2 as char) column_get(str, 3 as int)
+1 12 1,2 1 a NULL
+2 12 1,2 2 a NULL
+3 12 2,3 NULL c 100
+4 16 1,2,3 5 c 100
+5 15 1,10 6 NULL NULL
+6 21 2,3,10 NULL c 100
+update t1 set str=column_add(str, 4, 45 as char, 2, 'c') where id= 5;
+select id, length(str), column_list(str), column_get(str, 1 as int), column_get(str, 2 as char), column_get(str, 3 as int) from t1 where id = 5;
+id length(str) column_list(str) column_get(str, 1 as int) column_get(str, 2 as char) column_get(str, 3 as int)
+5 26 1,2,4,10 6 c NULL
+select id, length(str), column_list(str), column_exists(str, 4) from t1;
+id length(str) column_list(str) column_exists(str, 4)
+1 12 1,2 0
+2 12 1,2 0
+3 12 2,3 0
+4 16 1,2,3 0
+5 26 1,2,4,10 1
+6 21 2,3,10 0
+select sum(column_get(str, 1 as int)), column_list(str) from t1 group by 2;
+sum(column_get(str, 1 as int)) column_list(str)
+3 1,2
+5 1,2,3
+6 1,2,4,10
+NULL 2,3
+NULL 2,3,10
+select id, hex(str) from t1;
+id hex(str)
+1 00020001000002000B020861
+2 00020001000002000B040861
+3 0002000200030300100863C8
+4 00030001000002000B0300180A0863C8
+5 00040001000002000B04001B0A00330C08633F34350874657374
+6 0003000200030300100A001B0863C8087465737432
+update t1 set str=column_add(str, 4, repeat("a", 100000)) where id=5;
+select id from t1 where column_get(str,4 as char(100000)) = repeat("a", 100000);
+id
+5
+select id from t1 where column_get(str,4 as char(100)) = repeat("a", 100);
+id
+5
+Warnings:
+Warning 1292 Truncated incorrect CHAR(100) value: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+update t1 set str=column_add(str, 4, repeat("b", 10000)) where id=5;
+select id from t1 where column_get(str,4 as char(100000)) = repeat("b", 10000);
+id
+5
+update t1 set str=column_add(str, 4, repeat("c", 100)) where id=5;
+select id from t1 where column_get(str,4 as char(100000)) = repeat("c", 100);
+id
+5
+update t1 set str=column_add(str, 4, repeat("d", 10000)) where id=5;
+select id from t1 where column_get(str,4 as char(100000)) = repeat("d", 10000);
+id
+5
+update t1 set str=column_add(str, 4, repeat("e", 10), 5, repeat("f", 100000)) where id=5;
+select id from t1 where column_get(str,5 as char(100000)) = repeat("f", 100000);
+id
+5
+select id, column_list(str), length(str) from t1 where id=5;
+id column_list(str) length(str)
+5 1,2,4,5,10 100048
+update t1 set str=column_delete(str, 5) where id=5;
+select id, column_list(str), length(str) from t1 where id=5;
+id column_list(str) length(str)
+5 1,2,4,10 34
+drop table t1;
+#
+# LP#778905: Assertion `value->year <= 9999' failed in
+# dynamic_column_date_store
+#
+SELECT COLUMN_GET( 'a' , 2 AS DATE );
+ERROR HY000: Encountered illegal format of dynamic column string
+SELECT COLUMN_CREATE( 1 , COLUMN_GET( 'a' , 2 AS DATE ) );
+ERROR HY000: Encountered illegal format of dynamic column string
+#
+# LP#778912: Assertion `field_pos < field_count' failed in
+# Protocol_text::store in maria-5.3-mwl34
+#
+CREATE TABLE t1 ( f1 blob );
+INSERT INTO t1 VALUES (NULL);
+INSERT INTO t1 SET f1 = COLUMN_CREATE( 2 , 'cde' );
+SELECT HEX(COLUMN_ADD(f1, 1, 'abc')), COLUMN_LIST(f1) FROM t1;
+HEX(COLUMN_ADD(f1, 1, 'abc')) COLUMN_LIST(f1)
+NULL NULL
+0002000100030200230861626308636465 2
+SELECT COLUMN_ADD(f1, 1, 'abc'), COLUMN_LIST(f1) FROM t1;
+DROP TABLE t1;
+#
+# Some dynamic strings that caused crashes in the past
+#
+set @a=0x0102000200030004000F0D086B74697A6A7176746F6B687563726A746E7A746A666163726C6F7A6B62636B6B756B666779666977617369796F67756C726D62677A72756E63626D78636D7077706A6F736C6D636464696770786B6371637A6A6A6463737A6A676879716462637178646C666E6B6C726A637677696E7271746C616D646368687A6C707869786D666F666261797470616A63797673737A796D74747475666B717573687A79696E7276706F796A6E767361796A6F6D646F6378677A667074746363736A796D67746C786F697873686464616265616A7A6F7168707A6B776B6376737A6B72666C6F666C69636163686F6B666D627166786A71616F;
+select column_add(@a, 3, "a");
+ERROR HY000: Encountered illegal format of dynamic column string
+#
+# LP#781233 mysqld: decimal.c:1459: decimal_bin_size:
+# Assertion `scale >= 0 && precision > 0 && scale <= precision' ...
+#
+set @a=0x00020008000009000C2C010080;
+select COLUMN_GET(@a, 9 AS DECIMAL);
+COLUMN_GET(@a, 9 AS DECIMAL)
+0
+select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL)));
+hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL)))
+000100000004
+select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL(19,0))));
+hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL(19,0))))
+000100000004
+select hex(COLUMN_CREATE(0, COLUMN_GET(COLUMN_CREATE(0, 0.0 as decimal), 0 as decimal)));
+hex(COLUMN_CREATE(0, COLUMN_GET(COLUMN_CREATE(0, 0.0 as decimal), 0 as decimal)))
+000100000004
+select hex(COLUMN_CREATE(0, 0.0 as decimal));
+hex(COLUMN_CREATE(0, 0.0 as decimal))
+000100000004
diff --git a/mysql-test/r/error_simulation.result b/mysql-test/r/error_simulation.result
index f1835186787..6d9ec36bb1d 100644
--- a/mysql-test/r/error_simulation.result
+++ b/mysql-test/r/error_simulation.result
@@ -62,6 +62,8 @@ INSERT INTO t2 VALUES (1, 1, 'data');
# re-scanned for every record in the outer table. if we used inner join,
# we would need to have thousands of records and/or more columns in both
# tables so that the join buffer is filled and re-scans are triggered).
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
SET SESSION debug = '+d,only_one_Unique_may_be_created';
EXPLAIN
SELECT * FROM t1 LEFT JOIN t2 ON ( t2.a < 10 OR t2.b < 10 );
@@ -81,6 +83,7 @@ a a b filler
8 1 1 data
9 1 1 data
SET SESSION debug = DEFAULT;
+SET optimizer_switch=@save_optimizer_switch;
DROP TABLE t1, t2;
#
# Bug#11747970 34660: CRASH WHEN FEDERATED TABLE LOSES CONNECTION DURING INSERT ... SELECT
@@ -89,10 +92,9 @@ CREATE TABLE t1(f1 INT, KEY(f1));
CREATE TABLE t2(f1 INT);
INSERT INTO t1 VALUES (1),(2);
INSERT INTO t2 VALUES (1),(2);
-SET SESSION debug='d,bug11747970_simulate_error';
+SET SESSION debug="+d,bug11747970_raise_error";
INSERT IGNORE INTO t2 SELECT f1 FROM t1 a WHERE NOT EXISTS (SELECT 1 FROM t2 b WHERE a.f1 = b.f1);
-Warnings:
-Error 1105 Unknown error
+ERROR HY000: Unknown error
SET SESSION debug = DEFAULT;
DROP TABLE t1,t2;
#
diff --git a/mysql-test/r/errors.result b/mysql-test/r/errors.result
index bcc92296945..62c9a86a46c 100644
--- a/mysql-test/r/errors.result
+++ b/mysql-test/r/errors.result
@@ -24,7 +24,7 @@ select count(*),b from t1;
ERROR 42S22: Unknown column 'b' in 'field list'
drop table t1;
create table t1 (a int(256));
-ERROR 42000: Display width out of range for column 'a' (max = 255)
+ERROR 42000: Display width out of range for 'a' (max = 255)
set sql_mode='traditional';
create table t1 (a varchar(66000));
ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead
@@ -69,3 +69,11 @@ ERROR 42S22: Unknown column '' in 'VALUES() function'
INSERT INTO t2(a,b) VALUES (1,0) ON DUPLICATE KEY UPDATE
b=(SELECT VALUES(a)+2 FROM t1);
DROP TABLE t1, t2;
+#
+# MDEV-492: incorrect error check before sending OK in mysql_update
+#
+CREATE TABLE t1 (a CHAR(3), b BLOB);
+UPDATE t1 SET a = 'new'
+WHERE COLUMN_CREATE( 1, 'v', 1, 'w' ) IS NULL;
+ERROR 22007: Illegal value used as argument of dynamic column function
+drop table t1;
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index d9acadb78fb..e08e3e22307 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;
@@ -64,7 +64,7 @@ explain extended select * from v1 where f2=1;
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 `f1`,'1' AS `f2` from `test`.`t1` where 1
+Note 1003 select 1 AS `f1`,1 AS `f2` from `test`.`t1` where 1
explain extended select * from t1 where 0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
@@ -74,7 +74,7 @@ explain extended select * from t1 where 1;
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 `f1`,'1' AS `f2` from `test`.`t1` where 1
+Note 1003 select 1 AS `f1`,1 AS `f2` from `test`.`t1` where 1
explain extended select * from t1 having 0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
@@ -84,7 +84,7 @@ explain extended select * from t1 having 1;
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 `f1`,'1' AS `f2` from `test`.`t1` having 1
+Note 1003 select 1 AS `f1`,1 AS `f2` from `test`.`t1` having 1
drop view v1;
drop table t1;
CREATE TABLE t1(c INT);
@@ -102,7 +102,7 @@ INSERT INTO t2 VALUES (),(),();
EXPLAIN SELECT 1 FROM
(SELECT 1 FROM t2,t1 WHERE b < c GROUP BY 1 LIMIT 1) AS d2;
id select_type table type possible_keys key key_len ref rows Extra
-X X X X X X X X X const row not found
+X X X X X X X X X
X X X X X X X X X
X X X X X X X X X Range checked for each record (index map: 0xFFFFFFFFFF)
DROP TABLE t2;
@@ -114,17 +114,17 @@ INSERT INTO t2 VALUES (1),(2);
EXPLAIN EXTENDED SELECT 1
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
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 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
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
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 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
@@ -132,9 +132,9 @@ prepare s1 from
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS 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
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 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
@@ -142,16 +142,16 @@ prepare s1 from
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS 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
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 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
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 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;
@@ -182,6 +182,9 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 SUBQUERY t system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
Note 1003 select 1 AS `1` from `test`.`t1` where 0
+SHOW WARNINGS;
+Level Code Message
+Note 1003 select 1 AS `1` from `test`.`t1` where 0
SET SESSION sql_mode=@old_sql_mode;
DROP TABLE t1;
End of 5.0 tests.
@@ -193,11 +196,13 @@ create table t2 (dt datetime not null);
insert into t1 values ('2001-01-01 1:1:1', '1:1:1'),
('2001-01-01 1:1:1', '1:1:1');
insert into t2 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1');
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
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 INNR ALL NULL NULL NULL NULL 2 Using where; FirstMatch(OUTR)
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
@@ -205,12 +210,13 @@ 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 INNR ALL NULL NULL NULL NULL 2 Using where; FirstMatch(OUTR)
flush tables;
SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
dt
2001-01-01 01:01:01
2001-01-01 01:01:01
+SET join_cache_level=@save_join_cache_level;
drop tables t1, t2;
#
# Bug#47669: Query showed by EXPLAIN EXTENDED gives different result from original query
@@ -225,7 +231,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..
@@ -259,43 +265,61 @@ CREATE TABLE t1(f1 VARCHAR(6) NOT NULL,
FULLTEXT KEY(f1),UNIQUE(f1));
INSERT INTO t1 VALUES ('test');
EXPLAIN SELECT 1 FROM t1
-WHERE 1 > ALL((SELECT 1 FROM t1 JOIN t1 a ON (MATCH(t1.f1) AGAINST (""))
+WHERE 1 > ALL((SELECT t1.f1 FROM t1 JOIN t1 a ON (MATCH(t1.f1) AGAINST (""))
WHERE t1.f1 GROUP BY t1.f1));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY a system NULL NULL NULL NULL 1 Using filesort
+2 SUBQUERY a system NULL NULL NULL NULL 1
2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where
PREPARE stmt FROM
'EXPLAIN SELECT 1 FROM t1
- WHERE 1 > ALL((SELECT 1 FROM t1 RIGHT OUTER JOIN t1 a
+ WHERE 1 > ALL((SELECT t1.f1 FROM t1 RIGHT OUTER JOIN t1 a
ON (MATCH(t1.f1) AGAINST (""))
WHERE t1.f1 GROUP BY t1.f1))';
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY a system NULL NULL NULL NULL 1 Using filesort
+2 SUBQUERY a system NULL NULL NULL NULL 1
2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY a system NULL NULL NULL NULL 1 Using filesort
+2 SUBQUERY a system NULL NULL NULL NULL 1
2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where
DEALLOCATE PREPARE stmt;
PREPARE stmt FROM
'EXPLAIN SELECT 1 FROM t1
- WHERE 1 > ALL((SELECT 1 FROM t1 JOIN t1 a
+ WHERE 1 > ALL((SELECT t1.f1 FROM t1 JOIN t1 a
ON (MATCH(t1.f1) AGAINST (""))
WHERE t1.f1 GROUP BY t1.f1))';
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY a system NULL NULL NULL NULL 1 Using filesort
+2 SUBQUERY a system NULL NULL NULL NULL 1
2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY a system NULL NULL NULL NULL 1 Using filesort
+2 SUBQUERY a system NULL NULL NULL NULL 1
2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
End of 5.1 tests.
+#
+# Bug#776295: EXPLAIN EXTENDED with always false multiple equality
+# in the WHERE condition of a derived table
+#
+CREATE TABLE t1 (a int) ;
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (8);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+EXPLAIN EXTENDED
+SELECT * FROM ( SELECT t1.a FROM t1,t2 WHERE t2.a = t1.a ) AS t;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 0.00 const row not found
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+Warnings:
+Note 1003 select NULL AS `a` from (select NULL AS `a` from `test`.`t1` join `test`.`t2` where 0) `t`
+set optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result
index b978304f59d..d575346a140 100644
--- a/mysql-test/r/flush.result
+++ b/mysql-test/r/flush.result
@@ -6,7 +6,7 @@ insert into t2 values(3);
select * from t1;
n
3
-flush tables with read lock;
+flush tables with read lock and disable checkpoint;
drop table t2;
ERROR HY000: Can't execute the query because you have a conflicting read lock
drop table t2;
diff --git a/mysql-test/r/foreign_key.result b/mysql-test/r/foreign_key.result
index 411252e0a5d..665c8d158be 100644
--- a/mysql-test/r/foreign_key.result
+++ b/mysql-test/r/foreign_key.result
@@ -29,8 +29,8 @@ id
6
delete ignore from t1;
Warnings:
-Error 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
-Error 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+Warning 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+Warning 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
select row_count();
row_count()
-1
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index 9d9e738b696..33ec3d1f39c 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -497,6 +497,8 @@ DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(255), b INT, FULLTEXT(a), KEY(b));
INSERT INTO t1 VALUES('test', 1),('test', 1),('test', 1),('test', 1),
('test', 1),('test', 2),('test', 3),('test', 4);
+INSERT INTO t1 VALUES('test', 5),('test', 6),('test', 7),('test', 8),
+('test', 5),('test', 6),('test', 7),('test', 8);
EXPLAIN SELECT * FROM t1
WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
id select_type table type possible_keys key key_len ref rows Extra
@@ -512,15 +514,15 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT * FROM t1 IGNORE INDEX(a)
WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref b b 5 const 4 Using where
+1 SIMPLE t1 ref b b 5 const 5 Using where
EXPLAIN SELECT * FROM t1 USE INDEX(b)
WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref b b 5 const 4 Using where
+1 SIMPLE t1 ref b b 5 const 5 Using where
EXPLAIN SELECT * FROM t1 FORCE INDEX(b)
WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref b b 5 const 4 Using where
+1 SIMPLE t1 ref b b 5 const 5 Using where
DROP TABLE t1;
create table t1(a text,b date,fulltext index(a))engine=myisam;
insert into t1 set a='water',b='2008-08-04';
diff --git a/mysql-test/r/fulltext_left_join.result b/mysql-test/r/fulltext_left_join.result
index ea4cacf2fab..d5373037538 100644
--- a/mysql-test/r/fulltext_left_join.result
+++ b/mysql-test/r/fulltext_left_join.result
@@ -97,3 +97,17 @@ INSERT INTO t2(b,c) VALUES(2,'castle'),(3,'castle');
SELECT * FROM t1 LEFT JOIN t2 ON a=b WHERE MATCH(c) AGAINST('+castle' IN BOOLEAN MODE);
a b c
DROP TABLE t1, t2;
+#
+# BUG#906357: Incorrect result with outer join and full text match
+#
+CREATE TABLE t1(f1 VARCHAR(6) NOT NULL, FULLTEXT KEY(f1), UNIQUE(f1));
+INSERT INTO t1 VALUES ('test');
+CREATE TABLE t2(f2 VARCHAR(6) NOT NULL, FULLTEXT KEY(f2), UNIQUE(f2));
+INSERT INTO t2 VALUES ('test');
+SELECT * FROM t2 LEFT OUTER JOIN t1 ON (MATCH(f1) against (""));
+f2 f1
+test NULL
+SELECT * FROM t1 RIGHT OUTER JOIN t2 ON (MATCH(f1) against (""));
+f1 f2
+NULL test
+DROP table t1,t2;
diff --git a/mysql-test/r/fulltext_order_by.result b/mysql-test/r/fulltext_order_by.result
index bd3e79ec5c2..419c1f53a2c 100644
--- a/mysql-test/r/fulltext_order_by.result
+++ b/mysql-test/r/fulltext_order_by.result
@@ -44,24 +44,24 @@ a FORMAT(MATCH (message) AGAINST ('steve'),6)
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY 1;
a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
7 1
-SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) as rel FROM t1 ORDER BY rel;
-a rel
-1 0.000000
-2 0.000000
-3 0.000000
-5 0.000000
-6 0.000000
-7 0.895690
-4 0.905873
-SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel;
-a rel
-1 0
-2 0
-3 0
-5 0
-6 0
-4 1
-7 1
+SELECT IF(a=7,'steve-is-cool',IF(a=4,'cool', 'other')), FORMAT(MATCH (message) AGAINST ('steve'),6) as rel FROM t1 ORDER BY rel;
+IF(a=7,'steve-is-cool',IF(a=4,'cool', 'other')) rel
+other 0.000000
+other 0.000000
+other 0.000000
+other 0.000000
+other 0.000000
+steve-is-cool 0.895690
+cool 0.905873
+SELECT IF(a=7,'match',IF(a=4,'match', 'no-match')), MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel;
+IF(a=7,'match',IF(a=4,'match', 'no-match')) rel
+no-match 0
+no-match 0
+no-match 0
+no-match 0
+no-match 0
+match 1
+match 1
alter table t1 add key m (message);
explain SELECT message FROM t1 WHERE MATCH (message) AGAINST ('steve') ORDER BY message;
id select_type table type possible_keys key key_len ref rows Extra
diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result
index 37f7c475148..786755f130c 100644
--- a/mysql-test/r/func_compress.result
+++ b/mysql-test/r/func_compress.result
@@ -102,6 +102,7 @@ a
foo
Warnings:
Error 1259 ZLIB: Input data corrupted
+Error 1259 ZLIB: Input data corrupted
explain select *, uncompress(a) from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
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_default.result b/mysql-test/r/func_default.result
index a8f59f73e88..872cd324275 100644
--- a/mysql-test/r/func_default.result
+++ b/mysql-test/r/func_default.result
@@ -8,7 +8,7 @@ explain extended select default(str), default(strnull), default(intg), default(r
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 default('') AS `default(str)`,default('') AS `default(strnull)`,default('0') AS `default(intg)`,default('0') AS `default(rel)` from `test`.`t1`
+Note 1003 select default('') AS `default(str)`,default('') AS `default(strnull)`,default(0) AS `default(intg)`,default(0) AS `default(rel)` from `test`.`t1`
select * from t1 where str <> default(str);
str strnull intg rel
0 0
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index 4a79a15a2b6..4af2a4c3a66 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -983,10 +983,10 @@ INSERT INTO t1 VALUES (),();
EXPLAIN EXTENDED SELECT 1 FROM
(SELECT DISTINCT GROUP_CONCAT(td.f1) FROM t1,t1 AS td GROUP BY td.f1) AS d,t1;
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
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00 Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+2 DERIVED td ALL NULL NULL NULL NULL 2 100.00 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
@@ -1005,9 +1005,9 @@ EXPLAIN EXTENDED SELECT 1 FROM
(SELECT GROUP_CONCAT(t1.a ORDER BY t1.a ASC) FROM
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
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 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;
@@ -1035,7 +1035,7 @@ DROP TABLE t1;
CREATE TABLE t1(f1 int);
INSERT INTO t1 values (0),(0);
SELECT POLYGON((SELECT 1 FROM (SELECT 1 IN (GROUP_CONCAT(t1.f1)) FROM t1, t1 t GROUP BY t.f1 ) d));
-ERROR 22007: Illegal non geometric '(select 1 from (select (1 = group_concat(`test`.`t1`.`f1` separator ',')) AS `1 IN (GROUP_CONCAT(t1.f1))` from `test`.`t1` join `test`.`t1` `t` group by `t`.`f1`) `d`)' value found during parsing
+ERROR 22007: Illegal non geometric '(select 1 from (select (1 = group_concat(`test`.`t1`.`f1` separator ',')) AS `1 IN (GROUP_CONCAT(t1.f1))` from `test`.`t1` join `test`.`t1` `t` group by `test`.`t`.`f1`) `d`)' value found during parsing
DROP TABLE t1;
#
# Bug#58396 group_concat and explain extended are still crashy
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index e4eaa3df213..10450b54781 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -215,6 +215,8 @@ a1 a2 a1 a2
10 bbb BBB 20
20 zzz AAA 10
20 zzz BBB 20
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select max(t1.a1), max(t2.a1) from t1, t2 where t2.a2=9;
max(t1.a1) max(t2.a1)
NULL NULL
@@ -245,6 +247,7 @@ NULL
select max(t1.a2),max(t2.a1) from t1 left outer join t2 on t1.a1=10;
max(t1.a2) max(t2.a1)
zzz BBB
+SET optimizer_switch=@save_optimizer_switch;
drop table t1,t2;
CREATE TABLE t1 (a int, b int);
select count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1;
@@ -614,7 +617,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 +654,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 +1336,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
@@ -1532,7 +1535,8 @@ insert into t1 values
(02,2002,20020101,"2002-01-01 23:59:59"),
(60,2060,20600101,"2060-01-01 11:11:11"),
(70,1970,19700101,"1970-11-11 22:22:22"),
-(NULL,NULL,NULL,NULL);
+(NULL,NULL,NULL,NULL),
+(71,1971,19710101,"1971-11-11 22:22:22");
select min(f1),max(f1) from t1;
min(f1) max(f1)
70 60
@@ -1555,36 +1559,49 @@ a b gt lt eq
60 98 1 0 0
70 98 0 1 0
NULL 98 NULL NULL 0
+71 98 0 1 0
98 00 0 1 0
00 00 0 0 1
02 00 1 0 0
60 00 1 0 0
70 00 0 1 0
NULL 00 NULL NULL 0
+71 00 0 1 0
98 02 0 1 0
00 02 0 1 0
02 02 0 0 1
60 02 1 0 0
70 02 0 1 0
NULL 02 NULL NULL 0
+71 02 0 1 0
98 60 0 1 0
00 60 0 1 0
02 60 0 1 0
60 60 0 0 1
70 60 0 1 0
NULL 60 NULL NULL 0
+71 60 0 1 0
98 70 1 0 0
00 70 1 0 0
02 70 1 0 0
60 70 1 0 0
70 70 0 0 1
NULL 70 NULL NULL 0
+71 70 1 0 0
98 NULL NULL NULL 0
00 NULL NULL NULL 0
02 NULL NULL NULL 0
60 NULL NULL NULL 0
70 NULL NULL NULL 0
NULL NULL NULL NULL 1
+71 NULL NULL NULL 0
+98 71 1 0 0
+00 71 1 0 0
+02 71 1 0 0
+60 71 1 0 0
+70 71 0 1 0
+NULL 71 NULL NULL 0
+71 71 0 0 1
select a.f1 as a, b.f2 as b, a.f1 > b.f2 as gt,
a.f1 < b.f2 as lt, a.f1<=>b.f2 as eq
from t1 a, t1 b;
@@ -1595,36 +1612,49 @@ a b gt lt eq
60 1998 1 0 0
70 1998 0 1 0
NULL 1998 NULL NULL 0
+71 1998 0 1 0
98 2000 0 1 0
00 2000 0 0 1
02 2000 1 0 0
60 2000 1 0 0
70 2000 0 1 0
NULL 2000 NULL NULL 0
+71 2000 0 1 0
98 2002 0 1 0
00 2002 0 1 0
02 2002 0 0 1
60 2002 1 0 0
70 2002 0 1 0
NULL 2002 NULL NULL 0
+71 2002 0 1 0
98 2060 0 1 0
00 2060 0 1 0
02 2060 0 1 0
60 2060 0 0 1
70 2060 0 1 0
NULL 2060 NULL NULL 0
+71 2060 0 1 0
98 1970 1 0 0
00 1970 1 0 0
02 1970 1 0 0
60 1970 1 0 0
70 1970 0 0 1
NULL 1970 NULL NULL 0
+71 1970 1 0 0
98 NULL NULL NULL 0
00 NULL NULL NULL 0
02 NULL NULL NULL 0
60 NULL NULL NULL 0
70 NULL NULL NULL 0
NULL NULL NULL NULL 1
+71 NULL NULL NULL 0
+98 1971 1 0 0
+00 1971 1 0 0
+02 1971 1 0 0
+60 1971 1 0 0
+70 1971 0 1 0
+NULL 1971 NULL NULL 0
+71 1971 0 0 1
select a.f1 as a, b.f3 as b, a.f1 > b.f3 as gt,
a.f1 < b.f3 as lt, a.f1<=>b.f3 as eq
from t1 a, t1 b;
@@ -1635,36 +1665,49 @@ a b gt lt eq
60 1998-01-01 1 0 0
70 1998-01-01 0 1 0
NULL 1998-01-01 NULL NULL 0
+71 1998-01-01 0 1 0
98 2000-01-01 0 1 0
00 2000-01-01 0 1 0
02 2000-01-01 1 0 0
60 2000-01-01 1 0 0
70 2000-01-01 0 1 0
NULL 2000-01-01 NULL NULL 0
+71 2000-01-01 0 1 0
98 2002-01-01 0 1 0
00 2002-01-01 0 1 0
02 2002-01-01 0 1 0
60 2002-01-01 1 0 0
70 2002-01-01 0 1 0
NULL 2002-01-01 NULL NULL 0
+71 2002-01-01 0 1 0
98 2060-01-01 0 1 0
00 2060-01-01 0 1 0
02 2060-01-01 0 1 0
60 2060-01-01 0 1 0
70 2060-01-01 0 1 0
NULL 2060-01-01 NULL NULL 0
+71 2060-01-01 0 1 0
98 1970-01-01 1 0 0
00 1970-01-01 1 0 0
02 1970-01-01 1 0 0
60 1970-01-01 1 0 0
70 1970-01-01 0 1 0
NULL 1970-01-01 NULL NULL 0
+71 1970-01-01 1 0 0
98 NULL NULL NULL 0
00 NULL NULL NULL 0
02 NULL NULL NULL 0
60 NULL NULL NULL 0
70 NULL NULL NULL 0
NULL NULL NULL NULL 1
+71 NULL NULL NULL 0
+98 1971-01-01 1 0 0
+00 1971-01-01 1 0 0
+02 1971-01-01 1 0 0
+60 1971-01-01 1 0 0
+70 1971-01-01 0 1 0
+NULL 1971-01-01 NULL NULL 0
+71 1971-01-01 0 1 0
select a.f1 as a, b.f4 as b, a.f1 > b.f4 as gt,
a.f1 < b.f4 as lt, a.f1<=>b.f4 as eq
from t1 a, t1 b;
@@ -1675,36 +1718,49 @@ a b gt lt eq
60 1998-01-01 00:00:00 1 0 0
70 1998-01-01 00:00:00 0 1 0
NULL 1998-01-01 00:00:00 NULL NULL 0
+71 1998-01-01 00:00:00 0 1 0
98 2000-01-01 00:00:01 0 1 0
00 2000-01-01 00:00:01 0 1 0
02 2000-01-01 00:00:01 1 0 0
60 2000-01-01 00:00:01 1 0 0
70 2000-01-01 00:00:01 0 1 0
NULL 2000-01-01 00:00:01 NULL NULL 0
+71 2000-01-01 00:00:01 0 1 0
98 2002-01-01 23:59:59 0 1 0
00 2002-01-01 23:59:59 0 1 0
02 2002-01-01 23:59:59 0 1 0
60 2002-01-01 23:59:59 1 0 0
70 2002-01-01 23:59:59 0 1 0
NULL 2002-01-01 23:59:59 NULL NULL 0
+71 2002-01-01 23:59:59 0 1 0
98 2060-01-01 11:11:11 0 1 0
00 2060-01-01 11:11:11 0 1 0
02 2060-01-01 11:11:11 0 1 0
60 2060-01-01 11:11:11 0 1 0
70 2060-01-01 11:11:11 0 1 0
NULL 2060-01-01 11:11:11 NULL NULL 0
+71 2060-01-01 11:11:11 0 1 0
98 1970-11-11 22:22:22 1 0 0
00 1970-11-11 22:22:22 1 0 0
02 1970-11-11 22:22:22 1 0 0
60 1970-11-11 22:22:22 1 0 0
70 1970-11-11 22:22:22 0 1 0
NULL 1970-11-11 22:22:22 NULL NULL 0
+71 1970-11-11 22:22:22 1 0 0
98 NULL NULL NULL 0
00 NULL NULL NULL 0
02 NULL NULL NULL 0
60 NULL NULL NULL 0
70 NULL NULL NULL 0
NULL NULL NULL NULL 1
+71 NULL NULL NULL 0
+98 1971-11-11 22:22:22 1 0 0
+00 1971-11-11 22:22:22 1 0 0
+02 1971-11-11 22:22:22 1 0 0
+60 1971-11-11 22:22:22 1 0 0
+70 1971-11-11 22:22:22 0 1 0
+NULL 1971-11-11 22:22:22 NULL NULL 0
+71 1971-11-11 22:22:22 0 1 0
select *, f1 = f2 from t1;
f1 f2 f3 f4 f1 = f2
98 1998 1998-01-01 1998-01-01 00:00:00 1
@@ -1713,6 +1769,7 @@ f1 f2 f3 f4 f1 = f2
60 2060 2060-01-01 2060-01-01 11:11:11 1
70 1970 1970-01-01 1970-11-11 22:22:22 1
NULL NULL NULL NULL NULL
+71 1971 1971-01-01 1971-11-11 22:22:22 1
drop table t1;
#
# Bug #54465: assert: field_types == 0 || field_types[field_pos] ==
@@ -1759,7 +1816,6 @@ MAX(f1)
2001
DROP TABLE t1;
#
-End of 5.1 tests
# LP BUG#813418 - incorrect optimisation of max/min by index for
# negated BETWEEN
CREATE TABLE t1 (a int, KEY (a));
@@ -1769,6 +1825,8 @@ MAX(a)
10
drop table t1;
#
+End of 5.1 tests
+#
# Bug #904345: MIN/MAX optimization with constant FALSE condition
#
CREATE TABLE t1 (a int NOT NULL, KEY(a));
@@ -1779,20 +1837,21 @@ INSERT INTO t2 VALUES
EXPLAIN EXTENDED
SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10;
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 NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
+1 PRIMARY t1 range a a 4 NULL 4 100.00 Using where; Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where 0
+Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where (<expr_cache><1,2>(<in_optimizer>((1,2),<exists>(select 3,4 having (((1 = 3) or isnull(3)) and ((2 = 4) or isnull(4)) and <is_not_null_test>(3) and <is_not_null_test>(4))))) and (`test`.`t1`.`a` < 10))
SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10;
MAX(a)
NULL
EXPLAIN EXTENDED
SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10;
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 ALL NULL NULL NULL NULL 5 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
+1 PRIMARY t1 range a a 4 NULL 4 100.00 Using where; Using index; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
Warnings:
-Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where 0
+Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`a` = 1) and (`test`.`t2`.`b` = 2) and (`test`.`t1`.`a` < 10))
SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10;
MAX(a)
NULL
@@ -1823,7 +1882,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00
Warnings:
Note 1276 Field or reference 'test.t3.b' of SELECT #2 was resolved in SELECT #1
-Note 1003 select (select min('1') from `test`.`t1` join `test`.`t2` where ('10' = `test`.`t3`.`b`)) AS `(SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b)` from `test`.`t3`
+Note 1003 select <expr_cache><`test`.`t3`.`b`>((select min(1) from `test`.`t1` join `test`.`t2` where (10 = `test`.`t3`.`b`))) AS `(SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b)` from `test`.`t3`
SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3;
(SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b)
NULL
@@ -1878,3 +1937,156 @@ MIN(f2)
b
DROP TABLE t1;
End of 5.2 tests
+#
+# BUG#46680 - Assertion failed in file item_subselect.cc,
+# line 305 crashing on HAVING subquery
+#
+# Create tables
+#
+CREATE TABLE t1 (
+pk INT,
+v VARCHAR(1) DEFAULT NULL,
+PRIMARY KEY(pk)
+);
+CREATE TABLE t2 LIKE t1;
+CREATE TABLE t3 LIKE t1;
+CREATE TABLE empty1 (a int);
+INSERT INTO t1 VALUES (1,'c'),(2,NULL);
+INSERT INTO t2 VALUES (3,'m'),(4,NULL);
+INSERT INTO t3 VALUES (1,'n');
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+
+#
+# 1) Test that subquery materialization is setup for query with
+# premature optimize() exit due to "Impossible WHERE"
+#
+SELECT MIN(t2.pk)
+FROM t2 JOIN t1 ON t1.pk=t2.pk
+WHERE 'j'
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+MIN(t2.pk)
+NULL
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: 'j'
+
+EXPLAIN
+SELECT MIN(t2.pk)
+FROM t2 JOIN t1 ON t1.pk=t2.pk
+WHERE 'j'
+HAVING ('m') IN (
+SELECT v
+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
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: 'j'
+
+#
+# 2) Test that subquery materialization is setup for query with
+# premature optimize() exit due to "No matching min/max row"
+#
+SELECT MIN(t2.pk)
+FROM t2
+WHERE t2.pk>10
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+MIN(t2.pk)
+NULL
+
+EXPLAIN
+SELECT MIN(t2.pk)
+FROM t2
+WHERE t2.pk>10
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+
+#
+# 3) Test that subquery materialization is setup for query with
+# premature optimize() exit due to "Select tables optimized away"
+#
+SELECT MIN(pk)
+FROM t1
+WHERE pk=NULL
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+MIN(pk)
+NULL
+
+EXPLAIN
+SELECT MIN(pk)
+FROM t1
+WHERE pk=NULL
+HAVING ('m') IN (
+SELECT v
+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
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+
+#
+# 4) Test that subquery materialization is setup for query with
+# premature optimize() exit due to "No matching row in const table"
+#
+
+SELECT MIN(a)
+FROM (SELECT a FROM empty1) tt
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+MIN(a)
+NULL
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+EXPLAIN
+SELECT MIN(a)
+FROM (SELECT a FROM empty1) tt
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
+3 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+set optimizer_switch=@tmp_optimizer_switch;
+
+#
+# 5) Test that subquery materialization is setup for query with
+# premature optimize() exit due to "Impossible WHERE noticed
+# after reading const tables"
+#
+SELECT min(t1.pk)
+FROM t1
+WHERE t1.pk IN (SELECT 1 from t3 where pk>10)
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+min(t1.pk)
+NULL
+
+EXPLAIN
+SELECT min(t1.pk)
+FROM t1
+WHERE t1.pk IN (SELECT 1 from t3 where pk>10)
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 2 Using where; Using index
+3 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+set @@optimizer_switch=@save_optimizer_switch;
+#
+# Cleanup for BUG#46680
+#
+DROP TABLE IF EXISTS t1,t2,t3,empty1;
diff --git a/mysql-test/r/func_group_innodb.result b/mysql-test/r/func_group_innodb.result
index 3a30816754a..b61f12e82a4 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_if.result b/mysql-test/r/func_if.result
index 8d3507f6bed..6acf1efe75d 100644
--- a/mysql-test/r/func_if.result
+++ b/mysql-test/r/func_if.result
@@ -177,13 +177,20 @@ IF((ROUND(t1.a,2)=1), 2,
IF((R
DROP TABLE t1;
CREATE TABLE t1 (c LONGTEXT);
-INSERT INTO t1 VALUES(1), (2), (3), (4), ('12345678901234567890');
+INSERT INTO t1 VALUES(1), (2), (3), (4), ('1234567890123456789');
+SELECT IF(1, CAST(c AS UNSIGNED), 0) FROM t1;
+IF(1, CAST(c AS UNSIGNED), 0)
+1
+2
+3
+4
+1234567890123456789
SELECT * FROM (SELECT MAX(IF(1, CAST(c AS UNSIGNED), 0)) FROM t1) AS te;
MAX(IF(1, CAST(c AS UNSIGNED), 0))
-12345678901234567890
+1234567890123456789
SELECT * FROM (SELECT MAX(IFNULL(CAST(c AS UNSIGNED), 0)) FROM t1) AS te;
MAX(IFNULL(CAST(c AS UNSIGNED), 0))
-12345678901234567890
+1234567890123456789
DROP TABLE t1;
End of 5.0 tests
#
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index e45c775b377..d25dcd40117 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
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
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
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
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
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
select * from t2 where a not in (345.67890, 43245.34, 64224.56344);
a filler
0.00000 1
@@ -479,7 +479,7 @@ SELECT * FROM t4 WHERE a IN ('1972-02-06','19772-07-29');
a
1972-02-06
Warnings:
-Warning 1292 Incorrect date value: '19772-07-29' for column 'a' at row 1
+Warning 1292 Incorrect datetime value: '19772-07-29'
DROP TABLE t1,t2,t3,t4;
CREATE TABLE t1 (id int not null);
INSERT INTO t1 VALUES (1),(2);
@@ -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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
@@ -796,3 +796,19 @@ PREPARE s FROM "SELECT 1 FROM t1 WHERE 1 < ALL (SELECT @:= (1 IN (SELECT 1 FROM
EXECUTE s;
1
DROP TABLE t1;
+create table t1 (a bigint, b int);
+insert t1 values (1,1),(2,2),(3,3);
+select * from t1 where a in ('2.1');
+a b
+2 2
+select * from t1 where b in ('2.1');
+a b
+select * from t1 where a='2.1';
+a b
+2 2
+select * from t1 where b='2.1';
+a b
+select * from t1 where IF(1,a,a)='2.1';
+a b
+drop table t1;
+# End of 5.3 tests
diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result
index 4e3608240d4..c3c7313a5d7 100644
--- a/mysql-test/r/func_math.result
+++ b/mysql-test/r/func_math.result
@@ -285,33 +285,55 @@ set names default;
select cast(-2 as unsigned), 18446744073709551614, -2;
cast(-2 as unsigned) 18446744073709551614 -2
18446744073709551614 18446744073709551614 -2
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select abs(cast(-2 as unsigned)), abs(18446744073709551614), abs(-2);
abs(cast(-2 as unsigned)) abs(18446744073709551614) abs(-2)
18446744073709551614 18446744073709551614 2
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select ceiling(cast(-2 as unsigned)), ceiling(18446744073709551614), ceiling(-2);
ceiling(cast(-2 as unsigned)) ceiling(18446744073709551614) ceiling(-2)
18446744073709551614 18446744073709551614 -2
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select floor(cast(-2 as unsigned)), floor(18446744073709551614), floor(-2);
floor(cast(-2 as unsigned)) floor(18446744073709551614) floor(-2)
18446744073709551614 18446744073709551614 -2
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select format(cast(-2 as unsigned), 2), format(18446744073709551614, 2), format(-2, 2);
format(cast(-2 as unsigned), 2) format(18446744073709551614, 2) format(-2, 2)
18,446,744,073,709,551,614.00 18,446,744,073,709,551,614.00 -2.00
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select sqrt(cast(-2 as unsigned)), sqrt(18446744073709551614), sqrt(-2);
sqrt(cast(-2 as unsigned)) sqrt(18446744073709551614) sqrt(-2)
4294967296 4294967296 NULL
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select round(cast(-2 as unsigned), 1), round(18446744073709551614, 1), round(-2, 1);
round(cast(-2 as unsigned), 1) round(18446744073709551614, 1) round(-2, 1)
18446744073709551614 18446744073709551614 -2
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select round(4, cast(-2 as unsigned)), round(4, 18446744073709551614), round(4, -2);
round(4, cast(-2 as unsigned)) round(4, 18446744073709551614) round(4, -2)
4 4 0
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select truncate(cast(-2 as unsigned), 1), truncate(18446744073709551614, 1), truncate(-2, 1);
truncate(cast(-2 as unsigned), 1) truncate(18446744073709551614, 1) truncate(-2, 1)
18446744073709551614 18446744073709551614 -2
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select truncate(4, cast(-2 as unsigned)), truncate(4, 18446744073709551614), truncate(4, -2);
truncate(4, cast(-2 as unsigned)) truncate(4, 18446744073709551614) truncate(4, -2)
4 4 0
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select round(10000000000000000000, -19), truncate(10000000000000000000, -19);
round(10000000000000000000, -19) truncate(10000000000000000000, -19)
10000000000000000000 10000000000000000000
@@ -363,12 +385,18 @@ round(4, -4294967200) truncate(4, -4294967200)
select mod(cast(-2 as unsigned), 3), mod(18446744073709551614, 3), mod(-2, 3);
mod(cast(-2 as unsigned), 3) mod(18446744073709551614, 3) mod(-2, 3)
2 2 -2
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select mod(5, cast(-2 as unsigned)), mod(5, 18446744073709551614), mod(5, -2);
mod(5, cast(-2 as unsigned)) mod(5, 18446744073709551614) mod(5, -2)
5 5 1
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select pow(cast(-2 as unsigned), 5), pow(18446744073709551614, 5), pow(-2, 5);
pow(cast(-2 as unsigned), 5) pow(18446744073709551614, 5) pow(-2, 5)
2.13598703592091e+96 2.13598703592091e+96 -32
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
CREATE TABLE t1 (a timestamp, b varchar(20), c bit(1));
INSERT INTO t1 VALUES('1998-09-23', 'str1', 1), ('2003-03-25', 'str2', 0);
SELECT a DIV 900 y FROM t1 GROUP BY y;
@@ -488,7 +516,7 @@ SELECT -9999999999999999991 DIV -1;
-9999999999999999991 DIV -1
-9223372036854775808
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999991' to INT. Value truncated.
SELECT -9223372036854775808 DIV -1;
-9223372036854775808 DIV -1
-9223372036854775808
diff --git a/mysql-test/r/func_op.result b/mysql-test/r/func_op.result
index 636163e6b29..ce755e86b4c 100644
--- a/mysql-test/r/func_op.result
+++ b/mysql-test/r/func_op.result
@@ -40,9 +40,12 @@ create table t1(a int);
create table t2(a int, b int);
insert into t1 values (1), (2), (3);
insert into t2 values (1, 7), (3, 7);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select t1.a, t2.a, t2.b, bit_count(t2.b) from t1 left join t2 on t1.a=t2.a;
a a b bit_count(t2.b)
1 1 7 3
2 NULL NULL NULL
3 3 7 3
+SET optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result
index 87b88692a34..f0c1abd84fe 100644
--- a/mysql-test/r/func_sapdb.result
+++ b/mysql-test/r/func_sapdb.result
@@ -113,10 +113,10 @@ subtime("01:00:00.999999", "02:00:00.999998")
-00:59:59.999999
select subtime("02:01:01.999999", "01:01:01.999999");
subtime("02:01:01.999999", "01:01:01.999999")
-01:00:00.000000
+01:00:00
select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002");
timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002")
-838:59:59
+838:59:59.999999
Warnings:
Warning 1292 Truncated incorrect time value: '8807:59:59.999999'
select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002");
@@ -184,8 +184,8 @@ microsecond("1997-12-31 23:59:59.000001")
1
create table t1
select makedate(1997,1) as f1,
-addtime(cast("1997-12-31 23:59:59.000001" as datetime), "1 1:1:1.000002") as f2,
-addtime(cast("23:59:59.999999" as time) , "1 1:1:1.000002") as f3,
+addtime(cast("1997-12-31 23:59:59.000001" as datetime(6)), "1 1:1:1.000002") as f2,
+addtime(cast("23:59:59.999999" as time(6)) , "1 1:1:1.000002") as f3,
timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") as f4,
timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") as f5,
maketime(10,11,12) as f6,
@@ -195,17 +195,17 @@ time("1997-12-31 23:59:59.000001") as f9;
describe t1;
Field Type Null Key Default Extra
f1 date YES NULL
-f2 datetime YES NULL
-f3 time YES NULL
-f4 time YES NULL
-f5 time YES NULL
+f2 datetime(6) YES NULL
+f3 time(6) YES NULL
+f4 time(6) YES NULL
+f5 time(6) YES NULL
f6 time YES NULL
-f7 datetime YES NULL
+f7 datetime(6) YES NULL
f8 date YES NULL
-f9 time YES NULL
+f9 time(6) YES NULL
select * from t1;
f1 f2 f3 f4 f5 f6 f7 f8 f9
-1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -24:00:00 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59
+1997-01-01 1998-01-02 01:01:00.000003 49:01:01.000001 46:58:57.999999 -24:00:00.000001 10:11:12 2001-12-01 01:01:01.000000 1997-12-31 23:59:59.000001
create table test(t1 datetime, t2 time, t3 time, t4 datetime);
insert into test values
('2001-01-01 01:01:01', '01:01:01', null, '2001-02-01 01:01:01'),
@@ -250,6 +250,8 @@ a
select microsecond(19971231235959.01) as a;
a
10000
+Warnings:
+Warning 1292 Truncated incorrect time value: '19971231235959.01'
select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a;
a
1997-12-31 00:00:10.090000
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index aef452b7b50..b77ccdae82c 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -1533,7 +1533,7 @@ select locate('lo','hello',-18446744073709551615);
locate('lo','hello',-18446744073709551615)
0
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select locate('lo','hello',18446744073709551615);
locate('lo','hello',18446744073709551615)
0
@@ -1541,22 +1541,22 @@ select locate('lo','hello',-18446744073709551616);
locate('lo','hello',-18446744073709551616)
0
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select locate('lo','hello',18446744073709551616);
locate('lo','hello',18446744073709551616)
0
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select locate('lo','hello',-18446744073709551617);
locate('lo','hello',-18446744073709551617)
0
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select locate('lo','hello',18446744073709551617);
locate('lo','hello',18446744073709551617)
0
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select left('hello', 10);
left('hello', 10)
hello
@@ -1588,8 +1588,8 @@ select left('hello', -18446744073709551615);
left('hello', -18446744073709551615)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select left('hello', 18446744073709551615);
left('hello', 18446744073709551615)
hello
@@ -1597,26 +1597,26 @@ select left('hello', -18446744073709551616);
left('hello', -18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select left('hello', 18446744073709551616);
left('hello', 18446744073709551616)
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select left('hello', -18446744073709551617);
left('hello', -18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select left('hello', 18446744073709551617);
left('hello', 18446744073709551617)
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select right('hello', 10);
right('hello', 10)
hello
@@ -1648,8 +1648,8 @@ select right('hello', -18446744073709551615);
right('hello', -18446744073709551615)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select right('hello', 18446744073709551615);
right('hello', 18446744073709551615)
hello
@@ -1657,26 +1657,26 @@ select right('hello', -18446744073709551616);
right('hello', -18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select right('hello', 18446744073709551616);
right('hello', 18446744073709551616)
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select right('hello', -18446744073709551617);
right('hello', -18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select right('hello', 18446744073709551617);
right('hello', 18446744073709551617)
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select substring('hello', 2, -1);
substring('hello', 2, -1)
@@ -1708,8 +1708,8 @@ select substring('hello', -18446744073709551615, 1);
substring('hello', -18446744073709551615, 1)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select substring('hello', 18446744073709551615, 1);
substring('hello', 18446744073709551615, 1)
@@ -1717,26 +1717,26 @@ select substring('hello', -18446744073709551616, 1);
substring('hello', -18446744073709551616, 1)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select substring('hello', 18446744073709551616, 1);
substring('hello', 18446744073709551616, 1)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select substring('hello', -18446744073709551617, 1);
substring('hello', -18446744073709551617, 1)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select substring('hello', 18446744073709551617, 1);
substring('hello', 18446744073709551617, 1)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select substring('hello', 1, -1);
substring('hello', 1, -1)
@@ -1762,8 +1762,8 @@ select substring('hello', 1, -18446744073709551615);
substring('hello', 1, -18446744073709551615)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select substring('hello', 1, 18446744073709551615);
substring('hello', 1, 18446744073709551615)
hello
@@ -1771,26 +1771,26 @@ select substring('hello', 1, -18446744073709551616);
substring('hello', 1, -18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select substring('hello', 1, 18446744073709551616);
substring('hello', 1, 18446744073709551616)
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select substring('hello', 1, -18446744073709551617);
substring('hello', 1, -18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select substring('hello', 1, 18446744073709551617);
substring('hello', 1, 18446744073709551617)
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select substring('hello', -1, -1);
substring('hello', -1, -1)
@@ -1816,10 +1816,10 @@ select substring('hello', -18446744073709551615, -18446744073709551615);
substring('hello', -18446744073709551615, -18446744073709551615)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select substring('hello', 18446744073709551615, 18446744073709551615);
substring('hello', 18446744073709551615, 18446744073709551615)
@@ -1827,34 +1827,34 @@ select substring('hello', -18446744073709551616, -18446744073709551616);
substring('hello', -18446744073709551616, -18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select substring('hello', 18446744073709551616, 18446744073709551616);
substring('hello', 18446744073709551616, 18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select substring('hello', -18446744073709551617, -18446744073709551617);
substring('hello', -18446744073709551617, -18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select substring('hello', 18446744073709551617, 18446744073709551617);
substring('hello', 18446744073709551617, 18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select insert('hello', -1, 1, 'hi');
insert('hello', -1, 1, 'hi')
hello
@@ -1880,7 +1880,7 @@ select insert('hello', -18446744073709551615, 1, 'hi');
insert('hello', -18446744073709551615, 1, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select insert('hello', 18446744073709551615, 1, 'hi');
insert('hello', 18446744073709551615, 1, 'hi')
hello
@@ -1888,22 +1888,22 @@ select insert('hello', -18446744073709551616, 1, 'hi');
insert('hello', -18446744073709551616, 1, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select insert('hello', 18446744073709551616, 1, 'hi');
insert('hello', 18446744073709551616, 1, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select insert('hello', -18446744073709551617, 1, 'hi');
insert('hello', -18446744073709551617, 1, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select insert('hello', 18446744073709551617, 1, 'hi');
insert('hello', 18446744073709551617, 1, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select insert('hello', 1, -1, 'hi');
insert('hello', 1, -1, 'hi')
hi
@@ -1929,7 +1929,7 @@ select insert('hello', 1, -18446744073709551615, 'hi');
insert('hello', 1, -18446744073709551615, 'hi')
hi
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select insert('hello', 1, 18446744073709551615, 'hi');
insert('hello', 1, 18446744073709551615, 'hi')
hi
@@ -1937,22 +1937,22 @@ select insert('hello', 1, -18446744073709551616, 'hi');
insert('hello', 1, -18446744073709551616, 'hi')
hi
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select insert('hello', 1, 18446744073709551616, 'hi');
insert('hello', 1, 18446744073709551616, 'hi')
hi
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select insert('hello', 1, -18446744073709551617, 'hi');
insert('hello', 1, -18446744073709551617, 'hi')
hi
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select insert('hello', 1, 18446744073709551617, 'hi');
insert('hello', 1, 18446744073709551617, 'hi')
hi
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select insert('hello', -1, -1, 'hi');
insert('hello', -1, -1, 'hi')
hello
@@ -1978,8 +1978,8 @@ select insert('hello', -18446744073709551615, -18446744073709551615, 'hi');
insert('hello', -18446744073709551615, -18446744073709551615, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select insert('hello', 18446744073709551615, 18446744073709551615, 'hi');
insert('hello', 18446744073709551615, 18446744073709551615, 'hi')
hello
@@ -1987,26 +1987,26 @@ select insert('hello', -18446744073709551616, -18446744073709551616, 'hi');
insert('hello', -18446744073709551616, -18446744073709551616, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select insert('hello', 18446744073709551616, 18446744073709551616, 'hi');
insert('hello', 18446744073709551616, 18446744073709551616, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select insert('hello', -18446744073709551617, -18446744073709551617, 'hi');
insert('hello', -18446744073709551617, -18446744073709551617, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select insert('hello', 18446744073709551617, 18446744073709551617, 'hi');
insert('hello', 18446744073709551617, 18446744073709551617, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select repeat('hello', -1);
repeat('hello', -1)
@@ -2038,8 +2038,8 @@ select repeat('hello', -18446744073709551615);
repeat('hello', -18446744073709551615)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select repeat('hello', 18446744073709551615);
repeat('hello', 18446744073709551615)
NULL
@@ -2049,27 +2049,27 @@ select repeat('hello', -18446744073709551616);
repeat('hello', -18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select repeat('hello', 18446744073709551616);
repeat('hello', 18446744073709551616)
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
select repeat('hello', -18446744073709551617);
repeat('hello', -18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select repeat('hello', 18446744073709551617);
repeat('hello', 18446744073709551617)
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
select space(-1);
space(-1)
@@ -2102,8 +2102,8 @@ select space(-18446744073709551615);
space(-18446744073709551615)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select space(18446744073709551615);
space(18446744073709551615)
NULL
@@ -2113,27 +2113,27 @@ select space(-18446744073709551616);
space(-18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select space(18446744073709551616);
space(18446744073709551616)
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
select space(-18446744073709551617);
space(-18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select space(18446744073709551617);
space(18446744073709551617)
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
select rpad('hello', -1, '1');
rpad('hello', -1, '1')
@@ -2166,8 +2166,8 @@ select rpad('hello', -18446744073709551615, '1');
rpad('hello', -18446744073709551615, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select rpad('hello', 18446744073709551615, '1');
rpad('hello', 18446744073709551615, '1')
NULL
@@ -2177,27 +2177,27 @@ select rpad('hello', -18446744073709551616, '1');
rpad('hello', -18446744073709551616, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select rpad('hello', 18446744073709551616, '1');
rpad('hello', 18446744073709551616, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
Warning 1301 Result of rpad() was larger than max_allowed_packet (1048576) - truncated
select rpad('hello', -18446744073709551617, '1');
rpad('hello', -18446744073709551617, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select rpad('hello', 18446744073709551617, '1');
rpad('hello', 18446744073709551617, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
Warning 1301 Result of rpad() was larger than max_allowed_packet (1048576) - truncated
select lpad('hello', -1, '1');
lpad('hello', -1, '1')
@@ -2230,8 +2230,8 @@ select lpad('hello', -18446744073709551615, '1');
lpad('hello', -18446744073709551615, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select lpad('hello', 18446744073709551615, '1');
lpad('hello', 18446744073709551615, '1')
NULL
@@ -2241,27 +2241,27 @@ select lpad('hello', -18446744073709551616, '1');
lpad('hello', -18446744073709551616, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select lpad('hello', 18446744073709551616, '1');
lpad('hello', 18446744073709551616, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
Warning 1301 Result of lpad() was larger than max_allowed_packet (1048576) - truncated
select lpad('hello', -18446744073709551617, '1');
lpad('hello', -18446744073709551617, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select lpad('hello', 18446744073709551617, '1');
lpad('hello', 18446744073709551617, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
Warning 1301 Result of lpad() was larger than max_allowed_packet (1048576) - truncated
SET @orig_sql_mode = @@SQL_MODE;
SET SQL_MODE=traditional;
@@ -2547,16 +2547,19 @@ End of 5.0 tests
drop table if exists t1;
create table t1(f1 tinyint default null)engine=myisam;
insert into t1 values (-1),(null);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
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
+set optimizer_switch=@tmp_optimizer_switch;
drop table t1;
#
# Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0
diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result
index e3c77a40a77..ea9d653402c 100644
--- a/mysql-test/r/func_test.result
+++ b/mysql-test/r/func_test.result
@@ -87,7 +87,7 @@ explain extended select - a 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 -('1') AS `- a` from `test`.`t1`
+Note 1003 select -(1) AS `- a` from `test`.`t1`
drop table t1;
select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1;
5 between 0 and 10 between 0 and 1 (5 between 0 and 10) between 0 and 1
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index cc5cb5edbd6..14d2729e952 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -8,20 +8,43 @@ period_add("9602",-12) period_diff(199505,"9404")
199502 13
select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_timestamp(now());
now()-now() weekday(curdate())-weekday(now()) unix_timestamp()-unix_timestamp(now())
-0.000000 0 0
+0 0 0
select from_unixtime(unix_timestamp("1994-03-02 10:11:12")),from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s"),from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0;
from_unixtime(unix_timestamp("1994-03-02 10:11:12")) from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s") from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0
-1994-03-02 10:11:12 1994-03-02 10:11:12 19940302101112.000000
+1994-03-02 10:11:12.000000 1994-03-02 10:11:12 19940302101112.000000
select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"),
sec_to_time(time_to_sec("0:30:47")/6.21);
sec_to_time(9001) sec_to_time(9001)+0 time_to_sec("15:12:22") sec_to_time(time_to_sec("0:30:47")/6.21)
-02:30:01 23001.000000 54742 00:04:57
+02:30:01 23001 54742.000000 00:04:57.423510
+select sec_to_time(9001.1), time_to_sec('15:12:22.123456'), time_to_sec(15.5566778899);
+sec_to_time(9001.1) time_to_sec('15:12:22.123456') time_to_sec(15.5566778899)
+02:30:01.1 54742.123456 15.556677
select sec_to_time(time_to_sec('-838:59:59'));
sec_to_time(time_to_sec('-838:59:59'))
--838:59:59
+-838:59:59.000000
+select sec_to_time('9001.1'), sec_to_time('1234567890123.123');
+sec_to_time('9001.1') sec_to_time('1234567890123.123')
+02:30:01.100000 838:59:59.999999
+Warnings:
+Warning 1292 Truncated incorrect time value: '1234567890123.123'
+select sec_to_time(-9001.1), sec_to_time(-9001.1) / 1,
+sec_to_time(-9001.1) / 1e0, sec_to_time(-9001) div 1;
+sec_to_time(-9001.1) sec_to_time(-9001.1) / 1 sec_to_time(-9001.1) / 1e0 sec_to_time(-9001) div 1
+-02:30:01.1 -23001.10000 -23001.1 -23001
+select sec_to_time(90011e-1), sec_to_time(1234567890123e30);
+sec_to_time(90011e-1) sec_to_time(1234567890123e30)
+02:30:01.100000 838:59:59.999999
+Warnings:
+Warning 1292 Truncated incorrect time value: '1.234567890123e+42'
+select sec_to_time(1234567890123), sec_to_time('99999999999999999999999999999');
+sec_to_time(1234567890123) sec_to_time('99999999999999999999999999999')
+838:59:59 838:59:59.999999
+Warnings:
+Warning 1292 Truncated incorrect time value: '1234567890123'
+Warning 1292 Truncated incorrect time value: '99999999999999999999999999999'
select now()-curdate()*1000000-curtime();
now()-curdate()*1000000-curtime()
-0.000000
+0
select strcmp(current_timestamp(),concat(current_date()," ",current_time()));
strcmp(current_timestamp(),concat(current_date()," ",current_time()))
0
@@ -52,6 +75,9 @@ DAYOFYEAR("1997-03-03") WEEK("1998-03-03") QUARTER(980303)
select HOUR("1997-03-03 23:03:22"), MINUTE("23:03:22"), SECOND(230322);
HOUR("1997-03-03 23:03:22") MINUTE("23:03:22") SECOND(230322)
23 3 22
+select TIME(230322), TIME(230322.33), TIME("230322.33");
+TIME(230322) TIME(230322.33) TIME("230322.33")
+23:03:22 23:03:22.33 23:03:22.330000
select week(19980101),week(19970101),week(19980101,1),week(19970101,1);
week(19980101) week(19970101) week(19980101,1) week(19970101,1)
0 0 1 1
@@ -137,18 +163,18 @@ Saturday 5
select monthname("1972-03-04"),monthname("1972-03-04")+0;
monthname("1972-03-04") monthname("1972-03-04")+0
March 3
-select time_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
-time_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
-00|12|0|12|00|AM|12:00:00 AM|00|00:00:00
-select time_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
-time_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
-01|01|1|1|02|AM|01:02:03 AM|03|01:02:03
-select time_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
-time_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
-13|01|13|1|14|PM|01:14:15 PM|15|13:14:15
-select time_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
-time_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
-01|01|1|1|00|AM|01:00:15 AM|15|01:00:15
+select time_format(000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
+time_format(000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T') date_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
+00|12|0|12|00|AM|12:00:00 AM|00|00:00:00 00|12|0|12|00|AM|12:00:00 AM|00|00:00:00
+select time_format(010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
+time_format(010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T') date_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
+01|01|1|1|02|AM|01:02:03 AM|03|01:02:03 01|01|1|1|02|AM|01:02:03 AM|03|01:02:03
+select time_format(131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
+time_format(131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T') date_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
+13|01|13|1|14|PM|01:14:15 PM|15|13:14:15 13|01|13|1|14|PM|01:14:15 PM|15|13:14:15
+select time_format(010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
+time_format(010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T') date_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
+01|01|1|1|00|AM|01:00:15 AM|15|01:00:15 01|01|1|1|00|AM|01:00:15 AM|15|01:00:15
select date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w');
date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w')
13|01|13|1|14|PM|01:14:15 PM|15|13:14:15| January|Saturday|31st|1998|98|Sat|Jan|031|01|31|01|15|6
@@ -543,10 +569,10 @@ select @a:=FROM_UNIXTIME(1);
1970-01-01 03:00:01
select unix_timestamp(@a);
unix_timestamp(@a)
-1
+1.000000
select unix_timestamp('1969-12-01 19:00:01');
unix_timestamp('1969-12-01 19:00:01')
-0
+NULL
select from_unixtime(-1);
from_unixtime(-1)
NULL
@@ -567,31 +593,31 @@ unix_timestamp(from_unixtime(2147483648))
NULL
select unix_timestamp('2039-01-20 01:00:00');
unix_timestamp('2039-01-20 01:00:00')
-0
+NULL
select unix_timestamp('1968-01-20 01:00:00');
unix_timestamp('1968-01-20 01:00:00')
-0
+NULL
select unix_timestamp('2038-02-10 01:00:00');
unix_timestamp('2038-02-10 01:00:00')
-0
+NULL
select unix_timestamp('1969-11-20 01:00:00');
unix_timestamp('1969-11-20 01:00:00')
-0
+NULL
select unix_timestamp('2038-01-20 01:00:00');
unix_timestamp('2038-01-20 01:00:00')
-0
+NULL
select unix_timestamp('1969-12-30 01:00:00');
unix_timestamp('1969-12-30 01:00:00')
-0
+NULL
select unix_timestamp('2038-01-17 12:00:00');
unix_timestamp('2038-01-17 12:00:00')
-2147331600
+2147331600.000000
select unix_timestamp('1970-01-01 03:00:01');
unix_timestamp('1970-01-01 03:00:01')
-1
+1.000000
select unix_timestamp('2038-01-19 07:14:07');
unix_timestamp('2038-01-19 07:14:07')
-0
+NULL
SELECT CHARSET(DAYNAME(19700101));
CHARSET(DAYNAME(19700101))
latin1
@@ -798,9 +824,7 @@ TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:29')
2
select date_add(time,INTERVAL 1 SECOND) from t1;
date_add(time,INTERVAL 1 SECOND)
-NULL
-Warnings:
-Warning 1264 Out of range value for column 'time' at row 1
+06:07:09
drop table t1;
select last_day('2000-02-05') as f1, last_day('2002-12-31') as f2,
last_day('2003-03-32') as f3, last_day('2003-04-01') as f4,
@@ -871,18 +895,12 @@ DROP TABLE t1;
select last_day('2005-00-00');
last_day('2005-00-00')
NULL
-Warnings:
-Warning 1292 Incorrect datetime value: '2005-00-00'
select last_day('2005-00-01');
last_day('2005-00-01')
NULL
-Warnings:
-Warning 1292 Incorrect datetime value: '2005-00-01'
select last_day('2005-01-00');
last_day('2005-01-00')
-NULL
-Warnings:
-Warning 1292 Incorrect datetime value: '2005-01-00'
+2005-01-31
select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')),
monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));
monthname(str_to_date(null, '%m')) monthname(str_to_date(null, '%m')) monthname(str_to_date(1, '%m')) monthname(str_to_date(0, '%m'))
@@ -941,10 +959,10 @@ sec_to_time(1) + 0, from_unixtime(1) + 0;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `now() - now()` double(23,6) NOT NULL DEFAULT '0.000000',
- `curtime() - curtime()` double(23,6) NOT NULL DEFAULT '0.000000',
- `sec_to_time(1) + 0` double(23,6) DEFAULT NULL,
- `from_unixtime(1) + 0` double(23,6) DEFAULT NULL
+ `now() - now()` decimal(20,0) NOT NULL DEFAULT '0',
+ `curtime() - curtime()` decimal(11,0) NOT NULL DEFAULT '0',
+ `sec_to_time(1) + 0` decimal(11,0) DEFAULT NULL,
+ `from_unixtime(1) + 0` decimal(20,0) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
SELECT SEC_TO_TIME(3300000);
@@ -954,7 +972,7 @@ Warnings:
Warning 1292 Truncated incorrect time value: '3300000'
SELECT SEC_TO_TIME(3300000)+0;
SEC_TO_TIME(3300000)+0
-8385959.000000
+8385959
Warnings:
Warning 1292 Truncated incorrect time value: '3300000'
SELECT SEC_TO_TIME(3600 * 4294967296);
@@ -964,31 +982,31 @@ Warnings:
Warning 1292 Truncated incorrect time value: '15461882265600'
SELECT TIME_TO_SEC('916:40:00');
TIME_TO_SEC('916:40:00')
-3020399
+3020399.999999
Warnings:
Warning 1292 Truncated incorrect time value: '916:40:00'
SELECT ADDTIME('500:00:00', '416:40:00');
ADDTIME('500:00:00', '416:40:00')
-838:59:59
+838:59:59.999999
Warnings:
Warning 1292 Truncated incorrect time value: '916:40:00'
SELECT ADDTIME('916:40:00', '416:40:00');
ADDTIME('916:40:00', '416:40:00')
-838:59:59
+838:59:59.999999
Warnings:
Warning 1292 Truncated incorrect time value: '916:40:00'
-Warning 1292 Truncated incorrect time value: '1255:39:59'
+Warning 1292 Truncated incorrect time value: '1255:39:59.999999'
SELECT SUBTIME('916:40:00', '416:40:00');
SUBTIME('916:40:00', '416:40:00')
-422:19:59
+422:19:59.999999
Warnings:
Warning 1292 Truncated incorrect time value: '916:40:00'
SELECT SUBTIME('-916:40:00', '416:40:00');
SUBTIME('-916:40:00', '416:40:00')
--838:59:59
+-838:59:59.999999
Warnings:
Warning 1292 Truncated incorrect time value: '-916:40:00'
-Warning 1292 Truncated incorrect time value: '-1255:39:59'
+Warning 1292 Truncated incorrect time value: '-1255:39:59.999999'
SELECT MAKETIME(916,0,0);
MAKETIME(916,0,0)
838:59:59
@@ -1014,6 +1032,7 @@ SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0);
MAKETIME(CAST(-1 AS UNSIGNED), 0, 0)
838:59:59
Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
Warning 1292 Truncated incorrect time value: '18446744073709551615:00:00'
SELECT EXTRACT(HOUR FROM '100000:02:03');
EXTRACT(HOUR FROM '100000:02:03')
@@ -1033,6 +1052,8 @@ SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED));
SEC_TO_TIME(CAST(-1 AS UNSIGNED))
838:59:59
Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
Warning 1292 Truncated incorrect time value: '18446744073709551615'
SET NAMES latin1;
SET character_set_results = NULL;
@@ -1081,7 +1102,9 @@ NULL
select isnull(week(now() + 0)), isnull(week(now() + 0.2)),
week(20061108), week(20061108.01), week(20061108085411.000002);
isnull(week(now() + 0)) isnull(week(now() + 0.2)) week(20061108) week(20061108.01) week(20061108085411.000002)
-0 0 45 45 45
+0 0 45 NULL 45
+Warnings:
+Warning 1292 Incorrect datetime value: '20061108.01'
End of 4.1 tests
explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2;
@@ -1218,6 +1241,13 @@ set time_zone= @@global.time_zone;
select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE;
str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE
NULL
+Warnings:
+Error 1411 Incorrect datetime value: '10:00 PM' for function str_to_date
+select str_to_date("1997-00-04 22:23:00","%Y-%m-%D") + interval 10 minute;
+str_to_date("1997-00-04 22:23:00","%Y-%m-%D") + interval 10 minute
+NULL
+Warnings:
+Error 1411 Incorrect datetime value: '1997-00-04 22:23:00' for function str_to_date
create table t1 (field DATE);
insert into t1 values ('2006-11-06');
select * from t1 where field < '2006-11-06 04:08:36.0';
@@ -1397,8 +1427,6 @@ NULL
# Bug#11766126 59166: ANOTHER DATETIME VALGRIND UNINITIALIZED WARNING
#
SELECT CAST((MONTH(FROM_UNIXTIME(@@GLOBAL.SQL_MODE))) AS BINARY(1025));
-CAST((MONTH(FROM_UNIXTIME(@@GLOBAL.SQL_MODE))) AS BINARY(1025))
-NULL
#
# Bug#11766124 59164: VALGRIND: UNINITIALIZED VALUE IN NUMBER_TO_DATETIME
#
@@ -1425,11 +1453,13 @@ MAKEDATE(11111111,1)
NULL
SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1);
WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1)
-NULL
+0
#
# Bug#12584302 AFTER FIX FOR #12403504: ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0,
#
DO WEEK((DATE_ADD((CAST(0 AS DATE)), INTERVAL 1 YEAR_MONTH)), 5);
+Warnings:
+Warning 1292 Incorrect datetime value: '0'
#
# BUG#13458237 INCONSISTENT HANDLING OF INVALIDE DATES WITH ZERO DAY
# SIMILAR TO '2009-10-00'
@@ -1463,28 +1493,28 @@ TO_DAYs(DATE'2009-10-00'),
TO_DAYs(STR_TO_DATE('200910','%Y%m'));
DATE('20091000') 2009-10-00
STR_TO_DATE('200910','%Y%m') 2009-10-00
-LAST_DAY('2009-10-00') NULL
+LAST_DAY('2009-10-00') 2009-10-31
LAST_DAY(DATE('2009-10-00')) 2009-10-31
-LAST_DAY(DATE'2009-10-00') NULL
+LAST_DAY(DATE'2009-10-00') 2009-10-31
LAST_DAY(STR_TO_DATE('200910','%Y%m')) 2009-10-31
WEEK('2009-10-00') NULL
-WEEK(DATE('2009-10-00')) 39
+WEEK(DATE('2009-10-00')) NULL
WEEK(DATE'2009-10-00') NULL
WEEK(STR_TO_DATE('200910','%Y%m')) NULL
WEEKOFYEAR('2009-10-00') NULL
-WEEKOFYEAR(DATE('2009-10-00')) 40
+WEEKOFYEAR(DATE('2009-10-00')) NULL
WEEKOFYEAR(DATE'2009-10-00') NULL
WEEKOFYEAR(STR_TO_DATE('200910','%Y%m')) NULL
DAYOFYEAR('2009-10-00') NULL
-DAYOFYEAR(DATE('2009-10-00')) 273
+DAYOFYEAR(DATE('2009-10-00')) NULL
DAYOFYEAR(DATE'2009-10-00') NULL
DAYOFYEAR(STR_TO_DATE('200910','%Y%m')) NULL
WEEKDAY('2009-10-00') NULL
-WEEKDAY(DATE('2009-10-00')) 2
+WEEKDAY(DATE('2009-10-00')) NULL
WEEKDAY(DATE'2009-10-00') NULL
WEEKDAY(STR_TO_DATE('200910','%Y%m')) NULL
TO_DAYs('2009-10-00') NULL
-TO_DAYs(DATE('2009-10-00')) 734045
+TO_DAYs(DATE('2009-10-00')) NULL
TO_DAYs(DATE'2009-10-00') NULL
TO_DAYs(STR_TO_DATE('200910','%Y%m')) NULL
Warnings:
@@ -1497,6 +1527,21 @@ Message Incorrect datetime value: '2009-10-00'
Level Warning
Code 1292
Message Incorrect datetime value: '2009-10-00'
+Level Error
+Code 1411
+Message Incorrect datetime value: '200910' for function str_to_date
+Level Warning
+Code 1292
+Message Incorrect datetime value: '2009-10-00'
+Level Warning
+Code 1292
+Message Incorrect datetime value: '2009-10-00'
+Level Warning
+Code 1292
+Message Incorrect datetime value: '2009-10-00'
+Level Error
+Code 1411
+Message Incorrect datetime value: '200910' for function str_to_date
Level Warning
Code 1292
Message Incorrect datetime value: '2009-10-00'
@@ -1506,6 +1551,9 @@ Message Incorrect datetime value: '2009-10-00'
Level Warning
Code 1292
Message Incorrect datetime value: '2009-10-00'
+Level Error
+Code 1411
+Message Incorrect datetime value: '200910' for function str_to_date
Level Warning
Code 1292
Message Incorrect datetime value: '2009-10-00'
@@ -1515,6 +1563,9 @@ Message Incorrect datetime value: '2009-10-00'
Level Warning
Code 1292
Message Incorrect datetime value: '2009-10-00'
+Level Error
+Code 1411
+Message Incorrect datetime value: '200910' for function str_to_date
Level Warning
Code 1292
Message Incorrect datetime value: '2009-10-00'
@@ -1524,6 +1575,9 @@ Message Incorrect datetime value: '2009-10-00'
Level Warning
Code 1292
Message Incorrect datetime value: '2009-10-00'
+Level Error
+Code 1411
+Message Incorrect datetime value: '200910' for function str_to_date
SELECT
DATE('00000100'),
STR_TO_DATE('000001','%Y%m'),
@@ -1553,28 +1607,28 @@ TO_DAYs(DATE'0000-01-00'),
TO_DAYs(STR_TO_DATE('000001','%Y%m'));
DATE('00000100') 0000-01-00
STR_TO_DATE('000001','%Y%m') 0000-01-00
-LAST_DAY('0000-01-00') NULL
+LAST_DAY('0000-01-00') 0000-01-31
LAST_DAY(DATE('0000-01-00')) 0000-01-31
-LAST_DAY(DATE'0000-01-00') NULL
+LAST_DAY(DATE'0000-01-00') 0000-01-31
LAST_DAY(STR_TO_DATE('000001','%Y%m')) 0000-01-31
WEEK('0000-01-00') NULL
-WEEK(DATE('0000-01-00')) 52
+WEEK(DATE('0000-01-00')) NULL
WEEK(DATE'0000-01-00') NULL
WEEK(STR_TO_DATE('000001','%Y%m')) NULL
WEEKOFYEAR('0000-01-00') NULL
-WEEKOFYEAR(DATE('0000-01-00')) 52
+WEEKOFYEAR(DATE('0000-01-00')) NULL
WEEKOFYEAR(DATE'0000-01-00') NULL
WEEKOFYEAR(STR_TO_DATE('000001','%Y%m')) NULL
DAYOFYEAR('0000-01-00') NULL
-DAYOFYEAR(DATE('0000-01-00')) 0
+DAYOFYEAR(DATE('0000-01-00')) NULL
DAYOFYEAR(DATE'0000-01-00') NULL
DAYOFYEAR(STR_TO_DATE('000001','%Y%m')) NULL
WEEKDAY('0000-01-00') NULL
-WEEKDAY(DATE('0000-01-00')) 5
+WEEKDAY(DATE('0000-01-00')) NULL
WEEKDAY(DATE'0000-01-00') NULL
WEEKDAY(STR_TO_DATE('000001','%Y%m')) NULL
TO_DAYs('0000-01-00') NULL
-TO_DAYs(DATE('0000-01-00')) 0
+TO_DAYs(DATE('0000-01-00')) NULL
TO_DAYs(DATE'0000-01-00') NULL
TO_DAYs(STR_TO_DATE('000001','%Y%m')) NULL
Warnings:
@@ -1587,6 +1641,9 @@ Message Incorrect datetime value: '0000-01-00'
Level Warning
Code 1292
Message Incorrect datetime value: '0000-01-00'
+Level Error
+Code 1411
+Message Incorrect datetime value: '000001' for function str_to_date
Level Warning
Code 1292
Message Incorrect datetime value: '0000-01-00'
@@ -1596,6 +1653,9 @@ Message Incorrect datetime value: '0000-01-00'
Level Warning
Code 1292
Message Incorrect datetime value: '0000-01-00'
+Level Error
+Code 1411
+Message Incorrect datetime value: '000001' for function str_to_date
Level Warning
Code 1292
Message Incorrect datetime value: '0000-01-00'
@@ -1605,6 +1665,9 @@ Message Incorrect datetime value: '0000-01-00'
Level Warning
Code 1292
Message Incorrect datetime value: '0000-01-00'
+Level Error
+Code 1411
+Message Incorrect datetime value: '000001' for function str_to_date
Level Warning
Code 1292
Message Incorrect datetime value: '0000-01-00'
@@ -1614,4 +1677,225 @@ Message Incorrect datetime value: '0000-01-00'
Level Warning
Code 1292
Message Incorrect datetime value: '0000-01-00'
+Level Error
+Code 1411
+Message Incorrect datetime value: '000001' for function str_to_date
+Level Warning
+Code 1292
+Message Incorrect datetime value: '0000-01-00'
+Level Warning
+Code 1292
+Message Incorrect datetime value: '0000-01-00'
+Level Warning
+Code 1292
+Message Incorrect datetime value: '0000-01-00'
+Level Error
+Code 1411
+Message Incorrect datetime value: '000001' for function str_to_date
End of 5.1 tests
+select time('10:10:10') > 10;
+time('10:10:10') > 10
+1
+select time('10:10:10') > 1010;
+time('10:10:10') > 1010
+1
+select time('10:10:09') > 101010;
+time('10:10:09') > 101010
+0
+select time('10:10:10') > 101010;
+time('10:10:10') > 101010
+0
+select time('10:10:11') > 101010;
+time('10:10:11') > 101010
+1
+select time(' 1 02:03:04') + interval 9 microsecond;
+time(' 1 02:03:04') + interval 9 microsecond
+26:03:04.000009
+select time(' 1 02:03:04') - interval 9 microsecond;
+time(' 1 02:03:04') - interval 9 microsecond
+26:03:03.999991
+select time('-1 02:03:04') + interval 9 microsecond;
+time('-1 02:03:04') + interval 9 microsecond
+-26:03:03.999991
+select time('-1 02:03:04') - interval 9 microsecond;
+time('-1 02:03:04') - interval 9 microsecond
+-26:03:04.000009
+select time(' 1 02:03:04') + interval '4:4:4' hour_second;
+time(' 1 02:03:04') + interval '4:4:4' hour_second
+30:07:08
+select time(' 1 02:03:04') - interval '4:4:4' hour_second;
+time(' 1 02:03:04') - interval '4:4:4' hour_second
+21:59:00
+select time('-1 02:03:04') + interval '4:4:4' hour_second;
+time('-1 02:03:04') + interval '4:4:4' hour_second
+-21:59:00
+select time('-1 02:03:04') - interval '4:4:4' hour_second;
+time('-1 02:03:04') - interval '4:4:4' hour_second
+-30:07:08
+select time(' 1 02:03:04') + interval 2 day;
+time(' 1 02:03:04') + interval 2 day
+74:03:04
+select time(' 1 02:03:04') - interval 2 day;
+time(' 1 02:03:04') - interval 2 day
+-21:56:56
+select time('-1 02:03:04') + interval 2 day;
+time('-1 02:03:04') + interval 2 day
+21:56:56
+select time('-1 02:03:04') - interval 2 day;
+time('-1 02:03:04') - interval 2 day
+-74:03:04
+select time('10 02:03:04') + interval 30 day;
+time('10 02:03:04') + interval 30 day
+NULL
+Warnings:
+Warning 1441 Datetime function: time field overflow
+select time('10 02:03:04') + interval 1 year;
+time('10 02:03:04') + interval 1 year
+NULL
+Warnings:
+Warning 1441 Datetime function: time field overflow
+select cast('131415.123e0' as time);
+cast('131415.123e0' as time)
+NULL
+Warnings:
+Warning 1292 Truncated incorrect time value: '131415.123e0'
+select cast('2010-01-02 03:04:05' as datetime) between null and '2010-01-02 03:04:04';
+cast('2010-01-02 03:04:05' as datetime) between null and '2010-01-02 03:04:04'
+0
+select least(time('1:2:3'), '01:02:04', null) div 1;
+least(time('1:2:3'), '01:02:04', null) div 1
+NULL
+select truncate(least(time('1:2:3'), '01:02:04', null), 6);
+truncate(least(time('1:2:3'), '01:02:04', null), 6)
+NULL
+select cast(least(time('1:2:3'), '01:02:04', null) as decimal(3,1));
+cast(least(time('1:2:3'), '01:02:04', null) as decimal(3,1))
+NULL
+select unix_timestamp(null);
+unix_timestamp(null)
+NULL
+select truncate(date('2010-40-10'), 6);
+truncate(date('2010-40-10'), 6)
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '2010-40-10'
+select extract(month from '2010-40-50');
+extract(month from '2010-40-50')
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '2010-40-50'
+select subtime('0000-00-10 10:10:10', '30 10:00:00');
+subtime('0000-00-10 10:10:10', '30 10:00:00')
+NULL
+select cast(str_to_date(NULL, '%H:%i:%s') as time);
+cast(str_to_date(NULL, '%H:%i:%s') as time)
+NULL
+create table t1 (f1 datetime, key (f1));
+insert into t1 values ('2000-09-12 00:00:00'), ('2007-04-25 05:08:49');
+select * from t1 where f1 > time('-23:00:06');
+f1
+2000-09-12 00:00:00
+2007-04-25 05:08:49
+drop table t1;
+select maketime(20,61,10)+0;
+maketime(20,61,10)+0
+NULL
+create table t1 (f2 int not null) ;
+insert into t1 values (0),(0);
+select last_day(f2) from t1;
+last_day(f2)
+NULL
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '0'
+Warning 1292 Incorrect datetime value: '0'
+select last_day(f2) from t1 where last_day(f2) is null;
+last_day(f2)
+NULL
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '0'
+Warning 1292 Incorrect datetime value: '0'
+Warning 1292 Incorrect datetime value: '0'
+Warning 1292 Incorrect datetime value: '0'
+select * from t1 order by last_day (f2);
+f2
+0
+0
+Warnings:
+Warning 1292 Incorrect datetime value: '0'
+Warning 1292 Incorrect datetime value: '0'
+drop table t1;
+select convert_tz(timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' as datetime)), 'UTC', 'Europe/Moscow');
+convert_tz(timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' as datetime)), 'UTC', 'Europe/Moscow')
+NULL
+create table t1 (f1 integer, f2 date);
+insert into t1 values (1,'2011-05-05'),(2,'2011-05-05'),(3,'2011-05-05'),(4,'2011-05-05'),(5,'2011-05-05'),(6, '2011-05-06');
+select * from t1 where 1 and concat(f2)=MAKEDATE(2011, 125);
+f1 f2
+1 2011-05-05
+2 2011-05-05
+3 2011-05-05
+4 2011-05-05
+5 2011-05-05
+drop table t1;
+create table t1 (f1 timestamp);
+insert into t1 values ('0000-00-00 00:00:00');
+select least(1, f1) from t1;
+least(1, f1)
+0000-00-00 00:00:00
+Warnings:
+Warning 1292 Incorrect datetime value: '1'
+drop table t1;
+select now() > coalesce(time('21:43:24'), date('2010-05-03'));
+now() > coalesce(time('21:43:24'), date('2010-05-03'))
+1
+create table t1 (f1 timestamp);
+select * from t1 where f1 > f1 and f1 <=> timestampadd(hour, 9 , '2010-01-01 16:55:35');
+f1
+drop table t1;
+create table t1 (f1 date);
+insert into t1 values ('0000-00-00');
+select timestampadd(week, 1, f1) from t1;
+timestampadd(week, 1, f1)
+NULL
+select timestampadd(week, 1, date("0000-00-00"));
+timestampadd(week, 1, date("0000-00-00"))
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '0000-00-00'
+drop table t1;
+create table t1 (f2 time not null, f3 datetime, f4 int not null, f5 timestamp);
+insert ignore t1 values ('04:38:11','0000-00-00 00:00:00',0,'0000-00-00 00:00:00');
+select least(greatest(f3, f2, f4), f5) from t1;
+least(greatest(f3, f2, f4), f5)
+0000-00-00 00:00:00
+Warnings:
+Warning 1292 Incorrect datetime value: '0'
+drop table t1;
+select day(coalesce(null));
+day(coalesce(null))
+NULL
+select timestamp(greatest('2002-08-20', '0000-00-00 00:00:00'));
+timestamp(greatest('2002-08-20', '0000-00-00 00:00:00'))
+2002-08-20 00:00:00
+create table t1 (f1 datetime);
+insert into t1 values ('0000-00-00 00:00:00');
+select cast(f1 AS time) from t1;
+cast(f1 AS time)
+00:00:00
+drop table t1;
+select greatest(cast("0-0-0" as date), cast("10:20:05" as time));
+greatest(cast("0-0-0" as date), cast("10:20:05" as time))
+0000-00-00
+select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00';
+greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00'
+1
+select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6));
+cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6))
+0000-00-00 00:00:00.000000
+select microsecond('12:00:00.123456'), microsecond('2009-12-31 23:59:59.000010');
+microsecond('12:00:00.123456') microsecond('2009-12-31 23:59:59.000010')
+123456 10
+select now(258);
+ERROR 42000: Too big precision 258 specified for 'now'. Maximum is 6.
diff --git a/mysql-test/r/func_time_hires.result b/mysql-test/r/func_time_hires.result
new file mode 100644
index 00000000000..4aa0333c4b4
--- /dev/null
+++ b/mysql-test/r/func_time_hires.result
@@ -0,0 +1,208 @@
+set time_zone='+03:00';
+set timestamp=unix_timestamp('2011-01-01 01:01:01.123456');
+select sec_to_time(12345), sec_to_time(12345.6789), sec_to_time(1234567e-2);
+sec_to_time(12345) 03:25:45
+sec_to_time(12345.6789) 03:25:45.6789
+sec_to_time(1234567e-2) 03:25:45.670000
+select now(), curtime(0), utc_timestamp(1), utc_time(2), current_time(3),
+current_timestamp(4), localtime(5), localtimestamp(6), time_to_sec('12:34:56'),
+time_to_sec('12:34:56.789');
+now() 2011-01-01 01:01:01
+curtime(0) 01:01:01
+utc_timestamp(1) 2010-12-31 22:01:01.1
+utc_time(2) 22:01:01.12
+current_time(3) 01:01:01.123
+current_timestamp(4) 2011-01-01 01:01:01.1234
+localtime(5) 2011-01-01 01:01:01.12345
+localtimestamp(6) 2011-01-01 01:01:01.123456
+time_to_sec('12:34:56') 45296.000000
+time_to_sec('12:34:56.789') 45296.789000
+select sec_to_time(time_to_sec('1:2:3')), sec_to_time(time_to_sec('2:3:4.567890'));
+sec_to_time(time_to_sec('1:2:3')) 01:02:03.000000
+sec_to_time(time_to_sec('2:3:4.567890')) 02:03:04.567890
+select time_to_sec(sec_to_time(11111)), time_to_sec(sec_to_time(11111.22222));
+time_to_sec(sec_to_time(11111)) 11111
+time_to_sec(sec_to_time(11111.22222)) 11111.22222
+select current_timestamp(7);
+ERROR 42000: Too big precision 7 specified for 'now'. Maximum is 6.
+select curtime(7);
+ERROR 42000: Too big precision 7 specified for 'curtime'. Maximum is 6.
+drop table if exists t1;
+create table t1 select sec_to_time(12345), sec_to_time(12345.6789),
+sec_to_time(1234567e-2), now(), curtime(0),
+utc_timestamp(1), utc_time(2), current_time(3),
+current_timestamp(4), localtime(5), localtimestamp(6),
+time_to_sec(123456), time_to_sec('12:34:56.789');
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `sec_to_time(12345)` time DEFAULT NULL,
+ `sec_to_time(12345.6789)` time(4) DEFAULT NULL,
+ `sec_to_time(1234567e-2)` time(6) DEFAULT NULL,
+ `now()` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `curtime(0)` time NOT NULL DEFAULT '00:00:00',
+ `utc_timestamp(1)` datetime(1) NOT NULL DEFAULT '0000-00-00 00:00:00.0',
+ `utc_time(2)` time(2) NOT NULL DEFAULT '00:00:00.00',
+ `current_time(3)` time(3) NOT NULL DEFAULT '00:00:00.000',
+ `current_timestamp(4)` datetime(4) NOT NULL DEFAULT '0000-00-00 00:00:00.0000',
+ `localtime(5)` datetime(5) NOT NULL DEFAULT '0000-00-00 00:00:00.00000',
+ `localtimestamp(6)` datetime(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
+ `time_to_sec(123456)` bigint(17) DEFAULT NULL,
+ `time_to_sec('12:34:56.789')` decimal(22,6) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t1;
+sec_to_time(12345) 03:25:45
+sec_to_time(12345.6789) 03:25:45.6789
+sec_to_time(1234567e-2) 03:25:45.670000
+now() 2011-01-01 01:01:01
+curtime(0) 01:01:01
+utc_timestamp(1) 2010-12-31 22:01:01.1
+utc_time(2) 22:01:01.12
+current_time(3) 01:01:01.123
+current_timestamp(4) 2011-01-01 01:01:01.1234
+localtime(5) 2011-01-01 01:01:01.12345
+localtimestamp(6) 2011-01-01 01:01:01.123456
+time_to_sec(123456) 45296
+time_to_sec('12:34:56.789') 45296.789000
+drop table t1;
+select unix_timestamp('2011-01-01 01:01:01'), unix_timestamp('2011-01-01 01:01:01.123456'), unix_timestamp(cast('2011-01-01 01:01:01.123456' as datetime(0))), unix_timestamp(cast('2011-01-01 01:01:01.123456' as datetime(4)));;
+unix_timestamp('2011-01-01 01:01:01') 1293832861.000000
+unix_timestamp('2011-01-01 01:01:01.123456') 1293832861.123456
+unix_timestamp(cast('2011-01-01 01:01:01.123456' as datetime(0))) 1293832861
+unix_timestamp(cast('2011-01-01 01:01:01.123456' as datetime(4))) 1293832861.1234
+select from_unixtime(unix_timestamp('2011/1/1 1:1:1')), from_unixtime(unix_timestamp('2011/1/1 1:1:1.123456')), from_unixtime(unix_timestamp(cast('2011/1/1 1:1:1.123456' as datetime(0)))), from_unixtime(unix_timestamp(cast('2011/1/1 1:1:1.123456' as datetime(4))));;
+from_unixtime(unix_timestamp('2011/1/1 1:1:1')) 2011-01-01 01:01:01.000000
+from_unixtime(unix_timestamp('2011/1/1 1:1:1.123456')) 2011-01-01 01:01:01.123456
+from_unixtime(unix_timestamp(cast('2011/1/1 1:1:1.123456' as datetime(0)))) 2011-01-01 01:01:01
+from_unixtime(unix_timestamp(cast('2011/1/1 1:1:1.123456' as datetime(4)))) 2011-01-01 01:01:01.1234
+select sec_to_time(3020399.99999), sec_to_time(3020399.999999), sec_to_time(3020399.9999999);
+sec_to_time(3020399.99999) sec_to_time(3020399.999999) sec_to_time(3020399.9999999)
+838:59:59.99999 838:59:59.999999 838:59:59.999999
+select sec_to_time(-3020399.99999), sec_to_time(-3020399.999999), sec_to_time(-3020399.9999999);
+sec_to_time(-3020399.99999) sec_to_time(-3020399.999999) sec_to_time(-3020399.9999999)
+-838:59:59.99999 -838:59:59.999999 -838:59:59.999999
+select 20010101000203.000000004 + interval 1 day;
+20010101000203.000000004 + interval 1 day
+2001-01-02 00:02:03.000000
+select 20010101000203.4 + interval 1 day;
+20010101000203.4 + interval 1 day
+2001-01-02 00:02:03.4
+set @a=cast('2011-01-02 12:13:14' as datetime);
+select @a + interval 1 minute;
+@a + interval 1 minute
+2011-01-02 12:14:14
+select @a + interval 10 microsecond;
+@a + interval 10 microsecond
+2011-01-02 12:13:14.000010
+select @a + interval 10 microsecond + interval 999990 microsecond;
+@a + interval 10 microsecond + interval 999990 microsecond
+2011-01-02 12:13:15.000000
+set @a='2011-01-02 12:13:14.123456';
+create table t1 select CAST(@a AS DATETIME) as dauto,
+CAST(@a AS DATETIME(0)) as d0,
+CAST(@a AS DATETIME(1)) as d1,
+CAST(@a AS DATETIME(2)) as d2,
+CAST(@a AS DATETIME(3)) as d3,
+CAST(@a AS DATETIME(4)) as d4,
+CAST(@a AS DATETIME(5)) as d5,
+CAST(@a AS DATETIME(6)) as d6,
+CAST(@a AS TIME) as tauto,
+CAST(@a AS TIME(0)) as t0,
+CAST(@a AS TIME(1)) as t1,
+CAST(@a AS TIME(2)) as t2,
+CAST(@a AS TIME(3)) as t3,
+CAST(@a AS TIME(4)) as t4,
+CAST(@a AS TIME(5)) as t5,
+CAST(@a AS TIME(6)) as t6;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `dauto` datetime DEFAULT NULL,
+ `d0` datetime DEFAULT NULL,
+ `d1` datetime(1) DEFAULT NULL,
+ `d2` datetime(2) DEFAULT NULL,
+ `d3` datetime(3) DEFAULT NULL,
+ `d4` datetime(4) DEFAULT NULL,
+ `d5` datetime(5) DEFAULT NULL,
+ `d6` datetime(6) DEFAULT NULL,
+ `tauto` time DEFAULT NULL,
+ `t0` time DEFAULT NULL,
+ `t1` time(1) DEFAULT NULL,
+ `t2` time(2) DEFAULT NULL,
+ `t3` time(3) DEFAULT NULL,
+ `t4` time(4) DEFAULT NULL,
+ `t5` time(5) DEFAULT NULL,
+ `t6` time(6) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t1;
+dauto 2011-01-02 12:13:14
+d0 2011-01-02 12:13:14
+d1 2011-01-02 12:13:14.1
+d2 2011-01-02 12:13:14.12
+d3 2011-01-02 12:13:14.123
+d4 2011-01-02 12:13:14.1234
+d5 2011-01-02 12:13:14.12345
+d6 2011-01-02 12:13:14.123456
+tauto 12:13:14
+t0 12:13:14
+t1 12:13:14.1
+t2 12:13:14.12
+t3 12:13:14.123
+t4 12:13:14.1234
+t5 12:13:14.12345
+t6 12:13:14.123456
+drop table t1;
+explain extended select cast(cast(@a as datetime(4)) as time(0));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select cast(cast((@`a`) as datetime(4)) as time) AS `cast(cast(@a as datetime(4)) as time(0))`
+select cast(cast(@a as time(2)) as time(6));
+cast(cast(@a as time(2)) as time(6))
+12:13:14.120000
+select CAST(@a AS DATETIME(7));
+ERROR 42000: Too big precision 7 specified for '(@`a`)'. Maximum is 6.
+SELECT CONVERT_TZ('2011-01-02 12:00:00', '+00:00', '+03:00');
+CONVERT_TZ('2011-01-02 12:00:00', '+00:00', '+03:00')
+2011-01-02 15:00:00
+SELECT CONVERT_TZ('2011-01-02 12:00:00.123', '+00:00', '+03:00');
+CONVERT_TZ('2011-01-02 12:00:00.123', '+00:00', '+03:00')
+2011-01-02 15:00:00.123000
+SELECT CONVERT_TZ('2011-01-02 12:00:00.123456', '+00:00', '+03:00');
+CONVERT_TZ('2011-01-02 12:00:00.123456', '+00:00', '+03:00')
+2011-01-02 15:00:00.123456
+SELECT CONVERT_TZ(CAST('2010-10-10 10:10:10.123456' AS DATETIME(4)), '+00:00', '+03:00');
+CONVERT_TZ(CAST('2010-10-10 10:10:10.123456' AS DATETIME(4)), '+00:00', '+03:00')
+2010-10-10 13:10:10.1234
+create table t1 (a varchar(200));
+insert t1 values (now(6));
+select * from t1;
+a
+2011-01-01 01:01:01.123456
+drop table t1;
+create table t1 (f1 timestamp(6));
+insert into t1 values ('2002-07-15 21:00:00');
+select time(f1) from t1;
+time(f1)
+21:00:00.000000
+select time(f1) from t1 union all select time(f1 + interval 1 second) from t1;
+time(f1)
+21:00:00.000000
+21:00:01.000000
+alter table t1 modify f1 timestamp;
+select time(f1) from t1;
+time(f1)
+21:00:00
+select time(f1) from t1 union all select time(f1 + interval 1 second) from t1;
+time(f1)
+21:00:00
+21:00:01
+alter table t1 modify f1 varchar(100);
+select time(f1) from t1;
+time(f1)
+21:00:00
+select time(f1) from t1 union all select time(f1 + interval 1 second) from t1;
+time(f1)
+21:00:00.000000
+21:00:01.000000
+drop table t1;
diff --git a/mysql-test/r/func_timestamp.result b/mysql-test/r/func_timestamp.result
index 495fedea9e6..18fcbd947e7 100644
--- a/mysql-test/r/func_timestamp.result
+++ b/mysql-test/r/func_timestamp.result
@@ -7,7 +7,7 @@ SELECT CONCAT(Jahr,'-',Monat,'-',Tag,' ',Zeit) AS Date,
UNIX_TIMESTAMP(CONCAT(Jahr,'-',Monat,'-',Tag,' ',Zeit)) AS Unix
FROM t1;
Date Unix
-1998-9-16 09:26:00 905927160
-1998-9-16 09:26:00 905927160
+1998-9-16 09:26:00 905927160.000000
+1998-9-16 09:26:00 905927160.000000
drop table t1;
set time_zone= @@global.time_zone;
diff --git a/mysql-test/r/gis-precise.result b/mysql-test/r/gis-precise.result
new file mode 100644
index 00000000000..5f3c5988f1e
--- /dev/null
+++ b/mysql-test/r/gis-precise.result
@@ -0,0 +1,454 @@
+DROP TABLE IF EXISTS t1;
+select 1, ST_Intersects(GeomFromText('POLYGON((0 0,20 0,20 20,0 20,0 0))'), GeomFromText('POLYGON((10 10,30 10,30 30,10 30,10 10))'));
+1 ST_Intersects(GeomFromText('POLYGON((0 0,20 0,20 20,0 20,0 0))'), GeomFromText('POLYGON((10 10,30 10,30 30,10 30,10 10))'))
+1 1
+select 0, ST_Intersects(GeomFromText('POLYGON((0 0,20 10,10 30, 0 0))'), GeomFromText('POLYGON((10 40, 40 50, 20 70, 10 40))'));
+0 ST_Intersects(GeomFromText('POLYGON((0 0,20 10,10 30, 0 0))'), GeomFromText('POLYGON((10 40, 40 50, 20 70, 10 40))'))
+0 0
+select 1, ST_Intersects(GeomFromText('POLYGON((0 0,20 10,10 30, 0 0))'), GeomFromText('POINT(10 10)'));
+1 ST_Intersects(GeomFromText('POLYGON((0 0,20 10,10 30, 0 0))'), GeomFromText('POINT(10 10)'))
+1 1
+select 1, ST_Intersects(GeomFromText('POLYGON((0 0,20 10,10 30, 0 0))'), GeomFromText('POLYGON((10 10,30 20,20 40, 10 10))'));
+1 ST_Intersects(GeomFromText('POLYGON((0 0,20 10,10 30, 0 0))'), GeomFromText('POLYGON((10 10,30 20,20 40, 10 10))'))
+1 1
+select 0, ST_Within(GeomFromText('POLYGON((0 0,20 10,10 30, 0 0))'), GeomFromText('POLYGON((10 10,30 20,20 40, 10 10))'));
+0 ST_Within(GeomFromText('POLYGON((0 0,20 10,10 30, 0 0))'), GeomFromText('POLYGON((10 10,30 20,20 40, 10 10))'))
+0 0
+select 1, ST_Within(GeomFromText('POLYGON((1 1,20 10,10 30, 1 1))'), GeomFromText('POLYGON((0 0,30 5,10 40, 0 0))'));
+1 ST_Within(GeomFromText('POLYGON((1 1,20 10,10 30, 1 1))'), GeomFromText('POLYGON((0 0,30 5,10 40, 0 0))'))
+1 1
+create table t1 (g point);
+insert into t1 values
+(GeomFromText('POINT(2 2)')), (GeomFromText('POINT(2 4)')), (GeomFromText('POINT(2 6)')), (GeomFromText('POINT(2 8)')),
+(GeomFromText('POINT(4 2)')), (GeomFromText('POINT(4 4)')), (GeomFromText('POINT(4 6)')), (GeomFromText('POINT(4 8)')),
+(GeomFromText('POINT(6 2)')), (GeomFromText('POINT(6 4)')), (GeomFromText('POINT(6 6)')), (GeomFromText('POINT(6 8)')),
+(GeomFromText('POINT(8 2)')), (GeomFromText('POINT(8 4)')), (GeomFromText('POINT(8 6)')), (GeomFromText('POINT(8 8)'));
+select astext(g) from t1 where ST_Within(g, GeomFromText('POLYGON((5 1, 7 1, 7 7, 5 7, 3 3, 5 3, 5 1))'));
+astext(g)
+POINT(4 4)
+POINT(6 2)
+POINT(6 4)
+POINT(6 6)
+select 'Contains';
+Contains
+Contains
+select astext(g) from t1 where ST_Contains(GeomFromText('POLYGON((5 1, 7 1, 7 7, 5 7, 3 3, 5 3, 5 1))'), g);
+astext(g)
+POINT(4 4)
+POINT(6 2)
+POINT(6 4)
+POINT(6 6)
+select 'Intersects';
+Intersects
+Intersects
+select astext(g) from t1 where ST_Intersects(GeomFromText('POLYGON((5 1, 7 1, 7 7, 5 7, 3 3, 5 3, 5 1))'), g);
+astext(g)
+POINT(4 4)
+POINT(6 2)
+POINT(6 4)
+POINT(6 6)
+select 'Contains';
+Contains
+Contains
+select astext(g) from t1 where ST_Contains(GeomFromText('POLYGON((5 1, 7 1, 7 7, 5 7, 3 3, 5 3, 5 1))'), g);
+astext(g)
+POINT(4 4)
+POINT(6 2)
+POINT(6 4)
+POINT(6 6)
+select 'Contains2';
+Contains2
+Contains2
+select astext(g) from t1 where ST_Contains(GeomFromText('POLYGON((5 1, 7 1, 7 7, 5 7, 3 3, 5 3, 5 1), (5.01 3.01, 6 5, 9 5, 8 3, 5.01 3.01))'), g);
+astext(g)
+POINT(4 4)
+POINT(6 2)
+POINT(6 6)
+POINT(8 4)
+DROP TABLE t1;
+select 0, ST_Within(GeomFromText('LINESTRING(15 15, 50 50, 60 60)'), GeomFromText('POLYGON((10 10,30 20,20 40, 10 10))'));
+0 ST_Within(GeomFromText('LINESTRING(15 15, 50 50, 60 60)'), GeomFromText('POLYGON((10 10,30 20,20 40, 10 10))'))
+0 0
+select 1, ST_Within(GeomFromText('LINESTRING(15 15, 16 16)'), GeomFromText('POLYGON((10 10,30 20,20 40, 10 10))'));
+1 ST_Within(GeomFromText('LINESTRING(15 15, 16 16)'), GeomFromText('POLYGON((10 10,30 20,20 40, 10 10))'))
+1 1
+select 1, ST_Intersects(GeomFromText('LINESTRING(15 15, 50 50)'), GeomFromText('LINESTRING(50 15, 15 50)'));
+1 ST_Intersects(GeomFromText('LINESTRING(15 15, 50 50)'), GeomFromText('LINESTRING(50 15, 15 50)'))
+1 1
+select 0, ST_Intersects(GeomFromText('LINESTRING(15 15, 50 50)'), GeomFromText('LINESTRING(16 16, 51 51)'));
+0 ST_Intersects(GeomFromText('LINESTRING(15 15, 50 50)'), GeomFromText('LINESTRING(16 16, 51 51)'))
+0 1
+select 1, ST_Intersects(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('POLYGON((50 5, 55 10, 0 45, 50 5))'));
+1 ST_Intersects(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('POLYGON((50 5, 55 10, 0 45, 50 5))'))
+1 1
+select astext(ST_Union(geometryfromtext('point(1 1)'), geometryfromtext('polygon((0 0, 2 0, 1 2, 0 0))')));
+astext(ST_Union(geometryfromtext('point(1 1)'), geometryfromtext('polygon((0 0, 2 0, 1 2, 0 0))')))
+POLYGON((0 0,1 2,2 0,0 0))
+select astext(ST_Intersection(geometryfromtext('point(1 1)'), geometryfromtext('polygon((0 0, 2 0, 1 2, 0 0))')));
+astext(ST_Intersection(geometryfromtext('point(1 1)'), geometryfromtext('polygon((0 0, 2 0, 1 2, 0 0))')))
+POINT(1 1)
+select ST_Intersects(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('POLYGON((50 5, 55 10, 0 45, 50 5))'));
+ST_Intersects(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('POLYGON((50 5, 55 10, 0 45, 50 5))'))
+1
+select ST_contains(GeomFromText('MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)), ((6 6, 6 11, 11 11, 11 6, 6 6)))'), GeomFromText('POINT(5 10)'));
+ST_contains(GeomFromText('MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)), ((6 6, 6 11, 11 11, 11 6, 6 6)))'), GeomFromText('POINT(5 10)'))
+0
+select ST_Disjoint(GeomFromText('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'), GeomFromText('POLYGON((10 10, 10 15, 15 15, 15 10, 10 10))'));
+ST_Disjoint(GeomFromText('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'), GeomFromText('POLYGON((10 10, 10 15, 15 15, 15 10, 10 10))'))
+1
+select ST_Disjoint(GeomFromText('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'), GeomFromText('POLYGON((10 10, 10 4, 4 4, 4 10, 10 10))'));
+ST_Disjoint(GeomFromText('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'), GeomFromText('POLYGON((10 10, 10 4, 4 4, 4 10, 10 10))'))
+0
+select ST_Overlaps(GeomFromText('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'), GeomFromText('POLYGON((10 10, 10 4, 4 4, 4 10, 10 10))'));
+ST_Overlaps(GeomFromText('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'), GeomFromText('POLYGON((10 10, 10 4, 4 4, 4 10, 10 10))'))
+1
+select ST_Overlaps(GeomFromText('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'), GeomFromText('POLYGON((1 1, 1 4, 4 4, 4 1, 1 1))'));
+ST_Overlaps(GeomFromText('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'), GeomFromText('POLYGON((1 1, 1 4, 4 4, 4 1, 1 1))'))
+0
+select ST_DISTANCE(geomfromtext('polygon((0 0, 1 2, 2 1, 0 0))'), geomfromtext('polygon((2 2, 3 4, 4 3, 2 2))'));
+ST_DISTANCE(geomfromtext('polygon((0 0, 1 2, 2 1, 0 0))'), geomfromtext('polygon((2 2, 3 4, 4 3, 2 2))'))
+0.707106781186547
+select ST_DISTANCE(geomfromtext('polygon((0 0, 1 2, 2 1, 0 0))'), geomfromtext('linestring(0 1, 1 0)'));
+ST_DISTANCE(geomfromtext('polygon((0 0, 1 2, 2 1, 0 0))'), geomfromtext('linestring(0 1, 1 0)'))
+0
+select ST_DISTANCE(geomfromtext('polygon((0 0, 3 6, 6 3, 0 0))'), geomfromtext('polygon((2 2, 3 4, 4 3, 2 2))'));
+ST_DISTANCE(geomfromtext('polygon((0 0, 3 6, 6 3, 0 0))'), geomfromtext('polygon((2 2, 3 4, 4 3, 2 2))'))
+0
+select ST_DISTANCE(geomfromtext('polygon((0 0, 3 6, 6 3, 0 0),(2 2, 3 4, 4 3, 2 2))'), geomfromtext('point(3 3)'));
+ST_DISTANCE(geomfromtext('polygon((0 0, 3 6, 6 3, 0 0),(2 2, 3 4, 4 3, 2 2))'), geomfromtext('point(3 3)'))
+0.447213595499958
+select ST_DISTANCE(geomfromtext('linestring(0 0, 3 6, 6 3, 0 0)'), geomfromtext('polygon((2 2, 3 4, 4 3, 2 2))'));
+ST_DISTANCE(geomfromtext('linestring(0 0, 3 6, 6 3, 0 0)'), geomfromtext('polygon((2 2, 3 4, 4 3, 2 2))'))
+0.894427190999916
+select astext(ST_Intersection(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('POLYGON((50 5, 55 10, 0 45, 50 5))')));
+astext(ST_Intersection(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('POLYGON((50 5, 55 10, 0 45, 50 5))')))
+POLYGON((26.4705882352941 23.8235294117647,21.9512195121951 27.4390243902439,23.855421686747 29.8192771084337,29.2899408284024 26.3609467455621,26.4705882352941 23.8235294117647))
+select astext(ST_Intersection(GeomFromText('LINESTRING(0 0, 50 45, 40 50, 0 0)'), GeomFromText('LINESTRING(50 5, 55 10, 0 45, 50 5)')));
+astext(ST_Intersection(GeomFromText('LINESTRING(0 0, 50 45, 40 50, 0 0)'), GeomFromText('LINESTRING(50 5, 55 10, 0 45, 50 5)')))
+MULTIPOINT(26.4705882352941 23.8235294117647,29.2899408284024 26.3609467455621,21.9512195121951 27.4390243902439,23.855421686747 29.8192771084337)
+select astext(ST_Intersection(GeomFromText('LINESTRING(0 0, 50 45, 40 50)'), GeomFromText('LINESTRING(50 5, 55 10, 0 45)')));
+astext(ST_Intersection(GeomFromText('LINESTRING(0 0, 50 45, 40 50)'), GeomFromText('LINESTRING(50 5, 55 10, 0 45)')))
+POINT(29.2899408284024 26.3609467455621)
+select astext(ST_Intersection(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('POINT(20 20)')));
+astext(ST_Intersection(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('POINT(20 20)')))
+POINT(20 20)
+select astext(ST_Intersection(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('LINESTRING(-10 -10, 200 200)')));
+astext(ST_Intersection(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('LINESTRING(-10 -10, 200 200)')))
+LINESTRING(0 0,46.6666666666667 46.6666666666667)
+select astext(ST_Intersection(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('LINESTRING(-10 -10, 200 200, 199 201, -11 -9)')));
+astext(ST_Intersection(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('LINESTRING(-10 -10, 200 200, 199 201, -11 -9)')))
+MULTILINESTRING((0 0,46.6666666666667 46.6666666666667),(8 10,45.3333333333333 47.3333333333333))
+select astext(ST_UNION(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('LINESTRING(-10 -10, 200 200, 199 201, -11 -9)')));
+astext(ST_UNION(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('LINESTRING(-10 -10, 200 200, 199 201, -11 -9)')))
+GEOMETRYCOLLECTION(LINESTRING(-10 -10,0 0),LINESTRING(-11 -9,8 10),POLYGON((0 0,40 50,50 45,0 0)),LINESTRING(46.6666666666667 46.6666666666667,200 200,199 201,45.3333333333333 47.3333333333333))
+select astext(ST_intersection(geomfromtext('polygon((0 0, 1 0, 0 1, 0 0))'), geomfromtext('polygon((0 0, 1 1, 0 2, 0 0))')));
+astext(ST_intersection(geomfromtext('polygon((0 0, 1 0, 0 1, 0 0))'), geomfromtext('polygon((0 0, 1 1, 0 2, 0 0))')))
+POLYGON((0 0,0 1,0.5 0.5,0 0))
+select astext(ST_symdifference(geomfromtext('polygon((0 0, 1 0, 0 1, 0 0))'), geomfromtext('polygon((0 0, 1 1, 0 2, 0 0))')));
+astext(ST_symdifference(geomfromtext('polygon((0 0, 1 0, 0 1, 0 0))'), geomfromtext('polygon((0 0, 1 1, 0 2, 0 0))')))
+MULTIPOLYGON(((0 0,0.5 0.5,1 0,0 0)),((0.5 0.5,0 1,0 2,1 1,0.5 0.5)))
+select astext(ST_UNION(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('LINESTRING(-10 -10, 200 200, 199 201, -11 -9)')));
+astext(ST_UNION(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('LINESTRING(-10 -10, 200 200, 199 201, -11 -9)')))
+GEOMETRYCOLLECTION(LINESTRING(-10 -10,0 0),LINESTRING(-11 -9,8 10),POLYGON((0 0,40 50,50 45,0 0)),LINESTRING(46.6666666666667 46.6666666666667,200 200,199 201,45.3333333333333 47.3333333333333))
+select astext(ST_buffer(geometryfromtext('point(1 1)'), 1));
+astext(ST_buffer(geometryfromtext('point(1 1)'), 1))
+POLYGON((1 0,0.950932325672582 0.00120454379482759,0.901982859670439 0.00481527332780318,0.853269525544638 0.010823490035219,0.804909677983872 0.0192147195967696,0.757019820096736 0.029968746805456,0.709715322745538 0.0430596642677911,0.66311014660778 0.0584559348169792,0.61731656763491 0.0761204674887133,0.572444906569718 0.0960107068765567,0.528603263174002 0.118078735651645,0.485897255806778 0.142271389999728,0.444429766980398 0.168530387697455,0.404300695507567 0.196792468519355,0.365606715836355 0.226989546637263,0.328441045152982 0.259048874645041,0.292893218813453 0.292893218813453,0.259048874645041 0.328441045152982,0.226989546637263 0.365606715836355,0.196792468519355 0.404300695507567,0.168530387697455 0.444429766980398,0.142271389999728 0.485897255806778,0.118078735651645 0.528603263174002,0.0960107068765567 0.572444906569718,0.0761204674887133 0.61731656763491,0.0584559348169792 0.66311014660778,0.0430596642677911 0.709715322745538,0.029968746805456 0.757019820096736,0.0192147195967696 0.804909677983872,0.010823490035219 0.853269525544638,0.00481527332780318 0.901982859670439,0.00120454379482759 0.950932325672582,0 1,0.00481527332780318 1.09801714032956,0.010823490035219 1.14673047445536,0.0192147195967696 1.19509032201613,0.029968746805456 1.24298017990326,0.0430596642677911 1.29028467725446,0.0584559348169792 1.33688985339222,0.0761204674887133 1.38268343236509,0.0960107068765567 1.42755509343028,0.118078735651645 1.471396736826,0.142271389999728 1.51410274419322,0.168530387697455 1.5555702330196,0.196792468519355 1.59569930449243,0.226989546637263 1.63439328416365,0.259048874645041 1.67155895484702,0.292893218813453 1.70710678118655,0.328441045152982 1.74095112535496,0.365606715836355 1.77301045336274,0.404300695507567 1.80320753148064,0.444429766980398 1.83146961230255,0.485897255806778 1.85772861000027,0.528603263174002 1.88192126434835,0.572444906569718 1.90398929312344,0.61731656763491 1.92387953251129,0.66311014660778 1.94154406518302,0.709715322745538 1.95694033573221,0.757019820096736 1.97003125319454,0.804909677983872 1.98078528040323,0.853269525544638 1.98917650996478,0.901982859670439 1.9951847266722,0.950932325672582 1.99879545620517,1 2,1.04906767432742 1.99879545620517,1.09801714032956 1.9951847266722,1.14673047445536 1.98917650996478,1.19509032201613 1.98078528040323,1.24298017990326 1.97003125319454,1.29028467725446 1.95694033573221,1.33688985339222 1.94154406518302,1.38268343236509 1.92387953251129,1.42755509343028 1.90398929312344,1.471396736826 1.88192126434835,1.51410274419322 1.85772861000027,1.5555702330196 1.83146961230255,1.59569930449243 1.80320753148064,1.63439328416365 1.77301045336274,1.67155895484702 1.74095112535496,1.70710678118655 1.70710678118655,1.74095112535496 1.67155895484702,1.77301045336274 1.63439328416365,1.80320753148064 1.59569930449243,1.83146961230255 1.5555702330196,1.85772861000027 1.51410274419322,1.88192126434835 1.471396736826,1.90398929312344 1.42755509343028,1.92387953251129 1.38268343236509,1.94154406518302 1.33688985339222,1.95694033573221 1.29028467725446,1.97003125319454 1.24298017990326,1.98078528040323 1.19509032201613,1.98917650996478 1.14673047445536,1.9951847266722 1.09801714032956,1.99879545620517 1.04906767432742,2 1,1.9951847266722 0.901982859670439,1.98917650996478 0.853269525544638,1.98078528040323 0.804909677983872,1.97003125319454 0.757019820096736,1.95694033573221 0.709715322745538,1.94154406518302 0.66311014660778,1.92387953251129 0.61731656763491,1.90398929312344 0.572444906569718,1.88192126434835 0.528603263174002,1.85772861000027 0.485897255806778,1.83146961230255 0.444429766980398,1.80320753148064 0.404300695507567,1.77301045336274 0.365606715836355,1.74095112535496 0.328441045152982,1.70710678118655 0.292893218813453,1.67155895484702 0.259048874645041,1.63439328416365 0.226989546637263,1.59569930449243 0.196792468519355,1.5555702330196 0.168530387697455,1.51410274419322 0.142271389999728,1.471396736826 0.118078735651645,1.42755509343028 0.0960107068765567,1.38268343236509 0.0761204674887133,1.33688985339222 0.0584559348169792,1.29028467725446 0.0430596642677911,1.24298017990326 0.029968746805456,1.19509032201613 0.0192147195967696,1.14673047445536 0.010823490035219,1.09801714032956 0.00481527332780318,1.04906767432742 0.00120454379482759,1 0))
+create table t1(geom geometrycollection);
+insert into t1 values (geomfromtext('POLYGON((0 0, 10 10, 0 8, 0 0))'));
+insert into t1 values (geomfromtext('POLYGON((1 1, 10 10, 0 8, 1 1))'));
+select astext(geom), area(geom),area(ST_buffer(geom,2)) from t1;
+astext(geom) area(geom) area(ST_buffer(geom,2))
+POLYGON((0 0,10 10,0 8,0 0)) 40 117.241676395915
+POLYGON((1 1,10 10,0 8,1 1)) 36 108.555395892665
+select astext(ST_buffer(geom,2)) from t1;
+astext(ST_buffer(geom,2))
+POLYGON((0 -2,-0.098135348654836 -1.99759091241034,-0.196034280659121 -1.99036945334439,-0.293460948910724 -1.97835301992956,-0.390180644032257 -1.96157056080646,-0.485960359806528 -1.94006250638909,-0.580569354508925 -1.91388067146442,-0.67377970678444 -1.88308813036604,-0.76536686473018 -1.84775906502257,-0.855110186860564 -1.80797858624689,-0.942793473651995 -1.76384252869671,-1.02820548838644 -1.71545722000054,-1.1111404660392 -1.66293922460509,-1.19139860898487 -1.60641506296129,-1.26878656832729 -1.54602090672547,-1.34311790969404 -1.48190225070992,-1.41421356237309 -1.41421356237309,-1.48190225070992 -1.34311790969404,-1.54602090672547 -1.26878656832729,-1.60641506296129 -1.19139860898487,-1.66293922460509 -1.1111404660392,-1.71545722000054 -1.02820548838644,-1.76384252869671 -0.942793473651995,-1.80797858624689 -0.855110186860564,-1.84775906502257 -0.76536686473018,-1.88308813036604 -0.67377970678444,-1.91388067146442 -0.580569354508925,-1.94006250638909 -0.485960359806528,-1.96157056080646 -0.390180644032257,-1.97835301992956 -0.293460948910724,-1.99036945334439 -0.196034280659121,-1.99759091241034 -0.098135348654836,-2 0,-2 8,-1.99769247099325 8.09604577729856,-1.99057342000233 8.19395220952653,-1.97865890328899 8.29139139389354,-1.96197762396757 8.38812859086979,-1.94056976870107 8.48393075207458,-1.91448691088793 8.5785670817103,-1.88379188641722 8.67180959256969,-1.84855864229144 8.76343365527701,-1.80887205848177 8.85321853943987,-1.76482774344474 8.94094794540811,-1.7165318037931 9.02641052535855,-1.66410058867569 9.10940039245046,-1.60766040948216 9.18971761682496,-1.54734723554777 9.26716870725357,-1.48330636659133 9.34156707727553,-1.41569208267549 9.41273349470094,-1.34466727253249 9.48049651339678,-1.27040304115102 9.54469288631567,-1.19307829756926 9.6051679587723,-1.11287932386733 9.66177604102015,-1.02999932639749 9.71438075923078,-0.944637970333077 9.76285538403041,-0.857000898657614 9.80708313580201,-0.767299236752872 9.84695746601768,-0.675749083779317 9.88238231392335,-0.582570992074307 9.91327233795755,-0.487989435822199 9.93955312134675,-0.392232270276368 9.96116135138184,9.60776772972363 11.9611613513818,9.60981935596774 11.9615705608065,9.70653905108928 11.9783530199296,9.80396571934088 11.9903694533444,9.90186465134516 11.9975909124103,10 12,10.0981353486548 11.9975909124103,10.1960342806591 11.9903694533444,10.2934609489107 11.9783530199296,10.3901806440323 11.9615705608065,10.4859603598065 11.9400625063891,10.5805693545089 11.9138806714644,10.6737797067844 11.883088130366,10.7653668647302 11.8477590650226,10.8551101868606 11.8079785862469,10.942793473652 11.7638425286967,11.0282054883864 11.7154572200005,11.1111404660392 11.6629392246051,11.1913986089849 11.6064150629613,11.2687865683273 11.5460209067255,11.343117909694 11.4819022507099,11.4142135623731 11.4142135623731,11.4819022507099 11.343117909694,11.5460209067255 11.2687865683273,11.6064150629613 11.1913986089849,11.6629392246051 11.1111404660392,11.7154572200005 11.0282054883864,11.7638425286967 10.942793473652,11.8079785862469 10.8551101868606,11.8477590650226 10.7653668647302,11.883088130366 10.6737797067844,11.9138806714644 10.5805693545089,11.9400625063891 10.4859603598065,11.9615705608065 10.3901806440323,11.9783530199296 10.2934609489107,11.9903694533444 10.1960342806591,11.9975909124103 10.0981353486548,12 10,11.9975909124103 9.90186465134516,11.9903694533444 9.80396571934088,11.9783530199296 9.70653905108928,11.9615705608065 9.60981935596774,11.9400625063891 9.51403964019347,11.9138806714644 9.41943064549108,11.883088130366 9.32622029321556,11.8477590650226 9.23463313526982,11.8079785862469 9.14488981313944,11.7638425286967 9.057206526348,11.7154572200005 8.97179451161356,11.6629392246051 8.8888595339608,11.6064150629613 8.80860139101513,11.5460209067255 8.73121343167271,11.4819022507099 8.65688209030596,11.4142135623731 8.5857864376269,1.41421356237309 -1.41421356237309,1.34311790969404 -1.48190225070992,1.26878656832729 -1.54602090672547,1.19139860898487 -1.60641506296129,1.1111404660392 -1.66293922460509,1.02820548838644 -1.71545722000054,0.942793473651995 -1.76384252869671,0.855110186860564 -1.80797858624689,0.76536686473018 -1.84775906502257,0.67377970678444 -1.88308813036604,0.580569354508925 -1.91388067146442,0.485960359806528 -1.94006250638909,0.390180644032257 -1.96157056080646,0.293460948910724 -1.97835301992956,0.196034280659121 -1.99036945334439,0.098135348654836 -1.99759091241034,0 -2))
+POLYGON((0.989269849411119 -0.999971215759952,0.891148838068309 -0.997035659307595,0.793290058708828 -0.989289069032301,0.69592926170357 -0.976750107148565,0.599300997740319 -0.959448981113848,0.503638052770599 -0.937427370856167,0.409170887207927 -0.910738328363497,0.316127080728489 -0.879446149876889,0.22473078401177 -0.843626220995187,0.135202178741929 -0.803364835064523,0.0477569471708416 -0.758758985290084,-0.0373942474793394 -0.709916131070988,-0.120046268522338 -0.656953939121177,-0.2 -0.6,-0.277062826370076 -0.539191520735374,-0.351049096533933 -0.474674994280042,-0.421780571086316 -0.406605846597216,-0.489086851709682 -0.335148062225815,-0.552805791678675 -0.260473789227354,-0.61278388648579 -0.182762924466179,-0.668876643647177 -0.102202680222169,-0.720948930797688 -0.0189871331799512,-0.768875301236584 0.0666832431188291,-0.812540296139623 0.154602061233829,-0.851838722709481 0.244557517031431,-0.886675907594418 0.33633289993945,-0.916967924964667 0.429707115021888,-0.942641798697117 0.524455215615996,-0.963635678181181 0.620348945248487,-0.979898987322333 0.717157287525381,-1.97989898732233 7.71715728752538,-1.99016330891247 7.8018838627003,-1.99748716815206 7.89977518736424,-1.99999890584435 7.99790796238047,-1.99769247099325 8.09604577729856,-1.99057342000233 8.19395220952653,-1.97865890328899 8.29139139389354,-1.96197762396757 8.38812859086979,-1.94056976870107 8.48393075207458,-1.91448691088793 8.5785670817103,-1.88379188641722 8.67180959256969,-1.84855864229144 8.76343365527701,-1.80887205848177 8.85321853943987,-1.76482774344474 8.94094794540811,-1.7165318037931 9.02641052535855,-1.66410058867569 9.10940039245046,-1.60766040948216 9.18971761682496,-1.54734723554777 9.26716870725357,-1.48330636659133 9.34156707727553,-1.41569208267549 9.41273349470094,-1.34466727253249 9.48049651339678,-1.27040304115102 9.54469288631567,-1.19307829756926 9.6051679587723,-1.11287932386733 9.66177604102015,-1.02999932639749 9.71438075923078,-0.944637970333077 9.76285538403041,-0.857000898657614 9.80708313580201,-0.767299236752872 9.84695746601768,-0.675749083779317 9.88238231392335,-0.582570992074307 9.91327233795755,-0.487989435822199 9.93955312134675,-0.392232270276368 9.96116135138184,9.60776772972363 11.9611613513818,9.60981935596774 11.9615705608065,9.70653905108928 11.9783530199296,9.80396571934088 11.9903694533444,9.90186465134516 11.9975909124103,10 12,10.0981353486548 11.9975909124103,10.1960342806591 11.9903694533444,10.2934609489107 11.9783530199296,10.3901806440323 11.9615705608065,10.4859603598065 11.9400625063891,10.5805693545089 11.9138806714644,10.6737797067844 11.883088130366,10.7653668647302 11.8477590650226,10.8551101868606 11.8079785862469,10.942793473652 11.7638425286967,11.0282054883864 11.7154572200005,11.1111404660392 11.6629392246051,11.1913986089849 11.6064150629613,11.2687865683273 11.5460209067255,11.343117909694 11.4819022507099,11.4142135623731 11.4142135623731,11.4819022507099 11.343117909694,11.5460209067255 11.2687865683273,11.6064150629613 11.1913986089849,11.6629392246051 11.1111404660392,11.7154572200005 11.0282054883864,11.7638425286967 10.942793473652,11.8079785862469 10.8551101868606,11.8477590650226 10.7653668647302,11.883088130366 10.6737797067844,11.9138806714644 10.5805693545089,11.9400625063891 10.4859603598065,11.9615705608065 10.3901806440323,11.9783530199296 10.2934609489107,11.9903694533444 10.1960342806591,11.9975909124103 10.0981353486548,12 10,11.9975909124103 9.90186465134516,11.9903694533444 9.80396571934088,11.9783530199296 9.70653905108928,11.9615705608065 9.60981935596774,11.9400625063891 9.51403964019347,11.9138806714644 9.41943064549108,11.883088130366 9.32622029321556,11.8477590650226 9.23463313526982,11.8079785862469 9.14488981313944,11.7638425286967 9.057206526348,11.7154572200005 8.97179451161356,11.6629392246051 8.8888595339608,11.6064150629613 8.80860139101513,11.5460209067255 8.73121343167271,11.4819022507099 8.65688209030596,11.4142135623731 8.5857864376269,2.41421356237309 -0.414213562373095,2.40660584659722 -0.421780571086316,2.33514806222581 -0.489086851709682,2.26047378922735 -0.552805791678675,2.18276292446618 -0.61278388648579,2.10220268022217 -0.668876643647177,2.01898713317995 -0.720948930797688,1.93331675688117 -0.768875301236584,1.84539793876617 -0.812540296139623,1.75544248296857 -0.851838722709481,1.66366710006055 -0.886675907594418,1.57029288497811 -0.916967924964667,1.475544784384 -0.942641798697117,1.37965105475151 -0.963635678181181,1.28284271247462 -0.979898987322333,1.18535297732928 -0.991392546384357,1.08741671062655 -0.998088666376754,0.989269849411119 -0.999971215759952))
+set @geom=geomfromtext('LINESTRING(2 1, 4 2, 2 3, 2 5)');
+set @buff=ST_buffer(@geom,1);
+select astext(@buff);
+astext(@buff)
+POLYGON((2.02185940085665 0.000238945250322198,1.97277712041129 0.000370611262904941,1.92376042226731 0.00291047203014849,1.87492739194389 0.0078524088049996,1.82639567248833 0.015184516028905,1.7782821810637 0.0248891300133454,1.73070282728507 0.0369428714932084,1.68377223398316 0.0513167019494863,1.63760346106787 0.0679759935656108,1.59230773315705 0.086880612648897,1.54799417162668 0.107985016316124,1.50476953172789 0.131238362210331,1.46273794540424 0.156584630984506,1.42200067042871 0.1839627612571,1.38265584646488 0.213306796714246,1.34479825863987 0.244546045004294,1.3085191091987 0.277605248041878,1.27390579779004 0.312404763311236,1.24104171091284 0.348860755732007,1.21000602103095 0.386885399625282,1.1808734958397 0.426387090293356,1.15371431814397 0.467270664703471,1.12859391678171 0.509437630743893,1.10557280900008 0.552786404500042,1.08470645466414 0.597212554979035,1.06604512264916 0.642609055693097,1.0496337697385 0.688866542495745,1.0355119323188 0.735873577049592,1.02371363113331 0.783516915291068,1.01426728932301 0.831681780245288,1.00719566395272 0.880252138533831,1.00251579118736 0.929110979909321,1.00023894525032 0.978140599143353,1.0003706112629 1.02722287958871,1.00291047203015 1.07623957773269,1.007852408805 1.12507260805611,1.01518451602891 1.17360432751167,1.02488913001335 1.2217178189363,1.03694287149321 1.26929717271493,1.05131670194949 1.31622776601684,1.06797599356561 1.36239653893213,1.0868806126489 1.40769226684295,1.10798501631612 1.45200582837332,1.13123836221033 1.49523046827211,1.15658463098451 1.53726205459576,1.1839627612571 1.57799932957129,1.21330679671425 1.61734415353512,1.24454604500429 1.65520174136013,1.27760524804188 1.6914808908013,1.31240476331124 1.72609420220996,1.34886075573201 1.75895828908716,1.38688539962528 1.78999397896905,1.42638709029336 1.8191265041603,1.46727066470347 1.84628568185603,1.50943763074389 1.87140608321829,1.55278640450004 1.89442719099992,1.76393202250021 2,1.55278640450004 2.10557280900008,1.528603263174 2.11807873565165,1.48589725580678 2.14227138999973,1.4444297669804 2.16853038769745,1.40430069550757 2.19679246851936,1.36560671583635 2.22698954663726,1.32844104515298 2.25904887464504,1.29289321881345 2.29289321881345,1.25904887464504 2.32844104515298,1.22698954663726 2.36560671583635,1.19679246851936 2.40430069550757,1.16853038769745 2.4444297669804,1.14227138999973 2.48589725580678,1.11807873565165 2.528603263174,1.09601070687656 2.57244490656972,1.07612046748871 2.61731656763491,1.05845593481698 2.66311014660778,1.04305966426779 2.70971532274554,1.02996874680546 2.75701982009674,1.01921471959677 2.80490967798387,1.01082349003522 2.85326952554464,1.0048152733278 2.90198285967044,1.00120454379483 2.95093232567258,1 3,1 5,1.0048152733278 5.09801714032956,1.01082349003522 5.14673047445536,1.01921471959677 5.19509032201613,1.02996874680546 5.24298017990326,1.04305966426779 5.29028467725446,1.05845593481698 5.33688985339222,1.07612046748871 5.38268343236509,1.09601070687656 5.42755509343028,1.11807873565165 5.471396736826,1.14227138999973 5.51410274419322,1.16853038769745 5.5555702330196,1.19679246851936 5.59569930449243,1.22698954663726 5.63439328416365,1.25904887464504 5.67155895484702,1.29289321881345 5.70710678118655,1.32844104515298 5.74095112535496,1.36560671583635 5.77301045336274,1.40430069550757 5.80320753148064,1.4444297669804 5.83146961230254,1.48589725580678 5.85772861000027,1.528603263174 5.88192126434835,1.57244490656972 5.90398929312344,1.61731656763491 5.92387953251129,1.66311014660778 5.94154406518302,1.70971532274554 5.95694033573221,1.75701982009674 5.97003125319454,1.80490967798387 5.98078528040323,1.85326952554464 5.98917650996478,1.90198285967044 5.9951847266722,1.95093232567258 5.99879545620517,2 6,2.04906767432742 5.99879545620517,2.09801714032956 5.9951847266722,2.14673047445536 5.98917650996478,2.19509032201613 5.98078528040323,2.24298017990326 5.97003125319454,2.29028467725446 5.95694033573221,2.33688985339222 5.94154406518302,2.38268343236509 5.92387953251129,2.42755509343028 5.90398929312344,2.471396736826 5.88192126434835,2.51410274419322 5.85772861000027,2.5555702330196 5.83146961230254,2.59569930449243 5.80320753148064,2.63439328416365 5.77301045336274,2.67155895484702 5.74095112535496,2.70710678118655 5.70710678118655,2.74095112535496 5.67155895484702,2.77301045336274 5.63439328416365,2.80320753148064 5.59569930449243,2.83146961230255 5.5555702330196,2.85772861000027 5.51410274419322,2.88192126434835 5.471396736826,2.90398929312344 5.42755509343028,2.92387953251129 5.38268343236509,2.94154406518302 5.33688985339222,2.95694033573221 5.29028467725446,2.97003125319454 5.24298017990326,2.98078528040323 5.19509032201613,2.98917650996478 5.14673047445536,2.9951847266722 5.09801714032956,2.99879545620517 5.04906767432742,3 5,3 3.61803398874989,4.44721359549996 2.89442719099992,4.45200582837332 2.89201498368388,4.49523046827211 2.86876163778967,4.53726205459576 2.84341536901549,4.57799932957129 2.8160372387429,4.61734415353512 2.78669320328575,4.65520174136013 2.75545395499571,4.6914808908013 2.72239475195812,4.72609420220996 2.68759523668876,4.75895828908716 2.65113924426799,4.78999397896905 2.61311460037472,4.8191265041603 2.57361290970664,4.84628568185602 2.53272933529653,4.87140608321829 2.49056236925611,4.89442719099992 2.44721359549996,4.91529354533586 2.40278744502096,4.93395487735084 2.3573909443069,4.9503662302615 2.31113345750426,4.9644880676812 2.26412642295041,4.97628636886669 2.21648308470893,4.98573271067699 2.16831821975471,4.99280433604728 2.11974786146617,4.99748420881264 2.07088902009068,4.99976105474968 2.02185940085665,4.99962938873709 1.97277712041129,4.99708952796985 1.92376042226731,4.992147591195 1.87492739194389,4.9848154839711 1.82639567248833,4.97511086998665 1.7782821810637,4.96305712850679 1.73070282728507,4.94868329805051 1.68377223398316,4.93202400643439 1.63760346106787,4.9131193873511 1.59230773315705,4.89201498368388 1.54799417162668,4.86876163778967 1.50476953172789,4.84341536901549 1.46273794540424,4.8160372387429 1.42200067042871,4.78669320328575 1.38265584646488,4.75545395499571 1.34479825863987,4.72239475195812 1.3085191091987,4.68759523668876 1.27390579779004,4.65113924426799 1.24104171091284,4.61311460037472 1.21000602103095,4.57361290970664 1.1808734958397,4.53272933529653 1.15371431814397,4.49056236925611 1.12859391678171,4.44721359549996 1.10557280900008,2.44721359549996 0.105572809000084,2.3573909443069 0.0660451226491613,2.31113345750426 0.0496337697385035,2.26412642295041 0.0355119323187965,2.21648308470893 0.0237136311333106,2.16831821975471 0.014267289323011,2.11974786146617 0.00719566395272053,2.07088902009068 0.00251579118735756,2.02185940085665 0.000238945250322198))
+DROP TABLE t1;
+select st_touches(geomfromtext('point(0 0)'), geomfromtext('point(1 1)'));
+st_touches(geomfromtext('point(0 0)'), geomfromtext('point(1 1)'))
+0
+select st_touches(geomfromtext('point(1 1)'), geomfromtext('point(1 1)'));
+st_touches(geomfromtext('point(1 1)'), geomfromtext('point(1 1)'))
+1
+select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('point(1 1)'));
+st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('point(1 1)'))
+1
+select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('point(1 0)'));
+st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('point(1 0)'))
+0
+select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('point(1 2)'));
+st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('point(1 2)'))
+0
+select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1.2, 1 0, 2 0, 1 1.2))'));
+st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1.2, 1 0, 2 0, 1 1.2))'))
+1
+select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1, 1 0, 2 0, 1 1))'));
+st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1, 1 0, 2 0, 1 1))'))
+1
+SELECT ST_Equals(PolyFromText('POLYGON((67 13, 67 18, 67 18, 59 18, 59 13, 67 13) )'),PolyFromText('POLYGON((67 13, 67 18, 59 19, 59 13, 59 13, 67 13) )')) as result;
+result
+0
+SELECT ST_Equals(PolyFromText('POLYGON((67 13, 67 18, 67 18, 59 18, 59 13, 67 13) )'),PolyFromText('POLYGON((67 13, 67 18, 59 18, 59 13, 59 13, 67 13) )')) as result;
+result
+1
+SELECT ST_Equals(PointFromText('POINT (12 13)'),PointFromText('POINT (12 13)')) as result;
+result
+1
+SELECT astext(ST_UNION (
+PolyFromText('POLYGON(( 2 2 ,3 2,2 7,2 2),( 0 0,8 2,1 9,0 0))'),
+ExteriorRing( Envelope( MultiLineStringFromText('MULTILINESTRING((3 4,5 3),(3 0,0 5))')))));
+astext(ST_UNION (
+PolyFromText('POLYGON(( 2 2 ,3 2,2 7,2 2),( 0 0,8 2,1 9,0 0))'),
+ExteriorRing( Envelope( MultiLineStringFromText('MULTILINESTRING((3 4,5 3),(3 0,0 5))')))))
+GEOMETRYCOLLECTION(POLYGON((0 0,1 9,8 2,0 0),(2 2,2 7,3 2,2 2)),LINESTRING(0.555555555555556 5,0 5,0 0,5 0,5 1.25),LINESTRING(2 5,2.4 5))
+SELECT astext(ST_BUFFER(LineStringFromText('LINESTRING(0 0,1 1)'),0));
+astext(ST_BUFFER(LineStringFromText('LINESTRING(0 0,1 1)'),0))
+LINESTRING(0 0,1 1)
+SELECT Round(ST_Area(ST_BUFFER(MultipointFromText('MULTIPOINT(7 7,3 7,7 2,7 4 ,7 7)'), 3)), 5);
+Round(ST_Area(ST_BUFFER(MultipointFromText('MULTIPOINT(7 7,3 7,7 2,7 4 ,7 7)'), 3)), 5)
+78.68426
+SELECT ST_INTERSECTION(NULL, NULL);
+ST_INTERSECTION(NULL, NULL)
+NULL
+SELECT ASTEXT(ST_INTERSECTION(
+MULTIPOLYGONFROMTEXT('MULTIPOLYGON(((2 2,2 8,8 8,8 2,2 2),(4 4,4 6,6 6,6 4,4 4)),
+ ((0 5,3 5,3 0,0 0,0 1,2 1,2 2,0 2,0 5), (1 3,2 3,2 4,1 4,1 3)),
+ ((2 2,5 2,4 4,2 8,2 2)))'),
+MULTIPOLYGONFROMTEXT('MULTIPOLYGON(((3 5,2 4,2 5,3 5)),
+ ((2 2,9 2,0 2,2 6,2 2)),
+ ((2 2,2 8,8 8,8 2,2 2), (4 4,4 6,6 6,6 4,4 4)),
+ ((9 9,6 8,7 0,9 9)))')));
+ASTEXT(ST_INTERSECTION(
+MULTIPOLYGONFROMTEXT('MULTIPOLYGON(((2 2,2 8,8 8,8 2,2 2),(4 4,4 6,6 6,6 4,4 4)),
+ ((0 5,3 5,3 0,0 0,0 1,2 1,2 2,0 2,0 5), (1 3,2 3,2 4,1 4,1 3)),
+ ((2 2,5 2,4 4,2 8,2 2)))'),
+MULTIPOLY
+POLYGON((0 2,1 4,1 3,2 3,2 4,1 4,1.5 5,2 5,2 8,8 8,8 2,0 2),(4 4,4 6,6 6,6 4,4 4))
+SELECT ASTEXT(ST_UNION(
+MULTILINESTRINGFROMTEXT('MULTILINESTRING((6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
+ (8 2,1 3,9 0,4 4))'),
+MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 5,6 7,9 7,5 2,1 6,3 6))')));
+ASTEXT(ST_UNION(
+MULTILINESTRINGFROMTEXT('MULTILINESTRING((6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
+ (8 2,1 3,9 0,4 4))'),
+MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 5,6 7,9 7,5 2,1 6,3 6))')))
+MULTILINESTRING((3.59459459459459 2.02702702702703,4 0,4.75 0.75),(5 0,4.75 0.75),(5.36363636363636 1.36363636363636,9 0,6.17391304347826 2.26086956521739),(4.75 0.75,4.42857142857143 1.71428571428571),(4.75 0.75,5.36363636363636 1.36363636363636),(5.36363636363636 1.36363636363636,4.42857142857143 1.71428571428571),(5.36363636363636 1.36363636363636,6 2),(4.42857142857143 1.71428571428571,3.59459459459459 2.02702702702703),(4.42857142857143 1.71428571428571,4.15 2.55),(4.5 2.5,5 2,5.30769230769231 2.38461538461538),(8 2,6.17391304347826 2.26086956521739),(3.59459459459459 2.02702702702703,1 3,3.47058823529412 2.64705882352941),(3.59459459459459 2.02702702702703,3.47058823529412 2.64705882352941),(6.17391304347826 2.26086956521739,5.30769230769231 2.38461538461538),(6.17391304347826 2.26086956521739,5.58536585365854 2.73170731707317),(5.30769230769231 2.38461538461538,4.5 2.5),(5.30769230769231 2.38461538461538,5.58536585365854 2.73170731707317),(4.5 2.5,4.15 2.55),(4.5 2.5,4 3),(4.15 2.55,3.47058823529412 2.64705882352941),(4.15 2.55,4 3),(3.47058823529412 2.64705882352941,3.25 3.75),(5.58536585365854 2.73170731707317,4.76923076923077 3.38461538461538),(5.58536585365854 2.73170731707317,7.05405405405405 4.56756756756757),(4 3,3.25 3.75),(4 3,3.14285714285714 5.57142857142857),(4 3,4.76923076923077 3.38461538461538),(4.76923076923077 3.38461538461538,4 4),(4.76923076923077 3.38461538461538,6 4,4.875 5.875),(3.25 3.75,2 5),(3.25 3.75,3 5,3 5.5),(7.05405405405405 4.56756756756757,8 4,7.16 4.7),(7.05405405405405 4.56756756756757,4.875 5.875),(7.05405405405405 4.56756756756757,7.16 4.7),(7.16 4.7,5 6.5),(7.16 4.7,9 7,6 7,5 6.5),(2 5,1 6,3 6),(2 5,3 5.5),(3 5.5,3 6),(3 5.5,3.14285714285714 5.57142857142857),(3.14285714285714 5.57142857142857,3 6),(3.14285714285714 5.57142857142857,4.36363636363636 6.18181818181818),(4.875 5.875,4.36363636363636 6.18181818181818),(4.875 5.875,4.61538461538461 6.30769230769231),(3 6,2.66666666666667 7),(4.36363636363636 6.18181818181818,3 7,2.66666666666667 7),(4.36363636363636 6.18181818181818,4.61538461538461 6.30769230769231),(4.61538461538461 6.30769230769231,4 7.33333333333333),(4.61538461538461 6.30769230769231,5 6.5),(5 6.5,4 7.33333333333333),(2.18181818181818 8.45454545454546,0 7,2.66666666666667 7),(2.66666666666667 7,2.18181818181818 8.45454545454546),(4 7.33333333333333,2.44444444444444 8.62962962962963),(4 7.33333333333333,3 9,2.44444444444444 8.62962962962963),(2.18181818181818 8.45454545454546,2 9,2.44444444444444 8.62962962962963),(2.18181818181818 8.45454545454546,2.44444444444444 8.62962962962963))
+SELECT ST_NUMGEOMETRIES((ST_UNION(ST_UNION(
+MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 0,4 2,0 2,1 5,0 3,7 0,8 5,5 8),
+ (6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
+ (7 8,3 1,0 9,6 0,4 8),
+ (9 3,0 4,5 9,6 4),
+ (8 2,1 3,9 0,4 4))'),
+MULTILINESTRINGFROMTEXT('MULTILINESTRING((6 0,9 3,2 5,3 6,3 2),
+ (2 5,6 7,9 7,5 2,1 6,3 6))')),
+MULTIPOLYGONFROMTEXT('MULTIPOLYGON(((7 7,3 7,3 1,7 8,7 7)),
+ ((3 5,2 4,2 5,3 5)),
+ ((7 7,8 7,3 7,7 7,7 7)),
+ ((0 5,3 5,3 4,1 4,1 3,3 3,3 0,0 0,0 5), (1 1,2 1,2 2,1 2,1 1)))'))));
+ST_NUMGEOMETRIES((ST_UNION(ST_UNION(
+MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 0,4 2,0 2,1 5,0 3,7 0,8 5,5 8),
+ (6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
+
+192
+SELECT Round(ST_AREA(ST_BUFFER( ST_UNION(
+POLYGONFROMTEXT('POLYGON((7 7, 7 7, 7 4, 7 7, 7 7))'),
+POLYGONFROMTEXT('POLYGON((7 7, 4 7, 2 9, 7 6, 7 7))')), 1)), 6);
+Round(ST_AREA(ST_BUFFER( ST_UNION(
+POLYGONFROMTEXT('POLYGON((7 7, 7 7, 7 4, 7 7, 7 7))'),
+POLYGONFROMTEXT('POLYGON((7 7, 4 7, 2 9, 7 6, 7 7))')), 1)), 6)
+21.901344
+SELECT AsText(ST_UNION(MultiPolygonFromText('
+ MULTIPOLYGON(((2 2, 2 8, 8 8, 8 2, 2 2), (4 4, 4 6, 6 6, 6 4, 4 4)),
+ ((0 0, 8 3, 7 4, 0 0)),
+ ((2 2, 2 8, 8 8, 8 2, 2 2), (4 4, 4 6, 6 6, 6 4, 4 4)))'),
+MultiPolygonFromText(' MULTIPOLYGON(((0 0, 1 9, 4 6, 0 0)),
+ ((0 5, 3 5, 3 4, 1 4, 1 3, 3 3, 3 0, 0 0, 0 5), (1 1, 2 1, 2 2, 1 2, 1 1)),
+ ((7 7, 4 7, 6 3, 7 2, 7 7)),
+ ((0 5, 3 5, 3 4, 1 4, 1 3, 3 3, 3 0, 0 0, 0 5), (1 1, 2 1, 2 2, 1 2, 1 1))) ')));
+AsText(ST_UNION(MultiPolygonFromText('
+ MULTIPOLYGON(((2 2, 2 8, 8 8, 8 2, 2 2), (4 4, 4 6, 6 6, 6 4, 4 4)),
+ ((0 0, 8 3, 7 4, 0 0)),
+ ((2 2, 2 8, 8 8, 8 2, 2 2), (4 4, 4 6, 6 6, 6 4, 4 4)))'),
+MultiPolygonFr
+POLYGON((0 0,0 5,0.555555555555556 5,1 9,2 8,8 8,8 2,5.33333333333333 2,3 1.125,3 0,0 0),(1 1,1 1.5,1.33333333333333 2,2 2,2 1.14285714285714,1.75 1,1 1),(3 1.71428571428571,3 2,3.5 2,3 1.71428571428571),(4 4,4 6,4.5 6,5.5 4,4 4))
+SELECT AsText(ST_SYMDIFFERENCE(
+MultiLineStringFromText('MULTILINESTRING((7 7, 1 7, 8 5, 7 8, 7 7),
+ (6 3, 3 4, 1 1, 9 9, 9 0, 8 4, 9 9))'),
+Envelope(GeometryFromText('MULTIPOINT(7 9, 0 0, 3 7, 1 6, 0 0)'))));
+AsText(ST_SYMDIFFERENCE(
+MultiLineStringFromText('MULTILINESTRING((7 7, 1 7, 8 5, 7 8, 7 7),
+ (6 3, 3 4, 1 1, 9 9, 9 0, 8 4, 9 9))'),
+Envelope(GeometryFromText('MULTIPOINT(7 9, 0 0, 3 7, 1 6, 0 0)'))))
+GEOMETRYCOLLECTION(POLYGON((0 0,0 9,7 9,7 0,0 0)),LINESTRING(9 9,8 4,9 0,9 9),LINESTRING(7 5.28571428571429,8 5,7.25 7.25),LINESTRING(7 7,7.25 7.25),LINESTRING(7.25 7.25,7 8),LINESTRING(7.25 7.25,9 9))
+SELECT AsText(ST_UNION(
+MultiPolygonFromText('MULTIPOLYGON(((9 9, 7 9, 1 1, 9 9)),
+ ((2 2, 1 2, 3 3, 2 2, 2 2)),
+ ((0 0, 7 5, 9 6, 0 0)),
+ ((7 7, 5 7, 1 5, 7 1, 7 7)))'),
+MultiPolygonFromText('MULTIPOLYGON(((2 2, 2 2, 1 5, 2 7, 2 2)),
+ ((0 5, 3 5, 3 0, 0 0, 0 5), (1 1, 2 1, 2 4, 1 4, 1 1)))')));
+AsText(ST_UNION(
+MultiPolygonFromText('MULTIPOLYGON(((9 9, 7 9, 1 1, 9 9)),
+ ((2 2, 1 2, 3 3, 2 2, 2 2)),
+ ((0 0, 7 5, 9 6, 0 0)),
+
+POLYGON((0 0,0 5,1 5,2 7,2 5.5,5 7,5.5 7,7 9,9 9,7 7,7 5,9 6,7 4.66666666666667,7 1,4.25 2.83333333333333,3 2,3 0,0 0),(1 1,1 4,1.33333333333333 4,1.85714285714286 2.42857142857143,1 2,1.75 2,1 1,2 2,2 1.42857142857143,1.4 1,1 1),(1.5 1,2 1.33333333333333,2 1,1.5 1),(3 2.14285714285714,3 3,3.4 3.4,4.10344827586207 2.93103448275862,3 2.14285714285714))
+SELECT AsText( ST_INTERSECTION(
+LinestringFromText('LINESTRING( 3 5, 2 5, 2 4, 3 4, 3 5 ) ') ,
+LinestringFromText('LINESTRING( 3 5, 2 4, 2 5, 3 5 ) ')
+));
+AsText( ST_INTERSECTION(
+LinestringFromText('LINESTRING( 3 5, 2 5, 2 4, 3 4, 3 5 ) ') ,
+LinestringFromText('LINESTRING( 3 5, 2 4, 2 5, 3 5 ) ')
+))
+LINESTRING(2 4,2 5,3 5)
+SELECT AsText( ST_UNION(
+PolygonFromText(' POLYGON( ( 2 2 , 3 2 , 7 5 , 2 0 , 2 2 ) ) ') ,
+PolygonFromText(' POLYGON( ( 2 2 , 3 2 , 3 3 , 2 5 , 2 2 ) ) ') ) );
+AsText( ST_UNION(
+PolygonFromText(' POLYGON( ( 2 2 , 3 2 , 7 5 , 2 0 , 2 2 ) ) ') ,
+PolygonFromText(' POLYGON( ( 2 2 , 3 2 , 3 3 , 2 5 , 2 2 ) ) ') ) )
+POLYGON((2 0,2 5,3 3,3 2,7 5,2 0))
+SELECT AsText(ST_INTERSECTION(LinestringFromText('LINESTRING(1 1, 2 2)'), GeometryFromText('LINESTRING(3 3, 4 4)')));
+AsText(ST_INTERSECTION(LinestringFromText('LINESTRING(1 1, 2 2)'), GeometryFromText('LINESTRING(3 3, 4 4)')))
+GEOMETRYCOLLECTION EMPTY
+SELECT AsText(ST_UNION(GEOMETRYFROMTEXT('POINT(8 1)') ,MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 5, 2 5, 2 4, 3 4, 3 5))')));
+AsText(ST_UNION(GEOMETRYFROMTEXT('POINT(8 1)') ,MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 5, 2 5, 2 4, 3 4, 3 5))')))
+GEOMETRYCOLLECTION(POINT(8 1),LINESTRING(2 4,2 5,3 5,3 4,2 4))
+SELECT ST_DISTANCE(POINTFROMTEXT('POINT(7 1)'),MULTILINESTRINGFROMTEXT('MULTILINESTRING(
+ (4 7,9 7,6 1,3 4,1 1), (3 5, 2 5, 2 4, 3 4, 3 5))'));
+ST_DISTANCE(POINTFROMTEXT('POINT(7 1)'),MULTILINESTRINGFROMTEXT('MULTILINESTRING(
+ (4 7,9 7,6 1,3 4,1 1), (3 5, 2 5, 2 4, 3 4, 3 5))'))
+1
+SELECT AsText(ST_UNION(POLYGONFROMTEXT('POLYGON((12 9, 3 6, 3 0, 12 9))'), POLYGONFROMTEXT('POLYGON((2 2, 7 2, 4 2, 2 0, 2 2))')));
+AsText(ST_UNION(POLYGONFROMTEXT('POLYGON((12 9, 3 6, 3 0, 12 9))'), POLYGONFROMTEXT('POLYGON((2 2, 7 2, 4 2, 2 0, 2 2))')))
+GEOMETRYCOLLECTION(POLYGON((2 0,2 2,3 2,3 6,12 9,3 0,3 1,2 0)),LINESTRING(5 2,7 2))
+SELECT ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER(ST_UNION(
+MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 2 5, 7 6, 1 8),(0 0 ,1 6 ,0 1, 8 9, 2 4, 6 1, 3 5, 4 8), (9 3, 5 4, 1 8, 4 2, 5 8, 3 0))' ) ,
+MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 3 1, 2 7, 4 2, 6 2, 1 5))')
+), 16)));
+ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER(ST_UNION(
+MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 2 5, 7 6, 1 8),(0 0 ,1 6 ,0 1, 8 9, 2 4, 6 1, 3 5, 4 8), (9 3, 5 4, 1 8, 4 2, 5 8, 3 0))' ) ,
+MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 3 1, 2 7, 4 2, 6 2
+278
+SELECT ST_NUMGEOMETRIES(ST_DIFFERENCE (
+ST_UNION (
+MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 4 , 5 0 , 2 9 , 6 2 , 0 2 ) , ( 4 3 , 5 6 , 9 4 , 0 7 , 7 2 , 2 0 , 8 2 ) , ( 5 0 , 1 5 , 3 7 , 7 7 ) , ( 2 3 , 9 5 , 2 0 , 8 1 ) , ( 0 9 , 9 3 , 2 8 , 8 1 , 9 4 ) ) ' ),
+ST_UNION (
+MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( ( 2 2 , 7 2 , 6 2 , 2 6 , 2 2 ) ) , ( (3 5, 2 5, 2 4, 3 4, 3 5) ) ) ' ) ,
+ENVELOPE(
+MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( (3 5, 2 5, 2 4, 3 4, 3 5) ) ) ' )
+)
+)
+),
+MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 9 , 1 3 , 7 3 , 8 5 ) , ( 5 0 , 8 1 , 2 0 , 7 4 , 1 0 ) , ( 9 2 , 5 2 , 6 5 , 8 8 , 0 2 ) , ( 0 8 , 3 9 , 4 0 , 1 0 ) , ( 0 0 , 7 6 , 8 3 , 0 0 ) ) ' )
+));
+ST_NUMGEOMETRIES(ST_DIFFERENCE (
+ST_UNION (
+MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 4 , 5 0 , 2 9 , 6 2 , 0 2 ) , ( 4 3 , 5 6 , 9 4 , 0 7 , 7 2 , 2 0 , 8 2 ) , ( 5 0 , 1 5 , 3 7 , 7 7 ) , ( 2 3 , 9 5 , 2 0 , 8 1 ) , ( 0 9 , 9 3 , 2 8 , 8 1 , 9 4 )
+125
+SELECT ASTEXT(ST_DIFFERENCE (
+POLYGONFROMTEXT( ' POLYGON( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) ' ) ,
+ST_UNION (
+MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( (3 5, 2 5, 2 4, 3 4, 3 5) ) ' ) ,
+ST_SYMDIFFERENCE (
+MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 3 8 , 0 8 , 6 6 , 6 1 , 0 5 , 6 7 , 3 7 ) , ( 5 8 , 7 7 , 9 0 , 8 7 ) , ( 1 5 , 1 8 , 2 3 , 3 9 ) , ( 1 3 , 9 7 , 5 5 , 0 8 , 6 9 ) , ( 3 6 , 6 9 , 8 7 , 0 2 , 4 6 , 9 5 ) ) ' ) ,
+ST_UNION (
+MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 9 4 , 2 0 , 2 2 , 7 2 , 6 2 ) , ( 5 2 , 8 2 , 4 8 , 3 4 ) , ( 1 0 , 1 4 , 2 7 , 7 0 , 1 5 ) , ( 2 8 , 4 4 , 5 0 , 7 0 , 4 0 ) ) ' ) ,
+GEOMETRYFROMTEXT( ' MULTILINESTRING( ( 3 7 , 7 3 , 5 8 , 4 8 ) , ( 3 2 , 5 0 , 9 3 , 4 4 ) , ( 6 0 , 4 2 , 7 8 , 1 3 ) ) ' )
+)
+)
+)
+));
+ASTEXT(ST_DIFFERENCE (
+POLYGONFROMTEXT( ' POLYGON( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) ' ) ,
+ST_UNION (
+MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( (3 5, 2 5, 2 4, 3 4, 3 5) ) ' ) ,
+ST_SYMDIFFERENCE (
+MULTILINESTRINGFROMTEX
+POLYGON((2 2,2 8,8 8,8 2,2 2),(4 4,4 6,6 6,6 4,4 4))
+SELECT ST_NUMGEOMETRIES(ST_UNION (
+MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 0 8 , 1 9 , 5 7 , 2 8 , 5 8 , 6 7 ) , ( 4 5 , 8 4 , 0 3 , 5 1 ) , ( 6 8 , 2 7 , 1 6 , 9 9 , 7 2 ) , ( 9 5 , 2 8 , 1 2 , 9 6 , 2 0 ) ) ' ) ,
+MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( ( 7 7 , 2 7, 6 8, 7 1 , 7 7 ) ) ) ' )
+));
+ST_NUMGEOMETRIES(ST_UNION (
+MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 0 8 , 1 9 , 5 7 , 2 8 , 5 8 , 6 7 ) , ( 4 5 , 8 4 , 0 3 , 5 1 ) , ( 6 8 , 2 7 , 1 6 , 9 9 , 7 2 ) , ( 9 5 , 2 8 , 1 2 , 9 6 , 2 0 ) ) ' ) ,
+MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( (
+50
+SELECT ST_BUFFER (
+LINESTRINGFROMTEXT( ' LINESTRING( 5 4 , 3 8 , 2 6 , 5 5 , 7 9 ) ' ) ,
+ST_DISTANCE (
+MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( (3 5, 2 4, 2 5, 3 5) ) , ( (3 5, 2 5, 2 4, 3 4, 3 5) ) , ( ( 0 0 , 8 3 , 9 5 , 0 0 ) ) ) ' ) ,
+ST_DIFFERENCE (
+MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( (3 5, 2 5, 2 4, 3 4, 3 5) ) ) ' ) ,
+MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) , ( ( 0 0 , 3 8 , 9 4 , 0 0 ) ) ) ' )
+)
+)
+) ;
+ST_BUFFER (
+LINESTRINGFROMTEXT( ' LINESTRING( 5 4 , 3 8 , 2 6 , 5 5 , 7 9 ) ' ) ,
+ST_DISTANCE (
+MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( (3 5, 2 4, 2 5, 3 5) ) , ( (3 5, 2 5, 2 4, 3 4, 3 5) ) , ( ( 0 0 , 8 3 , 9 5 , 0 0 ) ) ) ' ) ,
+ST_DIFFERENCE (
+MULTIPOL
+NULL
+SELECT ST_DISTANCE ( ST_DIFFERENCE ( MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( (3 5, 2 5, 2 4, 3 4, 3 5) ) ) ' ) , MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) , ( ( 0 0 , 3 8 , 9 4 , 0 0 ) ) ) ' ) ), MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( (3 5, 2 4, 2 5, 3 5) ) , ( (3 5, 2 5, 2 4, 3 4, 3 5) ) , ( ( 0 0 , 8 3 , 9 5 , 0 0 ) ) ) ' ) ) ;
+ST_DISTANCE ( ST_DIFFERENCE ( MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( (3 5, 2 5, 2 4, 3 4, 3 5) ) ) ' ) , MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 ,
+NULL
+SELECT ASTEXT(ST_INTERSECTION( GEOMETRYFROMTEXT('GEOMETRYCOLLECTION(LINESTRING(7 7,5.33333333333333 7),LINESTRING(5.33333333333333 7,0 7,5 8,5.33333333333333 7),LINESTRING(5.33333333333333 7,7 2,7 7),POLYGON((0 5,3 5,3 2,1 2,1 1,3 1,3 0,0 0,0 3,2 3,2 4,0 4,0 5)))'), geomETRYFROMTEXT(' MULTILINESTRING( ( 5 1 , 3 7 , 6 1 , 7 0 ) , ( 1 6 , 8 5 , 7 5 , 5 6 ) )') ));
+ASTEXT(ST_INTERSECTION( GEOMETRYFROMTEXT('GEOMETRYCOLLECTION(LINESTRING(7 7,5.33333333333333 7),LINESTRING(5.33333333333333 7,0 7,5 8,5.33333333333333 7),LINESTRING(5.33333333333333 7,7 2,7 7),POLYGON((0 5,3 5,3 2,1 2,1 1,3 1,3 0,0 0,0 3,2 3,2 4,0 4,0 5))
+MULTIPOINT(7 5,7 5.14285714285714,5.9 5.3,5.8 5.6,3 7)
+SELECT ST_CROSSES( GEOMETRYFROMTEXT(' POLYGON( (3 5, 2 4, 2 5, 3 5) ) ') , POLYGONFROMTEXT(' POLYGON((2 4,3 4,3 5,2 5,2 4)) '));
+ST_CROSSES( GEOMETRYFROMTEXT(' POLYGON( (3 5, 2 4, 2 5, 3 5) ) ') , POLYGONFROMTEXT(' POLYGON((2 4,3 4,3 5,2 5,2 4)) '))
+0
+SELECT ST_WITHIN( POLYGONFROMTEXT(' POLYGON( (0 5, 3 5, 3 4, 2 0 , 1 0, 2 4 , 0 4, 0 5) ) ') , POLYGONFROMTEXT(' POLYGON( (0 5, 3 5, 3 4, 1 4 , 1 3 , 3 3 , 3 0 , 0 0 , 0 5), ( 1 1 , 2 1 , 2 2 , 1 2 , 1 1 ) ) ') );
+ST_WITHIN( POLYGONFROMTEXT(' POLYGON( (0 5, 3 5, 3 4, 2 0 , 1 0, 2 4 , 0 4, 0 5) ) ') , POLYGONFROMTEXT(' POLYGON( (0 5, 3 5, 3 4, 1 4 , 1 3 , 3 3 , 3 0 , 0 0 , 0 5), ( 1 1 , 2 1 , 2 2 , 1 2 , 1 1 ) ) ') )
+0
+SELECT ST_WITHIN( POINTFROMTEXT(' POINT(1 2 ) ') , MULTIPOLYGONFROMTEXT(' MULTIPOLYGON( ( (0 5, 3 5, 3 0, 0 0, 0 5), ( 1 1 , 2 1 , 2 4, 1 4, 1 1 ) ) ) '));
+ST_WITHIN( POINTFROMTEXT(' POINT(1 2 ) ') , MULTIPOLYGONFROMTEXT(' MULTIPOLYGON( ( (0 5, 3 5, 3 0, 0 0, 0 5), ( 1 1 , 2 1 , 2 4, 1 4, 1 1 ) ) ) '))
+1
+select ST_ASTEXT(envelope(ST_GEOMCOLLFROMTEXT('GEOMETRYCOLLECTION EMPTY')));
+ST_ASTEXT(envelope(ST_GEOMCOLLFROMTEXT('GEOMETRYCOLLECTION EMPTY')))
+GEOMETRYCOLLECTION EMPTY
+SELECT ST_EQUALS( GEOMETRYFROMTEXT(' MULTILINESTRING( (3 5, 2 5, 2 4, 3 4, 3 5) ) ') , GEOMETRYFROMTEXT(' POLYGON( (3 5, 2 5, 2 4, 3 4, 3 5) ) ') );
+ST_EQUALS( GEOMETRYFROMTEXT(' MULTILINESTRING( (3 5, 2 5, 2 4, 3 4, 3 5) ) ') , GEOMETRYFROMTEXT(' POLYGON( (3 5, 2 5, 2 4, 3 4, 3 5) ) ') )
+0
+SELECT ST_TOUCHES( GEOMETRYFROMTEXT(' LINESTRING( 1 1 , 1 4 , 5 0 , 8 3 ) ') , POLYGONFROMTEXT(' POLYGON( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) ') );
+ST_TOUCHES( GEOMETRYFROMTEXT(' LINESTRING( 1 1 , 1 4 , 5 0 , 8 3 ) ') , POLYGONFROMTEXT(' POLYGON( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) ') )
+0
+SELECT ST_EQUALS( MULTIPOINTFROMTEXT(' MULTIPOINT( 5 1 , 6 9 , 1 4 , 4 0 ) ') , MULTIPOINTFROMTEXT(' MULTIPOINT( 5 8 , 5 2 , 1 8 , 3 0 , 3 0 , 7 8 ) ') );
+ST_EQUALS( MULTIPOINTFROMTEXT(' MULTIPOINT( 5 1 , 6 9 , 1 4 , 4 0 ) ') , MULTIPOINTFROMTEXT(' MULTIPOINT( 5 8 , 5 2 , 1 8 , 3 0 , 3 0 , 7 8 ) ') )
+0
+SELECT ST_EQUALS( MULTIPOINTFROMTEXT(' MULTIPOINT( 5 1 , 6 9 , 1 4 , 4 0 ) ') , MULTIPOINTFROMTEXT('MULTIPOINT( 4 0 , 6 9 , 5 1, 1 4 )') );
+ST_EQUALS( MULTIPOINTFROMTEXT(' MULTIPOINT( 5 1 , 6 9 , 1 4 , 4 0 ) ') , MULTIPOINTFROMTEXT('MULTIPOINT( 4 0 , 6 9 , 5 1, 1 4 )') )
+1
+SELECT ST_WITHIN( MULTIPOINTFROMTEXT(' MULTIPOINT( 2 9 , 2 9 , 4 9 , 9 1 ) ') , POLYGONFROMTEXT(' POLYGON( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) '));
+ST_WITHIN( MULTIPOINTFROMTEXT(' MULTIPOINT( 2 9 , 2 9 , 4 9 , 9 1 ) ') , POLYGONFROMTEXT(' POLYGON( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) '))
+0
+SELECT ST_INTERSECTS( GeomFromText('MULTILINESTRING( ( 4030 3045 , 3149 2461 , 3004 3831 , 3775 2976 ) )') , GeomFromText('LINESTRING(3058.41 3187.91,3081.52 3153.19,3042.99 3127.57,3019.89 3162.29,3039.07 3175.05,3039.07 3175.05,3058.41 3187.91,3081.52 3153.19,3042.99 3127.57,3019.89 3162.29)') );
+ST_INTERSECTS( GeomFromText('MULTILINESTRING( ( 4030 3045 , 3149 2461 , 3004 3831 , 3775 2976 ) )') , GeomFromText('LINESTRING(3058.41 3187.91,3081.52 3153.19,3042.99 3127.57,3019.89 3162.29,3039.07 3175.05,3039.07 3175.05,3058.41 3187.91,3081.52 3153.19,
+1
+select ASTEXT(ST_BUFFER(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))'), -3));
+ASTEXT(ST_BUFFER(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))'), -3))
+POLYGON((4 7,4 7,4 7))
+SELECT ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER( POLYGONFROMTEXT( 'POLYGON( ( 0.0 -3.0,
+ -2.910427500435995 0.727606875108998,
+ -0.910427500435995 8.727606875108998,
+ 7.664100588675687 1.503849116986468,
+ 1.664100588675687 -2.496150883013531,
+ 0.0 -3.0
+))' ), 3 )));
+ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER( POLYGONFROMTEXT( 'POLYGON( ( 0.0 -3.0,
+ -2.910427500435995 0.727606875108998,
+ -0.910427500435995 8.727606875108998,
+ 7.664100588675687 1.503849116986468,
+ 1.664100588675687 -2.496150883013531,
+ 0.0 -3.0
+))' ),
+136
diff --git a/mysql-test/r/gis-rt-precise.result b/mysql-test/r/gis-rt-precise.result
new file mode 100644
index 00000000000..3f4f014fb78
--- /dev/null
+++ b/mysql-test/r/gis-rt-precise.result
@@ -0,0 +1,62 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+g GEOMETRY NOT NULL,
+SPATIAL KEY(g)
+) ENGINE=MyISAM;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `fid` int(11) NOT NULL AUTO_INCREMENT,
+ `g` geometry NOT NULL,
+ PRIMARY KEY (`fid`),
+ SPATIAL KEY `g` (`g`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT count(*) FROM t1;
+count(*)
+150
+EXPLAIN SELECT fid, AsText(g) FROM t1 WHERE ST_Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 140))'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range g g 34 NULL 8 Using where
+SELECT fid, AsText(g) FROM t1 WHERE ST_Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
+fid AsText(g)
+1 LINESTRING(150 150,150 150)
+3 LINESTRING(148 148,152 152)
+4 LINESTRING(147 147,153 153)
+5 LINESTRING(146 146,154 154)
+6 LINESTRING(145 145,155 155)
+7 LINESTRING(144 144,156 156)
+8 LINESTRING(143 143,157 157)
+9 LINESTRING(142 142,158 158)
+10 LINESTRING(141 141,159 159)
+11 LINESTRING(140 140,160 160)
+2 LINESTRING(149 149,151 151)
+DROP TABLE t1;
+CREATE TABLE t1 (
+fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+g GEOMETRY NOT NULL
+) ENGINE=MyISAM;
+ALTER TABLE t1 ADD SPATIAL KEY(g);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `fid` int(11) NOT NULL AUTO_INCREMENT,
+ `g` geometry NOT NULL,
+ PRIMARY KEY (`fid`),
+ SPATIAL KEY `g` (`g`)
+) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1
+SELECT count(*) FROM t1;
+count(*)
+100
+EXPLAIN SELECT fid, AsText(g) FROM t1 WHERE ST_Within(g,
+GeomFromText('Polygon((40 40,60 40,60 60,40 40))'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range g g 34 NULL 1 Using where
+SELECT fid, AsText(g) FROM t1 WHERE ST_Within(g,
+GeomFromText('Polygon((40 40,60 40,60 60,40 40))'));
+fid AsText(g)
+46 LINESTRING(51 41,60 50)
+56 LINESTRING(41 41,50 50)
+45 LINESTRING(51 51,60 60)
+DROP TABLE t1;
+End of 5.5 tests.
diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result
index 6db63a6ada0..26787366358 100644
--- a/mysql-test/r/gis-rtree.result
+++ b/mysql-test/r/gis-rtree.result
@@ -12,6 +12,156 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`fid`),
SPATIAL KEY `g` (`g`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(150 150, 150 150)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(149 149, 151 151)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(148 148, 152 152)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(147 147, 153 153)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(146 146, 154 154)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(145 145, 155 155)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(144 144, 156 156)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(143 143, 157 157)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(142 142, 158 158)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(141 141, 159 159)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(140 140, 160 160)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(139 139, 161 161)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(138 138, 162 162)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(137 137, 163 163)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(136 136, 164 164)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(135 135, 165 165)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(134 134, 166 166)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(133 133, 167 167)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(132 132, 168 168)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(131 131, 169 169)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(130 130, 170 170)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(129 129, 171 171)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(128 128, 172 172)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(127 127, 173 173)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(126 126, 174 174)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(125 125, 175 175)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(124 124, 176 176)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(123 123, 177 177)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(122 122, 178 178)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(121 121, 179 179)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(120 120, 180 180)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(119 119, 181 181)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(118 118, 182 182)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(117 117, 183 183)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(116 116, 184 184)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(115 115, 185 185)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(114 114, 186 186)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(113 113, 187 187)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(112 112, 188 188)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(111 111, 189 189)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(110 110, 190 190)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(109 109, 191 191)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(108 108, 192 192)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(107 107, 193 193)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(106 106, 194 194)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(105 105, 195 195)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(104 104, 196 196)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(103 103, 197 197)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(102 102, 198 198)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(101 101, 199 199)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(100 100, 200 200)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(99 99, 201 201)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(98 98, 202 202)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(97 97, 203 203)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(96 96, 204 204)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(95 95, 205 205)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(94 94, 206 206)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(93 93, 207 207)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(92 92, 208 208)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(91 91, 209 209)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(90 90, 210 210)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(89 89, 211 211)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(88 88, 212 212)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(87 87, 213 213)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(86 86, 214 214)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(85 85, 215 215)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(84 84, 216 216)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(83 83, 217 217)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(82 82, 218 218)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(81 81, 219 219)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(80 80, 220 220)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(79 79, 221 221)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(78 78, 222 222)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(77 77, 223 223)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(76 76, 224 224)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(75 75, 225 225)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(74 74, 226 226)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(73 73, 227 227)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(72 72, 228 228)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(71 71, 229 229)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(70 70, 230 230)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(69 69, 231 231)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(68 68, 232 232)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(67 67, 233 233)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(66 66, 234 234)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(65 65, 235 235)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(64 64, 236 236)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(63 63, 237 237)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(62 62, 238 238)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(61 61, 239 239)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(60 60, 240 240)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(59 59, 241 241)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(58 58, 242 242)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(57 57, 243 243)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(56 56, 244 244)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(55 55, 245 245)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(54 54, 246 246)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(53 53, 247 247)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(52 52, 248 248)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(51 51, 249 249)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(50 50, 250 250)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(49 49, 251 251)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(48 48, 252 252)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(47 47, 253 253)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(46 46, 254 254)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(45 45, 255 255)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(44 44, 256 256)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(43 43, 257 257)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(42 42, 258 258)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(41 41, 259 259)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(40 40, 260 260)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(39 39, 261 261)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(38 38, 262 262)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(37 37, 263 263)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(36 36, 264 264)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(35 35, 265 265)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(34 34, 266 266)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(33 33, 267 267)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(32 32, 268 268)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(31 31, 269 269)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(30 30, 270 270)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(29 29, 271 271)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(28 28, 272 272)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(27 27, 273 273)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(26 26, 274 274)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(25 25, 275 275)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(24 24, 276 276)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(23 23, 277 277)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(22 22, 278 278)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(21 21, 279 279)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(20 20, 280 280)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(19 19, 281 281)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(18 18, 282 282)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(17 17, 283 283)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(16 16, 284 284)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(15 15, 285 285)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(14 14, 286 286)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(13 13, 287 287)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(12 12, 288 288)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(11 11, 289 289)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(10 10, 290 290)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(9 9, 291 291)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(8 8, 292 292)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(7 7, 293 293)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(6 6, 294 294)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(5 5, 295 295)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(4 4, 296 296)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(3 3, 297 297)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(2 2, 298 298)'));
+INSERT INTO t1 (g) VALUES (GeomFromText('LineString(1 1, 299 299)'));
SELECT count(*) FROM t1;
count(*)
150
@@ -36,6 +186,106 @@ CREATE TABLE t2 (
fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
g GEOMETRY NOT NULL
) ENGINE=MyISAM;
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10)));
ALTER TABLE t2 ADD SPATIAL KEY(g);
SHOW CREATE TABLE t2;
Table Create Table
@@ -51,7 +301,7 @@ count(*)
EXPLAIN SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range g g 34 NULL 4 Using where
+1 SIMPLE t2 range g g 34 NULL 1 Using where
SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
fid AsText(g)
@@ -59,204 +309,404 @@ fid AsText(g)
56 LINESTRING(41 41,50 50)
45 LINESTRING(51 51,60 60)
55 LINESTRING(41 51,50 60)
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10))));
+SELECT count(*) FROM t2;
count(*)
100
DROP TABLE t2;
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 8dad72fd3f8..f29d096fc57 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -66,7 +66,9 @@ INSERT INTO gis_multi_polygon VALUES
(119, MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));
INSERT INTO gis_geometrycollection VALUES
(120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),
-(121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9))))));
+(121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))),
+(122, GeomFromText('GeometryCollection()')),
+(123, GeomFromText('GeometryCollection EMPTY'));
INSERT into gis_geometry SELECT * FROM gis_point;
INSERT into gis_geometry SELECT * FROM gis_line;
INSERT into gis_geometry SELECT * FROM gis_polygon;
@@ -109,6 +111,8 @@ SELECT fid, AsText(g) FROM gis_geometrycollection;
fid AsText(g)
120 GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(0 0,10 10))
121 GEOMETRYCOLLECTION(POINT(44 6),LINESTRING(3 6,7 9))
+122 GEOMETRYCOLLECTION EMPTY
+123 GEOMETRYCOLLECTION EMPTY
SELECT fid, AsText(g) FROM gis_geometry;
fid AsText(g)
101 POINT(10 10)
@@ -132,6 +136,8 @@ fid AsText(g)
119 MULTIPOLYGON(((0 3,3 3,3 0,0 3)))
120 GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(0 0,10 10))
121 GEOMETRYCOLLECTION(POINT(44 6),LINESTRING(3 6,7 9))
+122 GEOMETRYCOLLECTION EMPTY
+123 GEOMETRYCOLLECTION EMPTY
SELECT fid, Dimension(g) FROM gis_geometry;
fid Dimension(g)
101 0
@@ -155,6 +161,8 @@ fid Dimension(g)
119 2
120 1
121 1
+122 0
+123 0
SELECT fid, GeometryType(g) FROM gis_geometry;
fid GeometryType(g)
101 POINT
@@ -178,6 +186,8 @@ fid GeometryType(g)
119 MULTIPOLYGON
120 GEOMETRYCOLLECTION
121 GEOMETRYCOLLECTION
+122 GEOMETRYCOLLECTION
+123 GEOMETRYCOLLECTION
SELECT fid, IsEmpty(g) FROM gis_geometry;
fid IsEmpty(g)
101 0
@@ -201,6 +211,8 @@ fid IsEmpty(g)
119 0
120 0
121 0
+122 0
+123 0
SELECT fid, AsText(Envelope(g)) FROM gis_geometry;
fid AsText(Envelope(g))
101 POLYGON((10 10,10 10,10 10,10 10,10 10))
@@ -224,11 +236,13 @@ fid AsText(Envelope(g))
119 POLYGON((0 0,3 0,3 3,0 3,0 0))
120 POLYGON((0 0,10 0,10 10,0 10,0 0))
121 POLYGON((3 6,44 6,44 9,3 9,3 6))
+122 GEOMETRYCOLLECTION EMPTY
+123 GEOMETRYCOLLECTION EMPTY
explain extended select Dimension(g), GeometryType(g), IsEmpty(g), AsText(Envelope(g)) from gis_geometry;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE gis_geometry ALL NULL NULL NULL NULL 21 100.00
+1 SIMPLE gis_geometry ALL NULL NULL NULL NULL 23 100.00
Warnings:
-Note 1003 select dimension(`test`.`gis_geometry`.`g`) AS `Dimension(g)`,geometrytype(`test`.`gis_geometry`.`g`) AS `GeometryType(g)`,isempty(`test`.`gis_geometry`.`g`) AS `IsEmpty(g)`,astext(envelope(`test`.`gis_geometry`.`g`)) AS `AsText(Envelope(g))` from `test`.`gis_geometry`
+Note 1003 select st_dimension(`test`.`gis_geometry`.`g`) AS `Dimension(g)`,st_geometrytype(`test`.`gis_geometry`.`g`) AS `GeometryType(g)`,st_isempty(`test`.`gis_geometry`.`g`) AS `IsEmpty(g)`,st_astext(st_envelope(`test`.`gis_geometry`.`g`)) AS `AsText(Envelope(g))` from `test`.`gis_geometry`
SELECT fid, X(g) FROM gis_point;
fid X(g)
101 10
@@ -245,7 +259,7 @@ explain extended select X(g),Y(g) FROM gis_point;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_point ALL NULL NULL NULL NULL 4 100.00
Warnings:
-Note 1003 select x(`test`.`gis_point`.`g`) AS `X(g)`,y(`test`.`gis_point`.`g`) AS `Y(g)` from `test`.`gis_point`
+Note 1003 select st_x(`test`.`gis_point`.`g`) AS `X(g)`,st_y(`test`.`gis_point`.`g`) AS `Y(g)` from `test`.`gis_point`
SELECT fid, AsText(StartPoint(g)) FROM gis_line;
fid AsText(StartPoint(g))
105 POINT(0 0)
@@ -280,7 +294,7 @@ explain extended select AsText(StartPoint(g)),AsText(EndPoint(g)),GLength(g),Num
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_line ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select astext(startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint(g))`,astext(endpoint(`test`.`gis_line`.`g`)) AS `AsText(EndPoint(g))`,glength(`test`.`gis_line`.`g`) AS `GLength(g)`,numpoints(`test`.`gis_line`.`g`) AS `NumPoints(g)`,astext(pointn(`test`.`gis_line`.`g`,2)) AS `AsText(PointN(g, 2))`,isclosed(`test`.`gis_line`.`g`) AS `IsClosed(g)` from `test`.`gis_line`
+Note 1003 select st_astext(st_startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint(g))`,st_astext(st_endpoint(`test`.`gis_line`.`g`)) AS `AsText(EndPoint(g))`,st_length(`test`.`gis_line`.`g`) AS `GLength(g)`,st_numpoints(`test`.`gis_line`.`g`) AS `NumPoints(g)`,st_astext(st_pointn(`test`.`gis_line`.`g`,2)) AS `AsText(PointN(g, 2))`,st_isclosed(`test`.`gis_line`.`g`) AS `IsClosed(g)` from `test`.`gis_line`
SELECT fid, AsText(Centroid(g)) FROM gis_polygon;
fid AsText(Centroid(g))
108 POINT(15 15)
@@ -310,7 +324,7 @@ explain extended select AsText(Centroid(g)),Area(g),AsText(ExteriorRing(g)),NumI
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_polygon ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select astext(centroid(`test`.`gis_polygon`.`g`)) AS `AsText(Centroid(g))`,area(`test`.`gis_polygon`.`g`) AS `Area(g)`,astext(exteriorring(`test`.`gis_polygon`.`g`)) AS `AsText(ExteriorRing(g))`,numinteriorrings(`test`.`gis_polygon`.`g`) AS `NumInteriorRings(g)`,astext(interiorringn(`test`.`gis_polygon`.`g`,1)) AS `AsText(InteriorRingN(g, 1))` from `test`.`gis_polygon`
+Note 1003 select st_astext(st_centroid(`test`.`gis_polygon`.`g`)) AS `AsText(Centroid(g))`,st_area(`test`.`gis_polygon`.`g`) AS `Area(g)`,st_astext(st_exteriorring(`test`.`gis_polygon`.`g`)) AS `AsText(ExteriorRing(g))`,st_numinteriorrings(`test`.`gis_polygon`.`g`) AS `NumInteriorRings(g)`,st_astext(st_interiorringn(`test`.`gis_polygon`.`g`,1)) AS `AsText(InteriorRingN(g, 1))` from `test`.`gis_polygon`
SELECT fid, IsClosed(g) FROM gis_multi_line;
fid IsClosed(g)
114 0
@@ -345,11 +359,13 @@ SELECT fid, NumGeometries(g) from gis_geometrycollection;
fid NumGeometries(g)
120 2
121 2
+122 0
+123 0
explain extended SELECT fid, NumGeometries(g) from gis_multi_point;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,numgeometries(`test`.`gis_multi_point`.`g`) AS `NumGeometries(g)` from `test`.`gis_multi_point`
+Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_numgeometries(`test`.`gis_multi_point`.`g`) AS `NumGeometries(g)` from `test`.`gis_multi_point`
SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point;
fid AsText(GeometryN(g, 2))
111 POINT(10 10)
@@ -369,35 +385,51 @@ SELECT fid, AsText(GeometryN(g, 2)) from gis_geometrycollection;
fid AsText(GeometryN(g, 2))
120 LINESTRING(0 0,10 10)
121 LINESTRING(3 6,7 9)
+122 NULL
+123 NULL
SELECT fid, AsText(GeometryN(g, 1)) from gis_geometrycollection;
fid AsText(GeometryN(g, 1))
120 POINT(0 0)
121 POINT(44 6)
+122 NULL
+123 NULL
explain extended SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,astext(geometryn(`test`.`gis_multi_point`.`g`,2)) AS `AsText(GeometryN(g, 2))` from `test`.`gis_multi_point`
+Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_astext(st_geometryn(`test`.`gis_multi_point`.`g`,2)) AS `AsText(GeometryN(g, 2))` from `test`.`gis_multi_point`
SELECT g1.fid as first, g2.fid as second,
Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o,
Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
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;
first second w c o e d t i r
-120 120 1 1 0 1 0 0 1 0
+120 120 1 1 0 1 0 1 1 0
120 121 0 0 1 0 0 0 1 0
+120 122 0 1 NULL 0 NULL 0 NULL 0
+120 123 0 1 NULL 0 NULL 0 NULL 0
121 120 0 0 1 0 0 0 1 0
-121 121 1 1 0 1 0 0 1 0
+121 121 1 1 0 1 0 1 1 0
+121 122 0 1 NULL 0 NULL 0 NULL 0
+121 123 0 1 NULL 0 NULL 0 NULL 0
+122 120 1 0 NULL 0 NULL 0 NULL 0
+122 121 1 0 NULL 0 NULL 0 NULL 0
+122 122 1 1 NULL 1 NULL 0 NULL 0
+122 123 1 1 NULL 1 NULL 0 NULL 0
+123 120 1 0 NULL 0 NULL 0 NULL 0
+123 121 1 0 NULL 0 NULL 0 NULL 0
+123 122 1 1 NULL 1 NULL 0 NULL 0
+123 123 1 1 NULL 1 NULL 0 NULL 0
explain extended SELECT g1.fid as first, g2.fid as second,
Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o,
Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
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 g1 ALL NULL NULL NULL NULL 4 100.00 Using temporary; Using filesort
+1 SIMPLE g2 ALL NULL NULL NULL NULL 4 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`
+Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,st_within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,st_contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,mbroverlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,st_equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,mbrdisjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,st_touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,mbrintersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,st_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;
CREATE TABLE t1 (
gp point,
@@ -439,12 +471,12 @@ explain extended SELECT AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select astext(geometryfromwkb(aswkb(geometryfromtext('POINT(1 4)')))) AS `AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4)'))))`
+Note 1003 select st_astext(st_geometryfromwkb(st_aswkb(st_geometryfromtext('POINT(1 4)')))) AS `AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4)'))))`
explain extended SELECT AsText(GeometryFromWKB(AsWKB(PointFromText('POINT(1 4)'))));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select astext(geometryfromwkb(aswkb(geometryfromtext('POINT(1 4)')))) AS `AsText(GeometryFromWKB(AsWKB(PointFromText('POINT(1 4)'))))`
+Note 1003 select st_astext(st_geometryfromwkb(st_aswkb(st_geometryfromtext('POINT(1 4)')))) AS `AsText(GeometryFromWKB(AsWKB(PointFromText('POINT(1 4)'))))`
SELECT SRID(GeomFromText('LineString(1 1,2 2)',101));
SRID(GeomFromText('LineString(1 1,2 2)',101))
101
@@ -452,12 +484,12 @@ explain extended SELECT SRID(GeomFromText('LineString(1 1,2 2)',101));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select srid(geometryfromtext('LineString(1 1,2 2)',101)) AS `SRID(GeomFromText('LineString(1 1,2 2)',101))`
+Note 1003 select srid(st_geometryfromtext('LineString(1 1,2 2)',101)) AS `SRID(GeomFromText('LineString(1 1,2 2)',101))`
explain extended select issimple(MultiPoint(Point(3, 6), Point(4, 10))), issimple(Point(3, 6));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select issimple(multipoint(point(3,6),point(4,10))) AS `issimple(MultiPoint(Point(3, 6), Point(4, 10)))`,issimple(point(3,6)) AS `issimple(Point(3, 6))`
+Note 1003 select st_issimple(st_multipoint(st_point(3,6),st_point(4,10))) AS `issimple(MultiPoint(Point(3, 6), Point(4, 10)))`,st_issimple(st_point(3,6)) AS `issimple(Point(3, 6))`
create table t1 (a geometry not null);
insert into t1 values (GeomFromText('Point(1 2)'));
insert into t1 values ('Garbage');
@@ -651,11 +683,11 @@ insert into t1 values ('85984',GeomFromText('MULTIPOLYGON(((-115.006363
select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
t1 where object_id=85998;
object_id geometrytype(geo) ISSIMPLE(GEO) ASTEXT(centroid(geo))
-85998 MULTIPOLYGON 0 POINT(115.318773152032 -36.2374728210215)
+85998 MULTIPOLYGON 1 POINT(115.318773152032 -36.2374728210215)
select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
t1 where object_id=85984;
object_id geometrytype(geo) ISSIMPLE(GEO) ASTEXT(centroid(geo))
-85984 MULTIPOLYGON 0 POINT(-114.877871869233 36.3310176346905)
+85984 MULTIPOLYGON 1 POINT(-114.877871869233 36.3310176346905)
drop table t1;
create table t1 (fl geometry not null);
insert into t1 values (1);
@@ -802,17 +834,6 @@ create table t1 (g geometry not null);
insert into t1 values(default);
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
drop table t1;
-CREATE TABLE t1 (a GEOMETRY);
-CREATE VIEW v1 AS SELECT GeomFromwkb(ASBINARY(a)) FROM t1;
-CREATE VIEW v2 AS SELECT a FROM t1;
-DESCRIBE v1;
-Field Type Null Key Default Extra
-GeomFromwkb(ASBINARY(a)) geometry YES NULL
-DESCRIBE v2;
-Field Type Null Key Default Extra
-a geometry YES NULL
-DROP VIEW v1,v2;
-DROP TABLE t1;
create table t1 (name VARCHAR(100), square GEOMETRY);
INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))'));
INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))'));
@@ -846,7 +867,7 @@ mbroverlaps
down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrtouches
-down2,left2,right2,up2
+big,center,down,down2,left,left2,right,right2,small,up,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrwithin
big,center
@@ -867,7 +888,7 @@ overlaps
down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
touches
-down2,left2,right2,up2
+big,center,down,down2,left,left2,right,right2,small,up,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
within
big,center
@@ -1088,3 +1109,390 @@ NULL
SELECT GEOMETRYCOLLECTION((SELECT @@OLD));
ERROR 22007: Illegal non geometric '' value found during parsing
End of 5.1 tests
+select ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))'));
+ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))'))
+1.5
+select ST_LENGTH(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 100 30, 20 30), POINT(3 3), LINESTRING(20 20, 30 20))'));
+ST_LENGTH(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 100 30, 20 30), POINT(3 3), LINESTRING(20 20, 30 20))'))
+160
+DROP DATABASE IF EXISTS gis_ogs;
+CREATE DATABASE gis_ogs;
+USE gis_ogs;
+#
+# C.3.3.1 Geometry types and functions schema construction
+#
+CREATE TABLE lakes (
+fid INTEGER NOT NULL PRIMARY KEY,
+name CHARACTER VARYING(64),
+shore POLYGON);
+CREATE TABLE road_segments (
+fid INTEGER NOT NULL PRIMARY KEY,
+name CHARACTER VARYING(64),
+aliases CHARACTER VARYING(64),
+num_lanes INTEGER,
+centerline LINESTRING);
+CREATE TABLE divided_routes (
+fid INTEGER NOT NULL PRIMARY KEY,
+name CHARACTER VARYING(64),
+num_lanes INTEGER,
+centerlines MULTILINESTRING);
+CREATE TABLE forests (
+fid INTEGER NOT NULL PRIMARY KEY,
+name CHARACTER VARYING(64),
+boundary MULTIPOLYGON);
+CREATE TABLE bridges (
+fid INTEGER NOT NULL PRIMARY KEY,
+name CHARACTER VARYING(64),
+position POINT);
+CREATE TABLE streams (
+fid INTEGER NOT NULL PRIMARY KEY,
+name CHARACTER VARYING(64),
+centerline LINESTRING);
+CREATE TABLE buildings (
+fid INTEGER NOT NULL PRIMARY KEY,
+address CHARACTER VARYING(64),
+position POINT,
+footprint POLYGON);
+CREATE TABLE ponds (
+fid INTEGER NOT NULL PRIMARY KEY,
+name CHARACTER VARYING(64),
+type CHARACTER VARYING(64),
+shores MULTIPOLYGON);
+CREATE TABLE named_places (
+fid INTEGER NOT NULL PRIMARY KEY,
+name CHARACTER VARYING(64),
+boundary POLYGON);
+CREATE TABLE map_neatlines (
+fid INTEGER NOT NULL PRIMARY KEY,
+neatline POLYGON);
+#
+# C.3.3.2 Geometry types and functions schema data loading
+#
+# Lakes
+INSERT INTO lakes VALUES (
+101, 'BLUE LAKE',
+PolyFromText(
+'POLYGON(
+(52 18,66 23,73 9,48 6,52 18),
+(59 18,67 18,67 13,59 13,59 18)
+)',
+101));
+# Road Segments
+INSERT INTO road_segments VALUES(102, 'Route 5', NULL, 2,
+LineFromText(
+'LINESTRING( 0 18, 10 21, 16 23, 28 26, 44 31 )' ,101));
+INSERT INTO road_segments VALUES(103, 'Route 5', 'Main Street', 4,
+LineFromText(
+'LINESTRING( 44 31, 56 34, 70 38 )' ,101));
+INSERT INTO road_segments VALUES(104, 'Route 5', NULL, 2,
+LineFromText(
+'LINESTRING( 70 38, 72 48 )' ,101));
+INSERT INTO road_segments VALUES(105, 'Main Street', NULL, 4,
+LineFromText(
+'LINESTRING( 70 38, 84 42 )' ,101));
+INSERT INTO road_segments VALUES(106, 'Dirt Road by Green Forest', NULL,
+1,
+LineFromText(
+'LINESTRING( 28 26, 28 0 )',101));
+# DividedRoutes
+INSERT INTO divided_routes VALUES(119, 'Route 75', 4,
+MLineFromText(
+'MULTILINESTRING((10 48,10 21,10 0),
+(16 0,16 23,16 48))', 101));
+# Forests
+INSERT INTO forests VALUES(109, 'Green Forest',
+MPolyFromText(
+'MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),
+(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))',
+101));
+# Bridges
+INSERT INTO bridges VALUES(110, 'Cam Bridge', PointFromText(
+'POINT( 44 31 )', 101));
+# Streams
+INSERT INTO streams VALUES(111, 'Cam Stream',
+LineFromText(
+'LINESTRING( 38 48, 44 41, 41 36, 44 31, 52 18 )', 101));
+INSERT INTO streams VALUES(112, NULL,
+LineFromText(
+'LINESTRING( 76 0, 78 4, 73 9 )', 101));
+# Buildings
+INSERT INTO buildings VALUES(113, '123 Main Street',
+PointFromText(
+'POINT( 52 30 )', 101),
+PolyFromText(
+'POLYGON( ( 50 31, 54 31, 54 29, 50 29, 50 31) )', 101));
+INSERT INTO buildings VALUES(114, '215 Main Street',
+PointFromText(
+'POINT( 64 33 )', 101),
+PolyFromText(
+'POLYGON( ( 66 34, 62 34, 62 32, 66 32, 66 34) )', 101));
+# Ponds
+INSERT INTO ponds VALUES(120, NULL, 'Stock Pond',
+MPolyFromText(
+'MULTIPOLYGON( ( ( 24 44, 22 42, 24 40, 24 44) ),
+( ( 26 44, 26 40, 28 42, 26 44) ) )', 101));
+# Named Places
+INSERT INTO named_places VALUES(117, 'Ashton',
+PolyFromText(
+'POLYGON( ( 62 48, 84 48, 84 30, 56 30, 56 34, 62 48) )', 101));
+INSERT INTO named_places VALUES(118, 'Goose Island',
+PolyFromText(
+'POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )', 101));
+# Map Neatlines
+INSERT INTO map_neatlines VALUES(115,
+PolyFromText(
+'POLYGON( ( 0 0, 0 48, 84 48, 84 0, 0 0 ) )', 101));
+#
+# C.3.3.3 Geometry types and functions schema test queries
+
+# Conformance Item T6
+SELECT Dimension(shore)
+FROM lakes
+WHERE name = 'Blue Lake';
+Dimension(shore)
+2
+# Conformance Item T7
+SELECT GeometryType(centerlines)
+FROM divided_routes
+WHERE name = 'Route 75';
+GeometryType(centerlines)
+MULTILINESTRING
+# Conformance Item T8
+SELECT AsText(boundary)
+FROM named_places
+WHERE name = 'Goose Island';
+AsText(boundary)
+POLYGON((67 13,67 18,59 18,59 13,67 13))
+# Conformance Item T9
+SELECT AsText(PolyFromWKB(AsBinary(boundary),101))
+FROM named_places
+WHERE name = 'Goose Island';
+AsText(PolyFromWKB(AsBinary(boundary),101))
+POLYGON((67 13,67 18,59 18,59 13,67 13))
+# Conformance Item T10
+SELECT SRID(boundary)
+FROM named_places
+WHERE name = 'Goose Island';
+SRID(boundary)
+101
+# Conformance Item T11
+SELECT IsEmpty(centerline)
+FROM road_segments
+WHERE name = 'Route 5'
+AND aliases = 'Main Street';
+IsEmpty(centerline)
+0
+# Conformance Item T14
+SELECT AsText(Envelope(boundary))
+FROM named_places
+WHERE name = 'Goose Island';
+AsText(Envelope(boundary))
+POLYGON((59 13,67 13,67 18,59 18,59 13))
+# Conformance Item T15
+SELECT X(position)
+FROM bridges
+WHERE name = 'Cam Bridge';
+X(position)
+44
+# Conformance Item T16
+SELECT Y(position)
+FROM bridges
+WHERE name = 'Cam Bridge';
+Y(position)
+31
+# Conformance Item T17
+SELECT AsText(StartPoint(centerline))
+FROM road_segments
+WHERE fid = 102;
+AsText(StartPoint(centerline))
+POINT(0 18)
+# Conformance Item T18
+SELECT AsText(EndPoint(centerline))
+FROM road_segments
+WHERE fid = 102;
+AsText(EndPoint(centerline))
+POINT(44 31)
+# Conformance Item T21
+SELECT GLength(centerline)
+FROM road_segments
+WHERE fid = 106;
+GLength(centerline)
+26
+# Conformance Item T22
+SELECT NumPoints(centerline)
+FROM road_segments
+WHERE fid = 102;
+NumPoints(centerline)
+5
+# Conformance Item T23
+SELECT AsText(PointN(centerline, 1))
+FROM road_segments
+WHERE fid = 102;
+AsText(PointN(centerline, 1))
+POINT(0 18)
+# Conformance Item T24
+SELECT AsText(Centroid(boundary))
+FROM named_places
+WHERE name = 'Goose Island';
+AsText(Centroid(boundary))
+POINT(63 15.5)
+# Conformance Item T26
+SELECT Area(boundary)
+FROM named_places
+WHERE name = 'Goose Island';
+Area(boundary)
+40
+# Conformance Item T27
+SELECT AsText(ExteriorRing(shore))
+FROM lakes
+WHERE name = 'Blue Lake';
+AsText(ExteriorRing(shore))
+LINESTRING(52 18,66 23,73 9,48 6,52 18)
+# Conformance Item T28
+SELECT NumInteriorRings(shore)
+FROM lakes
+WHERE name = 'Blue Lake';
+NumInteriorRings(shore)
+1
+# Conformance Item T29
+SELECT AsText(InteriorRingN(shore, 1))
+FROM lakes
+WHERE name = 'Blue Lake';
+AsText(InteriorRingN(shore, 1))
+LINESTRING(59 18,67 18,67 13,59 13,59 18)
+# Conformance Item T30
+SELECT NumGeometries(centerlines)
+FROM divided_routes
+WHERE name = 'Route 75';
+NumGeometries(centerlines)
+2
+# Conformance Item T31
+SELECT AsText(GeometryN(centerlines, 2))
+FROM divided_routes
+WHERE name = 'Route 75';
+AsText(GeometryN(centerlines, 2))
+LINESTRING(16 0,16 23,16 48)
+# Conformance Item T32
+SELECT IsClosed(centerlines)
+FROM divided_routes
+WHERE name = 'Route 75';
+IsClosed(centerlines)
+0
+# Conformance Item T33
+SELECT GLength(centerlines)
+FROM divided_routes
+WHERE name = 'Route 75';
+GLength(centerlines)
+96
+# Conformance Item T34
+SELECT AsText(Centroid(shores))
+FROM ponds
+WHERE fid = 120;
+AsText(Centroid(shores))
+POINT(25 42)
+# Conformance Item T36
+SELECT Area(shores)
+FROM ponds
+WHERE fid = 120;
+Area(shores)
+8
+# Conformance Item T37
+SELECT ST_Equals(boundary,
+PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1))
+FROM named_places
+WHERE name = 'Goose Island';
+ST_Equals(boundary,
+PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1))
+1
+# Conformance Item T38
+SELECT ST_Disjoint(centerlines, boundary)
+FROM divided_routes, named_places
+WHERE divided_routes.name = 'Route 75'
+AND named_places.name = 'Ashton';
+ST_Disjoint(centerlines, boundary)
+1
+# Conformance Item T39
+SELECT ST_Touches(centerline, shore)
+FROM streams, lakes
+WHERE streams.name = 'Cam Stream'
+AND lakes.name = 'Blue Lake';
+ST_Touches(centerline, shore)
+1
+# Conformance Item T42
+SELECT Crosses(road_segments.centerline, divided_routes.centerlines)
+FROM road_segments, divided_routes
+WHERE road_segments.fid = 102
+AND divided_routes.name = 'Route 75';
+Crosses(road_segments.centerline, divided_routes.centerlines)
+1
+# Conformance Item T43
+SELECT ST_Intersects(road_segments.centerline, divided_routes.centerlines)
+FROM road_segments, divided_routes
+WHERE road_segments.fid = 102
+AND divided_routes.name = 'Route 75';
+ST_Intersects(road_segments.centerline, divided_routes.centerlines)
+1
+# Conformance Item T44
+SELECT ST_Contains(forests.boundary, named_places.boundary)
+FROM forests, named_places
+WHERE forests.name = 'Green Forest'
+AND named_places.name = 'Ashton';
+ST_Contains(forests.boundary, named_places.boundary)
+0
+# Conformance Item T46
+SELECT ST_Distance(position, boundary)
+FROM bridges, named_places
+WHERE bridges.name = 'Cam Bridge'
+AND named_places.name = 'Ashton';
+ST_Distance(position, boundary)
+12
+# Conformance Item T48
+SELECT AsText(ST_Difference(named_places.boundary, forests.boundary))
+FROM named_places, forests
+WHERE named_places.name = 'Ashton'
+AND forests.name = 'Green Forest';
+AsText(ST_Difference(named_places.boundary, forests.boundary))
+POLYGON((56 34,62 48,84 48,84 42,56 34))
+SELECT AsText(ST_Union(shore, boundary))
+FROM lakes, named_places
+WHERE lakes.name = 'Blue Lake'
+AND named_places.name = 'Goose Island';
+AsText(ST_Union(shore, boundary))
+POLYGON((48 6,52 18,66 23,73 9,48 6))
+# Conformance Item T50
+SELECT AsText(ST_SymDifference(shore, boundary))
+FROM lakes, named_places
+WHERE lakes.name = 'Blue Lake'
+AND named_places.name = 'Ashton';
+AsText(ST_SymDifference(shore, boundary))
+MULTIPOLYGON(((48 6,52 18,66 23,73 9,48 6),(59 13,59 18,67 18,67 13,59 13)),((56 30,56 34,62 48,84 48,84 30,56 30)))
+# Conformance Item T51
+SELECT count(*)
+FROM buildings, bridges
+WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1;
+count(*)
+1
+DROP DATABASE gis_ogs;
+#
+# BUG #1043845 st_distance() results are incorrect depending on variable order
+#
+select st_distance(geomfromtext('LINESTRING(-95.9673005697771 36.13509598461,
+ -95.9673057475387 36.1344478941074,
+ -95.9673063519371 36.134484524621,
+ -95.9673049102515 36.1343976584193)'),
+geomfromtext('point(-95.96269500000000000000 36.14181833333330000000)')) ;
+st_distance(geomfromtext('LINESTRING(-95.9673005697771 36.13509598461,
+ -95.9673057475387 36.1344478941074,
+ -95.9673063519371 36.134484524621,
+
+0.008148695928138
+select st_distance(geomfromtext('point(-95.96269500000000000000 36.14181833333330000000)'),
+geomfromtext('LINESTRING(-95.9673005697771 36.13509598461,
+ -95.9673057475387 36.1344478941074,
+ -95.9673063519371 36.134484524621,
+ -95.9673049102515 36.1343976584193) ')) ;
+st_distance(geomfromtext('point(-95.96269500000000000000 36.14181833333330000000)'),
+geomfromtext('LINESTRING(-95.9673005697771 36.13509598461,
+ -95.9673057475387 36.1344478941074,
+ -95.9673063519371 36.
+0.008148695928138
diff --git a/mysql-test/r/grant_cache_no_prot.result b/mysql-test/r/grant_cache_no_prot.result
index 32bb9cce90e..281468ee2e1 100644
--- a/mysql-test/r/grant_cache_no_prot.result
+++ b/mysql-test/r/grant_cache_no_prot.result
@@ -174,7 +174,7 @@ Variable_name Value
Qcache_hits 7
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 7
+Qcache_not_cached 4
----- establish connection user4 (user=mysqltest_1) -----
select "user4";
user4
@@ -205,7 +205,7 @@ Variable_name Value
Qcache_hits 8
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 8
+Qcache_not_cached 5
----- close connections -----
----- switch to connection default -----
set names binary;
diff --git a/mysql-test/r/grant_cache_ps_prot.result b/mysql-test/r/grant_cache_ps_prot.result
index 281468ee2e1..2d8c543e9e4 100644
--- a/mysql-test/r/grant_cache_ps_prot.result
+++ b/mysql-test/r/grant_cache_ps_prot.result
@@ -174,7 +174,7 @@ Variable_name Value
Qcache_hits 7
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 4
+Qcache_not_cached 3
----- establish connection user4 (user=mysqltest_1) -----
select "user4";
user4
@@ -205,7 +205,7 @@ Variable_name Value
Qcache_hits 8
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 5
+Qcache_not_cached 4
----- close connections -----
----- switch to connection default -----
set names binary;
diff --git a/mysql-test/r/greedy_optimizer.result b/mysql-test/r/greedy_optimizer.result
index c0012c297d1..65ec63e2cd9 100644
--- a/mysql-test/r/greedy_optimizer.result
+++ b/mysql-test/r/greedy_optimizer.result
@@ -1,4 +1,6 @@
drop table if exists t1,t2,t3,t4,t5,t6,t7;
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
create table t1 (
c11 integer,c12 integer,c13 integer,c14 integer,c15 integer,c16 integer,
primary key (c11)
@@ -121,11 +123,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 +135,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
@@ -200,76 +202,76 @@ select @@optimizer_search_depth;
0
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
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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 821.837037
+Last_query_cost 1371.437037
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
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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 821.837037
+Last_query_cost 1371.437037
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
+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 289.418727
+Last_query_cost 362.618727
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
+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 289.418727
+Last_query_cost 362.618727
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
+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 289.418727
+Last_query_cost 362.618727
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
+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 289.418727
+Last_query_cost 362.618727
set optimizer_search_depth=1;
select @@optimizer_search_depth;
@@optimizer_search_depth
@@ -277,151 +279,151 @@ 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
-Last_query_cost 821.837037
+Last_query_cost 1693.637037
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
+Last_query_cost 1693.637037
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
+Last_query_cost 844.037037
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
+Last_query_cost 844.037037
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
+Last_query_cost 844.037037
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
+Last_query_cost 844.037037
set optimizer_search_depth=62;
select @@optimizer_search_depth;
@@optimizer_search_depth
62
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
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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 821.837037
+Last_query_cost 1371.437037
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
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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 821.837037
+Last_query_cost 1371.437037
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
+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 289.418727
+Last_query_cost 362.618727
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
+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 289.418727
+Last_query_cost 362.618727
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
+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 289.418727
+Last_query_cost 362.618727
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
+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 289.418727
+Last_query_cost 362.618727
set optimizer_prune_level=1;
select @@optimizer_prune_level;
@@optimizer_prune_level
@@ -433,75 +435,75 @@ 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
-Last_query_cost 821.837037
+Last_query_cost 1693.637037
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
+Last_query_cost 1693.637037
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 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 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 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 (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
+Last_query_cost 844.037037
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 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 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 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 (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
+Last_query_cost 844.037037
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 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 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 t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
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 (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
+Last_query_cost 844.037037
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 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 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 t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
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 (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
+Last_query_cost 844.037037
set optimizer_search_depth=1;
select @@optimizer_search_depth;
@@optimizer_search_depth
@@ -509,75 +511,75 @@ 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
-Last_query_cost 821.837037
+Last_query_cost 1693.637037
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
+Last_query_cost 1693.637037
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
+Last_query_cost 844.037037
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
+Last_query_cost 844.037037
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
+Last_query_cost 844.037037
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
+Last_query_cost 844.037037
set optimizer_search_depth=62;
select @@optimizer_search_depth;
@@optimizer_search_depth
@@ -585,75 +587,75 @@ 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
-Last_query_cost 821.837037
+Last_query_cost 1693.637037
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
+Last_query_cost 1693.637037
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 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 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 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 (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
+Last_query_cost 844.037037
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 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 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 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 (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
+Last_query_cost 844.037037
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 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 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 t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
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 (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
+Last_query_cost 844.037037
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 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 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 t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
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 (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
+Last_query_cost 844.037037
drop table t1,t2,t3,t4,t5,t6,t7;
CREATE TABLE t1 (a int, b int, d int, i int);
INSERT INTO t1 VALUES (1,1,1,1);
@@ -732,3 +734,4 @@ t4 LEFT JOIN (t5 JOIN t5_1 ON t5.l = t5_1.l) ON t5.d = t4.d
SET optimizer_search_depth = DEFAULT;
DROP TABLE t1,t2,t2_1,t3,t3_1,t4,t4_1,t5,t5_1;
End of 5.0 tests
+set join_cache_level=@save_join_cache_level;
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index 8c92b54b867..07cccf149ee 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -450,6 +450,8 @@ drop table t1,t2;
CREATE TABLE t1 (ID1 int, ID2 int, ID int NOT NULL AUTO_INCREMENT,PRIMARY KEY(ID
));
insert into t1 values (1,244,NULL),(2,243,NULL),(134,223,NULL),(185,186,NULL);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select S.ID as xID, S.ID1 as xID1 from t1 as S left join t1 as yS on S.ID1 between yS.ID1 and yS.ID2;
xID xID1
1 1
@@ -468,6 +470,7 @@ xID xID1 Level
2 2 **
3 134 ***
4 185 ****
+SET optimizer_switch=@save_optimizer_switch;
drop table t1;
CREATE TABLE t1 (
pid int(11) unsigned NOT NULL default '0',
@@ -537,11 +540,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 +876,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;
@@ -1539,11 +1542,15 @@ USE INDEX FOR JOIN (i2)
USE INDEX FOR JOIN (i2,i2);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL i2 9 NULL 144 Using index
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
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 <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 144
+SET optimizer_switch=@save_optimizer_switch;
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;
@@ -1552,11 +1559,14 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT a, SUM(b) FROM t2 IGNORE INDEX (a) GROUP BY a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
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)
+SET optimizer_switch=@save_optimizer_switch;
SHOW VARIABLES LIKE 'old';
Variable_name Value
old OFF
@@ -1742,7 +1752,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 +1760,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;
@@ -1898,8 +1908,8 @@ SELECT a, AVG(t1.b),
FROM t1 GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL a 10 NULL 9 Using index
-3 DEPENDENT SUBQUERY t12 ref a a 10 func,func 2 Using where
-2 DEPENDENT SUBQUERY t11 ref a a 10 func,func 2 Using where
+3 DEPENDENT SUBQUERY t12 ref a a 10 func,func 2 Using index condition
+2 DEPENDENT SUBQUERY t11 ref a a 10 func,func 2 Using index condition
SELECT a, AVG(t1.b),
(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c,
(SELECT t12.c FROM t1 t12 WHERE t12.a = t1.a AND t12.b = AVG(t1.b)) AS t12c
@@ -2247,7 +2257,21 @@ zzz
3
4
8
-#TODO: in merge with 5.3 add original test suite
+SET @save_optimizer_switch967242=@@optimizer_switch;
+SET optimizer_switch = 'in_to_exists=on';
+SELECT t2_1.b
+FROM t1 JOIN t2 AS t2_1 JOIN t2 AS t2_2
+ON (t2_2.b = t2_1.b ) AND (t2_2.c = t2_1.c )
+WHERE
+( SELECT COUNT(*) FROM t2 ) IS NOT NULL
+OR a = t2_1.c
+GROUP BY t2_1.b;
+b
+0
+3
+4
+8
+SET optimizer_switch=@save_optimizer_switch967242;
drop table t1, t2;
#
# Bug#12578908: SELECT SQL_BUFFER_RESULT OUTPUTS TOO MANY
@@ -2316,3 +2340,71 @@ max(1)
NULL
drop table t1;
# End of 5.2 tests
+#
+# lp:872702 Crash in add_ref_to_table_cond() when grouping by a PK
+#
+CREATE TABLE t1 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (14),(15),(16),(17),(18),(19),(20);
+CREATE TABLE t2 (a int) ;
+SELECT a
+FROM t1
+WHERE a = (
+SELECT t2.a
+FROM t2
+) OR t1.a = 73
+GROUP BY 1;
+a
+DROP TABLE t1, t2;
+FLUSH STATUS;
+CREATE TABLE t1 (f1 INT, f2 decimal(20,1), f3 blob);
+INSERT INTO t1 values(11,NULL,'blob'),(11,NULL,'blob');
+SELECT f3, MIN(f2) FROM t1 GROUP BY f1 LIMIT 1;
+f3 MIN(f2)
+blob NULL
+DROP TABLE t1;
+the value below *must* be 1
+show status like 'Created_tmp_disk_tables';
+Variable_name Value
+Created_tmp_disk_tables 1
+#
+# Bug #1002146: Unneeded filesort if usage of join buffer is not allowed
+# (bug mdev-645)
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, a int, INDEX idx(a));
+INSERT INTO t1 VALUES (3,2), (2,3), (5,3), (6,4);
+CREATE TABLE t2 (pk int PRIMARY KEY, a int, INDEX idx(a));
+INSERT INTO t2 VALUES (9,0), (10,3), (6,4), (1,6), (3,100), (5,200);
+set join_cache_level=0;
+EXPLAIN
+SELECT t2.a FROM t2 STRAIGHT_JOIN t1 ON t2.a <> 0 WHERE t2.a <> 6
+GROUP BY t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range idx idx 5 NULL 5 Using where; Using index
+1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 Using index
+SELECT t2.a FROM t2 STRAIGHT_JOIN t1 ON t2.a <> 0 WHERE t2.a <> 6
+GROUP BY t2.a;
+a
+3
+4
+100
+200
+set join_cache_level=default;
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='outer_join_with_cache=off';
+EXPLAIN
+SELECT t2.a FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t2.a <> 6
+GROUP BY t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range idx idx 5 NULL 5 Using where; Using index
+1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 Using where; Using index
+SELECT t2.a FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t2.a <> 6
+GROUP BY t2.a;
+a
+0
+3
+4
+100
+200
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2;
+# End of 5.3 tests
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index 2f6745dcb5e..c8dbfd570c6 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -876,10 +876,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
explain select a1,a2,b, max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
+1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
+1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b111') and (c <= 'g112') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
@@ -924,7 +924,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
explain select a1,a2,b, max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
+1 SIMPLE t2 range NULL idx_t2_1 146 NULL # Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
@@ -1360,12 +1360,164 @@ group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index
2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+select a1,a2,b,min(c),max(c) from t1
+where exists ( select * from t2 where t2.c = t1.c )
+group by a1,a2,b;
+a1 a2 b min(c) max(c)
+a a a a111 d111
+a a b e112 h112
+a b a i121 l121
+a b b m122 p122
+b a a a211 d211
+b a b e212 h212
+b b a i221 l221
+b b b m222 p222
+c a a a311 d311
+c a b e312 h312
+c b a i321 l321
+c b b m322 p322
+d a a a411 d411
+d a b e412 h412
+d b a i421 l421
+d b b m422 p422
explain select a1,a2,b,min(c),max(c) from t1
where exists ( select * from t2 where t2.c > 'b1' )
group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 range NULL idx_t1_1 147 NULL 17 Using index for group-by
+1 PRIMARY t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
2 SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+select a1,a2,b,min(c),max(c) from t1
+where exists ( select * from t2 where t2.c > 'b1' )
+group by a1,a2,b;
+a1 a2 b min(c) max(c)
+a a a a111 d111
+a a b e112 h112
+a b a i121 l121
+a b b m122 p122
+b a a a211 d211
+b a b e212 h212
+b b a i221 l221
+b b b m222 p222
+c a a a311 d311
+c a b e312 h312
+c b a i321 l321
+c b b m322 p322
+d a a a411 d411
+d a b e412 h412
+d b a i421 l421
+d b b m422 p422
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2 where t1.b > 'a' and t2.c > 'b1' )
+group by a1,a2,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
+2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2 where t1.b > 'a' and t2.c > 'b1' )
+group by a1,a2,b;
+a1 a2 b c min(c) max(c)
+a a b h112 e112 h112
+a b b p122 m122 p122
+b a b h212 e212 h212
+b b b p222 m222 p222
+c a b h312 e312 h312
+c b b p322 m322 p322
+d a b h412 e412 h412
+d b b p422 m422 p422
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.b) and
+t2.c > 'b1' )
+group by a1,a2,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
+2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+2 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index; FirstMatch(t2)
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.b) and
+t2.c > 'b1' )
+group by a1,a2,b;
+a1 a2 b c min(c) max(c)
+a a a d111 a111 d111
+a a b h112 e112 h112
+a b a l121 i121 l121
+a b b p122 m122 p122
+b a a d211 a211 d211
+b a b h212 e212 h212
+b b a l221 i221 l221
+b b b p222 m222 p222
+c a a d311 a311 d311
+c a b h312 e312 h312
+c b a l321 i321 l321
+c b b p322 m322 p322
+d a a d411 a411 d411
+d a b h412 e412 h412
+d b a l421 i421 l421
+d b b p422 m422 p422
+SET optimizer_switch=@save_optimizer_switch;
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2 where t1.c > 'a' and t2.c > 'b1' )
+group by a1,a2,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index
+2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2 where t1.c > 'a' and t2.c > 'b1' )
+group by a1,a2,b;
+a1 a2 b c min(c) max(c)
+a a a a111 a111 d111
+a a b e112 e112 h112
+a b a i121 i121 l121
+a b b m122 m122 p122
+b a a a211 a211 d211
+b a b e212 e212 h212
+b b a i221 i221 l221
+b b b m222 m222 p222
+c a a a311 a311 d311
+c a b e312 e312 h312
+c b a i321 i321 l321
+c b b m322 m322 p322
+d a a a411 a411 d411
+d a b e412 e412 h412
+d b a i421 i421 l421
+d b b m422 m422 p422
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.c) and
+t2.c > 'b1' )
+group by a1,a2,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index
+2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+2 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index; FirstMatch(t2)
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.c) and
+t2.c > 'b1' )
+group by a1,a2,b;
+a1 a2 b c min(c) max(c)
+a a a a111 a111 d111
+a a b e112 e112 h112
+a b a i121 i121 l121
+a b b m122 m122 p122
+b a a a211 a211 d211
+b a b e212 e212 h212
+b b a i221 i221 l221
+b b b m222 m222 p222
+c a a a311 a311 d311
+c a b e312 e312 h312
+c b a i321 i321 l321
+c b b m322 m322 o322
+d a a a411 a411 d411
+d a b e412 e412 h412
+d b a i421 i421 l421
+d b b m422 m422 o422
+SET optimizer_switch=@save_optimizer_switch;
explain select a1,a2,b,min(c),max(c) from t1 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 17 Using where; Using index for group-by
@@ -1562,7 +1714,7 @@ explain extended select distinct a1,a2,b,c from t1 where (a2 >= 'b') and (b = 'a
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index NULL idx_t1_1 163 NULL 128 50.78 Using where; Using index
Warnings:
-Note 1003 select distinct `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`c` = 'i121') and (`test`.`t1`.`b` = 'a') and (`test`.`t1`.`a2` >= 'b'))
+Note 1003 select distinct `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`b` = 'a') and (`test`.`t1`.`c` = 'i121') and (`test`.`t1`.`a2` >= 'b'))
explain select distinct a1,a2,b from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 14 Using where; Using index for group-by
@@ -1579,7 +1731,7 @@ explain extended select distinct a1,a2,b,c from t2 where (a2 >= 'b') and (b = 'a
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 index NULL idx_t2_1 163 NULL 164 50.61 Using where; Using index
Warnings:
-Note 1003 select distinct `test`.`t2`.`a1` AS `a1`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where ((`test`.`t2`.`c` = 'i121') and (`test`.`t2`.`b` = 'a') and (`test`.`t2`.`a2` >= 'b'))
+Note 1003 select distinct `test`.`t2`.`a1` AS `a1`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where ((`test`.`t2`.`b` = 'a') and (`test`.`t2`.`c` = 'i121') and (`test`.`t2`.`a2` >= 'b'))
explain select distinct a1,a2,b from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 146 NULL # Using where; Using index for group-by
@@ -2246,17 +2398,18 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE EXISTS
(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 index
-2 SUBQUERY t1 index NULL a 10 NULL 15 Using index
+2 SUBQUERY t1 index NULL a 10 NULL 1 Using index
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
(SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 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
+1 PRIMARY t1_outer index NULL a 10 NULL 15 Using index
2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
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
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 8
+1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 2 Using index
+2 MATERIALIZED 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
@@ -2266,8 +2419,8 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer1 JOIN t1 AS t1_outer2
ON t1_outer1.a = (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2)
AND t1_outer1.b = t1_outer2.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_outer1 ref a a 5 const 1 Using where; Using index
-1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer
+1 PRIMARY t1_outer1 ref a a 5 const 2 Using where; Using index
+1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer (flat, BNL join)
2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
EXPLAIN SELECT (SELECT (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) x
FROM t1 AS t1_outer) x2 FROM t1 AS t1_outer2;
@@ -2444,7 +2597,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;
@@ -2603,7 +2756,7 @@ NULL
EXPLAIN
SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0);
id select_type table type possible_keys key key_len ref rows Extra
-x x x x x x x x x Impossible WHERE noticed after reading const tables
+x x x x x x x x x Using where; Using index
x x x x x x x x x Using where; Using index
SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0);
MIN( a )
@@ -2675,7 +2828,7 @@ NULL
EXPLAIN
SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0);
id select_type table type possible_keys key key_len ref rows Extra
-x x x x x x x x x Impossible WHERE noticed after reading const tables
+x x x x x x x x x Using where; Using index
x x x x x x x x x Using where; Using index
SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0);
MIN( a )
@@ -2754,7 +2907,7 @@ NULL
EXPLAIN
SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0);
id select_type table type possible_keys key key_len ref rows Extra
-x x x x x x x x x Impossible WHERE noticed after reading const tables
+x x x x x x x x x Using where; Using index
x x x x x x x x x Using where; Using index
SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0);
MIN( a )
@@ -2816,9 +2969,8 @@ SELECT alias1.* FROM t1, (SELECT * FROM t1) AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL b 5 NULL 10 Using index
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10 Using where; Using join buffer
-3 DEPENDENT SUBQUERY t1 index b b 5 NULL 10 Using where; Using index; Using temporary
-2 DERIVED t1 ALL NULL NULL NULL NULL 10
+1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
+3 DEPENDENT SUBQUERY t1 index b b 5 NULL 10 Using where; Using index
SELECT alias1.* FROM t1, (SELECT * FROM t1) AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
a b
@@ -2927,8 +3079,8 @@ SELECT alias1.* FROM t1, t1 AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL b 5 NULL 10 Using index
-1 PRIMARY alias1 ALL NULL NULL NULL NULL 10 Using where; Using join buffer
-2 DEPENDENT SUBQUERY t1 index b b 5 NULL 10 Using where; Using index; Using temporary
+1 PRIMARY alias1 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t1 index b b 5 NULL 10 Using where; Using index
SELECT alias1.* FROM t1, t1 AS alias1
WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
a b
@@ -3034,3 +3186,97 @@ a b
109 19
drop table t1;
End of 5.1 tests
+#
+# MDEV-765: LP:825075 - Wrong result with GROUP BY + multipart key + MIN/MAX loose scan
+#
+CREATE TABLE t1 (a varchar(1), b varchar(1), KEY (b,a));
+INSERT INTO t1 VALUES
+('0',NULL),('9',NULL),('8','c'),('4','d'),('7','d'),(NULL,'f'),
+('7','f'),('8','g'),(NULL,'j');
+explain
+SELECT max(a) , b FROM t1 WHERE a IS NULL OR b = 'z' GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index b b 8 NULL 9 Using where; Using index
+SELECT max(a) , b FROM t1 WHERE a IS NULL OR b = 'z' GROUP BY b;
+max(a) b
+NULL f
+NULL j
+explain
+SELECT b, min(a) FROM t1 WHERE a = '7' OR b = 'z' GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index b b 8 NULL 9 Using where; Using index
+SELECT b, min(a) FROM t1 WHERE a = '7' OR b = 'z' GROUP BY b;
+b min(a)
+d 7
+f 7
+explain
+SELECT b, min(a) FROM t1 WHERE (a = b OR b = 'd' OR b is NULL) GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index b b 8 NULL 9 Using where; Using index
+SELECT b, min(a) FROM t1 WHERE (a = b OR b = 'd' OR b is NULL) GROUP BY b;
+b min(a)
+NULL 0
+d 4
+explain
+SELECT b, min(a) FROM t1 WHERE a > ('0' = b) AND b = 'z' GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref b b 4 const 1 Using where; Using index
+SELECT b, min(a) FROM t1 WHERE a > ('0' = b) AND b = 'z' GROUP BY b;
+b min(a)
+explain
+SELECT b, min(a) FROM t1 WHERE a > '0' AND (b < (a = '7')) GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL b 8 NULL 9 Using where; Using index
+SELECT b, min(a) FROM t1 WHERE a > '0' AND (b < (a = '7')) GROUP BY b;
+b min(a)
+d 7
+f 7
+explain
+SELECT b, min(a) FROM t1 WHERE (a > '0' AND (a > '1' OR b = 'd')) GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index b b 8 NULL 9 Using where; Using index
+SELECT b, min(a) FROM t1 WHERE (a > '0' AND (a > '1' OR b = 'd')) GROUP BY b;
+b min(a)
+NULL 9
+c 8
+d 4
+f 7
+g 8
+drop table t1;
+#
+# MDEV-4140 Wrong result with GROUP BY + multipart key + MIN/MAX loose scan and a subquery
+#
+CREATE TABLE t1 (a int, b int, KEY (b, a)) ;
+INSERT INTO t1 VALUES (0,99),(9,99),(4,0),(7,0),(99,0),(7,0),(8,0),(99,0),(1,0);
+CREATE TABLE t2 (c int) ;
+INSERT INTO t2 VALUES (0),(1);
+EXPLAIN
+SELECT MIN(a), b FROM t1 WHERE a > 0 GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range NULL b 10 NULL 10 Using where; Using index for group-by
+SELECT MIN(a), b FROM t1 WHERE a > 0 GROUP BY b;
+MIN(a) b
+1 0
+9 99
+EXPLAIN
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT c FROM t2 WHERE c = 0 ) GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL b 10 NULL 9 Using where; Using index
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT c FROM t2 WHERE c = 0 ) GROUP BY b;
+MIN(a) b
+1 0
+9 99
+EXPLAIN
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT min(c) FROM t2, t1 t1a, t1 t1b WHERE c = 0 ) GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL b 10 NULL 9 Using where; Using index
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY t1a index NULL b 10 NULL 9 Using index; Using join buffer (flat, BNL join)
+2 SUBQUERY t1b index NULL b 10 NULL 9 Using index; Using join buffer (incremental, BNL join)
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT min(c) FROM t2, t1 t1a, t1 t1b WHERE c = 0 ) GROUP BY b;
+MIN(a) b
+1 0
+9 99
+drop table t1, t2;
+End of 5.3 tests
diff --git a/mysql-test/r/handlersocket.result b/mysql-test/r/handlersocket.result
new file mode 100644
index 00000000000..dcea3c186b6
--- /dev/null
+++ b/mysql-test/r/handlersocket.result
@@ -0,0 +1,13 @@
+install plugin handlersocket soname 'handlersocket.so';
+select plugin_name, plugin_version, plugin_status, plugin_type, plugin_library, plugin_library_version, plugin_author, plugin_description plugin_license, plugin_maturity, plugin_auth_version from information_schema.plugins where plugin_name = 'handlersocket';
+plugin_name handlersocket
+plugin_version 1.0
+plugin_status ACTIVE
+plugin_type DAEMON
+plugin_library handlersocket.so
+plugin_library_version 0.0
+plugin_author higuchi dot akira at dena dot jp
+plugin_license
+plugin_maturity Unknown
+plugin_auth_version Unknown
+uninstall plugin handlersocket;
diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result
index b5d3d6e30c2..4fe5fa3d50d 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -473,7 +473,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE table2 const PRIMARY PRIMARY 4 const 1 100.00 Using filesort
1 SIMPLE table1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
-Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having (('7' = 8) and (`test`.`table1`.`f1` >= 6))
+Note 1003 select `test`.`table1`.`f1` AS `f1`,7 AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where (`test`.`table1`.`f3` = 9) group by `test`.`table1`.`f1`,7 having ((7 = 8) and (`test`.`table1`.`f1` >= 6))
EXPLAIN EXTENDED
SELECT table1.f1, table2.f2
FROM t1 AS table1
@@ -485,7 +485,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE table2 const PRIMARY PRIMARY 4 const 1 100.00 Using filesort
1 SIMPLE table1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
-Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having ('7' = 8)
+Note 1003 select `test`.`table1`.`f1` AS `f1`,7 AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where (`test`.`table1`.`f3` = 9) group by `test`.`table1`.`f1`,7 having (7 = 8)
DROP TABLE t1;
#
# Bug#52336 Segfault / crash in 5.1 copy_fields (param=0x9872980) at sql_select.cc:15355
@@ -614,20 +614,24 @@ CREATE TABLE t2 (f2 int);
INSERT INTO t2 VALUES (7);
CREATE TABLE t3 (f3 int);
INSERT INTO t3 VALUES (0),(8);
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=off,materialization=off';
SELECT MIN( t1.f10 ) AS field1
FROM t1 , t2
WHERE t2.f2 IN ( SELECT f3 FROM t3 )
HAVING field1 < 's';
field1
-explain extended
+explain extended
SELECT MIN( t1.f10 ) AS field1
FROM t1 , t2
WHERE t2.f2 IN ( SELECT f3 FROM t3 )
HAVING field1 < 's';
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
+1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t1 index NULL f10 4 NULL 2 100.00 Using index
2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select min(`test`.`t1`.`f10`) AS `field1` from `test`.`t1` join `test`.`t2` where <in_optimizer>('7',<exists>(select 1 from `test`.`t3` where (<cache>('7') = `test`.`t3`.`f3`))) having (`field1` < 's')
+Note 1003 select min(`test`.`t1`.`f10`) AS `field1` from `test`.`t1` join `test`.`t2` where <expr_cache><7>(<in_optimizer>(7,<exists>(select `test`.`t3`.`f3` from `test`.`t3` where (<cache>(7) = `test`.`t3`.`f3`)))) having (`field1` < 's')
+set optimizer_switch=@save_optimizer_switch;
drop table t1,t2,t3;
End of 5.2 tests
diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result
index 6f99b3790d9..2aa7b9a3d62 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 a0872fb09c5..86d072ac3cf 100644
--- a/mysql-test/r/heap_hash.result
+++ b/mysql-test/r/heap_hash.result
@@ -401,3 +401,39 @@ pk val
2 NULL
1 NULL
drop table t1;
+End of 5.2 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/ignore_db_dirs_basic.result b/mysql-test/r/ignore_db_dirs_basic.result
new file mode 100644
index 00000000000..a0bbcb54f15
--- /dev/null
+++ b/mysql-test/r/ignore_db_dirs_basic.result
@@ -0,0 +1,47 @@
+select @@ignore_db_dirs;
+@@ignore_db_dirs
+e,lost+found,.mysqlgui,ignored_db
+# Check that SHOW DATABASES ignores all directories from
+# @@ignore_db_dirs and all directories with names starting
+# with '.'
+SHOW DATABASES;
+Database
+information_schema
+#mysql50#.otherdir
+mtr
+mysql
+test
+USE ignored_db;
+ERROR 42000: Incorrect database name 'ignored_db'
+SELECT * FROM ignored_db.t1;
+ERROR 42000: Incorrect database name 'ignored_db'
+CALL ignored_db.p1();
+ERROR 42000: Incorrect database name 'ignored_db'
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='ignored_db';
+COUNT(*)
+1
+CREATE DATABASE ignored_db;
+ERROR 42000: Incorrect database name 'ignored_db'
+CREATE DATABASE `lost+found`;
+USE `lost+found`;
+CREATE TABLE t1(id INT);
+INSERT INTO t1 VALUES (1), (2);
+SELECT * FROM `lost+found`.t1;
+id
+1
+2
+SHOW DATABASES;
+Database
+information_schema
+#mysql50#.otherdir
+lost+found
+mtr
+mysql
+test
+DROP DATABASE `lost+found`;
+SET @@global.ignore_db_dirs = 'aha';
+ERROR HY000: Variable 'ignore_db_dirs' is a read only variable
+SET @@local.ignore_db_dirs = 'aha';
+ERROR HY000: Variable 'ignore_db_dirs' is a read only variable
+SET @@ignore_db_dirs = 'aha';
+ERROR HY000: Variable 'ignore_db_dirs' is a read only variable
diff --git a/mysql-test/r/in_datetime_241.result b/mysql-test/r/in_datetime_241.result
new file mode 100644
index 00000000000..2c5b4bd8db1
--- /dev/null
+++ b/mysql-test/r/in_datetime_241.result
@@ -0,0 +1,5 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 ( a DATE );
+SELECT * FROM t1 WHERE ( SELECT a FROM t1 ) IN ('2012-04-25','2012-04-26');
+a
+DROP TABLE t1;
diff --git a/mysql-test/r/index_intersect.result b/mysql-test/r/index_intersect.result
new file mode 100644
index 00000000000..d36580d3764
--- /dev/null
+++ b/mysql-test/r/index_intersect.result
@@ -0,0 +1,1046 @@
+DROP TABLE IF EXISTS t1,t2,t3,t4;
+DROP DATABASE IF EXISTS world;
+set names utf8;
+CREATE DATABASE world;
+use world;
+CREATE TABLE Country (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL,
+PRIMARY KEY (Code),
+UNIQUE INDEX (Name)
+);
+CREATE TABLE City (
+ID int(11) NOT NULL auto_increment,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID),
+INDEX (Population),
+INDEX (Country)
+);
+CREATE TABLE CountryLanguage (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0',
+PRIMARY KEY (Country, Language),
+INDEX (Percentage)
+);
+SELECT COUNT(*) FROM Country;
+COUNT(*)
+239
+SELECT COUNT(*) FROM City;
+COUNT(*)
+4079
+SELECT COUNT(*) FROM CountryLanguage;
+COUNT(*)
+984
+CREATE INDEX Name ON City(Name);
+SET SESSION optimizer_switch='index_merge_sort_intersection=on';
+SELECT COUNT(*) FROM City;
+COUNT(*)
+4079
+SELECT COUNT(*) FROM City WHERE Name LIKE 'C%';
+COUNT(*)
+281
+SELECT COUNT(*) FROM City WHERE Name LIKE 'M%';
+COUNT(*)
+301
+SELECT COUNT(*) FROM City WHERE Population > 1000000;
+COUNT(*)
+237
+SELECT COUNT(*) FROM City WHERE Population > 1500000;
+COUNT(*)
+129
+SELECT COUNT(*) FROM City WHERE Population > 300000;
+COUNT(*)
+1062
+SELECT COUNT(*) FROM City WHERE Population > 7000000;
+COUNT(*)
+14
+EXPLAIN
+SELECT * FROM City WHERE
+Name LIKE 'C%' AND Population > 1000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name Name,Population 35,4 NULL # Using sort_intersect(Name,Population); Using where
+EXPLAIN
+SELECT * FROM City WHERE
+Name LIKE 'M%' AND Population > 1500000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 300000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Name Name 35 NULL # Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 7000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Name Population 4 NULL # Using index condition; Using where
+SELECT * FROM City USE INDEX ()
+WHERE Name LIKE 'C%' AND Population > 1000000;
+ID Name Country Population
+1026 Calcutta [Kolkata] IND 4399819
+1027 Chennai (Madras) IND 3841396
+151 Chittagong BGD 1392860
+1892 Chongqing CHN 6351600
+1898 Chengdu CHN 3361500
+1900 Changchun CHN 2812000
+1910 Changsha CHN 1809800
+212 Curitiba BRA 1584232
+2258 Cali COL 2077386
+2485 Casablanca MAR 2940623
+2515 Ciudad de México MEX 8591309
+3539 Caracas VEN 1975294
+3795 Chicago USA 2896016
+608 Cairo EGY 6789479
+71 Córdoba ARG 1157507
+712 Cape Town ZAF 2352121
+926 Conakry GIN 1090610
+SELECT * FROM City
+WHERE Name LIKE 'C%' AND Population > 1000000;
+ID Name Country Population
+1026 Calcutta [Kolkata] IND 4399819
+1027 Chennai (Madras) IND 3841396
+151 Chittagong BGD 1392860
+1892 Chongqing CHN 6351600
+1898 Chengdu CHN 3361500
+1900 Changchun CHN 2812000
+1910 Changsha CHN 1809800
+212 Curitiba BRA 1584232
+2258 Cali COL 2077386
+2485 Casablanca MAR 2940623
+2515 Ciudad de México MEX 8591309
+3539 Caracas VEN 1975294
+3795 Chicago USA 2896016
+608 Cairo EGY 6789479
+71 Córdoba ARG 1157507
+712 Cape Town ZAF 2352121
+926 Conakry GIN 1090610
+SELECT * FROM City USE INDEX ()
+WHERE Name LIKE 'M%' AND Population > 1500000;
+ID Name Country Population
+1024 Mumbai (Bombay) IND 10500000
+131 Melbourne AUS 2865329
+1381 Mashhad IRN 1887405
+2259 Medellín COL 1861265
+3520 Minsk BLR 1674000
+3580 Moscow RUS 8389200
+653 Madrid ESP 2879052
+766 Manila PHL 1581082
+942 Medan IDN 1843919
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 1500000;
+ID Name Country Population
+1024 Mumbai (Bombay) IND 10500000
+131 Melbourne AUS 2865329
+1381 Mashhad IRN 1887405
+2259 Medellín COL 1861265
+3520 Minsk BLR 1674000
+3580 Moscow RUS 8389200
+653 Madrid ESP 2879052
+766 Manila PHL 1581082
+942 Medan IDN 1843919
+SELECT * FROM City USE INDEX ()
+WHERE Name LIKE 'M%' AND Population > 300000;
+ID Name Country Population
+1024 Mumbai (Bombay) IND 10500000
+1042 Madurai IND 977856
+1051 Meerut IND 753778
+1074 Mysore IND 480692
+1081 Moradabad IND 429214
+1098 Malegaon IND 342595
+131 Melbourne AUS 2865329
+1366 Mosul IRQ 879000
+1381 Mashhad IRN 1887405
+1465 Milano ITA 1300977
+1559 Matsuyama JPN 466133
+1560 Matsudo JPN 461126
+1578 Machida JPN 364197
+1595 Miyazaki JPN 303784
+1810 Montréal CAN 1016376
+1816 Mississauga CAN 608072
+1882 Mombasa KEN 461753
+1945 Mudanjiang CHN 570000
+2005 Ma´anshan CHN 305421
+215 Manaus BRA 1255049
+223 Maceió BRA 786288
+2259 Medellín COL 1861265
+2267 Manizales COL 337580
+2300 Mbuji-Mayi COD 806475
+2348 Masan KOR 441242
+2440 Monrovia LBR 850000
+2454 Macao MAC 437500
+2487 Marrakech MAR 621914
+2491 Meknès MAR 460000
+250 Mauá BRA 375055
+2523 Monterrey MEX 1108499
+2526 Mexicali MEX 764902
+2530 Mérida MEX 703324
+2537 Morelia MEX 619958
+2554 Matamoros MEX 416428
+2557 Mazatlán MEX 380265
+256 Moji das Cruzes BRA 339194
+2698 Maputo MOZ 1018938
+2699 Matola MOZ 424662
+2711 Mandalay MMR 885300
+2712 Moulmein (Mawlamyine) MMR 307900
+2734 Managua NIC 959000
+2756 Mushin NGA 333200
+2757 Maiduguri NGA 320000
+2826 Multan PAK 1182441
+2975 Marseille FRA 798430
+3070 Munich [München] DEU 1194560
+3086 Mannheim DEU 307730
+3175 Mekka SAU 965700
+3176 Medina SAU 608300
+3214 Mogadishu SOM 997000
+3364 Mersin (Içel) TUR 587212
+3371 Malatya TUR 330312
+3434 Mykolajiv UKR 508000
+3435 Mariupol UKR 490000
+3438 Makijivka UKR 384000
+3492 Montevideo URY 1236000
+3520 Minsk BLR 1674000
+3522 Mogiljov BLR 356000
+3540 Maracaíbo VEN 1304776
+3545 Maracay VEN 444443
+3547 Maturín VEN 319726
+3580 Moscow RUS 8389200
+3622 Magnitogorsk RUS 427900
+3625 Murmansk RUS 376300
+3636 Mahat?kala RUS 332800
+3810 Memphis USA 650100
+3811 Milwaukee USA 596974
+3834 Mesa USA 396375
+3837 Minneapolis USA 382618
+3839 Miami USA 362470
+462 Manchester GBR 430000
+653 Madrid ESP 2879052
+658 Málaga ESP 530553
+661 Murcia ESP 353504
+766 Manila PHL 1581082
+77 Mar del Plata ARG 512880
+778 Makati PHL 444867
+781 Marikina PHL 391170
+783 Muntinlupa PHL 379310
+786 Malabon PHL 338855
+80 Merlo ARG 463846
+83 Moreno ARG 356993
+87 Morón ARG 349246
+942 Medan IDN 1843919
+947 Malang IDN 716862
+962 Manado IDN 332288
+963 Mataram IDN 306600
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 300000;
+ID Name Country Population
+1024 Mumbai (Bombay) IND 10500000
+1042 Madurai IND 977856
+1051 Meerut IND 753778
+1074 Mysore IND 480692
+1081 Moradabad IND 429214
+1098 Malegaon IND 342595
+131 Melbourne AUS 2865329
+1366 Mosul IRQ 879000
+1381 Mashhad IRN 1887405
+1465 Milano ITA 1300977
+1559 Matsuyama JPN 466133
+1560 Matsudo JPN 461126
+1578 Machida JPN 364197
+1595 Miyazaki JPN 303784
+1810 Montréal CAN 1016376
+1816 Mississauga CAN 608072
+1882 Mombasa KEN 461753
+1945 Mudanjiang CHN 570000
+2005 Ma´anshan CHN 305421
+215 Manaus BRA 1255049
+223 Maceió BRA 786288
+2259 Medellín COL 1861265
+2267 Manizales COL 337580
+2300 Mbuji-Mayi COD 806475
+2348 Masan KOR 441242
+2440 Monrovia LBR 850000
+2454 Macao MAC 437500
+2487 Marrakech MAR 621914
+2491 Meknès MAR 460000
+250 Mauá BRA 375055
+2523 Monterrey MEX 1108499
+2526 Mexicali MEX 764902
+2530 Mérida MEX 703324
+2537 Morelia MEX 619958
+2554 Matamoros MEX 416428
+2557 Mazatlán MEX 380265
+256 Moji das Cruzes BRA 339194
+2698 Maputo MOZ 1018938
+2699 Matola MOZ 424662
+2711 Mandalay MMR 885300
+2712 Moulmein (Mawlamyine) MMR 307900
+2734 Managua NIC 959000
+2756 Mushin NGA 333200
+2757 Maiduguri NGA 320000
+2826 Multan PAK 1182441
+2975 Marseille FRA 798430
+3070 Munich [München] DEU 1194560
+3086 Mannheim DEU 307730
+3175 Mekka SAU 965700
+3176 Medina SAU 608300
+3214 Mogadishu SOM 997000
+3364 Mersin (Içel) TUR 587212
+3371 Malatya TUR 330312
+3434 Mykolajiv UKR 508000
+3435 Mariupol UKR 490000
+3438 Makijivka UKR 384000
+3492 Montevideo URY 1236000
+3520 Minsk BLR 1674000
+3522 Mogiljov BLR 356000
+3540 Maracaíbo VEN 1304776
+3545 Maracay VEN 444443
+3547 Maturín VEN 319726
+3580 Moscow RUS 8389200
+3622 Magnitogorsk RUS 427900
+3625 Murmansk RUS 376300
+3636 Mahat?kala RUS 332800
+3810 Memphis USA 650100
+3811 Milwaukee USA 596974
+3834 Mesa USA 396375
+3837 Minneapolis USA 382618
+3839 Miami USA 362470
+462 Manchester GBR 430000
+653 Madrid ESP 2879052
+658 Málaga ESP 530553
+661 Murcia ESP 353504
+766 Manila PHL 1581082
+77 Mar del Plata ARG 512880
+778 Makati PHL 444867
+781 Marikina PHL 391170
+783 Muntinlupa PHL 379310
+786 Malabon PHL 338855
+80 Merlo ARG 463846
+83 Moreno ARG 356993
+87 Morón ARG 349246
+942 Medan IDN 1843919
+947 Malang IDN 716862
+962 Manado IDN 332288
+963 Mataram IDN 306600
+SELECT * FROM City USE INDEX ()
+WHERE Name LIKE 'M%' AND Population > 7000000;
+ID Name Country Population
+1024 Mumbai (Bombay) IND 10500000
+3580 Moscow RUS 8389200
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 7000000;
+ID Name Country Population
+3580 Moscow RUS 8389200
+1024 Mumbai (Bombay) IND 10500000
+SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N';
+COUNT(*)
+301
+SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'J';
+COUNT(*)
+408
+SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'K';
+COUNT(*)
+512
+SELECT COUNT(*) FROM City WHERE Population > 1000000;
+COUNT(*)
+237
+SELECT COUNT(*) FROM City WHERE Population > 500000;
+COUNT(*)
+539
+SELECT COUNT(*) FROM City WHERE Country LIKE 'C%';
+COUNT(*)
+551
+SELECT COUNT(*) FROM City WHERE Country LIKE 'B%';
+COUNT(*)
+339
+EXPLAIN
+SELECT * FROM City
+WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Name,Population 35,4 NULL # Using sort_intersect(Name,Population); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Population,Country 4,3 NULL # Using sort_intersect(Population,Country); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Name,Country Name # NULL # Using index condition; Using where
+SELECT * FROM City USE INDEX ()
+WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
+ID Name Country Population
+1810 Montréal CAN 1016376
+2259 Medellín COL 1861265
+SELECT * FROM City
+WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
+ID Name Country Population
+1810 Montréal CAN 1016376
+2259 Medellín COL 1861265
+SELECT * FROM City USE INDEX ()
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
+ID Name Country Population
+217 Guarulhos BRA 1095874
+218 Goiânia BRA 1056330
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
+ID Name Country Population
+217 Guarulhos BRA 1095874
+218 Goiânia BRA 1056330
+SELECT * FROM City USE INDEX ()
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+ID Name Country Population
+1895 Harbin CHN 4289800
+1904 Jinan CHN 2278100
+1905 Hangzhou CHN 2190500
+1914 Guiyang CHN 1465200
+1916 Hefei CHN 1369100
+1923 Jilin CHN 1040000
+1927 Hohhot CHN 916700
+1928 Handan CHN 840000
+1937 Huainan CHN 700000
+1938 Jixi CHN 683885
+1944 Jinzhou CHN 570000
+1950 Hegang CHN 520000
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+ID Name Country Population
+1914 Guiyang CHN 1465200
+1928 Handan CHN 840000
+1905 Hangzhou CHN 2190500
+1895 Harbin CHN 4289800
+1916 Hefei CHN 1369100
+1950 Hegang CHN 520000
+1927 Hohhot CHN 916700
+1937 Huainan CHN 700000
+1923 Jilin CHN 1040000
+1904 Jinan CHN 2278100
+1944 Jinzhou CHN 570000
+1938 Jixi CHN 683885
+SELECT COUNT(*) FROM City WHERE ID BETWEEN 501 AND 1000;
+COUNT(*)
+500
+SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 500;
+COUNT(*)
+500
+SELECT COUNT(*) FROM City WHERE ID BETWEEN 2001 AND 2500;
+COUNT(*)
+500
+SELECT COUNT(*) FROM City WHERE ID BETWEEN 3701 AND 4000;
+COUNT(*)
+300
+SELECT COUNT(*) FROM City WHERE Population > 700000;
+COUNT(*)
+358
+SELECT COUNT(*) FROM City WHERE Population > 1000000;
+COUNT(*)
+237
+SELECT COUNT(*) FROM City WHERE Population > 300000;
+COUNT(*)
+1062
+SELECT COUNT(*) FROM City WHERE Population > 600000;
+COUNT(*)
+428
+SELECT COUNT(*) FROM City WHERE Country LIKE 'C%';
+COUNT(*)
+551
+SELECT COUNT(*) FROM City WHERE Country LIKE 'A%';
+COUNT(*)
+107
+SELECT COUNT(*) FROM City WHERE Country LIKE 'H%';
+COUNT(*)
+22
+SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z';
+COUNT(*)
+682
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country Country,Population 3,4 NULL # Using sort_intersect(Country,Population); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY,Population,Country Country 3 NULL # Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000
+AND Country BETWEEN 'S' AND 'Z';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country Population,PRIMARY 4,4 NULL # Using sort_intersect(Population,PRIMARY); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+AND Country BETWEEN 'S' AND 'Z' ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using index condition; Using where
+SELECT * FROM City USE INDEX ()
+WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
+ID Name Country Population
+554 Santiago de Chile CHL 4703954
+SELECT * FROM City
+WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
+ID Name Country Population
+554 Santiago de Chile CHL 4703954
+SELECT * FROM City USE INDEX ()
+WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+ID Name Country Population
+1 Kabul AFG 1780000
+126 Yerevan ARM 1248700
+130 Sydney AUS 3276207
+131 Melbourne AUS 2865329
+132 Brisbane AUS 1291117
+133 Perth AUS 1096829
+144 Baku AZE 1787800
+56 Luanda AGO 2022000
+69 Buenos Aires ARG 2982146
+70 La Matanza ARG 1266461
+71 Córdoba ARG 1157507
+SELECT * FROM City
+WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+ID Name Country Population
+1 Kabul AFG 1780000
+126 Yerevan ARM 1248700
+130 Sydney AUS 3276207
+131 Melbourne AUS 2865329
+132 Brisbane AUS 1291117
+133 Perth AUS 1096829
+144 Baku AZE 1787800
+56 Luanda AGO 2022000
+69 Buenos Aires ARG 2982146
+70 La Matanza ARG 1266461
+71 Córdoba ARG 1157507
+SELECT * FROM City USE INDEX ()
+WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%';
+ID Name Country Population
+2409 Zagreb HRV 706770
+SELECT * FROM City
+WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%';
+ID Name Country Population
+2409 Zagreb HRV 706770
+SELECT * FROM City USE INDEX ()
+WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000
+AND Country BETWEEN 'S' AND 'Z';
+ID Name Country Population
+3769 Ho Chi Minh City VNM 3980000
+3770 Hanoi VNM 1410000
+3771 Haiphong VNM 783133
+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
+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
+SELECT * FROM City
+WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000
+AND Country BETWEEN 'S' AND 'Z';
+ID Name Country Population
+3769 Ho Chi Minh City VNM 3980000
+3770 Hanoi VNM 1410000
+3771 Haiphong VNM 783133
+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
+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
+SELECT * FROM City USE INDEX ()
+WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+AND Country BETWEEN 'S' AND 'Z' ;
+ID Name Country Population
+3048 Stockholm SWE 750348
+3173 Riyadh SAU 3324000
+3174 Jedda SAU 2046300
+3175 Mekka SAU 965700
+3176 Medina SAU 608300
+3197 Pikine SEN 855287
+3198 Dakar SEN 785071
+3207 Freetown SLE 850000
+3208 Singapore SGP 4017733
+3214 Mogadishu SOM 997000
+3224 Omdurman SDN 1271403
+3225 Khartum SDN 947483
+3226 Sharq al-Nil SDN 700887
+3250 Damascus SYR 1347000
+3251 Aleppo SYR 1261983
+3263 Taipei TWN 2641312
+3264 Kaohsiung TWN 1475505
+3265 Taichung TWN 940589
+3266 Tainan TWN 728060
+3305 Dar es Salaam TZA 1747000
+3320 Bangkok THA 6320174
+3349 Tunis TUN 690600
+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
+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
+3492 Montevideo URY 1236000
+3503 Toskent UZB 2117500
+3539 Caracas VEN 1975294
+3540 Maracaíbo VEN 1304776
+3541 Barquisimeto VEN 877239
+3542 Valencia VEN 794246
+3543 Ciudad Guayana VEN 663713
+3769 Ho Chi Minh City VNM 3980000
+3770 Hanoi VNM 1410000
+3771 Haiphong VNM 783133
+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
+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
+SELECT * FROM City
+WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+AND Country BETWEEN 'S' AND 'Z' ;
+ID Name Country Population
+3048 Stockholm SWE 750348
+3173 Riyadh SAU 3324000
+3174 Jedda SAU 2046300
+3175 Mekka SAU 965700
+3176 Medina SAU 608300
+3197 Pikine SEN 855287
+3198 Dakar SEN 785071
+3207 Freetown SLE 850000
+3208 Singapore SGP 4017733
+3214 Mogadishu SOM 997000
+3224 Omdurman SDN 1271403
+3225 Khartum SDN 947483
+3226 Sharq al-Nil SDN 700887
+3250 Damascus SYR 1347000
+3251 Aleppo SYR 1261983
+3263 Taipei TWN 2641312
+3264 Kaohsiung TWN 1475505
+3265 Taichung TWN 940589
+3266 Tainan TWN 728060
+3305 Dar es Salaam TZA 1747000
+3320 Bangkok THA 6320174
+3349 Tunis TUN 690600
+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
+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
+3492 Montevideo URY 1236000
+3503 Toskent UZB 2117500
+3539 Caracas VEN 1975294
+3540 Maracaíbo VEN 1304776
+3541 Barquisimeto VEN 877239
+3542 Valencia VEN 794246
+3543 Ciudad Guayana VEN 663713
+3769 Ho Chi Minh City VNM 3980000
+3770 Hanoi VNM 1410000
+3771 Haiphong VNM 783133
+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
+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
+SET SESSION sort_buffer_size = 2048;
+EXPLAIN
+SELECT * FROM City WHERE
+Name LIKE 'C%' AND Population > 1000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name Name,Population 35,4 NULL # Using sort_intersect(Name,Population); Using where
+EXPLAIN
+SELECT * FROM City WHERE
+Name LIKE 'M%' AND Population > 1500000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Population,Country 4,3 NULL # Using sort_intersect(Population,Country); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country,Name Name 35 NULL # Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country Country,Population 3,4 NULL # Using sort_intersect(Country,Population); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+AND Country BETWEEN 'S' AND 'Z';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using index condition; Using where
+SELECT * FROM City WHERE
+Name LIKE 'C%' AND Population > 1000000;
+ID Name Country Population
+1026 Calcutta [Kolkata] IND 4399819
+1027 Chennai (Madras) IND 3841396
+151 Chittagong BGD 1392860
+1892 Chongqing CHN 6351600
+1898 Chengdu CHN 3361500
+1900 Changchun CHN 2812000
+1910 Changsha CHN 1809800
+212 Curitiba BRA 1584232
+2258 Cali COL 2077386
+2485 Casablanca MAR 2940623
+2515 Ciudad de México MEX 8591309
+3539 Caracas VEN 1975294
+3795 Chicago USA 2896016
+608 Cairo EGY 6789479
+71 Córdoba ARG 1157507
+712 Cape Town ZAF 2352121
+926 Conakry GIN 1090610
+SELECT * FROM City WHERE
+Name LIKE 'M%' AND Population > 1500000;
+ID Name Country Population
+131 Melbourne AUS 2865329
+653 Madrid ESP 2879052
+766 Manila PHL 1581082
+942 Medan IDN 1843919
+1024 Mumbai (Bombay) IND 10500000
+1381 Mashhad IRN 1887405
+2259 Medellín COL 1861265
+3520 Minsk BLR 1674000
+3580 Moscow RUS 8389200
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'B%';
+ID Name Country Population
+217 Guarulhos BRA 1095874
+218 Goiânia BRA 1056330
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+ID Name Country Population
+1914 Guiyang CHN 1465200
+1928 Handan CHN 840000
+1905 Hangzhou CHN 2190500
+1895 Harbin CHN 4289800
+1916 Hefei CHN 1369100
+1950 Hegang CHN 520000
+1927 Hohhot CHN 916700
+1937 Huainan CHN 700000
+SELECT * FROM City
+WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+ID Name Country Population
+1 Kabul AFG 1780000
+56 Luanda AGO 2022000
+69 Buenos Aires ARG 2982146
+70 La Matanza ARG 1266461
+71 Córdoba ARG 1157507
+126 Yerevan ARM 1248700
+130 Sydney AUS 3276207
+131 Melbourne AUS 2865329
+132 Brisbane AUS 1291117
+133 Perth AUS 1096829
+144 Baku AZE 1787800
+SELECT * FROM City
+WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+AND Country BETWEEN 'S' AND 'Z';
+ID Name Country Population
+3048 Stockholm SWE 750348
+3173 Riyadh SAU 3324000
+3174 Jedda SAU 2046300
+3175 Mekka SAU 965700
+3176 Medina SAU 608300
+3197 Pikine SEN 855287
+3198 Dakar SEN 785071
+3207 Freetown SLE 850000
+3208 Singapore SGP 4017733
+3214 Mogadishu SOM 997000
+3224 Omdurman SDN 1271403
+3225 Khartum SDN 947483
+3226 Sharq al-Nil SDN 700887
+3250 Damascus SYR 1347000
+3251 Aleppo SYR 1261983
+3263 Taipei TWN 2641312
+3264 Kaohsiung TWN 1475505
+3265 Taichung TWN 940589
+3266 Tainan TWN 728060
+3305 Dar es Salaam TZA 1747000
+3320 Bangkok THA 6320174
+3349 Tunis TUN 690600
+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
+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
+3492 Montevideo URY 1236000
+3503 Toskent UZB 2117500
+3539 Caracas VEN 1975294
+3540 Maracaíbo VEN 1304776
+3541 Barquisimeto VEN 877239
+3542 Valencia VEN 794246
+3543 Ciudad Guayana VEN 663713
+3769 Ho Chi Minh City VNM 3980000
+3770 Hanoi VNM 1410000
+3771 Haiphong VNM 783133
+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
+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
+SET SESSION sort_buffer_size = default;
+DROP INDEX Country ON City;
+CREATE INDEX CountryID ON City(Country,ID);
+CREATE INDEX CountryName ON City(Country,Name);
+EXPLAIN
+SELECT * FROM City
+WHERE Country LIKE 'M%' AND Population > 1000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,CountryID,CountryName Population,CountryID 4,3 NULL # Using sort_intersect(Population,CountryID); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Country='CHN' AND Population > 1500000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,CountryID,CountryName Population,CountryID 4,3 NULL # Using sort_intersect(Population,CountryID); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name,CountryID,CountryName CountryName,Population 38,4 NULL # Using sort_intersect(CountryName,Population); Using where
+SELECT * FROM City USE INDEX ()
+WHERE Country LIKE 'M%' AND Population > 1000000;
+ID Name Country Population
+2464 Kuala Lumpur MYS 1297526
+2485 Casablanca MAR 2940623
+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
+2698 Maputo MOZ 1018938
+2710 Rangoon (Yangon) MMR 3361700
+SELECT * FROM City
+WHERE Country LIKE 'M%' AND Population > 1000000;
+ID Name Country Population
+2464 Kuala Lumpur MYS 1297526
+2485 Casablanca MAR 2940623
+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
+2698 Maputo MOZ 1018938
+2710 Rangoon (Yangon) MMR 3361700
+SELECT * FROM City USE INDEX ()
+WHERE Country='CHN' AND Population > 1500000;
+ID Name Country Population
+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
+SELECT * FROM City
+WHERE Country='CHN' AND Population > 1500000;
+ID Name Country Population
+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
+SELECT * FROM City USE INDEX ()
+WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%';
+ID Name Country Population
+1892 Chongqing CHN 6351600
+1898 Chengdu CHN 3361500
+1900 Changchun CHN 2812000
+1910 Changsha CHN 1809800
+SELECT * FROM City
+WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%';
+ID Name Country Population
+1892 Chongqing CHN 6351600
+1898 Chengdu CHN 3361500
+1900 Changchun CHN 2812000
+1910 Changsha CHN 1809800
+EXPLAIN
+SELECT * FROM City, Country
+WHERE City.Name LIKE 'C%' AND City.Population > 1000000 AND
+Country.Code=City.Country;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name,CountryID,CountryName Name,Population 35,4 NULL # Using sort_intersect(Name,Population); Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country #
+DROP DATABASE world;
+use test;
+CREATE TABLE t1 (
+f1 int,
+f4 varchar(32),
+f5 int,
+PRIMARY KEY (f1),
+KEY (f4)
+) ENGINE=InnoDB;
+Warnings:
+Warning 1286 Unknown table engine 'InnoDB'
+Warning 1266 Using storage engine MyISAM for table 't1'
+INSERT INTO t1 VALUES
+(5,'H',1), (9,'g',0), (527,'i',0), (528,'y',1), (529,'S',6),
+(530,'m',7), (531,'b',2), (532,'N',1), (533,'V',NULL), (534,'l',1),
+(535,'M',0), (536,'w',1), (537,'j',5), (538,'l',0), (539,'n',2),
+(540,'m',2), (541,'r',2), (542,'l',2), (543,'h',3),(544,'o',0),
+(956,'h',0), (957,'g',0), (958,'W',5), (959,'s',3), (960,'w',0),
+(961,'q',0), (962,'e',NULL), (963,'u',7), (964,'q',1), (965,'N',NULL),
+(966,'e',0), (967,'t',3), (968,'e',6), (969,'f',NULL), (970,'j',0),
+(971,'s',3), (972,'I',0), (973,'h',4), (974,'g',1), (975,'s',0),
+(976,'r',3), (977,'x',1), (978,'v',8), (979,'j',NULL), (980,'z',7),
+(981,'t',9), (982,'j',5), (983,'u',NULL), (984,'g',6), (985,'w',1),
+(986,'h',1), (987,'v',0), (988,'v',0), (989,'c',2), (990,'b',7),
+(991,'z',0), (992,'M',1), (993,'u',2), (994,'r',2), (995,'b',4),
+(996,'A',2), (997,'u',0), (998,'a',0), (999,'j',2), (1,'I',2);
+EXPLAIN
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,f4 f4 35 NULL # Using index condition; Using where
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+f1 f4 f5
+996 A 2
+998 a 0
+994 r 2
+DROP TABLE t1;
+SET SESSION optimizer_switch='index_merge_sort_intersection=on';
diff --git a/mysql-test/r/index_intersect_innodb.result b/mysql-test/r/index_intersect_innodb.result
new file mode 100644
index 00000000000..878d6a5cc8e
--- /dev/null
+++ b/mysql-test/r/index_intersect_innodb.result
@@ -0,0 +1,1045 @@
+SET SESSION STORAGE_ENGINE='InnoDB';
+DROP TABLE IF EXISTS t1,t2,t3,t4;
+DROP DATABASE IF EXISTS world;
+set names utf8;
+CREATE DATABASE world;
+use world;
+CREATE TABLE Country (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL,
+PRIMARY KEY (Code),
+UNIQUE INDEX (Name)
+);
+CREATE TABLE City (
+ID int(11) NOT NULL auto_increment,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID),
+INDEX (Population),
+INDEX (Country)
+);
+CREATE TABLE CountryLanguage (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0',
+PRIMARY KEY (Country, Language),
+INDEX (Percentage)
+);
+SELECT COUNT(*) FROM Country;
+COUNT(*)
+239
+SELECT COUNT(*) FROM City;
+COUNT(*)
+4079
+SELECT COUNT(*) FROM CountryLanguage;
+COUNT(*)
+984
+CREATE INDEX Name ON City(Name);
+SET SESSION optimizer_switch='index_merge_sort_intersection=on';
+SELECT COUNT(*) FROM City;
+COUNT(*)
+4079
+SELECT COUNT(*) FROM City WHERE Name LIKE 'C%';
+COUNT(*)
+281
+SELECT COUNT(*) FROM City WHERE Name LIKE 'M%';
+COUNT(*)
+301
+SELECT COUNT(*) FROM City WHERE Population > 1000000;
+COUNT(*)
+237
+SELECT COUNT(*) FROM City WHERE Population > 1500000;
+COUNT(*)
+129
+SELECT COUNT(*) FROM City WHERE Population > 300000;
+COUNT(*)
+1062
+SELECT COUNT(*) FROM City WHERE Population > 7000000;
+COUNT(*)
+14
+EXPLAIN
+SELECT * FROM City WHERE
+Name LIKE 'C%' AND Population > 1000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where
+EXPLAIN
+SELECT * FROM City WHERE
+Name LIKE 'M%' AND Population > 1500000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 300000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name Name,Population 35,4 NULL # Using sort_intersect(Name,Population); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 7000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where
+SELECT * FROM City USE INDEX ()
+WHERE Name LIKE 'C%' AND Population > 1000000;
+ID Name Country Population
+1026 Calcutta [Kolkata] IND 4399819
+1027 Chennai (Madras) IND 3841396
+151 Chittagong BGD 1392860
+1892 Chongqing CHN 6351600
+1898 Chengdu CHN 3361500
+1900 Changchun CHN 2812000
+1910 Changsha CHN 1809800
+212 Curitiba BRA 1584232
+2258 Cali COL 2077386
+2485 Casablanca MAR 2940623
+2515 Ciudad de México MEX 8591309
+3539 Caracas VEN 1975294
+3795 Chicago USA 2896016
+608 Cairo EGY 6789479
+71 Córdoba ARG 1157507
+712 Cape Town ZAF 2352121
+926 Conakry GIN 1090610
+SELECT * FROM City
+WHERE Name LIKE 'C%' AND Population > 1000000;
+ID Name Country Population
+1026 Calcutta [Kolkata] IND 4399819
+1027 Chennai (Madras) IND 3841396
+151 Chittagong BGD 1392860
+1892 Chongqing CHN 6351600
+1898 Chengdu CHN 3361500
+1900 Changchun CHN 2812000
+1910 Changsha CHN 1809800
+212 Curitiba BRA 1584232
+2258 Cali COL 2077386
+2485 Casablanca MAR 2940623
+2515 Ciudad de México MEX 8591309
+3539 Caracas VEN 1975294
+3795 Chicago USA 2896016
+608 Cairo EGY 6789479
+71 Córdoba ARG 1157507
+712 Cape Town ZAF 2352121
+926 Conakry GIN 1090610
+SELECT * FROM City USE INDEX ()
+WHERE Name LIKE 'M%' AND Population > 1500000;
+ID Name Country Population
+1024 Mumbai (Bombay) IND 10500000
+131 Melbourne AUS 2865329
+1381 Mashhad IRN 1887405
+2259 Medellín COL 1861265
+3520 Minsk BLR 1674000
+3580 Moscow RUS 8389200
+653 Madrid ESP 2879052
+766 Manila PHL 1581082
+942 Medan IDN 1843919
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 1500000;
+ID Name Country Population
+1024 Mumbai (Bombay) IND 10500000
+131 Melbourne AUS 2865329
+1381 Mashhad IRN 1887405
+2259 Medellín COL 1861265
+3520 Minsk BLR 1674000
+3580 Moscow RUS 8389200
+653 Madrid ESP 2879052
+766 Manila PHL 1581082
+942 Medan IDN 1843919
+SELECT * FROM City USE INDEX ()
+WHERE Name LIKE 'M%' AND Population > 300000;
+ID Name Country Population
+1024 Mumbai (Bombay) IND 10500000
+1042 Madurai IND 977856
+1051 Meerut IND 753778
+1074 Mysore IND 480692
+1081 Moradabad IND 429214
+1098 Malegaon IND 342595
+131 Melbourne AUS 2865329
+1366 Mosul IRQ 879000
+1381 Mashhad IRN 1887405
+1465 Milano ITA 1300977
+1559 Matsuyama JPN 466133
+1560 Matsudo JPN 461126
+1578 Machida JPN 364197
+1595 Miyazaki JPN 303784
+1810 Montréal CAN 1016376
+1816 Mississauga CAN 608072
+1882 Mombasa KEN 461753
+1945 Mudanjiang CHN 570000
+2005 Ma´anshan CHN 305421
+215 Manaus BRA 1255049
+223 Maceió BRA 786288
+2259 Medellín COL 1861265
+2267 Manizales COL 337580
+2300 Mbuji-Mayi COD 806475
+2348 Masan KOR 441242
+2440 Monrovia LBR 850000
+2454 Macao MAC 437500
+2487 Marrakech MAR 621914
+2491 Meknès MAR 460000
+250 Mauá BRA 375055
+2523 Monterrey MEX 1108499
+2526 Mexicali MEX 764902
+2530 Mérida MEX 703324
+2537 Morelia MEX 619958
+2554 Matamoros MEX 416428
+2557 Mazatlán MEX 380265
+256 Moji das Cruzes BRA 339194
+2698 Maputo MOZ 1018938
+2699 Matola MOZ 424662
+2711 Mandalay MMR 885300
+2712 Moulmein (Mawlamyine) MMR 307900
+2734 Managua NIC 959000
+2756 Mushin NGA 333200
+2757 Maiduguri NGA 320000
+2826 Multan PAK 1182441
+2975 Marseille FRA 798430
+3070 Munich [München] DEU 1194560
+3086 Mannheim DEU 307730
+3175 Mekka SAU 965700
+3176 Medina SAU 608300
+3214 Mogadishu SOM 997000
+3364 Mersin (Içel) TUR 587212
+3371 Malatya TUR 330312
+3434 Mykolajiv UKR 508000
+3435 Mariupol UKR 490000
+3438 Makijivka UKR 384000
+3492 Montevideo URY 1236000
+3520 Minsk BLR 1674000
+3522 Mogiljov BLR 356000
+3540 Maracaíbo VEN 1304776
+3545 Maracay VEN 444443
+3547 Maturín VEN 319726
+3580 Moscow RUS 8389200
+3622 Magnitogorsk RUS 427900
+3625 Murmansk RUS 376300
+3636 Mahat?kala RUS 332800
+3810 Memphis USA 650100
+3811 Milwaukee USA 596974
+3834 Mesa USA 396375
+3837 Minneapolis USA 382618
+3839 Miami USA 362470
+462 Manchester GBR 430000
+653 Madrid ESP 2879052
+658 Málaga ESP 530553
+661 Murcia ESP 353504
+766 Manila PHL 1581082
+77 Mar del Plata ARG 512880
+778 Makati PHL 444867
+781 Marikina PHL 391170
+783 Muntinlupa PHL 379310
+786 Malabon PHL 338855
+80 Merlo ARG 463846
+83 Moreno ARG 356993
+87 Morón ARG 349246
+942 Medan IDN 1843919
+947 Malang IDN 716862
+962 Manado IDN 332288
+963 Mataram IDN 306600
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 300000;
+ID Name Country Population
+1024 Mumbai (Bombay) IND 10500000
+1042 Madurai IND 977856
+1051 Meerut IND 753778
+1074 Mysore IND 480692
+1081 Moradabad IND 429214
+1098 Malegaon IND 342595
+131 Melbourne AUS 2865329
+1366 Mosul IRQ 879000
+1381 Mashhad IRN 1887405
+1465 Milano ITA 1300977
+1559 Matsuyama JPN 466133
+1560 Matsudo JPN 461126
+1578 Machida JPN 364197
+1595 Miyazaki JPN 303784
+1810 Montréal CAN 1016376
+1816 Mississauga CAN 608072
+1882 Mombasa KEN 461753
+1945 Mudanjiang CHN 570000
+2005 Ma´anshan CHN 305421
+215 Manaus BRA 1255049
+223 Maceió BRA 786288
+2259 Medellín COL 1861265
+2267 Manizales COL 337580
+2300 Mbuji-Mayi COD 806475
+2348 Masan KOR 441242
+2440 Monrovia LBR 850000
+2454 Macao MAC 437500
+2487 Marrakech MAR 621914
+2491 Meknès MAR 460000
+250 Mauá BRA 375055
+2523 Monterrey MEX 1108499
+2526 Mexicali MEX 764902
+2530 Mérida MEX 703324
+2537 Morelia MEX 619958
+2554 Matamoros MEX 416428
+2557 Mazatlán MEX 380265
+256 Moji das Cruzes BRA 339194
+2698 Maputo MOZ 1018938
+2699 Matola MOZ 424662
+2711 Mandalay MMR 885300
+2712 Moulmein (Mawlamyine) MMR 307900
+2734 Managua NIC 959000
+2756 Mushin NGA 333200
+2757 Maiduguri NGA 320000
+2826 Multan PAK 1182441
+2975 Marseille FRA 798430
+3070 Munich [München] DEU 1194560
+3086 Mannheim DEU 307730
+3175 Mekka SAU 965700
+3176 Medina SAU 608300
+3214 Mogadishu SOM 997000
+3364 Mersin (Içel) TUR 587212
+3371 Malatya TUR 330312
+3434 Mykolajiv UKR 508000
+3435 Mariupol UKR 490000
+3438 Makijivka UKR 384000
+3492 Montevideo URY 1236000
+3520 Minsk BLR 1674000
+3522 Mogiljov BLR 356000
+3540 Maracaíbo VEN 1304776
+3545 Maracay VEN 444443
+3547 Maturín VEN 319726
+3580 Moscow RUS 8389200
+3622 Magnitogorsk RUS 427900
+3625 Murmansk RUS 376300
+3636 Mahat?kala RUS 332800
+3810 Memphis USA 650100
+3811 Milwaukee USA 596974
+3834 Mesa USA 396375
+3837 Minneapolis USA 382618
+3839 Miami USA 362470
+462 Manchester GBR 430000
+653 Madrid ESP 2879052
+658 Málaga ESP 530553
+661 Murcia ESP 353504
+766 Manila PHL 1581082
+77 Mar del Plata ARG 512880
+778 Makati PHL 444867
+781 Marikina PHL 391170
+783 Muntinlupa PHL 379310
+786 Malabon PHL 338855
+80 Merlo ARG 463846
+83 Moreno ARG 356993
+87 Morón ARG 349246
+942 Medan IDN 1843919
+947 Malang IDN 716862
+962 Manado IDN 332288
+963 Mataram IDN 306600
+SELECT * FROM City USE INDEX ()
+WHERE Name LIKE 'M%' AND Population > 7000000;
+ID Name Country Population
+1024 Mumbai (Bombay) IND 10500000
+3580 Moscow RUS 8389200
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 7000000;
+ID Name Country Population
+1024 Mumbai (Bombay) IND 10500000
+3580 Moscow RUS 8389200
+SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N';
+COUNT(*)
+301
+SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'J';
+COUNT(*)
+408
+SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'K';
+COUNT(*)
+512
+SELECT COUNT(*) FROM City WHERE Population > 1000000;
+COUNT(*)
+237
+SELECT COUNT(*) FROM City WHERE Population > 500000;
+COUNT(*)
+539
+SELECT COUNT(*) FROM City WHERE Country LIKE 'C%';
+COUNT(*)
+551
+SELECT COUNT(*) FROM City WHERE Country LIKE 'B%';
+COUNT(*)
+339
+EXPLAIN
+SELECT * FROM City
+WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Population,Name,Country 4,35,3 NULL # Using sort_intersect(Population,Name,Country); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Population,Country,Name 4,3,35 NULL # Using sort_intersect(Population,Country,Name); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name,Country Name,Population,Country # NULL # Using sort_intersect(Name,Population,Country); Using where
+SELECT * FROM City USE INDEX ()
+WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
+ID Name Country Population
+1810 Montréal CAN 1016376
+2259 Medellín COL 1861265
+SELECT * FROM City
+WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
+ID Name Country Population
+1810 Montréal CAN 1016376
+2259 Medellín COL 1861265
+SELECT * FROM City USE INDEX ()
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
+ID Name Country Population
+217 Guarulhos BRA 1095874
+218 Goiânia BRA 1056330
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
+ID Name Country Population
+217 Guarulhos BRA 1095874
+218 Goiânia BRA 1056330
+SELECT * FROM City USE INDEX ()
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+ID Name Country Population
+1895 Harbin CHN 4289800
+1904 Jinan CHN 2278100
+1905 Hangzhou CHN 2190500
+1914 Guiyang CHN 1465200
+1916 Hefei CHN 1369100
+1923 Jilin CHN 1040000
+1927 Hohhot CHN 916700
+1928 Handan CHN 840000
+1937 Huainan CHN 700000
+1938 Jixi CHN 683885
+1944 Jinzhou CHN 570000
+1950 Hegang CHN 520000
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+ID Name Country Population
+1895 Harbin CHN 4289800
+1904 Jinan CHN 2278100
+1905 Hangzhou CHN 2190500
+1914 Guiyang CHN 1465200
+1916 Hefei CHN 1369100
+1923 Jilin CHN 1040000
+1927 Hohhot CHN 916700
+1928 Handan CHN 840000
+1937 Huainan CHN 700000
+1938 Jixi CHN 683885
+1944 Jinzhou CHN 570000
+1950 Hegang CHN 520000
+SELECT COUNT(*) FROM City WHERE ID BETWEEN 501 AND 1000;
+COUNT(*)
+500
+SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 500;
+COUNT(*)
+500
+SELECT COUNT(*) FROM City WHERE ID BETWEEN 2001 AND 2500;
+COUNT(*)
+500
+SELECT COUNT(*) FROM City WHERE ID BETWEEN 3701 AND 4000;
+COUNT(*)
+300
+SELECT COUNT(*) FROM City WHERE Population > 700000;
+COUNT(*)
+358
+SELECT COUNT(*) FROM City WHERE Population > 1000000;
+COUNT(*)
+237
+SELECT COUNT(*) FROM City WHERE Population > 300000;
+COUNT(*)
+1062
+SELECT COUNT(*) FROM City WHERE Population > 600000;
+COUNT(*)
+428
+SELECT COUNT(*) FROM City WHERE Country LIKE 'C%';
+COUNT(*)
+551
+SELECT COUNT(*) FROM City WHERE Country LIKE 'A%';
+COUNT(*)
+107
+SELECT COUNT(*) FROM City WHERE Country LIKE 'H%';
+COUNT(*)
+22
+SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z';
+COUNT(*)
+682
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL # Using sort_intersect(PRIMARY,Country,Population); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,3 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Country 4,3 NULL # Using sort_intersect(PRIMARY,Country); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000
+AND Country BETWEEN 'S' AND 'Z';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL # Using sort_intersect(PRIMARY,Country,Population); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+AND Country BETWEEN 'S' AND 'Z' ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL # Using sort_intersect(PRIMARY,Country,Population); Using where
+SELECT * FROM City USE INDEX ()
+WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
+ID Name Country Population
+554 Santiago de Chile CHL 4703954
+SELECT * FROM City
+WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
+ID Name Country Population
+554 Santiago de Chile CHL 4703954
+SELECT * FROM City USE INDEX ()
+WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+ID Name Country Population
+1 Kabul AFG 1780000
+126 Yerevan ARM 1248700
+130 Sydney AUS 3276207
+131 Melbourne AUS 2865329
+132 Brisbane AUS 1291117
+133 Perth AUS 1096829
+144 Baku AZE 1787800
+56 Luanda AGO 2022000
+69 Buenos Aires ARG 2982146
+70 La Matanza ARG 1266461
+71 Córdoba ARG 1157507
+SELECT * FROM City
+WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+ID Name Country Population
+1 Kabul AFG 1780000
+126 Yerevan ARM 1248700
+130 Sydney AUS 3276207
+131 Melbourne AUS 2865329
+132 Brisbane AUS 1291117
+133 Perth AUS 1096829
+144 Baku AZE 1787800
+56 Luanda AGO 2022000
+69 Buenos Aires ARG 2982146
+70 La Matanza ARG 1266461
+71 Córdoba ARG 1157507
+SELECT * FROM City USE INDEX ()
+WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%';
+ID Name Country Population
+2409 Zagreb HRV 706770
+SELECT * FROM City
+WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%';
+ID Name Country Population
+2409 Zagreb HRV 706770
+SELECT * FROM City USE INDEX ()
+WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000
+AND Country BETWEEN 'S' AND 'Z';
+ID Name Country Population
+3769 Ho Chi Minh City VNM 3980000
+3770 Hanoi VNM 1410000
+3771 Haiphong VNM 783133
+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
+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
+SELECT * FROM City
+WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000
+AND Country BETWEEN 'S' AND 'Z';
+ID Name Country Population
+3769 Ho Chi Minh City VNM 3980000
+3770 Hanoi VNM 1410000
+3771 Haiphong VNM 783133
+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
+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
+SELECT * FROM City USE INDEX ()
+WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+AND Country BETWEEN 'S' AND 'Z' ;
+ID Name Country Population
+3048 Stockholm SWE 750348
+3173 Riyadh SAU 3324000
+3174 Jedda SAU 2046300
+3175 Mekka SAU 965700
+3176 Medina SAU 608300
+3197 Pikine SEN 855287
+3198 Dakar SEN 785071
+3207 Freetown SLE 850000
+3208 Singapore SGP 4017733
+3214 Mogadishu SOM 997000
+3224 Omdurman SDN 1271403
+3225 Khartum SDN 947483
+3226 Sharq al-Nil SDN 700887
+3250 Damascus SYR 1347000
+3251 Aleppo SYR 1261983
+3263 Taipei TWN 2641312
+3264 Kaohsiung TWN 1475505
+3265 Taichung TWN 940589
+3266 Tainan TWN 728060
+3305 Dar es Salaam TZA 1747000
+3320 Bangkok THA 6320174
+3349 Tunis TUN 690600
+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
+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
+3492 Montevideo URY 1236000
+3503 Toskent UZB 2117500
+3539 Caracas VEN 1975294
+3540 Maracaíbo VEN 1304776
+3541 Barquisimeto VEN 877239
+3542 Valencia VEN 794246
+3543 Ciudad Guayana VEN 663713
+3769 Ho Chi Minh City VNM 3980000
+3770 Hanoi VNM 1410000
+3771 Haiphong VNM 783133
+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
+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
+SELECT * FROM City
+WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+AND Country BETWEEN 'S' AND 'Z' ;
+ID Name Country Population
+3048 Stockholm SWE 750348
+3173 Riyadh SAU 3324000
+3174 Jedda SAU 2046300
+3175 Mekka SAU 965700
+3176 Medina SAU 608300
+3197 Pikine SEN 855287
+3198 Dakar SEN 785071
+3207 Freetown SLE 850000
+3208 Singapore SGP 4017733
+3214 Mogadishu SOM 997000
+3224 Omdurman SDN 1271403
+3225 Khartum SDN 947483
+3226 Sharq al-Nil SDN 700887
+3250 Damascus SYR 1347000
+3251 Aleppo SYR 1261983
+3263 Taipei TWN 2641312
+3264 Kaohsiung TWN 1475505
+3265 Taichung TWN 940589
+3266 Tainan TWN 728060
+3305 Dar es Salaam TZA 1747000
+3320 Bangkok THA 6320174
+3349 Tunis TUN 690600
+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
+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
+3492 Montevideo URY 1236000
+3503 Toskent UZB 2117500
+3539 Caracas VEN 1975294
+3540 Maracaíbo VEN 1304776
+3541 Barquisimeto VEN 877239
+3542 Valencia VEN 794246
+3543 Ciudad Guayana VEN 663713
+3769 Ho Chi Minh City VNM 3980000
+3770 Hanoi VNM 1410000
+3771 Haiphong VNM 783133
+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
+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
+SET SESSION sort_buffer_size = 2048;
+EXPLAIN
+SELECT * FROM City WHERE
+Name LIKE 'C%' AND Population > 1000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where
+EXPLAIN
+SELECT * FROM City WHERE
+Name LIKE 'M%' AND Population > 1500000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Population,Country,Name 4,3,35 NULL # Using sort_intersect(Population,Country,Name); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Name,Population,Country 35,4,3 NULL # Using sort_intersect(Name,Population,Country); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,3 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+AND Country BETWEEN 'S' AND 'Z';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL # Using sort_intersect(PRIMARY,Country,Population); Using where
+SELECT * FROM City WHERE
+Name LIKE 'C%' AND Population > 1000000;
+ID Name Country Population
+1026 Calcutta [Kolkata] IND 4399819
+1027 Chennai (Madras) IND 3841396
+151 Chittagong BGD 1392860
+1892 Chongqing CHN 6351600
+1898 Chengdu CHN 3361500
+1900 Changchun CHN 2812000
+1910 Changsha CHN 1809800
+212 Curitiba BRA 1584232
+2258 Cali COL 2077386
+2485 Casablanca MAR 2940623
+2515 Ciudad de México MEX 8591309
+3539 Caracas VEN 1975294
+3795 Chicago USA 2896016
+608 Cairo EGY 6789479
+71 Córdoba ARG 1157507
+712 Cape Town ZAF 2352121
+926 Conakry GIN 1090610
+SELECT * FROM City WHERE
+Name LIKE 'M%' AND Population > 1500000;
+ID Name Country Population
+131 Melbourne AUS 2865329
+653 Madrid ESP 2879052
+766 Manila PHL 1581082
+942 Medan IDN 1843919
+1024 Mumbai (Bombay) IND 10500000
+1381 Mashhad IRN 1887405
+2259 Medellín COL 1861265
+3520 Minsk BLR 1674000
+3580 Moscow RUS 8389200
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'B%';
+ID Name Country Population
+217 Guarulhos BRA 1095874
+218 Goiânia BRA 1056330
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+ID Name Country Population
+1895 Harbin CHN 4289800
+1905 Hangzhou CHN 2190500
+1914 Guiyang CHN 1465200
+1916 Hefei CHN 1369100
+1927 Hohhot CHN 916700
+1928 Handan CHN 840000
+1937 Huainan CHN 700000
+1950 Hegang CHN 520000
+SELECT * FROM City
+WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+ID Name Country Population
+1 Kabul AFG 1780000
+56 Luanda AGO 2022000
+69 Buenos Aires ARG 2982146
+70 La Matanza ARG 1266461
+71 Córdoba ARG 1157507
+126 Yerevan ARM 1248700
+130 Sydney AUS 3276207
+131 Melbourne AUS 2865329
+132 Brisbane AUS 1291117
+133 Perth AUS 1096829
+144 Baku AZE 1787800
+SELECT * FROM City
+WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+AND Country BETWEEN 'S' AND 'Z';
+ID Name Country Population
+3048 Stockholm SWE 750348
+3173 Riyadh SAU 3324000
+3174 Jedda SAU 2046300
+3175 Mekka SAU 965700
+3176 Medina SAU 608300
+3197 Pikine SEN 855287
+3198 Dakar SEN 785071
+3207 Freetown SLE 850000
+3208 Singapore SGP 4017733
+3214 Mogadishu SOM 997000
+3224 Omdurman SDN 1271403
+3225 Khartum SDN 947483
+3226 Sharq al-Nil SDN 700887
+3250 Damascus SYR 1347000
+3251 Aleppo SYR 1261983
+3263 Taipei TWN 2641312
+3264 Kaohsiung TWN 1475505
+3265 Taichung TWN 940589
+3266 Tainan TWN 728060
+3305 Dar es Salaam TZA 1747000
+3320 Bangkok THA 6320174
+3349 Tunis TUN 690600
+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
+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
+3492 Montevideo URY 1236000
+3503 Toskent UZB 2117500
+3539 Caracas VEN 1975294
+3540 Maracaíbo VEN 1304776
+3541 Barquisimeto VEN 877239
+3542 Valencia VEN 794246
+3543 Ciudad Guayana VEN 663713
+3769 Ho Chi Minh City VNM 3980000
+3770 Hanoi VNM 1410000
+3771 Haiphong VNM 783133
+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
+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
+SET SESSION sort_buffer_size = default;
+DROP INDEX Country ON City;
+CREATE INDEX CountryID ON City(Country,ID);
+CREATE INDEX CountryName ON City(Country,Name);
+EXPLAIN
+SELECT * FROM City
+WHERE Country LIKE 'M%' AND Population > 1000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,CountryID,CountryName Population,CountryID 4,3 NULL # Using sort_intersect(Population,CountryID); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Country='CHN' AND Population > 1500000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,CountryID,CountryName Population,CountryID 4,3 NULL # Using sort_intersect(Population,CountryID); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name,CountryID,CountryName CountryName,Population 38,4 NULL # Using sort_intersect(CountryName,Population); Using where
+SELECT * FROM City USE INDEX ()
+WHERE Country LIKE 'M%' AND Population > 1000000;
+ID Name Country Population
+2464 Kuala Lumpur MYS 1297526
+2485 Casablanca MAR 2940623
+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
+2698 Maputo MOZ 1018938
+2710 Rangoon (Yangon) MMR 3361700
+SELECT * FROM City
+WHERE Country LIKE 'M%' AND Population > 1000000;
+ID Name Country Population
+2464 Kuala Lumpur MYS 1297526
+2485 Casablanca MAR 2940623
+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
+2698 Maputo MOZ 1018938
+2710 Rangoon (Yangon) MMR 3361700
+SELECT * FROM City USE INDEX ()
+WHERE Country='CHN' AND Population > 1500000;
+ID Name Country Population
+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
+SELECT * FROM City
+WHERE Country='CHN' AND Population > 1500000;
+ID Name Country Population
+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
+SELECT * FROM City USE INDEX ()
+WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%';
+ID Name Country Population
+1892 Chongqing CHN 6351600
+1898 Chengdu CHN 3361500
+1900 Changchun CHN 2812000
+1910 Changsha CHN 1809800
+SELECT * FROM City
+WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%';
+ID Name Country Population
+1892 Chongqing CHN 6351600
+1898 Chengdu CHN 3361500
+1900 Changchun CHN 2812000
+1910 Changsha CHN 1809800
+EXPLAIN
+SELECT * FROM City, Country
+WHERE City.Name LIKE 'C%' AND City.Population > 1000000 AND
+Country.Code=City.Country;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Name,CountryID,CountryName Population,Name 4,35 NULL # Using sort_intersect(Population,Name); Using where
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country #
+DROP DATABASE world;
+use test;
+CREATE TABLE t1 (
+f1 int,
+f4 varchar(32),
+f5 int,
+PRIMARY KEY (f1),
+KEY (f4)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(5,'H',1), (9,'g',0), (527,'i',0), (528,'y',1), (529,'S',6),
+(530,'m',7), (531,'b',2), (532,'N',1), (533,'V',NULL), (534,'l',1),
+(535,'M',0), (536,'w',1), (537,'j',5), (538,'l',0), (539,'n',2),
+(540,'m',2), (541,'r',2), (542,'l',2), (543,'h',3),(544,'o',0),
+(956,'h',0), (957,'g',0), (958,'W',5), (959,'s',3), (960,'w',0),
+(961,'q',0), (962,'e',NULL), (963,'u',7), (964,'q',1), (965,'N',NULL),
+(966,'e',0), (967,'t',3), (968,'e',6), (969,'f',NULL), (970,'j',0),
+(971,'s',3), (972,'I',0), (973,'h',4), (974,'g',1), (975,'s',0),
+(976,'r',3), (977,'x',1), (978,'v',8), (979,'j',NULL), (980,'z',7),
+(981,'t',9), (982,'j',5), (983,'u',NULL), (984,'g',6), (985,'w',1),
+(986,'h',1), (987,'v',0), (988,'v',0), (989,'c',2), (990,'b',7),
+(991,'z',0), (992,'M',1), (993,'u',2), (994,'r',2), (995,'b',4),
+(996,'A',2), (997,'u',0), (998,'a',0), (999,'j',2), (1,'I',2);
+EXPLAIN
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge PRIMARY,f4 PRIMARY,f4 4,35 NULL # Using sort_intersect(PRIMARY,f4); Using where
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+f1 f4 f5
+994 r 2
+996 A 2
+998 a 0
+DROP TABLE t1;
+SET SESSION optimizer_switch='index_merge_sort_intersection=on';
+SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result
index 157cf007dfd..e5025acc998 100644
--- a/mysql-test/r/index_merge_innodb.result
+++ b/mysql-test/r/index_merge_innodb.result
@@ -1,3 +1,5 @@
+set @optimizer_switch_save= @@optimizer_switch;
+set optimizer_switch='index_merge_sort_intersection=off';
#---------------- Index merge test 2 -------------------------------------------
SET SESSION STORAGE_ENGINE = InnoDB;
drop table if exists t1,t2;
@@ -684,12 +686,14 @@ INSERT INTO t1(a,b) SELECT a,b FROM t1;
INSERT INTO t1(a,b) SELECT a,b FROM t1;
INSERT INTO t1 VALUES (1000000, 0, 0);
SET SESSION sort_buffer_size = 1024*36;
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
EXPLAIN
SELECT COUNT(*) FROM
(SELECT * FROM t1 FORCE INDEX(primary,idx)
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6144
2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 6144 Using sort_union(idx,PRIMARY); Using where
SELECT COUNT(*) FROM
(SELECT * FROM t1 FORCE INDEX(primary,idx)
@@ -701,7 +705,7 @@ SELECT COUNT(*) FROM
(SELECT * FROM t1 IGNORE INDEX(idx)
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL # Select tables optimized away
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL #
2 DERIVED t1 ALL PRIMARY NULL NULL NULL # Using where
SELECT COUNT(*) FROM
(SELECT * FROM t1 IGNORE INDEX(idx)
@@ -709,3 +713,68 @@ WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
COUNT(*)
6145
DROP TABLE t1;
+set optimizer_switch=@tmp_optimizer_switch;
+#
+# Testcase Backport: BUG#48093: 6.0 Server not processing equivalent IN clauses properly
+# with Innodb tables
+#
+CREATE TABLE t1 (
+i int(11) DEFAULT NULL,
+v1 varchar(1) DEFAULT NULL,
+v2 varchar(20) DEFAULT NULL,
+KEY i (i),
+KEY v (v1,i)
+) ENGINE=innodb;
+INSERT INTO t1 VALUES (1,'f','no');
+INSERT INTO t1 VALUES (2,'u','yes-u');
+INSERT INTO t1 VALUES (2,'h','yes-h');
+INSERT INTO t1 VALUES (3,'d','no');
+
+SELECT v2
+FROM t1
+WHERE v1 IN ('f', 'd', 'h', 'u' ) AND i = 2;
+v2
+yes-u
+yes-h
+
+# Should not use index_merge
+EXPLAIN
+SELECT v2
+FROM t1
+WHERE v1 IN ('f', 'd', 'h', 'u' ) AND i = 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref i,v i 5 const 2 Using where
+DROP TABLE t1;
+#
+# BUG#1006164: Multi-table DELETE that uses innodb + index_merge/intersect may fail to delete rows
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (
+pk int auto_increment,
+zone_id int,
+modified tinyint,
+primary key(pk),
+key (zone_id),
+key (modified)
+) engine=innodb;
+insert into t1 (zone_id, modified) select 0,0 from t0 A, t0 B, t0 C, t0 D;
+update t1 set zone_id=487, modified=9 where pk=7259;
+update t1 set zone_id=487, modified=9 where pk=7260;
+update t1 set zone_id=830, modified=9 where pk=8434;
+update t1 set zone_id=830, modified=9 where pk=8435;
+update t1 set zone_id=830, modified=9 where pk=8436;
+update t1 set zone_id=830, modified=9 where pk=8437;
+select * from t1 where t1.zone_id=830 AND modified=9;
+pk zone_id modified
+8434 830 9
+8435 830 9
+8436 830 9
+8437 830 9
+begin;
+DELETE t1 FROM t1 WHERE t1.zone_id=830 AND modified=9;
+commit;
+select * from t1 where t1.zone_id=830 AND modified=9;
+pk zone_id modified
+drop table t0, t1;
+set optimizer_switch= @optimizer_switch_save;
diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result
index ad44f241f5c..3616171ef58 100644
--- a/mysql-test/r/index_merge_myisam.result
+++ b/mysql-test/r/index_merge_myisam.result
@@ -1,3 +1,5 @@
+set @optimizer_switch_save= @@optimizer_switch;
+set optimizer_switch='index_merge_sort_intersection=off';
#---------------- Index merge test 1 -------------------------------------------
SET SESSION STORAGE_ENGINE = MyISAM;
drop table if exists t0, t1, t2, t3, t4;
@@ -19,7 +21,7 @@ Table Op Msg_type Msg_text
test.t0 analyze status OK
explain select * from t0 where key1 < 3 or key1 > 1020;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 range i1 i1 4 NULL 78 Using where
+1 SIMPLE t0 range i1 i1 4 NULL 78 Using index condition; Using where
explain
select * from t0 where key1 < 3 or key2 > 1020;
id select_type table type possible_keys key key_len ref rows Extra
@@ -115,11 +117,11 @@ 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 index_merge i1,i2,i3 i1,i2 4,4 NULL 6 Using sort_union(i1,i2); Using where
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
-1 SIMPLE t0 ALL i1,i2,i3 NULL NULL NULL 1024 Using where
+1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL 6 Using sort_union(i1,i2); Using where
explain select * from t0 where
((key1 < 4 or key2 < 4) and (key2 <5 or key3 < 4))
or
@@ -203,12 +205,12 @@ alter table t2 add index i321(key3, key2, key1);
explain select key3 from t2 where key1 = 100 or key2 = 100;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index_merge i1_3,i2_3 i1_3,i2_3 4,4 NULL 2 Using sort_union(i1_3,i2_3); Using where
-explain select key3 from t2 where key1 <100 or key2 < 100;
+explain select key3 from t2 where key1 < 500 or key2 < 500;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index i1_3,i2_3 i321 12 NULL 1024 Using where; Using index
explain select key7 from t2 where key1 <100 or key2 < 100;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL i1_3,i2_3 NULL NULL NULL 1024 Using where
+1 SIMPLE t2 index_merge i1_3,i2_3 i1_3,i2_3 4,4 NULL 188 Using sort_union(i1_3,i2_3); Using where
create table t4 (
key1a int not null,
key1b int not null,
@@ -259,7 +261,7 @@ explain
select * from t0,t1 where (t0.key1=t1.key1) and
(t0.key1=3 or t0.key2=4) and t1.key1<200;
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
+1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
1 SIMPLE t1 ref i1 i1 4 test.t0.key1 1
explain
select * from t0,t1 where (t0.key1=t1.key1) and
@@ -271,11 +273,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
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;
@@ -283,10 +285,13 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
2 UNION t1 index_merge i1,i3 i1,i3 4,4 NULL 5 Using sort_union(i1,i3); Using where
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
explain select * from (select * from t1 where key1 = 3 or key2 =3) as Z where key8 >5;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using where
2 DERIVED t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
+set optimizer_switch=@tmp_optimizer_switch;
create table t3 like t0;
insert into t3 select * from t0;
alter table t3 add key9 int not null, add index i9(key9);
@@ -342,15 +347,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 +367,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)
@@ -374,14 +377,14 @@ max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.ke
alter table t0 add filler1 char(200), add filler2 char(200), add filler3 char(200);
update t0 set key2=1, key3=1, key4=1, key5=1,key6=1,key7=1 where key7 < 500;
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, t0 as B
+from t0 as A straight_join 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)
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
+from t0 as A straight_join 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)
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);
max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
@@ -569,9 +572,7 @@ INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
-SET SESSION sort_buffer_size=1;
-Warnings:
-Warning 1292 Truncated incorrect sort_buffer_size value: '1'
+SET SESSION sort_buffer_size=1024*8;
EXPLAIN
SELECT * FROM t1 FORCE INDEX(a,b) WHERE a LIKE 'a%' OR b LIKE 'b%'
ORDER BY a,b;
@@ -1381,7 +1382,7 @@ 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
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
@@ -1488,66 +1489,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 const 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),
@@ -1624,7 +1565,7 @@ explain select * from t1 where a=10 and b=10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a,b a 5 const 49 Using where
No intersect if it is disabled:
-set optimizer_switch='default,index_merge_intersection=off';
+set optimizer_switch='default,index_merge_sort_intersection=off,index_merge_intersection=off';
explain select * from t1 where a=10 and b=10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a,b a 5 const 49 Using where
@@ -1655,7 +1596,25 @@ 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;
+#
+# BUG#834514 Assertion `!table || (!table->read_set || bitmap_is_set(...' with aggregates
+#
+CREATE TABLE t1 ( a int , b int, c int, KEY (b), PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (1,4,0),(5,0,0),(6,7,0),(7,7,0),(8,1,0),(9,7,0),(10,1,0);
+CREATE TABLE t2 ( b int, c int, KEY (c,b)) ;
+INSERT INTO t2 VALUES (7,0),(1,0),(7,0),(1,0);
+CREATE TABLE t3 ( a int ) ;
+SELECT COUNT(DISTINCT t2.b), CONCAT(t1.c)
+FROM t1, t2
+WHERE (t2.c = t1.c)
+AND (
+t1.b IN ( 4 )
+OR t1.a = 137
+AND EXISTS ( SELECT a FROM t3 )
+)
+GROUP BY 2;
+COUNT(DISTINCT t2.b) CONCAT(t1.c)
+2 0
+DROP TABLE t1,t2,t3;
+set optimizer_switch= @optimizer_switch_save;
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index d50ff0bca4b..a9dd69ef698 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -219,8 +219,8 @@ Field Type Collation Null Key Default Extra Privileges Comment
c varchar(64) utf8_general_ci NO select,insert,update,references
select * from information_schema.COLUMNS where table_name="t1"
and column_name= "a";
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL mysqltest t1 a 1 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL mysqltest t1 a 1 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
show columns from mysqltest.t1 where field like "%a%";
Field Type Null Key Default Extra
a int(11) YES NULL
@@ -327,7 +327,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
@@ -1282,6 +1282,8 @@ COLUMN_NAME MD5(COLUMN_DEFAULT) LENGTH(COLUMN_DEFAULT) COLUMN_DEFAULT=get_value(
fld1 7cf7a6782be951a1f2464a350da926a5 65532 1
DROP TABLE bug23037;
DROP FUNCTION get_value;
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
create view v1 as
select table_schema as object_schema,
table_name as object_name,
@@ -1293,8 +1295,9 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE tables ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases; Using filesort
explain select * from (select table_name from information_schema.tables) as a;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED tables ALL NULL NULL NULL NULL NULL Skip_open_table; Scanned all databases
+set optimizer_switch=@tmp_optimizer_switch;
drop view v1;
create table t1 (f1 int(11));
create table t2 (f1 int(11), f2 int(11));
@@ -1455,7 +1458,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
@@ -1494,9 +1497,9 @@ WHERE TABLE_SCHEMA='mysql' and TABLE_NAME= 'db';
TABLE_COLLATION
utf8_bin
select * from information_schema.columns where table_schema = NULL;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
select * from `information_schema`.`COLUMNS` where `TABLE_NAME` = NULL;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
select * from `information_schema`.`KEY_COLUMN_USAGE` where `TABLE_SCHEMA` = NULL;
CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION POSITION_IN_UNIQUE_CONSTRAINT REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME
select * from `information_schema`.`KEY_COLUMN_USAGE` where `TABLE_NAME` = NULL;
diff --git a/mysql-test/r/information_schema_all_engines.result b/mysql-test/r/information_schema_all_engines.result
index 33cc5a95a48..4f1a2146a0a 100644
--- a/mysql-test/r/information_schema_all_engines.result
+++ b/mysql-test/r/information_schema_all_engines.result
@@ -68,7 +68,7 @@ FROM information_schema.columns c2
WHERE c2.table_schema = t.table_schema AND
c2.table_name = t.table_name AND
c2.column_name LIKE '%SCHEMA%'
- );
+ ) order by t.table_name;
table_name column_name
CHARACTER_SETS CHARACTER_SET_NAME
CLIENT_STATISTICS CLIENT
@@ -137,7 +137,7 @@ FROM information_schema.columns c2
WHERE c2.table_schema = 'information_schema' AND
c2.table_name = t.table_name AND
c2.column_name LIKE '%SCHEMA%'
- );
+ ) order by t.table_name;
table_name column_name
CHARACTER_SETS CHARACTER_SET_NAME
CLIENT_STATISTICS CLIENT
@@ -267,10 +267,11 @@ TRIGGERS information_schema.TRIGGERS 1
USER_PRIVILEGES information_schema.USER_PRIVILEGES 1
USER_STATISTICS information_schema.USER_STATISTICS 1
VIEWS information_schema.VIEWS 1
-Database: information_schema
+---------------------------------------+
-| Tables |
+---------------------------------------+
++---------------------------------------+
+Database: information_schema
+| Tables |
| CHARACTER_SETS |
| CLIENT_STATISTICS |
| COLLATIONS |
@@ -283,6 +284,26 @@ Database: information_schema
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
| INDEX_STATISTICS |
+| INNODB_BUFFER_PAGE |
+| INNODB_BUFFER_PAGE_LRU |
+| INNODB_BUFFER_POOL_PAGES |
+| INNODB_BUFFER_POOL_PAGES_BLOB |
+| INNODB_BUFFER_POOL_PAGES_INDEX |
+| INNODB_BUFFER_POOL_STATS |
+| INNODB_CHANGED_PAGES |
+| INNODB_CMP |
+| INNODB_CMPMEM |
+| INNODB_CMPMEM_RESET |
+| INNODB_CMP_RESET |
+| INNODB_INDEX_STATS |
+| INNODB_LOCKS |
+| INNODB_LOCK_WAITS |
+| INNODB_RSEG |
+| INNODB_SYS_INDEXES |
+| INNODB_SYS_STATS |
+| INNODB_SYS_TABLES |
+| INNODB_TABLE_STATS |
+| INNODB_TRX |
| KEY_CACHES |
| KEY_COLUMN_USAGE |
| PARTITIONS |
@@ -304,32 +325,12 @@ Database: information_schema
| USER_PRIVILEGES |
| USER_STATISTICS |
| VIEWS |
-| INNODB_BUFFER_POOL_PAGES_INDEX |
-| INNODB_RSEG |
-| INNODB_CHANGED_PAGES |
-| INNODB_BUFFER_POOL_PAGES |
-| INNODB_TABLE_STATS |
-| INNODB_TRX |
| XTRADB_ADMIN_COMMAND |
-| INNODB_LOCK_WAITS |
-| INNODB_SYS_TABLES |
-| INNODB_CMP |
-| INNODB_BUFFER_POOL_STATS |
-| INNODB_CMP_RESET |
-| INNODB_CMPMEM |
-| INNODB_INDEX_STATS |
-| INNODB_SYS_INDEXES |
-| INNODB_BUFFER_POOL_PAGES_BLOB |
-| INNODB_CMPMEM_RESET |
-| INNODB_LOCKS |
-| INNODB_BUFFER_PAGE |
-| INNODB_SYS_STATS |
-| INNODB_BUFFER_PAGE_LRU |
+---------------------------------------+
-Database: INFORMATION_SCHEMA
+---------------------------------------+
-| Tables |
+---------------------------------------+
+Database: INFORMATION_SCHEMA
+| Tables |
| CHARACTER_SETS |
| CLIENT_STATISTICS |
| COLLATIONS |
@@ -342,6 +343,26 @@ Database: INFORMATION_SCHEMA
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
| INDEX_STATISTICS |
+| INNODB_BUFFER_PAGE |
+| INNODB_BUFFER_PAGE_LRU |
+| INNODB_BUFFER_POOL_PAGES |
+| INNODB_BUFFER_POOL_PAGES_BLOB |
+| INNODB_BUFFER_POOL_PAGES_INDEX |
+| INNODB_BUFFER_POOL_STATS |
+| INNODB_CHANGED_PAGES |
+| INNODB_CMP |
+| INNODB_CMPMEM |
+| INNODB_CMPMEM_RESET |
+| INNODB_CMP_RESET |
+| INNODB_INDEX_STATS |
+| INNODB_LOCKS |
+| INNODB_LOCK_WAITS |
+| INNODB_RSEG |
+| INNODB_SYS_INDEXES |
+| INNODB_SYS_STATS |
+| INNODB_SYS_TABLES |
+| INNODB_TABLE_STATS |
+| INNODB_TRX |
| KEY_CACHES |
| KEY_COLUMN_USAGE |
| PARTITIONS |
@@ -363,34 +384,13 @@ Database: INFORMATION_SCHEMA
| USER_PRIVILEGES |
| USER_STATISTICS |
| VIEWS |
-| INNODB_BUFFER_POOL_PAGES_INDEX |
-| INNODB_RSEG |
-| INNODB_CHANGED_PAGES |
-| INNODB_BUFFER_POOL_PAGES |
-| INNODB_TABLE_STATS |
-| INNODB_TRX |
| XTRADB_ADMIN_COMMAND |
-| INNODB_LOCK_WAITS |
-| INNODB_SYS_TABLES |
-| INNODB_CMP |
-| INNODB_BUFFER_POOL_STATS |
-| INNODB_CMP_RESET |
-| INNODB_CMPMEM |
-| INNODB_INDEX_STATS |
-| INNODB_SYS_INDEXES |
-| INNODB_BUFFER_POOL_PAGES_BLOB |
-| INNODB_CMPMEM_RESET |
-| INNODB_LOCKS |
-| INNODB_BUFFER_PAGE |
-| INNODB_SYS_STATS |
-| INNODB_BUFFER_PAGE_LRU |
-+---------------------------------------+
-Wildcard: inf_rmation_schema
+--------------------+
-| Databases |
+--------------------+
-| information_schema |
+--------------------+
+Wildcard: inf_rmation_schema
+| Databases |
+| information_schema |
SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA;
table_schema count(*)
information_schema 54
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index a34fc94fa99..798aea24401 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1,3 +1,8 @@
+set @innodb_test_tmp=@@optimizer_switch;
+set optimizer_switch =
+if(@innodb_test_dont_touch_optimizer_switch,
+@@optimizer_switch,
+'mrr=on,mrr_sort_keys=on,index_condition_pushdown=on');
drop table if exists t1,t2,t3,t4;
drop database if exists mysqltest;
create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) engine=innodb;
@@ -1295,7 +1300,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; Rowid-ordered scan
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 +1995,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 +2171,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
@@ -3303,3 +3308,4 @@ Variable_name Value
Handler_update 1
Variable_name Value
Handler_delete 1
+set optimizer_switch=@innodb_test_tmp;
diff --git a/mysql-test/r/innodb_bug878769.result b/mysql-test/r/innodb_bug878769.result
new file mode 100644
index 00000000000..db7ba3d2ee4
--- /dev/null
+++ b/mysql-test/r/innodb_bug878769.result
@@ -0,0 +1,57 @@
+drop table if exists t1,t2;
+#
+# Bug #878769: valgrind complains when using join cache
+# to join an InnoDB table without primary key
+#
+CREATE TABLE t1 (
+col_int_key int(11), col_time_key time, col_varchar_key varchar(1),
+KEY (col_int_key), KEY (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT IGNORE INTO t1 VALUES
+(7,'10:19:31','d'),(1,'14:40:36','r'),(7,'04:37:47','f'),(9,'19:34:06','y'),
+(2,'00:00:00','m'),(4,'00:13:25','q'),(0,'03:47:16',NULL),(4,'01:41:48','d'),
+(8,'00:00:00','g'),(NULL,'22:32:04','x'),(NULL,'16:44:14','f'),
+(0,'17:38:37','p'),(NULL,'08:46:48','j'),(8,'14:11:27','c');
+CREATE TABLE t2 (
+col_int_nokey int(11), col_int_key int(11),
+col_datetime_key datetime, col_datetime_nokey datetime,
+col_varchar_key varchar(1), col_varchar_nokey varchar(1),
+KEY (col_int_key), KEY (col_varchar_key,col_int_key)
+);
+INSERT IGNORE INTO t2 VALUES
+(150,62,'2008-01-03 10:33:32','2008-01-03 10:33:32','v','v'),
+(2,1,'2007-10-09 19:53:04','2007-10-09 19:53:04',NULL,NULL),
+(5,0,'2001-11-08 21:02:12','2001-11-08 21:02:12','x','x'),
+(3,7,'2003-04-01 00:00','2003-04-01 00:00','i','i'),
+(1,7,'1900-01-01 00:00','1900-01-01 00:00:00','e','e'),
+(NULL,7,'2005-04-04 01:21','2005-04-04 01:21','s','s'),
+(2,1,'1900-01-01 00:00','1900-01-01 00:00','j','j'),
+(8,0,'2004-04-28 21:44','2004-04-28 21:44','a','a'),
+(6,8,'2001-04-18 00:00','2001-04-18 00:00:00','y','y'),
+(8,1,'2008-12-18 19:39:55','2008-12-18 19:39:55',NULL,NULL),
+(3,1,'2000-08-01 12:19:39','2000-08-01 12:19:39','r','r'),
+(3,9,'2004-09-25 21:29:06','2004-09-25 21:29:06','v','v');
+set session optimizer_switch='mrr=on,mrr_sort_keys=on';
+set session join_cache_level=6;
+EXPLAIN
+SELECT t1.col_time_key, t1.col_varchar_key
+FROM t2 STRAIGHT_JOIN t1 ON t1.col_int_key = t2.col_int_key
+GROUP BY 1,2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index col_int_key col_int_key 5 NULL 12 Using where; Using index; Using temporary; Using filesort
+1 SIMPLE t1 ref col_int_key col_int_key 5 test.t2.col_int_key 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+SELECT t1.col_time_key, t1.col_varchar_key
+FROM t2 STRAIGHT_JOIN t1 ON t1.col_int_key = t2.col_int_key
+GROUP BY 1,2;
+col_time_key col_varchar_key
+00:00:00 g
+03:47:16 NULL
+04:37:47 f
+10:19:31 d
+14:11:27 c
+14:40:36 r
+17:38:37 p
+19:34:06 y
+set session optimizer_switch=default;
+set session join_cache_level=default;
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/innodb_icp.result b/mysql-test/r/innodb_icp.result
new file mode 100644
index 00000000000..53a76b2a3f3
--- /dev/null
+++ b/mysql-test/r/innodb_icp.result
@@ -0,0 +1,855 @@
+set @save_storage_engine= @@storage_engine;
+set storage_engine=InnoDB;
+set @innodb_icp_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+#
+# Bug#36981 - "innodb crash when selecting for update"
+#
+CREATE TABLE t1 (
+c1 CHAR(1),
+c2 CHAR(10),
+KEY (c1)
+);
+INSERT INTO t1 VALUES ('3', null);
+SELECT * FROM t1 WHERE c1='3' FOR UPDATE;
+c1 c2
+3 NULL
+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);
+INSERT INTO t2 SELECT A.a + 10*(B.a + 10*C.a) FROM t1 A, t1 B, t1 C;
+CREATE TABLE t3 (
+c1 CHAR(10) NOT NULL,
+c2 CHAR(10) NOT NULL,
+c3 CHAR(200) NOT NULL,
+KEY (c1)
+);
+INSERT INTO t3
+SELECT CONCAT('c-',1000+t2.a,'=w'), CONCAT('c-',1000+ t2.a,'=w'), 'filler'
+ FROM t2;
+INSERT INTO t3
+SELECT CONCAT('c-',1000+t2.a,'=w'), CONCAT('c-',2000+t2.a,'=w'), 'filler-1'
+ FROM t2;
+INSERT INTO t3
+SELECT CONCAT('c-',1000+t2.a,'=w'), CONCAT('c-',3000+t2.a,'=w'), 'filler-2'
+ FROM t2;
+SELECT c1,c3 FROM t3 WHERE c1 >= 'c-1994=w' and c1 != 'c-1996=w' FOR UPDATE;
+c1 c3
+c-1994=w filler
+c-1994=w filler-1
+c-1994=w filler-2
+c-1995=w filler
+c-1995=w filler-1
+c-1995=w filler-2
+c-1997=w filler
+c-1997=w filler-1
+c-1997=w filler-2
+c-1998=w filler
+c-1998=w filler-1
+c-1998=w filler-2
+c-1999=w filler
+c-1999=w filler-1
+c-1999=w filler-2
+DROP TABLE t1,t2,t3;
+#
+# Bug#42580 - Innodb's ORDER BY ..LIMIT returns no rows for
+# null-safe operator <=> NULL
+#
+CREATE TABLE t1(
+c1 DATE NOT NULL,
+c2 DATE NULL,
+c3 DATETIME,
+c4 TIMESTAMP,
+PRIMARY KEY(c1),
+UNIQUE(c2)
+);
+
+INSERT INTO t1 VALUES('0000-00-00', '0000-00-00', '2008-01-04', '2008-01-05');
+INSERT INTO t1 VALUES('2007-05-25', '2007-05-25', '2007-05-26', '2007-05-26');
+INSERT INTO t1 VALUES('2008-01-01', NULL , '2008-01-02', '2008-01-03');
+INSERT INTO t1 VALUES('2008-01-17', NULL , NULL , '2009-01-29');
+INSERT INTO t1 VALUES('2009-01-29', '2009-01-29', '2009-01-29', '2009-01-29');
+
+SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c1,c2;
+c1 c2 c3 c4
+2008-01-01 NULL 2008-01-02 00:00:00 2008-01-03 00:00:00
+2008-01-17 NULL NULL 2009-01-29 00:00:00
+
+SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c1,c2 LIMIT 2;
+c1 c2 c3 c4
+2008-01-01 NULL 2008-01-02 00:00:00 2008-01-03 00:00:00
+2008-01-17 NULL NULL 2009-01-29 00:00:00
+
+DROP TABLE t1;
+#
+# Bug#43617 - Innodb returns wrong results with timestamp's range value
+# in IN clause
+# (Note: Fixed by patch for BUG#42580)
+#
+CREATE TABLE t1(
+c1 TIMESTAMP NOT NULL,
+c2 TIMESTAMP NULL,
+c3 DATE,
+c4 DATETIME,
+PRIMARY KEY(c1),
+UNIQUE INDEX(c2)
+);
+INSERT INTO t1 VALUES
+('0000-00-00 00:00:00','0000-00-00 00:00:00','2008-01-04','2008-01-05 00:00:00'),
+('1971-01-01 00:00:01','1980-01-01 00:00:01','2009-01-01','2009-01-02 00:00:00'),
+('1999-01-01 00:00:00','1999-01-01 00:00:00', NULL, NULL),
+('2007-05-23 09:15:28','2007-05-23 09:15:28','2007-05-24','2007-05-24 09:15:28'),
+('2007-05-27 00:00:00','2007-05-25 00:00:00','2007-05-26','2007-05-26 00:00:00'),
+('2008-01-01 00:00:00', NULL, '2008-01-02','2008-01-03 00:00:00'),
+('2009-01-29 11:11:27','2009-01-29 11:11:27','2009-01-29','2009-01-29 11:11:27'),
+('2038-01-09 03:14:07','2038-01-09 03:14:07','2009-01-05','2009-01-06 00:00:00');
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 LIMIT 2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC LIMIT 2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+DROP TABLE t1;
+#
+# BUG#43618: MyISAM&Maria returns wrong results with 'between'
+# on timestamp
+#
+CREATE TABLE t1(
+ts TIMESTAMP NOT NULL,
+c char NULL,
+PRIMARY KEY(ts)
+);
+INSERT INTO t1 VALUES
+('1971-01-01','a'),
+('2007-05-25','b'),
+('2008-01-01','c'),
+('2038-01-09','d');
+
+# Execute select with invalid timestamp, desc ordering
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+ts c
+2008-01-01 00:00:00 c
+2007-05-25 00:00:00 b
+
+# Should use index condition
+EXPLAIN
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where
+
+DROP TABLE t1;
+#
+# BUG#49906: Assertion failed - Field_varstring::val_str in field.cc
+# (Note: Fixed by patch for LP BUG#625841)
+#
+CREATE TABLE t1 (
+f1 VARCHAR(1024),
+f2 VARCHAR(10),
+INDEX test_idx USING BTREE (f2,f1(5))
+);
+INSERT INTO t1 VALUES ('a','c'), ('b','d');
+SELECT f1
+FROM t1
+WHERE f2 LIKE 'd'
+ORDER BY f1;
+f1
+b
+DROP TABLE t1;
+#
+# Bug#52660 - "Perf. regr. using ICP for MyISAM on range queries on
+# an index containing TEXT"
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 SELECT A.a + 10*(B.a) FROM t1 A, t1 B;
+CREATE TABLE t3 (
+c1 TINYTEXT NOT NULL,
+i1 INT NOT NULL,
+KEY (c1(6),i1)
+);
+INSERT INTO t3 SELECT CONCAT('c-',1000+t2.a,'=w'), 1 FROM t2;
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range c1 c1 8 NULL 3 Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+c1
+c-1004=w
+c-1005=w
+c-1006=w
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range c1 c1 12 NULL 2 Using index condition; Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+c1
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 ALL c1 NULL NULL NULL 100 Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+c1
+c-1004=w
+c-1005=w
+c-1006=w
+DROP TABLE t1, t2, t3;
+#
+# Bug#40992 - InnoDB: Crash when engine_condition_pushdown is on
+#
+CREATE TABLE t (
+dummy INT PRIMARY KEY,
+a INT UNIQUE,
+b INT
+);
+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;
+#
+# Bug#35080 - Innodb crash at mem_block_get_len line 72
+#
+CREATE TABLE t1 (
+t1_autoinc INT(11) NOT NULL AUTO_INCREMENT,
+uuid VARCHAR(36) DEFAULT NULL,
+PRIMARY KEY (t1_autoinc),
+KEY k (uuid)
+);
+CREATE TABLE t2 (
+t2_autoinc INT(11) NOT NULL AUTO_INCREMENT,
+uuid VARCHAR(36) DEFAULT NULL,
+date DATETIME DEFAULT NULL,
+PRIMARY KEY (t2_autoinc),
+KEY k (uuid)
+);
+CREATE VIEW v1 AS
+SELECT t1_autoinc, uuid
+FROM t1
+WHERE (ISNULL(uuid) OR (uuid like '%-%'));
+CREATE VIEW v2 AS
+SELECT t2_autoinc, uuid, date
+FROM t2
+WHERE (ISNULL(uuid) OR (LENGTH(uuid) = 36));
+CREATE PROCEDURE delete_multi (IN uuid CHAR(36))
+DELETE v1, v2 FROM v1 INNER JOIN v2
+ON v1.uuid = v2.uuid
+WHERE v1.uuid = @uuid;
+SET @uuid = UUID();
+INSERT INTO v1 (uuid) VALUES (@uuid);
+INSERT INTO v2 (uuid, date) VALUES (@uuid, '2009-09-09');
+CALL delete_multi(@uuid);
+DROP procedure delete_multi;
+DROP table t1,t2;
+DROP view v1,v2;
+#
+# Bug#41996 - multi-table delete crashes server (InnoDB table)
+#
+CREATE TABLE t1 (
+b BIGINT,
+i INT,
+KEY (b)
+);
+INSERT INTO t1 VALUES (2, 2);
+DELETE t1 FROM t1 a, t1 WHERE a.i=t1.b;
+DROP TABLE t1;
+#
+# Bug#43448 - Server crashes on multi table delete with Innodb
+#
+CREATE TABLE t1 (
+id1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+t CHAR(12)
+);
+CREATE TABLE t2 (
+id2 INT NOT NULL,
+t CHAR(12)
+);
+CREATE TABLE t3(
+id3 INT NOT NULL,
+t CHAR(12),
+INDEX(id3)
+);
+CREATE PROCEDURE insert_data ()
+BEGIN
+DECLARE i1 INT DEFAULT 20;
+DECLARE i2 INT;
+DECLARE i3 INT;
+WHILE (i1 > 0) DO
+INSERT INTO t1(t) VALUES (i1);
+SET i2 = 2;
+WHILE (i2 > 0) DO
+INSERT INTO t2(id2, t) VALUES (i1, i2);
+SET i3 = 2;
+WHILE (i3 > 0) DO
+INSERT INTO t3(id3, t) VALUES (i1, i2);
+SET i3 = i3 -1;
+END WHILE;
+SET i2 = i2 -1;
+END WHILE;
+SET i1 = i1 - 1;
+END WHILE;
+END |
+CALL insert_data();
+SELECT COUNT(*) FROM t1 WHERE id1 > 10;
+COUNT(*)
+10
+SELECT COUNT(*) FROM t2 WHERE id2 > 10;
+COUNT(*)
+20
+SELECT COUNT(*) FROM t3 WHERE id3 > 10;
+COUNT(*)
+40
+DELETE t1, t2, t3
+FROM t1, t2, t3
+WHERE t1.id1 = t2.id2 AND t2.id2 = t3.id3 AND t1.id1 > 3;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+3
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+6
+SELECT COUNT(*) FROM t3;
+COUNT(*)
+12
+DROP PROCEDURE insert_data;
+DROP TABLE t1, t2, t3;
+#
+# Bug#57372 "Multi-table updates and deletes fail when running with ICP
+# against InnoDB"
+#
+CREATE TABLE t1 (
+a INT KEY,
+b INT
+);
+CREATE TABLE t2 (
+a INT KEY,
+b INT
+);
+INSERT INTO t1 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105);
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+UPDATE t1, t2
+SET t1.a = t1.a + 100, t2.b = t1.a + 10
+WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b - 100;
+SELECT * FROM t1;
+a b
+1 101
+102 102
+103 103
+104 104
+5 105
+SELECT * FROM t2;
+a b
+1 1
+2 12
+3 13
+4 14
+5 5
+DROP TABLE t1, t2;
+#
+# Bug#52605 - "Adding LIMIT 1 clause to query with complex range
+# predicate causes wrong results"
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT,
+PRIMARY KEY (pk),
+KEY k1 (c1)
+);
+INSERT INTO t1 VALUES (1,NULL);
+INSERT INTO t1 VALUES (2,6);
+INSERT INTO t1 VALUES (3,NULL);
+INSERT INTO t1 VALUES (4,6);
+INSERT INTO t1 VALUES (5,NULL);
+INSERT INTO t1 VALUES (6,NULL);
+INSERT INTO t1 VALUES (7,9);
+INSERT INTO t1 VALUES (8,0);
+SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+pk c1
+4 6
+EXPLAIN SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,k1 k1 5 NULL 3 Using where; Using index
+DROP TABLE t1;
+#
+#
+# Bug#59259 "Incorrect rows returned for a correlated subquery
+# when ICP is on"
+#
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using where
+2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using where; Using index; Using join buffer (flat, BNL join)
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+pk i
+12 5
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1, t2;
+#
+# Bug #58816 "Extra temporary duplicate rows in result set when
+# switching ICP off"
+#
+set @save_optimizer_switch= @@optimizer_switch;
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1);
+EXPLAIN SELECT pk, c1 FROM t1 WHERE pk <> 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT pk, c1 FROM t1 WHERE pk <> 3;
+pk c1
+1 9
+2 7
+4 3
+5 1
+DROP TABLE t1;
+set optimizer_switch= @save_optimizer_switch;
+#
+# Bug#58837: ICP crash or valgrind error due to uninitialized
+# value in innobase_index_cond
+#
+CREATE TABLE t1 (
+t1_int INT,
+t1_time TIME
+);
+CREATE TABLE t2 (
+t2_int int PRIMARY KEY,
+t2_int2 INT
+);
+INSERT INTO t2 VALUES ();
+INSERT INTO t1 VALUES ();
+SELECT * FROM t1 AS t1a
+WHERE NOT EXISTS (SELECT * FROM t1 AS t1b
+WHERE t1b.t1_int NOT IN
+(SELECT t2.t2_int FROM t2
+WHERE t1b.t1_time LIKE t1b.t1_int
+OR t1b.t1_time <> t2.t2_int2
+AND 6=7));
+t1_int t1_time
+DROP TABLE t1,t2;
+#
+# Bug#59186: Wrong results of join when ICP is enabled
+# (fixed by the patch for LP bug #694092)
+#
+CREATE TABLE t1 (
+pk INTEGER NOT NULL,
+c1 VARCHAR(3) NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,'y'),(0,'or');
+CREATE TABLE t2 (
+pk INTEGER NOT NULL,
+c1 VARCHAR(3) NOT NULL,
+c2 VARCHAR(6) NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (6,'y','RPOYT'),(10,'m','JINQE');
+EXPLAIN
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+(t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Using join buffer (flat, BNL join)
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+(t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+c2
+DROP TABLE t1, t2;
+#
+# Bug#58838: "Wrong results with HAVING + LIMIT without GROUP BY when
+# ICP is enabled".
+# (Fixed by the patches for LP bugs #668644, #702322)
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT,
+PRIMARY KEY (pk),
+KEY col_int_key (c1)
+);
+INSERT INTO t1 VALUES (1,37),(2,8),(3,-25),(4,NULL),(5,55);
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 0;
+pk
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 1;
+pk
+3
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 2;
+pk
+3
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 5;
+pk
+3
+DROP TABLE t1;
+#
+# Bug#59483 "Crash on INSERT/REPLACE in
+# rec_convert_dtuple_to_rec_comp with ICP on"
+#
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT PRIMARY KEY,
+i1 INTEGER,
+c1 CHAR(6),
+i2 INTEGER NOT NULL,
+KEY (i2)
+);
+INSERT INTO t1 VALUES
+(NULL, 4, 'that', 8),
+(NULL, 1, 'she', 6),
+(NULL, 6, 'tell', 2);
+SELECT * FROM t1 WHERE i2 IN (3, 6) LIMIT 2 FOR UPDATE;
+pk i1 c1 i2
+2 1 she 6
+INSERT INTO t1 (i2) VALUES (1);
+DROP TABLE t1;
+#
+# Bug #11766678 - 59843:
+# USING UNINITIALISED VALUE IN USES_INDEX_FIELDS_ONLY
+#
+CREATE TABLE t1 (
+col999 FLOAT NOT NULL,
+COL1000 VARBINARY(179) NOT NULL,
+col1003 DATE DEFAULT NULL,
+KEY idx4267 (col1000, col1003)
+);
+INSERT INTO t1 VALUES (),();
+Warnings:
+Warning 1364 Field 'col999' doesn't have a default value
+Warning 1364 Field 'COL1000' doesn't have a default value
+SELECT col999 FROM t1 WHERE col1000 = "3" AND col1003 <=> sysdate();
+col999
+DROP TABLE t1;
+#
+# BUG#12822678 - ICP WITH STRAIGHT_JOIN
+#
+CREATE TABLE t1 (
+i1 INTEGER NOT NULL,
+d1 DOUBLE,
+KEY k1 (d1)
+);
+INSERT INTO t1 VALUES (10,1), (17,NULL), (22,NULL);
+CREATE TABLE t2 (
+pk INTEGER NOT NULL,
+i1 INTEGER NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (4,1);
+EXPLAIN
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL k1 9 NULL 3 Using index
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using where
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+d1 pk i1
+1 4 1
+DROP TABLE t1, t2;
+#
+# BUG#778434 Wrong result with in_to_exists=on in maria-5.3-mwl89
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0);
+CREATE TABLE t2 ( f10 int) ;
+INSERT IGNORE INTO t2 VALUES (0);
+CREATE TABLE t3 ( f1 int NOT NULL , f10 int, PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES (6,0),(10,0);
+CREATE TABLE t4 ( f11 int) ;
+INSERT IGNORE INTO t4 VALUES
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(NULL),
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+set @tmp_778434=@@optimizer_switch;
+SET optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off,semijoin=off';
+SELECT * FROM t1 INNER JOIN t2 ON t2.f10 = t1.f11
+WHERE (6, 234) IN (
+SELECT t3.f1, t3.f1
+FROM t3 JOIN t4 ON t4.f11 = t3.f10
+);
+f11 f10
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch= @tmp_778434;
+#
+# Bug#885168: ICP for one index + potential ORDER BY for another
+#
+CREATE TABLE t1 (a varchar(64), b varchar(10), INDEX(a), INDEX(b)) ;
+INSERT INTO t1 VALUES
+('Ohio','Iowa'), ('k','d'), ('bdkpj','mbdkpjdanp'), ('d','xdmbdkpjda'),
+('fkxdmbdkpjdanpje','o'), ('f','Pennsylvan'), ('Virginia','ei');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range b b 13 NULL 2 Using where; Rowid-ordered scan; Using filesort
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+a b
+d xdmbdkpjda
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range b b 13 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using filesort
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+a b
+d xdmbdkpjda
+DROP TABLE t1;
+#
+# Bug#886145: join with ICP + ORDER BY
+#
+CREATE TABLE t1 (b int NOT NULL, c int, a varchar(1024), PRIMARY KEY (b));
+INSERT INTO t1 VALUES (1,4,'Ill');
+CREATE TABLE t2 (a varchar(1024), KEY (a(512)));
+INSERT INTO t2 VALUES
+('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort
+1 SIMPLE t2 ref a a 515 test.t1.a 1 Using where
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+b c
+1 4
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort
+1 SIMPLE t2 ref a a 515 test.t1.a 1 Using where
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+b c
+1 4
+DROP TABLE t1,t2;
+#
+# Bug#879871: InnoDB: possible ICP + GROUP BY primary index
+#
+CREATE TABLE t1 (
+a int NOT NULL, b int, c varchar(1), d varchar(1),
+PRIMARY KEY (a), KEY c (c,b)
+);
+INSERT INTO t1 VALUES (10,8,'g','g');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+a
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+a
+DROP TABLE t1;
+#
+# Bug#904832: an attempt to perform an index condition pushdown
+# of a condition containing a subquery
+#
+CREATE TABLE t1 (
+a INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
+b INT, c INT, d DATE NOT NULL, e VARCHAR(1),
+KEY (c), KEY (d), KEY k2(b), KEY k3(b), KEY k4(b)
+);
+INSERT INTO t1 (b,c,d,e) VALUES
+(6,5,'2006-05-25','y'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(1,5,'2008-01-23','t'),(6,5,'2007-06-18','d'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','f'),
+(4,5,'2001-06-05','x'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(1,5,'2008-01-23','t'),(6,5,'2007-06-18','d'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(6,5,'2007-06-18','d'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(1,5,'2008-01-23','t'),(6,5,'2007-06-18','d'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,1,'1900-01-01','r'),
+(8,8,'1900-01-01','m'),(4,1,'2006-03-09','b'),
+(4,1,'2001-06-05','x'),(7,1,'2006-05-28','g');
+CREATE TABLE t2 (
+f INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
+g INT,
+h VARCHAR(1),
+KEY (g)
+);
+INSERT INTO t2 (g,h) VALUES
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(5,'l'),(8,'y'),(0,'p'),(0,'f'),(0,'p'),(7,'d'),
+(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'),
+(6,'i'),(1,'x'),(5,'l'),(8,'y'),(0,'p'),(0,'f'),
+(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(7,'d'),(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),
+(9,'u'),(6,'i'),(1,'x'),(5,'l'),(8,'y'),(0,'p'),
+(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),
+(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),(5,'l'),
+(6,'q'),(2,'n'),(4,'r'),(4,'b'),(8,'y'),(0,'p'),
+(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),
+(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),(5,'l'),
+(8,'y'),(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),
+(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),
+(1,'x'),(5,'l'),(8,'y'),(0,'p'),(0,'f'),(0,'p'),
+(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),
+(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),(7,'d'),
+(7,'f'),(5,'j'),(3,'e'),(1,'u'),(0,'f'),(0,'p'),
+(7,'d'),(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),
+(9,'u'),(6,'i'),(1,'x'),(5,'l'),(8,'y'),(0,'p'),
+(0,'f'),(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),
+(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),
+(1,'x'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),(1,'u'),
+(4,'v'),(9,'u'),(6,'i'),(1,'x'),(5,'l'),(8,'y'),
+(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(5,'l'),(6,'q'),(2,'n'),(4,'r'),(4,'b'),(8,'y'),
+(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u');
+SET @save_optimize_switch=@@optimizer_switch;
+SET optimizer_switch='materialization=on';
+EXPLAIN
+SELECT COUNT(*) FROM t1 AS t, t2
+WHERE c = g
+AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b)
+OR a = 0 AND h < 'z' );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t ALL PRIMARY,c NULL NULL NULL 64 Using where
+1 PRIMARY t2 ref g g 5 test.t.c 9 Using where
+2 DEPENDENT SUBQUERY t1 index PRIMARY d 3 NULL 64 Using where; Using index
+2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where
+SELECT COUNT(*) FROM t1 AS t, t2
+WHERE c = g
+AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b)
+OR a = 0 AND h < 'z' );
+COUNT(*)
+1478
+SELECT COUNT(*) FROM t1 AS t, t2
+WHERE c = g
+AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b)
+OR a = 0 AND h < 'z' );
+COUNT(*)
+1478
+SET optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2;
+# check "Handler_pushed" status varuiables
+CREATE TABLE t1 (
+c1 CHAR(1),
+c2 CHAR(1),
+KEY (c1)
+);
+INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5');
+flush status;
+show status like "Handler_icp%";
+Variable_name Value
+Handler_icp_attempts 0
+Handler_icp_match 0
+SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ;
+c1 c2
+4 4
+show status like "Handler_icp%";
+Variable_name Value
+Handler_icp_attempts 2
+Handler_icp_match 1
+SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ;
+c1 c2
+4 4
+show status like "Handler_icp%";
+Variable_name Value
+Handler_icp_attempts 2
+Handler_icp_match 1
+DROP TABLE t1;
+create table t1 (a int,b char(5),primary key (a), key (b(1)));
+insert into t1 values ('a','b');
+Warnings:
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 1
+select 1 from t1 where a and b >= 'aa';
+1
+drop table t1;
+#
+# Bug#58015 "Assert in row_sel_field_store_in_mysql_format
+# when running innodb_mrr_icp test"
+#
+create table t1 (a char(2) charset utf8,b double, primary key (a(1)),key (b));
+insert into t1 values ('',1);
+select 1 from t1 where b <= 1 and a <> '';
+1
+drop table t1;
+set optimizer_switch=@innodb_icp_tmp;
+set storage_engine= @save_storage_engine;
diff --git a/mysql-test/r/innodb_mrr.result b/mysql-test/r/innodb_mrr.result
new file mode 100644
index 00000000000..f56d55f7da2
--- /dev/null
+++ b/mysql-test/r/innodb_mrr.result
@@ -0,0 +1,771 @@
+drop table if exists t1,t2,t3,t4;
+set @save_storage_engine= @@storage_engine;
+set storage_engine=InnoDB;
+set @innodb_mrr_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+create table t1(a int);
+show create table t1;
+Table Create Table
+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 where; Rowid-ordered scan
+select * from t4 where a IS NULL and b IS NULL and (c IS NULL or c='no-such-row1'
+ or c='no-such-row2');
+a b c filler
+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 where; Rowid-ordered scan
+select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
+a b c filler
+b-1 NULL c-1 NULL-15
+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; Rowid-ordered scan
+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; Rowid-ordered scan
+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;
+#
+# BUG#665669: Result differences on query re-execution
+#
+create table t1 (pk int primary key, b int, c int default 0, index idx(b)) engine=innodb;
+insert into t1(pk,b) values (3, 30), (2, 20), (9, 90), (7, 70), (4, 40), (5, 50), (10, 100), (12, 120);
+set @bug665669_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=off';
+explain select * from t1 where b > 1000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx idx 5 NULL 1 Using index condition
+# The following two must produce indentical results:
+select * from t1 where pk < 2 or pk between 3 and 4;
+pk b c
+3 30 0
+4 40 0
+select * from t1 where pk < 2 or pk between 3 and 4;
+pk b c
+3 30 0
+4 40 0
+drop table t1;
+set optimizer_switch = @bug665669_tmp;
+#
+# Bug#43360 - Server crash with a simple multi-table update
+#
+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;
+#
+# Testcase backport: Bug#43249
+# (Note: Fixed by patch for BUG#42580)
+#
+CREATE TABLE t1(c1 TIME NOT NULL, c2 TIME NULL, c3 DATE, PRIMARY KEY(c1), UNIQUE INDEX(c2)) engine=innodb;
+INSERT INTO t1 VALUES('8:29:45',NULL,'2009-02-01');
+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`;
+#
+# BUG#707925: Wrong result with join_cache_level=6 optimizer_use_mrr =
+# force (incremental, BKA join)
+#
+set @_save_join_cache_level= @@join_cache_level;
+set join_cache_level = 6;
+CREATE TABLE t1 (
+f1 int(11), f2 int(11), f3 varchar(1), f4 varchar(1),
+PRIMARY KEY (f1),
+KEY (f3),
+KEY (f2)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('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 (
+SELECT alias1.f2
+FROM
+t1 AS alias1 JOIN (
+t1 AS alias2 FORCE KEY (f3) JOIN
+t1 AS alias3 FORCE KEY (f2) ON alias3.f2 = alias2.f2 AND alias3.f4 = alias2.f3
+) ON alias3.f1 <= alias2.f1
+) X;
+count(*)
+361
+set join_cache_level=@_save_join_cache_level;
+set optimizer_switch= @innodb_mrr_tmp;
+drop table t1;
diff --git a/mysql-test/r/innodb_mrr_cpk.result b/mysql-test/r/innodb_mrr_cpk.result
new file mode 100644
index 00000000000..90f59b96e61
--- /dev/null
+++ b/mysql-test/r/innodb_mrr_cpk.result
@@ -0,0 +1,151 @@
+drop table if exists t0,t1,t2,t3;
+set @innodb_mrr_cpk_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=6;
+set @save_storage_engine=@@storage_engine;
+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); Key-ordered scan
+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); Key-ordered scan
+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); Key-ordered scan
+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 where; Using join buffer (flat, BKA join); Key-ordered scan
+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 where; Using join buffer (flat, BKA join); Key-ordered scan
+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); Key-ordered scan
+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 where; Using join buffer (flat, BKA join); Key-ordered scan
+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); Key-ordered scan
+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;
+set optimizer_switch=@innodb_mrr_cpk_tmp;
+drop table t0;
diff --git a/mysql-test/r/innodb_no_mrricp.result b/mysql-test/r/innodb_no_mrricp.result
new file mode 100644
index 00000000000..674c47df171
--- /dev/null
+++ b/mysql-test/r/innodb_no_mrricp.result
@@ -0,0 +1,3316 @@
+set @innodb_with_mrricp=@@optimizer_switch;
+set optimizer_switch='mrr=off,mrr_sort_keys=off,index_condition_pushdown=off';
+set @innodb_test_dont_touch_optimizer_switch=1;
+set @innodb_test_tmp=@@optimizer_switch;
+set optimizer_switch =
+if(@innodb_test_dont_touch_optimizer_switch,
+@@optimizer_switch,
+'mrr=on,mrr_sort_keys=on,index_condition_pushdown=on');
+drop table if exists t1,t2,t3,t4;
+drop database if exists mysqltest;
+create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) engine=innodb;
+insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
+select id, code, name from t1 order by id;
+id code name
+1 1 Tim
+2 1 Monty
+3 2 David
+4 2 Erik
+5 3 Sasha
+6 3 Jeremy
+7 4 Matt
+update ignore t1 set id = 8, name = 'Sinisa' where id < 3;
+select id, code, name from t1 order by id;
+id code name
+2 1 Monty
+3 2 David
+4 2 Erik
+5 3 Sasha
+6 3 Jeremy
+7 4 Matt
+8 1 Sinisa
+update ignore t1 set id = id + 10, name = 'Ralph' where id < 4;
+select id, code, name from t1 order by id;
+id code name
+3 2 David
+4 2 Erik
+5 3 Sasha
+6 3 Jeremy
+7 4 Matt
+8 1 Sinisa
+12 1 Ralph
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+) engine=innodb;
+INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2);
+update t1 set parent_id=parent_id+100;
+select * from t1 where parent_id=102;
+id parent_id level
+8 102 2
+9 102 2
+15 102 2
+update t1 set id=id+1000;
+update t1 set id=1024 where id=1009;
+Got one of the listed errors
+select * from t1;
+id parent_id level
+1001 100 0
+1002 101 1
+1003 101 1
+1004 101 1
+1005 101 1
+1006 101 1
+1007 101 1
+1008 102 2
+1009 102 2
+1015 102 2
+1016 103 2
+1017 103 2
+1018 103 2
+1019 103 2
+1020 103 2
+1021 104 2
+1022 104 2
+1024 104 2
+1025 105 2
+1026 105 2
+1027 105 2
+1028 105 2
+1029 105 2
+1030 105 2
+1031 106 2
+1032 106 2
+1033 106 2
+1034 106 2
+1035 106 2
+1036 107 2
+1037 107 2
+1038 107 2
+1040 107 2
+1157 100 0
+1179 105 2
+1183 104 2
+1193 105 2
+1202 107 2
+1203 107 2
+update ignore t1 set id=id+1;
+select * from t1;
+id parent_id level
+1001 100 0
+1002 101 1
+1003 101 1
+1004 101 1
+1005 101 1
+1006 101 1
+1007 101 1
+1008 102 2
+1010 102 2
+1015 102 2
+1016 103 2
+1017 103 2
+1018 103 2
+1019 103 2
+1020 103 2
+1021 104 2
+1023 104 2
+1024 104 2
+1025 105 2
+1026 105 2
+1027 105 2
+1028 105 2
+1029 105 2
+1030 105 2
+1031 106 2
+1032 106 2
+1033 106 2
+1034 106 2
+1035 106 2
+1036 107 2
+1037 107 2
+1039 107 2
+1041 107 2
+1158 100 0
+1180 105 2
+1184 104 2
+1194 105 2
+1202 107 2
+1204 107 2
+update ignore t1 set id=1023 where id=1010;
+select * from t1 where parent_id=102;
+id parent_id level
+1008 102 2
+1010 102 2
+1015 102 2
+explain select level from t1 where level=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref level level 1 const # Using index
+explain select level,id from t1 where level=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref level level 1 const # Using index
+explain select level,id,parent_id from t1 where level=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref level level 1 const #
+select level,id from t1 where level=1;
+level id
+1 1002
+1 1003
+1 1004
+1 1005
+1 1006
+1 1007
+select level,id,parent_id from t1 where level=1;
+level id parent_id
+1 1002 101
+1 1003 101
+1 1004 101
+1 1005 101
+1 1006 101
+1 1007 101
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize status OK
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 id A # NULL NULL BTREE
+t1 1 parent_id 1 parent_id A # NULL NULL BTREE
+t1 1 level 1 level A # NULL NULL BTREE
+drop table t1;
+CREATE TABLE t1 (
+gesuchnr int(11) DEFAULT '0' NOT NULL,
+benutzer_id int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (gesuchnr,benutzer_id)
+) engine=innodb;
+replace into t1 (gesuchnr,benutzer_id) values (2,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+select * from t1;
+gesuchnr benutzer_id
+1 1
+2 1
+drop table t1;
+create table t1 (a int) engine=innodb;
+insert into t1 values (1), (2);
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize status OK
+delete from t1 where a = 1;
+select * from t1;
+a
+2
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+create table t1 (a int,b varchar(20)) engine=innodb;
+insert into t1 values (1,""), (2,"testing");
+delete from t1 where a = 1;
+select * from t1;
+a b
+2 testing
+create index skr on t1 (a);
+insert into t1 values (3,""), (4,"testing");
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 skr 1 a A # NULL NULL YES BTREE
+drop table t1;
+create table t1 (a int,b varchar(20),key(a)) engine=innodb;
+insert into t1 values (1,""), (2,"testing");
+select * from t1 where a = 1;
+a b
+1
+drop table t1;
+create table t1 (n int not null primary key) engine=innodb;
+set autocommit=0;
+insert into t1 values (4);
+rollback;
+select n, "after rollback" from t1;
+n after rollback
+insert into t1 values (4);
+commit;
+select n, "after commit" from t1;
+n after commit
+4 after commit
+commit;
+insert into t1 values (5);
+insert into t1 values (4);
+ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
+commit;
+select n, "after commit" from t1;
+n after commit
+4 after commit
+5 after commit
+set autocommit=1;
+insert into t1 values (6);
+insert into t1 values (4);
+ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
+select n from t1;
+n
+4
+5
+6
+set autocommit=0;
+begin;
+savepoint `my_savepoint`;
+insert into t1 values (7);
+savepoint `savept2`;
+insert into t1 values (3);
+select n from t1;
+n
+3
+4
+5
+6
+7
+savepoint savept3;
+rollback to savepoint savept2;
+rollback to savepoint savept3;
+ERROR 42000: SAVEPOINT savept3 does not exist
+rollback to savepoint savept2;
+release savepoint `my_savepoint`;
+select n from t1;
+n
+4
+5
+6
+7
+rollback to savepoint `my_savepoint`;
+ERROR 42000: SAVEPOINT my_savepoint does not exist
+rollback to savepoint savept2;
+ERROR 42000: SAVEPOINT savept2 does not exist
+insert into t1 values (8);
+savepoint sv;
+commit;
+savepoint sv;
+set autocommit=1;
+rollback;
+drop table t1;
+create table t1 (n int not null primary key) engine=innodb;
+start transaction;
+insert into t1 values (4);
+flush tables with read lock;
+commit;
+unlock tables;
+commit;
+select * from t1;
+n
+4
+drop table t1;
+create table t1 ( id int NOT NULL PRIMARY KEY, nom varchar(64)) engine=innodb;
+begin;
+insert into t1 values(1,'hamdouni');
+select id as afterbegin_id,nom as afterbegin_nom from t1;
+afterbegin_id afterbegin_nom
+1 hamdouni
+rollback;
+select id as afterrollback_id,nom as afterrollback_nom from t1;
+afterrollback_id afterrollback_nom
+set autocommit=0;
+insert into t1 values(2,'mysql');
+select id as afterautocommit0_id,nom as afterautocommit0_nom from t1;
+afterautocommit0_id afterautocommit0_nom
+2 mysql
+rollback;
+select id as afterrollback_id,nom as afterrollback_nom from t1;
+afterrollback_id afterrollback_nom
+set autocommit=1;
+drop table t1;
+CREATE TABLE t1 (id char(8) not null primary key, val int not null) engine=innodb;
+insert into t1 values ('pippo', 12);
+insert into t1 values ('pippo', 12);
+ERROR 23000: Duplicate entry 'pippo' for key 'PRIMARY'
+delete from t1;
+delete from t1 where id = 'pippo';
+select * from t1;
+id val
+insert into t1 values ('pippo', 12);
+set autocommit=0;
+delete from t1;
+rollback;
+select * from t1;
+id val
+pippo 12
+delete from t1;
+commit;
+select * from t1;
+id val
+drop table t1;
+create table t1 (a integer) engine=innodb;
+start transaction;
+rename table t1 to t2;
+create table t1 (b integer) engine=innodb;
+insert into t1 values (1);
+rollback;
+drop table t1;
+rename table t2 to t1;
+drop table t1;
+set autocommit=1;
+CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, NAME VARCHAR(64)) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 'Jochen');
+select * from t1;
+ID NAME
+1 Jochen
+drop table t1;
+CREATE TABLE t1 ( _userid VARCHAR(60) NOT NULL PRIMARY KEY) ENGINE=innodb;
+set autocommit=0;
+INSERT INTO t1 SET _userid='marc@anyware.co.uk';
+COMMIT;
+SELECT * FROM t1;
+_userid
+marc@anyware.co.uk
+SELECT _userid FROM t1 WHERE _userid='marc@anyware.co.uk';
+_userid
+marc@anyware.co.uk
+drop table t1;
+set autocommit=1;
+CREATE TABLE t1 (
+user_id int(10) DEFAULT '0' NOT NULL,
+name varchar(100),
+phone varchar(100),
+ref_email varchar(100) DEFAULT '' NOT NULL,
+detail varchar(200),
+PRIMARY KEY (user_id,ref_email)
+)engine=innodb;
+INSERT INTO t1 VALUES (10292,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10292,'shirish','2333604','shirish@yahoo.com','ddsds'),(10292,'sonali','323232','sonali@bolly.com','filmstar');
+select * from t1 where user_id=10292;
+user_id name phone ref_email detail
+10292 sanjeev 29153373 sansh777@hotmail.com xxx
+10292 shirish 2333604 shirish@yahoo.com ddsds
+10292 sonali 323232 sonali@bolly.com filmstar
+INSERT INTO t1 VALUES (10291,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10293,'shirish','2333604','shirish@yahoo.com','ddsds');
+select * from t1 where user_id=10292;
+user_id name phone ref_email detail
+10292 sanjeev 29153373 sansh777@hotmail.com xxx
+10292 shirish 2333604 shirish@yahoo.com ddsds
+10292 sonali 323232 sonali@bolly.com filmstar
+select * from t1 where user_id>=10292;
+user_id name phone ref_email detail
+10292 sanjeev 29153373 sansh777@hotmail.com xxx
+10292 shirish 2333604 shirish@yahoo.com ddsds
+10292 sonali 323232 sonali@bolly.com filmstar
+10293 shirish 2333604 shirish@yahoo.com ddsds
+select * from t1 where user_id>10292;
+user_id name phone ref_email detail
+10293 shirish 2333604 shirish@yahoo.com ddsds
+select * from t1 where user_id<10292;
+user_id name phone ref_email detail
+10291 sanjeev 29153373 sansh777@hotmail.com xxx
+drop table t1;
+CREATE TABLE t1 (a int not null, b int not null,c int not null,
+key(a),primary key(a,b), unique(c),key(a),unique(b));
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A # NULL NULL BTREE
+t1 0 PRIMARY 2 b A # NULL NULL BTREE
+t1 0 c 1 c A # NULL NULL BTREE
+t1 0 b 1 b A # NULL NULL BTREE
+t1 1 a 1 a A # NULL NULL BTREE
+t1 1 a_2 1 a A # NULL NULL BTREE
+drop table t1;
+create table t1 (col1 int not null, col2 char(4) not null, primary key(col1));
+alter table t1 engine=innodb;
+insert into t1 values ('1','1'),('5','2'),('2','3'),('3','4'),('4','4');
+select * from t1;
+col1 col2
+1 1
+2 3
+3 4
+4 4
+5 2
+update t1 set col2='7' where col1='4';
+select * from t1;
+col1 col2
+1 1
+2 3
+3 4
+4 7
+5 2
+alter table t1 add co3 int not null;
+select * from t1;
+col1 col2 co3
+1 1 0
+2 3 0
+3 4 0
+4 7 0
+5 2 0
+update t1 set col2='9' where col1='2';
+select * from t1;
+col1 col2 co3
+1 1 0
+2 9 0
+3 4 0
+4 7 0
+5 2 0
+drop table t1;
+create table t1 (a int not null , b int, primary key (a)) engine = innodb;
+create table t2 (a int not null , b int, primary key (a)) engine = myisam;
+insert into t1 VALUES (1,3) , (2,3), (3,3);
+select * from t1;
+a b
+1 3
+2 3
+3 3
+insert into t2 select * from t1;
+select * from t2;
+a b
+1 3
+2 3
+3 3
+delete from t1 where b = 3;
+select * from t1;
+a b
+insert into t1 select * from t2;
+select * from t1;
+a b
+1 3
+2 3
+3 3
+select * from t2;
+a b
+1 3
+2 3
+3 3
+drop table t1,t2;
+CREATE TABLE t1 (
+user_name varchar(12),
+password text,
+subscribed char(1),
+user_id int(11) DEFAULT '0' NOT NULL,
+quota bigint(20),
+weight double,
+access_date date,
+access_time time,
+approved datetime,
+dummy_primary_key int(11) NOT NULL auto_increment,
+PRIMARY KEY (dummy_primary_key)
+) ENGINE=innodb;
+INSERT INTO t1 VALUES ('user_0','somepassword','N',0,0,0,'2000-09-07','23:06:59','2000-09-07 23:06:59',1);
+INSERT INTO t1 VALUES ('user_1','somepassword','Y',1,1,1,'2000-09-07','23:06:59','2000-09-07 23:06:59',2);
+INSERT INTO t1 VALUES ('user_2','somepassword','N',2,2,1.4142135623731,'2000-09-07','23:06:59','2000-09-07 23:06:59',3);
+INSERT INTO t1 VALUES ('user_3','somepassword','Y',3,3,1.7320508075689,'2000-09-07','23:06:59','2000-09-07 23:06:59',4);
+INSERT INTO t1 VALUES ('user_4','somepassword','N',4,4,2,'2000-09-07','23:06:59','2000-09-07 23:06:59',5);
+select user_name, password , subscribed, user_id, quota, weight, access_date, access_time, approved, dummy_primary_key from t1 order by user_name;
+user_name password subscribed user_id quota weight access_date access_time approved dummy_primary_key
+user_0 somepassword N 0 0 0 2000-09-07 23:06:59 2000-09-07 23:06:59 1
+user_1 somepassword Y 1 1 1 2000-09-07 23:06:59 2000-09-07 23:06:59 2
+user_2 somepassword N 2 2 1.4142135623731 2000-09-07 23:06:59 2000-09-07 23:06:59 3
+user_3 somepassword Y 3 3 1.7320508075689 2000-09-07 23:06:59 2000-09-07 23:06:59 4
+user_4 somepassword N 4 4 2 2000-09-07 23:06:59 2000-09-07 23:06:59 5
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+) engine=innodb;
+INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1);
+INSERT INTO t1 values (179,5,2);
+update t1 set parent_id=parent_id+100;
+select * from t1 where parent_id=102;
+id parent_id level
+8 102 2
+9 102 2
+15 102 2
+update t1 set id=id+1000;
+update t1 set id=1024 where id=1009;
+select * from t1;
+id parent_id level
+1001 100 0
+1003 101 1
+1004 101 1
+1008 102 2
+1024 102 2
+1017 103 2
+1022 104 2
+1024 104 2
+1028 105 2
+1029 105 2
+1030 105 2
+1031 106 2
+1032 106 2
+1033 106 2
+1203 107 2
+1202 107 2
+1020 103 2
+1157 100 0
+1193 105 2
+1040 107 2
+1002 101 1
+1015 102 2
+1006 101 1
+1034 106 2
+1035 106 2
+1016 103 2
+1007 101 1
+1036 107 2
+1018 103 2
+1026 105 2
+1027 105 2
+1183 104 2
+1038 107 2
+1025 105 2
+1037 107 2
+1021 104 2
+1019 103 2
+1005 101 1
+1179 105 2
+update ignore t1 set id=id+1;
+select * from t1;
+id parent_id level
+1002 100 0
+1004 101 1
+1005 101 1
+1009 102 2
+1025 102 2
+1018 103 2
+1023 104 2
+1025 104 2
+1029 105 2
+1030 105 2
+1031 105 2
+1032 106 2
+1033 106 2
+1034 106 2
+1204 107 2
+1203 107 2
+1021 103 2
+1158 100 0
+1194 105 2
+1041 107 2
+1003 101 1
+1016 102 2
+1007 101 1
+1035 106 2
+1036 106 2
+1017 103 2
+1008 101 1
+1037 107 2
+1019 103 2
+1027 105 2
+1028 105 2
+1184 104 2
+1039 107 2
+1026 105 2
+1038 107 2
+1022 104 2
+1020 103 2
+1006 101 1
+1180 105 2
+update ignore t1 set id=1023 where id=1010;
+select * from t1 where parent_id=102;
+id parent_id level
+1009 102 2
+1025 102 2
+1016 102 2
+explain select level from t1 where level=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref level level 1 const # Using index
+select level,id from t1 where level=1;
+level id
+1 1004
+1 1005
+1 1003
+1 1007
+1 1008
+1 1006
+select level,id,parent_id from t1 where level=1;
+level id parent_id
+1 1004 101
+1 1005 101
+1 1003 101
+1 1007 101
+1 1008 101
+1 1006 101
+select level,id from t1 where level=1 order by id;
+level id
+1 1003
+1 1004
+1 1005
+1 1006
+1 1007
+1 1008
+delete from t1 where level=1;
+select * from t1;
+id parent_id level
+1002 100 0
+1009 102 2
+1025 102 2
+1018 103 2
+1023 104 2
+1025 104 2
+1029 105 2
+1030 105 2
+1031 105 2
+1032 106 2
+1033 106 2
+1034 106 2
+1204 107 2
+1203 107 2
+1021 103 2
+1158 100 0
+1194 105 2
+1041 107 2
+1016 102 2
+1035 106 2
+1036 106 2
+1017 103 2
+1037 107 2
+1019 103 2
+1027 105 2
+1028 105 2
+1184 104 2
+1039 107 2
+1026 105 2
+1038 107 2
+1022 104 2
+1020 103 2
+1180 105 2
+drop table t1;
+CREATE TABLE t1 (
+sca_code char(6) NOT NULL,
+cat_code char(6) NOT NULL,
+sca_desc varchar(50),
+lan_code char(2) NOT NULL,
+sca_pic varchar(100),
+sca_sdesc varchar(50),
+sca_sch_desc varchar(16),
+PRIMARY KEY (sca_code, cat_code, lan_code),
+INDEX sca_pic (sca_pic)
+) engine = innodb ;
+INSERT INTO t1 ( sca_code, cat_code, sca_desc, lan_code, sca_pic, sca_sdesc, sca_sch_desc) VALUES ( 'PD', 'J', 'PENDANT', 'EN', NULL, NULL, 'PENDANT'),( 'RI', 'J', 'RING', 'EN', NULL, NULL, 'RING'),( 'QQ', 'N', 'RING', 'EN', 'not null', NULL, 'RING');
+select count(*) from t1 where sca_code = 'PD';
+count(*)
+1
+select count(*) from t1 where sca_code <= 'PD';
+count(*)
+1
+select count(*) from t1 where sca_pic is null;
+count(*)
+2
+alter table t1 drop index sca_pic;
+alter table t1 add index sca_pic (cat_code, sca_pic);
+select count(*) from t1 where sca_code='PD' and sca_pic is null;
+count(*)
+1
+select count(*) from t1 where cat_code='E';
+count(*)
+0
+alter table t1 drop index sca_pic;
+alter table t1 add index (sca_pic, cat_code);
+select count(*) from t1 where sca_code='PD' and sca_pic is null;
+count(*)
+1
+select count(*) from t1 where sca_pic >= 'n';
+count(*)
+1
+select sca_pic from t1 where sca_pic is null;
+sca_pic
+NULL
+NULL
+update t1 set sca_pic="test" where sca_pic is null;
+delete from t1 where sca_code='pd';
+drop table t1;
+set @a:=now();
+CREATE TABLE t1 (a int not null, b timestamp not null, primary key (a)) engine=innodb;
+insert into t1 (a) values(1),(2),(3);
+select t1.a from t1 natural join t1 as t2 where t1.b >= @a order by t1.a;
+a
+1
+2
+3
+select a from t1 natural join t1 as t2 where b >= @a order by a;
+a
+1
+2
+3
+update t1 set a=5 where a=1;
+select a from t1;
+a
+2
+3
+5
+drop table t1;
+create table t1 (a varchar(100) not null, primary key(a), b int not null) engine=innodb;
+insert into t1 values("hello",1),("world",2);
+select * from t1 order by b desc;
+a b
+world 2
+hello 1
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize status OK
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A # NULL NULL BTREE
+drop table t1;
+create table t1 (i int, j int ) ENGINE=innodb;
+insert into t1 values (1,2);
+select * from t1 where i=1 and j=2;
+i j
+1 2
+create index ax1 on t1 (i,j);
+select * from t1 where i=1 and j=2;
+i j
+1 2
+drop table t1;
+CREATE TABLE t1 (
+a int3 unsigned NOT NULL,
+b int1 unsigned NOT NULL,
+UNIQUE (a, b)
+) ENGINE = innodb;
+INSERT INTO t1 VALUES (1, 1);
+SELECT MIN(B),MAX(b) FROM t1 WHERE t1.a = 1;
+MIN(B) MAX(b)
+1 1
+drop table t1;
+CREATE TABLE t1 (a int unsigned NOT NULL) engine=innodb;
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+a
+1
+DROP TABLE t1;
+create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h int, i int, j int, k int, l int, m int, n int, o int, p int, q int, r int, s int, t int, u int, v int, w int, x int, y int, z int, a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, b1 int, b2 int, b3 int, b4 int, b5 int, b6 int) engine = innodb;
+insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
+explain select * from t1 where a > 0 and a < 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL # Using where
+drop table t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) engine=innodb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
+LOCK TABLES t1 WRITE;
+insert into t1 values (99,1,2,'D'),(1,1,2,'D');
+ERROR 23000: Duplicate entry '1-1' for key 'PRIMARY'
+select id from t1;
+id
+0
+1
+2
+select id from t1;
+id
+0
+1
+2
+UNLOCK TABLES;
+DROP TABLE t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) engine=innodb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
+LOCK TABLES t1 WRITE;
+begin;
+insert into t1 values (99,1,2,'D'),(1,1,2,'D');
+ERROR 23000: Duplicate entry '1-1' for key 'PRIMARY'
+select id from t1;
+id
+0
+1
+2
+insert ignore into t1 values (100,1,2,'D'),(1,1,99,'D');
+commit;
+select id,id3 from t1;
+id id3
+0 0
+1 1
+2 2
+100 2
+UNLOCK TABLES;
+DROP TABLE t1;
+create table t1 (a char(20), unique (a(5))) engine=innodb;
+drop table t1;
+create table t1 (a char(20), index (a(5))) engine=innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(20) DEFAULT NULL,
+ KEY `a` (`a`(5))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+create temporary table t1 (a int not null auto_increment, primary key(a)) engine=innodb;
+insert into t1 values (NULL),(NULL),(NULL);
+delete from t1 where a=3;
+insert into t1 values (NULL);
+select * from t1;
+a
+1
+2
+4
+alter table t1 add b int;
+select * from t1;
+a b
+1 NULL
+2 NULL
+4 NULL
+drop table t1;
+create table t1
+(
+id int auto_increment primary key,
+name varchar(32) not null,
+value text not null,
+uid int not null,
+unique key(name,uid)
+) engine=innodb;
+insert into t1 values (1,'one','one value',101),
+(2,'two','two value',102),(3,'three','three value',103);
+set insert_id=5;
+replace into t1 (value,name,uid) values ('other value','two',102);
+delete from t1 where uid=102;
+set insert_id=5;
+replace into t1 (value,name,uid) values ('other value','two',102);
+set insert_id=6;
+replace into t1 (value,name,uid) values ('other value','two',102);
+select * from t1;
+id name value uid
+1 one one value 101
+3 three three value 103
+6 two other value 102
+drop table t1;
+create database mysqltest;
+create table mysqltest.t1 (a int not null) engine= innodb;
+insert into mysqltest.t1 values(1);
+create table mysqltest.t2 (a int not null) engine= myisam;
+insert into mysqltest.t2 values(1);
+create table mysqltest.t3 (a int not null) engine= heap;
+insert into mysqltest.t3 values(1);
+commit;
+drop database mysqltest;
+show tables from mysqltest;
+ERROR 42000: Unknown database 'mysqltest'
+set autocommit=0;
+create table t1 (a int not null) engine= innodb;
+insert into t1 values(1),(2);
+truncate table t1;
+commit;
+truncate table t1;
+truncate table t1;
+select * from t1;
+a
+insert into t1 values(1),(2);
+delete from t1;
+select * from t1;
+a
+commit;
+drop table t1;
+set autocommit=1;
+create table t1 (a int not null) engine= innodb;
+insert into t1 values(1),(2);
+truncate table t1;
+insert into t1 values(1),(2);
+select * from t1;
+a
+1
+2
+truncate table t1;
+insert into t1 values(1),(2);
+delete from t1;
+select * from t1;
+a
+drop table t1;
+create table t1 (a int not null, b int not null, c int not null, primary key (a),key(b)) engine=innodb;
+insert into t1 values (3,3,3),(1,1,1),(2,2,2),(4,4,4);
+explain select * from t1 order by a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 4 NULL #
+explain select * from t1 order by b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL # Using filesort
+explain select * from t1 order by c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL # Using filesort
+explain select a from t1 order by a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 4 NULL # Using index
+explain select b from t1 order by b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL b 4 NULL # Using index
+explain select a,b from t1 order by b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL b 4 NULL # Using index
+explain select a,b from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL b 4 NULL # Using index
+explain select a,b,c from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL #
+drop table t1;
+create table t1 (t int not null default 1, key (t)) engine=innodb;
+desc t1;
+Field Type Null Key Default Extra
+t int(11) NO MUL 1
+drop table t1;
+CREATE TABLE t1 (
+number bigint(20) NOT NULL default '0',
+cname char(15) NOT NULL default '',
+carrier_id smallint(6) NOT NULL default '0',
+privacy tinyint(4) NOT NULL default '0',
+last_mod_date timestamp NOT NULL,
+last_mod_id smallint(6) NOT NULL default '0',
+last_app_date timestamp NOT NULL,
+last_app_id smallint(6) default '-1',
+version smallint(6) NOT NULL default '0',
+assigned_scps int(11) default '0',
+status tinyint(4) default '0'
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (4077711111,'SeanWheeler',90,2,20020111112846,500,00000000000000,-1,2,3,1);
+INSERT INTO t1 VALUES (9197722223,'berry',90,3,20020111112809,500,20020102114532,501,4,10,0);
+INSERT INTO t1 VALUES (650,'San Francisco',0,0,20011227111336,342,00000000000000,-1,1,24,1);
+INSERT INTO t1 VALUES (302467,'Sue\'s Subshop',90,3,20020109113241,500,20020102115111,501,7,24,0);
+INSERT INTO t1 VALUES (6014911113,'SudzCarwash',520,1,20020102115234,500,20020102115259,501,33,32768,0);
+INSERT INTO t1 VALUES (333,'tubs',99,2,20020109113440,501,20020109113440,500,3,10,0);
+CREATE TABLE t2 (
+number bigint(20) NOT NULL default '0',
+cname char(15) NOT NULL default '',
+carrier_id smallint(6) NOT NULL default '0',
+privacy tinyint(4) NOT NULL default '0',
+last_mod_date timestamp NOT NULL,
+last_mod_id smallint(6) NOT NULL default '0',
+last_app_date timestamp NOT NULL,
+last_app_id smallint(6) default '-1',
+version smallint(6) NOT NULL default '0',
+assigned_scps int(11) default '0',
+status tinyint(4) default '0'
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (4077711111,'SeanWheeler',0,2,20020111112853,500,00000000000000,-1,2,3,1);
+INSERT INTO t2 VALUES (9197722223,'berry',90,3,20020111112818,500,20020102114532,501,4,10,0);
+INSERT INTO t2 VALUES (650,'San Francisco',90,0,20020109113158,342,00000000000000,-1,1,24,1);
+INSERT INTO t2 VALUES (333,'tubs',99,2,20020109113453,501,20020109113453,500,3,10,0);
+select * from t1;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+4077711111 SeanWheeler 90 2 2002-01-11 11:28:46 500 0000-00-00 00:00:00 -1 2 3 1
+9197722223 berry 90 3 2002-01-11 11:28:09 500 2002-01-02 11:45:32 501 4 10 0
+650 San Francisco 0 0 2001-12-27 11:13:36 342 0000-00-00 00:00:00 -1 1 24 1
+302467 Sue's Subshop 90 3 2002-01-09 11:32:41 500 2002-01-02 11:51:11 501 7 24 0
+6014911113 SudzCarwash 520 1 2002-01-02 11:52:34 500 2002-01-02 11:52:59 501 33 32768 0
+333 tubs 99 2 2002-01-09 11:34:40 501 2002-01-09 11:34:40 500 3 10 0
+select * from t2;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+4077711111 SeanWheeler 0 2 2002-01-11 11:28:53 500 0000-00-00 00:00:00 -1 2 3 1
+9197722223 berry 90 3 2002-01-11 11:28:18 500 2002-01-02 11:45:32 501 4 10 0
+650 San Francisco 90 0 2002-01-09 11:31:58 342 0000-00-00 00:00:00 -1 1 24 1
+333 tubs 99 2 2002-01-09 11:34:53 501 2002-01-09 11:34:53 500 3 10 0
+delete t1, t2 from t1 left join t2 on t1.number=t2.number where (t1.carrier_id=90 and t1.number=t2.number) or (t2.carrier_id=90 and t1.number=t2.number) or (t1.carrier_id=90 and t2.number is null);
+select * from t1;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+6014911113 SudzCarwash 520 1 2002-01-02 11:52:34 500 2002-01-02 11:52:59 501 33 32768 0
+333 tubs 99 2 2002-01-09 11:34:40 501 2002-01-09 11:34:40 500 3 10 0
+select * from t2;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+333 tubs 99 2 2002-01-09 11:34:53 501 2002-01-09 11:34:53 500 3 10 0
+select * from t2;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+333 tubs 99 2 2002-01-09 11:34:53 501 2002-01-09 11:34:53 500 3 10 0
+drop table t1,t2;
+create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) engine=innodb;
+BEGIN;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+SELECT @@tx_isolation,@@global.tx_isolation;
+@@tx_isolation @@global.tx_isolation
+SERIALIZABLE REPEATABLE-READ
+insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David');
+select id, code, name from t1 order by id;
+id code name
+1 1 Tim
+2 1 Monty
+3 2 David
+COMMIT;
+BEGIN;
+SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+insert into t1 (code, name) values (2, 'Erik'), (3, 'Sasha');
+select id, code, name from t1 order by id;
+id code name
+1 1 Tim
+2 1 Monty
+3 2 David
+4 2 Erik
+5 3 Sasha
+COMMIT;
+SET binlog_format='MIXED';
+BEGIN;
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+insert into t1 (code, name) values (3, 'Jeremy'), (4, 'Matt');
+select id, code, name from t1 order by id;
+id code name
+1 1 Tim
+2 1 Monty
+3 2 David
+4 2 Erik
+5 3 Sasha
+6 3 Jeremy
+7 4 Matt
+COMMIT;
+DROP TABLE t1;
+create table t1 (n int(10), d int(10)) engine=innodb;
+create table t2 (n int(10), d int(10)) engine=innodb;
+insert into t1 values(1,1),(1,2);
+insert into t2 values(1,10),(2,20);
+UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n;
+select * from t1;
+n d
+1 10
+1 10
+select * from t2;
+n d
+1 30
+2 20
+drop table t1,t2;
+drop table if exists t1, t2;
+CREATE TABLE t1 (a int, PRIMARY KEY (a));
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
+create trigger trg_del_t2 after delete on t2 for each row
+insert into t1 values (1);
+insert into t1 values (1);
+insert into t2 values (1),(2);
+delete t2 from t2;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+select count(*) from t2 /* must be 2 as restored after rollback caused by the error */;
+count(*)
+2
+drop table t1, t2;
+drop table if exists t1, t2;
+CREATE TABLE t1 (a int, PRIMARY KEY (a));
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
+create trigger trg_del_t2 after delete on t2 for each row
+insert into t1 values (1);
+insert into t1 values (1);
+insert into t2 values (1),(2);
+delete t2 from t2;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+select count(*) from t2 /* must be 2 as restored after rollback caused by the error */;
+count(*)
+2
+drop table t1, t2;
+create table t1 (a int, b int) engine=innodb;
+insert into t1 values(20,null);
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a;
+b ifnull(t2.b,"this is null")
+NULL this is null
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a order by 1;
+b ifnull(t2.b,"this is null")
+NULL this is null
+insert into t1 values(10,null);
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a order by 1;
+b ifnull(t2.b,"this is null")
+NULL this is null
+NULL this is null
+drop table t1;
+create table t1 (a varchar(10) not null) engine=myisam;
+create table t2 (b varchar(10) not null unique) engine=innodb;
+select t1.a from t1,t2 where t1.a=t2.b;
+a
+drop table t1,t2;
+create table t1 (a int not null, b int, primary key (a)) engine = innodb;
+create table t2 (a int not null, b int, primary key (a)) engine = innodb;
+insert into t1 values (10, 20);
+insert into t2 values (10, 20);
+update t1, t2 set t1.b = 150, t2.b = t1.b where t2.a = t1.a and t1.a = 10;
+drop table t1,t2;
+CREATE TABLE t1 (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB;
+CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE CASCADE ) ENGINE=INNODB;
+insert into t1 set id=1;
+insert into t2 set id=1, t1_id=1;
+delete t1,t2 from t1,t2 where t1.id=t2.t1_id;
+select * from t1;
+id
+select * from t2;
+id t1_id
+drop table t2,t1;
+CREATE TABLE t1(id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB;
+CREATE TABLE t2(id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id) ) ENGINE=INNODB;
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(1, 1);
+SELECT * from t1;
+id
+1
+UPDATE t1,t2 SET t1.id=t1.id+1, t2.t1_id=t1.id+1;
+SELECT * from t1;
+id
+2
+UPDATE t1,t2 SET t1.id=t1.id+1 where t1.id!=t2.id;
+SELECT * from t1;
+id
+3
+DROP TABLE t1,t2;
+set autocommit=0;
+CREATE TABLE t1 (id CHAR(15) NOT NULL, value CHAR(40) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;
+CREATE TABLE t2 (id CHAR(15) NOT NULL, value CHAR(40) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;
+CREATE TABLE t3 (id1 CHAR(15) NOT NULL, id2 CHAR(15) NOT NULL, PRIMARY KEY(id1, id2)) ENGINE=InnoDB;
+INSERT INTO t3 VALUES("my-test-1", "my-test-2");
+COMMIT;
+INSERT INTO t1 VALUES("this-key", "will disappear");
+INSERT INTO t2 VALUES("this-key", "will also disappear");
+DELETE FROM t3 WHERE id1="my-test-1";
+SELECT * FROM t1;
+id value
+this-key will disappear
+SELECT * FROM t2;
+id value
+this-key will also disappear
+SELECT * FROM t3;
+id1 id2
+ROLLBACK;
+SELECT * FROM t1;
+id value
+SELECT * FROM t2;
+id value
+SELECT * FROM t3;
+id1 id2
+my-test-1 my-test-2
+SELECT * FROM t3 WHERE id1="my-test-1" LOCK IN SHARE MODE;
+id1 id2
+my-test-1 my-test-2
+COMMIT;
+set autocommit=1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int not null primary key, b int not null, unique (b)) engine=innodb;
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+UPDATE t1 set a=a+100 where b between 2 and 3 and a < 1000;
+SELECT * from t1;
+a b
+1 1
+102 2
+103 3
+4 4
+5 5
+6 6
+7 7
+8 8
+9 9
+drop table t1;
+CREATE TABLE t1 (a int not null primary key, b int not null, key (b)) engine=innodb;
+CREATE TABLE t2 (a int not null primary key, b int not null, key (b)) engine=innodb;
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10),(11,11),(12,12);
+INSERT INTO t2 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+update t1,t2 set t1.a=t1.a+100;
+select * from t1;
+a b
+101 1
+102 2
+103 3
+104 4
+105 5
+106 6
+107 7
+108 8
+109 9
+110 10
+111 11
+112 12
+update t1,t2 set t1.a=t1.a+100 where t1.a=101;
+select * from t1;
+a b
+201 1
+102 2
+103 3
+104 4
+105 5
+106 6
+107 7
+108 8
+109 9
+110 10
+111 11
+112 12
+update t1,t2 set t1.b=t1.b+10 where t1.b=2;
+select * from t1;
+a b
+201 1
+103 3
+104 4
+105 5
+106 6
+107 7
+108 8
+109 9
+110 10
+111 11
+102 12
+112 12
+update t1,t2 set t1.b=t1.b+2,t2.b=t1.b+10 where t1.b between 3 and 5 and t1.a=t2.a+100;
+select * from t1;
+a b
+201 1
+103 5
+104 6
+106 6
+105 7
+107 7
+108 8
+109 9
+110 10
+111 11
+102 12
+112 12
+select * from t2;
+a b
+1 1
+2 2
+6 6
+7 7
+8 8
+9 9
+3 13
+4 14
+5 15
+drop table t1,t2;
+CREATE TABLE t2 ( NEXT_T BIGINT NOT NULL PRIMARY KEY) ENGINE=MyISAM;
+CREATE TABLE t1 ( B_ID INTEGER NOT NULL PRIMARY KEY) ENGINE=InnoDB;
+SET AUTOCOMMIT=0;
+INSERT INTO t1 ( B_ID ) VALUES ( 1 );
+INSERT INTO t2 ( NEXT_T ) VALUES ( 1 );
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+SELECT * FROM t1;
+B_ID
+drop table t1,t2;
+create table t1 ( pk int primary key, parent int not null, child int not null, index (parent) ) engine = innodb;
+insert into t1 values (1,0,4), (2,1,3), (3,2,1), (4,1,2);
+select distinct parent,child from t1 order by parent;
+parent child
+0 4
+1 2
+1 3
+2 1
+drop table t1;
+create table t1 (a int not null auto_increment primary key, b int, c int, key(c)) engine=innodb;
+create table t2 (a int not null auto_increment primary key, b int);
+insert into t1 (b) values (null),(null),(null),(null),(null),(null),(null);
+insert into t2 (a) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+select count(*) from t1;
+count(*)
+623
+explain select * from t1 where c between 1 and 2500;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c c 5 NULL # Using where
+update t1 set c=a;
+explain select * from t1 where c between 1 and 2500;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL c NULL NULL NULL # Using where
+drop table t1,t2;
+create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) engine=innodb;
+insert into t1 (id) values (null),(null),(null),(null),(null);
+update t1 set fk=69 where fk is null order by id limit 1;
+SELECT * from t1;
+id fk
+2 NULL
+3 NULL
+4 NULL
+5 NULL
+1 69
+drop table t1;
+create table t1 (a int not null, b int not null, key (a));
+insert into t1 values (1,1),(1,2),(1,3),(3,1),(3,2),(3,3),(3,1),(3,2),(3,3),(2,1),(2,2),(2,3);
+SET @tmp=0;
+update t1 set b=(@tmp:=@tmp+1) order by a;
+update t1 set b=99 where a=1 order by b asc limit 1;
+update t1 set b=100 where a=1 order by b desc limit 2;
+update t1 set a=a+10+b where a=1 order by b;
+select * from t1 order by a,b;
+a b
+2 4
+2 5
+2 6
+3 7
+3 8
+3 9
+3 10
+3 11
+3 12
+13 2
+111 100
+111 100
+drop table t1;
+create table t1 ( c char(8) not null ) engine=innodb;
+insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9');
+insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F');
+alter table t1 add b char(8) not null;
+alter table t1 add a char(8) not null;
+alter table t1 add primary key (a,b,c);
+update t1 set a=c, b=c;
+create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) engine=innodb;
+insert into t2 select * from t1;
+delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
+drop table t1,t2;
+SET AUTOCOMMIT=1;
+create table t1 (a integer auto_increment primary key) engine=innodb;
+insert into t1 (a) values (NULL),(NULL);
+truncate table t1;
+insert into t1 (a) values (NULL),(NULL);
+SELECT * from t1;
+a
+1
+2
+drop table t1;
+CREATE TABLE t1 (`id 1` INT NOT NULL, PRIMARY KEY (`id 1`)) ENGINE=INNODB;
+CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), FOREIGN KEY (`t1_id`) REFERENCES `t1`(`id 1`) ON DELETE CASCADE ) ENGINE=INNODB;
+drop table t2,t1;
+create table `t1` (`id` int( 11 ) not null ,primary key ( `id` )) engine = innodb;
+insert into `t1`values ( 1 ) ;
+create table `t2` (`id` int( 11 ) not null default '0',unique key `id` ( `id` ) ,constraint `t1_id_fk` foreign key ( `id` ) references `t1` (`id` )) engine = innodb;
+insert into `t2`values ( 1 ) ;
+create table `t3` (`id` int( 11 ) not null default '0',key `id` ( `id` ) ,constraint `t2_id_fk` foreign key ( `id` ) references `t2` (`id` )) engine = innodb;
+insert into `t3`values ( 1 ) ;
+delete t3,t2,t1 from t1,t2,t3 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
+ERROR 42S22: Unknown column 't1.id' in 'where clause'
+drop table t3,t2,t1;
+create table t1(
+id int primary key,
+pid int,
+index(pid),
+foreign key(pid) references t1(id) on delete cascade) engine=innodb;
+insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),
+(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
+delete from t1 where id=0;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `t1` (`id`) ON DELETE CASCADE)
+delete from t1 where id=15;
+delete from t1 where id=0;
+drop table t1;
+CREATE TABLE t1 (col1 int(1))ENGINE=InnoDB;
+CREATE TABLE t2 (col1 int(1),stamp TIMESTAMP,INDEX stamp_idx
+(stamp))ENGINE=InnoDB;
+insert into t1 values (1),(2),(3);
+insert into t2 values (1, 20020204130000),(2, 20020204130000),(4,20020204310000 ),(5,20020204230000);
+Warnings:
+Warning 1265 Data truncated for column 'stamp' at row 3
+SELECT col1 FROM t1 UNION SELECT col1 FROM t2 WHERE stamp <
+'20020204120000' GROUP BY col1;
+col1
+1
+2
+3
+4
+drop table t1,t2;
+CREATE TABLE t1 (
+`id` int(10) unsigned NOT NULL auto_increment,
+`id_object` int(10) unsigned default '0',
+`id_version` int(10) unsigned NOT NULL default '1',
+`label` varchar(100) NOT NULL default '',
+`description` text,
+PRIMARY KEY (`id`),
+KEY `id_object` (`id_object`),
+KEY `id_version` (`id_version`)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES("6", "3382", "9", "Test", NULL), ("7", "102", "5", "Le Pekin (Test)", NULL),("584", "1794", "4", "Test de resto", NULL),("837", "1822", "6", "Test 3", NULL),("1119", "3524", "1", "Societe Test", NULL),("1122", "3525", "1", "Fournisseur Test", NULL);
+CREATE TABLE t2 (
+`id` int(10) unsigned NOT NULL auto_increment,
+`id_version` int(10) unsigned NOT NULL default '1',
+PRIMARY KEY (`id`),
+KEY `id_version` (`id_version`)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES("3524", "1"),("3525", "1"),("1794", "4"),("102", "5"),("1822", "6"),("3382", "9");
+SELECT t2.id, t1.`label` FROM t2 INNER JOIN
+(SELECT t1.id_object as id_object FROM t1 WHERE t1.`label` LIKE '%test%') AS lbl
+ON (t2.id = lbl.id_object) INNER JOIN t1 ON (t2.id = t1.id_object);
+id label
+3382 Test
+102 Le Pekin (Test)
+1794 Test de resto
+1822 Test 3
+3524 Societe Test
+3525 Fournisseur Test
+drop table t1,t2;
+create table t1 (a int, b varchar(200), c text not null) checksum=1 engine=myisam;
+create table t2 (a int, b varchar(200), c text not null) checksum=0 engine=innodb;
+create table t3 (a int, b varchar(200), c text not null) checksum=1 engine=innodb;
+insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, "");
+insert t2 select * from t1;
+insert t3 select * from t1;
+checksum table t1, t2, t3, t4 quick;
+Table Checksum
+test.t1 3442722830
+test.t2 NULL
+test.t3 NULL
+test.t4 NULL
+Warnings:
+Error 1146 Table 'test.t4' doesn't exist
+checksum table t1, t2, t3, t4;
+Table Checksum
+test.t1 3442722830
+test.t2 3442722830
+test.t3 3442722830
+test.t4 NULL
+Warnings:
+Error 1146 Table 'test.t4' doesn't exist
+checksum table t1, t2, t3, t4 extended;
+Table Checksum
+test.t1 3442722830
+test.t2 3442722830
+test.t3 3442722830
+test.t4 NULL
+Warnings:
+Error 1146 Table 'test.t4' doesn't exist
+drop table t1,t2,t3;
+create table t1 (id int, name char(10) not null, name2 char(10) not null) engine=innodb;
+insert into t1 values(1,'first','fff'),(2,'second','sss'),(3,'third','ttt');
+select trim(name2) from t1 union all select trim(name) from t1 union all select trim(id) from t1;
+trim(name2)
+fff
+sss
+ttt
+first
+second
+third
+1
+2
+3
+drop table t1;
+create table t1 (a int) engine=innodb;
+create table t2 like t1;
+drop table t1,t2;
+create table t1 (id int(11) not null, id2 int(11) not null, unique (id,id2)) engine=innodb;
+create table t2 (id int(11) not null, constraint t1_id_fk foreign key ( id ) references t1 (id)) engine = innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `id2` int(11) NOT NULL,
+ UNIQUE KEY `id` (`id`,`id2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ KEY `t1_id_fk` (`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+create index id on t2 (id);
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ KEY `id` (`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+create index id2 on t2 (id);
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ KEY `id` (`id`),
+ KEY `id2` (`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop index id2 on t2;
+drop index id on t2;
+ERROR HY000: Cannot drop index 'id': needed in a foreign key constraint
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ KEY `id` (`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id,id2) references t1 (id,id2)) engine = innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `id2` int(11) NOT NULL,
+ KEY `t1_id_fk` (`id`,`id2`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`, `id2`) REFERENCES `t1` (`id`, `id2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+create unique index id on t2 (id,id2);
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `id2` int(11) NOT NULL,
+ UNIQUE KEY `id` (`id`,`id2`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`, `id2`) REFERENCES `t1` (`id`, `id2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null, id2 int(11) not null, unique (id,id2),constraint t1_id_fk foreign key (id2,id) references t1 (id,id2)) engine = innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `id2` int(11) NOT NULL,
+ UNIQUE KEY `id` (`id`,`id2`),
+ KEY `t1_id_fk` (`id2`,`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id2`, `id`) REFERENCES `t1` (`id`, `id2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null, id2 int(11) not null, unique (id,id2), constraint t1_id_fk foreign key (id) references t1 (id)) engine = innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `id2` int(11) NOT NULL,
+ UNIQUE KEY `id` (`id`,`id2`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null, id2 int(11) not null, unique (id,id2),constraint t1_id_fk foreign key (id2,id) references t1 (id,id2)) engine = innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `id2` int(11) NOT NULL,
+ UNIQUE KEY `id` (`id`,`id2`),
+ KEY `t1_id_fk` (`id2`,`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id2`, `id`) REFERENCES `t1` (`id`, `id2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null auto_increment, id2 int(11) not null, constraint t1_id_fk foreign key (id) references t1 (id), primary key (id), index (id,id2)) engine = innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `id2` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `id` (`id`,`id2`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null auto_increment, id2 int(11) not null, constraint t1_id_fk foreign key (id) references t1 (id)) engine= innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `id2` int(11) NOT NULL,
+ KEY `t1_id_fk` (`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+alter table t2 add index id_test (id), add index id_test2 (id,id2);
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `id2` int(11) NOT NULL,
+ KEY `id_test` (`id`),
+ KEY `id_test2` (`id`,`id2`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb;
+ERROR 42000: Incorrect foreign key definition for 't1_id_fk': Key reference and table reference don't match
+create table t2 (a int auto_increment primary key, b int, index(b), foreign key (b) references t1(id), unique(b)) engine=innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) NOT NULL AUTO_INCREMENT,
+ `b` int(11) DEFAULT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `b_2` (`b`),
+ KEY `b` (`b`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (a int auto_increment primary key, b int, foreign key (b) references t1(id), foreign key (b) references t1(id), unique(b)) engine=innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) NOT NULL AUTO_INCREMENT,
+ `b` int(11) DEFAULT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `b` (`b`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`id`),
+ CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`b`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2, t1;
+create table t1 (c char(10), index (c,c)) engine=innodb;
+ERROR 42S21: Duplicate column name 'c'
+create table t1 (c1 char(10), c2 char(10), index (c1,c2,c1)) engine=innodb;
+ERROR 42S21: Duplicate column name 'c1'
+create table t1 (c1 char(10), c2 char(10), index (c1,c1,c2)) engine=innodb;
+ERROR 42S21: Duplicate column name 'c1'
+create table t1 (c1 char(10), c2 char(10), index (c2,c1,c1)) engine=innodb;
+ERROR 42S21: Duplicate column name 'c1'
+create table t1 (c1 char(10), c2 char(10)) engine=innodb;
+alter table t1 add key (c1,c1);
+ERROR 42S21: Duplicate column name 'c1'
+alter table t1 add key (c2,c1,c1);
+ERROR 42S21: Duplicate column name 'c1'
+alter table t1 add key (c1,c2,c1);
+ERROR 42S21: Duplicate column name 'c1'
+alter table t1 add key (c1,c1,c2);
+ERROR 42S21: Duplicate column name 'c1'
+drop table t1;
+create table t1(a int(1) , b int(1)) engine=innodb;
+insert into t1 values ('1111', '3333');
+select distinct concat(a, b) from t1;
+concat(a, b)
+11113333
+drop table t1;
+CREATE TABLE t1 ( a char(10) ) ENGINE=InnoDB;
+SELECT a FROM t1 WHERE MATCH (a) AGAINST ('test' IN BOOLEAN MODE);
+ERROR HY000: The used table type doesn't support FULLTEXT indexes
+DROP TABLE t1;
+CREATE TABLE t1 (a_id tinyint(4) NOT NULL default '0', PRIMARY KEY (a_id)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(2),(3);
+CREATE TABLE t2 (b_id tinyint(4) NOT NULL default '0',b_a tinyint(4) NOT NULL default '0', PRIMARY KEY (b_id), KEY (b_a),
+CONSTRAINT fk_b_a FOREIGN KEY (b_a) REFERENCES t1 (a_id) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (1,1),(2,1),(3,1),(4,2),(5,2);
+SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN (t2) on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz;
+a_id b_list
+1 1,2,3
+2 4,5
+3 NULL
+DROP TABLE t2;
+DROP TABLE t1;
+create temporary table t1 (a int) engine=innodb;
+insert into t1 values (4711);
+truncate t1;
+insert into t1 values (42);
+select * from t1;
+a
+42
+drop table t1;
+create table t1 (a int) engine=innodb;
+insert into t1 values (4711);
+truncate t1;
+insert into t1 values (42);
+select * from t1;
+a
+42
+drop table t1;
+create table t1 (a int not null, b int not null, c blob not null, d int not null, e int, primary key (a,b,c(255),d)) engine=innodb;
+insert into t1 values (2,2,"b",2,2),(1,1,"a",1,1),(3,3,"ab",3,3);
+select * from t1 order by a,b,c,d;
+a b c d e
+1 1 a 1 1
+2 2 b 2 2
+3 3 ab 3 3
+explain select * from t1 order by a,b,c,d;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using filesort
+drop table t1;
+create table t1 (a char(1), b char(1), key(a, b)) engine=innodb;
+insert into t1 values ('8', '6'), ('4', '7');
+select min(a) from t1;
+min(a)
+4
+select min(b) from t1 where a='8';
+min(b)
+6
+drop table t1;
+create table t1 (x bigint unsigned not null primary key) engine=innodb;
+insert into t1(x) values (0xfffffffffffffff0),(0xfffffffffffffff1);
+select * from t1;
+x
+18446744073709551600
+18446744073709551601
+select count(*) from t1 where x>0;
+count(*)
+2
+select count(*) from t1 where x=0;
+count(*)
+0
+select count(*) from t1 where x<0;
+count(*)
+0
+select count(*) from t1 where x < -16;
+count(*)
+0
+select count(*) from t1 where x = -16;
+count(*)
+0
+explain select count(*) from t1 where x > -16;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 2 Using where; Using index
+select count(*) from t1 where x > -16;
+count(*)
+2
+select * from t1 where x > -16;
+x
+18446744073709551600
+18446744073709551601
+select count(*) from t1 where x = 18446744073709551601;
+count(*)
+1
+drop table t1;
+SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_buffer_pool_pages_total';
+variable_value
+8191
+SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size';
+variable_value
+16384
+SELECT variable_value - @innodb_rows_deleted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_deleted';
+variable_value - @innodb_rows_deleted_orig
+71
+SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted';
+variable_value - @innodb_rows_inserted_orig
+1084
+SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated';
+variable_value - @innodb_rows_updated_orig
+885
+SELECT variable_value - @innodb_row_lock_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_waits';
+variable_value - @innodb_row_lock_waits_orig
+0
+SELECT variable_value - @innodb_row_lock_current_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_current_waits';
+variable_value - @innodb_row_lock_current_waits_orig
+0
+SELECT variable_value - @innodb_row_lock_time_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time';
+variable_value - @innodb_row_lock_time_orig
+0
+SELECT variable_value - @innodb_row_lock_time_max_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_max';
+variable_value - @innodb_row_lock_time_max_orig
+0
+SELECT variable_value - @innodb_row_lock_time_avg_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg';
+variable_value - @innodb_row_lock_time_avg_orig
+0
+SET @innodb_sync_spin_loops_orig = @@innodb_sync_spin_loops;
+show variables like "innodb_sync_spin_loops";
+Variable_name Value
+innodb_sync_spin_loops 30
+set global innodb_sync_spin_loops=1000;
+show variables like "innodb_sync_spin_loops";
+Variable_name Value
+innodb_sync_spin_loops 1000
+set global innodb_sync_spin_loops=0;
+show variables like "innodb_sync_spin_loops";
+Variable_name Value
+innodb_sync_spin_loops 0
+set global innodb_sync_spin_loops=20;
+show variables like "innodb_sync_spin_loops";
+Variable_name Value
+innodb_sync_spin_loops 20
+set global innodb_sync_spin_loops=@innodb_sync_spin_loops_orig;
+SET @old_innodb_thread_concurrency= @@global.innodb_thread_concurrency;
+show variables like "innodb_thread_concurrency";
+Variable_name Value
+innodb_thread_concurrency 0
+set global innodb_thread_concurrency=1001;
+Warnings:
+Warning 1292 Truncated incorrect thread_concurrency value: '1001'
+show variables like "innodb_thread_concurrency";
+Variable_name Value
+innodb_thread_concurrency 1000
+set global innodb_thread_concurrency=0;
+show variables like "innodb_thread_concurrency";
+Variable_name Value
+innodb_thread_concurrency 0
+set global innodb_thread_concurrency=16;
+show variables like "innodb_thread_concurrency";
+Variable_name Value
+innodb_thread_concurrency 16
+SET @@global.innodb_thread_concurrency= @old_innodb_thread_concurrency;
+show variables like "innodb_concurrency_tickets";
+Variable_name Value
+innodb_concurrency_tickets 500
+set global innodb_concurrency_tickets=1000;
+show variables like "innodb_concurrency_tickets";
+Variable_name Value
+innodb_concurrency_tickets 1000
+set global innodb_concurrency_tickets=0;
+Warnings:
+Warning 1292 Truncated incorrect concurrency_tickets value: '0'
+show variables like "innodb_concurrency_tickets";
+Variable_name Value
+innodb_concurrency_tickets 1
+set global innodb_concurrency_tickets=500;
+show variables like "innodb_concurrency_tickets";
+Variable_name Value
+innodb_concurrency_tickets 500
+show variables like "innodb_thread_sleep_delay";
+Variable_name Value
+innodb_thread_sleep_delay 10000
+set global innodb_thread_sleep_delay=100000;
+show variables like "innodb_thread_sleep_delay";
+Variable_name Value
+innodb_thread_sleep_delay 100000
+set global innodb_thread_sleep_delay=0;
+show variables like "innodb_thread_sleep_delay";
+Variable_name Value
+innodb_thread_sleep_delay 0
+set global innodb_thread_sleep_delay=10000;
+show variables like "innodb_thread_sleep_delay";
+Variable_name Value
+innodb_thread_sleep_delay 10000
+set storage_engine=INNODB;
+drop table if exists t1,t2,t3;
+--- Testing varchar ---
+--- Testing varchar ---
+create table t1 (v varchar(10), c char(10), t text);
+insert into t1 values('+ ', '+ ', '+ ');
+set @a=repeat(' ',20);
+insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
+Warnings:
+Note 1265 Data truncated for column 'v' at row 1
+select concat('*',v,'*',c,'*',t,'*') from t1;
+concat('*',v,'*',c,'*',t,'*')
+*+ *+*+ *
+*+ *+*+ *
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+create table t2 like t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+create table t3 select * from t1;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+alter table t1 modify c varchar(10);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` varchar(10) DEFAULT NULL,
+ `t` text
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+alter table t1 modify v char(10);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` char(10) DEFAULT NULL,
+ `c` varchar(10) DEFAULT NULL,
+ `t` text
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+alter table t1 modify t varchar(10);
+Warnings:
+Note 1265 Data truncated for column 't' at row 2
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` char(10) DEFAULT NULL,
+ `c` varchar(10) DEFAULT NULL,
+ `t` varchar(10) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+select concat('*',v,'*',c,'*',t,'*') from t1;
+concat('*',v,'*',c,'*',t,'*')
+*+*+*+ *
+*+*+*+ *
+drop table t1,t2,t3;
+create table t1 (v varchar(10), c char(10), t text, key(v), key(c), key(t(10)));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `v` (`v`),
+ KEY `c` (`c`),
+ KEY `t` (`t`(10))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+select count(*) from t1;
+count(*)
+270
+insert into t1 values(concat('a',char(1)),concat('a',char(1)),concat('a',char(1)));
+select count(*) from t1 where v='a';
+count(*)
+10
+select count(*) from t1 where c='a';
+count(*)
+10
+select count(*) from t1 where t='a';
+count(*)
+10
+select count(*) from t1 where v='a ';
+count(*)
+10
+select count(*) from t1 where c='a ';
+count(*)
+10
+select count(*) from t1 where t='a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+count(*)
+10
+select count(*) from t1 where v like 'a%';
+count(*)
+11
+select count(*) from t1 where c like 'a%';
+count(*)
+11
+select count(*) from t1 where t like 'a%';
+count(*)
+11
+select count(*) from t1 where v like 'a %';
+count(*)
+9
+explain select count(*) from t1 where v='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
+explain select count(*) from t1 where c='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref c c 11 const # Using where; Using index
+explain select count(*) from t1 where t='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref t t 13 const # Using where
+explain select count(*) from t1 where v like 'a%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range v v 13 NULL # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
+alter table t1 add unique(v);
+ERROR 23000: Duplicate entry '{ ' for key 'v_2'
+alter table t1 add key(v);
+select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a';
+qq
+*a*a*a*
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+explain select * from t1 where v='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v,v_2 # 13 const # Using where
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(c) from t1 group by v limit 10;
+v count(c)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(c) from t1 group by v limit 10;
+v count(c)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select c,count(*) from t1 group by c limit 10;
+c count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select c,count(t) from t1 group by c limit 10;
+c count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result c,count(t) from t1 group by c limit 10;
+c count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select t,count(*) from t1 group by t limit 10;
+t count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select t,count(t) from t1 group by t limit 10;
+t count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result t,count(t) from t1 group by t limit 10;
+t count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+alter table t1 modify v varchar(300), drop key v, drop key v_2, add key v (v);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(300) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `c` (`c`),
+ KEY `t` (`t`(10)),
+ KEY `v` (`v`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+select count(*) from t1 where v='a';
+count(*)
+10
+select count(*) from t1 where v='a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+count(*)
+10
+select count(*) from t1 where v like 'a%';
+count(*)
+11
+select count(*) from t1 where v like 'a %';
+count(*)
+9
+explain select count(*) from t1 where v='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
+explain select count(*) from t1 where v like 'a%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range v v 303 NULL # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
+explain select * from t1 where v='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+alter table t1 drop key v, add key v (v(30));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(300) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `c` (`c`),
+ KEY `t` (`t`(10)),
+ KEY `v` (`v`(30))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+select count(*) from t1 where v='a';
+count(*)
+10
+select count(*) from t1 where v='a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+count(*)
+10
+select count(*) from t1 where v like 'a%';
+count(*)
+11
+select count(*) from t1 where v like 'a %';
+count(*)
+9
+explain select count(*) from t1 where v='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+explain select count(*) from t1 where v like 'a%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range v v 33 NULL # Using where
+explain select count(*) from t1 where v between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+explain select * from t1 where v='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+alter table t1 modify v varchar(600), drop key v, add key v (v);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(600) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `c` (`c`),
+ KEY `t` (`t`(10)),
+ KEY `v` (`v`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+drop table t1;
+create table t1 (a char(10), unique (a));
+insert into t1 values ('a ');
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a' for key 'a'
+alter table t1 modify a varchar(10);
+insert into t1 values ('a '),('a '),('a '),('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+update t1 set a='a ' where a like 'a%';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+update t1 set a='abc ' where a like 'a ';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+update t1 set a='a ' where a like 'a %';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+update t1 set a='a ' where a like 'a ';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+drop table t1;
+create table t1 (v varchar(10), c char(10), t text, key(v(5)), key(c(5)), key(t(5)));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `v` (`v`(5)),
+ KEY `c` (`c`(5)),
+ KEY `t` (`t`(5))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (v char(10) character set utf8);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` char(10) CHARACTER SET utf8 DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (v varchar(10), c char(10)) row_format=fixed;
+Warnings:
+Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT.
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED
+insert into t1 values('a','a'),('a ','a ');
+select concat('*',v,'*',c,'*') from t1;
+concat('*',v,'*',c,'*')
+*a*a*
+*a *a*
+drop table t1;
+create table t1 (v varchar(65530), key(v(10)));
+insert into t1 values(repeat('a',65530));
+select length(v) from t1 where v=repeat('a',65530);
+length(v)
+65530
+drop table t1;
+create table t1(a int, b varchar(12), key ba(b, a));
+insert into t1 values (1, 'A'), (20, NULL);
+explain select * from t1 where a=20 and b is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref ba ba 20 const,const 1 Using where; Using index
+select * from t1 where a=20 and b is null;
+a b
+20 NULL
+drop table t1;
+create table t1 (v varchar(65530), key(v));
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+drop table t1;
+create table t1 (v varchar(65536));
+Warnings:
+Note 1246 Converting column 'v' from VARCHAR to TEXT
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` mediumtext
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (v varchar(65530) character set utf8);
+Warnings:
+Note 1246 Converting column 'v' from VARCHAR to TEXT
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` mediumtext CHARACTER SET utf8
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+set storage_engine=MyISAM;
+create table t1 (v varchar(16384)) engine=innodb;
+drop table t1;
+create table t1 (a char(1), b char(1), key(a, b)) engine=innodb;
+insert into t1 values ('8', '6'), ('4', '7');
+select min(a) from t1;
+min(a)
+4
+select min(b) from t1 where a='8';
+min(b)
+6
+drop table t1;
+CREATE TABLE t1 ( `a` int(11) NOT NULL auto_increment, `b` int(11) default NULL,PRIMARY KEY (`a`),UNIQUE KEY `b` (`b`)) ENGINE=innodb;
+insert into t1 (b) values (1);
+replace into t1 (b) values (2), (1), (3);
+select * from t1;
+a b
+3 1
+2 2
+4 3
+truncate table t1;
+insert into t1 (b) values (1);
+replace into t1 (b) values (2);
+replace into t1 (b) values (1);
+replace into t1 (b) values (3);
+select * from t1;
+a b
+3 1
+2 2
+4 3
+drop table t1;
+create table t1 (rowid int not null auto_increment, val int not null,primary
+key (rowid), unique(val)) engine=innodb;
+replace into t1 (val) values ('1'),('2');
+replace into t1 (val) values ('1'),('2');
+insert into t1 (val) values ('1'),('2');
+ERROR 23000: Duplicate entry '1' for key 'val'
+select * from t1;
+rowid val
+3 1
+4 2
+drop table t1;
+create table t1 (a int not null auto_increment primary key, val int) engine=InnoDB;
+insert into t1 (val) values (1);
+update t1 set a=2 where a=1;
+insert into t1 (val) values (1);
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+select * from t1;
+a val
+2 1
+drop table t1;
+CREATE TABLE t1 (GRADE DECIMAL(4) NOT NULL, PRIMARY KEY (GRADE)) ENGINE=INNODB;
+INSERT INTO t1 (GRADE) VALUES (151),(252),(343);
+SELECT GRADE FROM t1 WHERE GRADE > 160 AND GRADE < 300;
+GRADE
+252
+SELECT GRADE FROM t1 WHERE GRADE= 151;
+GRADE
+151
+DROP TABLE t1;
+create table t1 (f1 varchar(10), f2 varchar(10), primary key (f1,f2)) engine=innodb;
+create table t2 (f3 varchar(10), f4 varchar(10), key (f4)) engine=innodb;
+insert into t2 values ('aa','cc');
+insert into t1 values ('aa','bb'),('aa','cc');
+delete t1 from t1,t2 where f1=f3 and f4='cc';
+select * from t1;
+f1 f2
+drop table t1,t2;
+CREATE TABLE t1 (
+id INTEGER NOT NULL AUTO_INCREMENT, PRIMARY KEY (id)
+) ENGINE=InnoDB;
+CREATE TABLE t2 (
+id INTEGER NOT NULL,
+FOREIGN KEY (id) REFERENCES t1 (id)
+) ENGINE=InnoDB;
+INSERT INTO t1 (id) VALUES (NULL);
+SELECT * FROM t1;
+id
+1
+TRUNCATE t1;
+INSERT INTO t1 (id) VALUES (NULL);
+SELECT * FROM t1;
+id
+1
+DELETE FROM t1;
+TRUNCATE t1;
+INSERT INTO t1 (id) VALUES (NULL);
+SELECT * FROM t1;
+id
+1
+DROP TABLE t2, t1;
+CREATE TABLE t1
+(
+id INT PRIMARY KEY
+) ENGINE=InnoDB;
+CREATE TEMPORARY TABLE t2
+(
+id INT NOT NULL PRIMARY KEY,
+b INT,
+FOREIGN KEY (b) REFERENCES test.t1(id)
+) ENGINE=InnoDB;
+Got one of the listed errors
+DROP TABLE t1;
+create table t1 (col1 varchar(2000), index (col1(767)))
+character set = latin1 engine = innodb;
+create table t2 (col1 char(255), index (col1))
+character set = latin1 engine = innodb;
+create table t3 (col1 binary(255), index (col1))
+character set = latin1 engine = innodb;
+create table t4 (col1 varchar(767), index (col1))
+character set = latin1 engine = innodb;
+create table t5 (col1 varchar(767) primary key)
+character set = latin1 engine = innodb;
+create table t6 (col1 varbinary(767) primary key)
+character set = latin1 engine = innodb;
+create table t7 (col1 text, index(col1(767)))
+character set = latin1 engine = innodb;
+create table t8 (col1 blob, index(col1(767)))
+character set = latin1 engine = innodb;
+create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
+character set = latin1 engine = innodb;
+show create table t9;
+Table Create Table
+t9 CREATE TABLE `t9` (
+ `col1` varchar(512) DEFAULT NULL,
+ `col2` varchar(512) DEFAULT NULL,
+ KEY `col1` (`col1`,`col2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
+create table t1 (col1 varchar(768), index(col1))
+character set = latin1 engine = innodb;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+create table t2 (col1 varbinary(768), index(col1))
+character set = latin1 engine = innodb;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+create table t3 (col1 text, index(col1(768)))
+character set = latin1 engine = innodb;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+create table t4 (col1 blob, index(col1(768)))
+character set = latin1 engine = innodb;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `col1` varchar(768) DEFAULT NULL,
+ KEY `col1` (`col1`(767))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1, t2, t3, t4;
+create table t1 (col1 varchar(768) primary key)
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+create table t2 (col1 varbinary(768) primary key)
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+create table t3 (col1 text, primary key(col1(768)))
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+create table t4 (col1 blob, primary key(col1(768)))
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+CREATE TABLE t1
+(
+id INT PRIMARY KEY
+) ENGINE=InnoDB;
+CREATE TABLE t2
+(
+v INT,
+CONSTRAINT c1 FOREIGN KEY (v) REFERENCES t1(id)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(2);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(1);
+DELETE FROM t1 WHERE id = 1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+DROP TABLE t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+SET FOREIGN_KEY_CHECKS=0;
+DROP TABLE t1;
+SET FOREIGN_KEY_CHECKS=1;
+INSERT INTO t2 VALUES(3);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+DROP TABLE t2;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
+set autocommit=0;
+checksum table t1;
+Table Checksum
+test.t1 1531596814
+insert into t1 values(3);
+checksum table t1;
+Table Checksum
+test.t1 1531596814
+commit;
+checksum table t1;
+Table Checksum
+test.t1 2050879373
+commit;
+drop table t1;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
+set autocommit=1;
+checksum table t1;
+Table Checksum
+test.t1 1531596814
+set autocommit=1;
+insert into t1 values(3);
+checksum table t1;
+Table Checksum
+test.t1 2050879373
+drop table t1;
+set foreign_key_checks=0;
+create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
+create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
+ERROR HY000: Can't create table 'test.t1' (errno: 150)
+set foreign_key_checks=1;
+drop table t2;
+set foreign_key_checks=0;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
+ERROR HY000: Can't create table 'test.t2' (errno: 150)
+set foreign_key_checks=1;
+drop table t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
+create table t1(a varchar(10) primary key) engine = innodb;
+alter table t1 modify column a int;
+Got one of the listed errors
+set foreign_key_checks=1;
+drop table t2,t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+alter table t1 convert to character set utf8;
+set foreign_key_checks=1;
+drop table t2,t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
+rename table t3 to t1;
+ERROR HY000: Error on rename of './test/t3' to './test/t1' (errno: 150)
+set foreign_key_checks=1;
+drop table t2,t3;
+create table t1(a int primary key) row_format=redundant engine=innodb;
+create table t2(a int primary key,constraint foreign key(a)references t1(a)) row_format=compact engine=innodb;
+create table t3(a int primary key) row_format=compact engine=innodb;
+create table t4(a int primary key,constraint foreign key(a)references t3(a)) row_format=redundant engine=innodb;
+insert into t1 values(1);
+insert into t3 values(1);
+insert into t2 values(2);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+insert into t4 values(2);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+insert into t2 values(1);
+insert into t4 values(1);
+update t1 set a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+update t2 set a=2;
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+update t3 set a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+update t4 set a=2;
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+truncate t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+truncate t3;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+truncate t2;
+truncate t4;
+truncate t1;
+truncate t3;
+drop table t4,t3,t2,t1;
+create table t1 (a varchar(255) character set utf8,
+b varchar(255) character set utf8,
+c varchar(255) character set utf8,
+d varchar(255) character set utf8,
+key (a,b,c,d)) engine=innodb;
+drop table t1;
+create table t1 (a varchar(255) character set utf8,
+b varchar(255) character set utf8,
+c varchar(255) character set utf8,
+d varchar(255) character set utf8,
+e varchar(255) character set utf8,
+key (a,b,c,d,e)) engine=innodb;
+ERROR 42000: Specified key was too long; max key length is 3072 bytes
+create table t1 (s1 varbinary(2),primary key (s1)) engine=innodb;
+create table t2 (s1 binary(2),primary key (s1)) engine=innodb;
+create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb;
+create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb;
+insert into t1 values (0x41),(0x4120),(0x4100);
+insert into t2 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A' for key 'PRIMARY'
+insert into t2 values (0x41),(0x4120);
+insert into t3 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A ' for key 'PRIMARY'
+insert into t3 values (0x41),(0x4100);
+insert into t4 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A' for key 'PRIMARY'
+insert into t4 values (0x41),(0x4100);
+select hex(s1) from t1;
+hex(s1)
+41
+4100
+4120
+select hex(s1) from t2;
+hex(s1)
+4100
+4120
+select hex(s1) from t3;
+hex(s1)
+4100
+41
+select hex(s1) from t4;
+hex(s1)
+4100
+41
+drop table t1,t2,t3,t4;
+create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=innodb;
+create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42);
+insert into t2 values(0x42);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+insert into t2 values(0x41);
+select hex(s1) from t2;
+hex(s1)
+4100
+update t1 set s1=0x123456 where a=2;
+select hex(s1) from t2;
+hex(s1)
+4100
+update t1 set s1=0x12 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x12345678 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x123457 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x1220 where a=1;
+select hex(s1) from t2;
+hex(s1)
+1220
+update t1 set s1=0x1200 where a=1;
+select hex(s1) from t2;
+hex(s1)
+1200
+update t1 set s1=0x4200 where a=1;
+select hex(s1) from t2;
+hex(s1)
+4200
+delete from t1 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+delete from t1 where a=2;
+update t2 set s1=0x4120;
+delete from t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+delete from t1 where a!=3;
+select a,hex(s1) from t1;
+a hex(s1)
+3 4120
+select hex(s1) from t2;
+hex(s1)
+4120
+drop table t2,t1;
+create table t1 (a int primary key,s1 varchar(2) binary not null unique) engine=innodb;
+create table t2 (s1 char(2) binary not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+insert into t1 values(1,0x4100),(2,0x41);
+insert into t2 values(0x41);
+select hex(s1) from t2;
+hex(s1)
+41
+update t1 set s1=0x1234 where a=1;
+select hex(s1) from t2;
+hex(s1)
+41
+update t1 set s1=0x12 where a=2;
+select hex(s1) from t2;
+hex(s1)
+12
+delete from t1 where a=1;
+delete from t1 where a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+select a,hex(s1) from t1;
+a hex(s1)
+2 12
+select hex(s1) from t2;
+hex(s1)
+12
+drop table t2,t1;
+CREATE TABLE t1(a INT, PRIMARY KEY(a)) ENGINE=InnoDB;
+CREATE TABLE t2(a INT) ENGINE=InnoDB;
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_1;
+ALTER TABLE t2 ADD CONSTRAINT t2_ibfk_0 FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_0;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ KEY `t2_ibfk_0` (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t2,t1;
+create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+insert into t1(a) values (1),(2),(3);
+commit;
+set autocommit = 0;
+update t1 set b = 5 where a = 2;
+create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
+set autocommit = 0;
+insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100),
+(11),(21),(31),(41),(51),(61),(71),(81),(91),(101),
+(12),(22),(32),(42),(52),(62),(72),(82),(92),(102),
+(13),(23),(33),(43),(53),(63),(73),(83),(93),(103),
+(14),(24),(34),(44),(54),(64),(74),(84),(94),(104);
+commit;
+commit;
+drop trigger t1t;
+drop table t1;
+create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t2(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t3(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t4(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t5(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+insert into t1(a) values (1),(2),(3);
+insert into t2(a) values (1),(2),(3);
+insert into t3(a) values (1),(2),(3);
+insert into t4(a) values (1),(2),(3);
+insert into t3(a) values (5),(7),(8);
+insert into t4(a) values (5),(7),(8);
+insert into t5(a) values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
+create trigger t1t before insert on t1 for each row begin
+INSERT INTO t2 SET a = NEW.a;
+end |
+create trigger t2t before insert on t2 for each row begin
+DELETE FROM t3 WHERE a = NEW.a;
+end |
+create trigger t3t before delete on t3 for each row begin
+UPDATE t4 SET b = b + 1 WHERE a = OLD.a;
+end |
+create trigger t4t before update on t4 for each row begin
+UPDATE t5 SET b = b + 1 where a = NEW.a;
+end |
+commit;
+set autocommit = 0;
+update t1 set b = b + 5 where a = 1;
+update t2 set b = b + 5 where a = 1;
+update t3 set b = b + 5 where a = 1;
+update t4 set b = b + 5 where a = 1;
+insert into t5(a) values(20);
+set autocommit = 0;
+insert into t1(a) values(7);
+insert into t2(a) values(8);
+delete from t2 where a = 3;
+update t4 set b = b + 1 where a = 3;
+commit;
+drop trigger t1t;
+drop trigger t2t;
+drop trigger t3t;
+drop trigger t4t;
+drop table t1, t2, t3, t4, t5;
+CREATE TABLE t1 (
+field1 varchar(8) NOT NULL DEFAULT '',
+field2 varchar(8) NOT NULL DEFAULT '',
+PRIMARY KEY (field1, field2)
+) ENGINE=InnoDB;
+CREATE TABLE t2 (
+field1 varchar(8) NOT NULL DEFAULT '' PRIMARY KEY,
+FOREIGN KEY (field1) REFERENCES t1 (field1)
+ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('old', 'somevalu');
+INSERT INTO t1 VALUES ('other', 'anyvalue');
+INSERT INTO t2 VALUES ('old');
+INSERT INTO t2 VALUES ('other');
+UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu';
+ERROR 23000: Upholding foreign key constraints for table 't1', entry 'other-somevalu', key 1 would lead to a duplicate entry
+DROP TABLE t2;
+DROP TABLE t1;
+create table t1 (
+c1 bigint not null,
+c2 bigint not null,
+primary key (c1),
+unique key (c2)
+) engine=innodb;
+create table t2 (
+c1 bigint not null,
+primary key (c1)
+) engine=innodb;
+alter table t1 add constraint c2_fk foreign key (c2)
+references t2(c1) on delete cascade;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` bigint(20) NOT NULL,
+ `c2` bigint(20) NOT NULL,
+ PRIMARY KEY (`c1`),
+ UNIQUE KEY `c2` (`c2`),
+ CONSTRAINT `c2_fk` FOREIGN KEY (`c2`) REFERENCES `t2` (`c1`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+alter table t1 drop foreign key c2_fk;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` bigint(20) NOT NULL,
+ `c2` bigint(20) NOT NULL,
+ PRIMARY KEY (`c1`),
+ UNIQUE KEY `c2` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1, t2;
+create table t1(a date) engine=innodb;
+create table t2(a date, key(a)) engine=innodb;
+insert into t1 values('2005-10-01');
+insert into t2 values('2005-10-01');
+select * from t1, t2
+where t2.a between t1.a - interval 2 day and t1.a + interval 2 day;
+a a
+2005-10-01 2005-10-01
+drop table t1, t2;
+create table t1 (id int not null, f_id int not null, f int not null,
+primary key(f_id, id)) engine=innodb;
+create table t2 (id int not null,s_id int not null,s varchar(200),
+primary key(id)) engine=innodb;
+INSERT INTO t1 VALUES (8, 1, 3);
+INSERT INTO t1 VALUES (1, 2, 1);
+INSERT INTO t2 VALUES (1, 0, '');
+INSERT INTO t2 VALUES (8, 1, '');
+commit;
+DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
+WHERE mm.id IS NULL;
+select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
+where mm.id is null lock in share mode;
+id f_id f
+drop table t1,t2;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2),(7,3);
+commit;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+update t1 set b = 5 where b = 1;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+select * from t1 where a = 7 and b = 3 for update;
+a b
+7 3
+commit;
+commit;
+drop table t1;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2);
+commit;
+set autocommit = 0;
+select * from t1 lock in share mode;
+a b
+1 1
+2 2
+3 1
+4 2
+5 1
+6 2
+update t1 set b = 5 where b = 1;
+set autocommit = 0;
+select * from t1 where a = 2 and b = 2 for update;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+commit;
+commit;
+drop table t1;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values (1,2),(5,3),(4,2);
+create table t2(d int not null, e int, primary key(d)) engine=innodb;
+insert into t2 values (8,6),(12,1),(3,1);
+commit;
+set autocommit = 0;
+select * from t2 for update;
+d e
+3 1
+8 6
+12 1
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+insert into t1 select * from t2;
+update t1 set b = (select e from t2 where a = d);
+create table t3(d int not null, e int, primary key(d)) engine=innodb
+select * from t2;
+commit;
+commit;
+drop table t1, t2, t3;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values (1,2),(5,3),(4,2);
+create table t2(a int not null, b int, primary key(a)) engine=innodb;
+insert into t2 values (8,6),(12,1),(3,1);
+create table t3(d int not null, b int, primary key(d)) engine=innodb;
+insert into t3 values (8,6),(12,1),(3,1);
+create table t5(a int not null, b int, primary key(a)) engine=innodb;
+insert into t5 values (1,2),(5,3),(4,2);
+create table t6(d int not null, e int, primary key(d)) engine=innodb;
+insert into t6 values (8,6),(12,1),(3,1);
+create table t8(a int not null, b int, primary key(a)) engine=innodb;
+insert into t8 values (1,2),(5,3),(4,2);
+create table t9(d int not null, e int, primary key(d)) engine=innodb;
+insert into t9 values (8,6),(12,1),(3,1);
+commit;
+set autocommit = 0;
+select * from t2 for update;
+a b
+3 1
+8 6
+12 1
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+insert into t1 select * from t2;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+update t3 set b = (select b from t2 where a = d);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+create table t4(a int not null, b int, primary key(a)) engine=innodb select * from t2;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+insert into t5 (select * from t2 lock in share mode);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+update t6 set e = (select b from t2 where a = d lock in share mode);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+create table t7(a int not null, b int, primary key(a)) engine=innodb select * from t2 lock in share mode;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+insert into t8 (select * from t2 for update);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+update t9 set e = (select b from t2 where a = d for update);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+create table t10(a int not null, b int, primary key(a)) engine=innodb select * from t2 for update;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+commit;
+drop table t1, t2, t3, t5, t6, t8, t9;
+CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
+ERROR 42000: Incorrect column name 'DB_ROW_ID'
+CREATE TABLE t1 (
+a BIGINT(20) NOT NULL,
+PRIMARY KEY (a)
+) ENGINE=INNODB DEFAULT CHARSET=UTF8;
+CREATE TABLE t2 (
+a BIGINT(20) NOT NULL,
+b VARCHAR(128) NOT NULL,
+c TEXT NOT NULL,
+PRIMARY KEY (a,b),
+KEY idx_t2_b_c (b,c(200)),
+CONSTRAINT t_fk FOREIGN KEY (a) REFERENCES t1 (a)
+ON DELETE CASCADE
+) ENGINE=INNODB DEFAULT CHARSET=UTF8;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1, 'bar', 'vbar');
+INSERT INTO t2 VALUES (1, 'BAR2', 'VBAR');
+INSERT INTO t2 VALUES (1, 'bar_bar', 'bibi');
+INSERT INTO t2 VALUES (1, 'customer_over', '1');
+SELECT * FROM t2 WHERE b = 'customer_over';
+a b c
+1 customer_over 1
+SELECT * FROM t2 WHERE BINARY b = 'customer_over';
+a b c
+1 customer_over 1
+SELECT DISTINCT p0.a FROM t2 p0 WHERE p0.b = 'customer_over';
+a
+1
+/* Bang: Empty result set, above was expected: */
+SELECT DISTINCT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over';
+a
+1
+SELECT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over';
+a
+1
+drop table t2, t1;
+CREATE TABLE t1 ( a int ) ENGINE=innodb;
+BEGIN;
+INSERT INTO t1 VALUES (1);
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize status OK
+DROP TABLE t1;
+CREATE TABLE t1 (id int PRIMARY KEY, f int NOT NULL, INDEX(f)) ENGINE=InnoDB;
+CREATE TABLE t2 (id int PRIMARY KEY, f INT NOT NULL,
+CONSTRAINT t2_t1 FOREIGN KEY (id) REFERENCES t1 (id)
+ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB;
+ALTER TABLE t2 ADD FOREIGN KEY (f) REFERENCES t1 (f) ON
+DELETE CASCADE ON UPDATE CASCADE;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `f` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `f` (`f`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f`) REFERENCES `t1` (`f`) ON DELETE CASCADE ON UPDATE CASCADE,
+ CONSTRAINT `t2_t1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t2, t1;
+CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL;
+ALTER TABLE t2 MODIFY a INT NOT NULL;
+ERROR HY000: Error on rename of '#sql-temporary' to './test/t2' (errno: 150)
+DELETE FROM t1;
+DROP TABLE t2,t1;
+CREATE TABLE t1 (id int PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB
+AUTO_INCREMENT=42;
+INSERT INTO t1 VALUES (0),(347),(0);
+SELECT * FROM t1;
+id
+42
+347
+348
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1
+CREATE TABLE t2 (id int PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(42),(347),(348);
+ALTER TABLE t1 ADD CONSTRAINT t1_t2 FOREIGN KEY (id) REFERENCES t2(id);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`),
+ CONSTRAINT `t1_t2` FOREIGN KEY (`id`) REFERENCES `t2` (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1
+DROP TABLE t1,t2;
+set innodb_strict_mode=on;
+CREATE TABLE t1 (
+c01 CHAR(255), c02 CHAR(255), c03 CHAR(255), c04 CHAR(255),
+c05 CHAR(255), c06 CHAR(255), c07 CHAR(255), c08 CHAR(255),
+c09 CHAR(255), c10 CHAR(255), c11 CHAR(255), c12 CHAR(255),
+c13 CHAR(255), c14 CHAR(255), c15 CHAR(255), c16 CHAR(255),
+c17 CHAR(255), c18 CHAR(255), c19 CHAR(255), c20 CHAR(255),
+c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255),
+c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255),
+c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255)
+) ENGINE = InnoDB;
+ERROR 42000: Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
+DROP TABLE IF EXISTS t1;
+Warnings:
+Note 1051 Unknown table 't1'
+CREATE TABLE t1(
+id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(-10);
+SELECT * FROM t1;
+id
+-10
+INSERT INTO t1 VALUES(NULL);
+SELECT * FROM t1;
+id
+-10
+1
+DROP TABLE t1;
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+DROP TABLE IF EXISTS t1, t2;
+Warnings:
+Note 1051 Unknown table 't1'
+Note 1051 Unknown table 't2'
+CREATE TABLE t1 ( a int ) ENGINE=InnoDB;
+CREATE TABLE t2 LIKE t1;
+SELECT * FROM t2;
+a
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (1);
+COMMIT;
+SELECT * FROM t1 WHERE a=1;
+a
+1
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+SELECT * FROM t2;
+a
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (2);
+COMMIT;
+SELECT * FROM t1 WHERE a=2;
+a
+2
+SELECT * FROM t1 WHERE a=2;
+a
+2
+DROP TABLE t1;
+DROP TABLE t2;
+create table t1 (i int, j int) engine=innodb;
+insert into t1 (i, j) values (1, 1), (2, 2);
+update t1 set j = 2;
+affected rows: 1
+info: Rows matched: 2 Changed: 1 Warnings: 0
+drop table t1;
+create table t1 (id int) comment='this is a comment' engine=innodb;
+select table_comment, data_free > 0 as data_free_is_set
+from information_schema.tables
+where table_schema='test' and table_name = 't1';
+table_comment data_free_is_set
+this is a comment 1
+drop table t1;
+CREATE TABLE t1 (
+c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+c2 VARCHAR(128) NOT NULL,
+PRIMARY KEY(c1)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=100;
+CREATE TABLE t2 (
+c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+c2 INT(10) UNSIGNED DEFAULT NULL,
+PRIMARY KEY(c1)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=200;
+SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2';
+AUTO_INCREMENT
+200
+ALTER TABLE t2 ADD CONSTRAINT t1_t2_1 FOREIGN KEY(c1) REFERENCES t1(c1);
+SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2';
+AUTO_INCREMENT
+200
+DROP TABLE t2;
+DROP TABLE t1;
+CREATE TABLE t1 (c1 int default NULL,
+c2 int default NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+TRUNCATE TABLE t1;
+affected rows: 0
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+affected rows: 5
+info: Records: 5 Duplicates: 0 Warnings: 0
+TRUNCATE TABLE t1;
+affected rows: 0
+DROP TABLE t1;
+Variable_name Value
+Handler_update 0
+Variable_name Value
+Handler_delete 0
+Variable_name Value
+Handler_update 1
+Variable_name Value
+Handler_delete 1
+set optimizer_switch=@innodb_test_tmp;
+set @innodb_test_dont_touch_optimizer_switch=NULL;
+set optimizer_switch=@innodb_with_mrricp;
diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result
index cf3c0b0731e..636eecc085b 100644
--- a/mysql-test/r/insert_select.result
+++ b/mysql-test/r/insert_select.result
@@ -697,6 +697,7 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 1
DROP TABLE t1;
CREATE TABLE t1 (
diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result
index a285810b78b..c3acea5d11f 100644
--- a/mysql-test/r/insert_update.result
+++ b/mysql-test/r/insert_update.result
@@ -379,7 +379,6 @@ INSERT IGNORE INTO t1 (id,c1) SELECT 1,NULL
ON DUPLICATE KEY UPDATE c1=NULL, cnt=cnt+1;
Warnings:
Warning 1048 Column 'c1' cannot be null
-Error 1048 Column 'c1' cannot be null
SELECT * FROM t1;
id c1 cnt
1 0 2
@@ -387,7 +386,6 @@ INSERT IGNORE INTO t1 (id,c1) SELECT * FROM t2
ON DUPLICATE KEY UPDATE c1=NULL, cnt=cnt+1;
Warnings:
Warning 1048 Column 'c1' cannot be null
-Error 1048 Column 'c1' cannot be null
SELECT * FROM t1;
id c1 cnt
1 0 3
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index 41a05bb00bd..5185c9dcb2b 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -1,5 +1,7 @@
drop table if exists t1,t2,t3;
drop view if exists v1,v2;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
CREATE TABLE t1 (S1 INT);
CREATE TABLE t2 (S1 INT);
INSERT INTO t1 VALUES (1);
@@ -405,7 +407,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
@@ -847,7 +849,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:
@@ -858,6 +860,7 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 5
drop table t1, t2, t3;
create table t1 (a int);
@@ -870,7 +873,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);
@@ -890,12 +893,12 @@ 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
-Last_query_cost 24.016090
+Last_query_cost 28.016090
select '^^: The above should be ~= 20 + cost(select * from t1). Value less than 20 is an error' Z;
Z
^^: The above should be ~= 20 + cost(select * from t1). Value less than 20 is an error
@@ -911,7 +914,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
@@ -925,7 +928,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
@@ -1096,11 +1099,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
@@ -1128,9 +1131,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;
@@ -1239,6 +1242,37 @@ f1 MIN(f2)
214 88
drop table t1,t2;
drop view v1,v2;
+#
+# BUG#47217 Lost optimization caused slowdown & wrong result.
+#
+CREATE TABLE t1 (pk INT, v VARCHAR(2), PRIMARY KEY(pk));
+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_deleted 0
+Handler_read_rnd_next 1
+DROP TABLE t1, t2;
End of 5.1 tests
#
# Bug #43368: STRAIGHT_JOIN DOESN'T WORK FOR NESTED JOINS
@@ -1266,7 +1300,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 system NULL NULL NULL NULL 1
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 4 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
EXPLAIN
SELECT STRAIGHT_JOIN *
FROM t4 JOIN
@@ -1274,18 +1308,166 @@ FROM t4 JOIN
ON t4.ref_t1=t1.c1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 4
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where; Using join buffer
-1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 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)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
EXPLAIN
SELECT *
FROM t4 STRAIGHT_JOIN
(t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1)
ON t4.ref_t1=t1.c1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer
-1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer
+1 SIMPLE t4 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t4.ref_t1 1
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
drop table t1,t2,t3,t4;
End of 5.2 tests
+#
+# BUG#724275: Crash in JOIN::optimize in maria-5.3
+#
+create table t1 (a int);
+insert into t1 values (1),(2);
+insert into t1 select * from t1;
+create table t2 (a int, b int, key(a,b));
+insert into t2 values (1,1),(1,2),(1,3),(1,4),(2,5),(2,6),(2,7),(2,8),(2,9);
+insert into t2 select * from t2;
+insert into t2 select * from t2;
+insert into t2 select * from t2;
+create table t3 (a int, b int, key(a));
+insert into t3 values (1,1),(2,2);
+select * from
+t3 straight_join t1 straight_join t2 force index(a)
+where t2.a=1 and t2.b=t1.a and t1.a=t3.b and t3.a=1;
+a b a a b
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+1 1 1 1 1
+drop table t1,t2,t3;
+#
+# BUG#729067/730466: unexpected 'Range checked for each record'
+# for queries with OR in WHERE clause
+#
+CREATE TABLE t1 (f1 int, f2 int) ;
+INSERT INTO t1 VALUES (4,0),(5,1);
+CREATE TABLE t2 (f1 int, f2 int, KEY (f2)) ;
+INSERT INTO t2 VALUES (5,7), (8,9);
+EXPLAIN
+SELECT * FROM t1 STRAIGHT_JOIN t2 ON t2.f1 = t1.f1
+WHERE t1.f1<>0 OR t1.f2<>0 AND t1.f1 = t2.f2;
+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 f2 NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t1 STRAIGHT_JOIN t2 ON t2.f1 = t1.f1
+WHERE t1.f1<>0 OR t1.f2<>0 AND t1.f1 = t2.f2;
+f1 f2 f1 f2
+5 1 5 7
+DROP TABLE t1,t2;
+CREATE TABLE t1(f1 int PRIMARY KEY, f2 int) ;
+INSERT INTO t1 VALUES (9,4), (10,9);
+CREATE TABLE t2(f1 int PRIMARY KEY, f2 int) ;
+INSERT INTO t2 VALUES (9,4), (10,9);
+EXPLAIN
+SELECT STRAIGHT_JOIN * FROM t1 JOIN t2 ON t2.f2 = t1.f1
+WHERE t1.f1 IN (SELECT f1 FROM t1) AND t1.f1 = t2.f1 OR t1.f1 = 9;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 2 Using where
+1 PRIMARY t2 ALL PRIMARY NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 Using index
+SELECT STRAIGHT_JOIN * FROM t1 JOIN t2 ON t2.f2 = t1.f1
+WHERE t1.f1 IN (SELECT f1 FROM t1) AND t1.f1 = t2.f1 OR t1.f1 = 9;
+f1 f2 f1 f2
+9 4 10 9
+DROP TABLE t1,t2;
+create table t1 (i time key);
+insert into t1 values ('1:1:1'), ('2:2:2');
+create table t2 (i time);
+insert into t2 values ('1:1:1');
+select t2.i from t1 left join t2 on t2.i = t1.i where t1.i = '1:1:1';
+i
+01:01:01
+drop table t1,t2;
+#
+# BUG#954900: unexpected empty set due to an invalid build of key ref
+#
+CREATE TABLE t1 (dog_id int(10), birthday date, PRIMARY KEY (dog_id,birthday));
+INSERT INTO t1 VALUES (5918,'2004-07-22');
+CREATE TABLE t2 (dog_id int(10) unsigned, t_id char(1), birthday date, a_id int(10),
+PRIMARY KEY (dog_id,t_id,birthday,a_id));
+INSERT INTO t2 VALUES
+(5918,'N','2004-07-22',5216551), (5918,'N','2004-07-22',5223640),
+(5918,'N','2004-07-22',5389491), (5918,'N','2004-07-22',5749434),
+(5918,'N','2004-07-22',5992424), (5922,'N','2005-06-30',5076957),
+(5924,'N','2000-08-11',20264), (5924,'N','2000-08-11',64251),
+(5924,'N','2000-08-11',74748), (5924,'N','2000-08-11',87590),
+(5924,'N','2000-08-11',104695), (5924,'N','2000-08-11',133136),
+(5924,'N','2000-08-11',5027806), (5924,'N','2000-08-11',5076957),
+(5924,'N','2000-08-11',5166821), (5924,'N','2000-08-11',5181896),
+(5924,'N','2000-08-11',5217908), (5924,'N','2000-08-11',5220812),
+(5924,'N','2000-08-11',5226473), (5924,'N','2000-08-11',5339111),
+(5925,'N','2005-02-10',19227), (5925,'N','2005-02-10',74529),
+(5925,'N','2005-02-10',74748), (5927,'N','2005-08-18',20264),
+(5927,'N','2005-08-18',58364), (5929,'N','2005-01-19',58364),
+(5935,'N','2006-03-10',19227), (5935,'N','2006-03-10',64251),
+(5935,'N','2006-03-10',5222400), (5935,'N','2006-03-10',5226473),
+(5936,'N','2004-10-29',5015032), (5937,'N','2002-04-05',11237),
+(5937,'N','2002-04-05',23911), (5937,'N','2002-04-05',112133),
+(5937,'N','2002-04-05',169721), (5937,'N','2002-04-05',170650),
+(5937,'N','2002-04-05',5014494), (5937,'N','2002-04-05',5166009),
+(5937,'N','2002-04-05',5181871), (5937,'N','2002-04-05',5213380),
+(5937,'N','2002-04-05',5214875), (5937,'N','2002-04-05',5895062),
+(5938,'N','2006-03-24',11237), (5938,'N','2006-03-24',19227),
+(5938,'N','2006-03-24',23911), (5938,'N','2006-03-24',58364),
+(5938,'N','2006-03-24',64251), (5938,'N','2006-03-24',111716),
+(5938,'N','2006-03-24',112702), (5938,'N','2006-03-24',133136),
+(5938,'N','2006-03-24',168718), (5938,'N','2006-03-24',5137136),
+(5938,'N','2006-03-24',5161519), (5938,'N','2006-03-24',5168120),
+(5938,'N','2006-03-24',5219034), (6234,'N','2006-06-02',103058),
+(6234,'N','2006-06-02',5146844), (6235,'N','2006-06-01',12900),
+(6235,'N','2006-06-01',20264), (6235,'N','2006-06-01',64251),
+(6235,'N','2006-06-01',75160), (6235,'N','2006-06-01',5014494),
+(6235,'N','2006-06-01',5181638), (6236,'N','2006-06-06',112595),
+(6236,'N','2006-06-06',5219601), (6236,'N','2006-06-06',5808374);
+CREATE TABLE t3 (dog_id int(10) unsigned);
+INSERT INTO t3 VALUES (5918);
+CREATE TABLE t4 (dog_id int(10), t_id char(1), birthday date, KEY (t_id));
+INSERT INTO t4 VALUES (5918,'N','2004-07-22'), (5919,'N','2004-07-20');
+CREATE TABLE t5 (dog_id int(10) unsigned, UNIQUE KEY (dog_id));
+INSERT INTO t5 VALUES (5918);
+SET @tmp_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT * FROM t5 DU, t1 D, t4 DT, t2 DSA, t3 DSAR
+WHERE DU.dog_id=D.dog_id AND D.dog_id=DT.dog_id AND D.birthday=DT.birthday AND
+DT.t_id=DSA.t_id AND DT.birthday=DSA.birthday AND DSA.dog_id=DSAR.dog_id;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE DU system dog_id NULL NULL NULL 1
+1 SIMPLE D system PRIMARY NULL NULL NULL 1
+1 SIMPLE DSAR system NULL NULL NULL NULL 1
+1 SIMPLE DT range t_id t_id 2 NULL 2 Using where
+1 SIMPLE DSA ref PRIMARY PRIMARY 8 const,test.DT.t_id,test.D.birthday 1 Using index
+SELECT * FROM t5 DU, t1 D, t4 DT, t2 DSA, t3 DSAR
+WHERE DU.dog_id=D.dog_id AND D.dog_id=DT.dog_id AND D.birthday=DT.birthday AND
+DT.t_id=DSA.t_id AND DT.birthday=DSA.birthday AND DSA.dog_id=DSAR.dog_id;
+dog_id dog_id birthday dog_id t_id birthday dog_id t_id birthday a_id dog_id
+5918 5918 2004-07-22 5918 N 2004-07-22 5918 N 2004-07-22 5216551 5918
+5918 5918 2004-07-22 5918 N 2004-07-22 5918 N 2004-07-22 5223640 5918
+5918 5918 2004-07-22 5918 N 2004-07-22 5918 N 2004-07-22 5389491 5918
+5918 5918 2004-07-22 5918 N 2004-07-22 5918 N 2004-07-22 5749434 5918
+5918 5918 2004-07-22 5918 N 2004-07-22 5918 N 2004-07-22 5992424 5918
+SET optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1,t2,t3,t4,t5;
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result
new file mode 100644
index 00000000000..2c634c3d92b
--- /dev/null
+++ b/mysql-test/r/join_cache.result
@@ -0,0 +1,5639 @@
+DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11;
+DROP DATABASE IF EXISTS world;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @local_join_cache_test_optimizer_switch_default=@@optimizer_switch;
+set names utf8;
+CREATE DATABASE world;
+use world;
+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
+set join_cache_level=1;
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock United States English
+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 ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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 hash_ALL NULL #hash#$hj 3 world.Country.Code 984 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (flat, 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock United States English
+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 ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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 hash_ALL NULL #hash#$hj 3 world.Country.Code 984 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock United States English
+SELECT Country.Name, Country.Population, City.Name, City.Population
+FROM Country LEFT JOIN City
+ON City.Country=Country.Code AND City.Population > 5000000
+WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+Name Population Name Population
+China 1277558000 Shanghai 9696300
+China 1277558000 Peking 7472000
+China 1277558000 Chongqing 6351600
+China 1277558000 Tianjin 5286800
+Colombia 42321000 Santafé de Bogotá 6260862
+Congo, The Democratic Republic of the 51654000 Kinshasa 5064000
+Chile 15211000 NULL NULL
+Cambodia 11168000 NULL NULL
+Cameroon 15085000 NULL NULL
+Canada 31147000 NULL NULL
+Cuba 11201000 NULL NULL
+Côte d?Ivoire 14786000 NULL NULL
+Czech Republic 10278100 NULL NULL
+SELECT Country.Name, Country.Population, City.Name, City.Population
+FROM Country LEFT JOIN City
+ON City.Country=Country.Code AND
+(City.Population > 5000000 OR City.Name LIKE 'Za%')
+WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+Name Population Name Population
+China 1277558000 Shanghai 9696300
+China 1277558000 Peking 7472000
+China 1277558000 Chongqing 6351600
+China 1277558000 Tianjin 5286800
+China 1277558000 Zaozhuang 380846
+China 1277558000 Zaoyang 162198
+China 1277558000 Zalantun 130031
+Colombia 42321000 Santafé de Bogotá 6260862
+Congo, The Democratic Republic of the 51654000 Kinshasa 5064000
+Chile 15211000 NULL NULL
+Cambodia 11168000 NULL NULL
+Cameroon 15085000 NULL NULL
+Canada 31147000 NULL NULL
+Cuba 11201000 NULL NULL
+Côte d?Ivoire 14786000 NULL NULL
+Czech Republic 10278100 NULL NULL
+CREATE INDEX City_Population ON City(Population);
+CREATE INDEX City_Name ON City(Name);
+ANALYZE TABLE City;
+EXPLAIN
+SELECT Country.Name, Country.Population, City.Name, City.Population
+FROM Country LEFT JOIN City
+ON City.Country=Country.Code AND City.Population > 5000000
+WHERE Country.Name LIKE 'C%' AND 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 City hash_range City_Population #hash#$hj:City_Population 3:4 world.Country.Code 25 Using where; Rowid-ordered scan; Using join buffer (flat, BNLH join)
+SELECT Country.Name, Country.Population, City.Name, City.Population
+FROM Country LEFT JOIN City
+ON City.Country=Country.Code AND City.Population > 5000000
+WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+Name Population Name Population
+China 1277558000 Shanghai 9696300
+China 1277558000 Peking 7472000
+China 1277558000 Chongqing 6351600
+China 1277558000 Tianjin 5286800
+Colombia 42321000 Santafé de Bogotá 6260862
+Congo, The Democratic Republic of the 51654000 Kinshasa 5064000
+Chile 15211000 NULL NULL
+Cambodia 11168000 NULL NULL
+Cameroon 15085000 NULL NULL
+Canada 31147000 NULL NULL
+Cuba 11201000 NULL NULL
+Côte d?Ivoire 14786000 NULL NULL
+Czech Republic 10278100 NULL NULL
+EXPLAIN
+SELECT Country.Name, Country.Population, City.Name, City.Population
+FROM Country LEFT JOIN City
+ON City.Country=Country.Code AND
+(City.Population > 5000000 OR City.Name LIKE 'Za%')
+WHERE Country.Name LIKE 'C%' AND 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 City hash_index_merge City_Population,City_Name #hash#$hj:City_Population,City_Name 3:4,35 world.Country.Code 96 Using sort_union(City_Population,City_Name); Using where; Using join buffer (flat, BNLH join)
+SELECT Country.Name, Country.Population, City.Name, City.Population
+FROM Country LEFT JOIN City
+ON City.Country=Country.Code AND
+(City.Population > 5000000 OR City.Name LIKE 'Za%')
+WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+Name Population Name Population
+China 1277558000 Shanghai 9696300
+China 1277558000 Peking 7472000
+China 1277558000 Chongqing 6351600
+China 1277558000 Tianjin 5286800
+China 1277558000 Zaozhuang 380846
+China 1277558000 Zaoyang 162198
+China 1277558000 Zalantun 130031
+Colombia 42321000 Santafé de Bogotá 6260862
+Congo, The Democratic Republic of the 51654000 Kinshasa 5064000
+Chile 15211000 NULL NULL
+Cambodia 11168000 NULL NULL
+Cameroon 15085000 NULL NULL
+Canada 31147000 NULL NULL
+Cuba 11201000 NULL NULL
+Côte d?Ivoire 14786000 NULL NULL
+Czech Republic 10278100 NULL NULL
+DROP INDEX City_Population ON City;
+DROP INDEX City_Name ON City;
+set join_cache_level=1;
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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)
+1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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)
+1 SIMPLE CountryLanguage ALL NULL NULL NULL NULL 984 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock United States English
+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 ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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 hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE CountryLanguage hash_ALL NULL #hash#$hj 3 world.Country.Code 984 Using where; Using join buffer (flat, 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock United States English
+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 ALL NULL NULL NULL NULL 239 Using where
+1 SIMPLE City hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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 hash_ALL NULL #hash#$hj 3 world.Country.Code 4079 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE CountryLanguage hash_ALL NULL #hash#$hj 3 world.Country.Code 984 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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 2
+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; Rowid-ordered scan
+1 SIMPLE City hash_ALL Population,Country #hash#Country 3 world.Country.Code 4079 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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 hash_ALL PRIMARY #hash#PRIMARY 3 world.CountryLanguage.Country 239 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE City hash_ALL Country #hash#Country 3 world.CountryLanguage.Country 4079 Using where; Using join buffer (flat, 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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; Rowid-ordered scan
+1 PRIMARY City hash_ALL Population,Country #hash#Country 3 world.Country.Code 4079 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 hash_ALL PRIMARY #hash#PRIMARY 33 world.Country.Code,const 984 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; Rowid-ordered scan
+1 SIMPLE City hash_ALL Population,Country #hash#Country 3 world.Country.Code 4079 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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 hash_ALL PRIMARY #hash#PRIMARY 3 world.CountryLanguage.Country 239 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE City hash_ALL Country #hash#Country 3 world.CountryLanguage.Country 4079 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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; Rowid-ordered scan
+1 PRIMARY City hash_ALL Population,Country #hash#Country 3 world.Country.Code 4079 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 hash_ALL PRIMARY #hash#PRIMARY 33 world.Country.Code,const 984 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
+EXPLAIN
+SELECT Country.Name, Country.Population, City.Name, City.Population
+FROM Country LEFT JOIN City
+ON City.Country=Country.Code AND City.Population > 5000000
+WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range Name Name 52 NULL # Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City hash_range Population,Country #hash#Country:Population 3:4 world.Country.Code # Using where; Rowid-ordered scan; Using join buffer (flat, BNLH join)
+SELECT Country.Name, Country.Population, City.Name, City.Population
+FROM Country LEFT JOIN City
+ON City.Country=Country.Code AND City.Population > 5000000
+WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+Name Population Name Population
+China 1277558000 Shanghai 9696300
+China 1277558000 Peking 7472000
+China 1277558000 Chongqing 6351600
+China 1277558000 Tianjin 5286800
+Colombia 42321000 Santafé de Bogotá 6260862
+Congo, The Democratic Republic of the 51654000 Kinshasa 5064000
+Chile 15211000 NULL NULL
+Cambodia 11168000 NULL NULL
+Cameroon 15085000 NULL NULL
+Canada 31147000 NULL NULL
+Cuba 11201000 NULL NULL
+Côte d?Ivoire 14786000 NULL NULL
+Czech Republic 10278100 NULL NULL
+CREATE INDEX City_Name ON City(Name);
+EXPLAIN
+SELECT Country.Name, Country.Population, City.Name, City.Population
+FROM Country LEFT JOIN City
+ON City.Country=Country.Code AND
+(City.Population > 5000000 OR City.Name LIKE 'Za%')
+WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Country range Name Name 52 NULL 17 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City hash_index_merge Population,Country,City_Name #hash#Country:Population,City_Name 3:4,35 world.Country.Code 96 Using sort_union(Population,City_Name); Using where; Using join buffer (flat, BNLH join)
+SELECT Country.Name, Country.Population, City.Name, City.Population
+FROM Country LEFT JOIN City
+ON City.Country=Country.Code AND
+(City.Population > 5000000 OR City.Name LIKE 'Za%')
+WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+Name Population Name Population
+China 1277558000 Shanghai 9696300
+China 1277558000 Peking 7472000
+China 1277558000 Chongqing 6351600
+China 1277558000 Tianjin 5286800
+China 1277558000 Zaozhuang 380846
+China 1277558000 Zaoyang 162198
+China 1277558000 Zalantun 130031
+Colombia 42321000 Santafé de Bogotá 6260862
+Congo, The Democratic Republic of the 51654000 Kinshasa 5064000
+Chile 15211000 NULL NULL
+Cambodia 11168000 NULL NULL
+Cameroon 15085000 NULL NULL
+Canada 31147000 NULL NULL
+Cuba 11201000 NULL NULL
+Côte d?Ivoire 14786000 NULL NULL
+Czech Republic 10278100 NULL NULL
+DROP INDEX City_Name ON City;
+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; Rowid-ordered scan
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE City ref Country Country 3 world.CountryLanguage.Country 18 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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; Rowid-ordered scan
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE City ref Country Country 3 world.CountryLanguage.Country 18 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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; Rowid-ordered scan
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE City ref Country Country 3 world.CountryLanguage.Country 18 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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; Rowid-ordered scan
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE City ref Country Country 3 world.CountryLanguage.Country 18 Using where; Using join buffer (incremental, BKAH join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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; Rowid-ordered scan
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE City hash_ALL Population,Country #hash#Country 3 world.Country.Code 4079 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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 hash_ALL PRIMARY #hash#PRIMARY 3 world.CountryLanguage.Country 239 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE City hash_ALL Country #hash#Country 3 world.CountryLanguage.Country 4079 Using where; Using join buffer (flat, 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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; Rowid-ordered scan
+1 PRIMARY City hash_ALL Population,Country #hash#Country 3 world.Country.Code 4079 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; Rowid-ordered scan
+1 SIMPLE City hash_ALL Population,Country #hash#Country 3 world.Country.Code 4079 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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 hash_ALL PRIMARY #hash#PRIMARY 3 world.CountryLanguage.Country 239 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE City hash_ALL Country #hash#Country 3 world.CountryLanguage.Country 4079 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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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; Rowid-ordered scan
+1 PRIMARY City hash_ALL Population,Country #hash#Country 3 world.Country.Code 4079 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; Rowid-ordered scan
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE City ref Country Country 3 world.CountryLanguage.Country 18 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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; Rowid-ordered scan
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE City ref Country Country 3 world.CountryLanguage.Country 18 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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; Rowid-ordered scan
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE City ref Country Country 3 world.CountryLanguage.Country 18 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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; Rowid-ordered scan
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE City ref Country Country 3 world.CountryLanguage.Country 18 Using where; Using join buffer (incremental, BKAH join); Key-ordered Rowid-ordered scan
+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 AND
+LENGTH(Language) < LENGTH(City.Name) - 2;
+Name Name Language
+La Matanza Argentina Spanish
+Lomas de Zamora Argentina Spanish
+Lauro de Freitas Brazil Portuguese
+Los Angeles Chile Spanish
+Las Palmas de Gran Canaria Spain Spanish
+L´Hospitalet de Llobregat Spain Spanish
+Lleida (Lérida) Spain Spanish
+Liupanshui China Chinese
+Lianyungang China Chinese
+Liangcheng China Chinese
+Lengshuijiang China Chinese
+Lázaro Cárdenas Mexico Spanish
+Lagos de Moreno Mexico Spanish
+Las Margaritas Mexico Spanish
+Lashio (Lasho) Myanmar Burmese
+Lalitapur Nepal Nepali
+Ludwigshafen am Rhein Germany German
+Leverkusen Germany German
+Luchou Taiwan Min
+Lungtan Taiwan Min
+Lower Hutt New Zealand English
+Los Teques Venezuela Spanish
+Leninsk-Kuznetski Russian Federation Russian
+Los Angeles United States English
+Long Beach United States English
+Lexington-Fayette United States English
+Louisville United States English
+Little Rock 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; Rowid-ordered scan
+1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
+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 2
+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; Rowid-ordered scan
+1 SIMPLE Country eq_ref PRIMARY PRIMARY 3 world.City.Country # Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
+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 t2 eq_ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t7 ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using index
+1 SIMPLE t8 eq_ref PRIMARY PRIMARY 4 test.t7.artistid 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t3 ref t3_metaid,t3_formatid,t3_metaidformatid t3_metaidformatid 4 test.t1.metaid 1 Using index condition; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t4 eq_ref PRIMARY,t4_formatclassid,t4_formats_idx PRIMARY 4 test.t3.formatid 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t5 eq_ref PRIMARY,t5_formattypeid PRIMARY 4 test.t4.formatclassid 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t9 index PRIMARY,t9_subgenreid,t9_metaid PRIMARY 8 NULL 2 Using where; Using index; Using join buffer (incremental, BNL join)
+1 SIMPLE t10 eq_ref PRIMARY,t10_genreid PRIMARY 4 test.t9.subgenreid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t11 eq_ref PRIMARY PRIMARY 4 test.t10.genreid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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);
+INSERT INTO t2 VALUES (17,10), (11,20), (12,20), (18,20), (18,10), (11,20);
+INSERT INTO t2 VALUES (11,10), (14,20), (13,20), (17,20), (17,10), (11,20);
+set join_buffer_size=32;
+Warnings:
+Warning 1292 Truncated incorrect join_buffer_size value: '32'
+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); Key-ordered Rowid-ordered scan
+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);
+INSERT INTO t2 VALUES (14,10), (12,10), (15,30), (12,20), (14,20);
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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 hash_ALL NULL #hash#$hj 5 test.t1.a 3 Using where; Using join buffer (flat, BNLH 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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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');
+flush status;
+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); Key-ordered Rowid-ordered scan
+show status like "Handler_icp%";
+Variable_name Value
+Handler_icp_attempts 20
+Handler_icp_match 4
+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); Key-ordered Rowid-ordered scan
+show status like "Handler_icp%";
+Variable_name Value
+Handler_icp_attempts 40
+Handler_icp_match 8
+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); Key-ordered Rowid-ordered scan
+show status like "Handler_icp%";
+Variable_name Value
+Handler_icp_attempts 60
+Handler_icp_match 12
+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); Key-ordered Rowid-ordered scan
+show status like "Handler_icp%";
+Variable_name Value
+Handler_icp_attempts 80
+Handler_icp_match 16
+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);
+insert into t2 values
+(21, 10), (31, 400), (21, 400), (31, 200), (11, 300), (11, 200), (41, 100),
+(41, 200), (31, 300), (11, 400), (21, 200), (21, 300);
+set join_cache_level=6;
+explain
+select t1.id1, sum(t2.id2) from t1 join t2 on t1.id1=t2.id1
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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 t2 values
+(130, 'bbb'), (110, 'b'), (170, 'bbbbbbb'), (160, 'bbbbbb'),
+(131, 'bbb'), (111, 'b'), (171, 'bbbbbbb'), (161, 'bbbbbb'),
+(132, 'bbb'), (112, 'b'), (172, 'bbbbbbb'), (162, 'bbbbbb');
+insert into t3 values
+(4000, 'dddd'), (3000, 'ddd'), (1000, 'd'), (8000, 'dddddddd'),
+(4001, 'dddd'), (3001, 'ddd'), (1001, 'd'), (8001, 'dddddddd'),
+(4002, 'dddd'), (3002, 'ddd'), (1002, 'd'), (8002, 'dddddddd');
+insert into t3 values
+(14000, 'dddd'), (13000, 'ddd'), (11000, 'd'), (18000, 'dddddddd'),
+(14001, 'dddd'), (13001, 'ddd'), (11001, 'd'), (18001, 'dddddddd'),
+(4002, 'dddd'), (3002, 'ddd'), (1002, 'd'), (8002, 'dddddddd');
+insert into t4 values
+(200, 'cc'), (600, 'cccccc'), (300, 'ccc'), (500, 'ccccc'),
+(201, 'cc'), (601, 'cccccc'), (301, 'ccc'), (501, 'ccccc'),
+(202, 'cc'), (602, 'cccccc'), (302, 'ccc'), (502, 'ccccc');
+insert into t4 values
+(1200, 'cc'), (1600, 'cccccc'), (1300, 'ccc'), (1500, 'ccccc'),
+(1201, 'cc'), (1601, 'cccccc'), (1301, 'ccc'), (1501, 'ccccc'),
+(1202, 'cc'), (1602, 'cccccc'), (1302, 'ccc'), (1502, 'ccccc');
+analyze table t2,t3,t4;
+set join_cache_level=1;
+explain
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE t3 ref idx idx 5 test.t1.d 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t4 ref idx idx 5 test.t1.c 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t2.id4 1 Using where; Using join buffer (incremental, BKAH join); Key-ordered Rowid-ordered scan
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t1.id2 1 Using join buffer (incremental, BKAH join); Key-ordered Rowid-ordered scan
+1 SIMPLE t5 eq_ref PRIMARY PRIMARY 16 test.t1.id1,test.t1.id2 1 Using where; Using join buffer (incremental, BKAH join); Key-ordered Rowid-ordered scan
+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);
+set join_cache_level=1;
+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 t3 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using join buffer (incremental, BNL 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),(50,150),(250,350),(180,210),(100,150),
+(101,NULL),(151,200),(51,150),(251,350),(181,210),(101,150);
+set join_cache_level = 5;
+explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+id select_type table type possible_keys key key_len ref rows Extra
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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");
+INSERT INTO t2 VALUES (100,NULL),(150,"long varchar"),(200,"varchar"),(250,"long long long varchar");
+set join_cache_level = 5;
+explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+id select_type table type possible_keys key key_len ref rows Extra
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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');
+INSERT INTO t3 VALUES
+(103,108,'2008-12-04','00:00:00','a','v'), (103,108,'2009-03-28','00:00:00','b','f'),
+(103,105,'1900-01-01','00:55:47','c','v'), (102,108,'2009-10-02','00:00:00','d','s'),
+(100,108,'1900-01-01','20:51:59','e','a'), (100,106,'2008-06-04','09:47:27','f','p'),
+(108,107,'2009-01-13','21:58:29','g','z'), (105,102,'1900-01-01','22:45:53','h','a'),
+(109,105,'2008-01-28','14:06:48','i','h'), (105,107,'2004-09-18','22:17:16','j','h'),
+(104,102,'2006-10-14','14:59:37','k','v'), (102,109,'1900-01-01','23:37:40','l','v'),
+(1033,1142,'2000-11-28','14:14:01','m','b'), (105,103,'2008-04-04','02:54:19','n','y'),
+(100,100,'2002-07-13','06:34:26','o','v'), (109,103,'2003-01-03','18:07:38','p','m'),
+(100,105,'2006-04-02','13:55:23','q','z'), (103,109,'2006-10-19','20:32:28','s','n'),
+(108,100,'2005-06-08','11:57:44','t','d'), (1231,1107,'2006-12-26','03:10:35','v','a');
+CREATE TABLE t1 SELECT * FROM t3;
+DELETE FROM t1 WHERE i > 8;
+CREATE TABLE t2 SELECT * FROM t3;
+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 hash_ALL idx #hash#idx 3 test.t2.u 40 Using where; Using join buffer (flat, BNLH join)
+SELECT t1.i, t1.d, t1.v, t2.i, t2.d, t2.t, t2.v FROM t1,t2,t3
+WHERE t3.u <='a' AND t2.j < 5 AND t3.v = t2.u;
+i d v i d t v
+0 2008-06-04 p 1 2002-07-13 06:34:26 v
+0 2008-06-04 p 4 2006-10-14 14:59:37 v
+0 2008-06-04 p 5 1900-01-01 22:45:53 a
+0 2008-06-04 p 5 1900-01-01 22:45:53 a
+0 2008-06-04 p 5 1900-01-01 22:45:53 a
+1 1900-01-01 a 1 2002-07-13 06:34:26 v
+1 1900-01-01 a 4 2006-10-14 14:59:37 v
+1 1900-01-01 a 5 1900-01-01 22:45:53 a
+1 1900-01-01 a 5 1900-01-01 22:45:53 a
+1 1900-01-01 a 5 1900-01-01 22:45:53 a
+1 2002-07-13 v 1 2002-07-13 06:34:26 v
+1 2002-07-13 v 4 2006-10-14 14:59:37 v
+1 2002-07-13 v 5 1900-01-01 22:45:53 a
+1 2002-07-13 v 5 1900-01-01 22:45:53 a
+1 2002-07-13 v 5 1900-01-01 22:45:53 a
+1 2006-04-02 z 1 2002-07-13 06:34:26 v
+1 2006-04-02 z 4 2006-10-14 14:59:37 v
+1 2006-04-02 z 5 1900-01-01 22:45:53 a
+1 2006-04-02 z 5 1900-01-01 22:45:53 a
+1 2006-04-02 z 5 1900-01-01 22:45:53 a
+2 1900-01-01 v 1 2002-07-13 06:34:26 v
+2 1900-01-01 v 4 2006-10-14 14:59:37 v
+2 1900-01-01 v 5 1900-01-01 22:45:53 a
+2 1900-01-01 v 5 1900-01-01 22:45:53 a
+2 1900-01-01 v 5 1900-01-01 22:45:53 a
+2 2009-10-02 s 1 2002-07-13 06:34:26 v
+2 2009-10-02 s 4 2006-10-14 14:59:37 v
+2 2009-10-02 s 5 1900-01-01 22:45:53 a
+2 2009-10-02 s 5 1900-01-01 22:45:53 a
+2 2009-10-02 s 5 1900-01-01 22:45:53 a
+3 1900-01-01 v 1 2002-07-13 06:34:26 v
+3 1900-01-01 v 4 2006-10-14 14:59:37 v
+3 1900-01-01 v 5 1900-01-01 22:45:53 a
+3 1900-01-01 v 5 1900-01-01 22:45:53 a
+3 1900-01-01 v 5 1900-01-01 22:45:53 a
+3 2006-10-19 n 1 2002-07-13 06:34:26 v
+3 2006-10-19 n 4 2006-10-14 14:59:37 v
+3 2006-10-19 n 5 1900-01-01 22:45:53 a
+3 2006-10-19 n 5 1900-01-01 22:45:53 a
+3 2006-10-19 n 5 1900-01-01 22:45:53 a
+3 2008-12-04 v 1 2002-07-13 06:34:26 v
+3 2008-12-04 v 4 2006-10-14 14:59:37 v
+3 2008-12-04 v 5 1900-01-01 22:45:53 a
+3 2008-12-04 v 5 1900-01-01 22:45:53 a
+3 2008-12-04 v 5 1900-01-01 22:45:53 a
+3 2009-03-28 f 1 2002-07-13 06:34:26 v
+3 2009-03-28 f 4 2006-10-14 14:59:37 v
+3 2009-03-28 f 5 1900-01-01 22:45:53 a
+3 2009-03-28 f 5 1900-01-01 22:45:53 a
+3 2009-03-28 f 5 1900-01-01 22:45:53 a
+4 2006-10-14 v 1 2002-07-13 06:34:26 v
+4 2006-10-14 v 4 2006-10-14 14:59:37 v
+4 2006-10-14 v 5 1900-01-01 22:45:53 a
+4 2006-10-14 v 5 1900-01-01 22:45:53 a
+4 2006-10-14 v 5 1900-01-01 22:45:53 a
+5 1900-01-01 a 1 2002-07-13 06:34:26 v
+5 1900-01-01 a 4 2006-10-14 14:59:37 v
+5 1900-01-01 a 5 1900-01-01 22:45:53 a
+5 1900-01-01 a 5 1900-01-01 22:45:53 a
+5 1900-01-01 a 5 1900-01-01 22:45:53 a
+5 2004-09-18 h 1 2002-07-13 06:34:26 v
+5 2004-09-18 h 4 2006-10-14 14:59:37 v
+5 2004-09-18 h 5 1900-01-01 22:45:53 a
+5 2004-09-18 h 5 1900-01-01 22:45:53 a
+5 2004-09-18 h 5 1900-01-01 22:45:53 a
+5 2008-04-04 y 1 2002-07-13 06:34:26 v
+5 2008-04-04 y 4 2006-10-14 14:59:37 v
+5 2008-04-04 y 5 1900-01-01 22:45:53 a
+5 2008-04-04 y 5 1900-01-01 22:45:53 a
+5 2008-04-04 y 5 1900-01-01 22:45:53 a
+8 2005-06-08 d 1 2002-07-13 06:34:26 v
+8 2005-06-08 d 4 2006-10-14 14:59:37 v
+8 2005-06-08 d 5 1900-01-01 22:45:53 a
+8 2005-06-08 d 5 1900-01-01 22:45:53 a
+8 2005-06-08 d 5 1900-01-01 22:45:53 a
+8 2009-01-13 z 1 2002-07-13 06:34:26 v
+8 2009-01-13 z 4 2006-10-14 14:59:37 v
+8 2009-01-13 z 5 1900-01-01 22:45:53 a
+8 2009-01-13 z 5 1900-01-01 22:45:53 a
+8 2009-01-13 z 5 1900-01-01 22:45:53 a
+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,'a'), (27,9,'n'), (28,1,'d'), (29,107,'a');
+INSERT INTO t1 VALUES
+(110,8,'x'), (111,8,'y'), (112,5,'v'), (113,8,'z'), (114,8,'i'),
+(115,6,'j'), (116,7,'t'), (117,2,'b'), (118,5,'j'), (119,7,'w'),
+(125,3,'q'), (126,5,'o'), (127,9,'n'), (128,1,'e'), (129,107,'c');
+INSERT INTO t1 VALUES
+(210,8,'b'), (211,8,'c'), (212,5,'d'), (213,8,'e'), (214,8,'g'),
+(215,6,'f'), (216,7,'h'), (217,2,'i'), (218,5,'j'), (219,7,'k'),
+(225,3,'l'), (226,5,'m'), (227,9,'n'), (228,1,'o'), (229,107,'p');
+CREATE TABLE t2 (
+pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
+PRIMARY KEY (pk), INDEX idx1(i), INDEX idx2(v,i)
+) 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,'b'), (27,9,'n'), (28,1,'d'), (29,107,'a');
+CREATE TABLE t3 (
+pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
+PRIMARY KEY (pk), INDEX idx1(i), INDEX idx2(v,i)
+) 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 AND t1.pk*2<100
+GROUP BY t2.v ORDER BY t1.pk,t2.v;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using index; Using temporary; Using filesort
+1 SIMPLE t3 eq_ref PRIMARY,idx2 PRIMARY 4 test.t2.i 1 Using where
+1 SIMPLE t1 ref idx2 idx2 3 test.t3.v 5 Using where
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
+GROUP BY t2.v ORDER BY t1.pk,t2.v;
+v
+b
+h
+n
+v
+p
+SET SESSION join_cache_level=6;
+EXPLAIN
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
+GROUP BY t2.v ORDER BY t1.pk,t2.v;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL idx1 NULL NULL NULL 20 Using temporary; Using filesort
+1 SIMPLE t3 eq_ref PRIMARY,idx2 PRIMARY 4 test.t2.i 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t1 ref idx2 idx2 3 test.t3.v 5 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
+GROUP BY t2.v ORDER BY t1.pk,t2.v;
+v
+b
+h
+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 AND t1.pk*2<100
+GROUP BY t2.v ORDER BY t1.pk,t2.v;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL idx1 NULL NULL NULL 20 Using temporary; Using filesort
+1 SIMPLE t3 hash_ALL PRIMARY,idx2 #hash#PRIMARY 4 test.t2.i 20 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t1 hash_ALL idx2 #hash#idx2 3 test.t3.v 45 Using where; Using join buffer (incremental, BNLH join)
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
+GROUP BY t2.v ORDER BY t1.pk,t2.v;
+v
+b
+h
+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 hash_index cu #hash#cu:cu 33:33 func 10 Using where; 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 t2 ALL idx NULL NULL NULL 15 Using where
+1 SIMPLE t1 hash_ALL NULL #hash#$hj 5 test.t2.a 36 Using where; 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);
+INSERT INTO t2 VALUES
+('dig',5), ('were',-1631322112), ('is',3), ('abcdefjhjl',3),
+('abcdefjh',4), ('told',-824573952), ('tt',0),('vv',-1711013888),
+('abcdefjhjj',1015414784), ('and',4), ('here',0), ('abcdefjhjm',-32702464),
+('abcdefjhji',4), ('space',1078394880), ('fs',4), ('mn',-1845559296),
+('fq', 5), ('abcdefjhjp',-1074397184);
+EXPLAIN
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t2 ref idx idx 13 test.t1.v 3
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
+v i
+abcdefjh 4
+f 4
+f 4
+EXPLAIN
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 7
+1 SIMPLE t2 ref idx idx 13 func 3 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 hash_ALL idx #hash#idx 13 test.t1.v 36 Using join buffer (flat, BNLH join)
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
+v i
+f 4
+f 4
+abcdefjh 4
+EXPLAIN
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 7
+1 SIMPLE t2 hash_ALL idx #hash#idx 13 func 36 Using where; Using join buffer (flat, BNLH join)
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v);
+v i
+f 5
+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');
+INSERT INTO t2 VALUES
+(101,6,'yes'), (102,NULL,'will'), (103,NULL,'o'), (104,NULL,'k'), (105,NULL,'she'),
+(106,-1450835968,'abcdefjhjkl'), (107,-975831040,'abcdefjhjkl'), (108,NULL,'z'),
+(100,-343932928,'t'),
+(111,6,'yes'), (112,NULL,'will'), (113,NULL,'o'), (114,NULL,'k'), (115,NULL,'she'),
+(116,-1450835968,'abcdefjhjkl'), (117,-975831040,'abcdefjhjkl'), (118,NULL,'z'),
+(119,-343932928,'t');
+CREATE TABLE t3 (
+pk int NOT NULL PRIMARY KEY,
+i int,
+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');
+INSERT INTO t3 VALUES
+(101,7,'abcdefjhjkl'),(102,6,'y'), (103,NULL,'to'),(104,7,'n'),(105,7,'look'),
+(106,NULL,'all'), (107,1443168256,'c'), (108,1427046400,'right'),
+(111,7,'abcdefjhjkl'), (112,6,'y'), (113,NULL,'to'), (114,7,'n'), (115,7,'look'),
+(116,NULL,'all'), (117,1443168256,'c'), (118,1427046400,'right'),
+(121,7,'abcdefjhjkl'), (122,6,'y'), (123,NULL,'to'), (124,7,'n'), (125,7,'look'),
+(126,NULL,'all'), (127,1443168256,'c'), (128,1427046400,'right'),
+(131,7,'abcdefjhjkl'), (132,6,'y'), (133,NULL,'to'), (134,7,'n'), (135,7,'look'),
+(136,NULL,'all'), (137,1443168256,'c'), (138,1427046400,'right');
+SET SESSION join_buffer_size = 192;
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT t3.i FROM t1,t2,t3
+WHERE t1.v = t2.v AND t3.v = t1.v AND t2.i <> 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index idx idx 13 NULL 7 Using where; Using index
+1 SIMPLE t2 hash_ALL idx #hash#idx 1003 test.t1.v 36 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t3 hash_ALL idx #hash#idx 1002 func 64 Using where; Using join buffer (incremental, BNLH join)
+SELECT t3.i FROM t1,t2,t3
+WHERE t1.v = t2.v AND t3.v = t1.v AND t2.i <> 0;
+i
+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');
+INSERT INTO t2 VALUES
+(110, 'a'), (120, 'c'), (130, 'aa'), (14, 'bb'),
+(111, 'a'), (121, 'c'), (131, 'aa'), (141, 'cc'),
+(112, 'a'), (122, 'c'), (132, 'bb'), (142, 'aa');
+SELECT * FROM t1,t2 WHERE t2.a=t1.a;
+pk a pk a
+2 aa 30 aa
+2 aa 31 aa
+2 aa 42 aa
+2 aa 130 aa
+2 aa 131 aa
+2 aa 142 aa
+3 bb 4 bb
+3 bb 32 bb
+3 bb 14 bb
+3 bb 132 bb
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE t2.a=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL idx NULL NULL NULL 3 Using where
+1 SIMPLE t2 hash_ALL idx #hash#idx 515 test.t1.a 24 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
+2 aa 130 aa
+3 bb 14 bb
+2 aa 131 aa
+3 bb 132 bb
+2 aa 142 aa
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2;
+#
+# 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);
+INSERT IGNORE INTO t4 VALUES (12,10), (18,20);
+INSERT IGNORE INTO t4 VALUES (22,11), (28,21);
+INSERT IGNORE INTO t4 VALUES (32,12), (38,22);
+CREATE TABLE t5 (pk int, a5 int) ;
+INSERT IGNORE INTO t5 VALUES (2,0), (8,0);
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+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 t3 hash_ALL PRIMARY #hash#$hj 5 test.t1.c1 1 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t2 hash_ALL NULL #hash#$hj 5 test.t3.b3 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); Key-ordered Rowid-ordered scan
+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 hash_ALL PRIMARY #hash#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); Key-ordered Rowid-ordered scan
+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'),
+(101,'Bbbb'), (102,'BBB'), (103,'bbbb'), (104,'AaA'), (105,'CC'),
+(106,'cC'), (107,'CCC'), (108,'AAA'), (109,'bBbB'), (110,'aaaa'),
+(111,'a'), (112,'dd'), (113,'EE'), (114,'ee'), (115,'D');
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE t1.a=t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where
+1 SIMPLE t2 hash_ALL idx #hash#idx 35 test.t1.a 30 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
+20 BBBB 101 Bbbb
+20 BBBB 103 bbbb
+10 AAA 104 AaA
+30 Cc 105 CC
+30 Cc 106 cC
+10 AAA 108 AAA
+20 BBBB 109 bBbB
+40 DD 112 dd
+50 ee 113 EE
+50 ee 114 ee
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2;
+#
+# 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; Rowid-ordered scan
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Rowid-ordered scan; Using join buffer (flat, BNL join)
+SELECT * FROM t1,t2
+WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6);
+f1 f3 f3 f2 f4
+SET SESSION 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 where; Rowid-ordered scan
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using join buffer (flat, BNL join)
+SELECT * FROM t1,t2
+WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6);
+f1 f3 f3 f2 f4
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default;
+DROP TABLE t1,t2;
+CREATE TABLE t1 (f1 int, f2 varchar(10), KEY (f1), KEY (f2)) ;
+INSERT INTO t1 VALUES
+(4,'e'), (891879424,'l'), (-243400704,'ectlyqupbk'), (1851981824,'of'),
+(-1495203840,'you'), (4,'no'), (-1436942336,'c'), (891420672,'DQQYO'),
+(608698368,'qergldqmec'), (1,'x');
+CREATE TABLE t2 (f3 varchar(64), KEY (f3));
+INSERT INTO t2 VALUES
+('d'), ('UALLN'), ('d'), ('z'), ('r'), ('YVAKV'), ('d'), ('TNGZK'), ('e'),
+('xucupaxdyythsgiw'), ('why'), ('ttugkxucupaxdyyt'), ('l'), ('LHTKN'),
+('d'), ('o'), ('v'), ('KGLCJ'), ('your');
+SET SESSION optimizer_switch='index_merge_sort_intersection=off';
+SET SESSION optimizer_switch = 'index_condition_pushdown=off';
+EXPLAIN SELECT * FROM t1,t2
+WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0, 100) ORDER BY t1.f2 LIMIT 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range f1,f2 f2 13 NULL 10 Using where
+1 SIMPLE t2 ref f3 f3 67 test.t1.f2 2 Using where; Using index
+SELECT * FROM t1,t2
+WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1;
+f1 f2 f3
+SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default;
+SET SESSION optimizer_switch = 'index_condition_pushdown=on';
+EXPLAIN SELECT * FROM t1,t2
+WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range f1,f2 f2 13 NULL 10 Using where
+1 SIMPLE t2 ref f3 f3 67 test.t1.f2 2 Using where; Using index
+SELECT * FROM t1,t2
+WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1;
+f1 f2 f3
+SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default;
+DROP TABLE t1,t2;
+#
+# Bug #694443: hash join using IS NULL the an equi-join condition
+#
+CREATE TABLE t1 (a int PRIMARY KEY);
+INSERT INTO t1 VALUES
+(7), (4), (9), (1), (3), (8), (2);
+CREATE TABLE t2 (a int, b int, INDEX idx (a));
+INSERT INTO t2 VALUES
+(NULL,10), (4,80), (7,70), (6,11), (7,90), (NULL,40),
+(4,77), (4,50), (NULL,41), (7,99), (7,88), (8,12),
+(1,21), (4,90), (7,91), (8,22), (6,92), (NULL,42),
+(2,78), (2,51), (1,43), (5,97), (5,89);
+SET SESSION join_cache_level = 1;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL;
+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 index
+1 SIMPLE t2 ref idx idx 5 const 4 Using index condition
+SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL;
+a a b
+1 NULL 10
+1 NULL 40
+1 NULL 41
+1 NULL 42
+2 NULL 10
+2 NULL 40
+2 NULL 41
+2 NULL 42
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL;
+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 index
+1 SIMPLE t2 hash_range idx #hash#idx:idx 5:5 const 4 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNLH join)
+SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL;
+a a b
+1 NULL 10
+2 NULL 10
+1 NULL 40
+2 NULL 40
+1 NULL 41
+2 NULL 41
+1 NULL 42
+2 NULL 42
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2;
+#
+# Bug #697557: hash join on a varchar field
+#
+CREATE TABLE t1 ( f1 varchar(10) , f2 int(11) , KEY (f1));
+INSERT INTO t1 VALUES ('r',1), ('m',2);
+CREATE TABLE t2 ( f1 varchar(10) , f2 int(11) , KEY (f1));
+INSERT INTO t2 VALUES
+('hgtofubn',1), ('GDOXZ',91), ('n',2), ('fggxgalh',88),
+('hgtofu',1), ('GDO',101), ('n',3), ('fggxga',55),
+('hgtofu',3), ('GDO',33), ('nn',3), ('fggxgarrr',77),
+('jgtofu',3), ('JDO',33), ('mn',3), ('jggxgarrr',77),
+('igtofu',3), ('IDO',33), ('ln',3), ('iggxgarrr',77);
+SET SESSION join_cache_level=3;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE t2.f1 = t1.f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL f1 NULL NULL NULL 2 Using where
+1 SIMPLE t2 hash_ALL f1 #hash#f1 13 test.t1.f1 20 Using join buffer (flat, BNLH join)
+SELECT * FROM t1,t2 WHERE t2.f1 = t1.f1;
+f1 f2 f1 f2
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1,t2;
+#
+# Bug #707827: hash join on varchar column with NULLs
+#
+CREATE TABLE t1 (v varchar(1));
+INSERT INTO t1 VALUES ('o'), ('u');
+CREATE TABLE t2 (a int, v varchar(1), INDEX idx (v)) ;
+INSERT INTO t2 VALUES
+(8,NULL), (10,'b'), (5,'k'), (4,NULL),
+(1,NULL), (11,'u'), (7,NULL), (2,'d'),
+(18,'u'), (11,'b'), (15,'k'), (12,'d'),
+(18,'x'), (11,'y'), (15,'l'), (12,'e');
+SET SESSION join_buffer_size = 255;
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT a FROM t1,t2 WHERE t2.v = t1.v ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t2 hash_ALL idx #hash#idx 4 test.t1.v 16 Using join buffer (flat, BNLH join)
+SELECT a FROM t1,t2 WHERE t2.v = t1.v ;
+a
+11
+18
+SET SESSION join_cache_level = 1;
+EXPLAIN
+SELECT a FROM t1,t2 WHERE t2.v = t1.v ;
+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 ref idx idx 4 test.t1.v 2
+SELECT a FROM t1,t2 WHERE t2.v = t1.v ;
+a
+11
+18
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION join_buffer_size = DEFAULT;
+DROP TABLE t1,t2;
+#
+# Bug #802860: crash on join cache + derived + duplicate_weedout
+#
+SET SESSION optimizer_switch=
+'semijoin=on,materialization=off,firstmatch=off,loosescan=off,derived_with_keys=on';
+CREATE TABLE t1 (a int) ;
+INSERT IGNORE INTO t1 VALUES (0), (1), (0);
+CREATE TABLE t2 (a int) ;
+INSERT IGNORE INTO t2 VALUES (0), (3), (0), (2);
+SET SESSION join_cache_level = 0;
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+WHERE t.a IN (SELECT t2.a FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 End temporary
+2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+WHERE t.a IN (SELECT t2.a FROM t2);
+a
+0
+SET SESSION join_cache_level = 1;
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+WHERE t.a IN (SELECT t2.a FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
+1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+WHERE t.a IN (SELECT t2.a FROM t2);
+a
+0
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1, t2;
+#
+# Bug #887479: join_cache_level=3 + semijoin=on
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (3914,17), (3710,5), (3888,20);
+CREATE TABLE t2 (c int, KEY (c));
+INSERT INTO t2 VALUES (27), (17), (33), (20), (3), (7), (18), (2);
+SET @tmp887479_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on';
+SET SESSION optimizer_switch='semijoin_with_cache=on';
+SET SESSION join_cache_level=1;
+EXPLAIN
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY t2 ref c c 5 test.t1.b 2 Using index; Start temporary; End temporary
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+a b
+3914 17
+3888 20
+SET SESSION join_cache_level=3;
+EXPLAIN
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY t2 hash_index c #hash#c:c 5:5 test.t1.b 8 Start temporary; End temporary; Using join buffer (flat, BNLH join)
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+a b
+3914 17
+3888 20
+SET SESSION join_cache_level = DEFAULT;
+SET optimizer_switch=@tmp887479_optimizer_switch;
+DROP TABLE t1,t2;
+#
+# Bug #899777: join_cache_level=4 + semijoin=on
+#
+CREATE TABLE t1 (a int, b int, c int, UNIQUE INDEX idx (a));
+INSERT INTO t1 VALUES (1,8,6), (2,2,8);
+CREATE TABLE t2 (a int, b int, c int, UNIQUE INDEX idx (a));
+INSERT INTO t2 VALUES (1,8,6), (2,2,8);
+CREATE TABLE t3 (a int, b int, c int, UNIQUE INDEX idx (a));
+INSERT INTO t3 VALUES (1,8,6), (2,2,8);
+CREATE TABLE t4 (a int, b int, c int, UNIQUE INDEX idx (a));
+INSERT INTO t4 VALUES (1,8,6), (2,2,8);
+SET @tmp_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on';
+SET SESSION optimizer_switch='semijoin_with_cache=on';
+SET SESSION join_cache_level=1;
+EXPLAIN
+SELECT t1.* FROM t1,t2
+WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
+AND t1.a = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 const idx idx 5 const 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; Start temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+SELECT t1.* FROM t1,t2
+WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
+AND t1.a = 1;
+a b c
+1 8 6
+SET SESSION join_cache_level=4;
+EXPLAIN
+SELECT t1.* FROM t1,t2
+WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
+AND t1.a = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 const idx idx 5 const 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t3 hash_ALL NULL #hash#$hj 5 const 2 Using where; Start temporary; Using join buffer (flat, BNLH join)
+1 PRIMARY t4 hash_ALL NULL #hash#$hj 10 const,test.t2.b 2 Using where; End temporary; Using join buffer (incremental, BNLH join)
+SELECT t1.* FROM t1,t2
+WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
+AND t1.a = 1;
+a b c
+1 8 6
+SET SESSION join_cache_level = DEFAULT;
+SET optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1,t2,t3,t4;
+#
+# Bug #899509: an attempt to use hash join with join_cache_level=0
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (8), (7);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (8), (7);
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (8), (7);
+SET @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch=default;
+set @@optimizer_switch='semijoin_with_cache=off';
+set @@optimizer_switch='outer_join_with_cache=off';
+SET optimizer_switch='derived_merge=off,derived_with_keys=off';
+SET join_cache_level=0;
+EXPLAIN
+SELECT * FROM (SELECT t1.* FROM t1, t2) t WHERE t.a IN (SELECT * FROM t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ALL NULL NULL NULL NULL 2
+2 DERIVED t2 ALL NULL NULL NULL NULL 2
+SELECT * FROM (SELECT t1.* FROM t1, t2) t WHERE t.a IN (SELECT * FROM t3);
+a
+8
+8
+7
+7
+SELECT * FROM ( SELECT ta.* FROM t1 AS ta, t1 ) tb WHERE a IN ( SELECT * FROM t1 );
+a
+8
+8
+7
+7
+SET SESSION join_cache_level = DEFAULT;
+SET optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# Bug #900469: semijoin + BNLH + ORDER BY
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (8,10);
+CREATE TABLE t2 (c int, d int);
+INSERT INTO t2 VALUES (8,10);
+INSERT INTO t2 VALUES (9,11);
+CREATE TABLE t3 (c int, d int);
+INSERT INTO t3 VALUES (8,10);
+INSERT INTO t3 VALUES (9,11);
+SET @tmp_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+SET join_cache_level=1;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
+a b c d
+8 10 8 10
+8 10 9 11
+SET join_cache_level=3;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t3 hash_ALL NULL #hash#$hj 5 const 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNLH join)
+SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c);
+a b c d
+8 10 8 10
+8 10 9 11
+SET join_cache_level=3;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t3 hash_ALL NULL #hash#$hj 5 const 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNLH join)
+SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
+a b c d
+8 10 8 10
+8 10 9 11
+SET SESSION join_cache_level = DEFAULT;
+SET optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# Bug #901478: semijoin + ORDER BY + join_cache_level=4|6
+#
+CREATE TABLE t1 (a char(1));
+INSERT INTO t1 VALUES ('x');
+CREATE TABLE t2 (a int, b int, c int, KEY(a), KEY(b), KEY(c));
+INSERT INTO t2 VALUES
+(9,1,0), (7,2,8), (2,3,5), (4,2,9), (8,3,8), (3,4,1), (5,5,4);
+CREATE TABLE t3 (a CHAR(1));
+INSERT INTO t3 VALUES ('x');
+CREATE TABLE t4 (a int, b int, c int, KEY(b), KEY(c));
+INSERT INTO t4 VALUES
+(9,1,0), (7,2,8), (2,3,5), (4,2,9), (8,3,8), (3,4,1), (5,5,4);
+INSERT INTO t4 VALUES
+(19,11,10), (17,12,18), (12,13,15), (14,12,19),
+(18,13,18), (13,14,11), (15,15,14);
+SET @tmp_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch='semijoin=on';
+SET @@optimizer_switch='firstmatch=off';
+SET @@optimizer_switch='mrr=off';
+SET @@optimizer_switch='semijoin_with_cache=off';
+set join_cache_level=1;
+EXPLAIN
+SELECT * FROM t1,t2
+WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
+t2.a BETWEEN 4 and 5
+ORDER BY t2.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 Using filesort
+1 PRIMARY t3 system NULL NULL NULL NULL 1
+1 PRIMARY t2 range a,c a 5 NULL 1 Using index condition; Using where
+1 PRIMARY t4 ref c c 5 test.t2.c 2 Using where; Start temporary; End temporary
+SELECT * FROM t1,t2
+WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
+t2.a BETWEEN 4 and 5
+ORDER BY t2.b;
+a a b c
+x 4 2 9
+x 5 5 4
+set join_cache_level=4;
+EXPLAIN
+SELECT * FROM t1,t2
+WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
+t2.a BETWEEN 4 and 5
+ORDER BY t2.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort
+1 PRIMARY t3 system NULL NULL NULL NULL 1
+1 PRIMARY t2 range a,c a 5 NULL 1 Using index condition; Using where
+1 PRIMARY t4 ref c c 5 test.t2.c 2 Using where; Start temporary; End temporary
+SELECT * FROM t1,t2
+WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
+t2.a BETWEEN 4 and 5
+ORDER BY t2.b;
+a a b c
+x 4 2 9
+x 5 5 4
+SET @@optimizer_switch='semijoin_with_cache=on';
+set join_cache_level=6;
+EXPLAIN
+SELECT * FROM t1,t2
+WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
+t2.a BETWEEN 4 and 5
+ORDER BY t2.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort
+1 PRIMARY t3 system NULL NULL NULL NULL 1
+1 PRIMARY t2 range a,c a 5 NULL 1 Using index condition; Using where
+1 PRIMARY t4 ref c c 5 test.t2.c 2 Using where; Start temporary; End temporary
+SELECT * FROM t1,t2
+WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
+t2.a BETWEEN 4 and 5
+ORDER BY t2.b;
+a a b c
+x 4 2 9
+x 5 5 4
+SET join_cache_level = DEFAULT;
+SET optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1,t2,t3,t4;
+#
+# Bug#53305 Duplicate weedout + join buffer (join cache --level=7,8)
+#
+create table t1 (uid int, fid int, index(uid));
+insert into t1 values
+(1,1), (1,2), (1,3), (1,4),
+(2,5), (2,6), (2,7), (2,8),
+(3,1), (3,2), (3,9);
+create table t2 (uid int primary key, name varchar(128), index(name));
+insert into t2 values
+(1, "A"), (2, "B"), (3, "C"), (4, "D"), (5, "E"),
+(6, "F"), (7, "G"), (8, "H"), (9, "I");
+create table t3 (uid int, fid int, index(uid));
+insert into t3 values
+(1,1), (1,2), (1,3),(1,4),
+(2,5), (2,6), (2,7), (2,8),
+(3,1), (3,2), (3,9);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='semijoin=on';
+set optimizer_switch='materialization=off';
+set optimizer_switch='loosescan=off,firstmatch=off';
+set optimizer_switch='mrr_sort_keys=off';
+set join_cache_level=7;
+create table t4 (uid int primary key, name varchar(128), index(name));
+insert into t4 values
+(1, "A"), (2, "B"), (3, "C"), (4, "D"), (5, "E"),
+(6, "F"), (7, "G"), (8, "H"), (9, "I");
+explain select name from t2, t1
+where t1.uid in (select t4.uid from t4, t3 where t3.uid=1 and t4.uid=t3.fid)
+and t2.uid=t1.fid;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ref uid uid 5 const 4 Using where; Start temporary
+1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t3.fid 1 Using index
+1 PRIMARY t1 ALL uid NULL NULL NULL 11 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.fid 1 Using join buffer (flat, BKAH join); Rowid-ordered scan
+select name from t2, t1
+where t1.uid in (select t4.uid from t4, t3 where t3.uid=1 and t4.uid=t3.fid)
+and t2.uid=t1.fid;
+name
+A
+A
+B
+B
+C
+D
+E
+F
+G
+H
+I
+set join_cache_level = default;
+set optimizer_switch=@tmp_optimizer_switch;
+drop table t1,t2,t3,t4;
+#
+# Bug#50358 - semijoin execution of subquery with outerjoin
+# emplying join buffer
+#
+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 (6);
+INSERT INTO t3 VALUES (1), (2);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='semijoin=on';
+set optimizer_switch='materialization=on';
+set join_cache_level=0;
+EXPLAIN
+SELECT * FROM t1 WHERE t1.i IN
+(SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 Using where
+SELECT * FROM t1 WHERE t1.i IN
+(SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i);
+i
+1
+2
+set join_cache_level=2;
+EXPLAIN
+SELECT * FROM t1 WHERE t1.i IN
+(SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t1 WHERE t1.i IN
+(SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i);
+i
+1
+2
+set join_cache_level = default;
+set optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# Bug #12546542: missing row with semijoin=off + join cache
+# (LP bug #922971)
+#
+CREATE TABLE t1 (a varchar(1024));
+INSERT INTO t1 VALUES ('v'), ('we');
+CREATE TABLE t2 (
+a varchar(1024) CHARACTER SET utf8 DEFAULT NULL, b int, c int
+);
+INSERT INTO t2 VALUES ('we',4,NULL), ('v',1305673728,6);
+CREATE TABLE t3 (b int, c int);
+INSERT INTO t3 VALUES (4,4);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=off';
+set optimizer_switch='materialization=off';
+set join_cache_level=0;
+EXPLAIN
+SELECT * FROM t1
+WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b
+WHERE t2.c < 10 OR t3.c > 1);
+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 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 1 Using where
+SELECT * FROM t1
+WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b
+WHERE t2.c < 10 OR t3.c > 1);
+a
+v
+we
+set join_cache_level=2;
+EXPLAIN
+SELECT * FROM t1
+WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b
+WHERE t2.c < 10 OR t3.c > 1);
+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 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t1
+WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b
+WHERE t2.c < 10 OR t3.c > 1);
+a
+v
+we
+set join_cache_level = default;
+set optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# Bug #925985: LEFT JOIN with optimize_join_buffer_size=off +
+# join_buffer_size > join_buffer_space_limit
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (5), (3);
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES
+(3,30), (1,10), (7,70), (2,20),
+(3,31), (1,11), (7,71), (2,21),
+(3,32), (1,12), (7,72), (2,22);
+CREATE TABLE t3 (b int, c int);
+INSERT INTO t3 VALUES (32, 302), (42,400), (30,300);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='optimize_join_buffer_size=off';
+set join_buffer_space_limit=4096;
+set join_buffer_size=4096*2;
+set join_cache_level=2;
+set optimizer_switch='outer_join_with_cache=on';
+EXPLAIN
+SELECT * FROM t1, t2 LEFT JOIN t3 ON 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 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (incremental, BNL join)
+SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a;
+a a b b c
+3 3 30 30 300
+3 3 31 NULL NULL
+3 3 32 32 302
+set join_buffer_space_limit=default;
+set join_buffer_size=default;
+set join_cache_level=default;
+set optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# Bug #1058071: LEFT JOIN using blobs
+# (mdev-564) when join buffer size is small
+#
+CREATE TABLE t1 (
+col269 decimal(31,10) unsigned DEFAULT NULL,
+col280 multipoint DEFAULT NULL,
+col281 tinyint(1) DEFAULT NULL,
+col282 time NOT NULL,
+col284 datetime DEFAULT NULL,
+col286 date DEFAULT NULL,
+col287 datetime DEFAULT NULL,
+col288 decimal(30,29) DEFAULT NULL,
+col291 time DEFAULT NULL,
+col292 time DEFAULT NULL
+) ENGINE=Aria;
+INSERT INTO t1 VALUES
+(0.0,PointFromText('POINT(9 0)'),0,'11:24:05','2013-04-14 21:30:28',NULL,'2011-12-20 06:00:34',9.9,'13:04:39',NULL),
+(0.0,NULL,127,'05:43:12','2012-09-05 06:15:27','2027-01-01','2011-10-29 10:48:29',0.0,'06:24:05','11:33:37'),
+(0.0,NULL,127,'12:54:41','2013-01-12 11:32:58','2011-11-03','2013-01-03 02:00:34',00,'11:54:15','20:19:15'),
+(0.0,PointFromText('POINT(9 0)'),0,'19:48:07','2012-07-16 15:45:25','2012-03-25','2013-09-07 17:21:52',0.5,'17:36:54','21:24:19'),
+(0.0,PointFromText('POINT(9 0)'),0,'03:43:48','2012-09-28 00:00:00','2012-06-26','2011-11-16 05:01:09',00,'01:25:42','19:30:06'),
+(0.0,LineStringFromText('LINESTRING(0 0,9 9,0 0,9 0,0 0)'),127,'11:33:21','2012-03-31 10:29:22','2012-10-10','2012-04-21 19:21:06',NULL,'05:13:22','09:48:34'),
+(NULL,PointFromText('POINT(9 0)'),127,'00:00:00','0000-00-00','2012-04-04 21:26:12','2013-03-04',0.0,'12:54:30',NULL),
+(NULL,PointFromText('POINT(9 0)'),1,'00:00:00','2013-05-01 22:37:49','2013-06-26','2012-09-22 17:31:03',0.0,'08:09:57','11:15:36');
+Warnings:
+Note 1265 Data truncated for column 'col286' at row 7
+CREATE TABLE t2 (b int) ENGINE=Aria;
+INSERT INTO t2 VALUES (NULL);
+CREATE TABLE t3 (c int) ENGINE=Aria;
+INSERT INTO t3 VALUES (NULL);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch = 'outer_join_with_cache=on,join_cache_incremental=on';
+set join_buffer_size=128;
+Warnings:
+Warning 1292 Truncated incorrect join_buffer_size value: '128'
+EXPLAIN
+SELECT 1 AS c FROM t1 NATURAL LEFT JOIN t2 LEFT OUTER JOIN t3 ON 1
+GROUP BY elt(t1.col282,1,t1.col280);
+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 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+SELECT 1 AS c FROM t1 NATURAL LEFT JOIN t2 LEFT OUTER JOIN t3 ON 1
+GROUP BY elt(t1.col282,1,t1.col280);
+c
+1
+set join_buffer_size=default;
+set optimizer_switch=@tmp_optimizer_switch;
+DROP table t1,t2,t3;
+set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result
index 7965e287da2..255714a7236 100644
--- a/mysql-test/r/join_nested.result
+++ b/mysql-test/r/join_nested.result
@@ -1,4 +1,7 @@
DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5,t6,t7,t8,t9;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch=ifnull(@optimizer_switch_for_join_nested_test,'outer_join_with_cache=off');
+set join_cache_level=1;
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);
@@ -74,7 +77,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 +153,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 +183,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,10 +232,10 @@ 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
+Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t7`.`b`) and (`test`.`t6`.`b` < 10))) where 1
SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
FROM (t6, t7)
LEFT JOIN
@@ -544,16 +547,16 @@ 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`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
FROM t0,t1
@@ -639,7 +642,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,9 +650,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`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
SELECT t9.a,t9.b
FROM t9;
a b
@@ -836,30 +839,31 @@ 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)
+INSERT INTO t2 VALUES (-1,9,0), (-3,10,0), (-2,8,0), (-4,11,0), (-5,15,0);
CREATE INDEX idx_b ON t2(b);
EXPLAIN EXTENDED
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
FROM (t3,t4)
LEFT JOIN
(t1,t2)
-ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
+ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00
-1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
-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`.`t2`.`a` > 0) and (`test`.`t3`.`b` is not null))) where 1
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
FROM (t3,t4)
LEFT JOIN
(t1,t2)
-ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
+ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0;
a b a b a b
4 2 1 2 3 2
4 2 1 2 3 2
@@ -878,7 +882,7 @@ LEFT JOIN
t2
LEFT JOIN
(t3, t4)
-ON t3.a=1 AND t2.b=t4.b,
+ON t3.a=1 AND t2.b=t4.b AND t2.a>0,
t5
LEFT JOIN
(
@@ -906,17 +910,19 @@ 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 t2 ALL NULL NULL NULL NULL 3 100.00 Using where
-1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
-1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`a` > 0))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+INSERT INTO t4 VALUES (-3,12,0), (-4,13,0), (-1,11,0), (-3,11,0), (-5,15,0);
+INSERT INTO t5 VALUES (-3,11,0), (-2,12,0), (-3,13,0), (-4,12,0);
CREATE INDEX idx_b ON t4(b);
CREATE INDEX idx_b ON t5(b);
EXPLAIN EXTENDED
@@ -928,7 +934,7 @@ LEFT JOIN
t2
LEFT JOIN
(t3, t4)
-ON t3.a=1 AND t2.b=t4.b,
+ON t3.a=1 AND t2.b=t4.b AND t2.a>0 AND t4.a>0,
t5
LEFT JOIN
(
@@ -937,7 +943,7 @@ LEFT JOIN
t8
ON t7.b=t8.b AND t6.b < 10
)
-ON t6.b >= 2 AND t5.b=t7.b
+ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
@@ -956,17 +962,18 @@ 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 t2 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 t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where
-1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
-1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
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`.`a` > 0) and (`test`.`t4`.`a` > 0) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`a` > 0)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
+INSERT INTO t8 VALUES (-3,12,0), (-1,14,0), (-5,15,0), (-1,11,0), (-4,13,0);
CREATE INDEX idx_b ON t8(b);
EXPLAIN EXTENDED
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
@@ -977,16 +984,16 @@ LEFT JOIN
t2
LEFT JOIN
(t3, t4)
-ON t3.a=1 AND t2.b=t4.b,
+ON t3.a=1 AND t2.b=t4.b AND t2.a>0 AND t4.a>0,
t5
LEFT JOIN
(
(t6, t7)
LEFT JOIN
t8
-ON t7.b=t8.b AND t6.b < 10
+ON t7.b=t8.b AND t6.b < 10 AND t8.a>=0
)
-ON t6.b >= 2 AND t5.b=t7.b
+ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
@@ -1005,17 +1012,18 @@ 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 t2 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 t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where
-1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where
-1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
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`.`a` > 0) and (`test`.`t4`.`a` > 0) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t8`.`a` >= 0) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`a` > 0)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
+INSERT INTO t1 VALUES (-1,133,0), (-2,12,0), (-3,11,0), (-5,15,0);
CREATE INDEX idx_b ON t1(b);
CREATE INDEX idx_a ON t0(a);
EXPLAIN EXTENDED
@@ -1040,7 +1048,7 @@ ON t6.b >= 2 AND t5.b=t7.b
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
-(t1.a != 2),
+(t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -1055,17 +1063,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 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 t2 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t1 ref idx_b idx_b 5 test.t0.b 2 100.00
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where
-1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where
-1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
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`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2) and (`test`.`t1`.`a` > 0))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
FROM t0,t1
@@ -1087,7 +1095,7 @@ ON t6.b >= 2 AND t5.b=t7.b
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
-(t1.a != 2),
+(t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -1124,6 +1132,11 @@ a b
3 3
4 2
5 3
+-1 9
+-3 10
+-2 8
+-4 11
+-5 15
SELECT t3.a,t3.b
FROM t3;
a b
@@ -1196,12 +1209,12 @@ 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 t3 index c c 5 NULL 6 Using where; Using index
1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index
SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
a b c
@@ -1272,7 +1285,7 @@ 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 t3 index c c 5 NULL 0 Using where; Using index
1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index
SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
a b c
@@ -1317,8 +1330,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 +1458,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 +1491,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,11 +1742,11 @@ 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
+1 SIMPLE t3 ref package_id package_id 5 test.t2.package_id 1 Using index
SELECT COUNT(*)
FROM ((t2 JOIN t1 ON t2.package_id = t1.id)
JOIN t3 ON t3.package_id = t1.id)
@@ -1801,4 +1814,36 @@ pk a pk a pk a
7 NULL NULL NULL NULL NULL
8 9 NULL NULL NULL NULL
DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (a int NOT NULL );
+INSERT INTO t1 VALUES (9), (9);
+CREATE TABLE t2 (a int NOT NULL );
+INSERT INTO t2 VALUES (9);
+CREATE TABLE t3 (a int NOT NULL, b int);
+INSERT INTO t3 VALUES (19,9);
+CREATE TABLE t4 (b int) ;
+SELECT * FROM t1 LEFT JOIN
+((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ON t1.a=t2.a;
+a a a b b
+9 9 19 9 NULL
+9 9 19 9 NULL
+SELECT * FROM t1 LEFT JOIN
+((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ON t1.a=t2.a
+WHERE t3.a IS NULL;
+a a a b b
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN
+((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ON t1.a=t2.a
+WHERE t3.a IS NULL;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1 100.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 1 100.00 Using where; Not exists
+1 SIMPLE t4 ALL NULL NULL NULL NULL 0 0.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`b` AS `b` from `test`.`t1` left join (`test`.`t2` left join `test`.`t3` on((`test`.`t3`.`b` = `test`.`t1`.`a`)) left join `test`.`t4` on((`test`.`t4`.`b` = `test`.`t3`.`a`))) on((`test`.`t2`.`a` = `test`.`t1`.`a`)) where isnull(`test`.`t3`.`a`)
+DROP TABLE t1,t2,t3,t4;
+SET optimizer_switch=@save_optimizer_switch;
End of 5.0 tests
diff --git a/mysql-test/r/join_nested_jcl6.result b/mysql-test/r/join_nested_jcl6.result
new file mode 100644
index 00000000000..c744df9e2fe
--- /dev/null
+++ b/mysql-test/r/join_nested_jcl6.result
@@ -0,0 +1,1972 @@
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set @@optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+set @optimizer_switch_for_join_nested_test=@@optimizer_switch;
+set @join_cache_level_for_join_nested_test=@@join_cache_level;
+DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5,t6,t7,t8,t9;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch=ifnull(@optimizer_switch_for_join_nested_test,'outer_join_with_cache=off');
+set join_cache_level=@join_cache_level_for_join_nested_test;
+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 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+Warnings:
+Note 1003 select `test`.`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`) and (`test`.`t2`.`b` is not null))) 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 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using 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`) and (`test`.`t2`.`b` is not null))) 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 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+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`) and (`test`.`t2`.`b` is not null))) 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 hash_ALL NULL #hash#$hj 5 test.t7.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+Warnings:
+Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t7`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t7`.`b` is not null))) where 1
+SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM (t6, t7)
+LEFT JOIN
+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 hash_ALL NULL #hash#$hj 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
+1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t8 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+Warnings:
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
+SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t0,t1
+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 hash_ALL NULL #hash#$hj 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t8 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE 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`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+SELECT t9.a,t9.b
+FROM t9;
+a b
+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 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) where (`test`.`t1`.`a` <= 2)
+INSERT INTO t2 VALUES (-1,9,0), (-3,10,0), (-2,8,0), (-4,11,0), (-5,15,0);
+CREATE INDEX idx_b ON t2(b);
+EXPLAIN EXTENDED
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM (t3,t4)
+LEFT JOIN
+(t1,t2)
+ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
+1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t3`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`b`) and (`test`.`t2`.`a` > 0) and (`test`.`t3`.`b` is not null))) where 1
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+FROM (t3,t4)
+LEFT JOIN
+(t1,t2)
+ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0;
+a b a b a b
+4 2 1 2 3 2
+4 2 1 2 4 2
+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 AND t2.a>0,
+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 hash_ALL NULL #hash#$hj 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t8 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+Warnings:
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`a` > 0) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+INSERT INTO t4 VALUES (-3,12,0), (-4,13,0), (-1,11,0), (-3,11,0), (-5,15,0);
+INSERT INTO t5 VALUES (-3,11,0), (-2,12,0), (-3,13,0), (-4,12,0);
+CREATE INDEX idx_b ON t4(b);
+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 AND t2.a>0 AND t4.a>0,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10
+)
+ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0
+)
+ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
+(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
+(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 hash_ALL NULL #hash#$hj 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t8 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+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`.`a` > 0) and (`test`.`t4`.`a` > 0) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`a` > 0) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
+INSERT INTO t8 VALUES (-3,12,0), (-1,14,0), (-5,15,0), (-1,11,0), (-4,13,0);
+CREATE INDEX idx_b ON t8(b);
+EXPLAIN EXTENDED
+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 AND t2.a>0 AND t4.a>0,
+t5
+LEFT JOIN
+(
+(t6, t7)
+LEFT JOIN
+t8
+ON t7.b=t8.b AND t6.b < 10 AND t8.a>=0
+)
+ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0
+)
+ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
+(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
+(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 hash_ALL NULL #hash#$hj 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+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`.`a` > 0) and (`test`.`t4`.`a` > 0) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t8`.`a` >= 0) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`a` > 0) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
+INSERT INTO t1 VALUES (-1,133,0), (-2,12,0), (-3,11,0), (-5,15,0);
+CREATE INDEX idx_b ON t1(b);
+CREATE INDEX idx_a ON t0(a);
+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) AND t1.a>0,
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+Warnings:
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2) and (`test`.`t1`.`a` > 0))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
+SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
+FROM t0,t1
+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) AND t1.a>0,
+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 4 2 2 2 6 2 2 2 0 2 1 2
+1 2 3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2 1 2
+1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 1
+1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 2
+1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 1
+1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 2
+1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 1
+1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 2
+1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 1
+1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 2
+1 2 3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 1 2
+1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 1
+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
+-1 9
+-3 10
+-2 8
+-4 11
+-5 15
+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 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 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 hash_ALL NULL #hash#$hj 5 test.t1.c11 0 Using where; Using join buffer (flat, BNLH 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); Key-ordered Rowid-ordered scan
+1 SIMPLE t5 ref a a 5 test.t3.b X Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t4 ref a a 5 test.t3.b X Using index condition(BKA); Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE t4 ref a a 5 test.t3.b X Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t6 ref a a 5 test.t4.b X Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t5 ref a a 5 test.t2.b X Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t7 ref a a 5 test.t5.b X Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE t5 ref a a 5 test.t3.b X Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t4 ref a a 5 test.t5.a X Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t6 ref a a 5 test.t4.b X Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+1 SIMPLE t3 ref a a 5 test.t1.a 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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.t2.package_id 1 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;
+CREATE TABLE t1 (a int NOT NULL );
+INSERT INTO t1 VALUES (9), (9);
+CREATE TABLE t2 (a int NOT NULL );
+INSERT INTO t2 VALUES (9);
+CREATE TABLE t3 (a int NOT NULL, b int);
+INSERT INTO t3 VALUES (19,9);
+CREATE TABLE t4 (b int) ;
+SELECT * FROM t1 LEFT JOIN
+((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ON t1.a=t2.a;
+a a a b b
+9 9 19 9 NULL
+9 9 19 9 NULL
+SELECT * FROM t1 LEFT JOIN
+((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ON t1.a=t2.a
+WHERE t3.a IS NULL;
+a a a b b
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN
+((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ON t1.a=t2.a
+WHERE t3.a IS NULL;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 hash_ALL NULL #hash#$hj 4 test.t1.a 1 100.00 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t3 hash_ALL NULL #hash#$hj 5 test.t1.a 1 100.00 Using where; Not exists; Using join buffer (incremental, BNLH join)
+1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t3.a 0 0.00 Using where; Using join buffer (incremental, BNLH join)
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`b` AS `b` from `test`.`t1` left join (`test`.`t2` left join `test`.`t3` on((`test`.`t3`.`b` = `test`.`t1`.`a`)) left join `test`.`t4` on(((`test`.`t4`.`b` = `test`.`t3`.`a`) and (`test`.`t3`.`a` is not null)))) on((`test`.`t2`.`a` = `test`.`t1`.`a`)) where isnull(`test`.`t3`.`a`)
+DROP TABLE t1,t2,t3,t4;
+SET optimizer_switch=@save_optimizer_switch;
+End of 5.0 tests
+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);
+INSERT INTO t6 VALUES (-1,12,0), (-3,13,0), (-6,11,0), (-4,14,0);
+INSERT INTO t7 VALUES (-1,11,0), (-2,12,0), (-3,13,0), (-4,14,0), (-5,15,0);
+INSERT INTO t8 VALUES (-3,13,0), (-1,12,0), (-2,14,0), (-5,15,0), (-4,16,0);
+EXPLAIN
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t5
+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) AND t6.a>0 AND t7.a>0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t5 ALL NULL NULL NULL NULL 3
+1 SIMPLE t7 ref PRIMARY,b_i b_i 5 test.t5.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t6 ALL PRIMARY,b_i NULL NULL NULL 7 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t8 ref b_i b_i 5 test.t5.b 2 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+FROM t5
+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) AND t6.a>0 AND t7.a>0;
+a b a b a b a b
+2 2 1 2 2 2 1 2
+2 2 3 2 2 2 1 2
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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 2
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
+set @optimizer_switch_for_join_nested_test=NULL;
+set @join_cache_level_for_join_nested_test=NULL;
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index 12989fdb036..7bc95e78041 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -1,4 +1,7 @@
drop table if exists t0,t1,t2,t3,t4,t5;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch=ifnull(@optimizer_switch_for_join_outer_test,'outer_join_with_cache=off');
+set join_cache_level=1;
CREATE TABLE t1 (
grp int(11) default NULL,
a bigint(20) unsigned default NULL,
@@ -416,10 +419,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 +633,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 +691,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 +862,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 +878,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 +889,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);
@@ -1237,6 +1240,7 @@ Handler_read_key 5
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 6
DROP TABLE t1,t2;
CREATE TABLE t1 (c int PRIMARY KEY, e int NOT NULL);
@@ -1268,7 +1272,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;
@@ -1302,7 +1306,7 @@ 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)))
+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(0) 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
@@ -1328,14 +1332,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 +1358,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 +1376,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` <> 0) and 1))) on(1) where 1
EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1
@@ -1389,11 +1393,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` <> 0) and 1)) left join `test`.`t1` `jt1` on(1) where 1
DROP TABLE t1;
@@ -1438,7 +1442,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
@@ -1478,6 +1482,8 @@ create table t2 like t1;
insert into t2 select if(t1.a is null, 10, t1.a) from t1;
create table t3 (a int, b int, index idx(a));
insert into t3 values (1, 100), (3, 301), (4, 402), (1, 102), (1, 101);
+insert into t3 values (11, 100), (33, 301), (44, 402), (11, 102), (11, 101);
+insert into t3 values (22, 100), (53, 301), (64, 402), (22, 102), (22, 101);
analyze table t1,t2,t3;
Table Op Msg_type Msg_text
test.t1 analyze status OK
@@ -1494,6 +1500,7 @@ Handler_read_key 4
Handler_read_next 5
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
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;
@@ -1506,8 +1513,10 @@ Handler_read_key 4
Handler_read_next 5
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 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));
@@ -1620,3 +1629,197 @@ c b
3 NULL
drop table t1,t2,t3;
End of 5.2 tests
+#
+# LP bug #813447: LEFT JOIN with single-row inner table and
+# a subquery in ON expression
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (0);
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (0), (0);
+SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3);
+a
+NULL
+EXPLAIN EXTENDED
+SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on(<in_optimizer>(6,<exists>(select `test`.`t3`.`a` from `test`.`t3` where (6 = `test`.`t3`.`a`)))) where 1
+DROP TABLE t1,t2,t3;
+#
+# LP bug #817384 Wrong result with outer join + subquery in ON
+# clause +unique key
+#
+CREATE TABLE t1 ( c int NOT NULL , b char(1) NOT NULL ) ;
+INSERT INTO t1 VALUES (1,'b');
+CREATE TABLE t2 ( a int NOT NULL , b char(1) NOT NULL , PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (1,'a');
+create table t3 (c1 char(1), c2 char(2));
+insert into t3 values ('c','d');
+insert into t3 values ('c','d');
+EXPLAIN SELECT t2.b
+FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b
+FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3);
+b
+NULL
+EXPLAIN SELECT t2.b
+FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 const PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b
+FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1;
+b
+NULL
+DROP TABLE t1,t2,t3;
+#
+# LP bug #825035: second execution of PS with outer join
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+CREATE TABLE t2 (a int);
+PREPARE stmt FROM
+"SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a";
+EXECUTE stmt;
+a a
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+EXECUTE stmt;
+a a
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1,t2;
+#
+# LP bug #838633: second execution of PS with outer join
+# converted to inner join
+#
+CREATE TABLE t1 ( b int NOT NULL ) ;
+INSERT INTO t1 VALUES (9),(10);
+CREATE TABLE t2 ( b int NOT NULL, PRIMARY KEY (b)) ;
+INSERT INTO t2 VALUES
+(75),(76),(77),(78),(79),(80),(81),(82),(83),(84),(85),(86),(87),(88),(89),
+(10), (90),(91),(92),(93),(94),(95),(96),(97),(98),(99),(100);
+CREATE TABLE t3 ( a int, b int NOT NULL , PRIMARY KEY (b)) ;
+INSERT INTO t3 VALUES
+(0,6),(0,7),(0,8),(2,9),(0,10),(2,21),(0,22),(2,23),(2,24),(2,25);
+SET SESSION join_cache_level=4;
+EXPLAIN EXTENDED
+SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t3 hash_ALL PRIMARY #hash#PRIMARY 4 test.t1.b 10 10.00 Using join buffer (flat, BNLH join)
+1 SIMPLE t2 hash_index PRIMARY #hash#PRIMARY:PRIMARY 4:4 test.t1.b 27 3.70 Using join buffer (incremental, BNLH join)
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t2` join `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t1`.`b`))
+PREPARE stmt FROM
+'SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b';
+EXECUTE stmt;
+b b a b
+10 10 0 10
+EXECUTE stmt;
+b b a b
+10 10 0 10
+DEALLOCATE PREPARE stmt;
+SET SESSION join_cache_level=default;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #943543: LEFT JOIN converted to JOIN with
+# ORed IS NULL(primary key) in WHERE clause
+#
+CREATE TABLE t1 (
+a int, b int NOT NULL, pk int NOT NULL,
+PRIMARY KEY (pk), INDEX idx(b)
+);
+INSERT INTO t1 VALUES
+(NULL,1,1), (6,2,2), (5,3,3), (NULL,4,4),
+(1,9,6), (8,5,7), (NULL,8,8), (8,1,5);
+CREATE TABLE t2 (pk int PRIMARY KEY);
+INSERT INTO t2 VALUES (3), (8), (5);
+EXPLAIN EXTENDED
+SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a
+WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
+ORDER BY t1.pk;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 100.00
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index
+Warnings:
+Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where 1 order by 5
+SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a
+WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
+ORDER BY t1.pk;
+pk
+5
+EXPLAIN EXTENDED
+SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a
+WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
+ORDER BY t1.pk;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 const PRIMARY,idx PRIMARY 4 const 1 100.00
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index
+Warnings:
+Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where ((((1 between 5 and 6) and isnull(5)) or 1)) order by 5
+SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a
+WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
+ORDER BY t1.pk;
+pk
+5
+DROP TABLE t2;
+CREATE TABLE t2 (c int, d int, KEY (c));
+INSERT INTO t2 VALUES
+(3,30), (8,88), (5,50), (8,81),
+(4,40), (9,90), (7,70), (9,90),
+(13,130), (18,188), (15,150), (18,181),
+(14,140), (19,190), (17,170), (19,190);
+INSERT INTO t1 VALUES (8,5,9);
+EXPLAIN EXTENDED
+SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a
+WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5
+ORDER BY t1.b;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ref idx idx 4 const 2 100.00 Using where
+1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`b` = 5)) order by `test`.`t1`.`b`
+SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a
+WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5
+ORDER BY t1.b;
+b c d
+5 8 88
+5 8 81
+5 8 88
+5 8 81
+EXPLAIN EXTENDED
+SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a
+WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5
+ORDER BY t1.b;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ref PRIMARY,idx idx 4 const 2 100.00 Using where; Using filesort
+1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (((`test`.`t1`.`pk` between 5 and 6) and isnull(`test`.`t1`.`b`)) or (`test`.`t1`.`b` = 5))) order by `test`.`t1`.`b`
+SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a
+WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5
+ORDER BY t1.b;
+b c d
+5 8 88
+5 8 81
+5 8 88
+5 8 81
+DROP TABLE t1,t2;
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/join_outer_innodb.result b/mysql-test/r/join_outer_innodb.result
index 80505be79be..3138701fc76 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;
@@ -99,12 +99,12 @@ ON t6a.pk IS TRUE
WHERE t6b.col_int_key IS TRUE;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t6a ALL NULL NULL NULL NULL 1 Using where
-1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 1
-1 SIMPLE t3 ALL NULL NULL NULL NULL 1
-1 SIMPLE t5 ALL NULL NULL NULL NULL 1 Using where; Using join buffer
-1 SIMPLE t6b ALL NULL NULL NULL NULL 1 Using where; Using join buffer
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 1 Using join buffer (incremental, BNL join)
+1 SIMPLE t5 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t6b ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
SELECT t6a.pk, t2.pk
FROM t6 AS t6a
LEFT JOIN
@@ -145,10 +145,10 @@ ON t6a.pk IS TRUE
WHERE t6b.col_int_key IS TRUE;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t6a ALL NULL NULL NULL NULL 1 Using where
-1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer
-1 SIMPLE t4 ALL NULL NULL NULL NULL 1
-1 SIMPLE t3 ALL NULL NULL NULL NULL 1
-1 SIMPLE t5 ALL NULL NULL NULL NULL 1 Using where; Using join buffer
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1
-1 SIMPLE t6b ALL NULL NULL NULL NULL 1 Using where; Using join buffer
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 1 Using join buffer (incremental, BNL join)
+1 SIMPLE t5 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t6b ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
drop table t1,t2,t3,t4,t5,t6;
diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result
new file mode 100644
index 00000000000..554e0027a9e
--- /dev/null
+++ b/mysql-test/r/join_outer_jcl6.result
@@ -0,0 +1,1843 @@
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+set @optimizer_switch_for_join_outer_test=@@optimizer_switch;
+set @join_cache_level_for_join_outer_test=@@join_cache_level;
+drop table if exists t0,t1,t2,t3,t4,t5;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch=ifnull(@optimizer_switch_for_join_outer_test,'outer_join_with_cache=off');
+set join_cache_level=@join_cache_level_for_join_outer_test;
+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); Key-ordered Rowid-ordered scan
+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 hash_ALL NULL #hash#$hj 2 test.t1.id 3 Using where; Not exists; Using join buffer (flat, BNLH 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 hash_ALL NULL #hash#$hj 2 test.t1.id 3 Using where; Using join buffer (flat, BNLH 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 hash_ALL NULL #hash#$hj 2 test.t1.id 3 Using where; Not exists; Using join buffer (flat, BNLH 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 hash_ALL NULL #hash#$hj 2 test.t1.id 3 Using where; Using join buffer (flat, BNLH 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 hash_ALL NULL #hash#$hj 4 test.t1.a1 2 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t3 hash_ALL NULL #hash#$hj 5 test.t1.a1 2 Using where; Using join buffer (incremental, BNLH 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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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_deleted 0
+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(0) 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` <> 0) and 1))) on(1) where 1
+EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1
+RIGHT JOIN t1 AS jt2
+RIGHT JOIN t1 AS jt3
+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` <> 0) and 1)) left join `test`.`t1` `jt1` on(1) where 1
+DROP TABLE t1;
+#
+# Bug#49600: outer join of two single-row tables with joining attributes
+# 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);
+insert into t3 values (11, 100), (33, 301), (44, 402), (11, 102), (11, 101);
+insert into t3 values (22, 100), (53, 301), (64, 402), (22, 102), (22, 101);
+analyze table t1,t2,t3;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+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_deleted 0
+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_deleted 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));
+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;
+
+# BUG#12567331 - INFINITE LOOP WHEN RESOLVING AN ALIASED COLUMN
+# USED IN GROUP BY
+
+CREATE TABLE t1 (
+col_varchar_1024_latin1_key varchar(1024),
+col_varchar_10_latin1 varchar(10),
+col_int int(11),
+pk int(11)
+);
+CREATE TABLE t2 (
+col_int_key int(11),
+col_int int(11),
+pk int(11)
+);
+PREPARE prep_stmt_9846 FROM '
+SELECT alias1.pk AS field1 FROM
+t1 AS alias1
+LEFT JOIN
+(
+ t2 AS alias2
+ RIGHT JOIN
+ (
+ t2 AS alias3
+ JOIN t1 AS alias4
+ ON 1
+ )
+ ON 1
+)
+ON 1
+GROUP BY field1';
+execute prep_stmt_9846;
+field1
+execute prep_stmt_9846;
+field1
+drop table t1,t2;
+#
+# Bug #11765810 58813: SERVER THREAD HANGS WHEN JOIN + WHERE + GROUP BY
+# IS EXECUTED TWICE FROM P
+#
+CREATE TABLE t1 ( a INT ) ENGINE = MYISAM;
+INSERT INTO t1 VALUES (1);
+PREPARE prep_stmt FROM '
+ SELECT 1 AS f FROM t1
+ LEFT JOIN t1 t2
+ RIGHT JOIN t1 t3
+ JOIN t1 t4
+ ON 1
+ ON 1
+ ON 1
+ GROUP BY f';
+EXECUTE prep_stmt;
+f
+1
+EXECUTE prep_stmt;
+f
+1
+DROP TABLE t1;
+End of 5.1 tests
+#
+# LP BUG#994392: Wrong result with RIGHT/LEFT JOIN and ALL subquery
+# predicate in WHERE condition.
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES(9);
+CREATE TABLE t2(b INT);
+INSERT INTO t2 VALUES(8);
+CREATE TABLE t3(c INT);
+INSERT INTO t3 VALUES(3);
+SELECT * FROM t2 RIGHT JOIN t3 ON(c = b) WHERE b < ALL(SELECT a FROM t1 WHERE a <= 7);
+b c
+NULL 3
+SELECT * FROM t3 LEFT JOIN t2 ON(c = b) WHERE b < ALL(SELECT a FROM t1 WHERE a <= 7);
+c b
+3 NULL
+SELECT * FROM t2 RIGHT JOIN t3 ON(c = b) WHERE b not in (SELECT a FROM t1 WHERE a <= 7);
+b c
+NULL 3
+SELECT * FROM t3 LEFT JOIN t2 ON(c = b) WHERE b not in (SELECT a FROM t1 WHERE a <= 7);
+c b
+3 NULL
+drop table t1,t2,t3;
+End of 5.2 tests
+#
+# LP bug #813447: LEFT JOIN with single-row inner table and
+# a subquery in ON expression
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (0);
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (0), (0);
+SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3);
+a
+NULL
+EXPLAIN EXTENDED
+SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on(<in_optimizer>(6,<exists>(select `test`.`t3`.`a` from `test`.`t3` where (6 = `test`.`t3`.`a`)))) where 1
+DROP TABLE t1,t2,t3;
+#
+# LP bug #817384 Wrong result with outer join + subquery in ON
+# clause +unique key
+#
+CREATE TABLE t1 ( c int NOT NULL , b char(1) NOT NULL ) ;
+INSERT INTO t1 VALUES (1,'b');
+CREATE TABLE t2 ( a int NOT NULL , b char(1) NOT NULL , PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (1,'a');
+create table t3 (c1 char(1), c2 char(2));
+insert into t3 values ('c','d');
+insert into t3 values ('c','d');
+EXPLAIN SELECT t2.b
+FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b
+FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3);
+b
+NULL
+EXPLAIN SELECT t2.b
+FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 const PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b
+FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1;
+b
+NULL
+DROP TABLE t1,t2,t3;
+#
+# LP bug #825035: second execution of PS with outer join
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+CREATE TABLE t2 (a int);
+PREPARE stmt FROM
+"SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a";
+EXECUTE stmt;
+a a
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+EXECUTE stmt;
+a a
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1,t2;
+#
+# LP bug #838633: second execution of PS with outer join
+# converted to inner join
+#
+CREATE TABLE t1 ( b int NOT NULL ) ;
+INSERT INTO t1 VALUES (9),(10);
+CREATE TABLE t2 ( b int NOT NULL, PRIMARY KEY (b)) ;
+INSERT INTO t2 VALUES
+(75),(76),(77),(78),(79),(80),(81),(82),(83),(84),(85),(86),(87),(88),(89),
+(10), (90),(91),(92),(93),(94),(95),(96),(97),(98),(99),(100);
+CREATE TABLE t3 ( a int, b int NOT NULL , PRIMARY KEY (b)) ;
+INSERT INTO t3 VALUES
+(0,6),(0,7),(0,8),(2,9),(0,10),(2,21),(0,22),(2,23),(2,24),(2,25);
+SET SESSION join_cache_level=4;
+EXPLAIN EXTENDED
+SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t3 hash_ALL PRIMARY #hash#PRIMARY 4 test.t1.b 10 10.00 Using join buffer (flat, BNLH join)
+1 SIMPLE t2 hash_index PRIMARY #hash#PRIMARY:PRIMARY 4:4 test.t1.b 27 3.70 Using join buffer (incremental, BNLH join)
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t2` join `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t1`.`b`))
+PREPARE stmt FROM
+'SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b';
+EXECUTE stmt;
+b b a b
+10 10 0 10
+EXECUTE stmt;
+b b a b
+10 10 0 10
+DEALLOCATE PREPARE stmt;
+SET SESSION join_cache_level=default;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #943543: LEFT JOIN converted to JOIN with
+# ORed IS NULL(primary key) in WHERE clause
+#
+CREATE TABLE t1 (
+a int, b int NOT NULL, pk int NOT NULL,
+PRIMARY KEY (pk), INDEX idx(b)
+);
+INSERT INTO t1 VALUES
+(NULL,1,1), (6,2,2), (5,3,3), (NULL,4,4),
+(1,9,6), (8,5,7), (NULL,8,8), (8,1,5);
+CREATE TABLE t2 (pk int PRIMARY KEY);
+INSERT INTO t2 VALUES (3), (8), (5);
+EXPLAIN EXTENDED
+SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a
+WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
+ORDER BY t1.pk;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 100.00
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index
+Warnings:
+Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where 1 order by 5
+SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a
+WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
+ORDER BY t1.pk;
+pk
+5
+EXPLAIN EXTENDED
+SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a
+WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
+ORDER BY t1.pk;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 const PRIMARY,idx PRIMARY 4 const 1 100.00
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index
+Warnings:
+Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where ((((1 between 5 and 6) and isnull(5)) or 1)) order by 5
+SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a
+WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
+ORDER BY t1.pk;
+pk
+5
+DROP TABLE t2;
+CREATE TABLE t2 (c int, d int, KEY (c));
+INSERT INTO t2 VALUES
+(3,30), (8,88), (5,50), (8,81),
+(4,40), (9,90), (7,70), (9,90),
+(13,130), (18,188), (15,150), (18,181),
+(14,140), (19,190), (17,170), (19,190);
+INSERT INTO t1 VALUES (8,5,9);
+EXPLAIN EXTENDED
+SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a
+WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5
+ORDER BY t1.b;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ref idx idx 4 const 2 100.00 Using where
+1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`b` = 5)) order by `test`.`t1`.`b`
+SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a
+WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5
+ORDER BY t1.b;
+b c d
+5 8 88
+5 8 81
+5 8 88
+5 8 81
+EXPLAIN EXTENDED
+SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a
+WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5
+ORDER BY t1.b;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ref PRIMARY,idx idx 4 const 2 100.00 Using where; Using filesort
+1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (((`test`.`t1`.`pk` between 5 and 6) and isnull(`test`.`t1`.`b`)) or (`test`.`t1`.`b` = 5))) order by `test`.`t1`.`b`
+SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a
+WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5
+ORDER BY t1.b;
+b c d
+5 8 88
+5 8 81
+5 8 88
+5 8 81
+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 2
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
+set @optimizer_switch_for_join_outer_test=NULL;
+set @join_cache_level_for_join_outer_test=NULL;
diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result
index fcc09a0244d..46313411e7d 100644
--- a/mysql-test/r/key.result
+++ b/mysql-test/r/key.result
@@ -598,7 +598,7 @@ VALUES
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
(SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 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
+1 PRIMARY t1_outer index NULL a 10 NULL 15 Using index
2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
SELECT 1 as RES FROM t1 AS t1_outer WHERE
(SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12;
diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result
index 9888eadcb31..4a7589c3446 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
@@ -644,7 +644,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
select i from t2 where p between 1010 and 1020;
i
1
@@ -660,7 +660,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/kill.result b/mysql-test/r/kill.result
index 8b6830d4798..fa6b90ea891 100644
--- a/mysql-test/r/kill.result
+++ b/mysql-test/r/kill.result
@@ -125,6 +125,7 @@ release_lock("lock27563")
drop table t1, t2;
drop function bug27563;
drop procedure proc27563;
+set session optimizer_search_depth=0;
PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40 WHERE a1=a2 AND a2=a3 AND a3=a4 AND a4=a5 AND a5=a6 AND a6=a7 AND a7=a8 AND a8=a9 AND a9=a10 AND a10=a11 AND a11=a12 AND a12=a13 AND a13=a14 AND a14=a15 AND a15=a16 AND a16=a17 AND a17=a18 AND a18=a19 AND a19=a20 AND a20=a21 AND a21=a22 AND a22=a23 AND a23=a24 AND a24=a25 AND a25=a26 AND a26=a27 AND a27=a28 AND a28=a29 AND a29=a30 AND a30=a31 AND a31=a32 AND a32=a33 AND a33=a34 AND a34=a35 AND a35=a36 AND a36=a37 AND a37=a38 AND a38=a39 AND a39=a40 ';
EXECUTE stmt;
#
@@ -138,4 +139,27 @@ KILL CONNECTION_ID();
# of close of the connection socket
SELECT 1;
Got one of the listed errors
+#
+# Test kill USER
+#
+grant ALL on test.* to test@localhost;
+grant ALL on test.* to test2@localhost;
+kill hard query user test2@nohost;
+affected rows: 0
+kill soft query user test@localhost;
+affected rows: 1
+kill hard query user test@localhost;
+affected rows: 1
+kill soft connection user test2;
+affected rows: 1
+kill hard connection user test@localhost;
+affected rows: 1
+revoke all privileges on test.* from test@localhost;
+revoke all privileges on test.* from test2@localhost;
+drop user test@localhost;
+drop user test2@localhost;
+select 1;
+Got one of the listed errors
+select 1;
+Got one of the listed errors
set @@global.concurrent_insert= @old_concurrent_insert;
diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result
index b3ac1a84fe6..6a2933ca1dc 100644
--- a/mysql-test/r/loaddata.result
+++ b/mysql-test/r/loaddata.result
@@ -5,8 +5,8 @@ Warnings:
Warning 1265 Data truncated for column 'a' at row 1
Warning 1265 Data truncated for column 'c' at row 1
Warning 1265 Data truncated for column 'd' at row 1
-Warning 1265 Data truncated for column 'a' at row 2
-Warning 1265 Data truncated for column 'b' at row 2
+Warning 1264 Out of range value for column 'a' at row 2
+Warning 1264 Out of range value for column 'b' at row 2
Warning 1265 Data truncated for column 'd' at row 2
load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' IGNORE 2 LINES;
SELECT * from t1;
@@ -20,7 +20,7 @@ load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated
Warnings:
Warning 1265 Data truncated for column 'c' at row 1
Warning 1265 Data truncated for column 'd' at row 1
-Warning 1265 Data truncated for column 'b' at row 2
+Warning 1264 Out of range value for column 'b' at row 2
Warning 1265 Data truncated for column 'd' at row 2
SELECT * from t1;
a b c d
diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result
index 3fc4de3da06..72f4b22b06a 100644
--- a/mysql-test/r/lock_multi.result
+++ b/mysql-test/r/lock_multi.result
@@ -1,4 +1,5 @@
drop table if exists t1,t2;
+drop DATABASE if exists mysqltest_1;
create table t1(n int);
insert into t1 values (1);
lock tables t1 write;
diff --git a/mysql-test/r/lock_multi_bug38499.result b/mysql-test/r/lock_multi_bug38499.result
index 9b3f57c8e53..6922312b298 100644
--- a/mysql-test/r/lock_multi_bug38499.result
+++ b/mysql-test/r/lock_multi_bug38499.result
@@ -2,7 +2,9 @@ SET @odl_sync_frm = @@global.sync_frm;
SET @@global.sync_frm = OFF;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1( a INT, b INT );
+CREATE TABLE t2( a INT, b INT );
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
# 1. test regular tables
# 1.1. test altering of columns that multiupdate doesn't use
# 1.1.1. normal mode
@@ -18,5 +20,5 @@ ALTER TABLE t1 ADD COLUMN a INT;
# 2.2. test altering of columns that multiupdate uses
# 2.2.1. normal mode
# 2.2.2. PS mode
-DROP TABLE t1;
+DROP TABLE t1,t2;
SET @@global.sync_frm = @odl_sync_frm;
diff --git a/mysql-test/r/log_slow.result b/mysql-test/r/log_slow.result
index b6341109556..276dc5db3a7 100644
--- a/mysql-test/r/log_slow.result
+++ b/mysql-test/r/log_slow.result
@@ -45,10 +45,10 @@ select @@log_slow_verbosity;
innodb
show fields from mysql.slow_log;
Field Type Null Key Default Extra
-start_time timestamp NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
+start_time timestamp(6) NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
user_host mediumtext NO NULL
-query_time time NO NULL
-lock_time time NO NULL
+query_time time(6) NO NULL
+lock_time time(6) NO NULL
rows_sent int(11) NO NULL
rows_examined int(11) NO NULL
db varchar(512) NO NULL
diff --git a/mysql-test/r/log_state.result b/mysql-test/r/log_state.result
index d296a64b675..597840c780e 100644
--- a/mysql-test/r/log_state.result
+++ b/mysql-test/r/log_state.result
@@ -55,7 +55,7 @@ sleep(@long_query_time + 1)
0
select * from mysql.slow_log where sql_text NOT LIKE '%slow_log%';
start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text
-TIMESTAMP USER_HOST QUERY_TIME 00:00:00 1 0 test 0 0 1 select sleep(@long_query_time + 1)
+TIMESTAMP USER_HOST QUERY_TIME 00:00:00.000000 1 0 test 0 0 1 select sleep(@long_query_time + 1)
# Switch to connection default
show global variables
where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result
index c6eaf9b6625..4b83ce31bd0 100644
--- a/mysql-test/r/log_tables.result
+++ b/mysql-test/r/log_tables.result
@@ -53,7 +53,7 @@ ERROR HY000: You can't use locks with log tables.
show create table mysql.general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
- `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
@@ -62,7 +62,7 @@ general_log CREATE TABLE `general_log` (
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'
show fields from mysql.general_log;
Field Type Null Key Default Extra
-event_time timestamp NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
+event_time timestamp(6) NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
user_host mediumtext NO NULL
thread_id int(11) NO NULL
server_id int(10) unsigned NO NULL
@@ -71,10 +71,10 @@ argument mediumtext NO NULL
show create table mysql.slow_log;
Table Create Table
slow_log CREATE TABLE `slow_log` (
- `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
- `query_time` time NOT NULL,
- `lock_time` time NOT NULL,
+ `query_time` time(6) NOT NULL,
+ `lock_time` time(6) NOT NULL,
`rows_sent` int(11) NOT NULL,
`rows_examined` int(11) NOT NULL,
`db` varchar(512) NOT NULL,
@@ -85,10 +85,10 @@ slow_log CREATE TABLE `slow_log` (
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log'
show fields from mysql.slow_log;
Field Type Null Key Default Extra
-start_time timestamp NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
+start_time timestamp(6) NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
user_host mediumtext NO NULL
-query_time time NO NULL
-lock_time time NO NULL
+query_time time(6) NO NULL
+lock_time time(6) NO NULL
rows_sent int(11) NO NULL
rows_examined int(11) NO NULL
db varchar(512) NO NULL
@@ -147,7 +147,7 @@ sleep(2)
0
select * from mysql.slow_log;
start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text
-TIMESTAMP USER_HOST QUERY_TIME 00:00:00 1 0 mysql 0 0 1 select sleep(2)
+TIMESTAMP USER_HOST QUERY_TIME 00:00:00.000000 1 0 mysql 0 0 1 select sleep(2)
set @@session.long_query_time = @saved_long_query_time;
alter table mysql.general_log engine=myisam;
ERROR HY000: You cannot 'ALTER' a log table if logging is enabled
@@ -164,7 +164,7 @@ set global slow_query_log='OFF';
show create table mysql.general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
- `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
@@ -174,10 +174,10 @@ general_log CREATE TABLE `general_log` (
show create table mysql.slow_log;
Table Create Table
slow_log CREATE TABLE `slow_log` (
- `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
- `query_time` time NOT NULL,
- `lock_time` time NOT NULL,
+ `query_time` time(6) NOT NULL,
+ `lock_time` time(6) NOT NULL,
`rows_sent` int(11) NOT NULL,
`rows_examined` int(11) NOT NULL,
`db` varchar(512) NOT NULL,
@@ -191,7 +191,7 @@ alter table mysql.slow_log engine=myisam;
show create table mysql.general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
- `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
@@ -201,10 +201,10 @@ general_log CREATE TABLE `general_log` (
show create table mysql.slow_log;
Table Create Table
slow_log CREATE TABLE `slow_log` (
- `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
- `query_time` time NOT NULL,
- `lock_time` time NOT NULL,
+ `query_time` time(6) NOT NULL,
+ `lock_time` time(6) NOT NULL,
`rows_sent` int(11) NOT NULL,
`rows_examined` int(11) NOT NULL,
`db` varchar(512) NOT NULL,
@@ -264,7 +264,7 @@ drop table mysql.slow_log;
ERROR 42S02: Unknown table 'slow_log'
use mysql;
CREATE TABLE `general_log` (
-`event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
+`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
@@ -273,11 +273,11 @@ ON UPDATE CURRENT_TIMESTAMP,
`argument` mediumtext NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log';
CREATE TABLE `slow_log` (
-`start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
+`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
-`query_time` time NOT NULL,
-`lock_time` time NOT NULL,
+`query_time` time(6) NOT NULL,
+`lock_time` time(6) NOT NULL,
`rows_sent` int(11) NOT NULL,
`rows_examined` int(11) NOT NULL,
`db` varchar(512) NOT NULL,
@@ -429,9 +429,9 @@ My own slow query sleep(2)
My own slow query 0
SELECT * FROM mysql.slow_log WHERE seq >= 2 LIMIT 3;
start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text seq
-START_TIME USER_HOST QUERY_TIME 00:00:00 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) 2
-START_TIME USER_HOST QUERY_TIME 00:00:00 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) 3
-START_TIME USER_HOST QUERY_TIME 00:00:00 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) 4
+START_TIME USER_HOST QUERY_TIME 00:00:00.000000 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) 2
+START_TIME USER_HOST QUERY_TIME 00:00:00.000000 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) 3
+START_TIME USER_HOST QUERY_TIME 00:00:00.000000 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) 4
SET GLOBAL slow_query_log = 0;
SET SESSION long_query_time =@saved_long_query_time;
FLUSH LOGS;
@@ -525,10 +525,10 @@ DROP PROCEDURE IF EXISTS `db_17876.archiveGeneralLog`;
DROP DATABASE IF EXISTS `db_17876`;
CREATE DATABASE db_17876;
CREATE TABLE `db_17876.slow_log_data` (
-`start_time` timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+`start_time` timestamp(6) default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`user_host` mediumtext ,
-`query_time` time ,
-`lock_time` time ,
+`query_time` time(6) ,
+`lock_time` time(6) ,
`rows_sent` int(11) ,
`rows_examined` int(11) ,
`db` varchar(512) default NULL,
@@ -538,7 +538,7 @@ CREATE TABLE `db_17876.slow_log_data` (
`sql_text` mediumtext
);
CREATE TABLE `db_17876.general_log_data` (
-`event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext,
`thread_id` int(11) DEFAULT NULL,
`server_id` int(11) DEFAULT NULL,
@@ -547,7 +547,7 @@ CREATE TABLE `db_17876.general_log_data` (
);
CREATE procedure `db_17876.archiveSlowLog`()
BEGIN
-DECLARE start_time, query_time, lock_time CHAR(20);
+DECLARE start_time, query_time, lock_time CHAR(28);
DECLARE user_host MEDIUMTEXT;
DECLARE rows_set, rows_examined, last_insert_id, insert_id, server_id INT;
DECLARE dbname MEDIUMTEXT;
@@ -580,7 +580,7 @@ TRUNCATE mysql.slow_log;
END //
CREATE procedure `db_17876.archiveGeneralLog`()
BEGIN
-DECLARE event_time CHAR(20);
+DECLARE event_time CHAR(28);
DECLARE user_host, argument MEDIUMTEXT;
DECLARE thread_id, server_id INT;
DECLARE sql_text BLOB;
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_icp.result b/mysql-test/r/maria_icp.result
new file mode 100644
index 00000000000..d6d776d6d1f
--- /dev/null
+++ b/mysql-test/r/maria_icp.result
@@ -0,0 +1,861 @@
+set @save_storage_engine= @@storage_engine;
+set storage_engine=Maria;
+set @maria_icp_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+#
+# Bug#36981 - "innodb crash when selecting for update"
+#
+CREATE TABLE t1 (
+c1 CHAR(1),
+c2 CHAR(10),
+KEY (c1)
+);
+INSERT INTO t1 VALUES ('3', null);
+SELECT * FROM t1 WHERE c1='3' FOR UPDATE;
+c1 c2
+3 NULL
+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);
+INSERT INTO t2 SELECT A.a + 10*(B.a + 10*C.a) FROM t1 A, t1 B, t1 C;
+CREATE TABLE t3 (
+c1 CHAR(10) NOT NULL,
+c2 CHAR(10) NOT NULL,
+c3 CHAR(200) NOT NULL,
+KEY (c1)
+);
+INSERT INTO t3
+SELECT CONCAT('c-',1000+t2.a,'=w'), CONCAT('c-',1000+ t2.a,'=w'), 'filler'
+ FROM t2;
+INSERT INTO t3
+SELECT CONCAT('c-',1000+t2.a,'=w'), CONCAT('c-',2000+t2.a,'=w'), 'filler-1'
+ FROM t2;
+INSERT INTO t3
+SELECT CONCAT('c-',1000+t2.a,'=w'), CONCAT('c-',3000+t2.a,'=w'), 'filler-2'
+ FROM t2;
+SELECT c1,c3 FROM t3 WHERE c1 >= 'c-1994=w' and c1 != 'c-1996=w' FOR UPDATE;
+c1 c3
+c-1994=w filler
+c-1994=w filler-1
+c-1994=w filler-2
+c-1995=w filler
+c-1995=w filler-1
+c-1995=w filler-2
+c-1997=w filler
+c-1997=w filler-1
+c-1997=w filler-2
+c-1998=w filler
+c-1998=w filler-1
+c-1998=w filler-2
+c-1999=w filler
+c-1999=w filler-1
+c-1999=w filler-2
+DROP TABLE t1,t2,t3;
+#
+# Bug#42580 - Innodb's ORDER BY ..LIMIT returns no rows for
+# null-safe operator <=> NULL
+#
+CREATE TABLE t1(
+c1 DATE NOT NULL,
+c2 DATE NULL,
+c3 DATETIME,
+c4 TIMESTAMP,
+PRIMARY KEY(c1),
+UNIQUE(c2)
+);
+
+INSERT INTO t1 VALUES('0000-00-00', '0000-00-00', '2008-01-04', '2008-01-05');
+INSERT INTO t1 VALUES('2007-05-25', '2007-05-25', '2007-05-26', '2007-05-26');
+INSERT INTO t1 VALUES('2008-01-01', NULL , '2008-01-02', '2008-01-03');
+INSERT INTO t1 VALUES('2008-01-17', NULL , NULL , '2009-01-29');
+INSERT INTO t1 VALUES('2009-01-29', '2009-01-29', '2009-01-29', '2009-01-29');
+
+SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c1,c2;
+c1 c2 c3 c4
+2008-01-01 NULL 2008-01-02 00:00:00 2008-01-03 00:00:00
+2008-01-17 NULL NULL 2009-01-29 00:00:00
+
+SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c1,c2 LIMIT 2;
+c1 c2 c3 c4
+2008-01-01 NULL 2008-01-02 00:00:00 2008-01-03 00:00:00
+2008-01-17 NULL NULL 2009-01-29 00:00:00
+
+DROP TABLE t1;
+#
+# Bug#43617 - Innodb returns wrong results with timestamp's range value
+# in IN clause
+# (Note: Fixed by patch for BUG#42580)
+#
+CREATE TABLE t1(
+c1 TIMESTAMP NOT NULL,
+c2 TIMESTAMP NULL,
+c3 DATE,
+c4 DATETIME,
+PRIMARY KEY(c1),
+UNIQUE INDEX(c2)
+);
+INSERT INTO t1 VALUES
+('0000-00-00 00:00:00','0000-00-00 00:00:00','2008-01-04','2008-01-05 00:00:00'),
+('1971-01-01 00:00:01','1980-01-01 00:00:01','2009-01-01','2009-01-02 00:00:00'),
+('1999-01-01 00:00:00','1999-01-01 00:00:00', NULL, NULL),
+('2007-05-23 09:15:28','2007-05-23 09:15:28','2007-05-24','2007-05-24 09:15:28'),
+('2007-05-27 00:00:00','2007-05-25 00:00:00','2007-05-26','2007-05-26 00:00:00'),
+('2008-01-01 00:00:00', NULL, '2008-01-02','2008-01-03 00:00:00'),
+('2009-01-29 11:11:27','2009-01-29 11:11:27','2009-01-29','2009-01-29 11:11:27'),
+('2038-01-09 03:14:07','2038-01-09 03:14:07','2009-01-05','2009-01-06 00:00:00');
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 LIMIT 2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC LIMIT 2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+DROP TABLE t1;
+#
+# BUG#43618: MyISAM&Maria returns wrong results with 'between'
+# on timestamp
+#
+CREATE TABLE t1(
+ts TIMESTAMP NOT NULL,
+c char NULL,
+PRIMARY KEY(ts)
+);
+INSERT INTO t1 VALUES
+('1971-01-01','a'),
+('2007-05-25','b'),
+('2008-01-01','c'),
+('2038-01-09','d');
+
+# Execute select with invalid timestamp, desc ordering
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+ts c
+2008-01-01 00:00:00 c
+2007-05-25 00:00:00 b
+
+# Should use index condition
+EXPLAIN
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where
+
+DROP TABLE t1;
+#
+# BUG#49906: Assertion failed - Field_varstring::val_str in field.cc
+# (Note: Fixed by patch for LP BUG#625841)
+#
+CREATE TABLE t1 (
+f1 VARCHAR(1024),
+f2 VARCHAR(10),
+INDEX test_idx USING BTREE (f2,f1(5))
+);
+INSERT INTO t1 VALUES ('a','c'), ('b','d');
+SELECT f1
+FROM t1
+WHERE f2 LIKE 'd'
+ORDER BY f1;
+f1
+b
+DROP TABLE t1;
+#
+# Bug#52660 - "Perf. regr. using ICP for MyISAM on range queries on
+# an index containing TEXT"
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 SELECT A.a + 10*(B.a) FROM t1 A, t1 B;
+CREATE TABLE t3 (
+c1 TINYTEXT NOT NULL,
+i1 INT NOT NULL,
+KEY (c1(6),i1)
+);
+INSERT INTO t3 SELECT CONCAT('c-',1000+t2.a,'=w'), 1 FROM t2;
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range c1 c1 8 NULL 3 Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+c1
+c-1004=w
+c-1005=w
+c-1006=w
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range c1 c1 12 NULL 2 Using index condition; Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+c1
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 ALL c1 NULL NULL NULL 100 Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+c1
+c-1004=w
+c-1005=w
+c-1006=w
+DROP TABLE t1, t2, t3;
+#
+# Bug#40992 - InnoDB: Crash when engine_condition_pushdown is on
+#
+CREATE TABLE t (
+dummy INT PRIMARY KEY,
+a INT UNIQUE,
+b INT
+);
+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;
+#
+# Bug#35080 - Innodb crash at mem_block_get_len line 72
+#
+CREATE TABLE t1 (
+t1_autoinc INT(11) NOT NULL AUTO_INCREMENT,
+uuid VARCHAR(36) DEFAULT NULL,
+PRIMARY KEY (t1_autoinc),
+KEY k (uuid)
+);
+CREATE TABLE t2 (
+t2_autoinc INT(11) NOT NULL AUTO_INCREMENT,
+uuid VARCHAR(36) DEFAULT NULL,
+date DATETIME DEFAULT NULL,
+PRIMARY KEY (t2_autoinc),
+KEY k (uuid)
+);
+CREATE VIEW v1 AS
+SELECT t1_autoinc, uuid
+FROM t1
+WHERE (ISNULL(uuid) OR (uuid like '%-%'));
+CREATE VIEW v2 AS
+SELECT t2_autoinc, uuid, date
+FROM t2
+WHERE (ISNULL(uuid) OR (LENGTH(uuid) = 36));
+CREATE PROCEDURE delete_multi (IN uuid CHAR(36))
+DELETE v1, v2 FROM v1 INNER JOIN v2
+ON v1.uuid = v2.uuid
+WHERE v1.uuid = @uuid;
+SET @uuid = UUID();
+INSERT INTO v1 (uuid) VALUES (@uuid);
+INSERT INTO v2 (uuid, date) VALUES (@uuid, '2009-09-09');
+CALL delete_multi(@uuid);
+DROP procedure delete_multi;
+DROP table t1,t2;
+DROP view v1,v2;
+#
+# Bug#41996 - multi-table delete crashes server (InnoDB table)
+#
+CREATE TABLE t1 (
+b BIGINT,
+i INT,
+KEY (b)
+);
+INSERT INTO t1 VALUES (2, 2);
+DELETE t1 FROM t1 a, t1 WHERE a.i=t1.b;
+DROP TABLE t1;
+#
+# Bug#43448 - Server crashes on multi table delete with Innodb
+#
+CREATE TABLE t1 (
+id1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+t CHAR(12)
+);
+CREATE TABLE t2 (
+id2 INT NOT NULL,
+t CHAR(12)
+);
+CREATE TABLE t3(
+id3 INT NOT NULL,
+t CHAR(12),
+INDEX(id3)
+);
+CREATE PROCEDURE insert_data ()
+BEGIN
+DECLARE i1 INT DEFAULT 20;
+DECLARE i2 INT;
+DECLARE i3 INT;
+WHILE (i1 > 0) DO
+INSERT INTO t1(t) VALUES (i1);
+SET i2 = 2;
+WHILE (i2 > 0) DO
+INSERT INTO t2(id2, t) VALUES (i1, i2);
+SET i3 = 2;
+WHILE (i3 > 0) DO
+INSERT INTO t3(id3, t) VALUES (i1, i2);
+SET i3 = i3 -1;
+END WHILE;
+SET i2 = i2 -1;
+END WHILE;
+SET i1 = i1 - 1;
+END WHILE;
+END |
+CALL insert_data();
+SELECT COUNT(*) FROM t1 WHERE id1 > 10;
+COUNT(*)
+10
+SELECT COUNT(*) FROM t2 WHERE id2 > 10;
+COUNT(*)
+20
+SELECT COUNT(*) FROM t3 WHERE id3 > 10;
+COUNT(*)
+40
+DELETE t1, t2, t3
+FROM t1, t2, t3
+WHERE t1.id1 = t2.id2 AND t2.id2 = t3.id3 AND t1.id1 > 3;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+3
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+6
+SELECT COUNT(*) FROM t3;
+COUNT(*)
+12
+DROP PROCEDURE insert_data;
+DROP TABLE t1, t2, t3;
+#
+# Bug#57372 "Multi-table updates and deletes fail when running with ICP
+# against InnoDB"
+#
+CREATE TABLE t1 (
+a INT KEY,
+b INT
+);
+CREATE TABLE t2 (
+a INT KEY,
+b INT
+);
+INSERT INTO t1 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105);
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+UPDATE t1, t2
+SET t1.a = t1.a + 100, t2.b = t1.a + 10
+WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b - 100;
+SELECT * FROM t1;
+a b
+1 101
+102 102
+103 103
+104 104
+5 105
+SELECT * FROM t2;
+a b
+1 1
+2 12
+3 13
+4 14
+5 5
+DROP TABLE t1, t2;
+#
+# Bug#52605 - "Adding LIMIT 1 clause to query with complex range
+# predicate causes wrong results"
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT,
+PRIMARY KEY (pk),
+KEY k1 (c1)
+);
+INSERT INTO t1 VALUES (1,NULL);
+INSERT INTO t1 VALUES (2,6);
+INSERT INTO t1 VALUES (3,NULL);
+INSERT INTO t1 VALUES (4,6);
+INSERT INTO t1 VALUES (5,NULL);
+INSERT INTO t1 VALUES (6,NULL);
+INSERT INTO t1 VALUES (7,9);
+INSERT INTO t1 VALUES (8,0);
+SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+pk c1
+4 6
+EXPLAIN SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,k1 k1 5 NULL 4 Using where
+DROP TABLE t1;
+#
+#
+# Bug#59259 "Incorrect rows returned for a correlated subquery
+# when ICP is on"
+#
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+Warnings:
+Warning 1286 Unknown table engine 'InnoDB'
+Warning 1266 Using storage engine Aria for table 't1'
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+Warnings:
+Warning 1286 Unknown table engine 'InnoDB'
+Warning 1266 Using storage engine Aria for table 't2'
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index condition
+2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using where; Using index; Using join buffer (flat, BNL join)
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+pk i
+12 5
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1, t2;
+#
+# Bug #58816 "Extra temporary duplicate rows in result set when
+# switching ICP off"
+#
+set @save_optimizer_switch= @@optimizer_switch;
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1);
+EXPLAIN SELECT pk, c1 FROM t1 WHERE pk <> 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 5 Using where
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT pk, c1 FROM t1 WHERE pk <> 3;
+pk c1
+1 9
+2 7
+4 3
+5 1
+DROP TABLE t1;
+set optimizer_switch= @save_optimizer_switch;
+#
+# Bug#58837: ICP crash or valgrind error due to uninitialized
+# value in innobase_index_cond
+#
+CREATE TABLE t1 (
+t1_int INT,
+t1_time TIME
+);
+CREATE TABLE t2 (
+t2_int int PRIMARY KEY,
+t2_int2 INT
+);
+INSERT INTO t2 VALUES ();
+INSERT INTO t1 VALUES ();
+SELECT * FROM t1 AS t1a
+WHERE NOT EXISTS (SELECT * FROM t1 AS t1b
+WHERE t1b.t1_int NOT IN
+(SELECT t2.t2_int FROM t2
+WHERE t1b.t1_time LIKE t1b.t1_int
+OR t1b.t1_time <> t2.t2_int2
+AND 6=7));
+t1_int t1_time
+DROP TABLE t1,t2;
+#
+# Bug#59186: Wrong results of join when ICP is enabled
+# (fixed by the patch for LP bug #694092)
+#
+CREATE TABLE t1 (
+pk INTEGER NOT NULL,
+c1 VARCHAR(3) NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,'y'),(0,'or');
+CREATE TABLE t2 (
+pk INTEGER NOT NULL,
+c1 VARCHAR(3) NOT NULL,
+c2 VARCHAR(6) NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (6,'y','RPOYT'),(10,'m','JINQE');
+EXPLAIN
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+(t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using join buffer (flat, BNL join)
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+(t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+c2
+DROP TABLE t1, t2;
+#
+# Bug#58838: "Wrong results with HAVING + LIMIT without GROUP BY when
+# ICP is enabled".
+# (Fixed by the patches for LP bugs #668644, #702322)
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT,
+PRIMARY KEY (pk),
+KEY col_int_key (c1)
+);
+INSERT INTO t1 VALUES (1,37),(2,8),(3,-25),(4,NULL),(5,55);
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 0;
+pk
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 1;
+pk
+3
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 2;
+pk
+3
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 5;
+pk
+3
+DROP TABLE t1;
+#
+# Bug#59483 "Crash on INSERT/REPLACE in
+# rec_convert_dtuple_to_rec_comp with ICP on"
+#
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT PRIMARY KEY,
+i1 INTEGER,
+c1 CHAR(6),
+i2 INTEGER NOT NULL,
+KEY (i2)
+);
+INSERT INTO t1 VALUES
+(NULL, 4, 'that', 8),
+(NULL, 1, 'she', 6),
+(NULL, 6, 'tell', 2);
+SELECT * FROM t1 WHERE i2 IN (3, 6) LIMIT 2 FOR UPDATE;
+pk i1 c1 i2
+2 1 she 6
+INSERT INTO t1 (i2) VALUES (1);
+DROP TABLE t1;
+#
+# Bug #11766678 - 59843:
+# USING UNINITIALISED VALUE IN USES_INDEX_FIELDS_ONLY
+#
+CREATE TABLE t1 (
+col999 FLOAT NOT NULL,
+COL1000 VARBINARY(179) NOT NULL,
+col1003 DATE DEFAULT NULL,
+KEY idx4267 (col1000, col1003)
+);
+INSERT INTO t1 VALUES (),();
+Warnings:
+Warning 1364 Field 'col999' doesn't have a default value
+Warning 1364 Field 'COL1000' doesn't have a default value
+SELECT col999 FROM t1 WHERE col1000 = "3" AND col1003 <=> sysdate();
+col999
+DROP TABLE t1;
+#
+# BUG#12822678 - ICP WITH STRAIGHT_JOIN
+#
+CREATE TABLE t1 (
+i1 INTEGER NOT NULL,
+d1 DOUBLE,
+KEY k1 (d1)
+);
+INSERT INTO t1 VALUES (10,1), (17,NULL), (22,NULL);
+CREATE TABLE t2 (
+pk INTEGER NOT NULL,
+i1 INTEGER NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (4,1);
+EXPLAIN
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL k1 9 NULL 3 Using index
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using where
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+d1 pk i1
+1 4 1
+DROP TABLE t1, t2;
+#
+# BUG#778434 Wrong result with in_to_exists=on in maria-5.3-mwl89
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0);
+CREATE TABLE t2 ( f10 int) ;
+INSERT IGNORE INTO t2 VALUES (0);
+CREATE TABLE t3 ( f1 int NOT NULL , f10 int, PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES (6,0),(10,0);
+CREATE TABLE t4 ( f11 int) ;
+INSERT IGNORE INTO t4 VALUES
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(NULL),
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+set @tmp_778434=@@optimizer_switch;
+SET optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off,semijoin=off';
+SELECT * FROM t1 INNER JOIN t2 ON t2.f10 = t1.f11
+WHERE (6, 234) IN (
+SELECT t3.f1, t3.f1
+FROM t3 JOIN t4 ON t4.f11 = t3.f10
+);
+f11 f10
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch= @tmp_778434;
+#
+# Bug#885168: ICP for one index + potential ORDER BY for another
+#
+CREATE TABLE t1 (a varchar(64), b varchar(10), INDEX(a), INDEX(b)) ;
+INSERT INTO t1 VALUES
+('Ohio','Iowa'), ('k','d'), ('bdkpj','mbdkpjdanp'), ('d','xdmbdkpjda'),
+('fkxdmbdkpjdanpje','o'), ('f','Pennsylvan'), ('Virginia','ei');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range b b 13 NULL 2 Using where; Rowid-ordered scan; Using filesort
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+a b
+d xdmbdkpjda
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range b b 13 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using filesort
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+a b
+d xdmbdkpjda
+DROP TABLE t1;
+#
+# Bug#886145: join with ICP + ORDER BY
+#
+CREATE TABLE t1 (b int NOT NULL, c int, a varchar(1024), PRIMARY KEY (b));
+INSERT INTO t1 VALUES (1,4,'Ill');
+CREATE TABLE t2 (a varchar(1024), KEY (a(512)));
+INSERT INTO t2 VALUES
+('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t2 ref a a 515 const 1 Using where
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+b c
+1 4
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t2 ref a a 515 const 1 Using where
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+b c
+1 4
+DROP TABLE t1,t2;
+#
+# Bug#879871: InnoDB: possible ICP + GROUP BY primary index
+#
+CREATE TABLE t1 (
+a int NOT NULL, b int, c varchar(1), d varchar(1),
+PRIMARY KEY (a), KEY c (c,b)
+);
+INSERT INTO t1 VALUES (10,8,'g','g');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+a
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+a
+DROP TABLE t1;
+#
+# Bug#904832: an attempt to perform an index condition pushdown
+# of a condition containing a subquery
+#
+CREATE TABLE t1 (
+a INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
+b INT, c INT, d DATE NOT NULL, e VARCHAR(1),
+KEY (c), KEY (d), KEY k2(b), KEY k3(b), KEY k4(b)
+);
+INSERT INTO t1 (b,c,d,e) VALUES
+(6,5,'2006-05-25','y'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(1,5,'2008-01-23','t'),(6,5,'2007-06-18','d'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','f'),
+(4,5,'2001-06-05','x'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(1,5,'2008-01-23','t'),(6,5,'2007-06-18','d'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(6,5,'2007-06-18','d'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(1,5,'2008-01-23','t'),(6,5,'2007-06-18','d'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,1,'1900-01-01','r'),
+(8,8,'1900-01-01','m'),(4,1,'2006-03-09','b'),
+(4,1,'2001-06-05','x'),(7,1,'2006-05-28','g');
+CREATE TABLE t2 (
+f INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
+g INT,
+h VARCHAR(1),
+KEY (g)
+);
+INSERT INTO t2 (g,h) VALUES
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(5,'l'),(8,'y'),(0,'p'),(0,'f'),(0,'p'),(7,'d'),
+(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'),
+(6,'i'),(1,'x'),(5,'l'),(8,'y'),(0,'p'),(0,'f'),
+(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(7,'d'),(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),
+(9,'u'),(6,'i'),(1,'x'),(5,'l'),(8,'y'),(0,'p'),
+(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),
+(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),(5,'l'),
+(6,'q'),(2,'n'),(4,'r'),(4,'b'),(8,'y'),(0,'p'),
+(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),
+(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),(5,'l'),
+(8,'y'),(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),
+(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),
+(1,'x'),(5,'l'),(8,'y'),(0,'p'),(0,'f'),(0,'p'),
+(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),
+(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),(7,'d'),
+(7,'f'),(5,'j'),(3,'e'),(1,'u'),(0,'f'),(0,'p'),
+(7,'d'),(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),
+(9,'u'),(6,'i'),(1,'x'),(5,'l'),(8,'y'),(0,'p'),
+(0,'f'),(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),
+(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),
+(1,'x'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),(1,'u'),
+(4,'v'),(9,'u'),(6,'i'),(1,'x'),(5,'l'),(8,'y'),
+(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(5,'l'),(6,'q'),(2,'n'),(4,'r'),(4,'b'),(8,'y'),
+(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u');
+SET @save_optimize_switch=@@optimizer_switch;
+SET optimizer_switch='materialization=on';
+EXPLAIN
+SELECT COUNT(*) FROM t1 AS t, t2
+WHERE c = g
+AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b)
+OR a = 0 AND h < 'z' );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t ALL PRIMARY,c NULL NULL NULL 64 Using where
+1 PRIMARY t2 ref g g 5 test.t.c 19 Using where
+2 DEPENDENT SUBQUERY t1 index PRIMARY PRIMARY 4 NULL 64 Using where; Using index
+2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using index condition; Using where
+SELECT COUNT(*) FROM t1 AS t, t2
+WHERE c = g
+AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b)
+OR a = 0 AND h < 'z' );
+COUNT(*)
+1478
+SELECT COUNT(*) FROM t1 AS t, t2
+WHERE c = g
+AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b)
+OR a = 0 AND h < 'z' );
+COUNT(*)
+1478
+SET optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2;
+# check "Handler_pushed" status varuiables
+CREATE TABLE t1 (
+c1 CHAR(1),
+c2 CHAR(1),
+KEY (c1)
+);
+INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5');
+flush status;
+show status like "Handler_icp%";
+Variable_name Value
+Handler_icp_attempts 0
+Handler_icp_match 0
+SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ;
+c1 c2
+4 4
+show status like "Handler_icp%";
+Variable_name Value
+Handler_icp_attempts 2
+Handler_icp_match 1
+SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ;
+c1 c2
+4 4
+show status like "Handler_icp%";
+Variable_name Value
+Handler_icp_attempts 2
+Handler_icp_match 1
+DROP TABLE t1;
+create table t1 (a int,b char(5),primary key (a), key (b(1)));
+insert into t1 values ('a','b');
+Warnings:
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 1
+select 1 from t1 where a and b >= 'aa';
+1
+drop table t1;
+#
+# Bug#58015 "Assert in row_sel_field_store_in_mysql_format
+# when running innodb_mrr_icp test"
+#
+create table t1 (a char(2) charset utf8,b double, primary key (a(1)),key (b));
+insert into t1 values ('',1);
+select 1 from t1 where b <= 1 and a <> '';
+1
+drop table t1;
+set storage_engine= @save_storage_engine;
+set optimizer_switch=@maria_icp_tmp;
diff --git a/mysql-test/r/maria_mrr.result b/mysql-test/r/maria_mrr.result
new file mode 100644
index 00000000000..ff664b87bb8
--- /dev/null
+++ b/mysql-test/r/maria_mrr.result
@@ -0,0 +1,438 @@
+drop table if exists t1,t2,t3,t4;
+set @maria_mrr_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @mrr_buffer_size_save= @@mrr_buffer_size;
+set @save_storage_engine= @@storage_engine;
+set storage_engine=aria;
+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 where; Rowid-ordered scan
+select * from t4 where a IS NULL and b IS NULL and (c IS NULL or c='no-such-row1'
+ or c='no-such-row2');
+a b c filler
+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 where; Rowid-ordered scan
+select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
+a b c filler
+b-1 NULL c-1 NULL-15
+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'), (87, 442, 'z'), (98, 445, 'v'), (86, 442, 'x'),
+(97, 445, 't'), (85, 442, 'b'), (96, 445, 'l'), (84, 442, 'a'), (95, 445, 'k');
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
+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 25 Using where; Using join buffer (flat, BNL join)
+SELECT COUNT(t1.v) FROM t1, t2, t3
+WHERE t3.v = t2.v AND t3.i < t2.i AND t3.pk > 0 AND t2.pk > 0;
+COUNT(t1.v)
+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
+set join_cache_level=@save_join_cache_level;
+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 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;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 1000 bytes
+INSERT INTO t1 VALUES
+(1,'z'), (2,'abcdefjhjkl'), (3,'in'), (4,'abcdefjhjkl'), (6,'abcdefjhjkl'),
+(11,'zx'), (12,'abcdefjhjm'), (13,'jn'), (14,'abcdefjhjp'), (16,'abcdefjhjr');
+CREATE TABLE t2 (
+col_varchar_10_latin1 varchar(10) DEFAULT NULL
+) ENGINE=Aria;
+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 1003 test.table2.col_varchar_10_latin1 2 Using where
+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;
+#
+# BUG#693747: Assertion multi_range_read.cc:908: int DsMrr_impl::dsmrr_init(
+#
+set @_save_join_cache_level= @@join_cache_level;
+set @_save_join_buffer_size= @@join_buffer_size;
+set join_cache_level=8;
+set join_buffer_size=10000;
+CREATE TABLE t1 (
+f2 varchar(32) COLLATE latin1_swedish_ci,
+f3 int(11),
+f4 varchar(1024) COLLATE utf8_bin,
+f5 varchar(1024) COLLATE latin1_bin,
+KEY (f5)
+) ENGINE=Aria TRANSACTIONAL=0 ;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 1000 bytes
+# Fill the table with some data
+SELECT alias2.* , alias1.f2
+FROM
+t1 AS alias1
+LEFT JOIN t1 AS alias2 ON alias1.f2 = alias2.f5
+WHERE
+alias2.f3 < 0;
+f2 f3 f4 f5 f2
+set join_cache_level=@_save_join_cache_level;
+set join_buffer_size=@_save_join_buffer_size;
+set optimizer_switch=@maria_mrr_tmp;
+drop table t1;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index 937fa77a885..1e1e6aeaa6b 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
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/metadata.result b/mysql-test/r/metadata.result
index 2f9fb6b67f5..fdb020500ee 100644
--- a/mysql-test/r/metadata.result
+++ b/mysql-test/r/metadata.result
@@ -21,7 +21,7 @@ def test t1 t1 g g 5 4 0 Y 32768 3 63
def test t1 t1 h h 246 7 0 Y 0 4 63
def test t1 t1 i i 13 4 0 Y 32864 0 63
def test t1 t1 j j 10 10 0 Y 128 0 63
-def test t1 t1 k k 7 19 0 N 9441 0 63
+def test t1 t1 k k 7 19 0 N 9377 0 63
def test t1 t1 l l 12 19 0 Y 128 0 63
def test t1 t1 m m 254 1 0 Y 256 0 8
def test t1 t1 n n 254 3 0 Y 2048 0 8
@@ -205,8 +205,14 @@ CREATE TABLE t1 (f1 INT);
CREATE VIEW v1 AS SELECT f1 FROM t1;
SELECT f1 FROM v1 va;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
-def test v1 va f1 f1 3 11 0 Y 32768 0 63
+def test va va f1 f1 3 11 0 Y 32768 0 63
f1
DROP VIEW v1;
DROP TABLE t1;
End of 5.0 tests
+select cast('01:01:01' as time), cast('01:01:01' as time(2));
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def cast('01:01:01' as time) 11 10 8 Y 128 0 63
+def cast('01:01:01' as time(2)) 11 13 11 Y 128 2 63
+cast('01:01:01' as time) cast('01:01:01' as time(2))
+01:01:01 01:01:01.00
diff --git a/mysql-test/r/mix2_myisam.result b/mysql-test/r/mix2_myisam.result
index e0a3d1af089..29a8ef7abe8 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
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
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/mrr_icp_extra.result b/mysql-test/r/mrr_icp_extra.result
new file mode 100644
index 00000000000..bf45702fcc0
--- /dev/null
+++ b/mysql-test/r/mrr_icp_extra.result
@@ -0,0 +1,892 @@
+set @mrr_icp_extra_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+SET NAMES latin1;
+CREATE TABLE t1
+(s1 char(10) COLLATE latin1_german1_ci,
+s2 char(10) COLLATE latin1_swedish_ci,
+KEY(s1),
+KEY(s2));
+INSERT INTO t1 VALUES ('a','a');
+INSERT INTO t1 VALUES ('b','b');
+INSERT INTO t1 VALUES ('c','c');
+INSERT INTO t1 VALUES ('d','d');
+INSERT INTO t1 VALUES ('e','e');
+INSERT INTO t1 VALUES ('f','f');
+INSERT INTO t1 VALUES ('g','g');
+INSERT INTO t1 VALUES ('h','h');
+INSERT INTO t1 VALUES ('i','i');
+INSERT INTO t1 VALUES ('j','j');
+EXPLAIN SELECT * FROM t1 WHERE s1='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref s1 s1 11 const 1 Using index condition
+EXPLAIN SELECT * FROM t1 WHERE s2='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref s2 s2 11 const 1 Using index condition
+EXPLAIN SELECT * FROM t1 WHERE s1='a' COLLATE latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref s1 s1 11 const 1 Using index condition
+EXPLAIN SELECT * FROM t1 WHERE s2='a' COLLATE latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
+EXPLAIN SELECT * FROM t1 WHERE s1 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range s1 s1 11 NULL 2 Using index condition; Rowid-ordered scan
+EXPLAIN SELECT * FROM t1 WHERE s2 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
+EXPLAIN SELECT * FROM t1 WHERE s1 IN ('a','b' COLLATE latin1_german1_ci);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range s1 s1 11 NULL 2 Using index condition; Rowid-ordered scan
+EXPLAIN SELECT * FROM t1 WHERE s2 IN ('a','b' COLLATE latin1_german1_ci);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
+EXPLAIN SELECT * FROM t1 WHERE s1 LIKE 'a' COLLATE latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range s1 s1 11 NULL 1 Using index condition; Rowid-ordered scan
+EXPLAIN SELECT * FROM t1 WHERE s2 LIKE 'a' COLLATE latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
+DROP TABLE t1;
+#
+#
+CREATE TABLE t2 (a varchar(32), b int(11), c float, d double,
+UNIQUE KEY a (a,b,c), KEY b (b), KEY c (c));
+CREATE TABLE t1 (a varchar(32), b char(3), UNIQUE KEY a (a,b), KEY b (b));
+CREATE TABLE t3 (a varchar(32), b char(3), UNIQUE KEY a (a,b));
+INSERT INTO t3 SELECT * FROM t1;
+EXPLAIN
+SELECT d FROM t1, t2
+WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
+ORDER BY t2.c LIMIT 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT d FROM t1, t2
+WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
+ORDER BY t2.c LIMIT 1;
+d
+DROP TABLE t1,t2,t3;
+#
+#
+create table t1(a int, b int, index(b));
+insert into t1 values (2, 1), (1, 1), (4, NULL), (3, NULL), (6, 2), (5, 2);
+insert into t1 values (2, 11), (1, 11), (4, 14), (3, 14), (6, 12), (5, 12);
+explain select * from t1 where b=1 or b is null order by a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref_or_null b b 5 const 4 Using index condition; Using where; Using filesort
+select * from t1 where b=1 or b is null order by a;
+a b
+1 1
+2 1
+3 NULL
+4 NULL
+explain select * from t1 where b=2 or b is null order by a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref_or_null b b 5 const 3 Using index condition; Using where; Using filesort
+select * from t1 where b=2 or b is null order by a;
+a b
+3 NULL
+4 NULL
+5 2
+6 2
+drop table t1;
+#
+#
+CREATE TABLE t1 (
+FieldKey varchar(36) NOT NULL default '',
+LongVal bigint(20) default NULL,
+StringVal mediumtext,
+KEY FieldKey (FieldKey),
+KEY LongField (FieldKey,LongVal),
+KEY StringField (FieldKey,StringVal(32))
+);
+INSERT INTO t1 VALUES ('0',3,'0'),('0',2,'1'),('0',1,'2'),('1',2,'1'),('1',1,'3'), ('1',0,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('3',2,'1'),('3',1,'2'),('3','3','3');
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (LongField, StringField) WHERE FieldKey > '2' ORDER BY LongVal;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range FieldKey FieldKey 38 NULL 4 Using index condition; Rowid-ordered scan; Using filesort
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (FieldKey, LongField) WHERE FieldKey > '2' ORDER BY LongVal;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range StringField StringField 38 NULL 4 Using index condition; Using filesort
+SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
+FieldKey LongVal StringVal
+3 1 2
+3 2 1
+3 3 3
+DROP TABLE t1;
+#
+#
+CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
+INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
+INSERT into t2 values (1,1,1), (2,2,2);
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+explain select * from t1 force index (a) where a=0 or a=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 4 NULL 4 Using index condition; Using where; Rowid-ordered scan
+select * from t1 force index (a) where a=0 or a=2;
+a b c
+0 NULL 0
+0 NULL 1
+0 NULL 2
+0 NULL 3
+drop table t1;
+#
+#
+create table t1
+(
+pk1 int not null,
+pk2 int not null,
+key1 int not null,
+key2 int not null,
+pktail1ok int not null,
+pktail2ok int not null,
+pktail3bad int not null,
+pktail4bad int not null,
+pktail5bad int not null,
+pk2copy int not null,
+badkey int not null,
+filler1 char (200),
+filler2 char (200),
+key (key1),
+key (key2),
+/* keys with tails from CPK members */
+key (pktail1ok, pk1),
+key (pktail2ok, pk1, pk2),
+key (pktail3bad, pk2, pk1),
+key (pktail4bad, pk1, pk2copy),
+key (pktail5bad, pk1, pk2, pk2copy),
+primary key (pk1, pk2)
+);
+explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 7 Using index condition; Using where; Rowid-ordered scan
+select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
+pk1 pk2 key1 key2 pktail1ok pktail2ok pktail3bad pktail4bad pktail5bad pk2copy badkey filler1 filler2
+1 19 0 0 0 0 0 0 0 19 0 filler-data-19 filler2
+1 18 0 0 0 0 0 0 0 18 0 filler-data-18 filler2
+1 17 0 0 0 0 0 0 0 17 0 filler-data-17 filler2
+1 16 0 0 0 0 0 0 0 16 0 filler-data-16 filler2
+1 15 0 0 0 0 0 0 0 15 0 filler-data-15 filler2
+1 14 0 0 0 0 0 0 0 14 0 filler-data-14 filler2
+1 13 0 0 0 0 0 0 0 13 0 filler-data-13 filler2
+1 12 0 0 0 0 0 0 0 12 0 filler-data-12 filler2
+1 11 0 0 0 0 0 0 0 11 0 filler-data-11 filler2
+1 10 0 0 0 0 0 0 0 10 0 filler-data-10 filler2
+drop table t1;
+#
+#
+CREATE TABLE t1 (
+f1 int,
+f4 varchar(32),
+f5 int,
+PRIMARY KEY (f1),
+KEY (f4)
+);
+INSERT INTO t1 VALUES
+(5,'H',1), (9,'g',0), (527,'i',0), (528,'y',1), (529,'S',6),
+(530,'m',7), (531,'b',2), (532,'N',1), (533,'V',NULL), (534,'l',1),
+(535,'M',0), (536,'w',1), (537,'j',5), (538,'l',0), (539,'n',2),
+(540,'m',2), (541,'r',2), (542,'l',2), (543,'h',3),(544,'o',0),
+(956,'h',0), (957,'g',0), (958,'W',5), (959,'s',3), (960,'w',0),
+(961,'q',0), (962,'e',NULL), (963,'u',7), (964,'q',1), (965,'N',NULL),
+(966,'e',0), (967,'t',3), (968,'e',6), (969,'f',NULL), (970,'j',0),
+(971,'s',3), (972,'I',0), (973,'h',4), (974,'g',1), (975,'s',0),
+(976,'r',3), (977,'x',1), (978,'v',8), (979,'j',NULL), (980,'z',7),
+(981,'t',9), (982,'j',5), (983,'u',NULL), (984,'g',6), (985,'w',1),
+(986,'h',1), (987,'v',0), (988,'v',0), (989,'c',2), (990,'b',7),
+(991,'z',0), (992,'M',1), (993,'u',2), (994,'r',2), (995,'b',4),
+(996,'A',2), (997,'u',0), (998,'a',0), (999,'j',2), (1,'I',2);
+EXPLAIN
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,f4 f4 35 NULL 5 Using index condition; Using where; Rowid-ordered scan
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+f1 f4 f5
+994 r 2
+996 A 2
+998 a 0
+drop table t1;
+#
+#
+drop table if exists t1,t2,t3;
+--- Testing varchar ---
+--- Testing varchar ---
+create table t1 (v varchar(10), c char(10), t text);
+insert into t1 values('+ ', '+ ', '+ ');
+set @a=repeat(' ',20);
+insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
+Warnings:
+Note 1265 Data truncated for column 'v' at row 1
+select concat('*',v,'*',c,'*',t,'*') from t1;
+concat('*',v,'*',c,'*',t,'*')
+*+ *+*+ *
+*+ *+*+ *
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+create table t2 like t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+create table t3 select * from t1;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t1 modify c varchar(10);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` varchar(10) DEFAULT NULL,
+ `t` text
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t1 modify v char(10);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` char(10) DEFAULT NULL,
+ `c` varchar(10) DEFAULT NULL,
+ `t` text
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t1 modify t varchar(10);
+Warnings:
+Note 1265 Data truncated for column 't' at row 2
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` char(10) DEFAULT NULL,
+ `c` varchar(10) DEFAULT NULL,
+ `t` varchar(10) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select concat('*',v,'*',c,'*',t,'*') from t1;
+concat('*',v,'*',c,'*',t,'*')
+*+*+*+ *
+*+*+*+ *
+drop table t1,t2,t3;
+create table t1 (v varchar(10), c char(10), t text, key(v), key(c), key(t(10)));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `v` (`v`),
+ KEY `c` (`c`),
+ KEY `t` (`t`(10))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select count(*) from t1;
+count(*)
+270
+insert into t1 values(concat('a',char(1)),concat('a',char(1)),concat('a',char(1)));
+select count(*) from t1 where v='a';
+count(*)
+10
+select count(*) from t1 where c='a';
+count(*)
+10
+select count(*) from t1 where t='a';
+count(*)
+10
+select count(*) from t1 where v='a ';
+count(*)
+10
+select count(*) from t1 where c='a ';
+count(*)
+10
+select count(*) from t1 where t='a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+count(*)
+10
+select count(*) from t1 where v like 'a%';
+count(*)
+11
+select count(*) from t1 where c like 'a%';
+count(*)
+11
+select count(*) from t1 where t like 'a%';
+count(*)
+11
+select count(*) from t1 where v like 'a %';
+count(*)
+9
+explain select count(*) from t1 where v='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
+explain select count(*) from t1 where c='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref c c 11 const # Using where; Using index
+explain select count(*) from t1 where t='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref t t 13 const # Using where
+explain select count(*) from t1 where v like 'a%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range v v 13 NULL # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
+alter table t1 add unique(v);
+ERROR 23000: Duplicate entry '{ ' for key 'v_2'
+alter table t1 add key(v);
+select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a';
+qq
+*a*a*a*
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+explain select * from t1 where v='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v,v_2 # 13 const # Using index condition
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(c) from t1 group by v limit 10;
+v count(c)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(c) from t1 group by v limit 10;
+v count(c)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select c,count(*) from t1 group by c limit 10;
+c count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select c,count(t) from t1 group by c limit 10;
+c count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result c,count(t) from t1 group by c limit 10;
+c count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select t,count(*) from t1 group by t limit 10;
+t count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select t,count(t) from t1 group by t limit 10;
+t count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result t,count(t) from t1 group by t limit 10;
+t count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+alter table t1 modify v varchar(300), drop key v, drop key v_2, add key v (v);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(300) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `c` (`c`),
+ KEY `t` (`t`(10)),
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select count(*) from t1 where v='a';
+count(*)
+10
+select count(*) from t1 where v='a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+count(*)
+10
+select count(*) from t1 where v like 'a%';
+count(*)
+11
+select count(*) from t1 where v like 'a %';
+count(*)
+9
+explain select count(*) from t1 where v='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
+explain select count(*) from t1 where v like 'a%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range v v 303 NULL # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
+explain select * from t1 where v='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using index condition
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+alter table t1 drop key v, add key v (v(30));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(300) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `c` (`c`),
+ KEY `t` (`t`(10)),
+ KEY `v` (`v`(30))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select count(*) from t1 where v='a';
+count(*)
+10
+select count(*) from t1 where v='a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+count(*)
+10
+select count(*) from t1 where v like 'a%';
+count(*)
+11
+select count(*) from t1 where v like 'a %';
+count(*)
+9
+explain select count(*) from t1 where v='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+explain select count(*) from t1 where v like 'a%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range v v 33 NULL # Using where
+explain select count(*) from t1 where v between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+explain select * from t1 where v='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+alter table t1 modify v varchar(600), drop key v, add key v (v);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(600) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `c` (`c`),
+ KEY `t` (`t`(10)),
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+drop table t1;
+create table t1 (a char(10), unique (a));
+insert into t1 values ('a ');
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a' for key 'a'
+alter table t1 modify a varchar(10);
+insert into t1 values ('a '),('a '),('a '),('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+update t1 set a='a ' where a like 'a%';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+update t1 set a='abc ' where a like 'a ';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+update t1 set a='a ' where a like 'a %';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+update t1 set a='a ' where a like 'a ';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+drop table t1;
+create table t1 (v varchar(10), c char(10), t text, key(v(5)), key(c(5)), key(t(5)));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `v` (`v`(5)),
+ KEY `c` (`c`(5)),
+ KEY `t` (`t`(5))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (v char(10) character set utf8);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` char(10) CHARACTER SET utf8 DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (v varchar(10), c char(10)) row_format=fixed;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED
+insert into t1 values('a','a'),('a ','a ');
+select concat('*',v,'*',c,'*') from t1;
+concat('*',v,'*',c,'*')
+*a*a*
+*a *a*
+drop table t1;
+create table t1 (v varchar(65530), key(v(10)));
+insert into t1 values(repeat('a',65530));
+select length(v) from t1 where v=repeat('a',65530);
+length(v)
+65530
+drop table t1;
+create table t1(a int, b varchar(12), key ba(b, a));
+insert into t1 values (1, 'A'), (20, NULL);
+explain select * from t1 where a=20 and b is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref ba ba 20 const,const 1 Using where; Using index
+select * from t1 where a=20 and b is null;
+a b
+20 NULL
+drop table t1;
+#
+#
+drop database if exists world;
+CREATE DATABASE world;
+use world;
+CREATE TABLE Country (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL,
+PRIMARY KEY (Code),
+UNIQUE INDEX (Name)
+);
+CREATE TABLE City (
+ID int(11) NOT NULL auto_increment,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID),
+INDEX (Population),
+INDEX (Country)
+);
+CREATE TABLE CountryLanguage (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0',
+PRIMARY KEY (Country, Language),
+INDEX (Percentage)
+);
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+ID Name Country Population
+637 Mit Ghamr EGY 101801
+707 Marbella ESP 101144
+3792 Tartu EST 101246
+4032 Cambridge USA 101355
+explain
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country Population 4 NULL # Using index condition; Using where; Rowid-ordered scan
+explain
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country Country,Population 3,4 NULL # Using sort_union(Country,Population); Using where
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+ID Name Country Population
+65 Abu Dhabi ARE 398695
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+750 Paarl ZAF 105768
+2865 Pak Pattan PAK 107800
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 7000000;
+ID Name Country Population
+1024 Mumbai (Bombay) IND 10500000
+3580 Moscow RUS 8389200
+explain
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 7000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL # Using index condition; Using where; Rowid-ordered scan
+explain
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country # # NULL # Using index condition; Using where; Rowid-ordered scan
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+ID Name Country Population
+1895 Harbin CHN 4289800
+1904 Jinan CHN 2278100
+1905 Hangzhou CHN 2190500
+1914 Guiyang CHN 1465200
+1916 Hefei CHN 1369100
+1923 Jilin CHN 1040000
+1927 Hohhot CHN 916700
+1928 Handan CHN 840000
+1937 Huainan CHN 700000
+1938 Jixi CHN 683885
+1944 Jinzhou CHN 570000
+1950 Hegang CHN 520000
+explain
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country # # NULL # Using index condition; Using where; Rowid-ordered scan
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+ID Name Country Population
+1895 Harbin CHN 4289800
+1905 Hangzhou CHN 2190500
+1914 Guiyang CHN 1465200
+1916 Hefei CHN 1369100
+1927 Hohhot CHN 916700
+1928 Handan CHN 840000
+1937 Huainan CHN 700000
+1950 Hegang CHN 520000
+drop database world;
+use test;
+set @mrr_icp_extra_tmp=@@optimizer_switch;
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result
index df3d7be6714..410ce34ee65 100644
--- a/mysql-test/r/multi_update.result
+++ b/mysql-test/r/multi_update.result
@@ -655,8 +655,8 @@ UPDATE IGNORE
( SELECT ( SELECT COUNT(*) FROM t1 GROUP BY a, @v ) a FROM t2 ) x, t3
SET t3.a = 0;
Warnings:
-Error 1242 Subquery returns more than 1 row
-Error 1242 Subquery returns more than 1 row
+Warning 1242 Subquery returns more than 1 row
+Warning 1242 Subquery returns more than 1 row
DROP TABLE t1, t2, t3;
SET SESSION sql_safe_updates = DEFAULT;
#
@@ -667,7 +667,63 @@ CREATE TABLE t1 (f1 DATE);
INSERT INTO t1 VALUES('2001-01-01');
UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1;
Warnings:
-Warning 1292 Truncated incorrect datetime value: '1'
+Warning 1292 Incorrect datetime value: '1'
+CREATE view v1 as SELECT f1() FROM t1;
+UPDATE (SELECT 1 FROM t1 WHERE f1 = (select * from v1)) x, t1 SET f1 = 1;
+Warnings:
+Warning 1292 Incorrect datetime value: '1'
+DROP VIEW v1;
DROP FUNCTION f1;
DROP TABLE t1;
+#
+# MDEV-4123: Incorrect results after multi-table update or
+# assertion `!table || (!table->read_set ||
+# bitmap_is_set(table->read_set, field_index))' failure
+#
+DROP TABLE IF EXISTS t1;
+Warnings:
+Note 1051 Unknown table 't1'
+CREATE TABLE t1 (
+id int(10) unsigned NOT NULL,
+level tinyint(3) unsigned NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES (2519583,1);
+DROP TABLE IF EXISTS t2;
+Warnings:
+Note 1051 Unknown table 't2'
+CREATE TABLE t2 (
+club_id int(11) NOT NULL DEFAULT '0',
+profile_id int(11) NOT NULL DEFAULT '0',
+member_level_id int(11) NOT NULL DEFAULT '0',
+PRIMARY KEY (profile_id,club_id)
+);
+INSERT INTO t2 VALUES (2,2519583,12);
+DROP TABLE IF EXISTS t3;
+Warnings:
+Note 1051 Unknown table 't3'
+CREATE TABLE t3 (
+member_level_id int(11) unsigned NOT NULL DEFAULT '0',
+map_level int(11) unsigned NOT NULL DEFAULT '0',
+map_status int(11) unsigned NOT NULL DEFAULT '0',
+PRIMARY KEY (member_level_id)
+);
+INSERT INTO t3 VALUES (12,12,1);
+CREATE
+VIEW v1 AS
+select club_id,profile_id,
+map_level AS member_level_id,map_status AS member_status
+from (t2 tc join t3 map
+on(((tc.member_level_id = map.member_level_id) and
+(club_id = 2))));
+select level, count(*) as cnt from t1 group by level;
+level cnt
+1 1
+UPDATE t1 c LEFT JOIN v1 t ON (c.id = t.profile_id AND t.club_id = 2)
+SET c.level = IF (t.member_status IS NULL, 1, IF (t.member_status = 1, 2,3));
+select level, count(*) as cnt from t1 group by level;
+level cnt
+2 1
+drop view v1;
+drop table t1,t2,t3;
end of tests
diff --git a/mysql-test/r/myisam-big.result b/mysql-test/r/myisam-big.result
new file mode 100644
index 00000000000..95a6e91d766
--- /dev/null
+++ b/mysql-test/r/myisam-big.result
@@ -0,0 +1,40 @@
+drop table if exists t1,t2;
+create table t1 (id int, sometext varchar(100)) engine=myisam;
+insert into t1 values (1, "hello"),(2, "hello2"),(4, "hello3"),(4, "hello4");
+create table t2 like t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+select count(*) from t1;
+count(*)
+131072
+alter table t1 add index (id), add index(sometext), add index(sometext,id);
+alter table t1 disable keys;
+alter table t1 enable keys;
+drop table t1,t2;
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 938a02319f9..565a1798818 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -329,7 +329,7 @@ ALTER TABLE t1 ADD INDEX t1 (a, b, c, d, e);
ERROR 42000: Specified key was too long; max key length is 1000 bytes
DROP TABLE t1;
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
-INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+INSERT into t1 values (0,null,0), (0,null,1), (0,null,2), (0,null,3), (1,1,4);
create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
INSERT into t2 values (1,1,1), (2,2,2);
optimize table t1;
@@ -346,32 +346,56 @@ 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
+INSERT into t1 values (2,4,5), (7,8,4), (8,3,1), (9,7,2), (5,5,9);
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 b 1 b A 10 NULL NULL YES BTREE
+t1 1 c 1 c A 10 NULL NULL YES BTREE
+t1 1 a 1 a A 10 NULL NULL BTREE
+t1 1 a 2 b A 10 NULL NULL YES BTREE
+t1 1 c_2 1 c A 10 NULL NULL YES BTREE
+t1 1 c_2 2 a A 10 NULL NULL BTREE
explain select * from t1,t2 where t1.b=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL b NULL NULL NULL 2
-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
+delete from t1 where t1.a>1;
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 b 1 b A 5 NULL NULL YES BTREE
+t1 1 c 1 c A 5 NULL NULL YES BTREE
+t1 1 a 1 a A 1 NULL NULL BTREE
+t1 1 a 2 b A 5 NULL NULL YES BTREE
+t1 1 c_2 1 c A 5 NULL NULL YES BTREE
+t1 1 c_2 2 a A 5 NULL NULL BTREE
explain select * from t1,t2 force index(c) where t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 2
-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 where
explain select * from t1 where c=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref c,c_2 c 5 const 1 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 +1254,7 @@ qq
*a *a*a *
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v,v_2 # 13 const # Using 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 +1430,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v v 303 const # Using 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_icp.result b/mysql-test/r/myisam_icp.result
new file mode 100644
index 00000000000..9feafac510e
--- /dev/null
+++ b/mysql-test/r/myisam_icp.result
@@ -0,0 +1,947 @@
+set @myisam_icp_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+#
+# Bug#36981 - "innodb crash when selecting for update"
+#
+CREATE TABLE t1 (
+c1 CHAR(1),
+c2 CHAR(10),
+KEY (c1)
+);
+INSERT INTO t1 VALUES ('3', null);
+SELECT * FROM t1 WHERE c1='3' FOR UPDATE;
+c1 c2
+3 NULL
+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);
+INSERT INTO t2 SELECT A.a + 10*(B.a + 10*C.a) FROM t1 A, t1 B, t1 C;
+CREATE TABLE t3 (
+c1 CHAR(10) NOT NULL,
+c2 CHAR(10) NOT NULL,
+c3 CHAR(200) NOT NULL,
+KEY (c1)
+);
+INSERT INTO t3
+SELECT CONCAT('c-',1000+t2.a,'=w'), CONCAT('c-',1000+ t2.a,'=w'), 'filler'
+ FROM t2;
+INSERT INTO t3
+SELECT CONCAT('c-',1000+t2.a,'=w'), CONCAT('c-',2000+t2.a,'=w'), 'filler-1'
+ FROM t2;
+INSERT INTO t3
+SELECT CONCAT('c-',1000+t2.a,'=w'), CONCAT('c-',3000+t2.a,'=w'), 'filler-2'
+ FROM t2;
+SELECT c1,c3 FROM t3 WHERE c1 >= 'c-1994=w' and c1 != 'c-1996=w' FOR UPDATE;
+c1 c3
+c-1994=w filler
+c-1994=w filler-1
+c-1994=w filler-2
+c-1995=w filler
+c-1995=w filler-1
+c-1995=w filler-2
+c-1997=w filler
+c-1997=w filler-1
+c-1997=w filler-2
+c-1998=w filler
+c-1998=w filler-1
+c-1998=w filler-2
+c-1999=w filler
+c-1999=w filler-1
+c-1999=w filler-2
+DROP TABLE t1,t2,t3;
+#
+# Bug#42580 - Innodb's ORDER BY ..LIMIT returns no rows for
+# null-safe operator <=> NULL
+#
+CREATE TABLE t1(
+c1 DATE NOT NULL,
+c2 DATE NULL,
+c3 DATETIME,
+c4 TIMESTAMP,
+PRIMARY KEY(c1),
+UNIQUE(c2)
+);
+
+INSERT INTO t1 VALUES('0000-00-00', '0000-00-00', '2008-01-04', '2008-01-05');
+INSERT INTO t1 VALUES('2007-05-25', '2007-05-25', '2007-05-26', '2007-05-26');
+INSERT INTO t1 VALUES('2008-01-01', NULL , '2008-01-02', '2008-01-03');
+INSERT INTO t1 VALUES('2008-01-17', NULL , NULL , '2009-01-29');
+INSERT INTO t1 VALUES('2009-01-29', '2009-01-29', '2009-01-29', '2009-01-29');
+
+SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c1,c2;
+c1 c2 c3 c4
+2008-01-01 NULL 2008-01-02 00:00:00 2008-01-03 00:00:00
+2008-01-17 NULL NULL 2009-01-29 00:00:00
+
+SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c1,c2 LIMIT 2;
+c1 c2 c3 c4
+2008-01-01 NULL 2008-01-02 00:00:00 2008-01-03 00:00:00
+2008-01-17 NULL NULL 2009-01-29 00:00:00
+
+DROP TABLE t1;
+#
+# Bug#43617 - Innodb returns wrong results with timestamp's range value
+# in IN clause
+# (Note: Fixed by patch for BUG#42580)
+#
+CREATE TABLE t1(
+c1 TIMESTAMP NOT NULL,
+c2 TIMESTAMP NULL,
+c3 DATE,
+c4 DATETIME,
+PRIMARY KEY(c1),
+UNIQUE INDEX(c2)
+);
+INSERT INTO t1 VALUES
+('0000-00-00 00:00:00','0000-00-00 00:00:00','2008-01-04','2008-01-05 00:00:00'),
+('1971-01-01 00:00:01','1980-01-01 00:00:01','2009-01-01','2009-01-02 00:00:00'),
+('1999-01-01 00:00:00','1999-01-01 00:00:00', NULL, NULL),
+('2007-05-23 09:15:28','2007-05-23 09:15:28','2007-05-24','2007-05-24 09:15:28'),
+('2007-05-27 00:00:00','2007-05-25 00:00:00','2007-05-26','2007-05-26 00:00:00'),
+('2008-01-01 00:00:00', NULL, '2008-01-02','2008-01-03 00:00:00'),
+('2009-01-29 11:11:27','2009-01-29 11:11:27','2009-01-29','2009-01-29 11:11:27'),
+('2038-01-09 03:14:07','2038-01-09 03:14:07','2009-01-05','2009-01-06 00:00:00');
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 LIMIT 2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC LIMIT 2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+DROP TABLE t1;
+#
+# BUG#43618: MyISAM&Maria returns wrong results with 'between'
+# on timestamp
+#
+CREATE TABLE t1(
+ts TIMESTAMP NOT NULL,
+c char NULL,
+PRIMARY KEY(ts)
+);
+INSERT INTO t1 VALUES
+('1971-01-01','a'),
+('2007-05-25','b'),
+('2008-01-01','c'),
+('2038-01-09','d');
+
+# Execute select with invalid timestamp, desc ordering
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+ts c
+2008-01-01 00:00:00 c
+2007-05-25 00:00:00 b
+
+# Should use index condition
+EXPLAIN
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where
+
+DROP TABLE t1;
+#
+# BUG#49906: Assertion failed - Field_varstring::val_str in field.cc
+# (Note: Fixed by patch for LP BUG#625841)
+#
+CREATE TABLE t1 (
+f1 VARCHAR(1024),
+f2 VARCHAR(10),
+INDEX test_idx USING BTREE (f2,f1(5))
+);
+INSERT INTO t1 VALUES ('a','c'), ('b','d');
+SELECT f1
+FROM t1
+WHERE f2 LIKE 'd'
+ORDER BY f1;
+f1
+b
+DROP TABLE t1;
+#
+# Bug#52660 - "Perf. regr. using ICP for MyISAM on range queries on
+# an index containing TEXT"
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 SELECT A.a + 10*(B.a) FROM t1 A, t1 B;
+CREATE TABLE t3 (
+c1 TINYTEXT NOT NULL,
+i1 INT NOT NULL,
+KEY (c1(6),i1)
+);
+INSERT INTO t3 SELECT CONCAT('c-',1000+t2.a,'=w'), 1 FROM t2;
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range c1 c1 8 NULL 3 Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+c1
+c-1004=w
+c-1005=w
+c-1006=w
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range c1 c1 12 NULL 2 Using index condition; Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+c1
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 ALL c1 NULL NULL NULL 100 Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+c1
+c-1004=w
+c-1005=w
+c-1006=w
+DROP TABLE t1, t2, t3;
+#
+# Bug#40992 - InnoDB: Crash when engine_condition_pushdown is on
+#
+CREATE TABLE t (
+dummy INT PRIMARY KEY,
+a INT UNIQUE,
+b INT
+);
+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;
+#
+# Bug#35080 - Innodb crash at mem_block_get_len line 72
+#
+CREATE TABLE t1 (
+t1_autoinc INT(11) NOT NULL AUTO_INCREMENT,
+uuid VARCHAR(36) DEFAULT NULL,
+PRIMARY KEY (t1_autoinc),
+KEY k (uuid)
+);
+CREATE TABLE t2 (
+t2_autoinc INT(11) NOT NULL AUTO_INCREMENT,
+uuid VARCHAR(36) DEFAULT NULL,
+date DATETIME DEFAULT NULL,
+PRIMARY KEY (t2_autoinc),
+KEY k (uuid)
+);
+CREATE VIEW v1 AS
+SELECT t1_autoinc, uuid
+FROM t1
+WHERE (ISNULL(uuid) OR (uuid like '%-%'));
+CREATE VIEW v2 AS
+SELECT t2_autoinc, uuid, date
+FROM t2
+WHERE (ISNULL(uuid) OR (LENGTH(uuid) = 36));
+CREATE PROCEDURE delete_multi (IN uuid CHAR(36))
+DELETE v1, v2 FROM v1 INNER JOIN v2
+ON v1.uuid = v2.uuid
+WHERE v1.uuid = @uuid;
+SET @uuid = UUID();
+INSERT INTO v1 (uuid) VALUES (@uuid);
+INSERT INTO v2 (uuid, date) VALUES (@uuid, '2009-09-09');
+CALL delete_multi(@uuid);
+DROP procedure delete_multi;
+DROP table t1,t2;
+DROP view v1,v2;
+#
+# Bug#41996 - multi-table delete crashes server (InnoDB table)
+#
+CREATE TABLE t1 (
+b BIGINT,
+i INT,
+KEY (b)
+);
+INSERT INTO t1 VALUES (2, 2);
+DELETE t1 FROM t1 a, t1 WHERE a.i=t1.b;
+DROP TABLE t1;
+#
+# Bug#43448 - Server crashes on multi table delete with Innodb
+#
+CREATE TABLE t1 (
+id1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+t CHAR(12)
+);
+CREATE TABLE t2 (
+id2 INT NOT NULL,
+t CHAR(12)
+);
+CREATE TABLE t3(
+id3 INT NOT NULL,
+t CHAR(12),
+INDEX(id3)
+);
+CREATE PROCEDURE insert_data ()
+BEGIN
+DECLARE i1 INT DEFAULT 20;
+DECLARE i2 INT;
+DECLARE i3 INT;
+WHILE (i1 > 0) DO
+INSERT INTO t1(t) VALUES (i1);
+SET i2 = 2;
+WHILE (i2 > 0) DO
+INSERT INTO t2(id2, t) VALUES (i1, i2);
+SET i3 = 2;
+WHILE (i3 > 0) DO
+INSERT INTO t3(id3, t) VALUES (i1, i2);
+SET i3 = i3 -1;
+END WHILE;
+SET i2 = i2 -1;
+END WHILE;
+SET i1 = i1 - 1;
+END WHILE;
+END |
+CALL insert_data();
+SELECT COUNT(*) FROM t1 WHERE id1 > 10;
+COUNT(*)
+10
+SELECT COUNT(*) FROM t2 WHERE id2 > 10;
+COUNT(*)
+20
+SELECT COUNT(*) FROM t3 WHERE id3 > 10;
+COUNT(*)
+40
+DELETE t1, t2, t3
+FROM t1, t2, t3
+WHERE t1.id1 = t2.id2 AND t2.id2 = t3.id3 AND t1.id1 > 3;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+3
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+6
+SELECT COUNT(*) FROM t3;
+COUNT(*)
+12
+DROP PROCEDURE insert_data;
+DROP TABLE t1, t2, t3;
+#
+# Bug#57372 "Multi-table updates and deletes fail when running with ICP
+# against InnoDB"
+#
+CREATE TABLE t1 (
+a INT KEY,
+b INT
+);
+CREATE TABLE t2 (
+a INT KEY,
+b INT
+);
+INSERT INTO t1 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105);
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+UPDATE t1, t2
+SET t1.a = t1.a + 100, t2.b = t1.a + 10
+WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b - 100;
+SELECT * FROM t1;
+a b
+1 101
+102 102
+103 103
+104 104
+5 105
+SELECT * FROM t2;
+a b
+1 1
+2 12
+3 13
+4 14
+5 5
+DROP TABLE t1, t2;
+#
+# Bug#52605 - "Adding LIMIT 1 clause to query with complex range
+# predicate causes wrong results"
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT,
+PRIMARY KEY (pk),
+KEY k1 (c1)
+);
+INSERT INTO t1 VALUES (1,NULL);
+INSERT INTO t1 VALUES (2,6);
+INSERT INTO t1 VALUES (3,NULL);
+INSERT INTO t1 VALUES (4,6);
+INSERT INTO t1 VALUES (5,NULL);
+INSERT INTO t1 VALUES (6,NULL);
+INSERT INTO t1 VALUES (7,9);
+INSERT INTO t1 VALUES (8,0);
+SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+pk c1
+4 6
+EXPLAIN SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,k1 k1 5 NULL 4 Using where
+DROP TABLE t1;
+#
+#
+# Bug#59259 "Incorrect rows returned for a correlated subquery
+# when ICP is on"
+#
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+Warnings:
+Warning 1286 Unknown table engine 'InnoDB'
+Warning 1266 Using storage engine MyISAM for table 't1'
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+Warnings:
+Warning 1286 Unknown table engine 'InnoDB'
+Warning 1266 Using storage engine MyISAM for table 't2'
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index condition
+2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using where; Using index; Using join buffer (flat, BNL join)
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+pk i
+12 5
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1, t2;
+#
+# Bug #58816 "Extra temporary duplicate rows in result set when
+# switching ICP off"
+#
+set @save_optimizer_switch= @@optimizer_switch;
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1);
+EXPLAIN SELECT pk, c1 FROM t1 WHERE pk <> 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 5 Using where
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT pk, c1 FROM t1 WHERE pk <> 3;
+pk c1
+1 9
+2 7
+4 3
+5 1
+DROP TABLE t1;
+set optimizer_switch= @save_optimizer_switch;
+#
+# Bug#58837: ICP crash or valgrind error due to uninitialized
+# value in innobase_index_cond
+#
+CREATE TABLE t1 (
+t1_int INT,
+t1_time TIME
+);
+CREATE TABLE t2 (
+t2_int int PRIMARY KEY,
+t2_int2 INT
+);
+INSERT INTO t2 VALUES ();
+INSERT INTO t1 VALUES ();
+SELECT * FROM t1 AS t1a
+WHERE NOT EXISTS (SELECT * FROM t1 AS t1b
+WHERE t1b.t1_int NOT IN
+(SELECT t2.t2_int FROM t2
+WHERE t1b.t1_time LIKE t1b.t1_int
+OR t1b.t1_time <> t2.t2_int2
+AND 6=7));
+t1_int t1_time
+DROP TABLE t1,t2;
+#
+# Bug#59186: Wrong results of join when ICP is enabled
+# (fixed by the patch for LP bug #694092)
+#
+CREATE TABLE t1 (
+pk INTEGER NOT NULL,
+c1 VARCHAR(3) NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,'y'),(0,'or');
+CREATE TABLE t2 (
+pk INTEGER NOT NULL,
+c1 VARCHAR(3) NOT NULL,
+c2 VARCHAR(6) NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (6,'y','RPOYT'),(10,'m','JINQE');
+EXPLAIN
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+(t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using join buffer (flat, BNL join)
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+(t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+c2
+DROP TABLE t1, t2;
+#
+# Bug#58838: "Wrong results with HAVING + LIMIT without GROUP BY when
+# ICP is enabled".
+# (Fixed by the patches for LP bugs #668644, #702322)
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT,
+PRIMARY KEY (pk),
+KEY col_int_key (c1)
+);
+INSERT INTO t1 VALUES (1,37),(2,8),(3,-25),(4,NULL),(5,55);
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 0;
+pk
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 1;
+pk
+3
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 2;
+pk
+3
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 5;
+pk
+3
+DROP TABLE t1;
+#
+# Bug#59483 "Crash on INSERT/REPLACE in
+# rec_convert_dtuple_to_rec_comp with ICP on"
+#
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT PRIMARY KEY,
+i1 INTEGER,
+c1 CHAR(6),
+i2 INTEGER NOT NULL,
+KEY (i2)
+);
+INSERT INTO t1 VALUES
+(NULL, 4, 'that', 8),
+(NULL, 1, 'she', 6),
+(NULL, 6, 'tell', 2);
+SELECT * FROM t1 WHERE i2 IN (3, 6) LIMIT 2 FOR UPDATE;
+pk i1 c1 i2
+2 1 she 6
+INSERT INTO t1 (i2) VALUES (1);
+DROP TABLE t1;
+#
+# Bug #11766678 - 59843:
+# USING UNINITIALISED VALUE IN USES_INDEX_FIELDS_ONLY
+#
+CREATE TABLE t1 (
+col999 FLOAT NOT NULL,
+COL1000 VARBINARY(179) NOT NULL,
+col1003 DATE DEFAULT NULL,
+KEY idx4267 (col1000, col1003)
+);
+INSERT INTO t1 VALUES (),();
+Warnings:
+Warning 1364 Field 'col999' doesn't have a default value
+Warning 1364 Field 'COL1000' doesn't have a default value
+SELECT col999 FROM t1 WHERE col1000 = "3" AND col1003 <=> sysdate();
+col999
+DROP TABLE t1;
+#
+# BUG#12822678 - ICP WITH STRAIGHT_JOIN
+#
+CREATE TABLE t1 (
+i1 INTEGER NOT NULL,
+d1 DOUBLE,
+KEY k1 (d1)
+);
+INSERT INTO t1 VALUES (10,1), (17,NULL), (22,NULL);
+CREATE TABLE t2 (
+pk INTEGER NOT NULL,
+i1 INTEGER NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (4,1);
+EXPLAIN
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL k1 9 NULL 3 Using index
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using where
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+d1 pk i1
+1 4 1
+DROP TABLE t1, t2;
+#
+# BUG#778434 Wrong result with in_to_exists=on in maria-5.3-mwl89
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0);
+CREATE TABLE t2 ( f10 int) ;
+INSERT IGNORE INTO t2 VALUES (0);
+CREATE TABLE t3 ( f1 int NOT NULL , f10 int, PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES (6,0),(10,0);
+CREATE TABLE t4 ( f11 int) ;
+INSERT IGNORE INTO t4 VALUES
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(NULL),
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+set @tmp_778434=@@optimizer_switch;
+SET optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off,semijoin=off';
+SELECT * FROM t1 INNER JOIN t2 ON t2.f10 = t1.f11
+WHERE (6, 234) IN (
+SELECT t3.f1, t3.f1
+FROM t3 JOIN t4 ON t4.f11 = t3.f10
+);
+f11 f10
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch= @tmp_778434;
+#
+# Bug#885168: ICP for one index + potential ORDER BY for another
+#
+CREATE TABLE t1 (a varchar(64), b varchar(10), INDEX(a), INDEX(b)) ;
+INSERT INTO t1 VALUES
+('Ohio','Iowa'), ('k','d'), ('bdkpj','mbdkpjdanp'), ('d','xdmbdkpjda'),
+('fkxdmbdkpjdanpje','o'), ('f','Pennsylvan'), ('Virginia','ei');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range b b 13 NULL 2 Using where; Rowid-ordered scan; Using filesort
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+a b
+d xdmbdkpjda
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range b b 13 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using filesort
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+a b
+d xdmbdkpjda
+DROP TABLE t1;
+#
+# Bug#886145: join with ICP + ORDER BY
+#
+CREATE TABLE t1 (b int NOT NULL, c int, a varchar(1024), PRIMARY KEY (b));
+INSERT INTO t1 VALUES (1,4,'Ill');
+CREATE TABLE t2 (a varchar(1024), KEY (a(512)));
+INSERT INTO t2 VALUES
+('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t2 ref a a 515 const 1 Using where
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+b c
+1 4
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t2 ref a a 515 const 1 Using where
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+b c
+1 4
+DROP TABLE t1,t2;
+#
+# Bug#879871: InnoDB: possible ICP + GROUP BY primary index
+#
+CREATE TABLE t1 (
+a int NOT NULL, b int, c varchar(1), d varchar(1),
+PRIMARY KEY (a), KEY c (c,b)
+);
+INSERT INTO t1 VALUES (10,8,'g','g');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+a
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+a
+DROP TABLE t1;
+#
+# Bug#904832: an attempt to perform an index condition pushdown
+# of a condition containing a subquery
+#
+CREATE TABLE t1 (
+a INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
+b INT, c INT, d DATE NOT NULL, e VARCHAR(1),
+KEY (c), KEY (d), KEY k2(b), KEY k3(b), KEY k4(b)
+);
+INSERT INTO t1 (b,c,d,e) VALUES
+(6,5,'2006-05-25','y'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(1,5,'2008-01-23','t'),(6,5,'2007-06-18','d'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','f'),
+(4,5,'2001-06-05','x'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(1,5,'2008-01-23','t'),(6,5,'2007-06-18','d'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(6,5,'2007-06-18','d'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(1,5,'2008-01-23','t'),(6,5,'2007-06-18','d'),
+(4,5,'1900-01-01','r'),(8,5,'1900-01-01','m'),
+(4,5,'2006-03-09','b'),(4,5,'2001-06-05','x'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,5,'1900-01-01','r'),
+(8,5,'1900-01-01','m'),(4,5,'2006-03-09','b'),
+(4,5,'2001-06-05','x'),(1,5,'2008-01-23','t'),
+(6,5,'2007-06-18','d'),(4,1,'1900-01-01','r'),
+(8,8,'1900-01-01','m'),(4,1,'2006-03-09','b'),
+(4,1,'2001-06-05','x'),(7,1,'2006-05-28','g');
+CREATE TABLE t2 (
+f INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
+g INT,
+h VARCHAR(1),
+KEY (g)
+);
+INSERT INTO t2 (g,h) VALUES
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(5,'l'),(8,'y'),(0,'p'),(0,'f'),(0,'p'),(7,'d'),
+(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'),
+(6,'i'),(1,'x'),(5,'l'),(8,'y'),(0,'p'),(0,'f'),
+(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(7,'d'),(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),
+(9,'u'),(6,'i'),(1,'x'),(5,'l'),(8,'y'),(0,'p'),
+(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),
+(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),(5,'l'),
+(6,'q'),(2,'n'),(4,'r'),(4,'b'),(8,'y'),(0,'p'),
+(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),
+(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),(5,'l'),
+(8,'y'),(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),
+(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),
+(1,'x'),(5,'l'),(8,'y'),(0,'p'),(0,'f'),(0,'p'),
+(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),
+(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),(7,'d'),
+(7,'f'),(5,'j'),(3,'e'),(1,'u'),(0,'f'),(0,'p'),
+(7,'d'),(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),
+(9,'u'),(6,'i'),(1,'x'),(5,'l'),(8,'y'),(0,'p'),
+(0,'f'),(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),
+(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),
+(1,'x'),(7,'d'),(7,'f'),(5,'j'),(3,'e'),(1,'u'),
+(4,'v'),(9,'u'),(6,'i'),(1,'x'),(5,'l'),(8,'y'),
+(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(5,'l'),(6,'q'),(2,'n'),(4,'r'),(4,'b'),(8,'y'),
+(0,'p'),(0,'f'),(0,'p'),(7,'d'),(7,'f'),(5,'j'),
+(3,'e'),(1,'u'),(4,'v'),(9,'u'),(6,'i'),(1,'x'),
+(7,'f'),(5,'j'),(3,'e'),(1,'u'),(4,'v'),(9,'u');
+SET @save_optimize_switch=@@optimizer_switch;
+SET optimizer_switch='materialization=on';
+EXPLAIN
+SELECT COUNT(*) FROM t1 AS t, t2
+WHERE c = g
+AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b)
+OR a = 0 AND h < 'z' );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t ALL PRIMARY,c NULL NULL NULL 64 Using where
+1 PRIMARY t2 ref g g 5 test.t.c 19 Using where
+2 DEPENDENT SUBQUERY t1 index PRIMARY PRIMARY 4 NULL 64 Using where; Using index
+2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using index condition; Using where
+SELECT COUNT(*) FROM t1 AS t, t2
+WHERE c = g
+AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b)
+OR a = 0 AND h < 'z' );
+COUNT(*)
+1478
+SELECT COUNT(*) FROM t1 AS t, t2
+WHERE c = g
+AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b)
+OR a = 0 AND h < 'z' );
+COUNT(*)
+1478
+SET optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2;
+# check "Handler_pushed" status varuiables
+CREATE TABLE t1 (
+c1 CHAR(1),
+c2 CHAR(1),
+KEY (c1)
+);
+INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5');
+flush status;
+show status like "Handler_icp%";
+Variable_name Value
+Handler_icp_attempts 0
+Handler_icp_match 0
+SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ;
+c1 c2
+4 4
+show status like "Handler_icp%";
+Variable_name Value
+Handler_icp_attempts 2
+Handler_icp_match 1
+SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ;
+c1 c2
+4 4
+show status like "Handler_icp%";
+Variable_name Value
+Handler_icp_attempts 2
+Handler_icp_match 1
+DROP TABLE t1;
+create table t1 (a int,b char(5),primary key (a), key (b(1)));
+insert into t1 values ('a','b');
+Warnings:
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 1
+select 1 from t1 where a and b >= 'aa';
+1
+drop table t1;
+#
+# Bug#58015 "Assert in row_sel_field_store_in_mysql_format
+# when running innodb_mrr_icp test"
+#
+create table t1 (a char(2) charset utf8,b double, primary key (a(1)),key (b));
+insert into t1 values ('',1);
+select 1 from t1 where b <= 1 and a <> '';
+1
+drop table t1;
+drop table if exists t0, t1, t1i, t1m;
+#
+# BUG#826935 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed
+#
+CREATE TABLE t1 ( a int, b varchar(1024), c int, KEY (c), KEY (c,a)) ;
+INSERT INTO t1 VALUES
+(NULL,'x','-678428672'),
+(NULL,'ok',NULL),
+(796262400,'byluovkgwoukfxedyeffsedajyqkyhpaqqpozn', NULL),
+(7,'STQUF',146014208),
+(955711488,'WWVOR','-1515388928');
+SELECT b FROM t1 WHERE a != 1 AND c IS NULL ORDER BY 1;
+b
+byluovkgwoukfxedyeffsedajyqkyhpaqqpozn
+DROP TABLE t1;
+#
+# Bug#870046: ICP for a GROUP BY query
+#
+CREATE TABLE t1 (a int, b varchar(1), c varchar(1), INDEX idx(b));
+INSERT INTO t1 VALUES (2,'x','x'), (5,'x','y');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx idx 4 const 1 Using where; Using temporary; Using filesort
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+a MIN(c)
+5 y
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx idx 4 const 1 Using index condition; Using where; Using temporary; Using filesort
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+a MIN(c)
+5 y
+DROP TABLE t1;
+#
+# BUG#887026: Wrong result with ICP, outer join, subquery in maria-5.3-icp
+#
+CREATE TABLE t1 (c varchar(1));
+INSERT INTO t1 VALUES ('c'), ('c');
+CREATE TABLE t2 (c varchar(1), b int);
+INSERT INTO t2 VALUES ('d', NULL),('d', NULL);
+CREATE TABLE t3 (c varchar(1));
+INSERT INTO t3 VALUES ('c');
+INSERT INTO t3 VALUES ('c');
+CREATE TABLE t4 ( b int, c varchar(1), KEY (b));
+INSERT INTO t4 VALUES (7,'c');
+INSERT INTO t4 VALUES (7,'c');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+# Must be t1,t2,t3,t4, with t4 having Full-scan-on-NULL but not Using index condition
+explain
+SELECT * FROM t1 LEFT JOIN t2 ON t1.c=t2.b
+WHERE
+t2.b NOT IN (SELECT t4.b FROM t3 STRAIGHT_JOIN t4 WHERE t4.b <= 2 AND t4.c = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t4 range b b 5 NULL 1 Using index condition; Using where; Rowid-ordered scan; Using join buffer (flat, BNL join)
+SELECT * FROM t1 LEFT JOIN t2 ON t1.c=t2.b
+WHERE
+t2.b NOT IN (SELECT t4.b FROM t3 STRAIGHT_JOIN t4 WHERE t4.b <= 2 AND t4.c = t3.c);
+c c b
+c NULL NULL
+c NULL NULL
+SET optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2,t3,t4;
+#
+# BUG#1000051: Query with simple join and ORDER BY takes thousands times longer when run with 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, col int, filler char(100), key(a, col));
+insert into t1 select A.a + 10*B.a, 1234, 'filler' from t0 A, t0 B, t0 C;
+set @tmp_10000051= @@optimizer_switch;
+set optimizer_switch='mrr=off';
+# Must not use ICP:
+explain select * from t1 where a between 5 and 8 order by a desc, col desc;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 39 Using where
+set optimizer_switch= @tmp_10000051;
+# Must not use ICP:
+explain select * from t1 where a=3 and col > 500 order by a desc, col desc;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 10 NULL 10 Using where
+drop table t0, t1;
+set optimizer_switch=@myisam_icp_tmp;
diff --git a/mysql-test/r/myisam_icp_notembedded.result b/mysql-test/r/myisam_icp_notembedded.result
new file mode 100644
index 00000000000..d965cbd980d
--- /dev/null
+++ b/mysql-test/r/myisam_icp_notembedded.result
@@ -0,0 +1,19 @@
+drop table if exists t1,t2;
+set @myisam_icp_notembedded_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+#
+# BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN
+#
+CREATE TABLE t1 (
+b INT,
+c VARCHAR(1) NOT NULL,
+d DATETIME,
+KEY (c, b)
+) ENGINE=MyISAM;
+# INSERT some data
+CREATE TABLE t2 ( a INT ) ENGINE=MyISAM;
+INSERT INTO t2 VALUES
+(7),(3),(7),(3);
+# Now run a number of ICP queries while trying to kill them
+DROP TABLE t1,t2;
+set optimizer_switch=@myisam_icp_notembedded_tmp;
diff --git a/mysql-test/r/myisam_mrr.result b/mysql-test/r/myisam_mrr.result
new file mode 100644
index 00000000000..0ea75c8aebb
--- /dev/null
+++ b/mysql-test/r/myisam_mrr.result
@@ -0,0 +1,637 @@
+drop table if exists t0, t1, t2, t3;
+set @myisam_mrr_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @mrr_buffer_size_save= @@mrr_buffer_size;
+set mrr_buffer_size=79;
+Warnings:
+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 where; Rowid-ordered scan
+select * from t4 where a IS NULL and b IS NULL and (c IS NULL or c='no-such-row1'
+ or c='no-such-row2');
+a b c filler
+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 where; Rowid-ordered scan
+select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
+a b c filler
+b-1 NULL c-1 NULL-15
+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 t1 system NULL NULL NULL NULL 1 100.00
+2 SUBQUERY t2 ref int_key int_key 5 const 1 100.00 Using index condition
+Warnings:
+Note 1003 select min(1) AS `MIN(t1.pk)` from `test`.`t1` where exists(select `test`.`t2`.`pk` from `test`.`t2` where isnull(`test`.`t2`.`int_key`))
+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 index condition; 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; Rowid-ordered scan
+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; Rowid-ordered scan
+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; Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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');
+INSERT INTO t1 VALUES
+(110,8,'v','v'),(111,8,'f','f'), (112,5,'v','v'),
+(113,8,'s','s'),(114,8,'a','a'),(115,6,'p','p'),
+(116,7,'z','z'),(117,2,'a','a'),(118,5,'h','h'),
+(119,7,'h','h'),(120,2,'v','v'),(121,9,'v','v'),
+(122,142,'b','b'),(123,3,'y','y'),(124,0,'v','v'),
+(125,3,'m','m'),(126,5,'z','z'),(127,9,'n','n'),
+(128,1,'d','d'),(129,107,'a','a');
+SELECT COUNT(*)
+FROM
+t1 AS table2, t1 AS table3
+where
+table3.col_varchar_key = table2.col_varchar_key AND
+table3.col_varchar_key = table2.col_varchar_nokey AND
+table3.pk<>0;
+COUNT(*)
+200
+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 40 Using where
+1 SIMPLE table3 ref PRIMARY,col_varchar_key col_varchar_key 3 test.table2.col_varchar_key 5 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+set join_cache_level= @save_join_cache_level;
+set join_buffer_size= @save_join_buffer_size;
+drop table t1;
+#
+# BUG#730133: Wrong result with jkl = 7, BKA, ICP in maria-5.3 + compound index
+#
+set @tmp_730133_jcl= @@join_cache_level;
+set join_cache_level = 7;
+set @tmp_730133_os= @@optimizer_switch;
+set optimizer_switch= 'join_cache_hashed=off,join_cache_bka=on,index_condition_pushdown=on,optimize_join_buffer_size=on';
+CREATE TABLE t1 (f1 int, f2 int, f3 int, f4 int, f5 int, KEY (f4,f3));
+INSERT IGNORE INTO t1 VALUES ('2','9','5','0','0'),('4','7','0','0','0'),
+('6','97','190','0','0'),('7','3','6','0','0'),('11','101','186','0','0'),
+('14','194','226','0','0'),('15','148','133','0','0'),
+('16','9','6','0','0'),('17','9','3','0','0'),('18','1','8','0','0'),
+('19','1','5','0','0'),('20','5','7','0','0');
+explain
+SELECT COUNT(alias2.f2)
+FROM
+t1 STRAIGHT_JOIN
+t1 AS alias3 STRAIGHT_JOIN
+t1 AS alias2 FORCE KEY (f4)
+WHERE
+alias2.f4=alias3.f5 AND
+alias2.f3 > alias3.f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL f4 10 NULL 12 Using index
+1 SIMPLE alias3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE alias2 ref f4 f4 5 test.alias3.f5 2 Using index condition(BKA); Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+SELECT COUNT(alias2.f2)
+FROM
+t1 STRAIGHT_JOIN
+t1 AS alias3 STRAIGHT_JOIN
+t1 AS alias2 FORCE KEY (f4)
+WHERE
+alias2.f4=alias3.f5 AND
+alias2.f3 > alias3.f1;
+COUNT(alias2.f2)
+768
+set @@join_cache_level= @tmp_730133_jcl;
+set @@optimizer_switch= @tmp_730133_os;
+drop table t1;
+#
+# Test of MRR handler counters
+#
+flush status;
+show status like 'Handler_mrr%';
+Variable_name Value
+Handler_mrr_init 0
+Handler_mrr_key_refills 0
+Handler_mrr_rowid_refills 0
+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(200), key(a));
+insert into t1
+select A.a+10*B.a+100*C.a+1000*D.a, 123,'filler' from t0 A, t0 B, t0 C, t0 D;
+explain select sum(b) from t1 where a < 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 8 Using index condition; Rowid-ordered scan
+# This should show one MRR scan and no re-fills:
+flush status;
+select sum(b) from t1 where a < 10;
+sum(b)
+1230
+show status like 'handler_mrr%';
+Variable_name Value
+Handler_mrr_init 1
+Handler_mrr_key_refills 0
+Handler_mrr_rowid_refills 0
+set @mrr_buffer_size_save= @@mrr_buffer_size;
+set mrr_buffer_size=128;
+explain select sum(b) from t1 where a < 1600;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 1380 Using index condition; Rowid-ordered scan
+# This should show one MRR scan and one extra rowid sort:
+flush status;
+select sum(b) from t1 where a < 1600;
+sum(b)
+196800
+show status like 'handler_mrr%';
+Variable_name Value
+Handler_mrr_init 1
+Handler_mrr_key_refills 0
+Handler_mrr_rowid_refills 1
+set @@mrr_buffer_size= @mrr_buffer_size_save;
+#Now, let's check BKA:
+set @join_cache_level_save= @@join_cache_level;
+set @join_buffer_size_save= @@join_buffer_size;
+set join_cache_level=6;
+explain select sum(t1.b) 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 10 Using where
+1 SIMPLE t1 ref a a 5 test.t0.a 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+flush status;
+select sum(t1.b) from t0,t1 where t0.a=t1.a;
+sum(t1.b)
+1230
+show status like 'handler_mrr%';
+Variable_name Value
+Handler_mrr_init 1
+Handler_mrr_key_refills 0
+Handler_mrr_rowid_refills 0
+set join_buffer_size=10;
+explain select sum(t1.b) 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 10 Using where
+1 SIMPLE t1 ref a a 5 test.t0.a 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+flush status;
+select sum(t1.b) from t0,t1 where t0.a=t1.a;
+sum(t1.b)
+1230
+show status like 'handler_mrr%';
+Variable_name Value
+Handler_mrr_init 1or2
+Handler_mrr_key_refills 1or2
+Handler_mrr_rowid_refills 1or2
+set join_cache_level= @join_cache_level_save;
+set join_buffer_size= @join_buffer_size_save;
+drop table t0, t1;
+set optimizer_switch= @myisam_mrr_tmp;
diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result
index 6e58eed08b1..04005412758 100644
--- a/mysql-test/r/mysql.result
+++ b/mysql-test/r/mysql.result
@@ -1,4 +1,4 @@
-drop table if exists t1;
+drop table if exists t1,t2,t3;
create table t1(a int);
insert into t1 values(1);
ERROR at line 9: DELIMITER must be followed by a 'delimiter' character or string
@@ -137,6 +137,14 @@ drop table t1;
1
ERROR 1064 (42000) at line 3: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
ERROR at line 1: USE must be followed by a database name
+1 +1
+2
+1 +1
+2
+1 +1
+2
+1 +1
+2
\
\\
';
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
index 540ecd99479..043739c41dd 100644
--- a/mysql-test/r/mysqlbinlog.result
+++ b/mysql-test/r/mysqlbinlog.result
@@ -1,15 +1,17 @@
reset master;
+SET @save_binlog_size= @@global.max_binlog_size;
+SET @@global.max_binlog_size= 4096;
set timestamp=1000000000;
drop table if exists t1,t2,t3,t4,t5,t03,t04;
create table t1 (word varchar(20));
create table t2 (id int auto_increment not null primary key);
insert into t1 values ("abirvalg");
insert into t2 values ();
-load data infile '../../std_data/words.dat' into table t1;
-load data infile '../../std_data/words.dat' into table t1;
-load data infile '../../std_data/words.dat' into table t1;
-load data infile '../../std_data/words.dat' into table t1;
-load data infile '../../std_data/words.dat' into table t1;
+load data infile '../../std_data/words3.dat' into table t1;
+load data infile '../../std_data/words3.dat' into table t1;
+load data infile '../../std_data/words3.dat' into table t1;
+load data infile '../../std_data/words3.dat' into table t1;
+load data infile '../../std_data/words3.dat' into table t1;
insert into t1 values ("Alas");
flush logs;
@@ -220,7 +222,6 @@ ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
ROLLBACK/*!*/;
-use `test`/*!*/;
SET TIMESTAMP=1108844556/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
@@ -228,6 +229,7 @@ SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
+use `test`/*!*/;
SET TIMESTAMP=1108844555/*!*/;
insert t1 values (1)
/*!*/;
@@ -239,7 +241,6 @@ Warning: The option '--position' is deprecated and will be removed in a future r
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
-use `test`/*!*/;
SET TIMESTAMP=1108844556/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
@@ -247,6 +248,7 @@ SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
+use `test`/*!*/;
SET TIMESTAMP=1108844555/*!*/;
insert t1 values (1)
/*!*/;
@@ -255,6 +257,7 @@ DELIMITER ;
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
drop table t1,t2;
+SET @@global.max_binlog_size= @save_binlog_size;
flush logs;
flush logs;
select * from t5 /* must be (1),(1) */;
@@ -377,14 +380,14 @@ LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FI
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=7/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO TABLE `t1` CHARACTER SET koi8r FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`)
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` CHARACTER SET koi8r FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
drop table t1
@@ -581,7 +584,6 @@ SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
-use `test`/*!*/;
SET TIMESTAMP=1266652094/*!*/;
SavePoint mixed_cases
/*!*/;
@@ -592,11 +594,9 @@ INSERT INTO db1.t2 VALUES("in savepoint mixed_cases")
SET TIMESTAMP=1266652094/*!*/;
INSERT INTO db1.t1 VALUES(40)
/*!*/;
-use `test`/*!*/;
SET TIMESTAMP=1266652094/*!*/;
ROLLBACK TO mixed_cases
/*!*/;
-use `db1`/*!*/;
SET TIMESTAMP=1266652094/*!*/;
INSERT INTO db1.t2 VALUES("after rollback to")
/*!*/;
@@ -624,7 +624,6 @@ SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
-use `test`/*!*/;
SET TIMESTAMP=1266652094/*!*/;
SavePoint mixed_cases
/*!*/;
diff --git a/mysql-test/r/mysqldump-max.result b/mysql-test/r/mysqldump-max.result
index c300f3d7996..6722f308358 100644
--- a/mysql-test/r/mysqldump-max.result
+++ b/mysql-test/r/mysqldump-max.result
@@ -290,3 +290,60 @@ COUNT(*)
DROP VIEW v1;
DROP TABLE t1;
SET GLOBAL storage_engine=@old_engine;
+# Connection default
+SET binlog_format= mixed;
+RESET MASTER;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1,0), (2,0);
+SELECT GET_LOCK("block_queries_1", 120);
+GET_LOCK("block_queries_1", 120)
+1
+# Connection c3
+SELECT GET_LOCK("block_queries_2", 120);
+GET_LOCK("block_queries_2", 120)
+1
+# Connection c1
+SET @c= 0;
+SELECT IF(@c<1, @c:=@c+1, GET_LOCK("block_queries_1", 120)) FROM t1 ORDER BY a;
+# Connection c2
+SET binlog_format="row";
+SET @d= 10;
+UPDATE t2 SET b=IF(@d<=10, @d:=@d+1, GET_LOCK("block_queries_2", 120)) ORDER BY a;
+# Connection default
+# Make sure other queries are running (and waiting).
+SELECT RELEASE_LOCK("block_queries_1");
+RELEASE_LOCK("block_queries_1")
+1
+# Connection c3
+SELECT RELEASE_LOCK("block_queries_2");
+RELEASE_LOCK("block_queries_2")
+1
+# Connection c1
+IF(@c<1, @c:=@c+1, GET_LOCK("block_queries_1", 120))
+1
+1
+# Connection c2
+# Connection default
+SELECT * FROM t2 ORDER BY a;
+a b
+1 11
+2 1
+DROP TABLE t1;
+DROP TABLE t2;
+SHOW BINLOG EVENTS LIMIT 6,3;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 663 Query 1 731 BEGIN
+master-bin.000001 731 Query 1 828 use `test`; INSERT INTO t2 VALUES (1,0), (2,0)
+master-bin.000001 828 Xid 1 855 COMMIT /* XID */
+-- CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=855;
+SELECT * FROM t1 ORDER BY a;
+a
+1
+2
+SELECT * FROM t2 ORDER BY a;
+a b
+1 0
+2 0
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 86a41eb5e22..02251cc8c7c 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -5168,7 +5168,7 @@ Error 1146 Table 'mysql.event' doesn't exist
SHOW CREATE TABLE mysql.general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
- `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
@@ -5178,10 +5178,10 @@ general_log CREATE TABLE `general_log` (
SHOW CREATE TABLE mysql.slow_log;
Table Create Table
slow_log CREATE TABLE `slow_log` (
- `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
- `query_time` time NOT NULL,
- `lock_time` time NOT NULL,
+ `query_time` time(6) NOT NULL,
+ `lock_time` time(6) NOT NULL,
`rows_sent` int(11) NOT NULL,
`rows_examined` int(11) NOT NULL,
`db` varchar(512) NOT NULL,
diff --git a/mysql-test/r/named_pipe.result b/mysql-test/r/named_pipe.result
index 32e96fa27b7..609fb80c811 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");
@@ -1347,6 +1347,8 @@ fld1 fld1
250503 250505
250504 250505
250505 250505
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
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
@@ -1389,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
@@ -1413,15 +1415,16 @@ 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
+SET optimizer_switch=@save_optimizer_switch;
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
@@ -1429,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/negation_elimination.result b/mysql-test/r/negation_elimination.result
index 35510242bcb..aea6518b676 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
@@ -321,7 +321,7 @@ select * from t1 where not(NULL or a);
a
explain select * from t1 where not(NULL and a);
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(NULL and a);
a
0
@@ -375,6 +375,121 @@ a
13
14
15
+# XOR (Note: XOR is negated by negating one of the operands)
+# Should return 6,7
+SELECT * FROM t1 WHERE ((a > 5) XOR (a > 7));
+a
+6
+7
+# Should return 0..5,8..19
+SELECT * FROM t1 WHERE ((NOT (a > 5)) XOR (a > 7));
+a
+0
+1
+2
+3
+4
+5
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+SELECT * FROM t1 WHERE ((a > 5) XOR (NOT (a > 7)));
+a
+0
+1
+2
+3
+4
+5
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+SELECT * FROM t1 WHERE NOT ((a > 5) XOR (a > 7));
+a
+0
+1
+2
+3
+4
+5
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+# Should return 6,7
+SELECT * FROM t1 WHERE NOT ((NOT (a > 5)) XOR (a > 7));
+a
+6
+7
+SELECT * FROM t1 WHERE NOT ((a > 5) XOR (NOT (a > 7)));
+a
+6
+7
+# Should return 0..5,8..19
+SELECT * FROM t1 WHERE NOT ((NOT (a > 5)) XOR (NOT (a > 7)));
+a
+0
+1
+2
+3
+4
+5
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+# Should have empty result
+SELECT * FROM t1 WHERE (NULL XOR (a > 7));
+a
+SELECT * FROM t1 WHERE NOT (NULL XOR (a > 7));
+a
+# Should be simplified to "...WHERE (a XOR a)
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT ((NOT a) XOR (a));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index NULL a 5 NULL 21 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` xor `test`.`t1`.`a`)
+# Should be simplified to "...WHERE (a XOR a)
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT (a XOR (NOT a));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index NULL a 5 NULL 21 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` xor `test`.`t1`.`a`)
+# End XOR
delete from t1 where a > 3;
select a, not(not(a)) from t1;
a not(not(a))
diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result
index 1cdc48e6552..ac72e1e303e 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
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
drop table t1;
select cast(NULL as signed);
cast(NULL as signed)
diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result
index 58c587fe588..a21f9190069 100644
--- a/mysql-test/r/null_key.result
+++ b/mysql-test/r/null_key.result
@@ -76,13 +76,13 @@ 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));
explain select * from t1 where a is null and b = 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
+1 SIMPLE t1 ref a,b a 5 const 3 Using index condition; Using where
explain select * from t1 where a is null and b = 2 and c=0;
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
+1 SIMPLE t1 ref a,b a 5 const 3 Using index condition; Using where
explain select * from t1 where a is null and b = 7 and c=0;
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
+1 SIMPLE t1 ref a,b a 5 const 3 Using index condition; Using where
explain select * from t1 where a=2 and b = 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a,b a 5 const 1 Using where
@@ -91,25 +91,25 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 12 Using where
explain select * from t1 where (a is null or a > 0 and a < 3) and b < 5 and c=0 limit 3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a,b a 5 NULL 5 Using where
+1 SIMPLE t1 range a,b a 5 NULL 5 Using index condition; Using where
explain select * from t1 where (a is null or a = 7) and b=7 and c=0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null a,b a 5 const 4 Using where
+1 SIMPLE t1 ref_or_null a,b a 5 const 4 Using index condition; Using where
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
+1 SIMPLE t1 ref a,b a 5 const 3 Using index condition; Using where
explain select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
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
+1 SIMPLE t1 ref a,b a 5 const 3 Using index condition; Using where
explain select * from t1 where a > 1 and a < 3 limit 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 1 Using where
+1 SIMPLE t1 range a a 5 NULL 1 Using index condition
explain select * from t1 where a is null and b=7 or a > 1 and a < 3 limit 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a,b a 5 NULL 4 Using where
+1 SIMPLE t1 range a,b a 5 NULL 4 Using index condition; Using where
explain select * from t1 where a > 8 and a < 9;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 1 Using where
+1 SIMPLE t1 range a a 5 NULL 1 Using index condition
explain select * from t1 where b like "6%";
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range b b 12 NULL 1 Using where
@@ -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,7 +191,7 @@ 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 t2 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t1 ref_or_null a a 10 test.t2.a,const 4 Using where; Using index
select * from t2,t1 where t1.a=t2.a and (b= 7 or b is null);
a a b
@@ -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;
@@ -427,6 +427,7 @@ Handler_read_key 6
Handler_read_next 2
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 5
DROP TABLE t1,t2,t3,t4;
CREATE TABLE t1 (
@@ -447,3 +448,15 @@ a b a b
3 12 0 12
drop table t1, t2;
End of 5.0 tests
+#
+# BUG#727667 Wrong result with OR + NOT NULL in maria-5.3
+#
+CREATE TABLE t1 (
+f3 int(11),
+f10 varchar(1),
+KEY (f3)
+);
+INSERT INTO t1 VALUES ('9','k'),(NULL,'r');
+SELECT * FROM t1 WHERE (f3 = 83) OR (f10 = 'z' AND f3 IS NULL);
+f3 f10
+DROP TABLE t1;
diff --git a/mysql-test/r/old-mode.result b/mysql-test/r/old-mode.result
index a9815d7dab2..6e6f9965e73 100644
--- a/mysql-test/r/old-mode.result
+++ b/mysql-test/r/old-mode.result
@@ -16,3 +16,6 @@ Table Checksum
test.t1 2948697075
test.t2 2948697075
drop table t1,t2;
+SHOW PROCESSLIST;
+Id User Host db Command Time State Info
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
diff --git a/mysql-test/r/optimizer_switch.result b/mysql-test/r/optimizer_switch.result
new file mode 100644
index 00000000000..7169ee60650
--- /dev/null
+++ b/mysql-test/r/optimizer_switch.result
@@ -0,0 +1,102 @@
+#
+# 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_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch='index_merge=off,index_merge_union=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch='index_merge_union=on';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch='default,index_merge_sort_union=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch=4;
+ERROR 42000: Variable 'optimizer_switch' can't be set to the value of '4'
+set optimizer_switch=NULL;
+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_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch=default;
+select @@global.optimizer_switch;
+@@global.optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set @@global.optimizer_switch=default;
+select @@global.optimizer_switch;
+@@global.optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+#
+# Check index_merge's @@optimizer_switch flags
+#
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+
+BUG#37120 optimizer_switch allowable values not according to specification
+
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch='default,materialization=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch='default,semijoin=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch='default,loosescan=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=off,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch='default,semijoin=off,materialization=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch='default,materialization=off,semijoin=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch='default,semijoin=off,materialization=off,loosescan=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch='default,semijoin=off,loosescan=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=off,materialization=on,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch='default,materialization=off,loosescan=off';
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=off,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
+set optimizer_switch=default;
+select @@optimizer_switch;
+@@optimizer_switch
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index 88d4e729c1f..8fa1006b8fc 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -1,4 +1,5 @@
drop table if exists t1,t2,t3;
+call mtr.add_suppression("Out of sort memory; increase server sort buffer size");
CREATE TABLE t1 (
id int(6) DEFAULT '0' NOT NULL,
idservice int(5),
@@ -178,6 +179,8 @@ INSERT INTO t2 VALUES (1,50);
INSERT INTO t2 VALUES (2,25);
INSERT INTO t3 VALUES (1,'123 Park Place');
INSERT INTO t3 VALUES (2,'453 Boardwalk');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
SELECT a,b,if(b = 1,i,if(b = 2,v,''))
FROM t1
LEFT JOIN t2 USING(c)
@@ -216,6 +219,7 @@ a b if(b = 1,i,if(b = 2,v,''))
2 1 25
3 2 123 Park Place
4 2 453 Boardwalk
+SET optimizer_switch=@save_optimizer_switch;
drop table t1,t2,t3;
create table t1 (ID int not null primary key, TransactionID int not null);
insert into t1 (ID, TransactionID) values (1, 87), (2, 89), (3, 92), (4, 94), (5, 486), (6, 490), (7, 753), (9, 828), (10, 832), (11, 834), (12, 840);
@@ -514,7 +518,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 +611,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 FieldKey 38 NULL 4 Using index condition; 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 FieldKey,LongField,StringField FieldKey 38 NULL 4 Using where; Using filesort
+1 SIMPLE t1 range StringField StringField 38 NULL 4 Using index condition; Using filesort
SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
FieldKey LongVal StringVal
3 1 2
@@ -636,9 +645,10 @@ id
drop table t1;
create table t1(a int, b int, index(b));
insert into t1 values (2, 1), (1, 1), (4, NULL), (3, NULL), (6, 2), (5, 2);
+insert into t1 values (12, 11), (11, 11), (14, 3), (13, 5), (16, 12), (15, 12);
explain select * from t1 where b=1 or b is null order by a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null b b 5 const 3 Using where; Using filesort
+1 SIMPLE t1 ref_or_null b b 5 const 4 Using index condition; Using where; Using filesort
select * from t1 where b=1 or b is null order by a;
a b
1 1
@@ -647,7 +657,7 @@ a b
4 NULL
explain select * from t1 where b=2 or b is null order by a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null b b 5 const 4 Using where; Using filesort
+1 SIMPLE t1 ref_or_null b b 5 const 3 Using index condition; Using where; Using filesort
select * from t1 where b=2 or b is null order by a;
a b
3 NULL
@@ -1004,7 +1014,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 +1117,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 filesort
SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 20;
id c3
6 14
@@ -1421,14 +1431,13 @@ DROP TABLE t1;
#
create table t1(a int, b tinytext);
insert into t1 values (1,2),(3,2);
-set session sort_buffer_size= 30000;
+set session sort_buffer_size= 1000;
Warnings:
-Warning 1292 Truncated incorrect sort_buffer_size value: '30000'
+Warning 1292 Truncated incorrect sort_buffer_size value: '1000'
set session max_sort_length= 2180;
select * from t1 order by b;
ERROR HY001: Out of sort memory; increase server sort buffer size
drop table t1;
-call mtr.add_suppression("Out of sort memory; increase server sort buffer size");
#
# Bug #39844: Query Crash Mysql Server 5.0.67
#
@@ -1459,7 +1468,7 @@ INSERT INTO t1 VALUES (1, 10), (2, NULL);
EXPLAIN
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null a_c,a a_c 10 const,const 1 Using where
+1 SIMPLE t1 ref_or_null a_c,a a_c 10 const,const 2 Using where; Using index; Using filesort
# Must return 1 row
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
col
@@ -1485,8 +1494,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;
@@ -1504,6 +1513,24 @@ WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
ORDER BY t2.c LIMIT 1;
d
52.5
+SELECT t1.*,t2.* 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 5;
+a b a b c d
+ppfcz1 DE ppfcz1 14 6 52.5
+ppfcz1 DE ppfcz1 14 7 55.5
+ppfcz1 DE ppfcz1 14 8 57.5
+ppfcz1 DE ppfcz1 14 9 59.5
+ppfcz1 DE ppfcz1 14 10 61.5
+SELECT t1.*, t2.* FROM t3 AS t1, t2 AS t2
+WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
+ORDER BY t2.c LIMIT 5;
+a b a b c d
+ppfcz1 DE ppfcz1 14 6 52.5
+ppfcz1 DE ppfcz1 14 7 55.5
+ppfcz1 DE ppfcz1 14 8 57.5
+ppfcz1 DE ppfcz1 14 9 59.5
+ppfcz1 DE ppfcz1 14 10 61.5
DROP TABLE t1,t2,t3;
CREATE TABLE t1 (
id1 INT NULL,
@@ -1603,20 +1630,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 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 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 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
@@ -1640,6 +1667,36 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using where
DROP TABLE t1, t2;
#
+# Bug #707848: WHERE condition with OR + ORDER BY + field substitution
+#
+CREATE TABLE t1 (a int PRIMARY KEY);
+INSERT INTO t1 VALUES
+(9), (7), (11), (15), (2), (4), (1), (5), (14), (54), (3), (8);
+EXPLAIN EXTENDED
+SELECT * FROM t1 r JOIN t1 s ON r.a = s.a
+WHERE s.a IN (2,9) OR s.a < 100 AND s.a != 0
+ORDER BY 1 LIMIT 10;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE r index PRIMARY PRIMARY 4 NULL 10 100.00 Using where; Using index
+1 SIMPLE s eq_ref PRIMARY PRIMARY 4 test.r.a 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`r`.`a` AS `a`,`test`.`s`.`a` AS `a` from `test`.`t1` `r` join `test`.`t1` `s` where ((`test`.`s`.`a` = `test`.`r`.`a`) and ((`test`.`r`.`a` in (2,9)) or ((`test`.`r`.`a` < 100) and (`test`.`r`.`a` <> 0)))) order by 1 limit 10
+SELECT * FROM t1 r JOIN t1 s ON r.a = s.a
+WHERE s.a IN (2,9) OR s.a < 100 AND s.a != 0
+ORDER BY 1 LIMIT 10;
+a a
+1 1
+2 2
+3 3
+4 4
+5 5
+7 7
+8 8
+9 9
+11 11
+14 14
+DROP TABLE t1;
+#
# Bug #59110: Memory leak of QUICK_SELECT_I allocated memory
# and
# Bug #59308: Incorrect result for
@@ -1699,30 +1756,162 @@ b
explain extended
SELECT t2.b AS field1 FROM t1, t2 WHERE t1.b = t2.a GROUP BY field1 ORDER BY t1.b, field1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00
Warnings:
Note 1003 select `test`.`t2`.`b` AS `field1` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b`
explain extended
SELECT t2.b, t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b, t2.b;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00
Warnings:
Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t1`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b`
explain extended
SELECT t2.b,t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00
Warnings:
Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t1`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b`
explain extended
SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00
Warnings:
Note 1003 select `test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b`
drop table t1,t2;
End of 5.2 tests
+#
+# Bug mdev-449: ORDER BY with small sort_buffer_size
+#
+CREATE TABLE t1(f0 int auto_increment primary key, f1 int, f2 varchar(200));
+INSERT INTO t1(f1, f2) VALUES
+(0,"0"),(1,"1"),(2,"2"),(3,"3"),(4,"4"),(5,"5"),
+(6,"6"),(7,"7"),(8,"8"),(9,"9"),(10,"10"),
+(11,"11"),(12,"12"),(13,"13"),(14,"14"),(15,"15"),
+(16,"16"),(17,"17"),(18,"18"),(19,"19"),(20,"20"),
+(21,"21"),(22,"22"),(23,"23"),(24,"24"),(25,"25"),
+(26,"26"),(27,"27"),(28,"28"),(29,"29"),(30,"30"),
+(31,"31"),(32,"32"),(33,"33"),(34,"34"),(35,"35"),
+(36,"36"),(37,"37"),(38,"38"),(39,"39"),(40,"40"),
+(41,"41"),(42,"42"),(43,"43"),(44,"44"),(45,"45"),
+(46,"46"),(47,"47"),(48,"48"),(49,"49"),(50,"50"),
+(51,"51"),(52,"52"),(53,"53"),(54,"54"),(55,"55"),
+(56,"56"),(57,"57"),(58,"58"),(59,"59"),(60,"60"),
+(61,"61"),(62,"62"),(63,"63"),(64,"64"),(65,"65"),
+(66,"66"),(67,"67"),(68,"68"),(69,"69"),(70,"70"),
+(71,"71"),(72,"72"),(73,"73"),(74,"74"),(75,"75"),
+(76,"76"),(77,"77"),(78,"78"),(79,"79"),(80,"80"),
+(81,"81"),(82,"82"),(83,"83"),(84,"84"),(85,"85"),
+(86,"86"),(87,"87"),(88,"88"),(89,"89"),(90,"90"),
+(91,"91"),(92,"92"),(93,"93"),(94,"94"),(95,"95"),
+(96,"96"),(97,"97"),(98,"98"),(99,"99");
+set @save_sort_buffer_size= @@sort_buffer_size;
+set sort_buffer_size= 2000;
+SELECT * FROM t1 ORDER BY f1 DESC, f0;
+f0 f1 f2
+100 99 99
+99 98 98
+98 97 97
+97 96 96
+96 95 95
+95 94 94
+94 93 93
+93 92 92
+92 91 91
+91 90 90
+90 89 89
+89 88 88
+88 87 87
+87 86 86
+86 85 85
+85 84 84
+84 83 83
+83 82 82
+82 81 81
+81 80 80
+80 79 79
+79 78 78
+78 77 77
+77 76 76
+76 75 75
+75 74 74
+74 73 73
+73 72 72
+72 71 71
+71 70 70
+70 69 69
+69 68 68
+68 67 67
+67 66 66
+66 65 65
+65 64 64
+64 63 63
+63 62 62
+62 61 61
+61 60 60
+60 59 59
+59 58 58
+58 57 57
+57 56 56
+56 55 55
+55 54 54
+54 53 53
+53 52 52
+52 51 51
+51 50 50
+50 49 49
+49 48 48
+48 47 47
+47 46 46
+46 45 45
+45 44 44
+44 43 43
+43 42 42
+42 41 41
+41 40 40
+40 39 39
+39 38 38
+38 37 37
+37 36 36
+36 35 35
+35 34 34
+34 33 33
+33 32 32
+32 31 31
+31 30 30
+30 29 29
+29 28 28
+28 27 27
+27 26 26
+26 25 25
+25 24 24
+24 23 23
+23 22 22
+22 21 21
+21 20 20
+20 19 19
+19 18 18
+18 17 17
+17 16 16
+16 15 15
+15 14 14
+14 13 13
+13 12 12
+12 11 11
+11 10 10
+10 9 9
+9 8 8
+8 7 7
+7 6 6
+6 5 5
+5 4 4
+4 3 3
+3 2 2
+2 1 1
+1 0 0
+set sort_buffer_size= @save_sort_buffer_size;
+DROP TABLE t1;
+End of 5.3 tests
diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result
index 7e703de0876..1f5b359199d 100644
--- a/mysql-test/r/parser.result
+++ b/mysql-test/r/parser.result
@@ -556,9 +556,13 @@ DROP TABLE IF EXISTS t1;
SELECT STR_TO_DATE('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE;
STR_TO_DATE('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE
NULL
+Warnings:
+Error 1411 Incorrect datetime value: '10:00 PM' for function str_to_date
SELECT STR_TO_DATE('10:00 PM', '%h:%i %p') + INTERVAL (INTERVAL(1,2,3) + 1) MINUTE;
STR_TO_DATE('10:00 PM', '%h:%i %p') + INTERVAL (INTERVAL(1,2,3) + 1) MINUTE
NULL
+Warnings:
+Error 1411 Incorrect datetime value: '10:00 PM' for function str_to_date
SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
"1997-12-31 23:59:59" + INTERVAL 1 SECOND
1998-01-01 00:00:00
diff --git a/mysql-test/r/parser_precedence.result b/mysql-test/r/parser_precedence.result
index cf301ec677b..979084d0346 100644
--- a/mysql-test/r/parser_precedence.result
+++ b/mysql-test/r/parser_precedence.result
@@ -1,4 +1,5 @@
drop table if exists t1_30237_bool;
+set sql_mode=NO_UNSIGNED_SUBTRACTION;
create table t1_30237_bool(A boolean, B boolean, C boolean);
insert into t1_30237_bool values
(FALSE, FALSE, FALSE),
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index 316921a5814..258c605f461 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -382,6 +382,7 @@ Handler_read_key 2
Handler_read_next 4
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
EXPLAIN PARTITIONS SELECT c1 FROM t2 WHERE (c1 > 10 AND c1 < 13) OR (c1 > 17 AND c1 < 20);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -400,6 +401,7 @@ Handler_read_key 2
Handler_read_next 4
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
DROP TABLE t1,t2;
CREATE TABLE `t1` (
@@ -430,6 +432,7 @@ Handler_read_key 1
Handler_read_next 2
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
EXPLAIN PARTITIONS SELECT c1 FROM t2 WHERE (c1 > 2 AND c1 < 5);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -446,6 +449,7 @@ Handler_read_key 1
Handler_read_next 2
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
EXPLAIN PARTITIONS SELECT c1 FROM t1 WHERE (c1 > 12 AND c1 < 15);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -462,6 +466,7 @@ Handler_read_key 1
Handler_read_next 2
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
EXPLAIN PARTITIONS SELECT c1 FROM t2 WHERE (c1 > 12 AND c1 < 15);
id select_type table partitions type possible_keys key key_len ref rows Extra
@@ -478,6 +483,7 @@ Handler_read_key 1
Handler_read_next 2
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
DROP TABLE t1,t2;
create table t1 (a int) partition by list ((a/3)*10 div 1)
@@ -2253,3 +2259,21 @@ CREATE TABLE t1 (a INT, b INT, KEY(a)) ENGINE=Aria PARTITION BY KEY(a) PARTITION
ALTER TABLE t1 ADD KEY (b);
drop table t1;
End of 5.1 tests
+#
+# BUG#598247: partition.test produces valgrind errors in 5.3-based branches
+#
+CREATE TABLE t1 (
+a INT DEFAULT NULL,
+b DOUBLE DEFAULT NULL,
+c INT DEFAULT NULL,
+KEY idx2(b,a)
+) engine=myisam PARTITION BY HASH(c) PARTITIONS 3;
+INSERT INTO t1 VALUES (6,8,9);
+INSERT INTO t1 VALUES (6,8,10);
+SELECT 1 FROM t1 JOIN t1 AS t2 USING (a);
+1
+1
+1
+1
+1
+drop table t1;
diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result
index a14b1280eb7..4df5f1702c7 100644
--- a/mysql-test/r/partition_error.result
+++ b/mysql-test/r/partition_error.result
@@ -51,14 +51,14 @@ PARTITION BY RANGE (DAYOFWEEK(a))
(PARTITION a1 VALUES LESS THAN (60));
INSERT INTO t1 VALUES ('test'),('a'),('5');
Warnings:
-Warning 1264 Out of range value for column 'a' at row 1
-Warning 1264 Out of range value for column 'a' at row 2
-Warning 1264 Out of range value for column 'a' at row 3
+Warning 1265 Data truncated for column 'a' at row 1
+Warning 1265 Data truncated for column 'a' at row 2
+Warning 1265 Data truncated for column 'a' at row 3
SHOW WARNINGS;
Level Code Message
-Warning 1264 Out of range value for column 'a' at row 1
-Warning 1264 Out of range value for column 'a' at row 2
-Warning 1264 Out of range value for column 'a' at row 3
+Warning 1265 Data truncated for column 'a' at row 1
+Warning 1265 Data truncated for column 'a' at row 2
+Warning 1265 Data truncated for column 'a' at row 3
DROP TABLE t1;
CREATE TABLE t1 (a TIME)
PARTITION BY RANGE (DAYOFWEEK(a))
diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result
index 01ae3876fd0..d5594c7453e 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
@@ -2340,16 +2340,17 @@ drop table t1;
create table t1 (a int not null, b int not null, key(a), key(b))
partition by hash(a) partitions 4;
insert into t1 values (1,1),(2,2),(3,3),(4,4);
+insert into t1 values (5,5),(6,6),(7,7),(8,8);
explain partitions
select * from t1 X, t1 Y
where X.b = Y.b and (X.a=1 or X.a=2) and (Y.a=2 or Y.a=3);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE X p1,p2 ALL a,b NULL NULL NULL 2 Using where
+1 SIMPLE X p1,p2 range a,b a 4 NULL 4 Using where
1 SIMPLE Y p2,p3 ref a,b b 4 test.X.b 2 Using where
explain partitions
select * from t1 X, t1 Y where X.a = Y.a and (X.a=1 or X.a=2);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE X p1,p2 ALL a NULL NULL NULL 2 Using where
+1 SIMPLE X p1,p2 range a a 4 NULL 4 Using where
1 SIMPLE Y p1,p2 ref a a 4 test.X.a 2
drop table t1;
create table t1 (a int) partition by hash(a) partitions 20;
@@ -2537,15 +2538,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
@@ -2638,7 +2639,10 @@ flush status;
delete from t2 where b > 5;
show status like 'Handler_read_rnd_next';
Variable_name Value
-Handler_read_rnd_next 1215
+Handler_read_rnd_next 815
+show status like 'Handler_read_rnd_deleted';
+Variable_name Value
+Handler_read_rnd_deleted 400
show status like 'Handler_read_key';
Variable_name Value
Handler_read_key 0
@@ -2652,7 +2656,10 @@ flush status;
delete from t2 where b < 5 or b > 3;
show status like 'Handler_read_rnd_next';
Variable_name Value
-Handler_read_rnd_next 1215
+Handler_read_rnd_next 515
+show status like 'Handler_read_rnd_deleted';
+Variable_name Value
+Handler_read_rnd_deleted 700
show status like 'Handler_read_key';
Variable_name Value
Handler_read_key 0
diff --git a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result
index 98be0326ef0..f31d1bd530b 100644
--- a/mysql-test/r/plugin.result
+++ b/mysql-test/r/plugin.result
@@ -75,9 +75,9 @@ SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
#illegal value fixed
CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
Warnings:
-Warning 1653 Incorrect value '10000000000000000000' for option 'ULL'
-Warning 1653 Incorrect value 'ttt' for option 'one_or_two'
-Warning 1653 Incorrect value 'SSS' for option 'YESNO'
+Warning 1912 Incorrect value '10000000000000000000' for option 'ULL'
+Warning 1912 Incorrect value 'ttt' for option 'one_or_two'
+Warning 1912 Incorrect value 'SSS' for option 'YESNO'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/mysql-test/r/pool_of_threads.result b/mysql-test/r/pool_of_threads.result
index 42460a8040c..1a6ab80293f 100644
--- a/mysql-test/r/pool_of_threads.result
+++ b/mysql-test/r/pool_of_threads.result
@@ -1,3 +1,5 @@
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
drop table if exists t1,t2,t3,t4;
CREATE TABLE t1 (
Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
@@ -183,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");
@@ -1347,6 +1349,8 @@ fld1 fld1
250503 250505
250504 250505
250505 250505
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
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
@@ -1389,15 +1393,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 +1417,16 @@ 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
+SET optimizer_switch=@save_optimizer_switch;
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
@@ -1429,7 +1434,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
@@ -2151,6 +2156,7 @@ Privat (Private Nutzung) Mobilfunk
Warnings:
Warning 1052 Column 'kundentyp' in group statement is ambiguous
drop table t1;
+SET optimizer_switch=@save_optimizer_switch;
SELECT sleep(5);
SELECT sleep(5);
# -- Success: more than --thread-pool-size normal connections not possible
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index cd7b4705d7e..75aef40b529 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -149,6 +149,10 @@ 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 @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=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 ;
@@ -176,7 +180,9 @@ id select_type table type possible_keys key key_len ref rows Extra
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
deallocate prepare stmt1;
+set optimizer_switch=@tmp_optimizer_switch;
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 ;
@@ -248,15 +254,15 @@ deallocate prepare StMt1;
deallocate prepare Stmt1;
ERROR HY000: Unknown prepared statement handler (Stmt1) given to DEALLOCATE PREPARE
set names utf8;
-prepare `ü` from 'select 1234';
-execute `ü` ;
+prepare `ü` from 'select 1234';
+execute `ü` ;
1234
1234
set names latin1;
-execute `ü`;
+execute `ü`;
1234
1234
-deallocate prepare `ü`;
+deallocate prepare `ü`;
set names default;
create table t1 (a varchar(10)) charset=utf8;
insert into t1 (a) values ('yahoo');
@@ -3006,20 +3012,23 @@ DROP TABLE t1;
#
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1),(2);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
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;
+SET optimizer_switch=@save_optimizer_switch;
DROP TABLE t1;
#
# Bug#54488 crash when using explain and prepared statements with subqueries
@@ -3199,3 +3208,80 @@ field1
150
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2;
+prepare stmt from "select date('2010-10-10') between '2010-09-09' and ?";
+set @a='2010-11-11';
+execute stmt using @a;
+date('2010-10-10') between '2010-09-09' and ?
+1
+execute stmt using @a;
+date('2010-10-10') between '2010-09-09' and ?
+1
+set @a='2010-08-08';
+execute stmt using @a;
+date('2010-10-10') between '2010-09-09' and ?
+0
+execute stmt using @a;
+date('2010-10-10') between '2010-09-09' and ?
+0
+#
+# Bug #892725: look-up is changed for a full scan when executing PS
+#
+create table t1 (a int primary key, b int);
+insert into t1 values
+(7,70), (3,40), (4,40), (8,70), (1,70), (9,50), (2,70);
+prepare st from 'select * from t1 where a=8';
+flush status;
+execute st;
+a b
+8 70
+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_deleted 0
+Handler_read_rnd_next 0
+flush status;
+execute st;
+a b
+8 70
+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_deleted 0
+Handler_read_rnd_next 0
+flush status;
+select * from t1 use index() where a=3;
+a b
+3 40
+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_deleted 0
+Handler_read_rnd_next 8
+flush status;
+execute st;
+a b
+8 70
+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_deleted 0
+Handler_read_rnd_next 0
+deallocate prepare st;
+drop table t1;
+# End of 5.3 tests
diff --git a/mysql-test/r/ps_11bugs.result b/mysql-test/r/ps_11bugs.result
index 3b4d525aeb4..56894302505 100644
--- a/mysql-test/r/ps_11bugs.result
+++ b/mysql-test/r/ps_11bugs.result
@@ -120,9 +120,9 @@ create table t1 (a int primary key);
insert into t1 values (1);
explain select * from t1 where 3 in (select (1+1) union select 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 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
-3 UNION NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
select * from t1 where 3 in (select (1+1) union select 1);
a
diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result
index 8d578794d6d..924a0105367 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 37 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 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..2a9d08a70f4 100644
--- a/mysql-test/r/ps_2myisam.result
+++ b/mysql-test/r/ps_2myisam.result
@@ -63,8 +63,8 @@ def test t9 t9 c11 c11 246 9 6 Y 0 4 63
def test t9 t9 c12 c12 246 10 6 Y 0 4 63
def test t9 t9 c13 c13 10 10 10 Y 128 0 63
def test t9 t9 c14 c14 12 19 19 Y 128 0 63
-def test t9 t9 c15 c15 7 19 19 N 9441 0 63
-def test t9 t9 c16 c16 11 8 8 Y 128 0 63
+def test t9 t9 c15 c15 7 19 19 N 9377 0 63
+def test t9 t9 c16 c16 11 10 8 Y 128 0 63
def test t9 t9 c17 c17 13 4 4 Y 32864 0 63
def test t9 t9 c18 c18 1 4 1 Y 32768 0 63
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
@@ -1793,8 +1793,8 @@ t5 CREATE TABLE `t5` (
`param08` longtext,
`const09` datetime DEFAULT NULL,
`param09` longblob,
- `const10` int(10) NOT NULL DEFAULT '0',
- `param10` bigint(20) DEFAULT NULL,
+ `const10` decimal(22,6) NOT NULL DEFAULT '0.000000',
+ `param10` decimal(65,30) DEFAULT NULL,
`const11` int(4) DEFAULT NULL,
`param11` bigint(20) DEFAULT NULL,
`const12` binary(0) DEFAULT NULL,
@@ -1823,8 +1823,8 @@ def test t5 t5 const08 const08 253 19 19 N 1 0 8
def test t5 t5 param08 param08 252 4294967295 19 Y 16 0 8
def test t5 t5 const09 const09 12 19 19 Y 128 0 63
def test t5 t5 param09 param09 252 4294967295 19 Y 144 0 63
-def test t5 t5 const10 const10 3 10 9 N 32769 0 63
-def test t5 t5 param10 param10 8 20 9 Y 32768 0 63
+def test t5 t5 const10 const10 246 24 16 N 1 6 63
+def test t5 t5 param10 param10 246 67 40 Y 0 30 63
def test t5 t5 const11 const11 3 4 4 Y 32768 0 63
def test t5 t5 param11 param11 8 20 4 Y 32768 0 63
def test t5 t5 const12 const12 254 0 0 Y 128 0 63
@@ -1850,8 +1850,8 @@ const08 1991-08-05 01:01:01
param08 1991-08-05 01:01:01
const09 1991-08-05 01:01:01
param09 1991-08-05 01:01:01
-const10 662680861
-param10 662680861
+const10 662680861.000000
+param10 662680861.000000000000000000000000000000
const11 1991
param11 1991
const12 NULL
@@ -2762,46 +2762,212 @@ c12 -9999.9999
execute my_delete ;
test_sequence
-- insert into string columns --
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 20, '20', '20', '20', '20', '20', '20', '20', '20', '20', '20', '20' ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '21' ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 21, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 22, '22', '22', '22', '22', '22', '22', '22', '22', '22', '22', '22' )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '23';
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 23, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 30, CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary) ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '31' ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 31, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 32, CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary) )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= CAST('33' as binary);
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 33, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 41 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 41, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 43;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 43, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 50, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 51.0 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 51, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 52, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 53.0;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 53, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 54, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1,
+5.4e+1, 5.4e+1, 5.4e+1 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 5.5e+1 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 55, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 56, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1,
+ 5.6e+1, 5.6e+1, 5.6e+1 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 5.7e+1;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 57, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 'abc' ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 60, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 61, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 62, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL )" ;
+execute stmt1 ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 63, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 2 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 71, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 73, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 81, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 83, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
select c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30
from t9 where c1 >= 20
order by c1 ;
@@ -2960,70 +3126,208 @@ true
delete from t9 ;
test_sequence
-- insert into date/time columns --
+set @arg00= '1991-01-01 01:01:01' ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 20, '1991-01-01 01:01:01', '1991-01-01 01:01:01', '1991-01-01 01:01:01',
+'1991-01-01 01:01:01', '1991-01-01 01:01:01') ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 21, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 22, '1991-01-01 01:01:01', '1991-01-01 01:01:01', '1991-01-01 01:01:01',
+ '1991-01-01 01:01:01', '1991-01-01 01:01:01')" ;
+execute stmt1 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 23, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+set @arg00= CAST('1991-01-01 01:01:01' as datetime) ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 30, CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime)) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 31, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 32, CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime))" ;
+execute stmt1 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 33, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+set @arg00= 2000000000 ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 40, 2000000000, 2000000000, 2000000000, 2000000000, 2000000000 ) ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 41, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 42, 2000000000, 2000000000, 2000000000, 2000000000, 2000000000 )" ;
+execute stmt1 ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 43, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+set @arg00= 1.0e+10 ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 50, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 ) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 51, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 52, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 53, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+set @arg00= 'abc' ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 60, NULL, NULL, '1991-01-01 01:01:01',
+NULL, NULL) ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 61, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 62, NULL, NULL, '1991-01-01 01:01:01',
+ NULL, NULL)" ;
+execute stmt1 ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 63, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 71, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 73, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8.0 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 81, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 83, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
select c1, c13, c14, c15, c16, c17 from t9 order by c1 ;
c1 c13 c14 c15 c16 c17
20 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
@@ -3034,14 +3338,14 @@ c1 c13 c14 c15 c16 c17
31 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
32 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
33 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
-40 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-41 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
+40 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+41 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
51 2010-00-00 2010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
+52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
60 NULL NULL 1991-01-01 01:01:01 NULL NULL
61 NULL NULL 1991-01-01 01:01:01 NULL NULL
62 NULL NULL 1991-01-01 01:01:01 NULL NULL
@@ -3055,25 +3359,25 @@ test_sequence
set @arg00= '1991-01-01 01:01:01' ;
select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
-c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01' ;
found
true
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
found
true
prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
- c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+ c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01'" ;
execute stmt1 ;
found
true
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
found
true
set @arg00= CAST('1991-01-01 01:01:01' as datetime) ;
@@ -3081,12 +3385,11 @@ select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
-c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime) ;
found
true
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
found
true
@@ -3094,14 +3397,43 @@ prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
- c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime)" ;
execute stmt1 ;
found
true
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
+found
+true
+set @arg00= '01:01:01' ;
+select 'true' as found from t9 where c1= 20 and c16= '01:01:01' ;
+found
+true
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= '01:01:01'" ;
+execute stmt1 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
+found
+true
+set @arg00= CAST('01:01:01' as time) ;
+select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time) ;
+found
+true
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time)" ;
+execute stmt1 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
found
true
set @arg00= 1991 ;
diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result
index 9ba5e607b5d..6b7434390af 100644
--- a/mysql-test/r/ps_3innodb.result
+++ b/mysql-test/r/ps_3innodb.result
@@ -63,8 +63,8 @@ def test t9 t9 c11 c11 246 9 6 Y 0 4 63
def test t9 t9 c12 c12 246 10 6 Y 0 4 63
def test t9 t9 c13 c13 10 10 10 Y 128 0 63
def test t9 t9 c14 c14 12 19 19 Y 128 0 63
-def test t9 t9 c15 c15 7 19 19 N 9441 0 63
-def test t9 t9 c16 c16 11 8 8 Y 128 0 63
+def test t9 t9 c15 c15 7 19 19 N 9377 0 63
+def test t9 t9 c16 c16 11 10 8 Y 128 0 63
def test t9 t9 c17 c17 13 4 4 Y 32864 0 63
def test t9 t9 c18 c18 1 4 1 Y 32768 0 63
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
@@ -1776,8 +1776,8 @@ t5 CREATE TABLE `t5` (
`param08` longtext,
`const09` datetime DEFAULT NULL,
`param09` longblob,
- `const10` int(10) NOT NULL DEFAULT '0',
- `param10` bigint(20) DEFAULT NULL,
+ `const10` decimal(22,6) NOT NULL DEFAULT '0.000000',
+ `param10` decimal(65,30) DEFAULT NULL,
`const11` int(4) DEFAULT NULL,
`param11` bigint(20) DEFAULT NULL,
`const12` binary(0) DEFAULT NULL,
@@ -1806,8 +1806,8 @@ def test t5 t5 const08 const08 253 19 19 N 1 0 8
def test t5 t5 param08 param08 252 4294967295 19 Y 16 0 8
def test t5 t5 const09 const09 12 19 19 Y 128 0 63
def test t5 t5 param09 param09 252 4294967295 19 Y 144 0 63
-def test t5 t5 const10 const10 3 10 9 N 32769 0 63
-def test t5 t5 param10 param10 8 20 9 Y 32768 0 63
+def test t5 t5 const10 const10 246 24 16 N 1 6 63
+def test t5 t5 param10 param10 246 67 40 Y 0 30 63
def test t5 t5 const11 const11 3 4 4 Y 32768 0 63
def test t5 t5 param11 param11 8 20 4 Y 32768 0 63
def test t5 t5 const12 const12 254 0 0 Y 128 0 63
@@ -1833,8 +1833,8 @@ const08 1991-08-05 01:01:01
param08 1991-08-05 01:01:01
const09 1991-08-05 01:01:01
param09 1991-08-05 01:01:01
-const10 662680861
-param10 662680861
+const10 662680861.000000
+param10 662680861.000000000000000000000000000000
const11 1991
param11 1991
const12 NULL
@@ -2745,46 +2745,212 @@ c12 -9999.9999
execute my_delete ;
test_sequence
-- insert into string columns --
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 20, '20', '20', '20', '20', '20', '20', '20', '20', '20', '20', '20' ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '21' ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 21, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 22, '22', '22', '22', '22', '22', '22', '22', '22', '22', '22', '22' )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '23';
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 23, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 30, CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary) ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '31' ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 31, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 32, CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary) )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= CAST('33' as binary);
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 33, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 41 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 41, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 43;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 43, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 50, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 51.0 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 51, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 52, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 53.0;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 53, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 54, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1,
+5.4e+1, 5.4e+1, 5.4e+1 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 5.5e+1 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 55, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 56, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1,
+ 5.6e+1, 5.6e+1, 5.6e+1 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 5.7e+1;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 57, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 'abc' ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 60, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 61, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 62, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL )" ;
+execute stmt1 ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 63, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 2 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 71, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 73, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 81, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 83, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
select c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30
from t9 where c1 >= 20
order by c1 ;
@@ -2943,70 +3109,208 @@ true
delete from t9 ;
test_sequence
-- insert into date/time columns --
+set @arg00= '1991-01-01 01:01:01' ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 20, '1991-01-01 01:01:01', '1991-01-01 01:01:01', '1991-01-01 01:01:01',
+'1991-01-01 01:01:01', '1991-01-01 01:01:01') ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 21, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 22, '1991-01-01 01:01:01', '1991-01-01 01:01:01', '1991-01-01 01:01:01',
+ '1991-01-01 01:01:01', '1991-01-01 01:01:01')" ;
+execute stmt1 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 23, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+set @arg00= CAST('1991-01-01 01:01:01' as datetime) ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 30, CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime)) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 31, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 32, CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime))" ;
+execute stmt1 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 33, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+set @arg00= 2000000000 ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 40, 2000000000, 2000000000, 2000000000, 2000000000, 2000000000 ) ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 41, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 42, 2000000000, 2000000000, 2000000000, 2000000000, 2000000000 )" ;
+execute stmt1 ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 43, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+set @arg00= 1.0e+10 ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 50, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 ) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 51, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 52, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 53, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+set @arg00= 'abc' ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 60, NULL, NULL, '1991-01-01 01:01:01',
+NULL, NULL) ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 61, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 62, NULL, NULL, '1991-01-01 01:01:01',
+ NULL, NULL)" ;
+execute stmt1 ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 63, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 71, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 73, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8.0 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 81, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 83, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
select c1, c13, c14, c15, c16, c17 from t9 order by c1 ;
c1 c13 c14 c15 c16 c17
20 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
@@ -3017,14 +3321,14 @@ c1 c13 c14 c15 c16 c17
31 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
32 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
33 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
-40 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-41 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
+40 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+41 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
51 2010-00-00 2010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
+52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
60 NULL NULL 1991-01-01 01:01:01 NULL NULL
61 NULL NULL 1991-01-01 01:01:01 NULL NULL
62 NULL NULL 1991-01-01 01:01:01 NULL NULL
@@ -3038,25 +3342,25 @@ test_sequence
set @arg00= '1991-01-01 01:01:01' ;
select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
-c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01' ;
found
true
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
found
true
prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
- c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+ c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01'" ;
execute stmt1 ;
found
true
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
found
true
set @arg00= CAST('1991-01-01 01:01:01' as datetime) ;
@@ -3064,12 +3368,11 @@ select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
-c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime) ;
found
true
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
found
true
@@ -3077,14 +3380,43 @@ prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
- c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime)" ;
execute stmt1 ;
found
true
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
+found
+true
+set @arg00= '01:01:01' ;
+select 'true' as found from t9 where c1= 20 and c16= '01:01:01' ;
+found
+true
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= '01:01:01'" ;
+execute stmt1 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
+found
+true
+set @arg00= CAST('01:01:01' as time) ;
+select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time) ;
+found
+true
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time)" ;
+execute stmt1 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
found
true
set @arg00= 1991 ;
diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result
index e7252473c49..58acc19124a 100644
--- a/mysql-test/r/ps_4heap.result
+++ b/mysql-test/r/ps_4heap.result
@@ -64,8 +64,8 @@ def test t9 t9 c11 c11 246 9 6 Y 0 4 63
def test t9 t9 c12 c12 246 10 6 Y 0 4 63
def test t9 t9 c13 c13 10 10 10 Y 128 0 63
def test t9 t9 c14 c14 12 19 19 Y 128 0 63
-def test t9 t9 c15 c15 7 19 19 N 9441 0 63
-def test t9 t9 c16 c16 11 8 8 Y 128 0 63
+def test t9 t9 c15 c15 7 19 19 N 9377 0 63
+def test t9 t9 c16 c16 11 10 8 Y 128 0 63
def test t9 t9 c17 c17 13 4 4 Y 32864 0 63
def test t9 t9 c18 c18 1 4 1 Y 32768 0 63
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
@@ -1777,8 +1777,8 @@ t5 CREATE TABLE `t5` (
`param08` longtext,
`const09` datetime DEFAULT NULL,
`param09` longblob,
- `const10` int(10) NOT NULL DEFAULT '0',
- `param10` bigint(20) DEFAULT NULL,
+ `const10` decimal(22,6) NOT NULL DEFAULT '0.000000',
+ `param10` decimal(65,30) DEFAULT NULL,
`const11` int(4) DEFAULT NULL,
`param11` bigint(20) DEFAULT NULL,
`const12` binary(0) DEFAULT NULL,
@@ -1807,8 +1807,8 @@ def test t5 t5 const08 const08 253 19 19 N 1 0 8
def test t5 t5 param08 param08 252 4294967295 19 Y 16 0 8
def test t5 t5 const09 const09 12 19 19 Y 128 0 63
def test t5 t5 param09 param09 252 4294967295 19 Y 144 0 63
-def test t5 t5 const10 const10 3 10 9 N 32769 0 63
-def test t5 t5 param10 param10 8 20 9 Y 32768 0 63
+def test t5 t5 const10 const10 246 24 16 N 1 6 63
+def test t5 t5 param10 param10 246 67 40 Y 0 30 63
def test t5 t5 const11 const11 3 4 4 Y 32768 0 63
def test t5 t5 param11 param11 8 20 4 Y 32768 0 63
def test t5 t5 const12 const12 254 0 0 Y 128 0 63
@@ -1834,8 +1834,8 @@ const08 1991-08-05 01:01:01
param08 1991-08-05 01:01:01
const09 1991-08-05 01:01:01
param09 1991-08-05 01:01:01
-const10 662680861
-param10 662680861
+const10 662680861.000000
+param10 662680861.000000000000000000000000000000
const11 1991
param11 1991
const12 NULL
@@ -2746,46 +2746,212 @@ c12 -9999.9999
execute my_delete ;
test_sequence
-- insert into string columns --
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 20, '20', '20', '20', '20', '20', '20', '20', '20', '20', '20', '20' ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '21' ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 21, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 22, '22', '22', '22', '22', '22', '22', '22', '22', '22', '22', '22' )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '23';
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 23, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 30, CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary) ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '31' ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 31, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 32, CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary) )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= CAST('33' as binary);
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 33, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 41 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 41, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 43;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 43, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 50, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 51.0 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 51, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 52, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 53.0;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 53, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 54, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1,
+5.4e+1, 5.4e+1, 5.4e+1 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 5.5e+1 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 55, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 56, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1,
+ 5.6e+1, 5.6e+1, 5.6e+1 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 5.7e+1;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 57, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 'abc' ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 60, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 61, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 62, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL )" ;
+execute stmt1 ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 63, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 2 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 71, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 73, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 81, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 83, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
select c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30
from t9 where c1 >= 20
order by c1 ;
@@ -2944,70 +3110,208 @@ true
delete from t9 ;
test_sequence
-- insert into date/time columns --
+set @arg00= '1991-01-01 01:01:01' ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 20, '1991-01-01 01:01:01', '1991-01-01 01:01:01', '1991-01-01 01:01:01',
+'1991-01-01 01:01:01', '1991-01-01 01:01:01') ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 21, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 22, '1991-01-01 01:01:01', '1991-01-01 01:01:01', '1991-01-01 01:01:01',
+ '1991-01-01 01:01:01', '1991-01-01 01:01:01')" ;
+execute stmt1 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 23, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+set @arg00= CAST('1991-01-01 01:01:01' as datetime) ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 30, CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime)) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 31, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 32, CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime))" ;
+execute stmt1 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 33, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+set @arg00= 2000000000 ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 40, 2000000000, 2000000000, 2000000000, 2000000000, 2000000000 ) ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 41, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 42, 2000000000, 2000000000, 2000000000, 2000000000, 2000000000 )" ;
+execute stmt1 ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 43, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+set @arg00= 1.0e+10 ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 50, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 ) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 51, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 52, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 53, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+set @arg00= 'abc' ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 60, NULL, NULL, '1991-01-01 01:01:01',
+NULL, NULL) ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 61, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 62, NULL, NULL, '1991-01-01 01:01:01',
+ NULL, NULL)" ;
+execute stmt1 ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 63, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 71, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 73, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8.0 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 81, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 83, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
select c1, c13, c14, c15, c16, c17 from t9 order by c1 ;
c1 c13 c14 c15 c16 c17
20 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
@@ -3018,14 +3322,14 @@ c1 c13 c14 c15 c16 c17
31 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
32 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
33 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
-40 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-41 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
+40 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+41 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
51 2010-00-00 2010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
+52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
60 NULL NULL 1991-01-01 01:01:01 NULL NULL
61 NULL NULL 1991-01-01 01:01:01 NULL NULL
62 NULL NULL 1991-01-01 01:01:01 NULL NULL
@@ -3039,25 +3343,25 @@ test_sequence
set @arg00= '1991-01-01 01:01:01' ;
select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
-c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01' ;
found
true
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
found
true
prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
- c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+ c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01'" ;
execute stmt1 ;
found
true
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
found
true
set @arg00= CAST('1991-01-01 01:01:01' as datetime) ;
@@ -3065,12 +3369,11 @@ select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
-c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime) ;
found
true
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
found
true
@@ -3078,14 +3381,43 @@ prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
- c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime)" ;
execute stmt1 ;
found
true
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
+found
+true
+set @arg00= '01:01:01' ;
+select 'true' as found from t9 where c1= 20 and c16= '01:01:01' ;
+found
+true
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= '01:01:01'" ;
+execute stmt1 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
+found
+true
+set @arg00= CAST('01:01:01' as time) ;
+select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time) ;
+found
+true
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time)" ;
+execute stmt1 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
found
true
set @arg00= 1991 ;
diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result
index 7530b3ebe0b..654e641deeb 100644
--- a/mysql-test/r/ps_5merge.result
+++ b/mysql-test/r/ps_5merge.result
@@ -106,8 +106,8 @@ def test t9 t9 c11 c11 246 9 6 Y 0 4 63
def test t9 t9 c12 c12 246 10 6 Y 0 4 63
def test t9 t9 c13 c13 10 10 10 Y 128 0 63
def test t9 t9 c14 c14 12 19 19 Y 128 0 63
-def test t9 t9 c15 c15 7 19 19 N 9441 0 63
-def test t9 t9 c16 c16 11 8 8 Y 128 0 63
+def test t9 t9 c15 c15 7 19 19 N 9377 0 63
+def test t9 t9 c16 c16 11 10 8 Y 128 0 63
def test t9 t9 c17 c17 13 4 4 Y 32864 0 63
def test t9 t9 c18 c18 1 4 1 Y 32768 0 63
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
@@ -1713,8 +1713,8 @@ t5 CREATE TABLE `t5` (
`param08` longtext,
`const09` datetime DEFAULT NULL,
`param09` longblob,
- `const10` int(10) NOT NULL DEFAULT '0',
- `param10` bigint(20) DEFAULT NULL,
+ `const10` decimal(22,6) NOT NULL DEFAULT '0.000000',
+ `param10` decimal(65,30) DEFAULT NULL,
`const11` int(4) DEFAULT NULL,
`param11` bigint(20) DEFAULT NULL,
`const12` binary(0) DEFAULT NULL,
@@ -1743,8 +1743,8 @@ def test t5 t5 const08 const08 253 19 19 N 1 0 8
def test t5 t5 param08 param08 252 4294967295 19 Y 16 0 8
def test t5 t5 const09 const09 12 19 19 Y 128 0 63
def test t5 t5 param09 param09 252 4294967295 19 Y 144 0 63
-def test t5 t5 const10 const10 3 10 9 N 32769 0 63
-def test t5 t5 param10 param10 8 20 9 Y 32768 0 63
+def test t5 t5 const10 const10 246 24 16 N 1 6 63
+def test t5 t5 param10 param10 246 67 40 Y 0 30 63
def test t5 t5 const11 const11 3 4 4 Y 32768 0 63
def test t5 t5 param11 param11 8 20 4 Y 32768 0 63
def test t5 t5 const12 const12 254 0 0 Y 128 0 63
@@ -1770,8 +1770,8 @@ const08 1991-08-05 01:01:01
param08 1991-08-05 01:01:01
const09 1991-08-05 01:01:01
param09 1991-08-05 01:01:01
-const10 662680861
-param10 662680861
+const10 662680861.000000
+param10 662680861.000000000000000000000000000000
const11 1991
param11 1991
const12 NULL
@@ -2682,46 +2682,212 @@ c12 -9999.9999
execute my_delete ;
test_sequence
-- insert into string columns --
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 20, '20', '20', '20', '20', '20', '20', '20', '20', '20', '20', '20' ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '21' ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 21, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 22, '22', '22', '22', '22', '22', '22', '22', '22', '22', '22', '22' )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '23';
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 23, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 30, CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary) ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '31' ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 31, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 32, CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary) )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= CAST('33' as binary);
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 33, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 41 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 41, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 43;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 43, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 50, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 51.0 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 51, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 52, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 53.0;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 53, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 54, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1,
+5.4e+1, 5.4e+1, 5.4e+1 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 5.5e+1 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 55, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 56, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1,
+ 5.6e+1, 5.6e+1, 5.6e+1 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 5.7e+1;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 57, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 'abc' ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 60, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 61, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 62, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL )" ;
+execute stmt1 ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 63, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 2 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 71, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 73, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 81, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 83, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
select c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30
from t9 where c1 >= 20
order by c1 ;
@@ -2880,70 +3046,208 @@ true
delete from t9 ;
test_sequence
-- insert into date/time columns --
+set @arg00= '1991-01-01 01:01:01' ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 20, '1991-01-01 01:01:01', '1991-01-01 01:01:01', '1991-01-01 01:01:01',
+'1991-01-01 01:01:01', '1991-01-01 01:01:01') ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 21, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 22, '1991-01-01 01:01:01', '1991-01-01 01:01:01', '1991-01-01 01:01:01',
+ '1991-01-01 01:01:01', '1991-01-01 01:01:01')" ;
+execute stmt1 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 23, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+set @arg00= CAST('1991-01-01 01:01:01' as datetime) ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 30, CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime)) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 31, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 32, CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime))" ;
+execute stmt1 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 33, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+set @arg00= 2000000000 ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 40, 2000000000, 2000000000, 2000000000, 2000000000, 2000000000 ) ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 41, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 42, 2000000000, 2000000000, 2000000000, 2000000000, 2000000000 )" ;
+execute stmt1 ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 43, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+set @arg00= 1.0e+10 ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 50, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 ) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 51, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 52, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 53, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+set @arg00= 'abc' ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 60, NULL, NULL, '1991-01-01 01:01:01',
+NULL, NULL) ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 61, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 62, NULL, NULL, '1991-01-01 01:01:01',
+ NULL, NULL)" ;
+execute stmt1 ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 63, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 71, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 73, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8.0 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 81, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 83, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
select c1, c13, c14, c15, c16, c17 from t9 order by c1 ;
c1 c13 c14 c15 c16 c17
20 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
@@ -2954,14 +3258,14 @@ c1 c13 c14 c15 c16 c17
31 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
32 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
33 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
-40 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-41 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
+40 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+41 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
51 2010-00-00 2010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
+52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
60 NULL NULL 1991-01-01 01:01:01 NULL NULL
61 NULL NULL 1991-01-01 01:01:01 NULL NULL
62 NULL NULL 1991-01-01 01:01:01 NULL NULL
@@ -2975,25 +3279,25 @@ test_sequence
set @arg00= '1991-01-01 01:01:01' ;
select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
-c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01' ;
found
true
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
found
true
prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
- c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+ c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01'" ;
execute stmt1 ;
found
true
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
found
true
set @arg00= CAST('1991-01-01 01:01:01' as datetime) ;
@@ -3001,12 +3305,11 @@ select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
-c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime) ;
found
true
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
found
true
@@ -3014,14 +3317,43 @@ prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
- c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime)" ;
execute stmt1 ;
found
true
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
+found
+true
+set @arg00= '01:01:01' ;
+select 'true' as found from t9 where c1= 20 and c16= '01:01:01' ;
+found
+true
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= '01:01:01'" ;
+execute stmt1 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
+found
+true
+set @arg00= CAST('01:01:01' as time) ;
+select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time) ;
+found
+true
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time)" ;
+execute stmt1 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
found
true
set @arg00= 1991 ;
@@ -3128,8 +3460,8 @@ def test t9 t9 c11 c11 246 9 6 Y 0 4 63
def test t9 t9 c12 c12 246 10 6 Y 0 4 63
def test t9 t9 c13 c13 10 10 10 Y 128 0 63
def test t9 t9 c14 c14 12 19 19 Y 128 0 63
-def test t9 t9 c15 c15 7 19 19 N 9441 0 63
-def test t9 t9 c16 c16 11 8 8 Y 128 0 63
+def test t9 t9 c15 c15 7 19 19 N 9377 0 63
+def test t9 t9 c16 c16 11 10 8 Y 128 0 63
def test t9 t9 c17 c17 13 4 4 Y 32864 0 63
def test t9 t9 c18 c18 1 4 1 Y 32768 0 63
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
@@ -4735,8 +5067,8 @@ t5 CREATE TABLE `t5` (
`param08` longtext,
`const09` datetime DEFAULT NULL,
`param09` longblob,
- `const10` int(10) NOT NULL DEFAULT '0',
- `param10` bigint(20) DEFAULT NULL,
+ `const10` decimal(22,6) NOT NULL DEFAULT '0.000000',
+ `param10` decimal(65,30) DEFAULT NULL,
`const11` int(4) DEFAULT NULL,
`param11` bigint(20) DEFAULT NULL,
`const12` binary(0) DEFAULT NULL,
@@ -4765,8 +5097,8 @@ def test t5 t5 const08 const08 253 19 19 N 1 0 8
def test t5 t5 param08 param08 252 4294967295 19 Y 16 0 8
def test t5 t5 const09 const09 12 19 19 Y 128 0 63
def test t5 t5 param09 param09 252 4294967295 19 Y 144 0 63
-def test t5 t5 const10 const10 3 10 9 N 32769 0 63
-def test t5 t5 param10 param10 8 20 9 Y 32768 0 63
+def test t5 t5 const10 const10 246 24 16 N 1 6 63
+def test t5 t5 param10 param10 246 67 40 Y 0 30 63
def test t5 t5 const11 const11 3 4 4 Y 32768 0 63
def test t5 t5 param11 param11 8 20 4 Y 32768 0 63
def test t5 t5 const12 const12 254 0 0 Y 128 0 63
@@ -4792,8 +5124,8 @@ const08 1991-08-05 01:01:01
param08 1991-08-05 01:01:01
const09 1991-08-05 01:01:01
param09 1991-08-05 01:01:01
-const10 662680861
-param10 662680861
+const10 662680861.000000
+param10 662680861.000000000000000000000000000000
const11 1991
param11 1991
const12 NULL
@@ -5704,46 +6036,212 @@ c12 -9999.9999
execute my_delete ;
test_sequence
-- insert into string columns --
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 20, '20', '20', '20', '20', '20', '20', '20', '20', '20', '20', '20' ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '21' ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 21, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 22, '22', '22', '22', '22', '22', '22', '22', '22', '22', '22', '22' )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '23';
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 23, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 30, CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary) ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '31' ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 31, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 32, CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary) )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= CAST('33' as binary);
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 33, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 41 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 41, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 43;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 43, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 50, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 51.0 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 51, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 52, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 53.0;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 53, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 54, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1,
+5.4e+1, 5.4e+1, 5.4e+1 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 5.5e+1 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 55, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 56, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1,
+ 5.6e+1, 5.6e+1, 5.6e+1 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 5.7e+1;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 57, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 'abc' ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 60, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 61, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 62, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL )" ;
+execute stmt1 ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 63, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 2 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 71, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 73, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 81, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 83, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
select c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30
from t9 where c1 >= 20
order by c1 ;
@@ -5902,70 +6400,208 @@ true
delete from t9 ;
test_sequence
-- insert into date/time columns --
+set @arg00= '1991-01-01 01:01:01' ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 20, '1991-01-01 01:01:01', '1991-01-01 01:01:01', '1991-01-01 01:01:01',
+'1991-01-01 01:01:01', '1991-01-01 01:01:01') ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 21, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 22, '1991-01-01 01:01:01', '1991-01-01 01:01:01', '1991-01-01 01:01:01',
+ '1991-01-01 01:01:01', '1991-01-01 01:01:01')" ;
+execute stmt1 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 23, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+set @arg00= CAST('1991-01-01 01:01:01' as datetime) ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 30, CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime)) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 31, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 32, CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime))" ;
+execute stmt1 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 33, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+set @arg00= 2000000000 ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 40, 2000000000, 2000000000, 2000000000, 2000000000, 2000000000 ) ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 41, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 42, 2000000000, 2000000000, 2000000000, 2000000000, 2000000000 )" ;
+execute stmt1 ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 43, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+set @arg00= 1.0e+10 ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 50, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 ) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 51, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 52, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 53, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+set @arg00= 'abc' ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 60, NULL, NULL, '1991-01-01 01:01:01',
+NULL, NULL) ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 61, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 62, NULL, NULL, '1991-01-01 01:01:01',
+ NULL, NULL)" ;
+execute stmt1 ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 63, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 71, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 73, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8.0 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 81, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 83, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
select c1, c13, c14, c15, c16, c17 from t9 order by c1 ;
c1 c13 c14 c15 c16 c17
20 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
@@ -5976,14 +6612,14 @@ c1 c13 c14 c15 c16 c17
31 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
32 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
33 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
-40 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-41 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
+40 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+41 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
51 2010-00-00 2010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
+52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
60 NULL NULL 1991-01-01 01:01:01 NULL NULL
61 NULL NULL 1991-01-01 01:01:01 NULL NULL
62 NULL NULL 1991-01-01 01:01:01 NULL NULL
@@ -5997,25 +6633,25 @@ test_sequence
set @arg00= '1991-01-01 01:01:01' ;
select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
-c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01' ;
found
true
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
found
true
prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
- c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+ c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01'" ;
execute stmt1 ;
found
true
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
found
true
set @arg00= CAST('1991-01-01 01:01:01' as datetime) ;
@@ -6023,12 +6659,11 @@ select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
-c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime) ;
found
true
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
found
true
@@ -6036,14 +6671,43 @@ prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
- c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime)" ;
execute stmt1 ;
found
true
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
+found
+true
+set @arg00= '01:01:01' ;
+select 'true' as found from t9 where c1= 20 and c16= '01:01:01' ;
+found
+true
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= '01:01:01'" ;
+execute stmt1 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
+found
+true
+set @arg00= CAST('01:01:01' as time) ;
+select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time) ;
+found
+true
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time)" ;
+execute stmt1 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
found
true
set @arg00= 1991 ;
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index 2380ecc5969..26bf4e74219 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -991,20 +991,17 @@ SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050327 invalid';
COUNT(*)
0
Warnings:
-Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
-Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 0
+Warning 1292 Incorrect datetime value: '20050327 invalid'
SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050328 invalid';
COUNT(*)
0
Warnings:
-Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1
-Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 0
+Warning 1292 Incorrect datetime value: '20050328 invalid'
SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050327 invalid';
COUNT(*)
0
Warnings:
-Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
-Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 0
+Warning 1292 Incorrect datetime value: '20050327 invalid'
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
@@ -1091,6 +1088,23 @@ Qcache_inserts 1
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 1
+set global query_cache_strip_comments=1;
+(select a from t1) union (select a from t1);
+a
+(select a from t1) /* */union (select a from t1);
+a
+set global query_cache_strip_comments=0;
+(select a from t1) union (select a from t1);
+a
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+show status like "Qcache_inserts";
+Variable_name Value
+Qcache_inserts 1
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 4
drop table t1;
create table t1 (a int);
insert into t1 values (1),(2);
@@ -1639,6 +1653,7 @@ set GLOBAL query_cache_type=default;
set GLOBAL query_cache_limit=default;
set GLOBAL query_cache_min_res_unit=default;
set GLOBAL query_cache_size=default;
+set local query_cache_type=default;
FLUSH STATUS;
SET GLOBAL query_cache_size=10*1024*1024;
SET @save_concurrent_insert= @@concurrent_insert;
@@ -1823,3 +1838,33 @@ SELECT 1 FROM t1 GROUP BY
DROP TABLE t1;
SET GLOBAL query_cache_size= default;
End of 5.1 tests
+New query cache switching OFF mechanism test
+set global query_cache_size=1024*1024*20;
+set global query_cache_type=on;
+select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type;
+@@query_cache_size @@global.query_cache_type @@local.query_cache_type
+20971520 ON ON
+set global query_cache_size=0;
+select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type;
+@@query_cache_size @@global.query_cache_type @@local.query_cache_type
+0 ON ON
+set global query_cache_size=1024*1024*20;
+select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type;
+@@query_cache_size @@global.query_cache_type @@local.query_cache_type
+20971520 ON ON
+set global query_cache_type=off;
+select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type;
+@@query_cache_size @@global.query_cache_type @@local.query_cache_type
+20971520 OFF OFF
+set global query_cache_type=on;
+select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type;
+@@query_cache_size @@global.query_cache_type @@local.query_cache_type
+20971520 ON OFF
+set local query_cache_type= on;
+select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type;
+@@query_cache_size @@global.query_cache_type @@local.query_cache_type
+20971520 ON ON
+restore defaults
+SET GLOBAL query_cache_type= default;
+SET GLOBAL query_cache_size= default;
+SET LOCAL query_cache_type= default;
diff --git a/mysql-test/r/query_cache_28249.result b/mysql-test/r/query_cache_28249.result
index aed84911032..463a264a954 100644
--- a/mysql-test/r/query_cache_28249.result
+++ b/mysql-test/r/query_cache_28249.result
@@ -23,10 +23,10 @@ SELECT *, (SELECT COUNT(*) FROM t2) FROM t1;
# Switch to connection user3
# Poll till the select of connection user1 is blocked by the write lock on t1.
SELECT user,command,state,info FROM information_schema.processlist
-WHERE state = 'Locked'
+WHERE state = "Table Lock"
AND info = 'SELECT *, (SELECT COUNT(*) FROM t2) FROM t1';
user command state info
-root Query Locked SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
+root Query Table lock SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
INSERT INTO t1 VALUES (4);
# Switch to connection user2
UNLOCK TABLES;
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 8a416de66ee..3d6426148d0 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1,4 +1,4 @@
-drop table if exists t1, t2, t3;
+drop table if exists t1, t2, t3, t10, t100;
CREATE TABLE t1 (
event_date date DEFAULT '0000-00-00' NOT NULL,
type int(11) DEFAULT '0' NOT NULL,
@@ -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 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 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 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 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 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 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
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
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
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
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
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
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
explain select * from t1 where a='aaa' collate latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL a NULL NULL NULL 9 Using where
@@ -698,14 +698,26 @@ INSERT INTO t1 VALUES
'd8c4177d09f8b11f5.52725521'),
('d8c4177d24ccef970.14957924','d8c4177d09f8b11f5.52725521',10,11,
'd8c4177d09f8b11f5.52725521');
+INSERT INTO t1 VALUES
+('d8c4177d09f8b11f5.52725522','oxrootid',1,40,'d8c4177d09f8b11f5.52725522'),
+('d8c4177d151affab2.81582771','d8c4177d09f8b11f5.52725521',2,3,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d206a333d2.74422678','d8c4177d09f8b11f5.52725521',4,5,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d225791924.30714721','d8c4177d09f8b11f5.52725521',6,7,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d2380fc201.39666694','d8c4177d09f8b11f5.52725521',8,9,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d24ccef970.14957925','d8c4177d09f8b11f5.52725521',10,11,
+'d8c4177d09f8b11f5.52725522');
EXPLAIN
SELECT s.oxid FROM t1 v, t1 s
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
s.oxleft > v.oxleft AND s.oxleft < v.oxright;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 5 Using where
-1 SIMPLE s ALL OXLEFT NULL NULL NULL 6 Range checked for each record (index map: 0x4)
+1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 5 Using index condition
+1 SIMPLE s ALL OXLEFT NULL NULL NULL 12 Range checked for each record (index map: 0x4)
SELECT s.oxid FROM t1 v, t1 s
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
@@ -878,10 +890,10 @@ INSERT INTO t1 VALUES
(55,'C'), (56,'C'), (57,'C'), (58,'C'), (59,'C'), (60,'C');
EXPLAIN SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range status status 23 NULL 11 Using where
+1 SIMPLE t1 range status status 23 NULL 11 Using index condition
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
SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B';
id status
53 C
@@ -910,10 +922,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range status status 23 NULL 11 Using where; Using index
EXPLAIN SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range status status 23 NULL 10 Using where
+1 SIMPLE t1 range status status 23 NULL 10 Using index condition
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 where
SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B';
id status
53 C
@@ -1014,20 +1026,20 @@ create table t2 (a varchar(10), filler char(200), key(a));
insert into t2 select * from t1;
explain select * from t1 where a between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 13 NULL # Using where
+1 SIMPLE t1 range a a 13 NULL # Using index condition
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 where
explain select * from t2 where a between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref a a 13 const # Using 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; Using where
update t1 set a='b' where a<>'a';
explain select * from t1 where a not between 'b' and 'b';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 13 NULL # Using where
+1 SIMPLE t1 range a a 13 NULL # Using index condition
select a, hex(filler) from t1 where a not between 'b' and 'b';
a hex(filler)
a 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
@@ -1071,7 +1083,7 @@ 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
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
@@ -1103,17 +1115,11 @@ 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
-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
+1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using index condition
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
item started price
-A1 2005-11-01 08:00:00 1000.000
-A1 2005-11-15 00:00:00 2000.000
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
+Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00'
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
item started price
A1 2005-11-01 08:00:00 1000.000
@@ -1122,14 +1128,10 @@ DROP INDEX `PRIMARY` ON t1;
EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
-Warnings:
-Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
item started price
-A1 2005-11-01 08:00:00 1000.000
-A1 2005-11-15 00:00:00 2000.000
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'
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
item started price
A1 2005-11-01 08:00:00 1000.000
@@ -1151,7 +1153,7 @@ INSERT INTO t1 VALUES
This must use range access:
explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '2007-01-02 23:59:59';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range dateval dateval 4 NULL 2 Using where
+1 SIMPLE t1 range dateval dateval 4 NULL 2 Using index condition
drop table t1;
CREATE TABLE t1 (
a varchar(32), index (a)
@@ -1217,7 +1219,7 @@ Z
In following EXPLAIN the access method should be ref, #rows~=500 (and not 2)
explain select * from t2 where a=1000 and b<11;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref a a 5 const 502 Using 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 ) );
@@ -1579,21 +1581,20 @@ str_to_date('2007-10-00', '%Y-%m-%d') >= '' AND
str_to_date('2007-10-00', '%Y-%m-%d') <= '2007/10/20'
1
Warnings:
-Warning 1292 Truncated incorrect date value: ''
+Warning 1292 Incorrect datetime value: ''
SELECT str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND
str_to_date('2007-20-00', '%Y-%m-%d') <= '';
str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND
str_to_date('2007-20-00', '%Y-%m-%d') <= ''
NULL
Warnings:
-Warning 1292 Truncated incorrect date value: ''
Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20';
str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20'
1
Warnings:
-Warning 1292 Truncated incorrect datetime value: ''
+Warning 1292 Incorrect datetime value: ''
SELECT str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND '';
str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND ''
NULL
@@ -1689,7 +1690,7 @@ pk i4
EXPLAIN
SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range i4_uq i4_uq 5 NULL 3 Using where
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 3 Using index condition
SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4;
pk i4
1 10
@@ -1698,7 +1699,7 @@ pk i4
EXPLAIN
SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using where
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using index condition
SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10;
pk i4
1 10
@@ -1732,7 +1733,7 @@ pk i4
EXPLAIN
SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range i4_uq i4_uq 5 NULL 2 Using where
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 2 Using index condition
SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999;
pk i4
1 10
@@ -1747,7 +1748,7 @@ pk i4
EXPLAIN
SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using where
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using index condition
SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20';
pk i4
1 10
@@ -1756,14 +1757,14 @@ EXPLAIN
SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using where
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using index condition
SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4;
pk i4 pk i4
EXPLAIN
SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using where
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using index condition
SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk;
pk i4 pk i4
DROP TABLE t1;
@@ -1900,3 +1901,55 @@ a b c
2 2 0
2 2 1
drop table t1;
+create table t1 (f1 datetime, key (f1));
+insert into t1 values ('2000-03-09 15:56:59'),('2000-05-05 23:24:28'),('2000-06-13 13:12:06');
+select min(f1) from t1 where f1 >= '2006-05-25 07:00:20' and f1 between '2003-11-23 10:00:09' and '2010-01-01 01:01:01' and f1 > '2001-01-01 01:01:01';
+min(f1)
+NULL
+drop table t1;
+#
+# BUG#11765831: 'RANGE ACCESS' MAY INCORRECTLY FILTER
+# AWAY QUALIFYING ROWS
+#
+CREATE TABLE t10(
+K INT NOT NULL AUTO_INCREMENT,
+I INT, J INT,
+PRIMARY KEY(K),
+KEY(I,J)
+);
+INSERT INTO t10(I,J) VALUES (6,1),(6,2),(6,3),(6,4),(6,5),
+(6,6),(6,7),(6,8),(6,9),(6,0);
+CREATE TABLE t100 LIKE t10;
+INSERT INTO t100(I,J) SELECT X.I, X.K+(10*Y.K) FROM t10 AS X,t10 AS Y;
+INSERT INTO t100(I,J) VALUES(8,26);
+
+EXPLAIN SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t100 range I I 10 NULL 4 Using index condition; Using where
+
+SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5);
+K I J
+101 8 26
+DROP TABLE t10,t100;
+#
+# lp:817363: Wrong result with sort_union and multipart key in maria-5.3
+#
+CREATE TABLE t1 (a int NOT NULL , b int, c int, d varchar(32), KEY (d,b), PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (7,7,NULL,'e'),(8,1,0,'p'),(9,7,1,'s'),(10,1,1,'j'),(12,2,0,'c'),(13,0,0,'a'),(14,1,1,'q');
+SELECT c FROM t1 WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
+c
+1
+1
+SELECT c FROM t1 ignore index (d) WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
+c
+1
+1
+SELECT * FROM t1 ignore index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
+a b c d
+9 7 1 s
+14 1 1 q
+SELECT * FROM t1 force index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
+a b c d
+14 1 1 q
+9 7 1 s
+DROP TABLE t1;
diff --git a/mysql-test/r/range_mrr_icp.result b/mysql-test/r/range_mrr_icp.result
new file mode 100644
index 00000000000..74397909ea8
--- /dev/null
+++ b/mysql-test/r/range_mrr_icp.result
@@ -0,0 +1,1958 @@
+set @mrr_icp_extra_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+drop table if exists t1, t2, t3, t10, t100;
+CREATE TABLE t1 (
+event_date date DEFAULT '0000-00-00' NOT NULL,
+type int(11) DEFAULT '0' NOT NULL,
+event_id int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (event_date,type,event_id)
+);
+INSERT INTO t1 VALUES ('1999-07-10',100100,24), ('1999-07-11',100100,25),
+('1999-07-13',100600,0), ('1999-07-13',100600,4), ('1999-07-13',100600,26),
+('1999-07-14',100600,10), ('1999-07-15',100600,16), ('1999-07-15',100800,45),
+('1999-07-15',101000,47), ('1999-07-16',100800,46), ('1999-07-20',100600,5),
+('1999-07-20',100600,27), ('1999-07-21',100600,11), ('1999-07-22',100600,17),
+('1999-07-23',100100,39), ('1999-07-24',100100,39), ('1999-07-24',100500,40),
+('1999-07-25',100100,39), ('1999-07-27',100600,1), ('1999-07-27',100600,6),
+('1999-07-27',100600,28), ('1999-07-28',100600,12), ('1999-07-29',100500,41),
+('1999-07-29',100600,18), ('1999-07-30',100500,41), ('1999-07-31',100500,41),
+('1999-08-01',100700,34), ('1999-08-03',100600,7), ('1999-08-03',100600,29),
+('1999-08-04',100600,13), ('1999-08-05',100500,42), ('1999-08-05',100600,19),
+('1999-08-06',100500,42), ('1999-08-07',100500,42), ('1999-08-08',100500,42),
+('1999-08-10',100600,2), ('1999-08-10',100600,9), ('1999-08-10',100600,30),
+('1999-08-11',100600,14), ('1999-08-12',100600,20), ('1999-08-17',100500,8),
+('1999-08-17',100600,31), ('1999-08-18',100600,15), ('1999-08-19',100600,22),
+('1999-08-24',100600,3), ('1999-08-24',100600,32), ('1999-08-27',100500,43),
+('1999-08-31',100600,33), ('1999-09-17',100100,37), ('1999-09-18',100100,37),
+('1999-09-19',100100,37), ('2000-12-18',100700,38);
+select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date;
+event_date type event_id
+1999-07-10 100100 24
+1999-07-11 100100 25
+1999-07-13 100600 0
+1999-07-13 100600 4
+1999-07-13 100600 26
+1999-07-14 100600 10
+explain select event_date,type,event_id from t1 WHERE type = 100601 and event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date <= "1999-07-15" AND (type=100600 OR type=100100) or event_date >= "1999-07-01" AND event_date <= "1999-07-15" AND type=100099;
+event_date type event_id
+1999-07-10 100100 24
+1999-07-11 100100 25
+1999-07-13 100600 0
+1999-07-13 100600 4
+1999-07-13 100600 26
+1999-07-14 100600 10
+1999-07-15 100600 16
+drop table t1;
+CREATE TABLE t1 (
+PAPER_ID smallint(6) DEFAULT '0' NOT NULL,
+YEAR smallint(6) DEFAULT '0' NOT NULL,
+ISSUE smallint(6) DEFAULT '0' NOT NULL,
+CLOSED tinyint(4) DEFAULT '0' NOT NULL,
+ISS_DATE date DEFAULT '0000-00-00' NOT NULL,
+PRIMARY KEY (PAPER_ID,YEAR,ISSUE)
+);
+INSERT INTO t1 VALUES (3,1999,34,0,'1999-07-12'), (1,1999,111,0,'1999-03-23'),
+(1,1999,222,0,'1999-03-23'), (3,1999,33,0,'1999-07-12'),
+(3,1999,32,0,'1999-07-12'), (3,1999,31,0,'1999-07-12'),
+(3,1999,30,0,'1999-07-12'), (3,1999,29,0,'1999-07-12'),
+(3,1999,28,0,'1999-07-12'), (1,1999,40,1,'1999-05-01'),
+(1,1999,41,1,'1999-05-01'), (1,1999,42,1,'1999-05-01'),
+(1,1999,46,1,'1999-05-01'), (1,1999,47,1,'1999-05-01'),
+(1,1999,48,1,'1999-05-01'), (1,1999,49,1,'1999-05-01'),
+(1,1999,50,0,'1999-05-01'), (1,1999,51,0,'1999-05-01'),
+(1,1999,200,0,'1999-06-28'), (1,1999,52,0,'1999-06-28'),
+(1,1999,53,0,'1999-06-28'), (1,1999,54,0,'1999-06-28'),
+(1,1999,55,0,'1999-06-28'), (1,1999,56,0,'1999-07-01'),
+(1,1999,57,0,'1999-07-01'), (1,1999,58,0,'1999-07-01'),
+(1,1999,59,0,'1999-07-01'), (1,1999,60,0,'1999-07-01'),
+(3,1999,35,0,'1999-07-12');
+select YEAR,ISSUE from t1 where PAPER_ID=3 and (YEAR>1999 or (YEAR=1999 and ISSUE>28)) order by YEAR,ISSUE;
+YEAR ISSUE
+1999 29
+1999 30
+1999 31
+1999 32
+1999 33
+1999 34
+1999 35
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+repair table t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+);
+INSERT INTO t1 VALUES (1,0,0), (3,1,1), (4,1,1), (8,2,2), (9,2,2), (17,3,2),
+(22,4,2), (24,4,2), (28,5,2), (29,5,2), (30,5,2), (31,6,2), (32,6,2), (33,6,2),
+(203,7,2), (202,7,2), (20,3,2), (157,0,0), (193,5,2), (40,7,2), (2,1,1),
+(15,2,2), (6,1,1), (34,6,2), (35,6,2), (16,3,2), (7,1,1), (36,7,2), (18,3,2),
+(26,5,2), (27,5,2), (183,4,2), (38,7,2), (25,5,2), (37,7,2), (21,4,2),
+(19,3,2), (5,1,1), (179,5,2);
+SELECT * FROM t1 WHERE level = 1 AND parent_id = 1;
+id parent_id level
+3 1 1
+4 1 1
+2 1 1
+6 1 1
+7 1 1
+5 1 1
+SELECT * FROM t1 WHERE level = 1 AND parent_id = 1 order by id;
+id parent_id level
+2 1 1
+3 1 1
+4 1 1
+5 1 1
+6 1 1
+7 1 1
+drop table t1;
+create table t1(
+Satellite varchar(25) not null,
+SensorMode varchar(25) not null,
+FullImageCornersUpperLeftLongitude double not null,
+FullImageCornersUpperRightLongitude double not null,
+FullImageCornersUpperRightLatitude double not null,
+FullImageCornersLowerRightLatitude double not null,
+index two (Satellite, SensorMode, FullImageCornersUpperLeftLongitude, FullImageCornersUpperRightLongitude, FullImageCornersUpperRightLatitude, FullImageCornersLowerRightLatitude));
+insert into t1 values("OV-3","PAN1",91,-92,40,50);
+insert into t1 values("OV-4","PAN1",91,-92,40,50);
+select * from t1 where t1.Satellite = "OV-3" and t1.SensorMode = "PAN1" and t1.FullImageCornersUpperLeftLongitude > -90.000000 and t1.FullImageCornersUpperRightLongitude < -82.000000;
+Satellite SensorMode FullImageCornersUpperLeftLongitude FullImageCornersUpperRightLongitude FullImageCornersUpperRightLatitude FullImageCornersLowerRightLatitude
+OV-3 PAN1 91 -92 40 50
+drop table t1;
+create table t1 ( aString char(100) not null default "", key aString (aString(10)) );
+insert t1 (aString) values ( "believe in myself" ), ( "believe" ), ("baaa" ), ( "believe in love");
+select * from t1 where aString < "believe in myself" order by aString;
+aString
+baaa
+believe
+believe in love
+select * from t1 where aString > "believe in love" order by aString;
+aString
+believe in myself
+alter table t1 drop key aString;
+select * from t1 where aString < "believe in myself" order by aString;
+aString
+baaa
+believe
+believe in love
+select * from t1 where aString > "believe in love" order by aString;
+aString
+believe in myself
+drop table t1;
+CREATE TABLE t1 (
+t1ID int(10) unsigned NOT NULL auto_increment,
+art binary(1) NOT NULL default '',
+KNR char(5) NOT NULL default '',
+RECHNR char(6) NOT NULL default '',
+POSNR char(2) NOT NULL default '',
+ARTNR char(10) NOT NULL default '',
+TEX char(70) NOT NULL default '',
+PRIMARY KEY (t1ID),
+KEY IdxArt (art),
+KEY IdxKnr (KNR),
+KEY IdxArtnr (ARTNR)
+) ENGINE=MyISAM;
+INSERT INTO t1 (art) VALUES ('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j');
+select count(*) from t1 where upper(art) = 'J';
+count(*)
+213
+select count(*) from t1 where art = 'J' or art = 'j';
+count(*)
+602
+select count(*) from t1 where art = 'j' or art = 'J';
+count(*)
+602
+select count(*) from t1 where art = 'j';
+count(*)
+389
+select count(*) from t1 where art = 'J';
+count(*)
+213
+drop table t1;
+create table t1 (x int, y int, index(x), index(y));
+insert into t1 (x) values (1),(2),(3),(4),(5),(6),(7),(8),(9);
+update t1 set y=x;
+explain select * from t1, t1 t2 where t1.y = 8 and t2.x between 7 and t1.y+0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+explain select * from t1, t1 t2 where t1.y = 8 and t2.x >= 7 and t2.x <= t1.y+0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 3 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 3 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+explain select count(*) from t1 where x in (1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref x x 5 const 1 Using index
+explain select count(*) from t1 where x in (1,2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index x x 5 NULL 9 Using where; Using index
+drop table t1;
+CREATE TABLE t1 (key1 int(11) NOT NULL default '0', KEY i1 (key1));
+INSERT INTO t1 VALUES (0),(0),(0),(0),(0),(1),(1);
+CREATE TABLE t2 (keya int(11) NOT NULL default '0', KEY j1 (keya));
+INSERT INTO t2 VALUES (0),(0),(1),(1),(2),(2);
+explain select * from t1, t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref j1 j1 4 const 1 Using index
+1 SIMPLE t1 index i1 i1 4 NULL 7 Using where; Using index; Using join buffer (flat, BNL join)
+explain select * from t1 force index(i1), t2 force index(j1) where
+(t1.key1 <t2.keya + 1) and t2.keya=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref j1 j1 4 const 1 Using index
+1 SIMPLE t1 index i1 i1 4 NULL 7 Using where; Using index; Using join buffer (flat, BNL join)
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+a int(11) default NULL,
+b int(11) default NULL,
+KEY a (a),
+KEY b (b)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+(1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,2),(10,2),
+(13,2),(14,2),(15,2),(16,2),(17,3),(17,3),(16,3),(17,3),(19,3),(20,3),
+(21,4),(22,5),(23,5),(24,5),(25,5),(26,5),(30,5),(31,5),(32,5),(33,5),
+(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
+EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a,b a 5 NULL 2 Using index condition; Using where; Rowid-ordered scan
+SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
+a b
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int, c int, INDEX (c,a,b));
+INSERT INTO t1 VALUES (1,0,0),(1,0,0),(1,0,0);
+INSERT INTO t1 VALUES (0,1,0),(0,1,0),(0,1,0);
+SELECT COUNT(*) FROM t1 WHERE (c=0 and a=1) or (c=0 and b=1);
+COUNT(*)
+6
+SELECT COUNT(*) FROM t1 WHERE (c=0 and b=1) or (c=0 and a=1);
+COUNT(*)
+6
+DROP TABLE t1;
+CREATE TABLE t1 ( a int not null, b int not null, INDEX ab(a,b) );
+INSERT INTO t1 VALUES (47,1), (70,1), (15,1), (15, 4);
+SELECT * FROM t1
+WHERE
+(
+( b =1 AND a BETWEEN 14 AND 21 ) OR
+( b =2 AND a BETWEEN 16 AND 18 ) OR
+( b =3 AND a BETWEEN 15 AND 19 ) OR
+(a BETWEEN 19 AND 47)
+);
+a b
+15 1
+47 1
+DROP TABLE t1;
+CREATE TABLE t1 (
+id int( 11 ) unsigned NOT NULL AUTO_INCREMENT ,
+line int( 5 ) unsigned NOT NULL default '0',
+columnid int( 3 ) unsigned NOT NULL default '0',
+owner int( 3 ) unsigned NOT NULL default '0',
+ordinal int( 3 ) unsigned NOT NULL default '0',
+showid smallint( 6 ) unsigned NOT NULL default '1',
+tableid int( 1 ) unsigned NOT NULL default '1',
+content int( 5 ) unsigned NOT NULL default '188',
+PRIMARY KEY ( owner, id ) ,
+KEY menu( owner, showid, columnid ) ,
+KEY `COLUMN` ( owner, columnid, line ) ,
+KEY `LINES` ( owner, tableid, content, id ) ,
+KEY recount( owner, line )
+) ENGINE = MYISAM;
+INSERT into t1 (owner,id,columnid,line) values (11,15,15,1),(11,13,13,5);
+SELECT id, columnid, tableid, content, showid, line, ordinal FROM t1 WHERE owner=11 AND ((columnid IN ( 15, 13, 14 ) AND line IN ( 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 31 )) OR (columnid IN ( 13, 14 ) AND line IN ( 15 ))) LIMIT 0 , 30;
+id columnid tableid content showid line ordinal
+13 13 1 188 1 5 0
+15 15 1 188 1 1 0
+drop table t1;
+create table t1 (id int(10) primary key);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
+select id from t1 where id in (2,5,9) ;
+id
+2
+5
+9
+select id from t1 where id=2 or id=5 or id=9 ;
+id
+2
+5
+9
+drop table t1;
+create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2));
+insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"),
+(3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"),
+(6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"),
+(9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"),
+(12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"),
+(15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"),
+(18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa");
+select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1;
+id1 idnull
+drop table t1;
+create table t1 (
+id int not null auto_increment,
+name char(1) not null,
+uid int not null,
+primary key (id),
+index uid_index (uid));
+create table t2 (
+id int not null auto_increment,
+name char(1) not null,
+uid int not null,
+primary key (id),
+index uid_index (uid));
+insert into t1(id, uid, name) values(1, 0, ' ');
+insert into t1(uid, name) values(0, ' ');
+insert into t2(uid, name) select uid, name from t1;
+insert into t1(uid, name) select uid, name from t2;
+insert into t2(uid, name) select uid, name from t1;
+insert into t1(uid, name) select uid, name from t2;
+insert into t2(uid, name) select uid, name from t1;
+insert into t1(uid, name) select uid, name from t2;
+insert into t2(uid, name) select uid, name from t1;
+insert into t1(uid, name) select uid, name from t2;
+insert into t2(uid, name) select uid, name from t1;
+insert into t1(uid, name) select uid, name from t2;
+insert into t2(uid, name) select uid, name from t1;
+insert into t2(uid, name) select uid, name from t1;
+insert into t2(uid, name) select uid, name from t1;
+insert into t2(uid, name) select uid, name from t1;
+insert into t1(uid, name) select uid, name from t2;
+delete from t2;
+insert into t2(uid, name) values
+(1, CHAR(64+1)),
+(2, CHAR(64+2)),
+(3, CHAR(64+3)),
+(4, CHAR(64+4)),
+(5, CHAR(64+5)),
+(6, CHAR(64+6)),
+(7, CHAR(64+7)),
+(8, CHAR(64+8)),
+(9, CHAR(64+9)),
+(10, CHAR(64+10)),
+(11, CHAR(64+11)),
+(12, CHAR(64+12)),
+(13, CHAR(64+13)),
+(14, CHAR(64+14)),
+(15, CHAR(64+15)),
+(16, CHAR(64+16)),
+(17, CHAR(64+17)),
+(18, CHAR(64+18)),
+(19, CHAR(64+19)),
+(20, CHAR(64+20)),
+(21, CHAR(64+21)),
+(22, CHAR(64+22)),
+(23, CHAR(64+23)),
+(24, CHAR(64+24)),
+(25, CHAR(64+25)),
+(26, CHAR(64+26));
+insert into t1(uid, name) select uid, name from t2 order by uid;
+delete from t2;
+insert into t2(id, uid, name) select id, uid, name from t1;
+select count(*) from t1;
+count(*)
+1026
+select count(*) from t2;
+count(*)
+1026
+analyze table t1,t2;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+test.t2 analyze status Table is already up to date
+explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
+explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
+explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
+explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid != 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
+select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
+id name uid id name uid
+1001 A 1 1001 A 1
+1002 B 2 1002 B 2
+1003 C 3 1003 C 3
+1004 D 4 1004 D 4
+1005 E 5 1005 E 5
+1006 F 6 1006 F 6
+1007 G 7 1007 G 7
+1008 H 8 1008 H 8
+1009 I 9 1009 I 9
+1010 J 10 1010 J 10
+1011 K 11 1011 K 11
+1012 L 12 1012 L 12
+1013 M 13 1013 M 13
+1014 N 14 1014 N 14
+1015 O 15 1015 O 15
+1016 P 16 1016 P 16
+1017 Q 17 1017 Q 17
+1018 R 18 1018 R 18
+1019 S 19 1019 S 19
+1020 T 20 1020 T 20
+1021 U 21 1021 U 21
+1022 V 22 1022 V 22
+1023 W 23 1023 W 23
+1024 X 24 1024 X 24
+1025 Y 25 1025 Y 25
+1026 Z 26 1026 Z 26
+select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
+id name uid id name uid
+1001 A 1 1001 A 1
+1002 B 2 1002 B 2
+1003 C 3 1003 C 3
+1004 D 4 1004 D 4
+1005 E 5 1005 E 5
+1006 F 6 1006 F 6
+1007 G 7 1007 G 7
+1008 H 8 1008 H 8
+1009 I 9 1009 I 9
+1010 J 10 1010 J 10
+1011 K 11 1011 K 11
+1012 L 12 1012 L 12
+1013 M 13 1013 M 13
+1014 N 14 1014 N 14
+1015 O 15 1015 O 15
+1016 P 16 1016 P 16
+1017 Q 17 1017 Q 17
+1018 R 18 1018 R 18
+1019 S 19 1019 S 19
+1020 T 20 1020 T 20
+1021 U 21 1021 U 21
+1022 V 22 1022 V 22
+1023 W 23 1023 W 23
+1024 X 24 1024 X 24
+1025 Y 25 1025 Y 25
+1026 Z 26 1026 Z 26
+drop table t1,t2;
+create table t1 (x bigint unsigned not null);
+insert into t1(x) values (0xfffffffffffffff0);
+insert into t1(x) values (0xfffffffffffffff1);
+select * from t1;
+x
+18446744073709551600
+18446744073709551601
+select count(*) from t1 where x>0;
+count(*)
+2
+select count(*) from t1 where x=0;
+count(*)
+0
+select count(*) from t1 where x<0;
+count(*)
+0
+select count(*) from t1 where x < -16;
+count(*)
+0
+select count(*) from t1 where x = -16;
+count(*)
+0
+select count(*) from t1 where x > -16;
+count(*)
+2
+select count(*) from t1 where x = 18446744073709551601;
+count(*)
+1
+create table t2 (x bigint not null);
+insert into t2(x) values (-16);
+insert into t2(x) values (-15);
+select * from t2;
+x
+-16
+-15
+select count(*) from t2 where x>0;
+count(*)
+0
+select count(*) from t2 where x=0;
+count(*)
+0
+select count(*) from t2 where x<0;
+count(*)
+2
+select count(*) from t2 where x < -16;
+count(*)
+0
+select count(*) from t2 where x = -16;
+count(*)
+1
+select count(*) from t2 where x > -16;
+count(*)
+1
+select count(*) from t2 where x = 18446744073709551601;
+count(*)
+0
+drop table t1,t2;
+create table t1 (x bigint unsigned not null primary key) engine=innodb;
+insert into t1(x) values (0xfffffffffffffff0);
+insert into t1(x) values (0xfffffffffffffff1);
+select * from t1;
+x
+18446744073709551600
+18446744073709551601
+select count(*) from t1 where x>0;
+count(*)
+2
+select count(*) from t1 where x=0;
+count(*)
+0
+select count(*) from t1 where x<0;
+count(*)
+0
+select count(*) from t1 where x < -16;
+count(*)
+0
+select count(*) from t1 where x = -16;
+count(*)
+0
+select count(*) from t1 where x > -16;
+count(*)
+2
+select count(*) from t1 where x = 18446744073709551601;
+count(*)
+1
+drop table t1;
+create table t1 (a bigint unsigned);
+create index t1i on t1(a);
+insert into t1 select 18446744073709551615;
+insert into t1 select 18446744073709551614;
+explain select * from t1 where a <> -1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index t1i t1i 9 NULL 2 Using where; Using index
+select * from t1 where a <> -1;
+a
+18446744073709551614
+18446744073709551615
+explain select * from t1 where a > -1 or a < -1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index t1i t1i 9 NULL 2 Using where; Using index
+select * from t1 where a > -1 or a < -1;
+a
+18446744073709551614
+18446744073709551615
+explain select * from t1 where a > -1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index t1i t1i 9 NULL 2 Using where; Using index
+select * from t1 where a > -1;
+a
+18446744073709551614
+18446744073709551615
+explain select * from t1 where a < -1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+select * from t1 where a < -1;
+a
+drop table t1;
+set names latin1;
+create table t1 (a char(10), b text, key (a)) character set latin1;
+INSERT INTO t1 (a) VALUES
+('111'),('222'),('222'),('222'),('222'),('444'),('aaa'),('AAA'),('bbb');
+explain select * from t1 where a='aaa';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref a a 11 const 2 Using index condition
+explain select * from t1 where a=binary 'aaa';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 11 NULL 2 Using index condition; Rowid-ordered scan
+explain select * from t1 where a='aaa' collate latin1_bin;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 11 NULL 2 Using index condition; Rowid-ordered scan
+explain select * from t1 where a='aaa' collate latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 9 Using where
+drop table t1;
+CREATE TABLE t1 (
+`CLIENT` char(3) character set latin1 collate latin1_bin NOT NULL default '000',
+`ARG1` char(3) character set latin1 collate latin1_bin NOT NULL default '',
+`ARG2` char(3) character set latin1 collate latin1_bin NOT NULL default '',
+`FUNCTION` varchar(10) character set latin1 collate latin1_bin NOT NULL default '',
+`FUNCTINT` int(11) NOT NULL default '0',
+KEY `VERI_CLNT~2` (`ARG1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES ('000',' 0',' 0','Text 001',0), ('000',' 0',' 1','Text 002',0),
+('000',' 1',' 2','Text 003',0), ('000',' 2',' 3','Text 004',0),
+('001',' 3',' 0','Text 017',0);
+SELECT count(*) FROM t1 WHERE CLIENT='000' AND (ARG1 != ' 1' OR ARG1 != ' 2');
+count(*)
+4
+SELECT count(*) FROM t1 WHERE CLIENT='000' AND (ARG1 != ' 2' OR ARG1 != ' 1');
+count(*)
+4
+drop table t1;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+CREATE TABLE t2 (
+pk1 int(11) NOT NULL,
+pk2 int(11) NOT NULL,
+pk3 int(11) NOT NULL,
+pk4 int(11) NOT NULL,
+filler char(82),
+PRIMARY KEY (pk1,pk2,pk3,pk4)
+) DEFAULT CHARSET=latin1;
+insert into t2 select 1, A.a+10*B.a, 432, 44, 'fillerZ' from t1 A, t1 B;
+INSERT INTO t2 VALUES (2621, 2635, 0, 0,'filler'), (2621, 2635, 1, 0,'filler'),
+(2621, 2635, 10, 0,'filler'), (2621, 2635, 11, 0,'filler'),
+(2621, 2635, 14, 0,'filler'), (2621, 2635, 1000015, 0,'filler');
+SELECT * FROM t2
+WHERE ((((pk4 =0) AND (pk1 =2621) AND (pk2 =2635)))
+OR ((pk4 =1) AND (((pk1 IN ( 7, 2, 1 ))) OR (pk1 =522)) AND ((pk2 IN ( 0, 2635))))
+) AND (pk3 >=1000000);
+pk1 pk2 pk3 pk4 filler
+2621 2635 1000015 0 filler
+drop table t1, t2;
+create table t1(a char(2), key(a(1)));
+insert into t1 values ('x'), ('xx');
+explain select a from t1 where a > 'x';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 2 NULL 2 Using where
+select a from t1 where a > 'x';
+a
+xx
+drop table t1;
+CREATE TABLE t1 (
+OXID varchar(32) COLLATE latin1_german2_ci NOT NULL DEFAULT '',
+OXPARENTID varchar(32) COLLATE latin1_german2_ci NOT NULL DEFAULT 'oxrootid',
+OXLEFT int NOT NULL DEFAULT '0',
+OXRIGHT int NOT NULL DEFAULT '0',
+OXROOTID varchar(32) COLLATE latin1_german2_ci NOT NULL DEFAULT '',
+PRIMARY KEY (OXID),
+KEY OXNID (OXID),
+KEY OXLEFT (OXLEFT),
+KEY OXRIGHT (OXRIGHT),
+KEY OXROOTID (OXROOTID)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci;
+INSERT INTO t1 VALUES
+('d8c4177d09f8b11f5.52725521','oxrootid',1,40,'d8c4177d09f8b11f5.52725521'),
+('d8c4177d151affab2.81582770','d8c4177d09f8b11f5.52725521',2,3,
+'d8c4177d09f8b11f5.52725521'),
+('d8c4177d206a333d2.74422679','d8c4177d09f8b11f5.52725521',4,5,
+'d8c4177d09f8b11f5.52725521'),
+('d8c4177d225791924.30714720','d8c4177d09f8b11f5.52725521',6,7,
+'d8c4177d09f8b11f5.52725521'),
+('d8c4177d2380fc201.39666693','d8c4177d09f8b11f5.52725521',8,9,
+'d8c4177d09f8b11f5.52725521'),
+('d8c4177d24ccef970.14957924','d8c4177d09f8b11f5.52725521',10,11,
+'d8c4177d09f8b11f5.52725521');
+INSERT INTO t1 VALUES
+('d8c4177d09f8b11f5.52725522','oxrootid',1,40,'d8c4177d09f8b11f5.52725522'),
+('d8c4177d151affab2.81582771','d8c4177d09f8b11f5.52725521',2,3,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d206a333d2.74422678','d8c4177d09f8b11f5.52725521',4,5,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d225791924.30714721','d8c4177d09f8b11f5.52725521',6,7,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d2380fc201.39666694','d8c4177d09f8b11f5.52725521',8,9,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d24ccef970.14957925','d8c4177d09f8b11f5.52725521',10,11,
+'d8c4177d09f8b11f5.52725522');
+EXPLAIN
+SELECT s.oxid FROM t1 v, t1 s
+WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
+v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
+s.oxleft > v.oxleft AND s.oxleft < v.oxright;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 5 Using index condition
+1 SIMPLE s ALL OXLEFT NULL NULL NULL 12 Range checked for each record (index map: 0x4)
+SELECT s.oxid FROM t1 v, t1 s
+WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
+v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
+s.oxleft > v.oxleft AND s.oxleft < v.oxright;
+oxid
+d8c4177d151affab2.81582770
+d8c4177d206a333d2.74422679
+d8c4177d225791924.30714720
+d8c4177d2380fc201.39666693
+d8c4177d24ccef970.14957924
+DROP TABLE t1;
+create table t1 (
+c1 char(10), c2 char(10), c3 char(10), c4 char(10),
+c5 char(10), c6 char(10), c7 char(10), c8 char(10),
+c9 char(10), c10 char(10), c11 char(10), c12 char(10),
+c13 char(10), c14 char(10), c15 char(10), c16 char(10),
+index(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12,c13,c14,c15,c16)
+);
+insert into t1 (c1) values ('1'),('1'),('1'),('1');
+select * from t1 where
+c1 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c2 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c3 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c4 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c5 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c6 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c7 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c8 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c9 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c10 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC");
+c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16
+drop table t1;
+End of 4.1 tests
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+status varchar(20),
+PRIMARY KEY (id),
+KEY (status)
+);
+INSERT INTO t1 VALUES
+(1,'B'), (2,'B'), (3,'B'), (4,'B'), (5,'B'), (6,'B'),
+(7,'B'), (8,'B'), (9,'B'), (10,'B'), (11,'B'), (12,'B'),
+(13,'B'), (14,'B'), (15,'B'), (16,'B'), (17,'B'), (18,'B'),
+(19,'B'), (20,'B'), (21,'B'), (22,'B'), (23,'B'), (24,'B'),
+(25,'A'), (26,'A'), (27,'A'), (28,'A'), (29,'A'), (30,'A'),
+(31,'A'), (32,'A'), (33,'A'), (34,'A'), (35,'A'), (36,'A'),
+(37,'A'), (38,'A'), (39,'A'), (40,'A'), (41,'A'), (42,'A'),
+(43,'A'), (44,'A'), (45,'A'), (46,'A'), (47,'A'), (48,'A'),
+(49,'A'), (50,'A'), (51,'A'), (52,'A'), (53,'C'), (54,'C'),
+(55,'C'), (56,'C'), (57,'C'), (58,'C'), (59,'C'), (60,'C');
+EXPLAIN SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range status status 23 NULL 11 Using index condition; Rowid-ordered scan
+EXPLAIN SELECT * FROM t1 WHERE status NOT IN ('A','B');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range status status 23 NULL 11 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B';
+id status
+53 C
+54 C
+55 C
+56 C
+57 C
+58 C
+59 C
+60 C
+SELECT * FROM t1 WHERE status NOT IN ('A','B');
+id status
+53 C
+54 C
+55 C
+56 C
+57 C
+58 C
+59 C
+60 C
+EXPLAIN SELECT status FROM t1 WHERE status <> 'A' AND status <> 'B';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range status status 23 NULL 11 Using where; Using index
+EXPLAIN SELECT status FROM t1 WHERE status NOT IN ('A','B');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range status status 23 NULL 11 Using where; Using index
+EXPLAIN SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range status status 23 NULL 10 Using index condition; Rowid-ordered scan
+EXPLAIN SELECT * FROM t1 WHERE status < 'A' OR status > 'B';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range status status 23 NULL 10 Using index condition; Using where; Rowid-ordered scan
+SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B';
+id status
+53 C
+54 C
+55 C
+56 C
+57 C
+58 C
+59 C
+60 C
+SELECT * FROM t1 WHERE status < 'A' OR status > 'B';
+id status
+53 C
+54 C
+55 C
+56 C
+57 C
+58 C
+59 C
+60 C
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int, primary key(a,b));
+INSERT INTO t1 VALUES
+(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3),(4,1),(4,2),(4,3);
+CREATE VIEW v1 as SELECT a,b FROM t1 WHERE b=3;
+EXPLAIN SELECT a,b FROM t1 WHERE a < 2 and b=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
+EXPLAIN SELECT a,b FROM v1 WHERE a < 2 and b=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
+EXPLAIN SELECT a,b FROM t1 WHERE a < 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
+EXPLAIN SELECT a,b FROM v1 WHERE a < 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
+SELECT a,b FROM t1 WHERE a < 2 and b=3;
+a b
+1 3
+SELECT a,b FROM v1 WHERE a < 2 and b=3;
+a b
+1 3
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1 (name varchar(15) NOT NULL, KEY idx(name));
+INSERT INTO t1 VALUES ('Betty'), ('Anna');
+SELECT * FROM t1;
+name
+Anna
+Betty
+DELETE FROM t1 WHERE name NOT LIKE 'A%a';
+SELECT * FROM t1;
+name
+Anna
+DROP TABLE t1;
+CREATE TABLE t1 (a int, KEY idx(a));
+INSERT INTO t1 VALUES (NULL), (1), (2), (3);
+SELECT * FROM t1;
+a
+NULL
+1
+2
+3
+DELETE FROM t1 WHERE NOT(a <=> 2);
+SELECT * FROM t1;
+a
+2
+DROP TABLE t1;
+create table t1 (a int, b int, primary key(a,b));
+create view v1 as select a, b from t1;
+INSERT INTO `t1` VALUES
+(0,0),(1,0),(2,0),(3,0),(4,0),(5,1),(6,1),(7,1),(8,1),(9,1),(10,2),(11,2),(12,2)
+,(13,2),(14,2),(15,3),(16,3),(17,3),(18,3),(19,3);
+explain select * from t1 where a in (3,4) and b in (1,2,3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
+explain select * from v1 where a in (3,4) and b in (1,2,3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
+explain select * from t1 where a between 3 and 4 and b between 1 and 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
+explain select * from v1 where a between 3 and 4 and b between 1 and 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
+drop view v1;
+drop table t1;
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a varchar(10), filler char(200), key(a)) charset=binary;
+insert into t1 values ('a','');
+insert into t1 values ('a ','');
+insert into t1 values ('a ', '');
+insert into t1 select concat('a', 1000 + A.a + 10 * (B.a + 10 * C.a)), ''
+ from t3 A, t3 B, t3 C;
+create table t2 (a varchar(10), filler char(200), key(a));
+insert into t2 select * from t1;
+explain select * from t1 where a between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 13 NULL # Using index condition; Rowid-ordered scan
+explain select * from t1 where a = 'a' or a='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 13 NULL # Using index condition; Using where; Rowid-ordered scan
+explain select * from t2 where a between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref a a 13 const # Using index condition
+explain select * from t2 where a = 'a' or a='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref a a 13 const # Using index condition; Using where
+update t1 set a='b' where a<>'a';
+explain select * from t1 where a not between 'b' and 'b';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 13 NULL # Using index condition; Rowid-ordered scan
+select a, hex(filler) from t1 where a not between 'b' and 'b';
+a hex(filler)
+a 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+drop table t1,t2,t3;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, key(a));
+insert into t2 select 2*(A.a + 10*(B.a + 10*C.a)) from t1 A, t1 B, t1 C;
+set @a="select * from t2 force index (a) where a NOT IN(0";
+select count(*) from (select @a:=concat(@a, ',', a) from t2 ) Z;
+count(*)
+1000
+set @a=concat(@a, ')');
+insert into t2 values (11),(13),(15);
+set @b= concat("explain ", @a);
+prepare stmt1 from @b;
+execute stmt1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index a a 5 NULL 1003 Using where; Using index
+prepare stmt1 from @a;
+execute stmt1;
+a
+11
+13
+15
+drop table t1, t2;
+CREATE TABLE t1 (
+id int NOT NULL DEFAULT '0',
+b int NOT NULL DEFAULT '0',
+c int NOT NULL DEFAULT '0',
+INDEX idx1(b,c), INDEX idx2(c));
+INSERT INTO t1(id) VALUES (1), (2), (3), (4), (5), (6), (7), (8);
+INSERT INTO t1(b,c) VALUES (3,4), (3,4);
+SELECT * FROM t1 WHERE b<=3 AND 3<=c;
+id b c
+0 3 4
+0 3 4
+SELECT * FROM t1 WHERE 3 BETWEEN b AND c;
+id b c
+0 3 4
+0 3 4
+EXPLAIN SELECT * FROM t1 WHERE b<=3 AND 3<=c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using index condition; Using where; Rowid-ordered scan
+EXPLAIN SELECT * FROM t1 WHERE 3 BETWEEN b AND c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using where; Rowid-ordered scan
+SELECT * FROM t1 WHERE 0 < b OR 0 > c;
+id b c
+0 3 4
+0 3 4
+SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c;
+id b c
+0 3 4
+0 3 4
+EXPLAIN SELECT * FROM t1 WHERE 0 < b OR 0 > c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where
+EXPLAIN SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where
+DROP TABLE t1;
+CREATE TABLE t1 (
+item char(20) NOT NULL default '',
+started datetime NOT NULL default '0000-00-00 00:00:00',
+price decimal(16,3) NOT NULL default '0.000',
+PRIMARY KEY (item,started)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+('A1','2005-11-01 08:00:00',1000),
+('A1','2005-11-15 00:00:00',2000),
+('A1','2005-12-12 08:00:00',3000),
+('A2','2005-12-01 08:00:00',1000);
+EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using index condition
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+item started price
+Warnings:
+Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00'
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
+item started price
+A1 2005-11-01 08:00:00 1000.000
+A1 2005-11-15 00:00:00 2000.000
+DROP INDEX `PRIMARY` ON t1;
+EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+item started price
+Warnings:
+Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00'
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
+item started price
+A1 2005-11-01 08:00:00 1000.000
+A1 2005-11-15 00:00:00 2000.000
+DROP TABLE t1;
+
+BUG#32198 "Comparison of DATE with DATETIME still not using indexes correctly"
+
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+dateval date default NULL,
+PRIMARY KEY (id),
+KEY dateval (dateval)
+) AUTO_INCREMENT=173;
+INSERT INTO t1 VALUES
+(1,'2007-01-01'),(2,'2007-01-02'),(3,'2007-01-03'),(4,'2007-01-04'),
+(5,'2007-01-05'),(6,'2007-01-06'),(7,'2007-01-07'),(8,'2007-01-08'),
+(9,'2007-01-09'),(10,'2007-01-10'),(11,'2007-01-11');
+This must use range access:
+explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '2007-01-02 23:59:59';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range dateval dateval 4 NULL 2 Using index condition; Rowid-ordered scan
+drop table t1;
+CREATE TABLE t1 (
+a varchar(32), index (a)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_bin;
+INSERT INTO t1 VALUES
+('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A');
+SELECT a FROM t1 WHERE a='b' OR a='B';
+a
+B
+B
+EXPLAIN SELECT a FROM t1 WHERE a='b' OR a='B';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 35 NULL 3 Using where; Using index
+DROP TABLE t1;
+CREATE TABLE t1 (f1 TINYINT(11) UNSIGNED NOT NULL, PRIMARY KEY (f1));
+INSERT INTO t1 VALUES (127),(254),(0),(1),(255);
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < 256;
+COUNT(*)
+5
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < 256.0;
+COUNT(*)
+5
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < 255;
+COUNT(*)
+4
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < -1;
+COUNT(*)
+0
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 > -1;
+COUNT(*)
+5
+DROP TABLE t1;
+CREATE TABLE t1 ( f1 TINYINT(11) NOT NULL, PRIMARY KEY (f1));
+INSERT INTO t1 VALUES (127),(126),(0),(-128),(-127);
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < 128;
+COUNT(*)
+5
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < 128.0;
+COUNT(*)
+5
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < 127;
+COUNT(*)
+4
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 > -129;
+COUNT(*)
+5
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 > -129.0;
+COUNT(*)
+5
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 > -128;
+COUNT(*)
+4
+DROP TABLE t1;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, b int, filler char(100));
+insert into t2 select A.a + 10 * (B.a + 10 * C.a), 10, 'filler' from t1 A,
+t1 B, t1 C where A.a < 5;
+insert into t2 select 1000, b, 'filler' from t2;
+alter table t2 add index (a,b);
+select 'In following EXPLAIN the access method should be ref, #rows~=500 (and not 2)' Z;
+Z
+In following EXPLAIN the access method should be ref, #rows~=500 (and not 2)
+explain select * from t2 where a=1000 and b<11;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref a a 5 const 502 Using index condition
+drop table t1, t2;
+CREATE TABLE t1( a INT, b INT, KEY( a, b ) );
+CREATE TABLE t2( a INT, b INT, KEY( a, b ) );
+CREATE TABLE t3( a INT, b INT, KEY( a, b ) );
+INSERT INTO t1( a, b )
+VALUES (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7);
+INSERT INTO t2( a, b )
+VALUES ( 1, 1), ( 2, 1), ( 3, 1), ( 4, 1), ( 5, 1),
+( 6, 1), ( 7, 1), ( 8, 1), ( 9, 1), (10, 1),
+(11, 1), (12, 1), (13, 1), (14, 1), (15, 1),
+(16, 1), (17, 1), (18, 1), (19, 1), (20, 1);
+INSERT INTO t2 SELECT a, 2 FROM t2 WHERE b = 1;
+INSERT INTO t2 SELECT a, 3 FROM t2 WHERE b = 1;
+INSERT INTO t2 SELECT -1, -1 FROM t2;
+INSERT INTO t2 SELECT -1, -1 FROM t2;
+INSERT INTO t2 SELECT -1, -1 FROM t2;
+INSERT INTO t3
+VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0),
+(6, 0), (7, 0), (8, 0), (9, 0), (10, 0);
+INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
+INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 < a AND b = 3 OR
+3 <= a;
+a b
+5 0
+9 7
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 < a AND b = 3 OR
+3 <= a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+a b
+5 0
+9 7
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+a b
+5 0
+9 7
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+3 <= a;
+a b
+5 0
+9 7
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+3 <= a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 1 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+a b
+1 1
+2 1
+3 1
+4 1
+5 1
+6 1
+7 1
+8 1
+9 1
+10 1
+11 1
+12 1
+13 1
+14 1
+15 1
+15 3
+16 1
+16 3
+17 1
+17 3
+18 1
+18 3
+19 1
+19 3
+20 1
+EXPLAIN
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 1 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 2 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+a b
+1 1
+2 1
+3 1
+4 1
+5 1
+5 2
+6 1
+6 2
+7 1
+7 2
+8 1
+8 2
+9 1
+9 2
+10 1
+11 1
+12 1
+13 1
+14 1
+15 1
+15 3
+16 1
+16 3
+17 1
+17 3
+18 1
+18 3
+19 1
+19 3
+20 1
+EXPLAIN
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 2 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index
+SELECT * FROM t3 WHERE
+5 <= a AND a < 10 AND b = 3 OR
+a < 5 OR
+a < 10;
+a b
+1 0
+2 0
+3 0
+4 0
+5 0
+6 0
+7 0
+8 0
+9 0
+EXPLAIN
+SELECT * FROM t3 WHERE
+5 <= a AND a < 10 AND b = 3 OR
+a < 5 OR
+a < 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range a a 5 NULL 8 Using where; Using index
+DROP TABLE t1, t2, t3;
+#
+# Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN
+#
+CREATE TABLE t1(a INT, KEY(a));
+INSERT INTO t1 VALUES (1), (NULL);
+SELECT * FROM t1 WHERE a <> NULL and (a <> NULL or a <= NULL);
+a
+DROP TABLE t1;
+#
+# Bug#47925: regression of range optimizer and date comparison in 5.1.39!
+#
+CREATE TABLE t1 ( a DATE, KEY ( a ) );
+CREATE TABLE t2 ( a DATETIME, KEY ( a ) );
+# Make optimizer choose range scan
+INSERT INTO t1 VALUES ('2009-09-22'), ('2009-09-22'), ('2009-09-22');
+INSERT INTO t1 VALUES ('2009-09-23'), ('2009-09-23'), ('2009-09-23');
+INSERT INTO t2 VALUES ('2009-09-22 12:00:00'), ('2009-09-22 12:00:00'),
+('2009-09-22 12:00:00');
+INSERT INTO t2 VALUES ('2009-09-23 12:00:00'), ('2009-09-23 12:00:00'),
+('2009-09-23 12:00:00');
+# DATE vs DATE
+EXPLAIN
+SELECT * FROM t1 WHERE a >= '2009/09/23';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t1 WHERE a >= '2009/09/23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '20090923';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= 20090923;
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009-9-23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009.09.23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009:09:23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+# DATE vs DATETIME
+EXPLAIN
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '20090923';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= 20090923;
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009-9-23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009.09.23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009:09:23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+# DATETIME vs DATETIME
+EXPLAIN
+SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '20090923120000';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= 20090923120000;
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009-9-23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009.09.23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009:09:23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+# DATETIME vs DATE
+EXPLAIN
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '20090923000000';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= 20090923000000;
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009-9-23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009.09.23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009:09:23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+# Test of the new get_date_from_str implementation
+# Behavior differs slightly between the trunk and mysql-pe.
+# The former may give errors for the truncated values, while the latter
+# gives warnings. The purpose of this test is not to interfere, and only
+# preserve existing behavior.
+SELECT str_to_date('2007-10-00', '%Y-%m-%d') >= '' AND
+str_to_date('2007-10-00', '%Y-%m-%d') <= '2007/10/20';
+str_to_date('2007-10-00', '%Y-%m-%d') >= '' AND
+str_to_date('2007-10-00', '%Y-%m-%d') <= '2007/10/20'
+1
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND
+str_to_date('2007-20-00', '%Y-%m-%d') <= '';
+str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND
+str_to_date('2007-20-00', '%Y-%m-%d') <= ''
+NULL
+Warnings:
+Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
+Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
+SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20';
+str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20'
+1
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND '';
+str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND ''
+NULL
+Warnings:
+Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
+SELECT str_to_date('', '%Y-%m-%d');
+str_to_date('', '%Y-%m-%d')
+0000-00-00
+DROP TABLE t1, t2;
+#
+# Bug#48459: valgrind errors with query using 'Range checked for each
+# record'
+#
+CREATE TABLE t1 (
+a INT,
+b CHAR(2),
+c INT,
+d INT,
+KEY ( c ),
+KEY ( d, a, b ( 2 ) ),
+KEY ( b ( 1 ) )
+);
+INSERT INTO t1 VALUES ( NULL, 'a', 1, 2 ), ( NULL, 'a', 1, 2 ),
+( 1, 'a', 1, 2 ), ( 1, 'a', 1, 2 );
+CREATE TABLE t2 (
+a INT,
+c INT,
+e INT,
+KEY ( e )
+);
+INSERT INTO t2 VALUES ( 1, 1, NULL ), ( 1, 1, NULL );
+# Should not give Valgrind warnings
+SELECT 1
+FROM t1, t2
+WHERE t1.d <> '1' AND t1.b > '1'
+AND t1.a = t2.a AND t1.c = t2.c;
+1
+1
+1
+1
+1
+DROP TABLE t1, t2;
+#
+# Bug #48665: sql-bench's insert test fails due to wrong result
+#
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a));
+INSERT INTO t1 VALUES (0,0), (1,1);
+EXPLAIN
+SELECT * FROM t1 FORCE INDEX (PRIMARY)
+WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
+id select_type table type possible_keys key key_len ref rows Extra
+@ @ @ range @ @ @ @ @ @
+# Should return 2 rows
+SELECT * FROM t1 FORCE INDEX (PRIMARY)
+WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
+a b
+0 0
+1 1
+DROP TABLE t1;
+#
+# Bug #54802: 'NOT BETWEEN' evaluation is incorrect
+#
+CREATE TABLE t1 (c_key INT, c_notkey INT, KEY(c_key));
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
+EXPLAIN SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL c_key NULL NULL NULL 3 Using where
+SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
+c_key c_notkey
+1 1
+3 3
+DROP TABLE t1;
+#
+# Bug #57030: 'BETWEEN' evaluation is incorrect
+#
+CREATE TABLE t1(pk INT PRIMARY KEY, i4 INT);
+CREATE UNIQUE INDEX i4_uq ON t1(i4);
+INSERT INTO t1 VALUES (1,10), (2,20), (3,30);
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const i4_uq i4_uq 5 const 1
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 10;
+pk i4
+1 10
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND i4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const i4_uq i4_uq 5 const 1
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND i4;
+pk i4
+1 10
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 3 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4;
+pk i4
+1 10
+2 20
+3 30
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10;
+pk i4
+1 10
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND 10;
+pk i4
+1 10
+2 20
+3 30
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 11 AND 11;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+SELECT * FROM t1 WHERE 10 BETWEEN 11 AND 11;
+pk i4
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 100 AND 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+SELECT * FROM t1 WHERE 10 BETWEEN 100 AND 0;
+pk i4
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 100 AND 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT * FROM t1 WHERE i4 BETWEEN 100 AND 0;
+pk i4
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 2 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999;
+pk i4
+1 10
+2 20
+3 30
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 999999999999999 AND 30;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT * FROM t1 WHERE i4 BETWEEN 999999999999999 AND 30;
+pk i4
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20';
+pk i4
+1 10
+2 20
+EXPLAIN
+SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using index condition
+SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4;
+pk i4 pk i4
+EXPLAIN
+SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using index condition
+SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk;
+pk i4 pk i4
+DROP TABLE t1;
+#
+# BUG#13519696 - 62940: SELECT RESULTS VARY WITH VERSION AND
+# WITH/WITHOUT INDEX RANGE SCAN
+#
+create table t1 (id int unsigned not null auto_increment primary key);
+insert into t1 values (null);
+insert into t1 select null from t1;
+insert into t1 select null from t1;
+insert into t1 select null from t1;
+insert into t1 select null from t1;
+insert into t1 select null from t1;
+insert into t1 select null from t1;
+insert into t1 select null from t1;
+insert into t1 select null from t1;
+create table t2 (
+id int unsigned not null auto_increment,
+val decimal(5,3) not null,
+primary key (id,val),
+unique key (val,id),
+unique key (id));
+insert into t2 select null,id*0.0009 from t1;
+select count(val) from t2 ignore index (val) where val > 0.1155;
+count(val)
+128
+select count(val) from t2 force index (val) where val > 0.1155;
+count(val)
+128
+drop table t2, t1;
+#
+# BUG#13453382 - REGRESSION SINCE 5.1.39, RANGE OPTIMIZER WRONG
+# RESULTS WITH DECIMAL CONVERSION
+#
+create table t1 (a int,b int,c int,primary key (a,c));
+insert into t1 values (1,1,2),(1,1,3),(1,1,4);
+select convert(3, signed integer) > 2.9;
+convert(3, signed integer) > 2.9
+1
+select * from t1 force index (primary) where a=1 and c>= 2.9;
+a b c
+1 1 3
+1 1 4
+select * from t1 ignore index (primary) where a=1 and c>= 2.9;
+a b c
+1 1 3
+1 1 4
+select * from t1 force index (primary) where a=1 and c> 2.9;
+a b c
+1 1 3
+1 1 4
+select * from t1 ignore index (primary) where a=1 and c> 2.9;
+a b c
+1 1 3
+1 1 4
+drop table t1;
+#
+# BUG#13463488 - 63437: CHAR & BETWEEN WITH INDEX RETURNS WRONG
+# RESULT AFTER MYSQL 5.1.
+#
+CREATE TABLE t1(
+F1 CHAR(5) NOT NULL,
+F2 CHAR(5) NOT NULL,
+F3 CHAR(5) NOT NULL,
+PRIMARY KEY(F1),
+INDEX IDX_F2(F2)
+);
+INSERT INTO t1 VALUES
+('A','A','A'),('AA','AA','AA'),('AAA','AAA','AAA'),
+('AAAA','AAAA','AAAA'),('AAAAA','AAAAA','AAAAA');
+SELECT * FROM t1 WHERE F1 = 'A ';
+F1 F2 F3
+A A A
+SELECT * FROM t1 IGNORE INDEX(PRIMARY) WHERE F1 = 'A ';
+F1 F2 F3
+A A A
+SELECT * FROM t1 WHERE F1 >= 'A ';
+F1 F2 F3
+A A A
+AA AA AA
+AAA AAA AAA
+AAAA AAAA AAAA
+AAAAA AAAAA AAAAA
+SELECT * FROM t1 WHERE F1 > 'A ';
+F1 F2 F3
+AA AA AA
+AAA AAA AAA
+AAAA AAAA AAAA
+AAAAA AAAAA AAAAA
+SELECT * FROM t1 WHERE F1 BETWEEN 'A ' AND 'AAAAA';
+F1 F2 F3
+A A A
+AA AA AA
+AAA AAA AAA
+AAAA AAAA AAAA
+AAAAA AAAAA AAAAA
+SELECT * FROM t1 WHERE F2 BETWEEN 'A ' AND 'AAAAA';
+F1 F2 F3
+A A A
+AA AA AA
+AAA AAA AAA
+AAAA AAAA AAAA
+AAAAA AAAAA AAAAA
+SELECT * FROM t1 WHERE F3 BETWEEN 'A ' AND 'AAAAA';
+F1 F2 F3
+A A A
+AA AA AA
+AAA AAA AAA
+AAAA AAAA AAAA
+AAAAA AAAAA AAAAA
+SELECT * FROM t1 IGNORE INDEX(PRIMARY) WHERE F1 BETWEEN 'A ' AND
+'AAAAA';
+F1 F2 F3
+A A A
+AA AA AA
+AAA AAA AAA
+AAAA AAAA AAAA
+AAAAA AAAAA AAAAA
+DROP TABLE t1;
+End of 5.1 tests
+#
+# LP Bug #533117: Wrong use_count in SEL_ARG trees
+# (Bug #58731)
+#
+create table t1 (a int, b int, c int, key idx (a,b,c));
+insert into t1 values (0,0,0), (2,2,0), (1,1,1), (2,2,1);
+explain
+select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx idx 5 NULL 3 Using where; Using index
+select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1;
+a b c
+2 2 0
+2 2 1
+drop table t1;
+create table t1 (f1 datetime, key (f1));
+insert into t1 values ('2000-03-09 15:56:59'),('2000-05-05 23:24:28'),('2000-06-13 13:12:06');
+select min(f1) from t1 where f1 >= '2006-05-25 07:00:20' and f1 between '2003-11-23 10:00:09' and '2010-01-01 01:01:01' and f1 > '2001-01-01 01:01:01';
+min(f1)
+NULL
+drop table t1;
+#
+# BUG#11765831: 'RANGE ACCESS' MAY INCORRECTLY FILTER
+# AWAY QUALIFYING ROWS
+#
+CREATE TABLE t10(
+K INT NOT NULL AUTO_INCREMENT,
+I INT, J INT,
+PRIMARY KEY(K),
+KEY(I,J)
+);
+INSERT INTO t10(I,J) VALUES (6,1),(6,2),(6,3),(6,4),(6,5),
+(6,6),(6,7),(6,8),(6,9),(6,0);
+CREATE TABLE t100 LIKE t10;
+INSERT INTO t100(I,J) SELECT X.I, X.K+(10*Y.K) FROM t10 AS X,t10 AS Y;
+INSERT INTO t100(I,J) VALUES(8,26);
+
+EXPLAIN SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t100 range I I 10 NULL 4 Using index condition; Using where; Rowid-ordered scan
+
+SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5);
+K I J
+101 8 26
+DROP TABLE t10,t100;
+#
+# lp:817363: Wrong result with sort_union and multipart key in maria-5.3
+#
+CREATE TABLE t1 (a int NOT NULL , b int, c int, d varchar(32), KEY (d,b), PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (7,7,NULL,'e'),(8,1,0,'p'),(9,7,1,'s'),(10,1,1,'j'),(12,2,0,'c'),(13,0,0,'a'),(14,1,1,'q');
+SELECT c FROM t1 WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
+c
+1
+1
+SELECT c FROM t1 ignore index (d) WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
+c
+1
+1
+SELECT * FROM t1 ignore index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
+a b c d
+9 7 1 s
+14 1 1 q
+SELECT * FROM t1 force index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
+a b c d
+9 7 1 s
+14 1 1 q
+DROP TABLE t1;
+set optimizer_switch=@mrr_icp_extra_tmp;
diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result
new file mode 100644
index 00000000000..dfd00204c95
--- /dev/null
+++ b/mysql-test/r/range_vs_index_merge.result
@@ -0,0 +1,1763 @@
+DROP TABLE IF EXISTS t1,t2,t3,t4;
+DROP DATABASE IF EXISTS world;
+set names utf8;
+CREATE DATABASE world;
+use world;
+CREATE TABLE Country (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL,
+PRIMARY KEY (Code),
+UNIQUE INDEX (Name)
+);
+CREATE TABLE City (
+ID int(11) NOT NULL auto_increment,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID),
+INDEX (Population),
+INDEX (Country)
+);
+CREATE TABLE CountryLanguage (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0',
+PRIMARY KEY (Country, Language),
+INDEX (Percentage)
+);
+SELECT COUNT(*) FROM Country;
+COUNT(*)
+239
+SELECT COUNT(*) FROM City;
+COUNT(*)
+4079
+SELECT COUNT(*) FROM CountryLanguage;
+COUNT(*)
+984
+CREATE INDEX Name ON City(Name);
+set session optimizer_switch='index_merge_sort_intersection=off';
+EXPLAIN
+SELECT * FROM City
+WHERE (Population >= 100000 OR Name LIKE 'P%' OR Population < 100000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ALL Population,Name NULL NULL NULL 4079 Using where
+EXPLAIN
+SELECT * FROM City
+WHERE (Population >= 100000 OR Name LIKE 'P%') AND Country='CAN' OR
+(Population < 100000 OR Name Like 'T%') AND Country='ARG';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country,Name Country 3 NULL 104 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Population < 200000 AND Name LIKE 'P%' AND
+(Population > 300000 OR Name LIKE 'T%') AND
+(Population < 100000 OR Name LIKE 'Pa%');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Name Name 35 NULL 135 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Population > 100000 AND Name LIKE 'Aba%' OR
+Country IN ('CAN', 'ARG') AND ID < 3800 OR
+Country < 'U' AND Name LIKE 'Zhu%' OR
+ID BETWEEN 3800 AND 3810;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,PRIMARY 35,3,4 NULL 132 Using sort_union(Name,Country,PRIMARY); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE (Population > 101000 AND Population < 115000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 459 Using index condition
+EXPLAIN
+SELECT * FROM City
+WHERE (Population > 101000 AND Population < 102000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 39 Using index condition
+EXPLAIN
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Country,Name Name,Country 35,3 NULL 172 Using sort_union(Name,Country); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 115000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Name,Country 35,3 NULL 172 Using sort_union(Name,Country); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country,Name Population 4 NULL 39 Using index condition; Using where
+SELECT * FROM City USE INDEX ()
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 115000);
+ID Name Country Population
+403 Catanduva BRA 107761
+412 Cachoeirinha BRA 103240
+636 Bilbays EGY 113608
+637 Mit Ghamr EGY 101801
+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
+759 Gonder ETH 112249
+869 Cabuyao PHL 106630
+870 Calapan PHL 105910
+873 Cauayan PHL 103952
+1844 Cape Breton CAN 114733
+1847 Cambridge CAN 109186
+2908 Cajamarca PER 108009
+3003 Caen FRA 113987
+3411 Ceyhan TUR 102412
+3571 Calabozo VEN 107146
+3786 Cam Ranh VNM 114041
+3792 Tartu EST 101246
+4002 Carrollton USA 109576
+4027 Cape Coral USA 102286
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 115000);
+ID Name Country Population
+403 Catanduva BRA 107761
+412 Cachoeirinha BRA 103240
+636 Bilbays EGY 113608
+637 Mit Ghamr EGY 101801
+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
+759 Gonder ETH 112249
+869 Cabuyao PHL 106630
+870 Calapan PHL 105910
+873 Cauayan PHL 103952
+1844 Cape Breton CAN 114733
+1847 Cambridge CAN 109186
+2908 Cajamarca PER 108009
+3003 Caen FRA 113987
+3411 Ceyhan TUR 102412
+3571 Calabozo VEN 107146
+3786 Cam Ranh VNM 114041
+3792 Tartu EST 101246
+4002 Carrollton USA 109576
+4027 Cape Coral USA 102286
+4032 Cambridge USA 101355
+SELECT * FROM City USE INDEX ()
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+ID Name Country Population
+637 Mit Ghamr EGY 101801
+707 Marbella ESP 101144
+3792 Tartu EST 101246
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+ID Name Country Population
+707 Marbella ESP 101144
+3792 Tartu EST 101246
+4032 Cambridge USA 101355
+637 Mit Ghamr EGY 101801
+EXPLAIN
+SELECT * FROM City WHERE (Name < 'Ac');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 13 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Name < 'Bb');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 208 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Country > 'A' AND Country < 'B');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country Country 3 NULL 104 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'Pb');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 39 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'S');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 221 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Population > 101000 AND Population < 110000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 328 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Population > 103000 AND Population < 104000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 37 Using index condition
+EXPLAIN
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country,Name Name 35 NULL 52 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Name,Population 35,4 NULL 50 Using sort_union(Name,Population); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Country,Name 3,35 NULL 143 Using sort_union(Country,Name); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Country,Population 3,4 NULL 141 Using sort_union(Country,Population); Using where
+SELECT * FROM City USE INDEX ()
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+ID Name Country Population
+65 Abu Dhabi ARE 398695
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+750 Paarl ZAF 105768
+2865 Pak Pattan PAK 107800
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+ID Name Country Population
+65 Abu Dhabi ARE 398695
+750 Paarl ZAF 105768
+168 Pabna BGD 103277
+2865 Pak Pattan PAK 107800
+189 Parakou BEN 103577
+SELECT * FROM City USE INDEX ()
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+ID Name Country Population
+65 Abu Dhabi ARE 398695
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+1003 Pemalang IDN 103500
+2663 Río Bravo MEX 103901
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+ID Name Country Population
+65 Abu Dhabi ARE 398695
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+1003 Pemalang IDN 103500
+2663 Río Bravo MEX 103901
+SELECT * FROM City USE INDEX ()
+WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+ID Name Country Population
+55 Andorra la Vella AND 21189
+65 Abu Dhabi ARE 398695
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+75 Almirante Brown ARG 538918
+85 Avellaneda ARG 353046
+96 Bahía Blanca ARG 239810
+134 Adelaide AUS 978100
+144 Baku AZE 1787800
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+750 Paarl ZAF 105768
+2865 Pak Pattan PAK 107800
+SELECT * FROM City
+WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+ID Name Country Population
+55 Andorra la Vella AND 21189
+65 Abu Dhabi ARE 398695
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+75 Almirante Brown ARG 538918
+85 Avellaneda ARG 353046
+96 Bahía Blanca ARG 239810
+134 Adelaide AUS 978100
+144 Baku AZE 1787800
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+750 Paarl ZAF 105768
+2865 Pak Pattan PAK 107800
+SELECT * FROM City USE INDEX ()
+WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+ID Name Country Population
+55 Andorra la Vella AND 21189
+65 Abu Dhabi ARE 398695
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+75 Almirante Brown ARG 538918
+85 Avellaneda ARG 353046
+96 Bahía Blanca ARG 239810
+134 Adelaide AUS 978100
+144 Baku AZE 1787800
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+1003 Pemalang IDN 103500
+2663 Río Bravo MEX 103901
+SELECT * FROM City
+WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+ID Name Country Population
+55 Andorra la Vella AND 21189
+65 Abu Dhabi ARE 398695
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+75 Almirante Brown ARG 538918
+85 Avellaneda ARG 353046
+96 Bahía Blanca ARG 239810
+134 Adelaide AUS 978100
+144 Baku AZE 1787800
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+1003 Pemalang IDN 103500
+2663 Río Bravo MEX 103901
+EXPLAIN
+SELECT * FROM City WHERE (ID < 10) OR (ID BETWEEN 100 AND 110);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 21 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 100 AND 200);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 201 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1500);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ALL PRIMARY NULL NULL NULL 4079 Using where
+EXPLAIN
+SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country Country 3 NULL 19 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'H%' OR Name LIKE 'P%' ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 222 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'Ha%' OR Name LIKE 'Pa%' ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 72 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 100 AND 110) AND
+(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 21 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 900 AND 1500) AND
+(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 128 Using sort_union(Name,Country,Population); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 100 AND 200) AND
+(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 128 Using sort_union(Name,Country,Population); Using where
+SELECT * FROM City USE INDEX ()
+WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 100 AND 110) AND
+(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
+ID Name Country Population
+1 Kabul AFG 1780000
+2 Qandahar AFG 237500
+3 Herat AFG 186800
+4 Mazar-e-Sharif AFG 127800
+7 Haag NLD 440900
+100 Paraná ARG 207041
+102 Posadas ARG 201273
+SELECT * FROM City
+WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 100 AND 110) AND
+(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
+ID Name Country Population
+1 Kabul AFG 1780000
+2 Qandahar AFG 237500
+3 Herat AFG 186800
+4 Mazar-e-Sharif AFG 127800
+7 Haag NLD 440900
+100 Paraná ARG 207041
+102 Posadas ARG 201273
+SELECT * FROM City USE INDEX()
+WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 900 AND 1500) AND
+(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+ID Name Country Population
+1 Kabul AFG 1780000
+2 Qandahar AFG 237500
+3 Herat AFG 186800
+4 Mazar-e-Sharif AFG 127800
+7 Haag NLD 440900
+16 Haarlem NLD 148772
+25 Haarlemmermeer NLD 110722
+33 Willemstad ANT 2345
+34 Tirana ALB 270000
+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
+64 Dubai ARE 669181
+65 Abu Dhabi ARE 398695
+66 Sharja ARE 320095
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+129 Oranjestad ABW 29034
+191 Hamilton BMU 1200
+528 Hartlepool GBR 92000
+529 Halifax GBR 91069
+914 Sekondi-Takoradi GHA 103653
+943 Palembang IDN 1222764
+950 Padang IDN 534474
+983 Palu IDN 142800
+984 Pasuruan IDN 134019
+991 Pangkal Pinang IDN 124000
+1003 Pemalang IDN 103500
+1004 Klaten IDN 103300
+1007 Palangka Raya IDN 99693
+1020 Padang Sidempuan IDN 91200
+1045 Patna IND 917243
+1114 Panihati IND 275990
+1129 Patiala IND 238368
+1142 Panipat IND 215218
+1159 Parbhani IND 190255
+1231 Pali IND 136842
+1263 Pathankot IND 123930
+1265 Palghat (Palakkad) IND 123289
+1293 Pallavaram IND 111866
+1319 Tellicherry (Thalassery) IND 103579
+1339 Palayankottai IND 97662
+1345 Patan IND 96109
+1436 Marv Dasht IRN 103579
+1468 Palermo ITA 683794
+1478 Padova ITA 211391
+1484 Parma ITA 168717
+SELECT * FROM City
+WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 900 AND 1500) AND
+(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+ID Name Country Population
+1 Kabul AFG 1780000
+2 Qandahar AFG 237500
+3 Herat AFG 186800
+4 Mazar-e-Sharif AFG 127800
+7 Haag NLD 440900
+16 Haarlem NLD 148772
+25 Haarlemmermeer NLD 110722
+33 Willemstad ANT 2345
+34 Tirana ALB 270000
+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
+64 Dubai ARE 669181
+65 Abu Dhabi ARE 398695
+66 Sharja ARE 320095
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+129 Oranjestad ABW 29034
+191 Hamilton BMU 1200
+528 Hartlepool GBR 92000
+529 Halifax GBR 91069
+914 Sekondi-Takoradi GHA 103653
+943 Palembang IDN 1222764
+950 Padang IDN 534474
+983 Palu IDN 142800
+984 Pasuruan IDN 134019
+991 Pangkal Pinang IDN 124000
+1003 Pemalang IDN 103500
+1004 Klaten IDN 103300
+1007 Palangka Raya IDN 99693
+1020 Padang Sidempuan IDN 91200
+1045 Patna IND 917243
+1114 Panihati IND 275990
+1129 Patiala IND 238368
+1142 Panipat IND 215218
+1159 Parbhani IND 190255
+1231 Pali IND 136842
+1263 Pathankot IND 123930
+1265 Palghat (Palakkad) IND 123289
+1293 Pallavaram IND 111866
+1319 Tellicherry (Thalassery) IND 103579
+1339 Palayankottai IND 97662
+1345 Patan IND 96109
+1436 Marv Dasht IRN 103579
+1468 Palermo ITA 683794
+1478 Padova ITA 211391
+1484 Parma ITA 168717
+SELECT * FROM City USE INDEX ()
+WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 100 AND 200) AND
+(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+ID Name Country Population
+1 Kabul AFG 1780000
+2 Qandahar AFG 237500
+3 Herat AFG 186800
+4 Mazar-e-Sharif AFG 127800
+7 Haag NLD 440900
+16 Haarlem NLD 148772
+25 Haarlemmermeer NLD 110722
+33 Willemstad ANT 2345
+34 Tirana ALB 270000
+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
+64 Dubai ARE 669181
+65 Abu Dhabi ARE 398695
+66 Sharja ARE 320095
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+100 Paraná ARG 207041
+129 Oranjestad ABW 29034
+167 Jamalpur BGD 103556
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+191 Hamilton BMU 1200
+SELECT * FROM City
+WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 100 AND 200) AND
+(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+ID Name Country Population
+1 Kabul AFG 1780000
+2 Qandahar AFG 237500
+3 Herat AFG 186800
+4 Mazar-e-Sharif AFG 127800
+7 Haag NLD 440900
+16 Haarlem NLD 148772
+25 Haarlemmermeer NLD 110722
+33 Willemstad ANT 2345
+34 Tirana ALB 270000
+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
+64 Dubai ARE 669181
+65 Abu Dhabi ARE 398695
+66 Sharja ARE 320095
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+100 Paraná ARG 207041
+129 Oranjestad ABW 29034
+167 Jamalpur BGD 103556
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+191 Hamilton BMU 1200
+EXPLAIN
+SELECT * FROM City WHERE Population > 101000 AND Population < 102000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 39 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Population > 101000 AND Population < 110000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 328 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Country < 'C';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country Country 3 NULL 436 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Country < 'AGO';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country Country 3 NULL 6 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Name BETWEEN 'P' AND 'S';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 221 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Name BETWEEN 'P' AND 'Pb';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 39 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 3400 AND 3800;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 401 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'P%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 135 Using index condition
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 102000) AND
+(Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR
+((ID BETWEEN 3400 AND 3800) AND
+(Country < 'AGO' OR Name LIKE 'Pa%'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name Country,Name,Population 3,35,4 NULL 84 Using sort_union(Country,Name,Population); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 110000) AND
+(Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR
+((ID BETWEEN 3790 AND 3800) AND
+(Country < 'C' OR Name LIKE 'P%'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name Country,Name,PRIMARY 3,35,4 NULL 56 Using sort_union(Country,Name,PRIMARY); Using where
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 102000) AND
+(Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR
+((ID BETWEEN 3400 AND 3800) AND
+(Country < 'AGO' OR Name LIKE 'Pa%'));
+ID Name Country Population
+169 Naogaon BGD 101266
+205 Francistown BWA 101805
+417 Itaituba BRA 101320
+418 Araras BRA 101046
+751 Potchefstroom ZAF 101817
+2909 Puno PER 101578
+3463 Pavlograd UKR 127000
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 102000) AND
+(Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR
+((ID BETWEEN 3400 AND 3800) AND
+(Country < 'AGO' OR Name LIKE 'Pa%'));
+ID Name Country Population
+169 Naogaon BGD 101266
+205 Francistown BWA 101805
+417 Itaituba BRA 101320
+418 Araras BRA 101046
+751 Potchefstroom ZAF 101817
+2909 Puno PER 101578
+3463 Pavlograd UKR 127000
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 110000) AND
+(Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR
+((ID BETWEEN 3790 AND 3800) AND
+(Country < 'C' OR Name LIKE 'P%'));
+ID Name Country Population
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+750 Paarl ZAF 105768
+2865 Pak Pattan PAK 107800
+3797 Philadelphia USA 1517550
+3798 Phoenix USA 1321045
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 110000) AND
+(Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR
+((ID BETWEEN 3790 AND 3800) AND
+(Country < 'C' OR Name LIKE 'P%'));
+ID Name Country Population
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+750 Paarl ZAF 105768
+2865 Pak Pattan PAK 107800
+3797 Philadelphia USA 1517550
+3798 Phoenix USA 1321045
+CREATE INDEX CountryPopulation ON City(Country,Population);
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'Pas%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 5 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'P%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 135 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Population > 101000 AND Population < 103000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 81 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Country='USA';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref Country,CountryPopulation Country 3 const 267 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Country='FIN';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref Country,CountryPopulation Country 3 const 6 Using index condition
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
+AND Country='USA';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 15 Using sort_union(CountryPopulation,Name); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
+AND Country='FIN';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 6 Using index condition; Using where
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
+AND Country='USA';
+ID Name Country Population
+3943 Pasadena USA 141674
+3953 Pasadena USA 133936
+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
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
+AND Country='USA';
+ID Name Country Population
+3943 Pasadena USA 141674
+3953 Pasadena USA 133936
+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
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
+AND Country='FIN';
+ID Name Country Population
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
+AND Country='FIN';
+ID Name Country Population
+CREATE INDEX CountryName ON City(Country,Name);
+EXPLAIN
+SELECT * FROM City WHERE Country='USA';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 267 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Country='FIN';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref Country,CountryPopulation,CountryName CountryName 3 const 5 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Country='BRA';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref Country,CountryPopulation,CountryName CountryName 3 const 221 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 4025 AND 4035;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 4028 AND 4032;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 5 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 3500 AND 3800;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 301 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 4000 AND 4300;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 80 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 250 and 260 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Population > 101000 AND Population < 102000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 39 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Population > 101000 AND Population < 103000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 81 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'Pa%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 41 Using index condition
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryPopulation,PRIMARY 7,4 NULL 14 Using sort_union(CountryPopulation,PRIMARY); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 103000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName,PRIMARY 38,4 NULL 11 Using sort_union(CountryName,PRIMARY); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 110000) OR
+ID BETWEEN 3500 AND 3800) AND Country='FIN'
+ AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName 3 const 5 Using index condition; Using where
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+ID Name Country Population
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+ID Name Country Population
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032);
+ID Name Country Population
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032);
+ID Name Country Population
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='FIN'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+ID Name Country Population
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='FIN'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+ID Name Country Population
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 and Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryPopulation,PRIMARY,CountryName 7,4,38 NULL 35 Using sort_union(CountryPopulation,PRIMARY,CountryName); Using where
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 and Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA';
+ID Name Country Population
+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
+285 Paulista BRA 248473
+339 Passo Fundo BRA 166343
+364 Parnaíba BRA 129756
+372 Paranaguá BRA 126076
+379 Palmas BRA 121919
+386 Patos de Minas BRA 119262
+424 Passos BRA 98570
+430 Paulo Afonso BRA 97291
+435 Parnamirim BRA 96210
+448 Patos BRA 90519
+451 Palhoça BRA 89465
+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
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE ((Population > 101000 and Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA';
+ID Name Country Population
+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
+285 Paulista BRA 248473
+339 Passo Fundo BRA 166343
+364 Parnaíba BRA 129756
+372 Paranaguá BRA 126076
+379 Palmas BRA 121919
+386 Patos de Minas BRA 119262
+424 Passos BRA 98570
+430 Paulo Afonso BRA 97291
+435 Parnamirim BRA 96210
+448 Patos BRA 90519
+451 Palhoça BRA 89465
+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
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 11000) OR
+ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName 38 NULL 23 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 11000) OR
+ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName Name 35 NULL 1 Using where
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 11000) OR
+ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300);
+ID Name Country Population
+3797 Philadelphia USA 1517550
+3798 Phoenix USA 1321045
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 11000) OR
+ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300);
+ID Name Country Population
+3797 Philadelphia USA 1517550
+3798 Phoenix USA 1321045
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 11000) OR
+ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300);
+ID Name Country Population
+3798 Phoenix USA 1321045
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 11000) OR
+ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300);
+ID Name Country Population
+3798 Phoenix USA 1321045
+DROP INDEX Population ON City;
+DROP INDEX Name ON City;
+EXPLAIN
+SELECT * FROM City
+WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR
+Country='USA' AND Name LIKE 'Pa%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Country,CountryPopulation,CountryName CountryPopulation,CountryName 7,38 NULL 10 Using sort_union(CountryPopulation,CountryName); Using where
+SELECT * FROM City USE INDEX()
+WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR
+Country='USA' AND Name LIKE 'Pa%';
+ID Name Country Population
+3932 Paterson USA 149222
+3943 Pasadena USA 141674
+3953 Pasadena USA 133936
+3967 Paradise USA 124682
+3986 Palmdale USA 116670
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR
+Country='USA' AND Name LIKE 'Pa%';
+ID Name Country Population
+3932 Paterson USA 149222
+3943 Pasadena USA 141674
+3953 Pasadena USA 133936
+3967 Paradise USA 124682
+3986 Palmdale USA 116670
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+EXPLAIN
+SELECT * FROM City
+WHERE Country='USA' AND
+(Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Country,CountryPopulation,CountryName CountryPopulation,CountryName 7,38 NULL 10 Using sort_union(CountryPopulation,CountryName); Using where
+SELECT * FROM City
+WHERE Country='USA' AND
+(Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%');
+ID Name Country Population
+3932 Paterson USA 149222
+3943 Pasadena USA 141674
+3953 Pasadena USA 133936
+3967 Paradise USA 124682
+3986 Palmdale USA 116670
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE Country='USA' AND
+(Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%');
+ID Name Country Population
+3932 Paterson USA 149222
+3943 Pasadena USA 141674
+3953 Pasadena USA 133936
+3967 Paradise USA 124682
+3986 Palmdale USA 116670
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE INDEX CityName on City(Name);
+EXPLAIN SELECT Name, Country, Population FROM City WHERE
+(Name='Manila' AND Country='PHL') OR
+(Name='Addis Abeba' AND Country='ETH') OR
+(Name='Jakarta' AND Country='IDN') OR
+(Name='Bangalore' AND Country='IND') OR
+(Name='Teheran' AND Country='IRN') OR
+(Name='Roma' AND Country='ITA') OR
+(Name='Delhi' AND Country='IND') OR
+(Name='Venezia' AND Country='ITA') OR
+(Name='Tokyo' AND Country='JPN') OR
+(Name='Toronto' AND Country='CAN') OR
+(Name='Peking' AND Country='CHN') OR
+(Name='Lagos' AND Country='NGA') OR
+(Name='Tijuana' AND Country='MEX') OR
+(Name='Rabat' AND Country='MAR') OR
+(Name='Seoul' AND Country='KOR') OR
+(Name='Vancouver' AND Country='CAN') OR
+(Name='Kaunas' AND Country='LTU') OR
+(Name='Paris' AND Country='FRA') OR
+(Name='Dakar' AND Country='SEN') OR
+(Name='Basel' AND Country='CHE') OR
+(Name='Praha' AND Country='CZE') OR
+(Name='Ankara' AND Country='TUR') OR
+(Name='Dresden' AND Country='DEU') OR
+(Name='Lugansk' AND Country='UKR') OR
+(Name='Caracas' AND Country='VEN') OR
+(Name='Samara' AND Country='RUS') OR
+(Name='Seattle' AND Country='USA');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Country,CountryPopulation,CountryName,CityName CountryName,CityName 38,35 NULL 28 Using sort_union(CountryName,CityName); Using where
+SELECT Name, Country, Population FROM City WHERE
+(Name='Manila' AND Country='PHL') OR
+(Name='Addis Abeba' AND Country='ETH') OR
+(Name='Jakarta' AND Country='IDN') OR
+(Name='Bangalore' AND Country='IND') OR
+(Name='Teheran' AND Country='IRN') OR
+(Name='Roma' AND Country='ITA') OR
+(Name='Delhi' AND Country='IND') OR
+(Name='Venezia' AND Country='ITA') OR
+(Name='Tokyo' AND Country='JPN') OR
+(Name='Toronto' AND Country='CAN') OR
+(Name='Peking' AND Country='CHN') OR
+(Name='Lagos' AND Country='NGA') OR
+(Name='Tijuana' AND Country='MEX') OR
+(Name='Rabat' AND Country='MAR') OR
+(Name='Seoul' AND Country='KOR') OR
+(Name='Vancouver' AND Country='CAN') OR
+(Name='Kaunas' AND Country='LTU') OR
+(Name='Paris' AND Country='FRA') OR
+(Name='Dakar' AND Country='SEN') OR
+(Name='Basel' AND Country='CHE') OR
+(Name='Praha' AND Country='CZE') OR
+(Name='Ankara' AND Country='TUR') OR
+(Name='Dresden' AND Country='DEU') OR
+(Name='Lugansk' AND Country='UKR') OR
+(Name='Caracas' AND Country='VEN') OR
+(Name='Samara' AND Country='RUS') OR
+(Name='Seattle' AND Country='USA');
+Name Country Population
+Addis Abeba ETH 2495000
+Manila PHL 1581082
+Jakarta IDN 9604900
+Delhi IND 7206704
+Bangalore IND 2660088
+Teheran IRN 6758845
+Roma ITA 2643581
+Venezia ITA 277305
+Tokyo JPN 7980230
+Toronto CAN 688275
+Vancouver CAN 514008
+Peking CHN 7472000
+Seoul KOR 9981619
+Kaunas LTU 412639
+Rabat MAR 623457
+Tijuana MEX 1212232
+Lagos NGA 1518000
+Paris FRA 2125246
+Dresden DEU 476668
+Dakar SEN 785071
+Basel CHE 166700
+Praha CZE 1181126
+Ankara TUR 3038159
+Lugansk UKR 469000
+Caracas VEN 1975294
+Samara RUS 1156100
+Seattle USA 563374
+set optimizer_switch='index_merge=off';
+EXPLAIN SELECT Name, Country, Population FROM City WHERE
+(Name='Manila' AND Country='PHL') OR
+(Name='Addis Abeba' AND Country='ETH') OR
+(Name='Jakarta' AND Country='IDN') OR
+(Name='Bangalore' AND Country='IND') OR
+(Name='Teheran' AND Country='IRN') OR
+(Name='Roma' AND Country='ITA') OR
+(Name='Delhi' AND Country='IND') OR
+(Name='Venezia' AND Country='ITA') OR
+(Name='Tokyo' AND Country='JPN') OR
+(Name='Toronto' AND Country='CAN') OR
+(Name='Peking' AND Country='CHN') OR
+(Name='Lagos' AND Country='NGA') OR
+(Name='Tijuana' AND Country='MEX') OR
+(Name='Rabat' AND Country='MAR') OR
+(Name='Seoul' AND Country='KOR') OR
+(Name='Vancouver' AND Country='CAN') OR
+(Name='Kaunas' AND Country='LTU') OR
+(Name='Paris' AND Country='FRA') OR
+(Name='Dakar' AND Country='SEN') OR
+(Name='Basel' AND Country='CHE') OR
+(Name='Praha' AND Country='CZE') OR
+(Name='Ankara' AND Country='TUR') OR
+(Name='Dresden' AND Country='DEU') OR
+(Name='Lugansk' AND Country='UKR') OR
+(Name='Caracas' AND Country='VEN') OR
+(Name='Samara' AND Country='RUS') OR
+(Name='Seattle' AND Country='USA');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country,CountryPopulation,CountryName,CityName CountryName 38 NULL 29 Using index condition; Using where
+SELECT Name, Country, Population FROM City WHERE
+(Name='Manila' AND Country='PHL') OR
+(Name='Addis Abeba' AND Country='ETH') OR
+(Name='Jakarta' AND Country='IDN') OR
+(Name='Bangalore' AND Country='IND') OR
+(Name='Teheran' AND Country='IRN') OR
+(Name='Roma' AND Country='ITA') OR
+(Name='Delhi' AND Country='IND') OR
+(Name='Venezia' AND Country='ITA') OR
+(Name='Tokyo' AND Country='JPN') OR
+(Name='Toronto' AND Country='CAN') OR
+(Name='Peking' AND Country='CHN') OR
+(Name='Lagos' AND Country='NGA') OR
+(Name='Tijuana' AND Country='MEX') OR
+(Name='Rabat' AND Country='MAR') OR
+(Name='Seoul' AND Country='KOR') OR
+(Name='Vancouver' AND Country='CAN') OR
+(Name='Kaunas' AND Country='LTU') OR
+(Name='Paris' AND Country='FRA') OR
+(Name='Dakar' AND Country='SEN') OR
+(Name='Basel' AND Country='CHE') OR
+(Name='Praha' AND Country='CZE') OR
+(Name='Ankara' AND Country='TUR') OR
+(Name='Dresden' AND Country='DEU') OR
+(Name='Lugansk' AND Country='UKR') OR
+(Name='Caracas' AND Country='VEN') OR
+(Name='Samara' AND Country='RUS') OR
+(Name='Seattle' AND Country='USA');
+Name Country Population
+Toronto CAN 688275
+Vancouver CAN 514008
+Basel CHE 166700
+Peking CHN 7472000
+Praha CZE 1181126
+Dresden DEU 476668
+Addis Abeba ETH 2495000
+Paris FRA 2125246
+Jakarta IDN 9604900
+Bangalore IND 2660088
+Delhi IND 7206704
+Teheran IRN 6758845
+Roma ITA 2643581
+Venezia ITA 277305
+Tokyo JPN 7980230
+Seoul KOR 9981619
+Kaunas LTU 412639
+Rabat MAR 623457
+Tijuana MEX 1212232
+Lagos NGA 1518000
+Manila PHL 1581082
+Samara RUS 1156100
+Dakar SEN 785071
+Ankara TUR 3038159
+Lugansk UKR 469000
+Seattle USA 563374
+Caracas VEN 1975294
+set optimizer_switch=@save_optimizer_switch;
+#
+# Bug mdev-585: range vs index-merge with ORDER BY ... LIMIT n
+# (LP bug #637962)
+#
+DROP INDEX CountryPopulation ON City;
+DROP INDEX CountryName ON City;
+DROP INDEX CityName on City;
+CREATE INDEX Name ON City(Name);
+CREATE INDEX Population ON City(Population);
+EXPLAIN
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+AND (Population >= 100000 AND Population < 120000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Country,Name,Population Name,Country 35,3 NULL # Using sort_union(Name,Country); Using where
+FLUSH STATUS;
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+AND (Population >= 100000 AND Population < 120000);
+ID Name Country Population
+384 Cabo Frio BRA 119503
+387 Camaragibe BRA 118968
+403 Catanduva BRA 107761
+412 Cachoeirinha BRA 103240
+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
+635 Mallawi EGY 119283
+636 Bilbays EGY 113608
+637 Mit Ghamr EGY 101801
+638 al-Arish EGY 100447
+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
+759 Gonder ETH 112249
+869 Cabuyao PHL 106630
+870 Calapan PHL 105910
+873 Cauayan PHL 103952
+903 Serekunda GMB 102600
+909 Sohumi GEO 111700
+913 Tema GHA 109975
+914 Sekondi-Takoradi GHA 103653
+924 Villa Nueva GTM 101295
+1844 Cape Breton CAN 114733
+1847 Cambridge CAN 109186
+2406 Herakleion GRC 116178
+2407 Kallithea GRC 114233
+2408 Larisa GRC 113090
+2908 Cajamarca PER 108009
+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
+3411 Ceyhan TUR 102412
+3567 Carúpano VEN 119639
+3568 Catia La Mar VEN 117012
+3571 Calabozo VEN 107146
+3786 Cam Ranh VNM 114041
+3792 Tartu EST 101246
+4002 Carrollton USA 109576
+4027 Cape Coral USA 102286
+4032 Cambridge USA 101355
+SHOW STATUS LIKE 'Handler_read_%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 2
+Handler_read_next 385
+Handler_read_prev 0
+Handler_read_rnd 377
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 0
+EXPLAIN
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+AND (Population >= 100000 AND Population < 120000)
+ORDER BY Population LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country,Name,Population Population 4 NULL # Using where
+FLUSH STATUS;
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+AND (Population >= 100000 AND Population < 120000)
+ORDER BY Population LIMIT 5;
+ID Name Country Population
+519 Worthing GBR 100000
+638 al-Arish EGY 100447
+518 Basildon GBR 100924
+707 Marbella ESP 101144
+3792 Tartu EST 101246
+SHOW STATUS LIKE 'Handler_read_%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 1
+Handler_read_next 59
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 0
+set optimizer_switch='index_merge=off';
+EXPLAIN
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+AND (Population >= 100000 AND Population < 120000)
+ORDER BY Population LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country,Name,Population Population 4 NULL # Using index condition; Using where
+FLUSH STATUS;
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+AND (Population >= 100000 AND Population < 120000)
+ORDER BY Population LIMIT 5;
+ID Name Country Population
+519 Worthing GBR 100000
+638 al-Arish EGY 100447
+518 Basildon GBR 100924
+707 Marbella ESP 101144
+3792 Tartu EST 101246
+SHOW STATUS LIKE 'Handler_read_%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 1
+Handler_read_next 59
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 0
+set optimizer_switch=@save_optimizer_switch;
+DROP DATABASE world;
+use test;
+CREATE TABLE t1 (
+id int(10) unsigned NOT NULL auto_increment,
+account_id int(10) unsigned NOT NULL,
+first_name varchar(50) default NULL,
+middle_name varchar(50) default NULL,
+last_name varchar(100) default NULL,
+home_address_1 varchar(150) default NULL,
+home_city varchar(75) default NULL,
+home_state char(2) default NULL,
+home_postal_code varchar(50) default NULL,
+home_county varchar(75) default NULL,
+home_country char(3) default NULL,
+work_address_1 varchar(150) default NULL,
+work_city varchar(75) default NULL,
+work_state char(2) default NULL,
+work_postal_code varchar(50) default NULL,
+work_county varchar(75) default NULL,
+work_country char(3) default NULL,
+login varchar(50) NOT NULL,
+PRIMARY KEY (id),
+KEY login (login,account_id),
+KEY account_id (account_id),
+KEY user_home_country_indx (home_country),
+KEY user_work_country_indx (work_country),
+KEY user_home_state_indx (home_state),
+KEY user_work_state_indx (work_state),
+KEY user_home_city_indx (home_city),
+KEY user_work_city_indx (work_city),
+KEY user_first_name_indx (first_name),
+KEY user_last_name_indx (last_name)
+);
+insert into t1(account_id, login, home_state, work_state) values
+(1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'),
+(1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia');
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+select count(*) from t1 where account_id = 1;
+count(*)
+3072
+select * from t1
+where (home_state = 'ia' or work_state='ia') and account_id = 1;
+id account_id first_name middle_name last_name home_address_1 home_city home_state home_postal_code home_county home_country work_address_1 work_city work_state work_postal_code work_county work_country login
+1 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw
+2 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw
+3 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw
+4 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw
+5 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw
+6 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw
+explain
+select * from t1
+where (home_state = 'ia' or work_state='ia') and account_id = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge account_id,user_home_state_indx,user_work_state_indx user_home_state_indx,user_work_state_indx 3,3 NULL 6 Using union(user_home_state_indx,user_work_state_indx); Using where
+drop table t1;
+CREATE TABLE t1 (
+c1 int(11) NOT NULL auto_increment,
+c2 decimal(10,0) default NULL,
+c3 decimal(10,0) default NULL,
+c4 decimal(10,0) default NULL,
+c5 decimal(10,0) default NULL,
+cp decimal(1,0) default NULL,
+ce decimal(10,0) default NULL,
+cdata char(20),
+PRIMARY KEY (c1),
+KEY k1 (c2,c3,cp,ce),
+KEY k2 (c4,c5,cp,ce)
+);
+insert into t1 (c2, c3, c4, c5, cp) values(1,1,1,1,1);
+insert into t1 (c2, c3, c4, c5, cp) values(2,1,1,1,4);
+insert into t1 (c2, c3, c4, c5, cp) values(2,1,2,1,1);
+insert into t1 (c2, c3, c4, c5, cp) values(2,1,3,1,4);
+insert into t1 (c2, c3, c4, c5, cp) values(3,1,4,1,4);
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+explain
+select * from t1 where (c2=1 and c3=1) or (c4=2 and c5=1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge k1,k2 k1,k2 12,12 NULL 2 Using sort_union(k1,k2); Using where
+explain
+select * from t1
+where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge k1,k2 k1,k2 14,14 NULL 2 Using sort_union(k1,k2); Using where
+explain
+select * from t1
+where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge k1,k2 k1,k2 14,14 NULL 2 Using sort_union(k1,k2); Using where
+select * from t1
+where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1);
+c1 c2 c3 c4 c5 cp ce cdata
+1 1 1 1 1 1 NULL NULL
+3 2 1 2 1 1 NULL NULL
+select * from t1
+where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1;
+c1 c2 c3 c4 c5 cp ce cdata
+1 1 1 1 1 1 NULL NULL
+3 2 1 2 1 1 NULL NULL
+drop table t1;
+create table t1 (
+c1 int auto_increment primary key,
+c2 char(20),
+c3 char (20),
+c4 int
+);
+alter table t1 add key k1 (c2);
+alter table t1 add key k2 (c3);
+alter table t1 add key k3 (c4);
+insert into t1 values(null, 'a', 'b', 0);
+insert into t1 values(null, 'c', 'b', 0);
+insert into t1 values(null, 'a', 'd', 0);
+insert into t1 values(null, 'ccc', 'qqq', 0);
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3,c4) select c2,c3,1 from t1 where c2 != 'a';
+insert into t1 (c2,c3,c4) select c2,c3,2 from t1 where c2 != 'a';
+insert into t1 (c2,c3,c4) select c2,c3,3 from t1 where c2 != 'a';
+insert into t1 (c2,c3,c4) select c2,c3,4 from t1 where c2 != 'a';
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+select count(*) from t1 where (c2='e' OR c3='q');
+count(*)
+0
+select count(*) from t1 where c4 != 0;
+count(*)
+3840
+explain
+select distinct c1 from t1 where (c2='e' OR c3='q');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge k1,k2 k1,k2 21,21 NULL 2 Using union(k1,k2); Using where
+explain
+select distinct c1 from t1 where (c4!= 0) AND (c2='e' OR c3='q');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge k1,k2,k3 k1,k2 21,21 NULL 2 Using union(k1,k2); Using where
+drop table t1;
+create table t1 (
+id int unsigned auto_increment primary key,
+c1 char(12),
+c2 char(15),
+c3 char(1)
+);
+insert into t1 (c3) values ('1'), ('2');
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+update t1 set c1=lpad(id+1000, 12, ' '), c2=lpad(id+10000, 15, ' ');
+alter table t1 add unique index (c1), add unique index (c2), add index (c3);
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+explain
+select * from t1 where (c1=' 100000' or c2=' 2000000');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge c1,c2 c1,c2 13,16 NULL 2 Using union(c1,c2); Using where
+explain
+select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge c1,c2,c3 c1,c2 13,16 NULL 2 Using union(c1,c2); Using where
+select * from t1 where (c1=' 100000' or c2=' 2000000');
+id c1 c2 c3
+select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2';
+id c1 c2 c3
+drop table t1;
+CREATE TABLE t1 (
+a smallint DEFAULT NULL,
+pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+b varchar(10) DEFAULT NULL,
+c varchar(64) DEFAULT NULL,
+INDEX idx1 (a),
+INDEX idx2 (b),
+INDEX idx3 (c)
+);
+SELECT COUNT(*) FROM t1 IGNORE INDEX (idx2,idx3)
+WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR
+(pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ;
+COUNT(*)
+5
+SELECT COUNT(*) FROM t1
+WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR
+(pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ;
+COUNT(*)
+5
+EXPLAIN
+SELECT COUNT(*) FROM t1
+WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR
+(pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,PRIMARY,idx1 67,13,4,3 NULL 8 Using sort_union(idx3,idx2,PRIMARY,idx1); Using where
+DROP TABLE t1;
+CREATE TABLE t1 (
+f1 int, f2 int, f3 int, f4 int, f5 int,
+PRIMARY KEY (f4), KEY (f1), KEY (f2), KEY (f3)
+) ;
+INSERT INTO t1 VALUES (0,0,NULL,9,5), (0,0,1,9425,NULL);
+SELECT f5 FROM t1
+WHERE f2 != 1 OR f1 IS NULL OR f4 = 4 OR
+f2 AND (f4 BETWEEN 6 AND 255 OR f3 IS NULL);
+f5
+5
+NULL
+DROP TABLE t1;
+CREATE TABLE t1 (
+f1 int, f2 int, f3 int, f4 int,
+PRIMARY KEY (f1), KEY (f3), KEY (f4)
+);
+INSERT INTO t1 VALUES (9,0,2,6), (9930,0,0,NULL);
+SET SESSION optimizer_switch='index_merge_intersection=off';
+SET SESSION optimizer_switch='index_merge_sort_union=off';
+SET SESSION optimizer_switch='index_merge_union=off';
+EXPLAIN
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,f3,f4 NULL NULL NULL 2 Using where
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+f1 f2 f3 f4
+9 0 2 6
+SET SESSION optimizer_switch='index_merge_union=on';
+EXPLAIN
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,f3,f4 NULL NULL NULL 2 Using where
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+f1 f2 f3 f4
+9 0 2 6
+INSERT INTO t1 VALUES
+(93,0,3,6), (9933,0,3,3), (94,0,4,6), (9934,0,4,4),
+(95,0,5,6), (9935,0,5,5), (96,0,6,6), (9936,0,6,6),
+(97,0,7,6), (9937,0,7,7), (98,0,8,6), (9938,0,8,8),
+(99,0,9,6), (9939,0,9,9);
+SET SESSION optimizer_switch='index_merge_union=off';
+EXPLAIN
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,f3,f4 NULL NULL NULL 16 Using where
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+f1 f2 f3 f4
+9 0 2 6
+SET SESSION optimizer_switch='index_merge_union=on';
+EXPLAIN
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge PRIMARY,f3,f4 f3,PRIMARY,f3 5,4,5 NULL 3 Using union(f3,PRIMARY,f3); Using where
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+f1 f2 f3 f4
+9 0 2 6
+SET SESSION optimizer_switch=DEFAULT;
+DROP TABLE t1;
+CREATE TABLE t1 (f1 int) ;
+INSERT INTO t1 VALUES (0), (0);
+CREATE TABLE t2 (f1 int, f2 int, f3 int, f4 int, INDEX idx (f3,f2)) ;
+INSERT INTO t2 VALUES (5,6,0,0), (0,4,0,0);
+CREATE TABLE t3 (f1 int, f2 int, INDEX idx1 (f2,f1) , INDEX idx2 (f1)) ;
+INSERT INTO t3 VALUES (6,0),( 4,0);
+SELECT * FROM t1,t2,t3
+WHERE (t2.f3 = 1 OR t3.f1=t2.f1) AND t3.f1 <> t2.f2 AND t3.f2 = t2.f4;
+f1 f1 f2 f3 f4 f1 f2
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (
+a int, b int, c int, d int,
+PRIMARY KEY(b), INDEX idx1(d), INDEX idx2(d,b,c)
+);
+INSERT INTO t1 VALUES
+(0,58,7,7),(0,63,2,0),(0,64,186,8),(0,65,1,-2), (0,71,190,-3),
+(0,72,321,-7),(0,73,0,3),(0,74,5,25),(0,75,5,3);
+SET SESSION optimizer_switch='index_merge_sort_union=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 9 Using where
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+a b c d
+0 58 7 7
+0 64 186 8
+0 73 0 3
+0 74 5 25
+0 75 5 3
+SET SESSION optimizer_switch='index_merge_sort_union=on';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 9 Using where
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+a b c d
+0 58 7 7
+0 64 186 8
+0 73 0 3
+0 74 5 25
+0 75 5 3
+SET SESSION optimizer_switch=DEFAULT;
+DROP TABLE t1;
+CREATE TABLE t1 (a int NOT NULL PRIMARY KEY, b int, c int, INDEX idx(c,b));
+INSERT INTO t1 VALUES (19,1,NULL), (20,5,7);
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND
+(t1.c=0 OR t1.a=500);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,idx PRIMARY 4 NULL 1 Using index condition; Using where
+SELECT * FROM t1
+WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND
+(t1.c=0 OR t1.a=500);
+a b c
+DROP TABLE t1;
+CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX idx(b));
+INSERT INTO t1 VALUES (167,9999), (168,10000);
+EXPLAIN
+SELECT * FROM t1
+WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,idx NULL NULL NULL 2 Using where
+SELECT * FROM t1
+WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2;
+a b
+167 9999
+168 10000
+DROP TABLE t1;
+set session optimizer_switch='index_merge_sort_intersection=default';
diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result
new file mode 100644
index 00000000000..4970900a061
--- /dev/null
+++ b/mysql-test/r/range_vs_index_merge_innodb.result
@@ -0,0 +1,1765 @@
+SET SESSION STORAGE_ENGINE='InnoDB';
+DROP TABLE IF EXISTS t1,t2,t3,t4;
+DROP DATABASE IF EXISTS world;
+set names utf8;
+CREATE DATABASE world;
+use world;
+CREATE TABLE Country (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL,
+PRIMARY KEY (Code),
+UNIQUE INDEX (Name)
+);
+CREATE TABLE City (
+ID int(11) NOT NULL auto_increment,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID),
+INDEX (Population),
+INDEX (Country)
+);
+CREATE TABLE CountryLanguage (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0',
+PRIMARY KEY (Country, Language),
+INDEX (Percentage)
+);
+SELECT COUNT(*) FROM Country;
+COUNT(*)
+239
+SELECT COUNT(*) FROM City;
+COUNT(*)
+4079
+SELECT COUNT(*) FROM CountryLanguage;
+COUNT(*)
+984
+CREATE INDEX Name ON City(Name);
+set session optimizer_switch='index_merge_sort_intersection=off';
+EXPLAIN
+SELECT * FROM City
+WHERE (Population >= 100000 OR Name LIKE 'P%' OR Population < 100000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ALL Population,Name NULL NULL NULL 4079 Using where
+EXPLAIN
+SELECT * FROM City
+WHERE (Population >= 100000 OR Name LIKE 'P%') AND Country='CAN' OR
+(Population < 100000 OR Name Like 'T%') AND Country='ARG';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country,Name Country 3 NULL 106 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Population < 200000 AND Name LIKE 'P%' AND
+(Population > 300000 OR Name LIKE 'T%') AND
+(Population < 100000 OR Name LIKE 'Pa%');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Name Name 35 NULL 235 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE Population > 100000 AND Name LIKE 'Aba%' OR
+Country IN ('CAN', 'ARG') AND ID < 3800 OR
+Country < 'U' AND Name LIKE 'Zhu%' OR
+ID BETWEEN 3800 AND 3810;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,PRIMARY 35,3,4 NULL 125 Using sort_union(Name,Country,PRIMARY); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE (Population > 101000 AND Population < 115000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 458 Using index condition
+EXPLAIN
+SELECT * FROM City
+WHERE (Population > 101000 AND Population < 102000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 38 Using index condition
+EXPLAIN
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Country,Name Name,Country 35,3 NULL 213 Using sort_union(Name,Country); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 115000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Name,Country 35,3 NULL 213 Using sort_union(Name,Country); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country,Name Population 4 NULL 38 Using index condition; Using where
+SELECT * FROM City USE INDEX ()
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 115000);
+ID Name Country Population
+403 Catanduva BRA 107761
+412 Cachoeirinha BRA 103240
+636 Bilbays EGY 113608
+637 Mit Ghamr EGY 101801
+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
+759 Gonder ETH 112249
+869 Cabuyao PHL 106630
+870 Calapan PHL 105910
+873 Cauayan PHL 103952
+1844 Cape Breton CAN 114733
+1847 Cambridge CAN 109186
+2908 Cajamarca PER 108009
+3003 Caen FRA 113987
+3411 Ceyhan TUR 102412
+3571 Calabozo VEN 107146
+3786 Cam Ranh VNM 114041
+3792 Tartu EST 101246
+4002 Carrollton USA 109576
+4027 Cape Coral USA 102286
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 115000);
+ID Name Country Population
+403 Catanduva BRA 107761
+412 Cachoeirinha BRA 103240
+636 Bilbays EGY 113608
+637 Mit Ghamr EGY 101801
+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
+759 Gonder ETH 112249
+869 Cabuyao PHL 106630
+870 Calapan PHL 105910
+873 Cauayan PHL 103952
+1844 Cape Breton CAN 114733
+1847 Cambridge CAN 109186
+2908 Cajamarca PER 108009
+3003 Caen FRA 113987
+3411 Ceyhan TUR 102412
+3571 Calabozo VEN 107146
+3786 Cam Ranh VNM 114041
+3792 Tartu EST 101246
+4002 Carrollton USA 109576
+4027 Cape Coral USA 102286
+4032 Cambridge USA 101355
+SELECT * FROM City USE INDEX ()
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+ID Name Country Population
+637 Mit Ghamr EGY 101801
+707 Marbella ESP 101144
+3792 Tartu EST 101246
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+ID Name Country Population
+707 Marbella ESP 101144
+3792 Tartu EST 101246
+4032 Cambridge USA 101355
+637 Mit Ghamr EGY 101801
+EXPLAIN
+SELECT * FROM City WHERE (Name < 'Ac');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 23 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Name < 'Bb');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 373 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Country > 'A' AND Country < 'B');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country Country 3 NULL 106 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'Pb');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 71 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'S');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 384 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Population > 101000 AND Population < 110000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 327 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Population > 103000 AND Population < 104000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 36 Using index condition
+EXPLAIN
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country,Name Name 35 NULL 94 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Name,Population 35,4 NULL 59 Using sort_union(Name,Population); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Country,Name 3,35 NULL 177 Using sort_union(Country,Name); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name Country,Population 3,4 NULL 142 Using sort_union(Country,Population); Using where
+SELECT * FROM City USE INDEX ()
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+ID Name Country Population
+65 Abu Dhabi ARE 398695
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+750 Paarl ZAF 105768
+2865 Pak Pattan PAK 107800
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+ID Name Country Population
+65 Abu Dhabi ARE 398695
+750 Paarl ZAF 105768
+168 Pabna BGD 103277
+2865 Pak Pattan PAK 107800
+189 Parakou BEN 103577
+SELECT * FROM City USE INDEX ()
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+ID Name Country Population
+65 Abu Dhabi ARE 398695
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+1003 Pemalang IDN 103500
+2663 Río Bravo MEX 103901
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+ID Name Country Population
+65 Abu Dhabi ARE 398695
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+1003 Pemalang IDN 103500
+2663 Río Bravo MEX 103901
+SELECT * FROM City USE INDEX ()
+WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+ID Name Country Population
+55 Andorra la Vella AND 21189
+65 Abu Dhabi ARE 398695
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+75 Almirante Brown ARG 538918
+85 Avellaneda ARG 353046
+96 Bahía Blanca ARG 239810
+134 Adelaide AUS 978100
+144 Baku AZE 1787800
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+750 Paarl ZAF 105768
+2865 Pak Pattan PAK 107800
+SELECT * FROM City
+WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+ID Name Country Population
+55 Andorra la Vella AND 21189
+65 Abu Dhabi ARE 398695
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+75 Almirante Brown ARG 538918
+85 Avellaneda ARG 353046
+96 Bahía Blanca ARG 239810
+134 Adelaide AUS 978100
+144 Baku AZE 1787800
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+750 Paarl ZAF 105768
+2865 Pak Pattan PAK 107800
+SELECT * FROM City USE INDEX ()
+WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+ID Name Country Population
+55 Andorra la Vella AND 21189
+65 Abu Dhabi ARE 398695
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+75 Almirante Brown ARG 538918
+85 Avellaneda ARG 353046
+96 Bahía Blanca ARG 239810
+134 Adelaide AUS 978100
+144 Baku AZE 1787800
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+1003 Pemalang IDN 103500
+2663 Río Bravo MEX 103901
+SELECT * FROM City
+WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+ID Name Country Population
+55 Andorra la Vella AND 21189
+65 Abu Dhabi ARE 398695
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+75 Almirante Brown ARG 538918
+85 Avellaneda ARG 353046
+96 Bahía Blanca ARG 239810
+134 Adelaide AUS 978100
+144 Baku AZE 1787800
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+1003 Pemalang IDN 103500
+2663 Río Bravo MEX 103901
+EXPLAIN
+SELECT * FROM City WHERE (ID < 10) OR (ID BETWEEN 100 AND 110);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 20 Using where
+EXPLAIN
+SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 100 AND 200);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 200 Using where
+EXPLAIN
+SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1500);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 1198 Using where
+EXPLAIN
+SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country Country 3 NULL 19 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'H%' OR Name LIKE 'P%' ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 394 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'Ha%' OR Name LIKE 'Pa%' ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 133 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 100 AND 110) AND
+(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 20 Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 900 AND 1500) AND
+(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,PRIMARY 35,3,4 NULL 681 Using sort_union(Name,Country,PRIMARY); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 100 AND 200) AND
+(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 200 Using where
+SELECT * FROM City USE INDEX ()
+WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 100 AND 110) AND
+(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
+ID Name Country Population
+1 Kabul AFG 1780000
+2 Qandahar AFG 237500
+3 Herat AFG 186800
+4 Mazar-e-Sharif AFG 127800
+7 Haag NLD 440900
+100 Paraná ARG 207041
+102 Posadas ARG 201273
+SELECT * FROM City
+WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 100 AND 110) AND
+(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
+ID Name Country Population
+1 Kabul AFG 1780000
+2 Qandahar AFG 237500
+3 Herat AFG 186800
+4 Mazar-e-Sharif AFG 127800
+7 Haag NLD 440900
+100 Paraná ARG 207041
+102 Posadas ARG 201273
+SELECT * FROM City USE INDEX()
+WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 900 AND 1500) AND
+(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+ID Name Country Population
+1 Kabul AFG 1780000
+2 Qandahar AFG 237500
+3 Herat AFG 186800
+4 Mazar-e-Sharif AFG 127800
+7 Haag NLD 440900
+16 Haarlem NLD 148772
+25 Haarlemmermeer NLD 110722
+33 Willemstad ANT 2345
+34 Tirana ALB 270000
+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
+64 Dubai ARE 669181
+65 Abu Dhabi ARE 398695
+66 Sharja ARE 320095
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+129 Oranjestad ABW 29034
+191 Hamilton BMU 1200
+528 Hartlepool GBR 92000
+529 Halifax GBR 91069
+914 Sekondi-Takoradi GHA 103653
+943 Palembang IDN 1222764
+950 Padang IDN 534474
+983 Palu IDN 142800
+984 Pasuruan IDN 134019
+991 Pangkal Pinang IDN 124000
+1003 Pemalang IDN 103500
+1004 Klaten IDN 103300
+1007 Palangka Raya IDN 99693
+1020 Padang Sidempuan IDN 91200
+1045 Patna IND 917243
+1114 Panihati IND 275990
+1129 Patiala IND 238368
+1142 Panipat IND 215218
+1159 Parbhani IND 190255
+1231 Pali IND 136842
+1263 Pathankot IND 123930
+1265 Palghat (Palakkad) IND 123289
+1293 Pallavaram IND 111866
+1319 Tellicherry (Thalassery) IND 103579
+1339 Palayankottai IND 97662
+1345 Patan IND 96109
+1436 Marv Dasht IRN 103579
+1468 Palermo ITA 683794
+1478 Padova ITA 211391
+1484 Parma ITA 168717
+SELECT * FROM City
+WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 900 AND 1500) AND
+(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+ID Name Country Population
+1 Kabul AFG 1780000
+2 Qandahar AFG 237500
+3 Herat AFG 186800
+4 Mazar-e-Sharif AFG 127800
+7 Haag NLD 440900
+16 Haarlem NLD 148772
+25 Haarlemmermeer NLD 110722
+33 Willemstad ANT 2345
+34 Tirana ALB 270000
+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
+64 Dubai ARE 669181
+65 Abu Dhabi ARE 398695
+66 Sharja ARE 320095
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+129 Oranjestad ABW 29034
+191 Hamilton BMU 1200
+528 Hartlepool GBR 92000
+529 Halifax GBR 91069
+914 Sekondi-Takoradi GHA 103653
+943 Palembang IDN 1222764
+950 Padang IDN 534474
+983 Palu IDN 142800
+984 Pasuruan IDN 134019
+991 Pangkal Pinang IDN 124000
+1003 Pemalang IDN 103500
+1004 Klaten IDN 103300
+1007 Palangka Raya IDN 99693
+1020 Padang Sidempuan IDN 91200
+1045 Patna IND 917243
+1114 Panihati IND 275990
+1129 Patiala IND 238368
+1142 Panipat IND 215218
+1159 Parbhani IND 190255
+1231 Pali IND 136842
+1263 Pathankot IND 123930
+1265 Palghat (Palakkad) IND 123289
+1293 Pallavaram IND 111866
+1319 Tellicherry (Thalassery) IND 103579
+1339 Palayankottai IND 97662
+1345 Patan IND 96109
+1436 Marv Dasht IRN 103579
+1468 Palermo ITA 683794
+1478 Padova ITA 211391
+1484 Parma ITA 168717
+SELECT * FROM City USE INDEX ()
+WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 100 AND 200) AND
+(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+ID Name Country Population
+1 Kabul AFG 1780000
+2 Qandahar AFG 237500
+3 Herat AFG 186800
+4 Mazar-e-Sharif AFG 127800
+7 Haag NLD 440900
+16 Haarlem NLD 148772
+25 Haarlemmermeer NLD 110722
+33 Willemstad ANT 2345
+34 Tirana ALB 270000
+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
+64 Dubai ARE 669181
+65 Abu Dhabi ARE 398695
+66 Sharja ARE 320095
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+100 Paraná ARG 207041
+129 Oranjestad ABW 29034
+167 Jamalpur BGD 103556
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+191 Hamilton BMU 1200
+SELECT * FROM City
+WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+OR ((ID BETWEEN 100 AND 200) AND
+(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+ID Name Country Population
+1 Kabul AFG 1780000
+2 Qandahar AFG 237500
+3 Herat AFG 186800
+4 Mazar-e-Sharif AFG 127800
+7 Haag NLD 440900
+16 Haarlem NLD 148772
+25 Haarlemmermeer NLD 110722
+33 Willemstad ANT 2345
+34 Tirana ALB 270000
+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
+64 Dubai ARE 669181
+65 Abu Dhabi ARE 398695
+66 Sharja ARE 320095
+67 al-Ayn ARE 225970
+68 Ajman ARE 114395
+100 Paraná ARG 207041
+129 Oranjestad ABW 29034
+167 Jamalpur BGD 103556
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+191 Hamilton BMU 1200
+EXPLAIN
+SELECT * FROM City WHERE Population > 101000 AND Population < 102000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 38 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Population > 101000 AND Population < 110000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 327 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Country < 'C';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country Country 3 NULL 446 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Country < 'AGO';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country Country 3 NULL 5 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Name BETWEEN 'P' AND 'S';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 384 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Name BETWEEN 'P' AND 'Pb';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 71 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 3400 AND 3800;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 400 Using where
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'P%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 235 Using index condition
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 102000) AND
+(Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR
+((ID BETWEEN 3400 AND 3800) AND
+(Country < 'AGO' OR Name LIKE 'Pa%'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name Population,PRIMARY 4,4 NULL 438 Using sort_union(Population,PRIMARY); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 110000) AND
+(Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR
+((ID BETWEEN 3790 AND 3800) AND
+(Country < 'C' OR Name LIKE 'P%'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name Country,Name,PRIMARY 3,35,4 NULL 87 Using sort_union(Country,Name,PRIMARY); Using where
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 102000) AND
+(Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR
+((ID BETWEEN 3400 AND 3800) AND
+(Country < 'AGO' OR Name LIKE 'Pa%'));
+ID Name Country Population
+169 Naogaon BGD 101266
+205 Francistown BWA 101805
+417 Itaituba BRA 101320
+418 Araras BRA 101046
+751 Potchefstroom ZAF 101817
+2909 Puno PER 101578
+3463 Pavlograd UKR 127000
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 102000) AND
+(Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR
+((ID BETWEEN 3400 AND 3800) AND
+(Country < 'AGO' OR Name LIKE 'Pa%'));
+ID Name Country Population
+169 Naogaon BGD 101266
+205 Francistown BWA 101805
+417 Itaituba BRA 101320
+418 Araras BRA 101046
+751 Potchefstroom ZAF 101817
+2909 Puno PER 101578
+3463 Pavlograd UKR 127000
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 110000) AND
+(Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR
+((ID BETWEEN 3790 AND 3800) AND
+(Country < 'C' OR Name LIKE 'P%'));
+ID Name Country Population
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+750 Paarl ZAF 105768
+2865 Pak Pattan PAK 107800
+3797 Philadelphia USA 1517550
+3798 Phoenix USA 1321045
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 110000) AND
+(Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR
+((ID BETWEEN 3790 AND 3800) AND
+(Country < 'C' OR Name LIKE 'P%'));
+ID Name Country Population
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+750 Paarl ZAF 105768
+2865 Pak Pattan PAK 107800
+3797 Philadelphia USA 1517550
+3798 Phoenix USA 1321045
+CREATE INDEX CountryPopulation ON City(Country,Population);
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'Pas%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 8 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'P%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 235 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Population > 101000 AND Population < 103000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 80 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Country='USA';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref Country,CountryPopulation Country 3 const 274 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Country='FIN';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref Country,CountryPopulation Country 3 const 7 Using index condition
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
+AND Country='USA';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 17 Using sort_union(CountryPopulation,Name); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
+AND Country='FIN';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 7 Using index condition; Using where
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
+AND Country='USA';
+ID Name Country Population
+3943 Pasadena USA 141674
+3953 Pasadena USA 133936
+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
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
+AND Country='USA';
+ID Name Country Population
+3943 Pasadena USA 141674
+3953 Pasadena USA 133936
+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
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
+AND Country='FIN';
+ID Name Country Population
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
+AND Country='FIN';
+ID Name Country Population
+CREATE INDEX CountryName ON City(Country,Name);
+EXPLAIN
+SELECT * FROM City WHERE Country='USA';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 274 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Country='FIN';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 7 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Country='BRA';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 250 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 4025 AND 4035;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 4028 AND 4032;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 5 Using where
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 3500 AND 3800;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 300 Using where
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 4000 AND 4300;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 80 Using where
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 250 and 260 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where
+EXPLAIN
+SELECT * FROM City WHERE (Population > 101000 AND Population < 102000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 38 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE (Population > 101000 AND Population < 103000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL 80 Using index condition
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'Pa%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Name Name 35 NULL 71 Using index condition
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryPopulation,PRIMARY 7,4 NULL 13 Using sort_union(CountryPopulation,PRIMARY); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 103000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName,PRIMARY 38,4 NULL 10 Using sort_union(CountryName,PRIMARY); Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 110000) OR
+ID BETWEEN 3500 AND 3800) AND Country='FIN'
+ AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName Country 3 const 7 Using index condition; Using where
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+ID Name Country Population
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+ID Name Country Population
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032);
+ID Name Country Population
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032);
+ID Name Country Population
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='FIN'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+ID Name Country Population
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='FIN'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+ID Name Country Population
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 and Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryPopulation,CountryName,PRIMARY 7,38,4 NULL 35 Using sort_union(CountryPopulation,CountryName,PRIMARY); Using where
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 and Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA';
+ID Name Country Population
+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
+285 Paulista BRA 248473
+339 Passo Fundo BRA 166343
+364 Parnaíba BRA 129756
+372 Paranaguá BRA 126076
+379 Palmas BRA 121919
+386 Patos de Minas BRA 119262
+424 Passos BRA 98570
+430 Paulo Afonso BRA 97291
+435 Parnamirim BRA 96210
+448 Patos BRA 90519
+451 Palhoça BRA 89465
+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
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE ((Population > 101000 and Population < 102000) OR
+ID BETWEEN 3790 AND 3800) AND Country='USA'
+ OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA';
+ID Name Country Population
+285 Paulista BRA 248473
+339 Passo Fundo BRA 166343
+364 Parnaíba BRA 129756
+372 Paranaguá BRA 126076
+379 Palmas BRA 121919
+386 Patos de Minas BRA 119262
+424 Passos BRA 98570
+430 Paulo Afonso BRA 97291
+435 Parnamirim BRA 96210
+448 Patos BRA 90519
+451 Palhoça BRA 89465
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+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
+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
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 11000) OR
+ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName 38 NULL 18 Using index condition; Using where
+EXPLAIN
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 11000) OR
+ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName Name 35 NULL 1 Using index condition; Using where
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 11000) OR
+ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300);
+ID Name Country Population
+3797 Philadelphia USA 1517550
+3798 Phoenix USA 1321045
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 11000) OR
+ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300);
+ID Name Country Population
+3797 Philadelphia USA 1517550
+3798 Phoenix USA 1321045
+SELECT * FROM City USE INDEX ()
+WHERE ((Population > 101000 AND Population < 11000) OR
+ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300);
+ID Name Country Population
+3798 Phoenix USA 1321045
+SELECT * FROM City
+WHERE ((Population > 101000 AND Population < 11000) OR
+ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300);
+ID Name Country Population
+3798 Phoenix USA 1321045
+DROP INDEX Population ON City;
+DROP INDEX Name ON City;
+EXPLAIN
+SELECT * FROM City
+WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR
+Country='USA' AND Name LIKE 'Pa%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Country,CountryPopulation,CountryName CountryPopulation,CountryName 7,38 NULL 8 Using sort_union(CountryPopulation,CountryName); Using where
+SELECT * FROM City USE INDEX()
+WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR
+Country='USA' AND Name LIKE 'Pa%';
+ID Name Country Population
+3932 Paterson USA 149222
+3943 Pasadena USA 141674
+3953 Pasadena USA 133936
+3967 Paradise USA 124682
+3986 Palmdale USA 116670
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR
+Country='USA' AND Name LIKE 'Pa%';
+ID Name Country Population
+3932 Paterson USA 149222
+3943 Pasadena USA 141674
+3953 Pasadena USA 133936
+3967 Paradise USA 124682
+3986 Palmdale USA 116670
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+EXPLAIN
+SELECT * FROM City
+WHERE Country='USA' AND
+(Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Country,CountryPopulation,CountryName CountryPopulation,CountryName 7,38 NULL 8 Using sort_union(CountryPopulation,CountryName); Using where
+SELECT * FROM City
+WHERE Country='USA' AND
+(Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%');
+ID Name Country Population
+3932 Paterson USA 149222
+3943 Pasadena USA 141674
+3953 Pasadena USA 133936
+3967 Paradise USA 124682
+3986 Palmdale USA 116670
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+SELECT * FROM City
+WHERE Country='USA' AND
+(Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%');
+ID Name Country Population
+3932 Paterson USA 149222
+3943 Pasadena USA 141674
+3953 Pasadena USA 133936
+3967 Paradise USA 124682
+3986 Palmdale USA 116670
+4030 Sandy USA 101853
+4031 Athens-Clarke County USA 101489
+4032 Cambridge USA 101355
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE INDEX CityName on City(Name);
+EXPLAIN SELECT Name, Country, Population FROM City WHERE
+(Name='Manila' AND Country='PHL') OR
+(Name='Addis Abeba' AND Country='ETH') OR
+(Name='Jakarta' AND Country='IDN') OR
+(Name='Bangalore' AND Country='IND') OR
+(Name='Teheran' AND Country='IRN') OR
+(Name='Roma' AND Country='ITA') OR
+(Name='Delhi' AND Country='IND') OR
+(Name='Venezia' AND Country='ITA') OR
+(Name='Tokyo' AND Country='JPN') OR
+(Name='Toronto' AND Country='CAN') OR
+(Name='Peking' AND Country='CHN') OR
+(Name='Lagos' AND Country='NGA') OR
+(Name='Tijuana' AND Country='MEX') OR
+(Name='Rabat' AND Country='MAR') OR
+(Name='Seoul' AND Country='KOR') OR
+(Name='Vancouver' AND Country='CAN') OR
+(Name='Kaunas' AND Country='LTU') OR
+(Name='Paris' AND Country='FRA') OR
+(Name='Dakar' AND Country='SEN') OR
+(Name='Basel' AND Country='CHE') OR
+(Name='Praha' AND Country='CZE') OR
+(Name='Ankara' AND Country='TUR') OR
+(Name='Dresden' AND Country='DEU') OR
+(Name='Lugansk' AND Country='UKR') OR
+(Name='Caracas' AND Country='VEN') OR
+(Name='Samara' AND Country='RUS') OR
+(Name='Seattle' AND Country='USA');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country,CountryPopulation,CountryName,CityName CountryName 38 NULL 27 Using index condition; Using where
+SELECT Name, Country, Population FROM City WHERE
+(Name='Manila' AND Country='PHL') OR
+(Name='Addis Abeba' AND Country='ETH') OR
+(Name='Jakarta' AND Country='IDN') OR
+(Name='Bangalore' AND Country='IND') OR
+(Name='Teheran' AND Country='IRN') OR
+(Name='Roma' AND Country='ITA') OR
+(Name='Delhi' AND Country='IND') OR
+(Name='Venezia' AND Country='ITA') OR
+(Name='Tokyo' AND Country='JPN') OR
+(Name='Toronto' AND Country='CAN') OR
+(Name='Peking' AND Country='CHN') OR
+(Name='Lagos' AND Country='NGA') OR
+(Name='Tijuana' AND Country='MEX') OR
+(Name='Rabat' AND Country='MAR') OR
+(Name='Seoul' AND Country='KOR') OR
+(Name='Vancouver' AND Country='CAN') OR
+(Name='Kaunas' AND Country='LTU') OR
+(Name='Paris' AND Country='FRA') OR
+(Name='Dakar' AND Country='SEN') OR
+(Name='Basel' AND Country='CHE') OR
+(Name='Praha' AND Country='CZE') OR
+(Name='Ankara' AND Country='TUR') OR
+(Name='Dresden' AND Country='DEU') OR
+(Name='Lugansk' AND Country='UKR') OR
+(Name='Caracas' AND Country='VEN') OR
+(Name='Samara' AND Country='RUS') OR
+(Name='Seattle' AND Country='USA');
+Name Country Population
+Toronto CAN 688275
+Vancouver CAN 514008
+Basel CHE 166700
+Peking CHN 7472000
+Praha CZE 1181126
+Dresden DEU 476668
+Addis Abeba ETH 2495000
+Paris FRA 2125246
+Jakarta IDN 9604900
+Bangalore IND 2660088
+Delhi IND 7206704
+Teheran IRN 6758845
+Roma ITA 2643581
+Venezia ITA 277305
+Tokyo JPN 7980230
+Seoul KOR 9981619
+Kaunas LTU 412639
+Rabat MAR 623457
+Tijuana MEX 1212232
+Lagos NGA 1518000
+Manila PHL 1581082
+Samara RUS 1156100
+Dakar SEN 785071
+Ankara TUR 3038159
+Lugansk UKR 469000
+Seattle USA 563374
+Caracas VEN 1975294
+set optimizer_switch='index_merge=off';
+EXPLAIN SELECT Name, Country, Population FROM City WHERE
+(Name='Manila' AND Country='PHL') OR
+(Name='Addis Abeba' AND Country='ETH') OR
+(Name='Jakarta' AND Country='IDN') OR
+(Name='Bangalore' AND Country='IND') OR
+(Name='Teheran' AND Country='IRN') OR
+(Name='Roma' AND Country='ITA') OR
+(Name='Delhi' AND Country='IND') OR
+(Name='Venezia' AND Country='ITA') OR
+(Name='Tokyo' AND Country='JPN') OR
+(Name='Toronto' AND Country='CAN') OR
+(Name='Peking' AND Country='CHN') OR
+(Name='Lagos' AND Country='NGA') OR
+(Name='Tijuana' AND Country='MEX') OR
+(Name='Rabat' AND Country='MAR') OR
+(Name='Seoul' AND Country='KOR') OR
+(Name='Vancouver' AND Country='CAN') OR
+(Name='Kaunas' AND Country='LTU') OR
+(Name='Paris' AND Country='FRA') OR
+(Name='Dakar' AND Country='SEN') OR
+(Name='Basel' AND Country='CHE') OR
+(Name='Praha' AND Country='CZE') OR
+(Name='Ankara' AND Country='TUR') OR
+(Name='Dresden' AND Country='DEU') OR
+(Name='Lugansk' AND Country='UKR') OR
+(Name='Caracas' AND Country='VEN') OR
+(Name='Samara' AND Country='RUS') OR
+(Name='Seattle' AND Country='USA');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country,CountryPopulation,CountryName,CityName CountryName 38 NULL 27 Using index condition; Using where
+SELECT Name, Country, Population FROM City WHERE
+(Name='Manila' AND Country='PHL') OR
+(Name='Addis Abeba' AND Country='ETH') OR
+(Name='Jakarta' AND Country='IDN') OR
+(Name='Bangalore' AND Country='IND') OR
+(Name='Teheran' AND Country='IRN') OR
+(Name='Roma' AND Country='ITA') OR
+(Name='Delhi' AND Country='IND') OR
+(Name='Venezia' AND Country='ITA') OR
+(Name='Tokyo' AND Country='JPN') OR
+(Name='Toronto' AND Country='CAN') OR
+(Name='Peking' AND Country='CHN') OR
+(Name='Lagos' AND Country='NGA') OR
+(Name='Tijuana' AND Country='MEX') OR
+(Name='Rabat' AND Country='MAR') OR
+(Name='Seoul' AND Country='KOR') OR
+(Name='Vancouver' AND Country='CAN') OR
+(Name='Kaunas' AND Country='LTU') OR
+(Name='Paris' AND Country='FRA') OR
+(Name='Dakar' AND Country='SEN') OR
+(Name='Basel' AND Country='CHE') OR
+(Name='Praha' AND Country='CZE') OR
+(Name='Ankara' AND Country='TUR') OR
+(Name='Dresden' AND Country='DEU') OR
+(Name='Lugansk' AND Country='UKR') OR
+(Name='Caracas' AND Country='VEN') OR
+(Name='Samara' AND Country='RUS') OR
+(Name='Seattle' AND Country='USA');
+Name Country Population
+Toronto CAN 688275
+Vancouver CAN 514008
+Basel CHE 166700
+Peking CHN 7472000
+Praha CZE 1181126
+Dresden DEU 476668
+Addis Abeba ETH 2495000
+Paris FRA 2125246
+Jakarta IDN 9604900
+Bangalore IND 2660088
+Delhi IND 7206704
+Teheran IRN 6758845
+Roma ITA 2643581
+Venezia ITA 277305
+Tokyo JPN 7980230
+Seoul KOR 9981619
+Kaunas LTU 412639
+Rabat MAR 623457
+Tijuana MEX 1212232
+Lagos NGA 1518000
+Manila PHL 1581082
+Samara RUS 1156100
+Dakar SEN 785071
+Ankara TUR 3038159
+Lugansk UKR 469000
+Seattle USA 563374
+Caracas VEN 1975294
+set optimizer_switch=@save_optimizer_switch;
+#
+# Bug mdev-585: range vs index-merge with ORDER BY ... LIMIT n
+# (LP bug #637962)
+#
+DROP INDEX CountryPopulation ON City;
+DROP INDEX CountryName ON City;
+DROP INDEX CityName on City;
+CREATE INDEX Name ON City(Name);
+CREATE INDEX Population ON City(Population);
+EXPLAIN
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+AND (Population >= 100000 AND Population < 120000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Country,Name,Population Name,Country 35,3 NULL # Using sort_union(Name,Country); Using where
+FLUSH STATUS;
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+AND (Population >= 100000 AND Population < 120000);
+ID Name Country Population
+384 Cabo Frio BRA 119503
+387 Camaragibe BRA 118968
+403 Catanduva BRA 107761
+412 Cachoeirinha BRA 103240
+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
+635 Mallawi EGY 119283
+636 Bilbays EGY 113608
+637 Mit Ghamr EGY 101801
+638 al-Arish EGY 100447
+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
+759 Gonder ETH 112249
+869 Cabuyao PHL 106630
+870 Calapan PHL 105910
+873 Cauayan PHL 103952
+903 Serekunda GMB 102600
+909 Sohumi GEO 111700
+913 Tema GHA 109975
+914 Sekondi-Takoradi GHA 103653
+924 Villa Nueva GTM 101295
+1844 Cape Breton CAN 114733
+1847 Cambridge CAN 109186
+2406 Herakleion GRC 116178
+2407 Kallithea GRC 114233
+2408 Larisa GRC 113090
+2908 Cajamarca PER 108009
+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
+3411 Ceyhan TUR 102412
+3567 Carúpano VEN 119639
+3568 Catia La Mar VEN 117012
+3571 Calabozo VEN 107146
+3786 Cam Ranh VNM 114041
+3792 Tartu EST 101246
+4002 Carrollton USA 109576
+4027 Cape Coral USA 102286
+4032 Cambridge USA 101355
+SHOW STATUS LIKE 'Handler_read_%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 2
+Handler_read_next 385
+Handler_read_prev 0
+Handler_read_rnd 377
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 0
+EXPLAIN
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+AND (Population >= 100000 AND Population < 120000)
+ORDER BY Population LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country,Name,Population Population 4 NULL # Using where
+FLUSH STATUS;
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+AND (Population >= 100000 AND Population < 120000)
+ORDER BY Population LIMIT 5;
+ID Name Country Population
+519 Worthing GBR 100000
+638 al-Arish EGY 100447
+518 Basildon GBR 100924
+707 Marbella ESP 101144
+3792 Tartu EST 101246
+SHOW STATUS LIKE 'Handler_read_%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 1
+Handler_read_next 59
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 0
+set optimizer_switch='index_merge=off';
+EXPLAIN
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+AND (Population >= 100000 AND Population < 120000)
+ORDER BY Population LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Country,Name,Population Population 4 NULL # Using index condition; Using where
+FLUSH STATUS;
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+AND (Population >= 100000 AND Population < 120000)
+ORDER BY Population LIMIT 5;
+ID Name Country Population
+519 Worthing GBR 100000
+638 al-Arish EGY 100447
+518 Basildon GBR 100924
+707 Marbella ESP 101144
+3792 Tartu EST 101246
+SHOW STATUS LIKE 'Handler_read_%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 1
+Handler_read_next 59
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 0
+set optimizer_switch=@save_optimizer_switch;
+DROP DATABASE world;
+use test;
+CREATE TABLE t1 (
+id int(10) unsigned NOT NULL auto_increment,
+account_id int(10) unsigned NOT NULL,
+first_name varchar(50) default NULL,
+middle_name varchar(50) default NULL,
+last_name varchar(100) default NULL,
+home_address_1 varchar(150) default NULL,
+home_city varchar(75) default NULL,
+home_state char(2) default NULL,
+home_postal_code varchar(50) default NULL,
+home_county varchar(75) default NULL,
+home_country char(3) default NULL,
+work_address_1 varchar(150) default NULL,
+work_city varchar(75) default NULL,
+work_state char(2) default NULL,
+work_postal_code varchar(50) default NULL,
+work_county varchar(75) default NULL,
+work_country char(3) default NULL,
+login varchar(50) NOT NULL,
+PRIMARY KEY (id),
+KEY login (login,account_id),
+KEY account_id (account_id),
+KEY user_home_country_indx (home_country),
+KEY user_work_country_indx (work_country),
+KEY user_home_state_indx (home_state),
+KEY user_work_state_indx (work_state),
+KEY user_home_city_indx (home_city),
+KEY user_work_city_indx (work_city),
+KEY user_first_name_indx (first_name),
+KEY user_last_name_indx (last_name)
+);
+insert into t1(account_id, login, home_state, work_state) values
+(1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'),
+(1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia');
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+select 1, 'pw', 'ak', 'ak' from t1;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+select count(*) from t1 where account_id = 1;
+count(*)
+3072
+select * from t1
+where (home_state = 'ia' or work_state='ia') and account_id = 1;
+id account_id first_name middle_name last_name home_address_1 home_city home_state home_postal_code home_county home_country work_address_1 work_city work_state work_postal_code work_county work_country login
+1 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw
+2 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw
+3 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw
+4 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw
+5 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw
+6 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw
+explain
+select * from t1
+where (home_state = 'ia' or work_state='ia') and account_id = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge account_id,user_home_state_indx,user_work_state_indx user_home_state_indx,user_work_state_indx 3,3 NULL 10 Using union(user_home_state_indx,user_work_state_indx); Using where
+drop table t1;
+CREATE TABLE t1 (
+c1 int(11) NOT NULL auto_increment,
+c2 decimal(10,0) default NULL,
+c3 decimal(10,0) default NULL,
+c4 decimal(10,0) default NULL,
+c5 decimal(10,0) default NULL,
+cp decimal(1,0) default NULL,
+ce decimal(10,0) default NULL,
+cdata char(20),
+PRIMARY KEY (c1),
+KEY k1 (c2,c3,cp,ce),
+KEY k2 (c4,c5,cp,ce)
+);
+insert into t1 (c2, c3, c4, c5, cp) values(1,1,1,1,1);
+insert into t1 (c2, c3, c4, c5, cp) values(2,1,1,1,4);
+insert into t1 (c2, c3, c4, c5, cp) values(2,1,2,1,1);
+insert into t1 (c2, c3, c4, c5, cp) values(2,1,3,1,4);
+insert into t1 (c2, c3, c4, c5, cp) values(3,1,4,1,4);
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+select c2, c3, c4, c5, cp from t1 where cp = 4;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+explain
+select * from t1 where (c2=1 and c3=1) or (c4=2 and c5=1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge k1,k2 k1,k2 12,12 NULL 2 Using sort_union(k1,k2); Using where
+explain
+select * from t1
+where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge k1,k2 k1,k2 14,14 NULL 2 Using sort_union(k1,k2); Using where
+explain
+select * from t1
+where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge k1,k2 k1,k2 14,14 NULL 2 Using sort_union(k1,k2); Using where
+select * from t1
+where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1);
+c1 c2 c3 c4 c5 cp ce cdata
+1 1 1 1 1 1 NULL NULL
+3 2 1 2 1 1 NULL NULL
+select * from t1
+where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1;
+c1 c2 c3 c4 c5 cp ce cdata
+1 1 1 1 1 1 NULL NULL
+3 2 1 2 1 1 NULL NULL
+drop table t1;
+create table t1 (
+c1 int auto_increment primary key,
+c2 char(20),
+c3 char (20),
+c4 int
+);
+alter table t1 add key k1 (c2);
+alter table t1 add key k2 (c3);
+alter table t1 add key k3 (c4);
+insert into t1 values(null, 'a', 'b', 0);
+insert into t1 values(null, 'c', 'b', 0);
+insert into t1 values(null, 'a', 'd', 0);
+insert into t1 values(null, 'ccc', 'qqq', 0);
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3,c4) select c2,c3,1 from t1 where c2 != 'a';
+insert into t1 (c2,c3,c4) select c2,c3,2 from t1 where c2 != 'a';
+insert into t1 (c2,c3,c4) select c2,c3,3 from t1 where c2 != 'a';
+insert into t1 (c2,c3,c4) select c2,c3,4 from t1 where c2 != 'a';
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+select count(*) from t1 where (c2='e' OR c3='q');
+count(*)
+0
+select count(*) from t1 where c4 != 0;
+count(*)
+3840
+explain
+select distinct c1 from t1 where (c2='e' OR c3='q');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge k1,k2 k1,k2 21,21 NULL 2 Using union(k1,k2); Using where
+explain
+select distinct c1 from t1 where (c4!= 0) AND (c2='e' OR c3='q');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge k1,k2,k3 k1,k2 21,21 NULL 2 Using union(k1,k2); Using where
+drop table t1;
+create table t1 (
+id int unsigned auto_increment primary key,
+c1 char(12),
+c2 char(15),
+c3 char(1)
+);
+insert into t1 (c3) values ('1'), ('2');
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+update t1 set c1=lpad(id+1000, 12, ' '), c2=lpad(id+10000, 15, ' ');
+alter table t1 add unique index (c1), add unique index (c2), add index (c3);
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+explain
+select * from t1 where (c1=' 100000' or c2=' 2000000');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge c1,c2 c1,c2 13,16 NULL 2 Using union(c1,c2); Using where
+explain
+select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge c1,c2,c3 c1,c2 13,16 NULL 2 Using union(c1,c2); Using where
+select * from t1 where (c1=' 100000' or c2=' 2000000');
+id c1 c2 c3
+select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2';
+id c1 c2 c3
+drop table t1;
+CREATE TABLE t1 (
+a smallint DEFAULT NULL,
+pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+b varchar(10) DEFAULT NULL,
+c varchar(64) DEFAULT NULL,
+INDEX idx1 (a),
+INDEX idx2 (b),
+INDEX idx3 (c)
+);
+SELECT COUNT(*) FROM t1 IGNORE INDEX (idx2,idx3)
+WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR
+(pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ;
+COUNT(*)
+5
+SELECT COUNT(*) FROM t1
+WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR
+(pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ;
+COUNT(*)
+5
+EXPLAIN
+SELECT COUNT(*) FROM t1
+WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR
+(pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,idx1,PRIMARY 67,13,3,4 NULL 9 Using sort_union(idx3,idx2,idx1,PRIMARY); Using where
+DROP TABLE t1;
+CREATE TABLE t1 (
+f1 int, f2 int, f3 int, f4 int, f5 int,
+PRIMARY KEY (f4), KEY (f1), KEY (f2), KEY (f3)
+) ;
+INSERT INTO t1 VALUES (0,0,NULL,9,5), (0,0,1,9425,NULL);
+SELECT f5 FROM t1
+WHERE f2 != 1 OR f1 IS NULL OR f4 = 4 OR
+f2 AND (f4 BETWEEN 6 AND 255 OR f3 IS NULL);
+f5
+5
+NULL
+DROP TABLE t1;
+CREATE TABLE t1 (
+f1 int, f2 int, f3 int, f4 int,
+PRIMARY KEY (f1), KEY (f3), KEY (f4)
+);
+INSERT INTO t1 VALUES (9,0,2,6), (9930,0,0,NULL);
+SET SESSION optimizer_switch='index_merge_intersection=off';
+SET SESSION optimizer_switch='index_merge_sort_union=off';
+SET SESSION optimizer_switch='index_merge_union=off';
+EXPLAIN
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,f3,f4 NULL NULL NULL 2 Using where
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+f1 f2 f3 f4
+9 0 2 6
+SET SESSION optimizer_switch='index_merge_union=on';
+EXPLAIN
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge PRIMARY,f3,f4 PRIMARY,f3 4,5 NULL 2 Using union(PRIMARY,f3); Using where
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+f1 f2 f3 f4
+9 0 2 6
+INSERT INTO t1 VALUES
+(93,0,3,6), (9933,0,3,3), (94,0,4,6), (9934,0,4,4),
+(95,0,5,6), (9935,0,5,5), (96,0,6,6), (9936,0,6,6),
+(97,0,7,6), (9937,0,7,7), (98,0,8,6), (9938,0,8,8),
+(99,0,9,6), (9939,0,9,9);
+SET SESSION optimizer_switch='index_merge_union=off';
+EXPLAIN
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,f3,f4 NULL NULL NULL 16 Using where
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+f1 f2 f3 f4
+9 0 2 6
+SET SESSION optimizer_switch='index_merge_union=on';
+EXPLAIN
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge PRIMARY,f3,f4 PRIMARY,f3 4,5 NULL 2 Using union(PRIMARY,f3); Using where
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+f1 f2 f3 f4
+9 0 2 6
+SET SESSION optimizer_switch=DEFAULT;
+DROP TABLE t1;
+CREATE TABLE t1 (f1 int) ;
+INSERT INTO t1 VALUES (0), (0);
+CREATE TABLE t2 (f1 int, f2 int, f3 int, f4 int, INDEX idx (f3,f2)) ;
+INSERT INTO t2 VALUES (5,6,0,0), (0,4,0,0);
+CREATE TABLE t3 (f1 int, f2 int, INDEX idx1 (f2,f1) , INDEX idx2 (f1)) ;
+INSERT INTO t3 VALUES (6,0),( 4,0);
+SELECT * FROM t1,t2,t3
+WHERE (t2.f3 = 1 OR t3.f1=t2.f1) AND t3.f1 <> t2.f2 AND t3.f2 = t2.f4;
+f1 f1 f2 f3 f4 f1 f2
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (
+a int, b int, c int, d int,
+PRIMARY KEY(b), INDEX idx1(d), INDEX idx2(d,b,c)
+);
+INSERT INTO t1 VALUES
+(0,58,7,7),(0,63,2,0),(0,64,186,8),(0,65,1,-2), (0,71,190,-3),
+(0,72,321,-7),(0,73,0,3),(0,74,5,25),(0,75,5,3);
+SET SESSION optimizer_switch='index_merge_sort_union=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 9 Using where
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+a b c d
+0 58 7 7
+0 64 186 8
+0 73 0 3
+0 74 5 25
+0 75 5 3
+SET SESSION optimizer_switch='index_merge_sort_union=on';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 9 Using where
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+a b c d
+0 58 7 7
+0 64 186 8
+0 73 0 3
+0 74 5 25
+0 75 5 3
+SET SESSION optimizer_switch=DEFAULT;
+DROP TABLE t1;
+CREATE TABLE t1 (a int NOT NULL PRIMARY KEY, b int, c int, INDEX idx(c,b));
+INSERT INTO t1 VALUES (19,1,NULL), (20,5,7);
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND
+(t1.c=0 OR t1.a=500);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,idx PRIMARY 4 NULL 1 Using where
+SELECT * FROM t1
+WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND
+(t1.c=0 OR t1.a=500);
+a b c
+DROP TABLE t1;
+CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX idx(b));
+INSERT INTO t1 VALUES (167,9999), (168,10000);
+EXPLAIN
+SELECT * FROM t1
+WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index PRIMARY,idx idx 5 NULL 2 Using where; Using index
+SELECT * FROM t1
+WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2;
+a b
+167 9999
+168 10000
+DROP TABLE t1;
+set session optimizer_switch='index_merge_sort_intersection=default';
+SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/r/read_only_innodb.result b/mysql-test/r/read_only_innodb.result
index 690de085bf9..2633c54a307 100644
--- a/mysql-test/r/read_only_innodb.result
+++ b/mysql-test/r/read_only_innodb.result
@@ -43,6 +43,28 @@ a
1
COMMIT;
UNLOCK TABLES;
+FLUSH STATUS;
+# Expected 0 at the beginning of the test
+show status like 'Opened_tables';
+Variable_name Value
+Opened_tables 0
+connection con1;
+lock table t1 write;
+connection default;
+set global read_only=1;
+# Expected 1 as the slow_log was reopened
+show status like 'Opened_tables';
+Variable_name Value
+Opened_tables 1
+connection con1;
+unlock tables;
+connection default;
+SET GLOBAL read_only=0;
+# Expected 2 as the slow_log was reopened
+show status like 'Opened_tables';
+Variable_name Value
+Opened_tables 2
+UNLOCK TABLES;
DROP TABLE t1;
DROP USER test@localhost;
echo End of 5.1 tests
diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result
index 789b9c4f383..f94c958a1be 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);
@@ -405,7 +405,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 6 100.00 Using index
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 12 test.t1.a,const,const 1 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = 1) and (`test`.`t2`.`b` = 2) and (`test`.`t2`.`a` = `test`.`t1`.`a`))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`b` = 2) and (`test`.`t2`.`c` = 1))
SELECT * FROM t1,t2 WHERE (t2.a,(t2.b,t2.c))=(t1.a,(2,1));
a b a b c
1 1 1 2 1
@@ -415,7 +415,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 6 100.00 Using index
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 12 test.t1.a,const,const 1 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = 1) and (`test`.`t2`.`b` = 2) and (`test`.`t2`.`a` = `test`.`t1`.`a`))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`b` = 2) and (`test`.`t2`.`c` = 1))
SELECT * FROM t1,t2 WHERE t2.a=t1.a AND (t2.b,t2.c)=(2,1);
a b a b c
1 1 1 2 1
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 8f213121c9a..5a234c17409 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -1,6 +1,9 @@
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;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch=ifnull(@optimizer_switch_for_select_test,'outer_join_with_cache=off');
+set join_cache_level=1;
CREATE TABLE t1 (
Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
@@ -1391,15 +1394,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 +1418,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 +1434,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
@@ -2115,8 +2118,8 @@ INSERT INTO t2 VALUES (1,3,10,'2002-06-01 08:00:00',35),(1,3,1010,'2002-06-01 12
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
+Warning 1292 Incorrect datetime value: 'wrong-date-value'
+Warning 1292 Incorrect datetime value: 'wrong-date-value'
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;
@@ -2196,10 +2199,10 @@ a a
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 2
2 3
+3 2
3 3
select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
a a
@@ -2362,16 +2365,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
@@ -2394,14 +2397,15 @@ CREATE TABLE t1 ( a BLOB, INDEX (a(20)) );
CREATE TABLE t2 ( a BLOB, INDEX (a(20)) );
INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five');
INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
+INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
-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 +2720,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 +2742,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 +2752,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 +2914,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
@@ -3265,7 +3269,7 @@ f1 f2
4 2005-10-01
5 2005-12-30
Warnings:
-Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1
+Warning 1292 Truncated incorrect date value: '2005-09-3a'
select * from t1 where f2 <= '2005-09-31' order by f2;
f1 f2
1 2005-01-01
@@ -3276,7 +3280,7 @@ 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
+Warning 1292 Truncated incorrect date value: '2005-09-3a'
drop table t1;
create table t1 (f1 int, f2 int);
insert into t1 values (1, 30), (2, 20), (3, 10);
@@ -3417,7 +3421,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 where
DROP TABLE t1,t2;
CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
INSERT t1 SET i = 0;
@@ -3453,7 +3457,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
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 +3471,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
+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
+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 +3537,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 +3566,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
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
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
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 +3612,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
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 +3620,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
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 +3628,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
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 +3636,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
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,16 +3756,12 @@ 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
-Warnings:
-Warning 1292 Incorrect datetime value: '2999-12-31 00:00:00' for column 'ts' at row 1
+1 SIMPLE t1 range ts ts 4 NULL 1 Using index condition; Using where
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30
AND t1.ts BETWEEN t2.dt1 AND t2.dt2
AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31";
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
@@ -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
@@ -4098,17 +4098,22 @@ 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'
+Warning 1292 Truncated incorrect datetime value: '2007/10/01 00:00:00 GMT-6'
+select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6';
+str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007/10/20 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
+0
Warnings:
-Warning 1292 Truncated incorrect date value: '2007/10/2000:00:00 GMT-6'
+Warning 1292 Incorrect datetime 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'
+Warning 1292 Truncated incorrect datetime 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
@@ -4128,7 +4133,7 @@ select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT
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'
+Warning 1292 Truncated incorrect date 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
@@ -4167,33 +4172,24 @@ str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00'
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'
+1
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
+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: ''
+Warning 1292 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
@@ -4207,31 +4203,40 @@ 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: ''
+Warning 1292 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'
+Warning 1292 Incorrect datetime 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'
+Warning 1292 Incorrect datetime value: '1'
select str_to_date('','%Y-%m-%d') = '';
str_to_date('','%Y-%m-%d') = ''
-0
+1
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'
+Warning 1292 Incorrect datetime value: ''
+select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01';
+str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01'
+1
+select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL;
+str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL
+NULL
+select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01';
+str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01'
+NULL
+select str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL;
+str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL
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
+select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01';
+str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01'
0
+select str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL;
+str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL
+NULL
CREATE TABLE t1 (c11 INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE t2 (c21 INT UNSIGNED NOT NULL,
c22 INT DEFAULT NULL,
@@ -4337,6 +4342,7 @@ Handler_read_key 2
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 6
DROP TABLE t1, t2;
CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0',
@@ -4376,14 +4382,14 @@ 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
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
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
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2
DROP TABLE t1;
#
# Bug#47019: Assertion failed: 0, file .\rt_mbr.c, line 138 when
@@ -4396,7 +4402,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 +4412,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
@@ -4606,8 +4612,8 @@ a
4
5
DROP TABLE t1;
-CREATE TABLE A (date_key date);
-CREATE TABLE C (
+CREATE TABLE t1 (date_key date);
+CREATE TABLE t2 (
pk int,
int_nokey int,
int_key int,
@@ -4615,29 +4621,27 @@ date_key date NOT NULL,
date_nokey date,
varchar_key varchar(1)
);
-INSERT INTO C VALUES
+INSERT INTO t2 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);
+SELECT 1 FROM t2 WHERE pk > ANY (SELECT 1 FROM t2);
1
-SELECT COUNT(DISTINCT 1) FROM C
-WHERE date_key = (SELECT 1 FROM A WHERE C.date_key IS NULL) GROUP BY pk;
+SELECT COUNT(DISTINCT 1) FROM t2
+WHERE date_key = (SELECT 1 FROM t1 WHERE t2.date_key IS NULL) GROUP BY pk;
COUNT(DISTINCT 1)
-SELECT date_nokey FROM C
-WHERE int_key IN (SELECT 1 FROM A)
+SELECT date_nokey FROM t2
+WHERE int_key IN (SELECT 1 FROM t1)
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;
+DROP TABLE t1,t2;
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
+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
@@ -4813,16 +4817,16 @@ CREATE TABLE t5 (f1 int) ;
INSERT INTO t5 VALUES (20),(5);
CREATE TABLE t6(f1 int);
INSERT INTO t6 VALUES (9),(7);
-SET SESSION join_buffer_size = 9000;
+SET SESSION join_buffer_size = 2176;
EXPLAIN
SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 12
-1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer
-1 SIMPLE t3 ALL NULL NULL NULL NULL 1
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 1 Using where
1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 test.t1.f1 1
-1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 2 Using join buffer
+1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6;
f1 f1 f1 f1 f2 f1 f1
3 9 NULL NULL NULL 20 9
@@ -4830,51 +4834,194 @@ f1 f1 f1 f1 f2 f1 f1
18 9 NULL NULL NULL 20 9
3 9 NULL NULL NULL 20 9
7 9 NULL NULL NULL 20 9
-18 9 NULL NULL NULL 20 9
-3 9 NULL NULL NULL 20 9
3 9 NULL NULL NULL 20 7
7 9 NULL NULL NULL 20 7
18 9 NULL NULL NULL 20 7
3 9 NULL NULL NULL 20 7
7 9 NULL NULL NULL 20 7
-18 9 NULL NULL NULL 20 7
-3 9 NULL NULL NULL 20 7
+18 9 NULL NULL NULL 20 9
+3 9 NULL NULL NULL 20 9
3 9 NULL NULL NULL 5 9
7 9 NULL NULL NULL 5 9
18 9 NULL NULL NULL 5 9
+18 9 NULL NULL NULL 20 7
+3 9 NULL NULL NULL 20 7
+3 9 NULL NULL NULL 5 7
+7 9 NULL NULL NULL 5 7
+18 9 NULL NULL NULL 5 7
3 9 NULL NULL NULL 5 9
7 9 NULL NULL NULL 5 9
18 9 NULL NULL NULL 5 9
3 9 NULL NULL NULL 5 9
+7 9 NULL NULL NULL 20 9
3 9 NULL NULL NULL 5 7
7 9 NULL NULL NULL 5 7
18 9 NULL NULL NULL 5 7
3 9 NULL NULL NULL 5 7
-7 9 NULL NULL NULL 5 7
-18 9 NULL NULL NULL 5 7
-3 9 NULL NULL NULL 5 7
-7 9 NULL NULL NULL 20 9
+7 9 NULL NULL NULL 20 7
18 9 NULL NULL NULL 20 9
3 9 NULL NULL NULL 20 9
7 9 NULL NULL NULL 20 9
18 9 NULL NULL NULL 20 9
7 9 NULL NULL NULL 5 9
-18 9 NULL NULL NULL 5 9
-7 9 NULL NULL NULL 20 7
18 9 NULL NULL NULL 20 7
3 9 NULL NULL NULL 20 7
7 9 NULL NULL NULL 20 7
18 9 NULL NULL NULL 20 7
7 9 NULL NULL NULL 5 7
-18 9 NULL NULL NULL 5 7
+18 9 NULL NULL NULL 5 9
3 9 NULL NULL NULL 5 9
7 9 NULL NULL NULL 5 9
18 9 NULL NULL NULL 5 9
+18 9 NULL NULL NULL 5 7
3 9 NULL NULL NULL 5 7
7 9 NULL NULL NULL 5 7
18 9 NULL NULL NULL 5 7
SET SESSION join_buffer_size = DEFAULT;
DROP TABLE t1,t2,t3,t4,t5,t6;
+#
+# Bug #698882: best equality substitution not applied to ref
+#
+CREATE TABLE t1 (a1 int NOT NULL, b1 char(10), INDEX idx (a1));
+CREATE TABLE t2 (a2 int NOT NULL, b2 char(10), INDEX idx (a2));
+CREATE TABLE t3 (a3 int NOT NULL, b3 char(10), INDEX idx (a3));
+INSERT INTO t1 VALUES (2,'xx'), (1,'xxx'), (11,'xxxxxxx');
+INSERT INTO t2 VALUES
+(7,'yyyy'), (2,'y'), (3,'yyy'), (1,'yy'), (1,'yyyyy'),
+(3,'yy'), (1,'y'), (4,'yyy'), (7,'y'), (4,'yyyyy'), (7,'yyy'),
+(7,'yyyy'), (2,'yy'), (3,'yyy'), (1,'yyyyyyyy'), (1,'yyyyy'),
+(3,'yy'), (1,'yyy'), (4,'yyy'), (7,'y'), (4,'yyyyy'), (7,'yyy');
+INSERT INTO t3 VALUES
+(9,'zzzzzzz'), (2,'zzzzz'), (1,'z'), (9,'zz'), (1,'zz'), (5,'zzzzzzz'),
+(4,'zz'), (3,'z'), (5,'zzzzzz'), (3,'zz'), (4,'zzzz'), (3,'z'),
+(9,'zzzzzzzz'), (2,'zz'), (1,'zz'), (9,'zzz'), (1,'zzz'), (5,'zzzzzzzz'),
+(4,'zzz'), (3,'zz'), (5,'zzzzzzz'), (3,'zzz'), (4,'zzzzz'), (3,'zz'),
+(9,'zzzzzz'), (2,'zzzz'), (1,'zzz'), (9,'z'), (1,'z'), (5,'zzzzzz'),
+(4,'z'), (3,'zzz'), (5,'zzzzz'), (3,'z'), (4,'zzz'), (3,'zzzz'),
+(9,'zzzzz'), (2,'zzz'), (1,'zzzz'), (9,'zzz'), (1,'zzzz'), (5,'zzzzz'),
+(4,'zzz'), (3,'zzzz'), (5,'zzzz'), (3,'zzz'), (4,'zz'), (3,'zzzzz');
+set @tmp= @@optimizer_switch;
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN SELECT * from t1,t2,t3 WHERE t3.a3=t1.a1 AND t2.a2=t1.a1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL idx NULL NULL NULL 3
+1 SIMPLE t2 ref idx idx 4 test.t1.a1 2
+1 SIMPLE t3 ref idx idx 4 test.t1.a1 5
+EXPLAIN SELECT * FROM t1,t2,t3 WHERE t2.a2=t1.a1 AND t3.a3=t1.a1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL idx NULL NULL NULL 3
+1 SIMPLE t2 ref idx idx 4 test.t1.a1 2
+1 SIMPLE t3 ref idx idx 4 test.t1.a1 5
+EXPLAIN SELECT * FROM t1,t2,t3 WHERE t2.a2=t1.a1 AND t3.a3=t2.a2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL idx NULL NULL NULL 3
+1 SIMPLE t2 ref idx idx 4 test.t1.a1 2
+1 SIMPLE t3 ref idx idx 4 test.t1.a1 5
+SELECT * from t1,t2,t3
+WHERE t3.a3=t1.a1 AND t2.a2=t1.a1 AND
+LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7;
+a1 b1 a2 b2 a3 b3
+1 xxx 1 y 1 z
+1 xxx 1 y 1 z
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zzz
+1 xxx 1 y 1 zzz
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 zz
+1 xxx 1 yy 1 zz
+1 xxx 1 yyy 1 z
+1 xxx 1 yyy 1 z
+2 xx 2 y 2 zz
+2 xx 2 y 2 zzz
+2 xx 2 y 2 zzzz
+2 xx 2 yy 2 zz
+2 xx 2 yy 2 zzz
+SELECT * FROM t1,t2,t3
+WHERE t2.a2=t1.a1 AND t3.a3=t1.a1 AND
+LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7;
+a1 b1 a2 b2 a3 b3
+1 xxx 1 y 1 z
+1 xxx 1 y 1 z
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zzz
+1 xxx 1 y 1 zzz
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 zz
+1 xxx 1 yy 1 zz
+1 xxx 1 yyy 1 z
+1 xxx 1 yyy 1 z
+2 xx 2 y 2 zz
+2 xx 2 y 2 zzz
+2 xx 2 y 2 zzzz
+2 xx 2 yy 2 zz
+2 xx 2 yy 2 zzz
+SELECT * FROM t1,t2,t3
+WHERE t2.a2=t1.a1 AND t3.a3=t2.a2 AND
+LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7;
+a1 b1 a2 b2 a3 b3
+1 xxx 1 y 1 z
+1 xxx 1 y 1 z
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zzz
+1 xxx 1 y 1 zzz
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 zz
+1 xxx 1 yy 1 zz
+1 xxx 1 yyy 1 z
+1 xxx 1 yyy 1 z
+2 xx 2 y 2 zz
+2 xx 2 y 2 zzz
+2 xx 2 y 2 zzzz
+2 xx 2 yy 2 zz
+2 xx 2 yy 2 zzz
+SET SESSION optimizer_switch=@tmp;
+DROP TABLE t1,t2,t3;
+#
+# Bug #707555: crash with equality substitution in ref
+#
+CREATE TABLE t1 (f11 int, f12 int, PRIMARY KEY (f11), KEY (f12)) ;
+INSERT INTO t1 VALUES (1,NULL), (8,NULL);
+CREATE TABLE t2 (f21 int, f22 int, f23 int, KEY (f22)) ;
+INSERT INTO t2 VALUES (1,NULL,3), (2,7,8);
+CREATE TABLE t3 (f31 int, f32 int(11), PRIMARY KEY (f31), KEY (f32)) ;
+INSERT INTO t3 VALUES (1,494862336);
+CREATE TABLE t4 (f41 int, f42 int, PRIMARY KEY (f41), KEY (f42)) ;
+INSERT INTO t4 VALUES (1,NULL), (8,NULL);
+CREATE TABLE t5 (f51 int, PRIMARY KEY (f51)) ;
+INSERT IGNORE INTO t5 VALUES (100);
+CREATE TABLE t6 (f61 int, f62 int, KEY (f61)) ;
+INSERT INTO t6 VALUES (NULL,1), (3,10);
+CREATE TABLE t7 (f71 int, f72 int, KEY (f72)) ;
+INSERT INTO t7 VALUES (1,NULL), (2,7);
+EXPLAIN
+SELECT t2.f23 FROM
+(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
+LEFT JOIN
+(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
+ON t3.f31 = t6.f61
+WHERE t7.f71>0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 system PRIMARY,f32 NULL NULL NULL 1
+1 SIMPLE t5 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE t2 ref f22 f22 5 const 1
+1 SIMPLE t6 ref f61 f61 5 const 1 Using where
+1 SIMPLE t4 ref f42 f42 5 const 1 Using index
+1 SIMPLE t7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+SELECT t2.f23 FROM
+(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
+LEFT JOIN
+(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
+ON t3.f31 = t6.f61
+WHERE t7.f71>0;
+f23
+DROP TABLE t1,t2,t3,t4,t5,t6,t7;
CREATE TABLE t1(f1 int UNSIGNED) engine=myisam;
INSERT INTO t1 VALUES (3),(2),(1);
set sql_buffer_result=0;
@@ -4903,3 +5050,66 @@ SELECT 1 FROM t1 GROUP BY 1;
1
drop table t1;
End of 5.1 tests
+#
+# BUG#776274: substitution of a single row table
+#
+CREATE TABLE t1 (a int NOT NULL , b int);
+INSERT INTO t1 VALUES (2,2);
+SELECT * FROM t1 WHERE a = b;
+a b
+2 2
+EXPLAIN
+SELECT * FROM t1 WHERE a = b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1
+DROP TABLE t1;
+#
+# lp:822760 Wrong result with view + invalid dates
+#
+CREATE TABLE t1 (f1 date);
+INSERT IGNORE INTO t1 VALUES ('0000-00-00');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t1 HAVING f1 = 'zz';
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+SELECT * FROM t1 HAVING f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'aa'
+SELECT * FROM t1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+SELECT * FROM t1 WHERE f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+Warning 1292 Incorrect datetime value: 'zz'
+SELECT * FROM v1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+DROP TABLE t1;
+DROP VIEW v1;
+SET optimizer_switch=@save_optimizer_switch;
+#
+# LP bug#994275 Assertion `real->type() == Item::FIELD_ITEM' failed
+# in add_not_null_conds(JOIN*) with JOIN, ZEROFILL column, PK
+#
+CREATE TABLE t1 ( a INT(6) ZEROFILL );
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 ( b INT PRIMARY KEY );
+INSERT INTO t2 VALUES (3),(4);
+SELECT * FROM t1, t2 WHERE a=3 AND a=b;
+a b
+drop table t1,t2;
+End of 5.3 tests
diff --git a/mysql-test/r/select_debug.result b/mysql-test/r/select_debug.result
new file mode 100644
index 00000000000..1eb8a0754fa
--- /dev/null
+++ b/mysql-test/r/select_debug.result
@@ -0,0 +1,18 @@
+#
+# Bug #725050: print keyuse info when hash join is used
+#
+create table t1 (a int, b int);
+insert into t1 values (2,2), (1,1);
+create table t2 (a int);
+insert into t2 values (2), (3);
+set session join_cache_level=3;
+set @@debug = 'd:t:O,/tmp/trace.out';
+explain select t1.b from t1,t2 where t1.b=t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t2 hash_ALL NULL #hash#$hj 5 test.t1.b 2 Using where; Using join buffer (flat, BNLH join)
+select t1.b from t1,t2 where t1.b=t2.a;
+b
+2
+set session join_cache_level=default;
+drop table t1,t2;
diff --git a/mysql-test/r/select_jcl6.result b/mysql-test/r/select_jcl6.result
new file mode 100644
index 00000000000..b7f278a327f
--- /dev/null
+++ b/mysql-test/r/select_jcl6.result
@@ -0,0 +1,5133 @@
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set @@optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+set @optimizer_switch_for_select_test=@@optimizer_switch;
+set @join_cache_level_for_select_test=@@join_cache_level;
+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;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch=ifnull(@optimizer_switch_for_select_test,'outer_join_with_cache=off');
+set join_cache_level=@join_cache_level_for_select_test;
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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 hash_ALL NULL #hash#$hj 1 test.t4.companynr 1200 Using where; Not exists; Using join buffer (flat, BNLH 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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+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 hash_ALL NULL #hash#$hj 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH 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 hash_ALL NULL #hash#$hj 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH 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 hash_ALL NULL #hash#$hj 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH 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 hash_ALL NULL #hash#$hj 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH 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 hash_ALL NULL #hash#$hj 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH 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 hash_ALL NULL #hash#$hj 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH 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 hash_ALL NULL #hash#$hj 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH 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 hash_ALL NULL #hash#$hj 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH 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 hash_ALL NULL #hash#$hj 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH 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 hash_ALL NULL #hash#$hj 1 func 1199 Using where; Using join buffer (flat, BNLH 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'
+Warning 1292 Incorrect datetime value: 'wrong-date-value'
+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
+1 3
+2 2
+2 3
+3 2
+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 hash_ALL NULL #hash#$hj 4 test.t1.id1 1 Using where; Using join buffer (flat, BNLH 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');
+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 t1 index key1 key1 5 NULL 4 Using where; Using index
+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 t1 range key1 key1 5 NULL 3 Using where; Using index
+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.384499996900558
+select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+min(key1)
+0.384499996900558
+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 Using where
+1 SIMPLE t2 hash_ALL NULL #hash#$hj 5 test.t1.a 3 Using where; Using join buffer (flat, BNLH 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 Using where
+1 SIMPLE t1 hash_ALL NULL #hash#$hj 5 test.t2.a 5 Using where; Using join buffer (flat, BNLH 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 Truncated incorrect date value: '2005-09-3a'
+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 Truncated incorrect date value: '2005-09-3a'
+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 where; Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE B ref PRIMARY PRIMARY 8 const,test.A.e 10 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE t2 ref c c 5 test.t1.a 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+EXPLAIN
+SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 ref c c 5 test.t1.a 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+EXPLAIN SELECT t2.*
+FROM t1 JOIN t2 ON t2.fk=t1.pk
+WHERE t2.fk BETWEEN 'a' AND 'b' AND t2.pk=t1.fk;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+EXPLAIN SELECT t2.*
+FROM t1 JOIN t2 ON t2.fk=t1.pk
+WHERE t2.fk IN ('a','b') AND t2.pk=t1.fk;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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; Rowid-ordered scan
+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
+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 datetime value: '2007/10/01 00:00:00 GMT-6'
+select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6';
+str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007/10/20 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'
+0
+Warnings:
+Warning 1292 Incorrect datetime 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 datetime 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 date 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'
+1
+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
+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
+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'
+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 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 Incorrect datetime value: ''
+select str_to_date('1','%Y-%m-%d') = '1';
+str_to_date('1','%Y-%m-%d') = '1'
+0
+Warnings:
+Warning 1292 Incorrect datetime value: '1'
+select str_to_date('1','%Y-%m-%d') = '1';
+str_to_date('1','%Y-%m-%d') = '1'
+0
+Warnings:
+Warning 1292 Incorrect datetime value: '1'
+select str_to_date('','%Y-%m-%d') = '';
+str_to_date('','%Y-%m-%d') = ''
+1
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01';
+str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01'
+1
+select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL;
+str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL
+NULL
+select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01';
+str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01'
+NULL
+select str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL;
+str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL
+0
+select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01';
+str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01'
+0
+select str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL;
+str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL
+NULL
+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_deleted 1
+Handler_read_rnd_next 6
+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; Rowid-ordered scan
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2
+EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using index condition; Using where; Rowid-ordered scan
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2
+DROP TABLE t1;
+#
+# 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 t1 (date_key date);
+CREATE TABLE t2 (
+pk int,
+int_nokey int,
+int_key int,
+date_key date NOT NULL,
+date_nokey date,
+varchar_key varchar(1)
+);
+INSERT INTO t2 VALUES
+(1,1,1,'0000-00-00',NULL,NULL),
+(1,1,1,'0000-00-00',NULL,NULL);
+SELECT 1 FROM t2 WHERE pk > ANY (SELECT 1 FROM t2);
+1
+SELECT COUNT(DISTINCT 1) FROM t2
+WHERE date_key = (SELECT 1 FROM t1 WHERE t2.date_key IS NULL) GROUP BY pk;
+COUNT(DISTINCT 1)
+SELECT date_nokey FROM t2
+WHERE int_key IN (SELECT 1 FROM t1)
+HAVING date_nokey = '10:41:7'
+ORDER BY date_key;
+date_nokey
+DROP TABLE t1,t2;
+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;
+#
+# Bug #702310: usage of 2 join buffers after ref access to an empty table
+#
+CREATE TABLE t1 (f1 int) ;
+INSERT INTO t1 VALUES (9);
+CREATE TABLE t2 (f1 int);
+INSERT INTO t2 VALUES (3),(7),(18);
+INSERT INTO t2 VALUES (3),(7),(18);
+INSERT INTO t2 VALUES (3),(7),(18);
+INSERT INTO t2 VALUES (3),(7),(18);
+CREATE TABLE t3 (f1 int);
+INSERT INTO t3 VALUES (17);
+CREATE TABLE t4 (f1 int PRIMARY KEY, f2 varchar(1024)) ;
+CREATE TABLE t5 (f1 int) ;
+INSERT INTO t5 VALUES (20),(5);
+CREATE TABLE t6(f1 int);
+INSERT INTO t6 VALUES (9),(7);
+SET SESSION join_buffer_size = 2176;
+EXPLAIN
+SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 12
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 test.t1.f1 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer (incremental, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 2 Using join buffer (incremental, BNL join)
+SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6;
+f1 f1 f1 f1 f2 f1 f1
+3 9 NULL NULL NULL 20 9
+7 9 NULL NULL NULL 20 9
+18 9 NULL NULL NULL 20 9
+3 9 NULL NULL NULL 20 9
+7 9 NULL NULL NULL 20 9
+18 9 NULL NULL NULL 20 9
+3 9 NULL NULL NULL 20 9
+7 9 NULL NULL NULL 20 9
+18 9 NULL NULL NULL 20 9
+3 9 NULL NULL NULL 20 9
+7 9 NULL NULL NULL 20 9
+18 9 NULL NULL NULL 20 9
+3 9 NULL NULL NULL 5 9
+7 9 NULL NULL NULL 5 9
+18 9 NULL NULL NULL 5 9
+3 9 NULL NULL NULL 5 9
+7 9 NULL NULL NULL 5 9
+18 9 NULL NULL NULL 5 9
+3 9 NULL NULL NULL 5 9
+7 9 NULL NULL NULL 5 9
+18 9 NULL NULL NULL 5 9
+3 9 NULL NULL NULL 5 9
+7 9 NULL NULL NULL 5 9
+18 9 NULL NULL NULL 5 9
+3 9 NULL NULL NULL 20 7
+7 9 NULL NULL NULL 20 7
+18 9 NULL NULL NULL 20 7
+3 9 NULL NULL NULL 20 7
+7 9 NULL NULL NULL 20 7
+18 9 NULL NULL NULL 20 7
+3 9 NULL NULL NULL 20 7
+7 9 NULL NULL NULL 20 7
+18 9 NULL NULL NULL 20 7
+3 9 NULL NULL NULL 20 7
+7 9 NULL NULL NULL 20 7
+18 9 NULL NULL NULL 20 7
+3 9 NULL NULL NULL 5 7
+7 9 NULL NULL NULL 5 7
+18 9 NULL NULL NULL 5 7
+3 9 NULL NULL NULL 5 7
+7 9 NULL NULL NULL 5 7
+18 9 NULL NULL NULL 5 7
+3 9 NULL NULL NULL 5 7
+7 9 NULL NULL NULL 5 7
+18 9 NULL NULL NULL 5 7
+3 9 NULL NULL NULL 5 7
+7 9 NULL NULL NULL 5 7
+18 9 NULL NULL NULL 5 7
+SET SESSION join_buffer_size = DEFAULT;
+DROP TABLE t1,t2,t3,t4,t5,t6;
+#
+# Bug #698882: best equality substitution not applied to ref
+#
+CREATE TABLE t1 (a1 int NOT NULL, b1 char(10), INDEX idx (a1));
+CREATE TABLE t2 (a2 int NOT NULL, b2 char(10), INDEX idx (a2));
+CREATE TABLE t3 (a3 int NOT NULL, b3 char(10), INDEX idx (a3));
+INSERT INTO t1 VALUES (2,'xx'), (1,'xxx'), (11,'xxxxxxx');
+INSERT INTO t2 VALUES
+(7,'yyyy'), (2,'y'), (3,'yyy'), (1,'yy'), (1,'yyyyy'),
+(3,'yy'), (1,'y'), (4,'yyy'), (7,'y'), (4,'yyyyy'), (7,'yyy'),
+(7,'yyyy'), (2,'yy'), (3,'yyy'), (1,'yyyyyyyy'), (1,'yyyyy'),
+(3,'yy'), (1,'yyy'), (4,'yyy'), (7,'y'), (4,'yyyyy'), (7,'yyy');
+INSERT INTO t3 VALUES
+(9,'zzzzzzz'), (2,'zzzzz'), (1,'z'), (9,'zz'), (1,'zz'), (5,'zzzzzzz'),
+(4,'zz'), (3,'z'), (5,'zzzzzz'), (3,'zz'), (4,'zzzz'), (3,'z'),
+(9,'zzzzzzzz'), (2,'zz'), (1,'zz'), (9,'zzz'), (1,'zzz'), (5,'zzzzzzzz'),
+(4,'zzz'), (3,'zz'), (5,'zzzzzzz'), (3,'zzz'), (4,'zzzzz'), (3,'zz'),
+(9,'zzzzzz'), (2,'zzzz'), (1,'zzz'), (9,'z'), (1,'z'), (5,'zzzzzz'),
+(4,'z'), (3,'zzz'), (5,'zzzzz'), (3,'z'), (4,'zzz'), (3,'zzzz'),
+(9,'zzzzz'), (2,'zzz'), (1,'zzzz'), (9,'zzz'), (1,'zzzz'), (5,'zzzzz'),
+(4,'zzz'), (3,'zzzz'), (5,'zzzz'), (3,'zzz'), (4,'zz'), (3,'zzzzz');
+set @tmp= @@optimizer_switch;
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN SELECT * from t1,t2,t3 WHERE t3.a3=t1.a1 AND t2.a2=t1.a1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL idx NULL NULL NULL 3
+1 SIMPLE t2 ref idx idx 4 test.t1.a1 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t3 ref idx idx 4 test.t1.a1 5 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+EXPLAIN SELECT * FROM t1,t2,t3 WHERE t2.a2=t1.a1 AND t3.a3=t1.a1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL idx NULL NULL NULL 3
+1 SIMPLE t2 ref idx idx 4 test.t1.a1 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t3 ref idx idx 4 test.t1.a1 5 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+EXPLAIN SELECT * FROM t1,t2,t3 WHERE t2.a2=t1.a1 AND t3.a3=t2.a2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL idx NULL NULL NULL 3
+1 SIMPLE t2 ref idx idx 4 test.t1.a1 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t3 ref idx idx 4 test.t1.a1 5 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+SELECT * from t1,t2,t3
+WHERE t3.a3=t1.a1 AND t2.a2=t1.a1 AND
+LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7;
+a1 b1 a2 b2 a3 b3
+1 xxx 1 y 1 z
+1 xxx 1 y 1 z
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zzz
+1 xxx 1 y 1 zzz
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 zz
+1 xxx 1 yy 1 zz
+1 xxx 1 yyy 1 z
+1 xxx 1 yyy 1 z
+2 xx 2 y 2 zz
+2 xx 2 y 2 zzz
+2 xx 2 y 2 zzzz
+2 xx 2 yy 2 zz
+2 xx 2 yy 2 zzz
+SELECT * FROM t1,t2,t3
+WHERE t2.a2=t1.a1 AND t3.a3=t1.a1 AND
+LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7;
+a1 b1 a2 b2 a3 b3
+1 xxx 1 y 1 z
+1 xxx 1 y 1 z
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zzz
+1 xxx 1 y 1 zzz
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 zz
+1 xxx 1 yy 1 zz
+1 xxx 1 yyy 1 z
+1 xxx 1 yyy 1 z
+2 xx 2 y 2 zz
+2 xx 2 y 2 zzz
+2 xx 2 y 2 zzzz
+2 xx 2 yy 2 zz
+2 xx 2 yy 2 zzz
+SELECT * FROM t1,t2,t3
+WHERE t2.a2=t1.a1 AND t3.a3=t2.a2 AND
+LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7;
+a1 b1 a2 b2 a3 b3
+1 xxx 1 y 1 z
+1 xxx 1 y 1 z
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zzz
+1 xxx 1 y 1 zzz
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 zz
+1 xxx 1 yy 1 zz
+1 xxx 1 yyy 1 z
+1 xxx 1 yyy 1 z
+2 xx 2 y 2 zz
+2 xx 2 y 2 zzz
+2 xx 2 y 2 zzzz
+2 xx 2 yy 2 zz
+2 xx 2 yy 2 zzz
+SET SESSION optimizer_switch=@tmp;
+DROP TABLE t1,t2,t3;
+#
+# Bug #707555: crash with equality substitution in ref
+#
+CREATE TABLE t1 (f11 int, f12 int, PRIMARY KEY (f11), KEY (f12)) ;
+INSERT INTO t1 VALUES (1,NULL), (8,NULL);
+CREATE TABLE t2 (f21 int, f22 int, f23 int, KEY (f22)) ;
+INSERT INTO t2 VALUES (1,NULL,3), (2,7,8);
+CREATE TABLE t3 (f31 int, f32 int(11), PRIMARY KEY (f31), KEY (f32)) ;
+INSERT INTO t3 VALUES (1,494862336);
+CREATE TABLE t4 (f41 int, f42 int, PRIMARY KEY (f41), KEY (f42)) ;
+INSERT INTO t4 VALUES (1,NULL), (8,NULL);
+CREATE TABLE t5 (f51 int, PRIMARY KEY (f51)) ;
+INSERT IGNORE INTO t5 VALUES (100);
+CREATE TABLE t6 (f61 int, f62 int, KEY (f61)) ;
+INSERT INTO t6 VALUES (NULL,1), (3,10);
+CREATE TABLE t7 (f71 int, f72 int, KEY (f72)) ;
+INSERT INTO t7 VALUES (1,NULL), (2,7);
+EXPLAIN
+SELECT t2.f23 FROM
+(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
+LEFT JOIN
+(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
+ON t3.f31 = t6.f61
+WHERE t7.f71>0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 system PRIMARY,f32 NULL NULL NULL 1
+1 SIMPLE t5 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE t2 ref f22 f22 5 const 1
+1 SIMPLE t6 ref f61 f61 5 const 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t4 ref f42 f42 5 const 1 Using index
+1 SIMPLE t7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+SELECT t2.f23 FROM
+(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
+LEFT JOIN
+(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
+ON t3.f31 = t6.f61
+WHERE t7.f71>0;
+f23
+DROP TABLE t1,t2,t3,t4,t5,t6,t7;
+CREATE TABLE t1(f1 int UNSIGNED) engine=myisam;
+INSERT INTO t1 VALUES (3),(2),(1);
+set sql_buffer_result=0;
+SELECT f1 FROM t1 GROUP BY 1;
+f1
+1
+2
+3
+SELECT f1 FROM t1 GROUP BY '123' = 'abc';
+f1
+3
+SELECT 1 FROM t1 GROUP BY 1;
+1
+1
+set sql_buffer_result=1;
+SELECT f1 FROM t1 GROUP BY 1;
+f1
+1
+2
+3
+SELECT f1 FROM t1 GROUP BY '123' = 'abc';
+f1
+3
+SELECT 1 FROM t1 GROUP BY 1;
+1
+1
+drop table t1;
+End of 5.1 tests
+#
+# BUG#776274: substitution of a single row table
+#
+CREATE TABLE t1 (a int NOT NULL , b int);
+INSERT INTO t1 VALUES (2,2);
+SELECT * FROM t1 WHERE a = b;
+a b
+2 2
+EXPLAIN
+SELECT * FROM t1 WHERE a = b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1
+DROP TABLE t1;
+#
+# lp:822760 Wrong result with view + invalid dates
+#
+CREATE TABLE t1 (f1 date);
+INSERT IGNORE INTO t1 VALUES ('0000-00-00');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t1 HAVING f1 = 'zz';
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+SELECT * FROM t1 HAVING f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'aa'
+SELECT * FROM t1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+SELECT * FROM t1 WHERE f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+Warning 1292 Incorrect datetime value: 'zz'
+SELECT * FROM v1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+DROP TABLE t1;
+DROP VIEW v1;
+SET optimizer_switch=@save_optimizer_switch;
+#
+# LP bug#994275 Assertion `real->type() == Item::FIELD_ITEM' failed
+# in add_not_null_conds(JOIN*) with JOIN, ZEROFILL column, PK
+#
+CREATE TABLE t1 ( a INT(6) ZEROFILL );
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 ( b INT PRIMARY KEY );
+INSERT INTO t2 VALUES (3),(4);
+SELECT * FROM t1, t2 WHERE a=3 AND a=b;
+a b
+drop table t1,t2;
+End of 5.3 tests
+set join_cache_level=default;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 2
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
+set @optimizer_switch_for_select_test=NULL;
+set @join_cache_level_for_select_test=NULL;
diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result
index 8f213121c9a..5a234c17409 100644
--- a/mysql-test/r/select_pkeycache.result
+++ b/mysql-test/r/select_pkeycache.result
@@ -1,6 +1,9 @@
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;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch=ifnull(@optimizer_switch_for_select_test,'outer_join_with_cache=off');
+set join_cache_level=1;
CREATE TABLE t1 (
Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
@@ -1391,15 +1394,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 +1418,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 +1434,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
@@ -2115,8 +2118,8 @@ INSERT INTO t2 VALUES (1,3,10,'2002-06-01 08:00:00',35),(1,3,1010,'2002-06-01 12
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
+Warning 1292 Incorrect datetime value: 'wrong-date-value'
+Warning 1292 Incorrect datetime value: 'wrong-date-value'
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;
@@ -2196,10 +2199,10 @@ a a
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 2
2 3
+3 2
3 3
select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
a a
@@ -2362,16 +2365,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
@@ -2394,14 +2397,15 @@ CREATE TABLE t1 ( a BLOB, INDEX (a(20)) );
CREATE TABLE t2 ( a BLOB, INDEX (a(20)) );
INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five');
INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
+INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
-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 +2720,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 +2742,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 +2752,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 +2914,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
@@ -3265,7 +3269,7 @@ f1 f2
4 2005-10-01
5 2005-12-30
Warnings:
-Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1
+Warning 1292 Truncated incorrect date value: '2005-09-3a'
select * from t1 where f2 <= '2005-09-31' order by f2;
f1 f2
1 2005-01-01
@@ -3276,7 +3280,7 @@ 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
+Warning 1292 Truncated incorrect date value: '2005-09-3a'
drop table t1;
create table t1 (f1 int, f2 int);
insert into t1 values (1, 30), (2, 20), (3, 10);
@@ -3417,7 +3421,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 where
DROP TABLE t1,t2;
CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
INSERT t1 SET i = 0;
@@ -3453,7 +3457,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
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 +3471,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
+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
+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 +3537,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 +3566,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
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
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
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 +3612,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
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 +3620,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
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 +3628,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
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 +3636,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
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,16 +3756,12 @@ 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
-Warnings:
-Warning 1292 Incorrect datetime value: '2999-12-31 00:00:00' for column 'ts' at row 1
+1 SIMPLE t1 range ts ts 4 NULL 1 Using index condition; Using where
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30
AND t1.ts BETWEEN t2.dt1 AND t2.dt2
AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31";
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
@@ -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
@@ -4098,17 +4098,22 @@ 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'
+Warning 1292 Truncated incorrect datetime value: '2007/10/01 00:00:00 GMT-6'
+select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6';
+str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2007/10/20 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
+0
Warnings:
-Warning 1292 Truncated incorrect date value: '2007/10/2000:00:00 GMT-6'
+Warning 1292 Incorrect datetime 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'
+Warning 1292 Truncated incorrect datetime 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
@@ -4128,7 +4133,7 @@ select str_to_date('2007-10-01','%Y-%m-%d %H:%i:%s') = '2007-10-01 x12:34:56 GMT
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'
+Warning 1292 Truncated incorrect date 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
@@ -4167,33 +4172,24 @@ str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00'
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'
+1
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
+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: ''
+Warning 1292 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
@@ -4207,31 +4203,40 @@ 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: ''
+Warning 1292 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'
+Warning 1292 Incorrect datetime 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'
+Warning 1292 Incorrect datetime value: '1'
select str_to_date('','%Y-%m-%d') = '';
str_to_date('','%Y-%m-%d') = ''
-0
+1
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'
+Warning 1292 Incorrect datetime value: ''
+select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01';
+str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01'
+1
+select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL;
+str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL
+NULL
+select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01';
+str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01'
+NULL
+select str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL;
+str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL
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
+select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01';
+str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01'
0
+select str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL;
+str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL
+NULL
CREATE TABLE t1 (c11 INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE t2 (c21 INT UNSIGNED NOT NULL,
c22 INT DEFAULT NULL,
@@ -4337,6 +4342,7 @@ Handler_read_key 2
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 6
DROP TABLE t1, t2;
CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0',
@@ -4376,14 +4382,14 @@ 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
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
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
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2
DROP TABLE t1;
#
# Bug#47019: Assertion failed: 0, file .\rt_mbr.c, line 138 when
@@ -4396,7 +4402,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 +4412,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
@@ -4606,8 +4612,8 @@ a
4
5
DROP TABLE t1;
-CREATE TABLE A (date_key date);
-CREATE TABLE C (
+CREATE TABLE t1 (date_key date);
+CREATE TABLE t2 (
pk int,
int_nokey int,
int_key int,
@@ -4615,29 +4621,27 @@ date_key date NOT NULL,
date_nokey date,
varchar_key varchar(1)
);
-INSERT INTO C VALUES
+INSERT INTO t2 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);
+SELECT 1 FROM t2 WHERE pk > ANY (SELECT 1 FROM t2);
1
-SELECT COUNT(DISTINCT 1) FROM C
-WHERE date_key = (SELECT 1 FROM A WHERE C.date_key IS NULL) GROUP BY pk;
+SELECT COUNT(DISTINCT 1) FROM t2
+WHERE date_key = (SELECT 1 FROM t1 WHERE t2.date_key IS NULL) GROUP BY pk;
COUNT(DISTINCT 1)
-SELECT date_nokey FROM C
-WHERE int_key IN (SELECT 1 FROM A)
+SELECT date_nokey FROM t2
+WHERE int_key IN (SELECT 1 FROM t1)
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;
+DROP TABLE t1,t2;
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
+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
@@ -4813,16 +4817,16 @@ CREATE TABLE t5 (f1 int) ;
INSERT INTO t5 VALUES (20),(5);
CREATE TABLE t6(f1 int);
INSERT INTO t6 VALUES (9),(7);
-SET SESSION join_buffer_size = 9000;
+SET SESSION join_buffer_size = 2176;
EXPLAIN
SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 12
-1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer
-1 SIMPLE t3 ALL NULL NULL NULL NULL 1
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 1 Using where
1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 test.t1.f1 1
-1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer
-1 SIMPLE t6 ALL NULL NULL NULL NULL 2 Using join buffer
+1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+1 SIMPLE t6 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6;
f1 f1 f1 f1 f2 f1 f1
3 9 NULL NULL NULL 20 9
@@ -4830,51 +4834,194 @@ f1 f1 f1 f1 f2 f1 f1
18 9 NULL NULL NULL 20 9
3 9 NULL NULL NULL 20 9
7 9 NULL NULL NULL 20 9
-18 9 NULL NULL NULL 20 9
-3 9 NULL NULL NULL 20 9
3 9 NULL NULL NULL 20 7
7 9 NULL NULL NULL 20 7
18 9 NULL NULL NULL 20 7
3 9 NULL NULL NULL 20 7
7 9 NULL NULL NULL 20 7
-18 9 NULL NULL NULL 20 7
-3 9 NULL NULL NULL 20 7
+18 9 NULL NULL NULL 20 9
+3 9 NULL NULL NULL 20 9
3 9 NULL NULL NULL 5 9
7 9 NULL NULL NULL 5 9
18 9 NULL NULL NULL 5 9
+18 9 NULL NULL NULL 20 7
+3 9 NULL NULL NULL 20 7
+3 9 NULL NULL NULL 5 7
+7 9 NULL NULL NULL 5 7
+18 9 NULL NULL NULL 5 7
3 9 NULL NULL NULL 5 9
7 9 NULL NULL NULL 5 9
18 9 NULL NULL NULL 5 9
3 9 NULL NULL NULL 5 9
+7 9 NULL NULL NULL 20 9
3 9 NULL NULL NULL 5 7
7 9 NULL NULL NULL 5 7
18 9 NULL NULL NULL 5 7
3 9 NULL NULL NULL 5 7
-7 9 NULL NULL NULL 5 7
-18 9 NULL NULL NULL 5 7
-3 9 NULL NULL NULL 5 7
-7 9 NULL NULL NULL 20 9
+7 9 NULL NULL NULL 20 7
18 9 NULL NULL NULL 20 9
3 9 NULL NULL NULL 20 9
7 9 NULL NULL NULL 20 9
18 9 NULL NULL NULL 20 9
7 9 NULL NULL NULL 5 9
-18 9 NULL NULL NULL 5 9
-7 9 NULL NULL NULL 20 7
18 9 NULL NULL NULL 20 7
3 9 NULL NULL NULL 20 7
7 9 NULL NULL NULL 20 7
18 9 NULL NULL NULL 20 7
7 9 NULL NULL NULL 5 7
-18 9 NULL NULL NULL 5 7
+18 9 NULL NULL NULL 5 9
3 9 NULL NULL NULL 5 9
7 9 NULL NULL NULL 5 9
18 9 NULL NULL NULL 5 9
+18 9 NULL NULL NULL 5 7
3 9 NULL NULL NULL 5 7
7 9 NULL NULL NULL 5 7
18 9 NULL NULL NULL 5 7
SET SESSION join_buffer_size = DEFAULT;
DROP TABLE t1,t2,t3,t4,t5,t6;
+#
+# Bug #698882: best equality substitution not applied to ref
+#
+CREATE TABLE t1 (a1 int NOT NULL, b1 char(10), INDEX idx (a1));
+CREATE TABLE t2 (a2 int NOT NULL, b2 char(10), INDEX idx (a2));
+CREATE TABLE t3 (a3 int NOT NULL, b3 char(10), INDEX idx (a3));
+INSERT INTO t1 VALUES (2,'xx'), (1,'xxx'), (11,'xxxxxxx');
+INSERT INTO t2 VALUES
+(7,'yyyy'), (2,'y'), (3,'yyy'), (1,'yy'), (1,'yyyyy'),
+(3,'yy'), (1,'y'), (4,'yyy'), (7,'y'), (4,'yyyyy'), (7,'yyy'),
+(7,'yyyy'), (2,'yy'), (3,'yyy'), (1,'yyyyyyyy'), (1,'yyyyy'),
+(3,'yy'), (1,'yyy'), (4,'yyy'), (7,'y'), (4,'yyyyy'), (7,'yyy');
+INSERT INTO t3 VALUES
+(9,'zzzzzzz'), (2,'zzzzz'), (1,'z'), (9,'zz'), (1,'zz'), (5,'zzzzzzz'),
+(4,'zz'), (3,'z'), (5,'zzzzzz'), (3,'zz'), (4,'zzzz'), (3,'z'),
+(9,'zzzzzzzz'), (2,'zz'), (1,'zz'), (9,'zzz'), (1,'zzz'), (5,'zzzzzzzz'),
+(4,'zzz'), (3,'zz'), (5,'zzzzzzz'), (3,'zzz'), (4,'zzzzz'), (3,'zz'),
+(9,'zzzzzz'), (2,'zzzz'), (1,'zzz'), (9,'z'), (1,'z'), (5,'zzzzzz'),
+(4,'z'), (3,'zzz'), (5,'zzzzz'), (3,'z'), (4,'zzz'), (3,'zzzz'),
+(9,'zzzzz'), (2,'zzz'), (1,'zzzz'), (9,'zzz'), (1,'zzzz'), (5,'zzzzz'),
+(4,'zzz'), (3,'zzzz'), (5,'zzzz'), (3,'zzz'), (4,'zz'), (3,'zzzzz');
+set @tmp= @@optimizer_switch;
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN SELECT * from t1,t2,t3 WHERE t3.a3=t1.a1 AND t2.a2=t1.a1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL idx NULL NULL NULL 3
+1 SIMPLE t2 ref idx idx 4 test.t1.a1 2
+1 SIMPLE t3 ref idx idx 4 test.t1.a1 5
+EXPLAIN SELECT * FROM t1,t2,t3 WHERE t2.a2=t1.a1 AND t3.a3=t1.a1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL idx NULL NULL NULL 3
+1 SIMPLE t2 ref idx idx 4 test.t1.a1 2
+1 SIMPLE t3 ref idx idx 4 test.t1.a1 5
+EXPLAIN SELECT * FROM t1,t2,t3 WHERE t2.a2=t1.a1 AND t3.a3=t2.a2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL idx NULL NULL NULL 3
+1 SIMPLE t2 ref idx idx 4 test.t1.a1 2
+1 SIMPLE t3 ref idx idx 4 test.t1.a1 5
+SELECT * from t1,t2,t3
+WHERE t3.a3=t1.a1 AND t2.a2=t1.a1 AND
+LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7;
+a1 b1 a2 b2 a3 b3
+1 xxx 1 y 1 z
+1 xxx 1 y 1 z
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zzz
+1 xxx 1 y 1 zzz
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 zz
+1 xxx 1 yy 1 zz
+1 xxx 1 yyy 1 z
+1 xxx 1 yyy 1 z
+2 xx 2 y 2 zz
+2 xx 2 y 2 zzz
+2 xx 2 y 2 zzzz
+2 xx 2 yy 2 zz
+2 xx 2 yy 2 zzz
+SELECT * FROM t1,t2,t3
+WHERE t2.a2=t1.a1 AND t3.a3=t1.a1 AND
+LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7;
+a1 b1 a2 b2 a3 b3
+1 xxx 1 y 1 z
+1 xxx 1 y 1 z
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zzz
+1 xxx 1 y 1 zzz
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 zz
+1 xxx 1 yy 1 zz
+1 xxx 1 yyy 1 z
+1 xxx 1 yyy 1 z
+2 xx 2 y 2 zz
+2 xx 2 y 2 zzz
+2 xx 2 y 2 zzzz
+2 xx 2 yy 2 zz
+2 xx 2 yy 2 zzz
+SELECT * FROM t1,t2,t3
+WHERE t2.a2=t1.a1 AND t3.a3=t2.a2 AND
+LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7;
+a1 b1 a2 b2 a3 b3
+1 xxx 1 y 1 z
+1 xxx 1 y 1 z
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zz
+1 xxx 1 y 1 zzz
+1 xxx 1 y 1 zzz
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 z
+1 xxx 1 yy 1 zz
+1 xxx 1 yy 1 zz
+1 xxx 1 yyy 1 z
+1 xxx 1 yyy 1 z
+2 xx 2 y 2 zz
+2 xx 2 y 2 zzz
+2 xx 2 y 2 zzzz
+2 xx 2 yy 2 zz
+2 xx 2 yy 2 zzz
+SET SESSION optimizer_switch=@tmp;
+DROP TABLE t1,t2,t3;
+#
+# Bug #707555: crash with equality substitution in ref
+#
+CREATE TABLE t1 (f11 int, f12 int, PRIMARY KEY (f11), KEY (f12)) ;
+INSERT INTO t1 VALUES (1,NULL), (8,NULL);
+CREATE TABLE t2 (f21 int, f22 int, f23 int, KEY (f22)) ;
+INSERT INTO t2 VALUES (1,NULL,3), (2,7,8);
+CREATE TABLE t3 (f31 int, f32 int(11), PRIMARY KEY (f31), KEY (f32)) ;
+INSERT INTO t3 VALUES (1,494862336);
+CREATE TABLE t4 (f41 int, f42 int, PRIMARY KEY (f41), KEY (f42)) ;
+INSERT INTO t4 VALUES (1,NULL), (8,NULL);
+CREATE TABLE t5 (f51 int, PRIMARY KEY (f51)) ;
+INSERT IGNORE INTO t5 VALUES (100);
+CREATE TABLE t6 (f61 int, f62 int, KEY (f61)) ;
+INSERT INTO t6 VALUES (NULL,1), (3,10);
+CREATE TABLE t7 (f71 int, f72 int, KEY (f72)) ;
+INSERT INTO t7 VALUES (1,NULL), (2,7);
+EXPLAIN
+SELECT t2.f23 FROM
+(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
+LEFT JOIN
+(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
+ON t3.f31 = t6.f61
+WHERE t7.f71>0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 system PRIMARY,f32 NULL NULL NULL 1
+1 SIMPLE t5 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE t2 ref f22 f22 5 const 1
+1 SIMPLE t6 ref f61 f61 5 const 1 Using where
+1 SIMPLE t4 ref f42 f42 5 const 1 Using index
+1 SIMPLE t7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+SELECT t2.f23 FROM
+(t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
+LEFT JOIN
+(((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
+ON t3.f31 = t6.f61
+WHERE t7.f71>0;
+f23
+DROP TABLE t1,t2,t3,t4,t5,t6,t7;
CREATE TABLE t1(f1 int UNSIGNED) engine=myisam;
INSERT INTO t1 VALUES (3),(2),(1);
set sql_buffer_result=0;
@@ -4903,3 +5050,66 @@ SELECT 1 FROM t1 GROUP BY 1;
1
drop table t1;
End of 5.1 tests
+#
+# BUG#776274: substitution of a single row table
+#
+CREATE TABLE t1 (a int NOT NULL , b int);
+INSERT INTO t1 VALUES (2,2);
+SELECT * FROM t1 WHERE a = b;
+a b
+2 2
+EXPLAIN
+SELECT * FROM t1 WHERE a = b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1
+DROP TABLE t1;
+#
+# lp:822760 Wrong result with view + invalid dates
+#
+CREATE TABLE t1 (f1 date);
+INSERT IGNORE INTO t1 VALUES ('0000-00-00');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t1 HAVING f1 = 'zz';
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+SELECT * FROM t1 HAVING f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'aa'
+SELECT * FROM t1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+SELECT * FROM t1 WHERE f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+Warning 1292 Incorrect datetime value: 'zz'
+SELECT * FROM v1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+DROP TABLE t1;
+DROP VIEW v1;
+SET optimizer_switch=@save_optimizer_switch;
+#
+# LP bug#994275 Assertion `real->type() == Item::FIELD_ITEM' failed
+# in add_not_null_conds(JOIN*) with JOIN, ZEROFILL column, PK
+#
+CREATE TABLE t1 ( a INT(6) ZEROFILL );
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 ( b INT PRIMARY KEY );
+INSERT INTO t2 VALUES (3),(4);
+SELECT * FROM t1, t2 WHERE a=3 AND a=b;
+a b
+drop table t1,t2;
+End of 5.3 tests
diff --git a/mysql-test/r/select_safe.result b/mysql-test/r/select_safe.result
index d810271e337..f601e294c66 100644
--- a/mysql-test/r/select_safe.result
+++ b/mysql-test/r/select_safe.result
@@ -64,15 +64,17 @@ analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a");
+insert into t1 values (null,"b"),(null,"b"),(null,"c"),(null,"c"),(null,"d"),(null,"d"),(null,"e"),(null,"e"),(null,"a"),(null,"e");
+insert into t1 values (null,"x"),(null,"x"),(null,"y"),(null,"y"),(null,"z"),(null,"z"),(null,"v"),(null,"v"),(null,"a"),(null,"v");
explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL b NULL NULL NULL 21
-1 SIMPLE t2 ref b b 21 test.t1.b 6 Using where
+1 SIMPLE t1 ALL b NULL NULL NULL 41 Using where
+1 SIMPLE t2 ref b b 21 test.t1.b 6
set MAX_SEEKS_FOR_KEY=1;
explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL b NULL NULL NULL 21
-1 SIMPLE t2 ref b b 21 test.t1.b 6 Using where
+1 SIMPLE t1 ALL b NULL NULL NULL 41 Using where
+1 SIMPLE t2 ref b b 21 test.t1.b 6
SET MAX_SEEKS_FOR_KEY=DEFAULT;
drop table t1;
create table t1 (a int);
diff --git a/mysql-test/r/shm.result b/mysql-test/r/shm.result
index 0e086e000c7..f6ce63555d7 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");
@@ -1347,6 +1347,8 @@ fld1 fld1
250503 250505
250504 250505
250505 250505
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
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
@@ -1389,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
@@ -1413,15 +1415,16 @@ 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
+SET optimizer_switch=@save_optimizer_switch;
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
@@ -1429,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/sp-threads.result b/mysql-test/r/sp-threads.result
index 953830ecc87..6f78137dd6a 100644
--- a/mysql-test/r/sp-threads.result
+++ b/mysql-test/r/sp-threads.result
@@ -33,11 +33,11 @@ call bug9486();
lock tables t2 write;
call bug9486();
show processlist;
-Id User Host db Command Time State Info
-# root localhost test Sleep # NULL
-# root localhost test Query # Locked update t1, t2 set val= 1 where id1=id2
-# root localhost test Query # NULL show processlist
-# root localhost test Sleep # NULL
+Id User Host db Command Time State Info Progress
+# root localhost test Sleep # NULL 0.000
+# root localhost test Query # Table lock update t1, t2 set val= 1 where id1=id2 0.000
+# root localhost test Query # NULL show processlist 0.000
+# root localhost test Sleep # NULL 0.000
unlock tables;
drop procedure bug9486;
drop table t1, t2;
diff --git a/mysql-test/r/sp-vars.result b/mysql-test/r/sp-vars.result
index f5420a62f63..15ddc2b44f5 100644
--- a/mysql-test/r/sp-vars.result
+++ b/mysql-test/r/sp-vars.result
@@ -380,7 +380,7 @@ ERROR 22003: Out of range value for column 'sp_vars_check_ret1()' at row 1
SELECT sp_vars_check_ret2();
ERROR 22003: Out of range value for column 'sp_vars_check_ret2()' at row 1
SELECT sp_vars_check_ret3();
-ERROR HY000: Incorrect integer value: 'Hello, world' for column 'sp_vars_check_ret3()' at row 1
+ERROR 22007: Incorrect integer value: 'Hello, world' for column 'sp_vars_check_ret3()' at row 1
SELECT sp_vars_check_ret4();
sp_vars_check_ret4()
154.12
@@ -698,7 +698,7 @@ t1 CREATE TABLE "t1" (
"x" datetime DEFAULT NULL
)
Warnings:
-Warning 1264 Out of range value for column 'x' at row 1
+Warning 1265 Data truncated for column 'x' at row 1
DROP PROCEDURE p1;
---------------------------------------------------------------
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index adb783ee243..cc5a1f6f65a 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -3051,8 +3051,7 @@ begin
set @x = @x + 1;
return @x;
end|
-set @qcs1 = @@query_cache_size|
-set global query_cache_size = 100000|
+# Set query cache size, if we have query cache
set @x = 1|
insert into t1 values ("qc", 42)|
select bug9902() from t1|
@@ -3064,7 +3063,7 @@ bug9902()
select @x|
@x
3
-set global query_cache_size = @qcs1|
+# Restore the old query cache size
delete from t1|
drop function bug9902|
drop function if exists bug9102|
@@ -6418,19 +6417,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
@@ -6484,7 +6483,7 @@ DROP TABLE t1;
CALL p1('text');
Warnings:
-Warning 1264 Out of range value for column 'v' at row 1
+Warning 1265 Data truncated for column 'v' at row 1
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -7147,3 +7146,33 @@ c1 c2 count(c3)
2012-03-01 01:00:00 3 1
2012-03-01 02:00:00 3 1
DROP PROCEDURE p1;
+
+MDEV-3900 Optimizer difference between MySQL and MariaDB with stored functions in WHERE clause of UPDATE or DELETE statements
+
+CREATE FUNCTION tdn() RETURNS int(7) DETERMINISTIC RETURN to_days(now());
+CREATE TABLE t1 (pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY, daynum INT, a CHAR(1), INDEX(daynum), INDEX(a)) ENGINE=MyISAM;
+INSERT INTO t1 (daynum) VALUES (1),(2),(3),(4),(5),(TO_DAYS(NOW())),(7),(8);
+INSERT INTO t1 (daynum) SELECT a1.daynum FROM t1 a1, t1 a2, t1 a3, t1 a4, t1 a5;
+FLUSH TABLES;
+FLUSH STATUS;
+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_deleted 0
+Handler_read_rnd_next 0
+UPDATE t1 SET a = '+' WHERE daynum=tdn();
+SHOW STATUS LIKE '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 2
+Handler_read_next 4097
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 0
+drop function tdn;
+drop table t1;
diff --git a/mysql-test/r/ssl.result b/mysql-test/r/ssl.result
index 9ad515a53a3..eae5bb5c2c9 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");
@@ -1350,6 +1350,8 @@ fld1 fld1
250503 250505
250504 250505
250505 250505
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
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
@@ -1392,15 +1394,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 +1418,16 @@ 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
+SET optimizer_switch=@save_optimizer_switch;
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
@@ -1432,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/ssl_compress.result b/mysql-test/r/ssl_compress.result
index 1bd427a65e2..d39d09322c8 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");
@@ -1353,6 +1353,8 @@ fld1 fld1
250503 250505
250504 250505
250505 250505
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
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
@@ -1395,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
@@ -1419,15 +1421,16 @@ 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
+SET optimizer_switch=@save_optimizer_switch;
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
@@ -1435,7 +1438,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/status.result b/mysql-test/r/status.result
index ce3acba9b8a..d3e1d26cbbd 100644
--- a/mysql-test/r/status.result
+++ b/mysql-test/r/status.result
@@ -149,32 +149,40 @@ a a
1 1
SHOW SESSION STATUS LIKE 'Last_query_cost';
Variable_name Value
-Last_query_cost 4.805836
+Last_query_cost 5.205836
DROP TABLE t1;
show status like 'com_show_status';
Variable_name Value
Com_show_status 3
show status like 'hand%write%';
Variable_name Value
+Handler_tmp_write 0
Handler_write 0
show status like '%tmp%';
Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_files 0
Created_tmp_tables 0
+Handler_tmp_update 0
+Handler_tmp_write 0
+Rows_tmp_read 5
show status like 'hand%write%';
Variable_name Value
+Handler_tmp_write 0
Handler_write 0
show status like '%tmp%';
Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_files 0
Created_tmp_tables 0
+Handler_tmp_update 0
+Handler_tmp_write 0
+Rows_tmp_read 13
show status like 'com_show_status';
Variable_name Value
Com_show_status 8
rnd_diff tmp_table_diff
-20 8
+28 8
flush status;
show status like 'Com%function';
Variable_name Value
@@ -238,5 +246,95 @@ SELECT 9;
9
DROP PROCEDURE p1;
DROP FUNCTION f1;
+flush status;
+create table t1 (a int not null auto_increment primary key, g int, b blob);
+insert into t1 (g,b) values (1,'a'), (2, 'b'), (3, 'b'), (1, 'c');
+select * from t1;
+a g b
+1 1 a
+2 2 b
+3 3 b
+4 1 c
+select b, count(*) from t1 group by b;
+b count(*)
+a 1
+b 2
+c 1
+select g, count(*) from t1 group by g;
+g count(*)
+1 2
+2 1
+3 1
+show status like 'Row%';
+Variable_name Value
+Rows_read 12
+Rows_sent 10
+Rows_tmp_read 14
+show status like 'Handler%';
+Variable_name Value
+Handler_commit 0
+Handler_delete 0
+Handler_discover 0
+Handler_icp_attempts 0
+Handler_icp_match 0
+Handler_mrr_init 0
+Handler_mrr_key_refills 0
+Handler_mrr_rowid_refills 0
+Handler_prepare 0
+Handler_read_first 0
+Handler_read_key 4
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 7
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 23
+Handler_rollback 0
+Handler_savepoint 0
+Handler_savepoint_rollback 0
+Handler_tmp_update 2
+Handler_tmp_write 7
+Handler_update 0
+Handler_write 4
+show status like '%tmp%';
+Variable_name Value
+Created_tmp_disk_tables 1
+Created_tmp_files 0
+Created_tmp_tables 2
+Handler_tmp_update 2
+Handler_tmp_write 7
+Rows_tmp_read 40
+drop table t1;
+CREATE TABLE t1 (i int(11) DEFAULT NULL, KEY i (i) ) ENGINE=MyISAM;
+insert into t1 values (1),(2),(3),(4),(5);
+flush status;
+select * from t1 where i=5 union select * from t1 where i=5;
+i
+5
+show status like "handler%";
+Variable_name Value
+Handler_commit 0
+Handler_delete 0
+Handler_discover 0
+Handler_icp_attempts 0
+Handler_icp_match 0
+Handler_mrr_init 0
+Handler_mrr_key_refills 0
+Handler_mrr_rowid_refills 0
+Handler_prepare 0
+Handler_read_first 0
+Handler_read_key 2
+Handler_read_next 2
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_deleted 1
+Handler_read_rnd_next 2
+Handler_rollback 0
+Handler_savepoint 0
+Handler_savepoint_rollback 0
+Handler_tmp_update 0
+Handler_tmp_write 2
+Handler_update 0
+Handler_write 0
+drop table t1;
set @@global.concurrent_insert= @old_concurrent_insert;
SET GLOBAL log_output = @old_log_output;
diff --git a/mysql-test/r/status_user.result b/mysql-test/r/status_user.result
index 636eeabfffc..b2d4b6f761f 100644
--- a/mysql-test/r/status_user.result
+++ b/mysql-test/r/status_user.result
@@ -94,21 +94,30 @@ show status like "rows%";
Variable_name Value
Rows_read 6
Rows_sent 1
+Rows_tmp_read 0
show status like "ha%";
Variable_name Value
Handler_commit 19
Handler_delete 1
Handler_discover 0
+Handler_icp_attempts 0
+Handler_icp_match 0
+Handler_mrr_init 0
+Handler_mrr_key_refills 0
+Handler_mrr_rowid_refills 0
Handler_prepare 18
Handler_read_first 0
Handler_read_key 3
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 5
Handler_rollback 2
Handler_savepoint 0
Handler_savepoint_rollback 0
+Handler_tmp_update 0
+Handler_tmp_write 0
Handler_update 5
Handler_write 7
select variable_value - @global_read_key as "handler_read_key" from information_schema.global_status where variable_name="handler_read_key";
@@ -133,7 +142,7 @@ CONCURRENT_CONNECTIONS 0
ROWS_READ 6
ROWS_SENT 2
ROWS_DELETED 1
-ROWS_INSERTED 8
+ROWS_INSERTED 7
ROWS_UPDATED 5
SELECT_COMMANDS 3
UPDATE_COMMANDS 11
@@ -150,7 +159,7 @@ CONCURRENT_CONNECTIONS 0
ROWS_READ 6
ROWS_SENT 2
ROWS_DELETED 1
-ROWS_INSERTED 8
+ROWS_INSERTED 7
ROWS_UPDATED 5
SELECT_COMMANDS 3
UPDATE_COMMANDS 11
@@ -183,4 +192,33 @@ bytes_sent <> 0, binlog_bytes_written <> 0
from information_schema.client_statistics;
connected_time <> 0 busy_time <> 0 bytes_received <> 0 bytes_sent <> 0 binlog_bytes_written <> 0
1 1 1 1 1
+create table t1 (a int) engine=innodb;
+select @@in_transaction;
+@@in_transaction
+0
+begin;
+select @@in_transaction;
+@@in_transaction
+1
+insert into t1 values (1);
+select @@in_transaction;
+@@in_transaction
+1
+commit;
+select @@in_transaction;
+@@in_transaction
+0
+set @@autocommit=0;
+select @@in_transaction;
+@@in_transaction
+0
+insert into t1 values (2);
+select @@in_transaction;
+@@in_transaction
+1
+set @@autocommit=1;
+select @@in_transaction;
+@@in_transaction
+0
+drop table t1;
set @@global.general_log=@save_general_log;
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index 241f4198bf7..31159051749 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -41,7 +41,7 @@ INSERT INTO t1 VALUES('0000-00-00');
ERROR 22007: Incorrect date value: '0000-00-00' for column 'col1' at row 1
INSERT IGNORE INTO t1 VALUES('0000-00-00');
Warnings:
-Warning 1265 Data truncated for column 'col1' at row 1
+Warning 1264 Out of range value for column 'col1' at row 1
INSERT INTO t1 VALUES ('2004-0-30');
INSERT INTO t1 VALUES ('2004-2-30');
ERROR 22007: Incorrect date value: '2004-2-30' for column 'col1' at row 1
@@ -51,7 +51,7 @@ set @@sql_mode='ansi,traditional';
INSERT IGNORE INTO t1 VALUES('2004-02-29'),('2004-13-15'),('0000-00-00');
Warnings:
Warning 1265 Data truncated for column 'col1' at row 2
-Warning 1265 Data truncated for column 'col1' at row 3
+Warning 1264 Out of range value for column 'col1' at row 3
select * from t1;
col1
2004-01-01
@@ -264,14 +264,14 @@ ERROR 22007: Incorrect date value: '2004-10-00' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES(CAST('2004-0-10' AS DATE));
ERROR 22007: Incorrect date value: '2004-00-10' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES(CAST('0000-00-00' AS DATE));
-ERROR 22007: Incorrect datetime value: '0000-00-00'
+ERROR 22007: Incorrect date value: '0000-00-00' for column 'col1' at row 1
INSERT INTO t1 (col2) VALUES(CAST('0000-10-31 15:30' AS DATETIME));
INSERT INTO t1 (col2) VALUES(CAST('2004-10-0 15:30' AS DATETIME));
ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col2' at row 1
INSERT INTO t1 (col2) VALUES(CAST('2004-0-10 15:30' AS DATETIME));
ERROR 22007: Incorrect datetime value: '2004-00-10 15:30:00' for column 'col2' at row 1
INSERT INTO t1 (col2) VALUES(CAST('0000-00-00' AS DATETIME));
-ERROR 22007: Incorrect datetime value: '0000-00-00'
+ERROR 22007: Incorrect datetime value: '0000-00-00 00:00:00' for column 'col2' at row 1
INSERT INTO t1 (col3) VALUES(CAST('0000-10-31 15:30' AS DATETIME));
ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1
INSERT INTO t1 (col3) VALUES(CAST('2004-10-0 15:30' AS DATETIME));
@@ -279,7 +279,7 @@ ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col3' a
INSERT INTO t1 (col3) VALUES(CAST('2004-0-10 15:30' AS DATETIME));
ERROR 22007: Incorrect datetime value: '2004-00-10 15:30:00' for column 'col3' at row 1
INSERT INTO t1 (col3) VALUES(CAST('0000-00-00' AS DATETIME));
-ERROR 22007: Incorrect datetime value: '0000-00-00'
+ERROR 22007: Incorrect datetime value: '0000-00-00 00:00:00' for column 'col3' at row 1
drop table t1;
CREATE TABLE t1 (col1 date, col2 datetime, col3 timestamp);
INSERT INTO t1 (col1) VALUES (CONVERT('2004-10-15',DATE));
@@ -290,15 +290,17 @@ INSERT INTO t1 (col1) VALUES(CONVERT('2004-10-0' , DATE));
ERROR 22007: Incorrect date value: '2004-10-00' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES(CONVERT('2004-0-10' , DATE));
ERROR 22007: Incorrect date value: '2004-00-10' for column 'col1' at row 1
+INSERT INTO t1 (col1) VALUES('2004-0-10');
+ERROR 22007: Incorrect date value: '2004-0-10' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES(CONVERT('0000-00-00',DATE));
-ERROR 22007: Incorrect datetime value: '0000-00-00'
+ERROR 22007: Incorrect date value: '0000-00-00' for column 'col1' at row 1
INSERT INTO t1 (col2) VALUES(CONVERT('0000-10-31 15:30',DATETIME));
INSERT INTO t1 (col2) VALUES(CONVERT('2004-10-0 15:30',DATETIME));
ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col2' at row 1
INSERT INTO t1 (col2) VALUES(CONVERT('2004-0-10 15:30',DATETIME));
ERROR 22007: Incorrect datetime value: '2004-00-10 15:30:00' for column 'col2' at row 1
INSERT INTO t1 (col2) VALUES(CONVERT('0000-00-00',DATETIME));
-ERROR 22007: Incorrect datetime value: '0000-00-00'
+ERROR 22007: Incorrect datetime value: '0000-00-00 00:00:00' for column 'col2' at row 1
INSERT INTO t1 (col3) VALUES(CONVERT('0000-10-31 15:30',DATETIME));
ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1
INSERT INTO t1 (col3) VALUES(CONVERT('2004-10-0 15:30',DATETIME));
@@ -306,7 +308,7 @@ ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col3' a
INSERT INTO t1 (col3) VALUES(CONVERT('2004-0-10 15:30',DATETIME));
ERROR 22007: Incorrect datetime value: '2004-00-10 15:30:00' for column 'col3' at row 1
INSERT INTO t1 (col3) VALUES(CONVERT('0000-00-00',DATETIME));
-ERROR 22007: Incorrect datetime value: '0000-00-00'
+ERROR 22007: Incorrect datetime value: '0000-00-00 00:00:00' for column 'col3' at row 1
drop table t1;
CREATE TABLE t1(col1 TINYINT, col2 TINYINT UNSIGNED);
INSERT INTO t1 VALUES(-128,0),(0,0),(127,255),('-128','0'),('0','0'),('127','255'),(-128.0,0.0),(0.0,0.0),(127.0,255.0);
@@ -364,9 +366,9 @@ Warnings:
Error 1365 Division by 0
Error 1365 Division by 0
INSERT INTO t1 (col1) VALUES ('');
-ERROR HY000: Incorrect integer value: '' for column 'col1' at row 1
+ERROR 22007: Incorrect integer value: '' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('a59b');
-ERROR HY000: Incorrect integer value: 'a59b' for column 'col1' at row 1
+ERROR 22007: Incorrect integer value: 'a59b' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('1a');
ERROR 01000: Data truncated for column 'col1' at row 1
INSERT IGNORE INTO t1 (col1) VALUES ('2a');
@@ -447,9 +449,9 @@ ERROR 22012: Division by 0
UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
ERROR 22012: Division by 0
INSERT INTO t1 (col1) VALUES ('');
-ERROR HY000: Incorrect integer value: '' for column 'col1' at row 1
+ERROR 22007: Incorrect integer value: '' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('a59b');
-ERROR HY000: Incorrect integer value: 'a59b' for column 'col1' at row 1
+ERROR 22007: Incorrect integer value: 'a59b' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('1a');
ERROR 01000: Data truncated for column 'col1' at row 1
INSERT IGNORE INTO t1 (col1) VALUES ('2a');
@@ -531,9 +533,9 @@ ERROR 22012: Division by 0
UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
ERROR 22012: Division by 0
INSERT INTO t1 (col1) VALUES ('');
-ERROR HY000: Incorrect integer value: '' for column 'col1' at row 1
+ERROR 22007: Incorrect integer value: '' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('a59b');
-ERROR HY000: Incorrect integer value: 'a59b' for column 'col1' at row 1
+ERROR 22007: Incorrect integer value: 'a59b' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('1a');
ERROR 01000: Data truncated for column 'col1' at row 1
INSERT IGNORE INTO t1 (col1) VALUES ('2a');
@@ -615,9 +617,9 @@ ERROR 22012: Division by 0
UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
ERROR 22012: Division by 0
INSERT INTO t1 (col1) VALUES ('');
-ERROR HY000: Incorrect integer value: '' for column 'col1' at row 1
+ERROR 22007: Incorrect integer value: '' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('a59b');
-ERROR HY000: Incorrect integer value: 'a59b' for column 'col1' at row 1
+ERROR 22007: Incorrect integer value: 'a59b' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('1a');
ERROR 01000: Data truncated for column 'col1' at row 1
INSERT IGNORE INTO t1 (col1) VALUES ('2a');
@@ -697,9 +699,9 @@ ERROR 22012: Division by 0
UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
ERROR 22012: Division by 0
INSERT INTO t1 (col1) VALUES ('');
-ERROR HY000: Incorrect integer value: '' for column 'col1' at row 1
+ERROR 22007: Incorrect integer value: '' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('a59b');
-ERROR HY000: Incorrect integer value: 'a59b' for column 'col1' at row 1
+ERROR 22007: Incorrect integer value: 'a59b' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('1a');
ERROR 01000: Data truncated for column 'col1' at row 1
INSERT IGNORE INTO t1 (col1) VALUES ('2a');
@@ -776,7 +778,7 @@ ERROR 22003: Out of range value for column 'col1' at row 1
INSERT INTO t1 VALUES ('-100E+1');
ERROR 22003: Out of range value for column 'col1' at row 1
INSERT INTO t1 VALUES ('-100E');
-ERROR HY000: Incorrect decimal value: '-100E' for column 'col1' at row 1
+ERROR 22007: Incorrect decimal value: '-100E' for column 'col1' at row 1
UPDATE t1 SET col1 =col1 * 50000 WHERE col1 =11;
ERROR 22003: Out of range value for column 'col1' at row 6
UPDATE t1 SET col1 =col1 / 0 WHERE col1 > 0;
@@ -784,11 +786,11 @@ ERROR 22012: Division by 0
UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
ERROR 22012: Division by 0
INSERT INTO t1 (col1) VALUES ('');
-ERROR HY000: Incorrect decimal value: '' for column 'col1' at row 1
+ERROR 22007: Incorrect decimal value: '' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('a59b');
-ERROR HY000: Incorrect decimal value: 'a59b' for column 'col1' at row 1
+ERROR 22007: Incorrect decimal value: 'a59b' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES ('1a');
-ERROR HY000: Incorrect decimal value: '1a' for column 'col1' at row 1
+ERROR 22007: Incorrect decimal value: '1a' for column 'col1' at row 1
INSERT IGNORE INTO t1 (col1) VALUES ('2a');
Warnings:
Note 1265 Data truncated for column 'col1' at row 1
@@ -1105,8 +1107,6 @@ count(*)
7
Warnings:
Error 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date
-Error 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date
-Error 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date
drop table t1;
create table t1 (col1 char(3), col2 integer);
insert into t1 (col1) values (cast(1000 as char(3)));
@@ -1136,9 +1136,9 @@ ERROR 22007: Incorrect date value: '0' for column 'col1' at row 1
insert into t1 values (0.0,0.0,0.0);
ERROR 22007: Incorrect date value: '0' for column 'col1' at row 1
insert into t1 (col1) values (convert('0000-00-00',date));
-ERROR 22007: Incorrect datetime value: '0000-00-00'
+ERROR 22007: Incorrect date value: '0000-00-00' for column 'col1' at row 1
insert into t1 (col1) values (cast('0000-00-00' as date));
-ERROR 22007: Incorrect datetime value: '0000-00-00'
+ERROR 22007: Incorrect date value: '0000-00-00' for column 'col1' at row 1
set sql_mode='no_zero_date';
insert into t1 values (0,0,0);
Warnings:
@@ -1155,15 +1155,15 @@ set sql_mode='traditional';
create table t1 (col1 date);
insert ignore into t1 values ('0000-00-00');
Warnings:
-Warning 1265 Data truncated for column 'col1' at row 1
+Warning 1264 Out of range value for column 'col1' at row 1
insert into t1 select * from t1;
ERROR 22007: Incorrect date value: '0000-00-00' for column 'col1' at row 1
insert ignore into t1 values ('0000-00-00');
Warnings:
-Warning 1265 Data truncated for column 'col1' at row 1
+Warning 1264 Out of range value for column 'col1' at row 1
insert ignore into t1 (col1) values (cast('0000-00-00' as date));
Warnings:
-Warning 1292 Incorrect datetime value: '0000-00-00'
+Warning 1264 Out of range value for column 'col1' at row 1
insert into t1 select * from t1;
ERROR 22007: Incorrect date value: '0000-00-00' for column 'col1' at row 1
alter table t1 modify col1 datetime;
@@ -1172,13 +1172,14 @@ alter ignore table t1 modify col1 datetime;
Warnings:
Warning 1264 Out of range value for column 'col1' at row 1
Warning 1264 Out of range value for column 'col1' at row 2
+Warning 1264 Out of range value for column 'col1' at row 3
insert into t1 select * from t1;
ERROR 22007: Incorrect datetime value: '0000-00-00 00:00:00' for column 'col1' at row 1
select * from t1;
col1
0000-00-00 00:00:00
0000-00-00 00:00:00
-NULL
+0000-00-00 00:00:00
drop table t1;
create table t1 (col1 tinyint);
drop procedure if exists t1;
@@ -1361,34 +1362,34 @@ col5 mediumint, col6 mediumint unsigned,
col7 int, col8 int unsigned,
col9 bigint, col10 bigint unsigned);
insert into t1(col1) values('-');
-ERROR HY000: Incorrect integer value: '-' for column 'col1' at row 1
+ERROR 22007: Incorrect integer value: '-' for column 'col1' at row 1
insert into t1(col2) values('+');
-ERROR HY000: Incorrect integer value: '+' for column 'col2' at row 1
+ERROR 22007: Incorrect integer value: '+' for column 'col2' at row 1
insert into t1(col3) values('-');
-ERROR HY000: Incorrect integer value: '-' for column 'col3' at row 1
+ERROR 22007: Incorrect integer value: '-' for column 'col3' at row 1
insert into t1(col4) values('+');
-ERROR HY000: Incorrect integer value: '+' for column 'col4' at row 1
+ERROR 22007: Incorrect integer value: '+' for column 'col4' at row 1
insert into t1(col5) values('-');
-ERROR HY000: Incorrect integer value: '-' for column 'col5' at row 1
+ERROR 22007: Incorrect integer value: '-' for column 'col5' at row 1
insert into t1(col6) values('+');
-ERROR HY000: Incorrect integer value: '+' for column 'col6' at row 1
+ERROR 22007: Incorrect integer value: '+' for column 'col6' at row 1
insert into t1(col7) values('-');
-ERROR HY000: Incorrect integer value: '-' for column 'col7' at row 1
+ERROR 22007: Incorrect integer value: '-' for column 'col7' at row 1
insert into t1(col8) values('+');
-ERROR HY000: Incorrect integer value: '+' for column 'col8' at row 1
+ERROR 22007: Incorrect integer value: '+' for column 'col8' at row 1
insert into t1(col9) values('-');
-ERROR HY000: Incorrect integer value: '-' for column 'col9' at row 1
+ERROR 22007: Incorrect integer value: '-' for column 'col9' at row 1
insert into t1(col10) values('+');
-ERROR HY000: Incorrect integer value: '+' for column 'col10' at row 1
+ERROR 22007: Incorrect integer value: '+' for column 'col10' at row 1
drop table t1;
set sql_mode='traditional';
create table t1(a year);
insert into t1 values ('-');
-ERROR HY000: Incorrect integer value: '-' for column 'a' at row 1
+ERROR 22007: Incorrect integer value: '-' for column 'a' at row 1
insert into t1 values ('+');
-ERROR HY000: Incorrect integer value: '+' for column 'a' at row 1
+ERROR 22007: Incorrect integer value: '+' for column 'a' at row 1
insert into t1 values ('');
-ERROR HY000: Incorrect integer value: '' for column 'a' at row 1
+ERROR 22007: Incorrect integer value: '' for column 'a' at row 1
insert into t1 values ('2000a');
ERROR 01000: Data truncated for column 'a' at row 1
insert into t1 values ('2E3x');
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 0087044c782..8503164dde2 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1,4 +1,10 @@
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+drop view if exists v2;
+set @subselect_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test,
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+set join_cache_level=1;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
select (select 2);
(select 2)
2
@@ -50,7 +56,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having ((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
@@ -196,14 +202,17 @@ 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
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
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
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 100.00
3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
Warnings:
-Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,'2' AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`tt`.`a` AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
+set optimizer_switch=@tmp_optimizer_switch;
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
@@ -224,7 +233,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t4.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select `test`.`t4`.`b` AS `b`,(select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+Note 1003 select `test`.`t4`.`b` AS `b`,<expr_cache><`test`.`t4`.`a`>((select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`)) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
select * from t3 where exists (select * from t2 where t2.b=t3.a);
a
7
@@ -270,7 +279,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(((select min(`test`.`t2`.`b`) from `test`.`t2`) <= `test`.`t3`.`a`))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2);
a
7
@@ -314,7 +323,7 @@ NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
Note 1276 Field or reference 'test.t2.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select (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 +341,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
Warnings:
Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where exists(select 1 from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`))
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where <expr_cache><`test`.`t6`.`clinic_uq`>(exists(select 1 from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`)))
select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
ERROR 23000: Column 'a' in field list is ambiguous
drop table t1,t2,t3;
@@ -362,12 +371,12 @@ INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where; Using index
4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
-2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where
3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
Warnings:
-Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
+Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
ERROR 21000: Operand should contain 1 column(s)
@@ -420,7 +429,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
+Note 1003 select 1 AS `1` from `test`.`t1` where (1 = (select 1 union select 1))
drop table t1;
CREATE TABLE `t1` (
`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
@@ -505,6 +514,9 @@ select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
ERROR 21000: Subquery returns more than 1 row
select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1);
ERROR 21000: Subquery returns more than 1 row
+show warnings;
+Level Code Message
+Error 1242 Subquery returns more than 1 row
drop table t1;
create table t1 (a int);
insert into t1 values (1),(2),(3);
@@ -535,6 +547,12 @@ SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT
numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY t1 ref PRIMARY PRIMARY 3 const 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select 1 from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
ERROR 21000: Subquery returns more than 1 row
EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
id select_type table type possible_keys key key_len ref rows filtered Extra
@@ -543,10 +561,10 @@ 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
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select '3' AS `numreponse` from `test`.`t1` where (('1' = '1'))
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
drop table t1;
CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1);
@@ -586,7 +604,7 @@ a b
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);
+delete from t1 where b in (select b from t1);
ERROR HY000: You can't specify target table 't1' for update in FROM clause
delete from t1 where b = (select b from t2);
ERROR 21000: Subquery returns more than 1 row
@@ -719,7 +737,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 +749,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 +761,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where <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 +909,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
2 DEPENDENT SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,<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;
@@ -904,9 +922,9 @@ explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) F
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 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 `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`)))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
drop table t1,t2,t3;
# check correct NULL Processing for normal IN/ALL/ANY
# and 2 ways of max/min optimization
@@ -1302,9 +1320,9 @@ SELECT 0 IN (SELECT 1 FROM t1 a);
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 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
INSERT INTO t1 (pseudo) VALUES ('test1');
SELECT 0 IN (SELECT 1 FROM t1 a);
0 IN (SELECT 1 FROM t1 a)
@@ -1312,9 +1330,9 @@ SELECT 0 IN (SELECT 1 FROM t1 a);
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 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
drop table t1;
CREATE TABLE `t1` (
`i` int(11) NOT NULL default '0',
@@ -1356,7 +1374,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using where
+1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using where
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
@@ -1381,7 +1399,7 @@ 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
+Warning 1242 Subquery returns more than 1 row
select * from t1;
a b
1 1
@@ -1418,36 +1436,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`.`t3`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t2`.`a`))
drop table t1, t2, t3;
create table t1 (a int, b int, index a (a,b));
create table t2 (a int, index a (a));
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);
@@ -1457,31 +1479,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.00 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`.`b` = `test`.`t3`.`a`) and (`test`.`t1`.`a` = `test`.`t2`.`a`))
insert into t1 values (3,31);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
@@ -1494,11 +1516,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);
@@ -1588,25 +1610,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 not null);
create table t3 (a int);
@@ -1621,7 +1643,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(((select max(NULL) from `test`.`t2`) > `test`.`t3`.`a`))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2);
a
explain extended select * from t3 where a >= some (select b from t2);
@@ -1629,7 +1651,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(((select min(NULL) from `test`.`t2`) <= `test`.`t3`.`a`))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2 group by 1);
a
6
@@ -1640,7 +1662,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((<max>(select NULL from `test`.`t2` group by 1) > `test`.`t3`.`a`))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2 group by 1);
a
explain extended select * from t3 where a >= some (select b from t2 group by 1);
@@ -1648,39 +1670,39 @@ 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>((<min>(select NULL from `test`.`t2` group by 1) <= `test`.`t3`.`a`))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where NULL >= any (select b from t2);
a
explain extended select * from t3 where NULL >= any (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= any (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= some (select b from t2);
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 NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= some (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a);
a
@@ -1689,9 +1711,9 @@ a
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
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= `test`.`t3`.`a`))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= <cache>(`test`.`t3`.`a`))))
drop table t2, t3;
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
@@ -1742,7 +1764,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION t1 system NULL NULL NULL NULL 1 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select 'e' AS `s1` from `test`.`t1` where 1
+Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',(<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`) < 'f')))
drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
@@ -1861,14 +1883,14 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00 Using where
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where
Warnings:
-Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not(<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');
@@ -1892,7 +1914,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;
@@ -2404,7 +2426,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where 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);
@@ -2875,6 +2897,8 @@ select * from (select max(fld) from t1) as foo;
max(fld)
1
drop table t1;
+set @tmp11867_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin_with_cache=off';
CREATE TABLE t1 (one int, two int, flag char(1));
CREATE TABLE t2 (one int, two int, flag char(1));
INSERT INTO t1 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
@@ -2945,20 +2969,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`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` 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
+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') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') 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`
DROP TABLE t1,t2;
+set optimizer_switch=@tmp11867_optimizer_switch;
CREATE TABLE t1 (a char(5), b char(5));
INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
SELECT * FROM t1 WHERE (a,b) IN (('aaa','aaa'), ('aaa','bbb'));
@@ -3073,7 +3099,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
-1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using where
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
@@ -3085,8 +3111,8 @@ 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 where
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
@@ -3227,10 +3253,10 @@ 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
+2
3
+4
SELECT a FROM t1
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
@@ -3239,8 +3265,8 @@ 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
+2
3
4
SELECT a FROM t1
@@ -3537,7 +3563,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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
ALTER TABLE t1 ADD INDEX(a);
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
a b
@@ -3547,8 +3574,9 @@ 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
+1 PRIMARY t1 ALL a NULL NULL NULL 9 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
DROP TABLE t1;
create table t1( f1 int,f2 int);
insert into t1 values (1,1),(2,2);
@@ -3679,28 +3707,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;
@@ -3788,12 +3794,15 @@ 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'
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;
@@ -3805,7 +3814,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);
@@ -4165,7 +4174,7 @@ CREATE TABLE t1 (a int, b int, KEY (a));
INSERT INTO t1 VALUES (1,1),(2,1);
EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref a a 5 const 1 Using where; Using index
+1 PRIMARY t1 ref a a 5 const 0 Using where; Using index
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
DROP TABLE t1;
CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
@@ -4229,8 +4238,6 @@ 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
@@ -4329,6 +4336,9 @@ LEFT(t1.a1,1)
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;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+SET optimizer_switch='materialization=off';
CREATE TABLE t1 (a CHAR(1), b VARCHAR(10));
INSERT INTO t1 VALUES ('a', 'aa');
INSERT INTO t1 VALUES ('a', 'aaa');
@@ -4338,8 +4348,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));
@@ -4348,18 +4358,19 @@ 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;
+SET optimizer_switch= @save_optimizer_switch;
CREATE TABLE t1(a INT, b INT);
INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4);
EXPLAIN
@@ -4385,37 +4396,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,
@@ -4473,18 +4467,23 @@ 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);
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
Warnings:
-Note 1003 select 1 AS `1` from `test`.`t1` where 1
-EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a);
+Note 1003 select 1 AS `1` from <materialize> (select min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (`<subquery2>`.`min(a)` = 1)
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) 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
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
Warnings:
-Note 1003 select 1 AS `1` from `test`.`t1` where 0
+Note 1003 select 1 AS `1` from <materialize> (select min(`test`.`t1`.`a`) from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a`) join `test`.`t1` where (`<subquery2>`.`min(a)` = 1)
+SET join_cache_level=@save_join_cache_level;
DROP TABLE t1;
#
# Bug#45061: Incorrectly market field caused wrong result.
@@ -4533,7 +4532,7 @@ 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
+NULL NULL
DROP TABLE t1, st1, st2;
#
# Bug #48709: Assertion failed in sql_select.cc:11782:
@@ -4574,7 +4573,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00
Warnings:
-Note 1003 select 1 AS `1` from `test`.`t1` where 1
+Note 1003 select 1 AS `1` from `test`.`t1` where <nop>(<in_optimizer>(1,((select max(`test`.`t1`.`a1`) from `test`.`t1`) > 1)))
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
1
1
@@ -4643,6 +4642,203 @@ SET SESSION sql_mode=@old_sql_mode;
drop table t2, t1;
drop view v1;
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;
@@ -4720,9 +4916,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
@@ -4755,6 +4951,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));
@@ -4966,6 +5198,134 @@ ERROR 21000: Subquery returns more than 1 row
drop table t1,t2;
End of 5.1 tests
#
+# No BUG#, a case brought from 5.2's innodb_mysql_lock.test
+#
+create table t1 (i int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+create table t2 (j int not null primary key);
+insert into t2 values (1),(2),(3),(4),(5);
+create table t3 (k int not null primary key);
+insert into t3 values (1),(2),(3);
+create view v2 as select t2.j as j from t2 where t2.j in (select t1.i from t1);
+select * from t3 where k in (select j from v2);
+k
+1
+2
+3
+drop table t1,t2,t3;
+drop view v2;
+#
+# Bug#52068: Optimizer generates invalid semijoin materialization plan
+#
+drop table if exists ot1, ot2, it1, it2;
+CREATE TABLE ot1(a INTEGER);
+INSERT INTO ot1 VALUES(5), (8);
+CREATE TABLE it2(a INTEGER);
+INSERT INTO it2 VALUES(9), (5), (1), (8);
+CREATE TABLE it3(a INTEGER);
+INSERT INTO it3 VALUES(7), (1), (0), (5), (1), (4);
+CREATE TABLE ot4(a INTEGER);
+INSERT INTO ot4 VALUES(1), (3), (5), (7), (9), (7), (3), (1);
+SELECT * FROM ot1,ot4
+WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
+FROM it2,it3);
+a a
+5 1
+8 1
+5 5
+8 5
+5 7
+8 7
+5 7
+8 7
+5 1
+8 1
+explain SELECT * FROM ot1,ot4
+WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
+FROM it2,it3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 2
+1 PRIMARY ot4 ALL NULL NULL NULL NULL 8 Using join buffer (flat, BNL join)
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED it2 ALL NULL NULL NULL NULL 4
+2 MATERIALIZED it3 ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
+DROP TABLE IF EXISTS ot1, ot4, it2, it3;
+#
+# Bug#729039: NULL keys used to evaluate subquery
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (NULL), (1), (NULL), (2);
+CREATE TABLE t2 (a int, INDEX idx(a)) ;
+INSERT INTO t2 VALUES (NULL), (1), (NULL);
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a);
+a
+1
+EXPLAIN
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+a
+1
+EXPLAIN
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
+DROP TABLE t1,t2;
+#
+# BUG#752992: Wrong results for a subquery with 'semijoin=on'
+#
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
+EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 3
+1 PRIMARY it eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index
+1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; FirstMatch(it)
+SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+pk i
+11 0
+12 5
+15 0
+SET join_cache_level=@save_join_cache_level;
+DROP table t1,t2;
+#
+# Bug#751350: crash with pushed condition for outer references when
+# there should be none of such conditions
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0),(0,0);
+set @optimizer_switch_save=@@optimizer_switch;
+set @@optimizer_switch='semijoin=off,materialization=on,in_to_exists=on';
+EXPLAIN
+SELECT b FROM t1
+WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT b FROM t1
+WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+GROUP BY b;
+b
+0
+set @@optimizer_switch=@optimizer_switch_save;
+DROP TABLE t1;
+#
# Bug #11765713 58705:
# OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES
# CREATED BY OPT_SUM_QUERY
@@ -5197,12 +5557,11 @@ CREATE TABLE t1 (a INT, b INT, INDEX (a));
INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
-2 DERIVED t1 ref a a 5 const 1 Using where
+1 SIMPLE t1 ref a a 5 const 1
EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
-2 SUBQUERY t1 ref a a 5 const 1 Using where; Using index
+2 SUBQUERY t1 ref a a 5 const 1 Using index
DROP TABLE t1;
#
# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS)
@@ -5219,8 +5578,8 @@ WHERE EXISTS (SELECT DISTINCT f1_key FROM t2
WHERE f1_key != table2.f1_key AND f1_key >= table1.f1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY table1 ALL NULL NULL NULL NULL 2
-1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer
-2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index; Using temporary
+1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index
SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2
WHERE EXISTS (SELECT DISTINCT f1_key FROM t2
WHERE f1_key != table2.f1_key AND f1_key >= table1.f1);
@@ -5274,8 +5633,9 @@ SELECT col_int_nokey FROM ot
WHERE col_varchar_nokey IN
(SELECT col_varchar_key FROM it1 WHERE col_int_key IS 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
-2 DEPENDENT SUBQUERY it1 index_subquery idx_cvk_cik idx_cvk_cik 9 func,const 2 Using index; Using where
+1 PRIMARY ot system NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index
SELECT col_int_nokey FROM ot
WHERE col_varchar_nokey IN
(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL);
@@ -5286,8 +5646,9 @@ SELECT col_int_nokey FROM ot
WHERE (col_varchar_nokey, 'x') IN
(SELECT col_varchar_key, col_varchar_key2 FROM it2);
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 it2 index_subquery idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 func,const 1 Using index; Using where
+1 PRIMARY ot system NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index
SELECT col_int_nokey FROM ot
WHERE (col_varchar_nokey, 'x') IN
(SELECT col_varchar_key, col_varchar_key2 FROM it2);
@@ -5346,7 +5707,7 @@ FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
sq4_alias1.col_varchar_key = @var3 ) AS alias3;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE <derived2> system NULL NULL NULL NULL 0 const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
FROM t1 AS sq4_alias1
@@ -5370,7 +5731,7 @@ WHERE (c_sq1_alias1.col_int_nokey != @var2
OR c_sq1_alias1.pk != @var3));
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 c_sq1_alias1 system PRIMARY,col_varchar_key NULL NULL NULL 1
+2 DEPENDENT SUBQUERY c_sq1_alias1 system PRIMARY NULL NULL NULL 1
SELECT sq4_alias1.*
FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
@@ -5391,9 +5752,8 @@ FROM t2 AS c_sq1_alias1
WHERE (c_sq1_alias1.col_int_nokey != @var2
OR c_sq1_alias1.pk != @var3)) ) AS alias3;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
-2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
-3 DEPENDENT SUBQUERY c_sq1_alias1 system PRIMARY,col_varchar_key NULL NULL NULL 1
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+3 DEPENDENT SUBQUERY c_sq1_alias1 system PRIMARY NULL NULL NULL 1
SELECT * FROM ( SELECT sq4_alias1.*
FROM t1 AS sq4_alias1
WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
@@ -5406,3 +5766,527 @@ OR c_sq1_alias1.pk != @var3)) ) AS alias3;
pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
DROP TABLE t1,t2;
End of 5.2 tests
+#
+# BUG#779885: Crash in eliminate_item_equal with materialization=on in
+#
+CREATE TABLE t1 ( f1 int );
+INSERT INTO t1 VALUES (19), (20);
+CREATE TABLE t2 ( f10 varchar(32) );
+INSERT INTO t2 VALUES ('c'),('d');
+CREATE TABLE t3 ( f10 varchar(32) );
+INSERT INTO t3 VALUES ('a'),('b');
+SELECT *
+FROM t1
+WHERE
+( 't' ) IN (
+SELECT t3.f10
+FROM t3
+JOIN t2
+ON t2.f10 = t3.f10
+);
+f1
+DROP TABLE t1,t2,t3;
+#
+# BUG LP:813473: Wrong result with outer join + NOT IN subquery
+# This bug is a duplicate of Bug#11764086 whose test case is added below
+#
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (5),(6);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (20,9),(20,9);
+create table t3 (d int, e int);
+insert into t3 values (2, 9), (3,10);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+EXPLAIN
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b , t1.c) NOT IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b, t1.c) NOT IN (SELECT * from t3);
+b c
+9 NULL
+9 NULL
+SET optimizer_switch=@save_optimizer_switch;
+drop table t1, t2, t3;
+#
+# Bug#11764086: Null left operand to NOT IN in WHERE clause
+# behaves differently than real NULL
+#
+CREATE TABLE parent (id int);
+INSERT INTO parent VALUES (1), (2);
+CREATE TABLE child (parent_id int, other int);
+INSERT INTO child VALUES (1,NULL);
+# Offending query (c.parent_id is NULL for null-complemented rows only)
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id NOT IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+);
+id parent_id
+1 1
+2 NULL
+# Some syntactic variations with IS FALSE and IS NOT TRUE
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS NOT TRUE;
+id parent_id
+1 1
+2 NULL
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS FALSE;
+id parent_id
+1 1
+2 NULL
+DROP TABLE parent, child;
+# End of test for bug#11764086.
+#
+# Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET ||
+# BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0), (1);
+CREATE TABLE t2(
+b TEXT,
+c INT,
+PRIMARY KEY (b(1))
+);
+INSERT INTO t2 VALUES ('a', 2), ('b', 3);
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ORDER BY b
+);
+1
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+GROUP BY b
+);
+1
+DROP TABLE t1, t2;
+#
+# LP bug #826279: assertion failure with GROUP BY a result of subquery
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0), (0);
+CREATE TABLE t2 (a int, b int, c int);
+INSERT INTO t2 VALUES (10,7,0), (0,7,0);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,7), (0,7);
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+7 NULL
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+7 NULL
+7 10
+DROP TABLE t1,t2,t3;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+#
+# LP BUG#833777 Performance regression with deeply nested subqueries
+#
+create table t1 (a int not null, b char(10) not null);
+insert into t1 values (1, 'a');
+set @@optimizer_switch='in_to_exists=on,semijoin=off,materialization=off,subquery_cache=off';
+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)))))))))))))))))))))))))))));
+a
+1
+set @@optimizer_switch=@subselect_tmp;
+drop table t1;
+#
+# LP BUG#894397 Wrong result with in_to_exists, constant table , semijoin=OFF,materialization=OFF
+#
+CREATE TABLE t1 (a varchar(3));
+INSERT INTO t1 VALUES ('AAA'),('BBB');
+CREATE TABLE t2 (a varchar(3));
+INSERT INTO t2 VALUES ('CCC');
+set @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquery_cache=off';
+SELECT * FROM t1 WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.a < 'ZZZ');
+a
+set @@optimizer_switch=@subselect_tmp;
+drop table t1, t2;
+#
+# LP bug #859375: Assertion `0' failed in st_select_lex_unit::optimize
+# with view , UNION and prepared statement (rewriting fake_select
+# condition).
+#
+CREATE TABLE t1 ( f1 int NOT NULL, f4 varchar(1) NOT NULL) ;
+INSERT INTO t1 VALUES (6,'d'),(7,'y');
+CREATE TABLE t2 ( f1 int NOT NULL, f2 int NOT NULL) ;
+INSERT INTO t2 VALUES (10,7);
+CREATE VIEW v2 AS SELECT * FROM t2;
+PREPARE st1 FROM "
+ SELECT *
+ FROM t1
+ LEFT JOIN v2 ON ( v2.f2 = t1.f1 )
+ WHERE v2.f1 NOT IN (
+ SELECT 1 UNION
+ SELECT 247
+ )
+";
+EXECUTE st1;
+f1 f4 f1 f2
+7 y 10 7
+deallocate prepare st1;
+DROP VIEW v2;
+DROP TABLE t1,t2;
+#
+# LP bug #887458 Crash in subselect_union_engine::no_rows with
+# double UNION and join_cache_level=3,8
+# (IN/ALL/ANY optimizations should not be applied to fake_select)
+CREATE TABLE t2 ( a int, b varchar(1)) ;
+INSERT IGNORE INTO t2 VALUES (8,'y'),(8,'y');
+CREATE TABLE t1 ( b varchar(1)) ;
+INSERT IGNORE INTO t1 VALUES (NULL),(NULL);
+set @save_join_cache_level=@@join_cache_level;
+SET SESSION join_cache_level=3;
+SELECT *
+FROM t1, t2
+WHERE t2.b IN (
+SELECT 'm' UNION
+SELECT 'm'
+) OR t1.b <> SOME (
+SELECT 'v' UNION
+SELECT 't'
+);
+b a b
+set @@join_cache_level= @save_join_cache_level;
+drop table t1,t2;
+#
+# LP bug #885162 Got error 124 from storage engine with UNION inside
+# subquery and join_cache_level=3..8
+# (IN/ALL/ANY optimizations should not be applied to fake_select)
+#
+CREATE TABLE t1 (
+f1 varchar(1) DEFAULT NULL
+);
+INSERT INTO t1 VALUES ('c');
+set @save_join_cache_level=@@join_cache_level;
+SET SESSION join_cache_level=8;
+SELECT * FROM t1 WHERE t1.f1 IN ( SELECT 'k' UNION SELECT 'e' );
+f1
+set @@join_cache_level= @save_join_cache_level;
+drop table t1;
+#
+# LP BUG#747278 incorrect values of the NULL (no rows) single
+# row subquery requested via element_index() interface
+#
+CREATE TABLE t1 (f1a int, f1b int) ;
+INSERT IGNORE INTO t1 VALUES (1,1),(2,2);
+CREATE TABLE t2 ( f2 int);
+INSERT IGNORE INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (f3a int default 1, f3b int default 2);
+INSERT INTO t3 VALUES (1,1),(2,2);
+set @old_optimizer_switch = @@session.optimizer_switch;
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,subquery_cache=off,semijoin=off';
+SELECT (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+SELECT (SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+set @@session.optimizer_switch=@old_optimizer_switch;
+SELECT (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+SELECT (SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+select (null, null) = (null, null);
+(null, null) = (null, null)
+NULL
+SELECT (SELECT f3a, f3a FROM t3 where f3a > 3) = (0, 0);
+(SELECT f3a, f3a FROM t3 where f3a > 3) = (0, 0)
+NULL
+drop tables t1,t2,t3;
+#
+# LP BUG#825051 Wrong result with date/datetime and subquery with GROUP BY and in_to_exists
+#
+CREATE TABLE t1 (a date, KEY (a)) ;
+INSERT INTO t1 VALUES ('2009-01-01'),('2009-02-02');
+set @old_optimizer_switch = @@optimizer_switch;
+SET @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index
+2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 2 Using index
+SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+a
+2009-01-01
+2009-02-02
+SET @@optimizer_switch='semijoin=off,materialization=on,in_to_exists=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index
+2 MATERIALIZED t1 index NULL a 4 NULL 2 Using index
+SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+a
+2009-01-01
+2009-02-02
+set @@optimizer_switch=@old_optimizer_switch;
+drop table t1;
+#
+# LP BUG#908269 incorrect condition in case of subqueries depending
+# on constant tables
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 ( b INT ) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (4),(5);
+SET optimizer_switch='subquery_cache=off';
+SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) )
+1
+NULL
+SELECT ( SELECT b FROM t2 WHERE b = a OR b * 0) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR b * 0)
+1
+NULL
+SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR rand() * 0)
+1
+NULL
+drop table t1,t2,t3;
+set optimizer_switch=@subselect_tmp;
+#
+# LP BUG#905353 Wrong non-empty result with a constant table,
+# aggregate function in subquery, MyISAM or Aria
+#
+CREATE TABLE t1 ( a INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1);
+SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 );
+a
+drop table t1;
+#
+# LP BUG#985667 Wrong result with subquery in SELECT clause, and constant table in
+# main query and implicit grouping
+#
+CREATE TABLE t1 (f1 int) engine=MyISAM;
+INSERT INTO t1 VALUES (7),(8);
+CREATE TABLE t2 (f2 int, f3 varchar(1)) engine=MyISAM;
+INSERT INTO t2 VALUES (3,'f');
+EXPLAIN
+SELECT COUNT(f1), (SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2
+SELECT COUNT(f1), (SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 NULL
+EXPLAIN
+SELECT COUNT(f1), exists(SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2
+SELECT COUNT(f1), exists(SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 0
+EXPLAIN
+SELECT COUNT(f1), f2 > ALL (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2 Using where
+SELECT COUNT(f1), f2 > ALL (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 1
+EXPLAIN
+SELECT COUNT(f1), f2 IN (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2 Using where
+SELECT COUNT(f1), f2 IN (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 0
+drop table t1,t2;
+#
+# LP BUG#1002079 Server crashes in Item_singlerow_subselect::val_int with constant table,
+# HAVING, UNION in subquery
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (7),(0);
+CREATE TABLE t2 (b INT);
+EXPLAIN
+SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
+f1 f2
+drop table t1,t2;
+#
+# LP BUG#1008686 Server crashes in subselect_union_engine::no_rows on SELECT with impossible
+# WHERE and UNION in HAVING
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(7);
+EXPLAIN
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 0 HAVING a NOT IN ( SELECT 2 UNION SELECT 5 ) OR min_a != 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 NULL NULL NULL NULL NULL NULL NULL No tables used
+3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 0 HAVING a NOT IN ( SELECT 2 UNION SELECT 5 ) OR min_a != 1;
+min_a a
+EXPLAIN
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 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 ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 2 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 1;
+min_a a
+drop table t1;
+#
+# MDEV-367: Different results with and without subquery_cache on
+# a query with a constant NOT IN condition
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2),(3);
+set @mdev367_optimizer_switch = @@optimizer_switch;
+set optimizer_switch = 'subquery_cache=on';
+SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
+a
+SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
+a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
+1 NULL
+2 NULL
+3 NULL
+set optimizer_switch=@mdev367_optimizer_switch;
+set optimizer_switch = 'subquery_cache=off';
+SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
+a
+SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
+a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
+1 NULL
+2 NULL
+3 NULL
+set optimizer_switch=@mdev367_optimizer_switch;
+DROP TABLE t1;
+#
+# MDEV-521 single value subselect transformation problem
+#
+CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('u1'),('u2');
+SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) );
+f1
+u1
+u2
+FLUSH TABLES;
+SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) );
+f1
+u1
+u2
+DROP TABLE t1;
+# return optimizer switch changed in the beginning of this test
+set optimizer_switch=@subselect_tmp;
diff --git a/mysql-test/r/subselect2.result b/mysql-test/r/subselect2.result
index 27ec0ccfc0f..a7689c37a0a 100644
--- a/mysql-test/r/subselect2.result
+++ b/mysql-test/r/subselect2.result
@@ -1,4 +1,6 @@
drop table if exists t1, t2, t3, t4;
+set @subselect2_test_tmp=@@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
CREATE TABLE t1
(
DOCID VARCHAR(32)BINARY NOT NULL
@@ -123,14 +125,14 @@ DOCID DOCNAME DOCTYPEID FOLDERID AUTHOR CREATED TITLE SUBTITLE DOCABSTRACT PUBLI
c373e9f5ad07993f3859444553544200 Last Discussion c373e9f5ad079174ff17444553544200 c373e9f5ad0796c0eca4444553544200 Goldilocks 2003-06-09 11:21:06 Title: Last Discussion NULL Setting new abstract and keeping doc checked out 2003-06-09 10:51:26 2003-06-09 10:51:26 NULL NULL NULL 03eea05112b845949f3fd03278b5fe43 2003-06-09 11:21:06 admin 0 NULL Discussion NULL NULL
EXPLAIN SELECT t2.*, t4.DOCTYPENAME, t1.CONTENTSIZE,t1.MIMETYPE FROM t2 INNER JOIN t4 ON t2.DOCTYPEID = t4.DOCTYPEID LEFT OUTER JOIN t1 ON t2.DOCID = t1.DOCID WHERE t2.FOLDERID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t3.FOLDERNAME = 'Level1') AND t3.FOLDERNAME = 'Level2') AND t3.FOLDERNAME = 'Level3') AND t3.FOLDERNAME = 'CopiedFolder') AND t3.FOLDERNAME = 'Movie Reviews') AND t2.DOCNAME = 'Last Discussion';
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 ALL DDOCTYPEID_IDX NULL NULL NULL 9 Using where
+1 PRIMARY t2 ALL DDOCTYPEID_IDX,DFOLDERID_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
+1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t2.FOLDERID 1 Using where
+1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
+1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
+1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
+1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
drop table t1, t2, t3, t4;
CREATE TABLE t1 (a int(10) , PRIMARY KEY (a)) Engine=InnoDB;
INSERT INTO t1 VALUES (1),(2);
@@ -144,3 +146,56 @@ and t2.a='1' AND t1.a=t3.b) > 0;
a
2
DROP TABLE t1,t2,t3;
+#
+# Bug #902356: DISTINCT in materialized subquery
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, a int, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0, 4), (8, 6);
+CREATE TABLE t2 (pk int PRIMARY KEY, a int, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (0, 4), (8, 6);
+CREATE TABLE t3 (b INT, KEY(b));
+INSERT INTO t3 VALUES (7), (0), (4), (2);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SET @tmp_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='materialization=on,in_to_exists=on';
+EXPLAIN
+SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM t1) OR a = b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index a a 5 NULL 2 Using index
+1 PRIMARY t3 index b b 5 NULL 4 Using where; Using index; Using join buffer (flat, BNL join)
+2 MATERIALIZED t1 index PRIMARY,a a 5 NULL 2 Using index
+SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM t1) OR a = b;
+pk a b
+0 4 4
+EXPLAIN
+SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM v1) OR a = b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index a a 5 NULL 2 Using index
+1 PRIMARY t3 index b b 5 NULL 4 Using where; Using index; Using join buffer (flat, BNL join)
+2 MATERIALIZED t1 index PRIMARY,a a 5 NULL 2 Using index
+SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM v1) OR a = b;
+pk a b
+0 4 4
+SET optimizer_switch=@tmp_optimizer_switch;
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# MDEV-567: Wrong result from a query with correlated subquery if ICP is allowed
+#
+CREATE TABLE t1 (a int, b int, INDEX idx(a));
+INSERT INTO t1 VALUES (9,0), (7,1), (1,9), (7,3), (2,1);
+CREATE TABLE t2 (a int, b int, INDEX idx(a));
+INSERT INTO t2 VALUES (2,1), (6,4), (7,6), (9,4);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (1,0), (1,1), (1,3);
+SELECT * FROM t3
+WHERE a = (SELECT COUNT(DISTINCT t2.b) FROM t1, t2
+WHERE t1.a = t2.a AND t2.a BETWEEN 7 AND 9
+AND t3.b = t1.b
+GROUP BY t1.b);
+a b
+1 0
+1 1
+1 3
+DROP TABLE t1, t2, t3;
+set optimizer_switch=@subselect2_test_tmp;
diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result
index 468f939c943..1a91f65b40c 100644
--- a/mysql-test/r/subselect3.result
+++ b/mysql-test/r/subselect3.result
@@ -1,4 +1,7 @@
-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 @subselect3_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on';
+set join_cache_level=1;
create table t1 (oref int, grp int, ie int) ;
insert into t1 (oref, grp, ie) values
(1, 1, 1),
@@ -27,19 +30,19 @@ 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
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using temporary
Warnings:
Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref`,<in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`))))))) AS `Z` from `test`.`t2`
explain extended
select a, oref from t2
where a in (select max(ie) from t1 where oref=t2.oref group by grp);
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
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using temporary
Warnings:
Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having (<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having (<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`))))))
select a, oref, a in (
select max(ie) from t1 where oref=t2.oref group by grp union
select max(ie) from t1 where oref=t2.oref group by grp
@@ -63,12 +66,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
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using temporary
Warnings:
-Note 1003 select <in_optimizer>(`test`.`t3`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = 4) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t3`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))) AS `a in (select max(ie) from t1 where oref=4 group by grp)` from `test`.`t3`
+Note 1003 select <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = 4) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t3`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`))))))) AS `a in (select max(ie) from t1 where oref=4 group by grp)` from `test`.`t3`
+set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2, t3;
create table t1 (a int, oref int, key(a));
insert into t1 values
@@ -77,6 +83,7 @@ insert into t1 values
(2, 3),
(2, NULL),
(3, NULL);
+insert into t1 values (5, 7), (8, 9), (4, 1);
create table t2 (a int, oref int);
insert into t2 values (1, 1), (2,2), (NULL, 3), (NULL, 4);
select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
@@ -92,7 +99,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`.`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
@@ -102,6 +109,7 @@ Variable_name Value
Handler_read_rnd_next 5
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
@@ -116,10 +124,12 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
-Handler_read_rnd_next 29
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 50
select 'No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.' Z;
Z
No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.
+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 +167,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 `test`.`t1`.`a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond(((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and (`test`.`t2`.`a` = `test`.`t1`.`b`)) having trigcond(<is_not_null_test>(`test`.`t1`.`a`))))) AS `Z` from `test`.`t3`
drop table t1, t2, t3;
create table t1 (a int NOT NULL, b int NOT NULL, key(a));
insert into t1 values
@@ -185,7 +195,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 `test`.`t1`.`a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`)) and (`test`.`t2`.`a` = `test`.`t1`.`b`))))) AS `Z` from `test`.`t3`
drop table t1,t2,t3;
create table t1 (oref int, grp int);
insert into t1 (oref, grp) values
@@ -206,10 +216,10 @@ 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
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
Warnings:
Note 1276 Field or reference 't2.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref`,<in_optimizer>(`test`.`t2`.`a`,<exists>(select count(0) from `test`.`t1` group by `test`.`t1`.`grp` having ((`test`.`t1`.`grp` = `test`.`t2`.`oref`) and trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(count(0))))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select count(0) from `test`.`t1` group by `test`.`t1`.`grp` having ((`test`.`t1`.`grp` = `test`.`t2`.`oref`) and trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(count(0)))))))) AS `Z` from `test`.`t2`
drop table t1, t2;
create table t1 (a int, b int, primary key (a));
insert into t1 values (1,1), (3,1),(100,1);
@@ -241,7 +251,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 100.00 Using where; Full scan on NULL key
Warnings:
Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`)))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`))))))) AS `Z` from `test`.`t2`
select a,b, oref, (a,b) in (select a,b from t1 where c=t2.oref) Z from t2;
a b oref Z
NULL 1 100 0
@@ -255,10 +265,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`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(select `test`.`t1`.`a`,`test`.`t1`.`b` from `test`.`t1` join `test`.`t4` where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`)))))) AS `Z` from `test`.`t2`
select a,b, oref,
(a,b) in (select a,b from t1,t4 where c=t2.oref) Z
from t2;
@@ -303,7 +313,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 index_subquery idx idx 5 func 4 100.00 Using where; Full scan on NULL key
Warnings:
Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`)))))) AS `Z` from `test`.`t2` where ((`test`.`t2`.`b` = 10) and (`test`.`t2`.`a` = 10))
+Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`))))))) AS `Z` from `test`.`t2` where ((`test`.`t2`.`a` = 10) and (`test`.`t2`.`b` = 10))
drop table t1, t2;
create table t1 (oref char(4), grp int, ie int);
insert into t1 (oref, grp, ie) values
@@ -337,8 +347,8 @@ dd NULL 0
bb NULL NULL
select oref, a from t2 where a in (select ie from t1 where oref=t2.oref);
oref a
-ff 2
aa 1
+ff 2
select oref, a from t2 where a not in (select ie from t1 where oref=t2.oref);
oref a
bb 2
@@ -457,7 +467,7 @@ 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
+2 DEPENDENT SUBQUERY t1 ref idx idx 5 test.t2.oref 2 Using where; Using temporary
select oref, a,
a in (select min(ie) from t1 where oref=t2.oref
group by grp having min(ie) > 1) Z
@@ -515,8 +525,8 @@ aa 1 1 1
dd 1 NULL 0
select oref, a, b from t2 where (a,b) in (select ie1,ie2 from t1 where oref=t2.oref);
oref a b
-ff 2 2
aa 1 1
+ff 2 2
select oref, a, b from t2 where (a,b) not in (select ie1,ie2 from t1 where oref=t2.oref);
oref a b
bb 2 1
@@ -573,7 +583,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 index_subquery idx idx 5 func 4 100.00 Using where; Full scan on NULL key
Warnings:
Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`)))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`))))))) AS `Z` from `test`.`t2`
drop table t1,t2;
create table t1 (oref char(4), grp int, ie int primary key);
insert into t1 (oref, grp, ie) values
@@ -618,7 +628,7 @@ 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
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 Using where; Using temporary
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
@@ -692,6 +702,7 @@ a MAX(b) test
2 3 h
3 4 i
DROP TABLE t1, t2;
+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 +714,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 `test`.`t1`.`a` from `test`.`t1` where trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) having trigcond(<is_not_null_test>(`test`.`t1`.`a`))))))))
SELECT a FROM t1, t2 WHERE a=b AND (b NOT IN (SELECT a FROM t1));
a
SELECT a FROM t1, t2 WHERE a=b AND (b NOT IN (SELECT a FROM t1 WHERE a > 4));
@@ -724,7 +735,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 test.t2.id 1 Using where
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 +770,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 +791,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,
@@ -823,11 +844,16 @@ 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
+# 2nd and 3rd columns should be same
+EXPLAIN SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 12), ROW(11, 12) IN (SELECT MAX(x), 12) FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
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
+1 0 0
+2 0 0
11 1 1
DROP TABLE t1;
# both columns should be same
@@ -864,11 +890,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 (select count(`test`.`t1`.`a`) from (select count(`test`.`t1`.`b`) AS `COUNT(b)` from `test`.`t1`) `x` group by `test`.`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 +963,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 +979,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 +996,499 @@ 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;
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
+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 t11 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort; Start temporary
+1 PRIMARY t12 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t21 ALL NULL NULL NULL NULL 26 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
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t11, t12, t21, t22;
+create table t1(a int);
+insert into t1 values (0),(1);
+set @@optimizer_switch='firstmatch=off,materialization=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 Z ALL NULL NULL NULL NULL 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+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=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
+explain select * from t1 where 2 in (select a from t0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 11 Using where; FirstMatch
+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;
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+explain select * from (select a from t0) X where a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11
+1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(<derived2>); Using join buffer (flat, BNL join)
+2 DERIVED t0 ALL NULL NULL NULL NULL 11
+drop table t0, t1;
+set optimizer_switch=@tmp_optimizer_switch;
+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 t1 range kp1 kp1 5 NULL 48 Using where; Using index; LooseScan
+1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
+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 Using where
+1 PRIMARY t1 ref kp1 kp1 5 test.t3.a 1 Using where
+1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index; FirstMatch(t3)
+drop table t1, t3, t4;
+set @@optimizer_switch=@save_optimizer_switch;
+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 where a+1 < 10000 + A.a + B.a +C.a+D.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY A ALL NULL NULL NULL NULL 10
+1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+1 PRIMARY E ALL NULL NULL NULL NULL 5 Start temporary; Using join buffer (flat, BNL join)
+1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY C 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 where a+1 < 10000 + A.a + B.a +C.a+D.a);
+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 <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t3 ref a a 5 test.t2.a 1
+2 MATERIALIZED 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
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary; 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
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary; 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
+1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; Start temporary; 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
+1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; Start temporary; 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
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+drop table t1;
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
+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 t2 ALL NULL NULL NULL NULL 10 Using where; Start temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ref a a 5 test.t2.a 10 End temporary
+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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
+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 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 10 Using where
+2 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 10 Using where; 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 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 10 Using where
+2 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 10 Using where; 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 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 10 Using where
+2 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 10 Using where; 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 t2 ALL NULL NULL NULL NULL 10 Using where; Start temporary
+1 PRIMARY t3 ref a a 5 test.t2.a 10 End temporary
+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 t4 ALL NULL NULL NULL NULL 10 Using where; Start temporary
+1 PRIMARY t3 ref a a 5 test.t4.x 10 Using where; End temporary
+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 t1 ref a a 5 const 8 Using index; LooseScan
+1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
+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 t1 ref a a 5 const 8 Using index; LooseScan
+1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
+drop table t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
+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,materialization=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 t2 ALL NULL NULL NULL NULL 100 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+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 t2 ALL NULL NULL NULL NULL 100 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+set @@optimizer_search_depth=@save_optimizer_search_depth;
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t0, t1, t2;
+set @@optimizer_switch='materialization=off';
+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 t1 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t0); Using join buffer (flat, BNL join)
+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 t1 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t0); Using join buffer (flat, BNL join)
+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 X ALL NULL NULL NULL NULL 6 Using where
+1 PRIMARY Y ALL NULL NULL NULL NULL 6 Using where
+1 PRIMARY Z ALL NULL NULL NULL NULL 6 Using where; FirstMatch(t1)
+drop table t0,t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
+
+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:
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=off';
+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 cona ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary
+1 PRIMARY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00 Using where
+1 PRIMARY a eq_ref PRIMARY PRIMARY 4 test.c.idObj 1 100.00 Using index; End temporary
+Warnings:
+Note 1003 select `test`.`a`.`idIndividual` AS `idIndividual` from `test`.`t1` `a` semi join (`test`.`t3` `cona` join `test`.`t2` `c`) where ((`test`.`cona`.`postalStripped` = 'T2H3B2') and (`test`.`a`.`idIndividual` = `test`.`c`.`idObj`) and (`test`.`c`.`idContact` = `test`.`cona`.`idContact`))
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1,t2,t3;
+#
+# BUG#47367 Crash in Name_resolution_context::process_error
+#
+SET SESSION optimizer_switch = 'semijoin=off';
+CREATE TABLE t1 (f1 INTEGER);
+CREATE TABLE t2 LIKE t1;
+CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t1 WHERE f1 IN (SELECT f1 FROM t2); END|
+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;
+#
+# fix of LP BUG#824425 (prohibiting subqueries in row in
+# left part of IN/ALL/ANY)
+#
+CREATE TABLE t1 ( a int) ;
+INSERT INTO t1 VALUES (20),(30);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (3),(9);
+CREATE TABLE t3 ( a int, b int) ;
+INSERT INTO t3 VALUES (20,5),(30,6);
+set @optimizer_switch_save=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=OFF,in_to_exists=OFF,materialization=ON,partial_match_rowid_merge=ON,partial_match_table_scan=OFF';
+SELECT * FROM t1
+WHERE (
+( SELECT a FROM t2 WHERE a = 9 )
+) NOT IN (
+SELECT b
+FROM t3
+);
+a
+20
+30
+explain extended
+SELECT * FROM t1
+WHERE (
+( SELECT a FROM t2 WHERE a = 9 )
+) NOT IN (
+SELECT b
+FROM t3
+);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 100.00
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (not(<expr_cache><(select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t2`.`a` = 9))>(<in_optimizer>((select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t2`.`a` = 9)),(select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t2`.`a` = 9)) in ( <materialize> (select `test`.`t3`.`b` from `test`.`t3` ), <primary_index_lookup>(9 in <temporary table> on distinct_key where ((9 = `<subquery3>`.`b`))))))))
+SELECT * FROM t1
+WHERE (
+( SELECT a FROM t2 WHERE a = 9 ),
+( SELECT a FROM t2 WHERE a = 3 )
+) NOT IN (
+SELECT b , a
+FROM t3
+);
+ERROR 42000: This version of MySQL doesn't yet support 'SUBQUERY in ROW in left expression of IN/ALL/ANY'
+set optimizer_switch=@optimizer_switch_save;
+drop table t1,t2,t3;
+set @@optimizer_switch=@subselect3_tmp;
diff --git a/mysql-test/r/subselect3_jcl6.result b/mysql-test/r/subselect3_jcl6.result
new file mode 100644
index 00000000000..1ec55f55c83
--- /dev/null
+++ b/mysql-test/r/subselect3_jcl6.result
@@ -0,0 +1,1510 @@
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+set @join_cache_level_for_subselect3_test=@@join_cache_level;
+drop table if exists t0, t1, t2, t3, t4, t5, t11, t12, t21, t22;
+set @subselect3_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on';
+set join_cache_level=@join_cache_level_for_subselect3_test;
+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
+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
+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
+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);
+insert into t1 values (5, 7), (8, 9), (4, 1);
+create table t2 (a int, oref int);
+insert into t2 values (1, 1), (2,2), (NULL, 3), (NULL, 4);
+select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
+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 5
+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_deleted 0
+Handler_read_rnd_next 50
+select 'No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.' Z;
+Z
+No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.
+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); Key-ordered Rowid-ordered scan
+Warnings:
+Note 1276 Field or reference 'test.t3.oref' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<expr_cache><`test`.`t3`.`a`,`test`.`t3`.`oref`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond(((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and (`test`.`t2`.`a` = `test`.`t1`.`b`)) having trigcond(<is_not_null_test>(`test`.`t1`.`a`))))) AS `Z` from `test`.`t3`
+drop table t1, t2, t3;
+create table t1 (a int NOT NULL, b int NOT NULL, key(a));
+insert into t1 values
+(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); Key-ordered Rowid-ordered scan
+Warnings:
+Note 1276 Field or reference 'test.t3.oref' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<expr_cache><`test`.`t3`.`a`,`test`.`t3`.`oref`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`)) and (`test`.`t2`.`a` = `test`.`t1`.`b`))))) AS `Z` from `test`.`t3`
+drop table t1,t2,t3;
+create table t1 (oref int, grp int);
+insert into t1 (oref, grp) values
+(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
+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`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`))))))) AS `Z` from `test`.`t2`
+select a,b, oref, (a,b) in (select a,b from t1 where c=t2.oref) Z from t2;
+a b oref Z
+NULL 1 100 0
+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`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(select `test`.`t1`.`a`,`test`.`t1`.`b` from `test`.`t1` join `test`.`t4` where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`)))))) AS `Z` from `test`.`t2`
+select a,b, oref,
+(a,b) in (select a,b from t1,t4 where c=t2.oref) Z
+from t2;
+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`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`))))))) AS `Z` from `test`.`t2` where ((`test`.`t2`.`a` = 10) and (`test`.`t2`.`b` = 10))
+drop table t1, t2;
+create table t1 (oref char(4), grp int, ie int);
+insert into t1 (oref, grp, ie) values
+('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
+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`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`))))))) AS `Z` from `test`.`t2`
+drop table t1,t2;
+create table t1 (oref char(4), grp int, ie int primary key);
+insert into t1 (oref, grp, ie) values
+('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
+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 @@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 `test`.`t1`.`a` from `test`.`t1` where trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) having trigcond(<is_not_null_test>(`test`.`t1`.`a`))))))))
+SELECT a FROM t1, t2 WHERE a=b AND (b NOT IN (SELECT a FROM t1));
+a
+SELECT a FROM t1, t2 WHERE a=b AND (b NOT IN (SELECT a FROM t1 WHERE a > 4));
+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 test.t2.id 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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
+EXPLAIN SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 12), ROW(11, 12) IN (SELECT MAX(x), 12) FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+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 0
+2 0 0
+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 (select count(`test`.`t1`.`a`) from (select count(`test`.`t1`.`b`) AS `COUNT(b)` from `test`.`t1`) `x` group by `test`.`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;
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
+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 t11 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort; Start temporary
+1 PRIMARY t12 hash_ALL NULL #hash#$hj 4 test.t11.a 8 Using where; Using join buffer (flat, BNLH join)
+1 PRIMARY t22 hash_ALL NULL #hash#$hj 4 test.t11.a 26 Using where; End temporary; Using join buffer (incremental, BNLH join)
+1 PRIMARY t21 hash_ALL NULL #hash#$hj 4 test.t11.a 26 Using where; Using join buffer (incremental, BNLH 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
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t11, t12, t21, t22;
+create table t1(a int);
+insert into t1 values (0),(1);
+set @@optimizer_switch='firstmatch=off,materialization=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 Z hash_ALL NULL #hash#$hj 5 test.Y.a 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNLH join)
+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=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
+explain select * from t1 where 2 in (select a from t0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 11 Using where; FirstMatch
+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;
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+explain select * from (select a from t0) X where a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11
+1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(<derived2>); Using join buffer (flat, BNL join)
+2 DERIVED t0 ALL NULL NULL NULL NULL 11
+drop table t0, t1;
+set optimizer_switch=@tmp_optimizer_switch;
+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 t1 range kp1 kp1 5 NULL 48 Using where; Using index; LooseScan
+1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
+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 Using where
+1 PRIMARY t1 ref kp1 kp1 5 test.t3.a 1 Using where
+1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index; FirstMatch(t3)
+drop table t1, t3, t4;
+set @@optimizer_switch=@save_optimizer_switch;
+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 where a+1 < 10000 + A.a + B.a +C.a+D.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY A ALL NULL NULL NULL NULL 10
+1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+1 PRIMARY E ALL NULL NULL NULL NULL 5 Using where; Start temporary; Using join buffer (incremental, BNL join)
+1 PRIMARY D hash_ALL NULL #hash#$hj 5 test.E.a 10 Using where; Using join buffer (incremental, BNLH join)
+1 PRIMARY C 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 where a+1 < 10000 + A.a + B.a +C.a+D.a);
+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 <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t3 ref a a 5 test.t2.a 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+2 MATERIALIZED 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 Using where
+1 PRIMARY t1 hash_ALL NULL #hash#$hj 4 test.t2.a 4 Using where; Start temporary; End temporary; Using join buffer (flat, BNLH 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 Using where
+1 PRIMARY t2 hash_ALL NULL #hash#$hj 5 test.t2.a 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNLH 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
+1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; Start temporary; 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
+1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; Start temporary; 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 Using where
+1 PRIMARY t1 hash_ALL NULL #hash#$hj 6 test.t1.a 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNLH join)
+drop table t1;
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
+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 t2 ALL NULL NULL NULL NULL 10 Using where; Start temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ref a a 5 test.t2.a 10 End temporary; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
+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 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 10 Using where
+2 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 10 Using where; 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 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 10 Using where
+2 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 10 Using where; 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 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 10 Using where
+2 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 10 Using where; 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 t2 ALL NULL NULL NULL NULL 10 Using where; Start temporary
+1 PRIMARY t3 ref a a 5 test.t2.a 10 End temporary; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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 t4 ALL NULL NULL NULL NULL 10 Using where; Start temporary
+1 PRIMARY t3 ref a a 5 test.t4.x 10 Using where; End temporary; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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 t1 ref a a 5 const 8 Using index; LooseScan
+1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
+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 t1 ref a a 5 const 8 Using index; LooseScan
+1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
+drop table t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
+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,materialization=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 Using where
+1 PRIMARY t2 hash_ALL NULL #hash#$hj 10 test.t1.a,test.t1.b 100 Using where; Start temporary; End temporary; Using join buffer (flat, BNLH join)
+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 Using where
+1 PRIMARY t2 hash_ALL NULL #hash#$hj 10 test.t1.a,test.t1.b 100 Using where; Start temporary; End temporary; Using join buffer (flat, BNLH join)
+set @@optimizer_search_depth=@save_optimizer_search_depth;
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t0, t1, t2;
+set @@optimizer_switch='materialization=off';
+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 t1 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t0); Using join buffer (flat, BNL join)
+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 t1 ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t0); Using join buffer (flat, BNL join)
+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 X ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY Y ALL NULL NULL NULL NULL 6 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY Z ALL NULL NULL NULL NULL 6 Using where; FirstMatch(t1); Using join buffer (incremental, BNL join)
+drop table t0,t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
+
+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:
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=off';
+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 cona ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary
+1 PRIMARY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 PRIMARY a eq_ref PRIMARY PRIMARY 4 test.c.idObj 1 100.00 Using index; End temporary
+Warnings:
+Note 1003 select `test`.`a`.`idIndividual` AS `idIndividual` from `test`.`t1` `a` semi join (`test`.`t3` `cona` join `test`.`t2` `c`) where ((`test`.`cona`.`postalStripped` = 'T2H3B2') and (`test`.`a`.`idIndividual` = `test`.`c`.`idObj`) and (`test`.`c`.`idContact` = `test`.`cona`.`idContact`))
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1,t2,t3;
+#
+# BUG#47367 Crash in Name_resolution_context::process_error
+#
+SET SESSION optimizer_switch = 'semijoin=off';
+CREATE TABLE t1 (f1 INTEGER);
+CREATE TABLE t2 LIKE t1;
+CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t1 WHERE f1 IN (SELECT f1 FROM t2); END|
+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;
+#
+# fix of LP BUG#824425 (prohibiting subqueries in row in
+# left part of IN/ALL/ANY)
+#
+CREATE TABLE t1 ( a int) ;
+INSERT INTO t1 VALUES (20),(30);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (3),(9);
+CREATE TABLE t3 ( a int, b int) ;
+INSERT INTO t3 VALUES (20,5),(30,6);
+set @optimizer_switch_save=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=OFF,in_to_exists=OFF,materialization=ON,partial_match_rowid_merge=ON,partial_match_table_scan=OFF';
+SELECT * FROM t1
+WHERE (
+( SELECT a FROM t2 WHERE a = 9 )
+) NOT IN (
+SELECT b
+FROM t3
+);
+a
+20
+30
+explain extended
+SELECT * FROM t1
+WHERE (
+( SELECT a FROM t2 WHERE a = 9 )
+) NOT IN (
+SELECT b
+FROM t3
+);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 100.00
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (not(<expr_cache><(select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t2`.`a` = 9))>(<in_optimizer>((select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t2`.`a` = 9)),(select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t2`.`a` = 9)) in ( <materialize> (select `test`.`t3`.`b` from `test`.`t3` ), <primary_index_lookup>(9 in <temporary table> on distinct_key where ((9 = `<subquery3>`.`b`))))))))
+SELECT * FROM t1
+WHERE (
+( SELECT a FROM t2 WHERE a = 9 ),
+( SELECT a FROM t2 WHERE a = 3 )
+) NOT IN (
+SELECT b , a
+FROM t3
+);
+ERROR 42000: This version of MySQL doesn't yet support 'SUBQUERY in ROW in left expression of IN/ALL/ANY'
+set optimizer_switch=@optimizer_switch_save;
+drop table t1,t2,t3;
+set @@optimizer_switch=@subselect3_tmp;
+set join_cache_level=default;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 2
+set @@optimizer_switch=@save_optimizer_switch;
+set @join_cache_level_for_subselect3_test=NULL;
diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result
index 952717c5c37..83716429efe 100644
--- a/mysql-test/r/subselect4.result
+++ b/mysql-test/r/subselect4.result
@@ -1,3 +1,8 @@
+drop table if exists t1,t2,t3,t4,t5,t6;
+set @subselect4_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='semijoin_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
#
# Bug #46791: Assertion failed:(table->key_read==0),function unknown
# function,file sql_base.cc
@@ -13,9 +18,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 +56,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 ALL b NULL NULL NULL 2 Range checked for each record (index map: 0x2)
# should return 0 rows
SELECT
(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
@@ -113,6 +118,8 @@ CREATE TABLE t4 ( a INT );
INSERT INTO t4 VALUES (1), (2), (3);
CREATE TABLE t5 ( a INT );
INSERT INTO t5 VALUES (NULL), (2);
+SET @old_optimizer_switch = @@session.optimizer_switch;
+SET SESSION optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off';
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
@@ -184,6 +191,7 @@ SELECT * FROM t1 WHERE NULL NOT IN ( SELECT c FROM t2 WHERE c = 1 AND c <> 1 );
a b
1 NULL
2 NULL
+SET SESSION optimizer_switch = @old_optimizer_switch;
DROP TABLE t1, t2, t3, t4, t5;
#
# Bug#58207: invalid memory reads when using default column value and
@@ -273,10 +281,2050 @@ EXPLAIN
SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk);
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 t2a eq_ref PRIMARY PRIMARY 8 const,test.t1.pk 2 Using where; Using index; Full scan on NULL key
+2 DEPENDENT SUBQUERY t2a eq_ref PRIMARY PRIMARY 8 const,test.t1.pk 1 Using where; Using index; Full scan on NULL key
SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk);
pk i
+0 10
+2 30
+3 40
drop table t1, t2a, t2b, t2c;
#
# 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><>((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><>((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><>((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_engine_condition_pushdown = @@session.engine_condition_pushdown;
+SET SESSION OPTIMIZER_SWITCH = 'materialization=off,semijoin=off,loosescan=off,firstmatch=off,mrr=on';
+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.engine_condition_pushdown = @old_engine_condition_pushdown;
+DROP TABLE t1;
+#
+# 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,in_to_exists=off,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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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;
+#
+# 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,in_to_exists=off,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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
+2 MATERIALIZED 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#716293: "Range checked for each record" is not used if condition refers to outside of subquery
+#
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, b int, `filler` char(200), key(a), key (b));
+insert into t2
+select A.a + 10*B.a + 100 * C.a, A.a + 10*B.a + 100 * C.a, 'filler' from t1 A, t1 B, t1 C;
+# The following must use "Range checked for each record" for table B
+explain
+select a,
+(select sum(X.a+B.b) from t1 X, t2 B where B.a=A.a or B.b=A.a)
+from t1 A;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY A ALL NULL NULL NULL NULL 10
+2 DEPENDENT SUBQUERY X ALL NULL NULL NULL NULL 10
+2 DEPENDENT SUBQUERY B ALL a,b NULL NULL NULL 1000 Range checked for each record (index map: 0x3)
+drop table t1, t2;
+#
+# BUG#723822: Crash in get_constant_key_infix with EXISTS ( SELECT .. DISTINCT )
+#
+CREATE TABLE t1 ( f1 int(11), f3 varchar(1)) ;
+INSERT INTO t1 VALUES ('8','c'),('5','f');
+ALTER TABLE t1 ADD KEY (f3,f1);
+CREATE TABLE t2 ( f4 varchar(1)) ;
+INSERT INTO t2 VALUES ('f'),('d');
+SELECT * FROM t2
+WHERE EXISTS (
+SELECT DISTINCT f3
+FROM t1
+WHERE f3 <= t2.f4
+);
+f4
+f
+d
+drop table t1,t2;
+#
+# LP BUG#718763 Second crash in select_describe() and materialization
+#
+CREATE TABLE t1 ( f1 int(11), f3 int(11), f10 varchar(1), KEY (f3)) ;
+INSERT INTO t1 VALUES ('28','6','m'),('29','4','c');
+CREATE TABLE t2 (f11 varchar(1)) ;
+INSERT INTO t2 VALUES ('f'),('d');
+SET @old_optimizer_switch = @@session.optimizer_switch;
+SET @@optimizer_switch = 'materialization=on,in_to_exists=off,semijoin=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE f3 = (
+SELECT t1.f3 FROM t1
+WHERE ( t1.f10 ) IN ( SELECT max(f11) FROM t2 GROUP BY f11 ));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref f3 f3 5 const 0 Using where
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+3 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using temporary
+SELECT * FROM t1
+WHERE f3 = (
+SELECT t1.f3 FROM t1
+WHERE ( t1.f10 ) IN ( SELECT max(f11) FROM t2 GROUP BY f11 ));
+f1 f3 f10
+EXPLAIN
+SELECT * FROM t1
+WHERE f3 = (
+SELECT f3 FROM t1
+WHERE ( f10, f10 ) IN ( SELECT max(f11), f11 FROM t2 GROUP BY f11 ));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref f3 f3 5 const 0 Using where
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+3 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using temporary
+SELECT * FROM t1
+WHERE f3 = (
+SELECT f3 FROM t1
+WHERE ( f10, f10 ) IN ( SELECT max(f11), f11 FROM t2 GROUP BY f11 ));
+f1 f3 f10
+SET SESSION optimizer_switch = @old_optimizer_switch;
+drop table t1,t2;
+#
+# LP BUG#715738: Wrong result with implicit grouping and empty result set
+#
+CREATE TABLE t1 (f1 int, f2 int);
+CREATE TABLE t2 (f3 int, f4 int not null, PRIMARY KEY (f3));
+set @save_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch = 'materialization=on,in_to_exists=off,semijoin=off';
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 MATERIALIZED t2 system NULL NULL NULL NULL 0 const row not found
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2);
+f1 f2
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 MATERIALIZED t2 system NULL NULL NULL NULL 0 const row not found
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2);
+f1 f2
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 MATERIALIZED t2 system NULL NULL NULL NULL 0 const row not found
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2);
+f1 f2
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2) as not_in;
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 MATERIALIZED t2 system NULL NULL NULL NULL 0 const row not found
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2);
+f1 f2
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 MATERIALIZED t2 system NULL NULL NULL NULL 0 const row not found
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2);
+f1 f2
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2) as not_in;
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) > 7) as not_in;
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) > 7) as not_in;
+not_in
+1
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) is null) as not_in;
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) is null) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2) as not_in;
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2) as not_in;
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2);
+f1 f2
+SET @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off';
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2);
+f1 f2
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2);
+f1 f2
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2);
+f1 f2
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2) as not_in;
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2);
+f1 f2
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2);
+f1 f2
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2) as not_in;
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) > 7) as not_in;
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) > 7) as not_in;
+not_in
+1
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) is null) as not_in;
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) is null) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2) as not_in;
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2) as not_in;
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2);
+f1 f2
+INSERT INTO t1 VALUES (1, 2);
+INSERT INTO t1 VALUES (3, 4);
+INSERT INTO t2 VALUES (5, 6);
+INSERT INTO t2 VALUES (7, 8);
+SET @@optimizer_switch = 'materialization=on,in_to_exists=off,semijoin=off';
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10);
+f1 f2
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2 WHERE f3 > 10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2 WHERE f3 > 10);
+f1 f2
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2 WHERE f3 > 10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2 WHERE f3 > 10);
+f1 f2
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10) as not_in;
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10);
+f1 f2
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2 WHERE f3 > 10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2 WHERE f3 > 10);
+f1 f2
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10) as not_in;
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) > 7) as not_in;
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) > 7) as not_in;
+not_in
+1
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) is null) as not_in;
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) is null) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2 WHERE f3 > 10) as not_in;
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2 WHERE f3 > 10) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2 WHERE f3 > 10) as not_in;
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2 WHERE f3 > 10) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10);
+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 No matching min/max row
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10);
+f1 f2
+SET @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off';
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10);
+f1 f2
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2 WHERE f3 > 10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2 WHERE f3 > 10);
+f1 f2
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2 WHERE f3 > 10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2 WHERE f3 > 10);
+f1 f2
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10) as not_in;
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10);
+f1 f2
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2 WHERE f3 > 10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2 WHERE f3 > 10);
+f1 f2
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10) as not_in;
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) > 7) as not_in;
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) > 7) as not_in;
+not_in
+1
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) is null) as not_in;
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) is null) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2 WHERE f3 > 10) as not_in;
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2 WHERE f3 > 10) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2 WHERE f3 > 10) as not_in;
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2 WHERE f3 > 10) as not_in;
+not_in
+NULL
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10);
+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 No matching min/max row
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10);
+f1 f2
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1,t2;
+#
+# LP BUG#613029 Wrong result with materialization and semijoin, and
+# valgrind warnings in Protocol::net_store_data with materialization
+# for implicit grouping
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+f2 int(11) NOT NULL,
+f3 varchar(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY f2 (f2));
+INSERT INTO t1 VALUES (1,9,'x');
+INSERT INTO t1 VALUES (2,5,'g');
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+f2 int(11) NOT NULL,
+f3 varchar(1) NOT NULL,
+PRIMARY KEY (pk),
+KEY f2 (f2));
+INSERT INTO t2 VALUES (1,7,'p');
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off';
+EXPLAIN
+SELECT t1.f3, MAX(t1.f2)
+FROM t1, t2
+WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system PRIMARY NULL NULL NULL 1
+1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1
+2 DEPENDENT SUBQUERY t1 index_subquery f2 f2 4 func 2 Using index
+SELECT t1.f3, MAX(t1.f2)
+FROM t1, t2
+WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1);
+f3 MAX(t1.f2)
+NULL NULL
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+EXPLAIN
+SELECT t1.f3, MAX(t1.f2)
+FROM t1, t2
+WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system PRIMARY NULL NULL NULL 1
+1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1
+2 MATERIALIZED t1 index NULL f2 4 NULL 2 Using index
+SELECT t1.f3, MAX(t1.f2)
+FROM t1, t2
+WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1);
+f3 MAX(t1.f2)
+NULL NULL
+TODO: add a test case for semijoin when the wrong result is fixed
+set @@optimizer_switch='materialization=off,semijoin=on';
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t2;
+#
+# LP BUG#777691 Wrong result with subqery in select list and subquery cache=off in maria-5.3
+#
+CREATE TABLE t1 ( f1 varchar(32)) ;
+INSERT INTO t1 VALUES ('b'),('x'),('c'),('x');
+CREATE TABLE t2 ( f2 int, f3 varchar(32)) ;
+INSERT INTO t2 VALUES (1,'x');
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off';
+EXPLAIN
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+f1 max_f2
+b NULL
+x 1
+c NULL
+x 1
+set @@optimizer_switch='materialization=on,in_to_exists=off,subquery_cache=off';
+EXPLAIN
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+f1 max_f2
+b NULL
+x 1
+c NULL
+x 1
+set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off';
+Even when t2 is not constant table, the result must be the same.
+INSERT INTO t2 VALUES (2,'y');
+EXPLAIN
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+f1 max_f2
+b NULL
+x 1
+c NULL
+x 1
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t2;
+#
+# LP BUG#641203 Query returns rows where no result is expected (impossible WHERE)
+#
+CREATE TABLE t1 (c1 varchar(1) DEFAULT NULL);
+CREATE TABLE t2 (c1 varchar(1) DEFAULT NULL);
+INSERT INTO t2 VALUES ('k'), ('d');
+CREATE TABLE t3 (c1 varchar(1) DEFAULT NULL);
+INSERT INTO t3 VALUES ('a'), ('b'), ('c');
+CREATE TABLE t4 (c1 varchar(1) primary key);
+INSERT INTO t4 VALUES ('k'), ('d');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+SET optimizer_switch='semijoin_with_cache=off';
+SET optimizer_switch='materialization=off';
+EXPLAIN
+SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
+c1 c1
+EXPLAIN
+SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
+c1 c1
+SET optimizer_switch='materialization=on';
+EXPLAIN
+SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2);
+c1 c1 c1
+EXPLAIN
+SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY t4 index NULL PRIMARY 3 NULL 2 Using index; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2);
+c1 c1
+SET optimizer_switch=@save_optimizer_switch;
+drop table t1, t2, t3, t4;
+#
+# LP BUG#675981 Assertion `cache != __null' failed in sub_select_cache()
+# on EXPLAIN
+#
+CREATE TABLE t1 (f1 int,f2 int) ;
+INSERT IGNORE INTO t1 VALUES ('2','5'),('2',NULL);
+CREATE TABLE t2 (f1 int, f5 int) ;
+INSERT IGNORE INTO t2 VALUES (1,0);
+CREATE TABLE t3 (f4 int) ;
+INSERT IGNORE INTO t3 VALUES (0),(0);
+set @@optimizer_switch='in_to_exists=on,materialization=off,semijoin=off';
+EXPLAIN
+SELECT * FROM t2
+WHERE f1 IN (SELECT t1.f2 FROM t1 JOIN t3 ON t3.f4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+drop table t1, t2, t3;
+#
+# LP BUG#680005 Second assertion `cache != __null' failed in
+# sub_select_cache() on EXPLAIN
+#
+CREATE TABLE t1 (f1 int,f2 int,f4 int,f6 int,KEY (f4)) ;
+INSERT IGNORE INTO t1 VALUES
+('1','5','1','0'),('2','1','1','0'),('2','2','2','0'),('0',NULL,'0','0'),
+('2','1','2','0'),('2','0','0','0'),('2','2','2','0'),('2','8','2','0'),
+('2','7','2','0'),('2','5','2','0'),('2',NULL,'1','0');
+CREATE TABLE t2 (f3 int) ;
+INSERT IGNORE INTO t2 VALUES ('7');
+CREATE TABLE t3 (f3 int) ;
+INSERT IGNORE INTO t3 VALUES ('2');
+EXPLAIN
+SELECT t1.f4
+FROM t2 JOIN t1 ON t1.f6
+WHERE
+( t1.f2 ) IN (SELECT SUBQUERY2_t1.f3
+FROM t3 AS SUBQUERY2_t1
+JOIN
+(t1 AS SUBQUERY2_t2
+JOIN
+t1 AS SUBQUERY2_t3 ON SUBQUERY2_t3.f1)
+ON SUBQUERY2_t3.f2)
+GROUP BY t1.f4 ORDER BY t1.f1 LIMIT 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1 Using temporary; Using filesort
+1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where
+2 DEPENDENT SUBQUERY SUBQUERY2_t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY SUBQUERY2_t2 index NULL f4 5 NULL 11 Using index
+2 DEPENDENT SUBQUERY SUBQUERY2_t3 ALL NULL NULL NULL NULL 11 Using where; Using join buffer (flat, BNL join)
+drop table t1, t2, t3;
+#
+# LP BUG#680038 bool close_thread_table(THD*, TABLE**):
+# Assertion `table->key_read == 0' failed in EXPLAIN
+#
+CREATE TABLE t1 (f1 int,f3 int,f4 int) ;
+INSERT IGNORE INTO t1 VALUES (NULL,1,0);
+CREATE TABLE t2 (f2 int,f4 int,f5 int) ;
+INSERT IGNORE INTO t2 VALUES (8,0,0),(5,0,0);
+CREATE TABLE t3 (f4 int,KEY (f4)) ;
+INSERT IGNORE INTO t3 VALUES (0),(0);
+set @@optimizer_switch='semijoin=off';
+EXPLAIN
+SELECT * FROM t1 WHERE
+(SELECT f2 FROM t2
+WHERE f4 <= ALL
+(SELECT max(SQ1_t1.f4)
+FROM t3 AS SQ1_t1 JOIN t3 AS SQ1_t3 ON SQ1_t3.f4
+GROUP BY SQ1_t1.f4));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+3 SUBQUERY SQ1_t1 index NULL f4 5 NULL 2 Using index; Using temporary
+3 SUBQUERY SQ1_t3 index f4 f4 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
+drop table t1, t2, t3;
+#
+# BUG#52317: Assertion failing in Field_varstring::store()
+# at field.cc:6833
+#
+CREATE TABLE t1 (i INTEGER);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (i INTEGER, KEY k(i));
+INSERT INTO t2 VALUES (1), (2);
+EXPLAIN
+SELECT i FROM t1 WHERE (1) NOT IN (SELECT i 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 index_subquery k k 5 const 2 Using index
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# LP BUG#680846: Crash in clear_tables() with subqueries
+#
+CREATE TABLE t1 (f3 int) ;
+INSERT IGNORE INTO t1 VALUES (0),(0);
+CREATE TABLE t2 (f1 int,f3 int,f4 varchar(32)) ;
+INSERT IGNORE INTO t2 VALUES (1,0,'f');
+EXPLAIN
+SELECT COUNT(t2.f3),
+(SELECT COUNT(f3) FROM t1 WHERE t2.f1) AS f9
+FROM t2 JOIN t1 ON t1.f3
+WHERE ('v') IN (SELECT f4 FROM t2)
+GROUP BY f9;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2
+SELECT COUNT(t2.f3),
+(SELECT COUNT(f3) FROM t1 WHERE t2.f1) AS f9
+FROM t2 JOIN t1 ON t1.f3
+WHERE ('v') IN (SELECT f4 FROM t2)
+GROUP BY f9;
+COUNT(t2.f3) f9
+EXPLAIN
+SELECT COUNT(t2.f3),
+(SELECT COUNT(f3) FROM t1 WHERE t2.f1) AS f9
+FROM t2 JOIN t1 ON t1.f3
+WHERE ('v') IN (SELECT f4 FROM t2)
+ORDER BY f9;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2
+SELECT COUNT(t2.f3),
+(SELECT COUNT(f3) FROM t1 WHERE t2.f1) AS f9
+FROM t2 JOIN t1 ON t1.f3
+WHERE ('v') IN (SELECT f4 FROM t2)
+ORDER BY f9;
+COUNT(t2.f3) f9
+0 2
+EXPLAIN
+SELECT COUNT(t2.f3),
+(SELECT t2.f1 FROM t1 limit 1) AS f9
+FROM t2 JOIN t1
+WHERE ('v') IN (SELECT f4 FROM t2)
+GROUP BY f9;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2
+SELECT COUNT(t2.f3),
+(SELECT t2.f1 FROM t1 limit 1) AS f9
+FROM t2 JOIN t1
+WHERE ('v') IN (SELECT f4 FROM t2)
+GROUP BY f9;
+COUNT(t2.f3) f9
+EXPLAIN
+SELECT COUNT(t2.f3),
+(SELECT t2.f1 FROM t1 limit 1) AS f9
+FROM t2 JOIN t1
+WHERE ('v') IN (SELECT f4 FROM t2)
+ORDER BY f9;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2
+SELECT COUNT(t2.f3),
+(SELECT t2.f1 FROM t1 limit 1) AS f9
+FROM t2 JOIN t1
+WHERE ('v') IN (SELECT f4 FROM t2)
+ORDER BY f9;
+COUNT(t2.f3) f9
+0 NULL
+drop table t1,t2;
+#
+# LP BUG#682683 Crash in create_tmp_table called from
+# JOIN::init_execution
+#
+CREATE TABLE t2 (f1 int) ;
+INSERT INTO t2 VALUES (1),(2);
+CREATE TABLE t1 (f1 int) ;
+EXPLAIN
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t1 system NULL NULL NULL NULL 0 const row not found
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
+field1
+NULL
+EXPLAIN
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t1 system NULL NULL NULL NULL 0 const row not found
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
+field1
+NULL
+NULL
+INSERT INTO t1 VALUES (1),(2);
+EXPLAIN
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
+ERROR 21000: Subquery returns more than 1 row
+drop table t1,t2;
+#
+# LP BUG#680943 Assertion `!table || (!table->read_set ||
+# bitmap_is_set(table->read_set, field_index))' failed with subquery
+#
+CREATE TABLE t1 (f1 int,f3 int) ;
+INSERT IGNORE INTO t1 VALUES ('6','0'),('4','0');
+CREATE TABLE t2 (f1 int,f2 int,f3 int) ;
+INSERT IGNORE INTO t2 VALUES ('6','0','0'),('2','0','0');
+SELECT f2
+FROM (SELECT * FROM t2) AS alias1
+WHERE (SELECT SQ2_t2.f1
+FROM t1 JOIN t1 AS SQ2_t2 ON SQ2_t2.f3
+WHERE SQ2_t2.f3 AND alias1.f1)
+ORDER BY f3 ;
+f2
+drop table t1,t2;
+#
+# LP BUG#715062: Wrong result with VIEW + UNION + subquery in maria-5.3-mwl89
+#
+create table t1 (f1 int);
+create table t2 (f2 int);
+create table t3 (f3 int);
+insert into t1 values (2);
+insert into t2 values (2);
+insert into t3 values (7);
+CREATE VIEW v1 AS SELECT 2 UNION SELECT 2 ;
+CREATE VIEW v2 AS SELECT * from t1 UNION SELECT * from t2 ;
+set @save_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch = 'in_to_exists=off,semijoin=off,materialization=on';
+EXPLAIN
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 );
+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 SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
+3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 );
+bug
+EXPLAIN
+SELECT ( 5 ) IN ( SELECT * FROM v1 );
+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 SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
+3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+SELECT ( 5 ) IN ( SELECT * FROM v1 );
+( 5 ) IN ( SELECT * FROM v1 )
+0
+EXPLAIN
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2);
+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 SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
+3 DERIVED t1 system NULL NULL NULL NULL 1
+4 UNION t2 system NULL NULL NULL NULL 1
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2);
+bug
+EXPLAIN
+SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 system NULL NULL NULL NULL 1
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2
+3 DERIVED t1 system NULL NULL NULL NULL 1
+4 UNION t2 system NULL NULL NULL NULL 1
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2);
+bug
+EXPLAIN
+SELECT ( 5 ) IN ( SELECT * FROM v2 );
+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 SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
+3 DERIVED t1 system NULL NULL NULL NULL 1
+4 UNION t2 system NULL NULL NULL NULL 1
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+SELECT ( 5 ) IN ( SELECT * FROM v2 );
+( 5 ) IN ( SELECT * FROM v2 )
+0
+SET @@optimizer_switch = 'in_to_exists=on,semijoin=off,materialization=off';
+EXPLAIN
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 );
+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 SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
+3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 );
+bug
+EXPLAIN
+SELECT ( 5 ) IN ( SELECT * FROM v1 );
+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 SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
+3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+SELECT ( 5 ) IN ( SELECT * FROM v1 );
+( 5 ) IN ( SELECT * FROM v1 )
+0
+EXPLAIN
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2);
+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 SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
+3 DERIVED t1 system NULL NULL NULL NULL 1
+4 UNION t2 system NULL NULL NULL NULL 1
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2);
+bug
+EXPLAIN
+SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 system NULL NULL NULL NULL 1
+2 SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
+3 DERIVED t1 system NULL NULL NULL NULL 1
+4 UNION t2 system NULL NULL NULL NULL 1
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2);
+bug
+EXPLAIN
+SELECT ( 5 ) IN ( SELECT * FROM v2 );
+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 SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
+3 DERIVED t1 system NULL NULL NULL NULL 1
+4 UNION t2 system NULL NULL NULL NULL 1
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+SELECT ( 5 ) IN ( SELECT * FROM v2 );
+( 5 ) IN ( SELECT * FROM v2 )
+0
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1,t2,t3;
+drop view v1,v2;
+#
+# LP BUG#715069 Wrong result with GROUP BY inside subquery and materialization=off
+#
+CREATE TABLE t0 ( f1 int(11), f2 int(11), f10 varchar(1), PRIMARY KEY (f1)) ;
+INSERT INTO t0 VALUES (8,8,'u'),(10,5,'o');
+CREATE TABLE t1 (f1a int, f2a int not null, f3a varchar(3) not null, PRIMARY KEY (f1a)) ;
+INSERT INTO t1 VALUES
+(8,8,'a1a'),
+(10,5,'b1b');
+CREATE TABLE t2 (f1b int, f2b int not null, f3b varchar(3) not null, PRIMARY KEY (f1b)) ;
+INSERT INTO t2 VALUES
+(10,5,'d1d');
+set @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+set @@optimizer_switch = 'in_to_exists=on,materialization=off,semijoin=off';
+EXPLAIN
+SELECT alias2.f1 , alias2.f2
+FROM t0 AS alias1
+RIGHT JOIN t0 AS alias2 ON alias2.f10
+WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT max(f2) , f1 FROM t0 GROUP BY f2 , f1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY alias2 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY alias1 index NULL PRIMARY 4 NULL 2 Using where; Using index
+2 DEPENDENT SUBQUERY t0 ALL NULL NULL NULL NULL 2 Using temporary
+SELECT alias2.f1 , alias2.f2
+FROM t0 AS alias1
+RIGHT JOIN t0 AS alias2 ON alias2.f10
+WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT max(f2) , f1 FROM t0 GROUP BY f2 , f1 );
+f1 f2
+8 8
+EXPLAIN
+SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT max(f1a), f2a FROM t1 GROUP BY f1a, f2a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT max(f1a), f2a FROM t1 GROUP BY f1a, f2a);
+f1b f2b f3b
+10 5 d1d
+EXPLAIN
+SELECT * FROM t2 WHERE (f1b) IN (SELECT max(f1a) FROM t1 GROUP BY f1a, f2a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+SELECT * FROM t2 WHERE (f1b) IN (SELECT max(f1a) FROM t1 GROUP BY f1a, f2a);
+f1b f2b f3b
+10 5 d1d
+set @@optimizer_switch = 'in_to_exists=off,materialization=on,semijoin=off';
+EXPLAIN
+SELECT alias2.f1 , alias2.f2
+FROM t0 AS alias1
+RIGHT JOIN t0 AS alias2 ON alias2.f10
+WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT max(f2) , f1 FROM t0 GROUP BY f2 , f1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY alias2 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY alias1 index NULL PRIMARY 4 NULL 2 Using where; Using index
+2 MATERIALIZED t0 ALL NULL NULL NULL NULL 2 Using temporary
+SELECT alias2.f1 , alias2.f2
+FROM t0 AS alias1
+RIGHT JOIN t0 AS alias2 ON alias2.f10
+WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT max(f2) , f1 FROM t0 GROUP BY f2 , f1 );
+f1 f2
+8 8
+EXPLAIN
+SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT max(f1a), f2a FROM t1 GROUP BY f1a, f2a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 Using temporary
+SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT max(f1a), f2a FROM t1 GROUP BY f1a, f2a);
+f1b f2b f3b
+10 5 d1d
+EXPLAIN
+SELECT * FROM t2 WHERE (f1b) IN (SELECT max(f1a) FROM t1 GROUP BY f1a, f2a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 Using temporary
+SELECT * FROM t2 WHERE (f1b) IN (SELECT max(f1a) FROM t1 GROUP BY f1a, f2a);
+f1b f2b f3b
+10 5 d1d
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t0,t1,t2;
+#
+# LP BUG#715759 Wrong result with in_to_exists=on in maria-5.3-mwl89
+#
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (a1 int, a2 int) ;
+INSERT INTO t1 VALUES (1, 2);
+INSERT INTO t1 VALUES (3, 4);
+CREATE TABLE t2 (b1 int, b2 int) ;
+INSERT INTO t2 VALUES (1, 2);
+SET @@optimizer_switch = 'in_to_exists=on,materialization=off,semijoin=off';
+EXPLAIN SELECT * FROM t1 WHERE a1 IN (SELECT b1 FROM t2 WHERE b1 = b2);
+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 NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT * FROM t1 WHERE a1 IN (SELECT b1 FROM t2 WHERE b1 = b2);
+a1 a2
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t2;
+#
+# LP BUG#772309 join_tab_cmp_straight(): Assertion `!jt2->emb_sj_nest' failed in maria-5.3-mwl89 with semijoin
+#
+CREATE TABLE t1 ( f2 int) ;
+INSERT INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f1 int NOT NULL ) ;
+INSERT INTO t2 VALUES (0),(0);
+CREATE TABLE t3 ( f1 int NOT NULL , f2 int) ;
+INSERT INTO t3 VALUES (0,0), (0,0);
+EXPLAIN SELECT STRAIGHT_JOIN (
+SELECT f2 FROM t1 WHERE ( f2 ) IN ( SELECT t3.f2 FROM t3 JOIN t2 ON t2.f1 = 1 )
+);
+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 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+SELECT STRAIGHT_JOIN (
+SELECT f2 FROM t1 WHERE ( f2 ) IN ( SELECT t3.f2 FROM t3 JOIN t2 ON t2.f1 = 1 )
+);
+(
+SELECT f2 FROM t1 WHERE ( f2 ) IN ( SELECT t3.f2 FROM t3 JOIN t2 ON t2.f1 = 1 )
+)
+NULL
+drop table t1, t2, t3;
+#
+# LP BUG#777597 Wrong result with multipart keys, in_to_exists=on, NOT IN in MWL#89
+#
+CREATE TABLE t1 ( f4 int);
+INSERT IGNORE INTO t1 VALUES (2),(2);
+CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3) );
+INSERT IGNORE INTO t2 VALUES (6, 1), (6, 1);
+CREATE TABLE t3 ( f10 int );
+INSERT IGNORE INTO t3 VALUES (1);
+SET SESSION optimizer_switch='in_to_exists=on,materialization=off';
+EXPLAIN
+SELECT * FROM t1 WHERE ( 6 ) NOT IN ( SELECT t2.f3 FROM t2 JOIN t3 ON t3.f10 = t2.f10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t3 system NULL NULL NULL NULL 1
+2 SUBQUERY t2 ref_or_null f10 f10 10 const,const 2 Using where; Using index
+SELECT * FROM t1 WHERE ( 6 ) NOT IN ( SELECT t2.f3 FROM t2 JOIN t3 ON t3.f10 = t2.f10);
+f4
+drop table t1,t2,t3;
+#
+# LP BUG#778413 Third crash in select_describe() in maria-5.3-mwl89
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT INTO t1 VALUES (1),(1);
+CREATE TABLE t2 ( f1 int NOT NULL) ;
+INSERT INTO t2 VALUES (20);
+CREATE TABLE t3 (f3 int) ;
+INSERT INTO t3 VALUES (2),(2);
+EXPLAIN SELECT * FROM t2
+WHERE t2.f1 = (
+SELECT MAX( f3 ) FROM t3
+WHERE EXISTS (
+SELECT DISTINCT f11
+FROM t1));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 2
+3 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+drop table t1, t2, t3;
+#
+# LP BUG#802979 Assertion `table->key_read == 0' in close_thread_table
+#
+CREATE TABLE t1 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t1 VALUES (1,0),(5,0);
+CREATE TABLE t2 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t2 VALUES (1,0),(5,0);
+CREATE TABLE t3 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES (1,0),(5,0);
+CREATE TABLE t4 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t4 VALUES (1,0),(5,0);
+EXPLAIN
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+WHERE EXISTS (SELECT DISTINCT f1 FROM t4))
+AND t2.f2 = t1.f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref f1 f1 5 const 0 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 2
+3 SUBQUERY t4 index NULL f1 5 NULL 2 Using index
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+WHERE EXISTS (SELECT DISTINCT f1 FROM t4))
+AND t2.f2 = t1.f1;
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+WHERE EXISTS (SELECT DISTINCT f1 FROM t4) LIMIT 1)
+AND t2.f2 = t1.f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref f1 f1 5 const 0 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 2
+3 SUBQUERY t4 index NULL f1 5 NULL 2 Using index
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+WHERE EXISTS (SELECT DISTINCT f1 FROM t4) LIMIT 1)
+AND t2.f2 = t1.f1;
+f1 f2 f1 f2
+drop table t1,t2,t3,t4;
+#
+# LP BUG#611690 Crash in select_describe() with nested subqueries
+#
+CREATE TABLE t1 (
+col_int_key int(11) DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_int_key (col_int_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (8,'v','v');
+INSERT INTO t1 VALUES (9,'r','r');
+CREATE TABLE t2 (
+col_int_key int(11) DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_int_key (col_int_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (2,'w','w');
+INSERT INTO t2 VALUES (9,'m','m');
+set @old_optimizer_switch = @@optimizer_switch;
+set @@optimizer_switch='subquery_cache=off,materialization=on,in_to_exists=off,semijoin=off';
+EXPLAIN
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ON SUBQUERY2_t2.col_varchar_key
+WHERE SUBQUERY2_t2.col_varchar_nokey IN
+(SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index NULL col_int_key 5 NULL 2 Using index
+2 SUBQUERY SUBQUERY2_t1 index NULL col_int_key 5 NULL 2 Using index
+2 SUBQUERY SUBQUERY2_t2 ALL col_varchar_key NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+3 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ON SUBQUERY2_t2.col_varchar_key
+WHERE SUBQUERY2_t2.col_varchar_nokey IN
+(SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+col_int_key
+set @@optimizer_switch='subquery_cache=off,materialization=off,in_to_exists=on,semijoin=off';
+EXPLAIN
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ON SUBQUERY2_t2.col_varchar_key
+WHERE SUBQUERY2_t2.col_varchar_nokey IN
+(SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index NULL col_int_key 5 NULL 2 Using index
+2 SUBQUERY SUBQUERY2_t1 index NULL col_int_key 5 NULL 2 Using index
+2 SUBQUERY SUBQUERY2_t2 ALL col_varchar_key NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ON SUBQUERY2_t2.col_varchar_key
+WHERE SUBQUERY2_t2.col_varchar_nokey IN
+(SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+col_int_key
+drop table t1, t2;
+set @@optimizer_switch = @old_optimizer_switch;
+#
+# LP BUG#612543 Crash in Item_field::used_tables() with view + subquery + prepared statements
+#
+CREATE TABLE t1 ( f1 int(11), f2 varchar(1));
+CREATE TABLE t2 ( f3 varchar(1));
+insert into t1 values (2,'x'), (5,'y');
+insert into t2 values ('x'), ('z');
+CREATE VIEW v2 AS SELECT * FROM t2;
+set @old_optimizer_switch = @@optimizer_switch;
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
+PREPARE st1 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )";
+EXECUTE st1;
+f1 f2 f3
+2 x x
+5 y x
+EXECUTE st1;
+f1 f2 f3
+2 x x
+5 y x
+set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+PREPARE st2 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )";
+EXECUTE st2;
+f1 f2 f3
+2 x x
+5 y x
+EXECUTE st2;
+f1 f2 f3
+2 x x
+5 y x
+set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
+PREPARE st3 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )";
+EXECUTE st3;
+f1 f2 f3
+2 x x
+5 y x
+EXECUTE st3;
+f1 f2 f3
+2 x x
+5 y x
+set @@optimizer_switch = @old_optimizer_switch;
+drop table t1, t2;
+drop view v2;
+#
+# LP BUG#611396 RQG: crash in Item_field::register_field_in_read_map with semijoin=off
+# and prepared statements and materialization
+CREATE TABLE t1 ( f1 int(11), f2 int(11)) ;
+CREATE TABLE t2 ( f1 int(11), f4 varchar(1), PRIMARY KEY (f1)) ;
+INSERT INTO t2 VALUES ('23','j'),('24','e');
+CREATE TABLE t3 ( f1 int(11), f4 varchar(1)) ;
+INSERT INTO t3 VALUES ('8','j');
+set @old_optimizer_switch = @@optimizer_switch;
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+EXPLAIN
+SELECT t2.f1, (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1))
+FROM t2 JOIN t3 ON t3.f4 = t2.f4
+WHERE t3.f1 = 8
+GROUP BY 1, 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 system NULL NULL NULL NULL 1 Using temporary; Using filesort
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+3 MATERIALIZED t1 system NULL NULL NULL NULL 0 const row not found
+PREPARE st1 FROM "
+SELECT t2.f1, (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1))
+FROM t2 JOIN t3 ON t3.f4 = t2.f4
+WHERE t3.f1 = 8
+GROUP BY 1, 2";
+EXECUTE st1;
+f1 (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1))
+23 NULL
+EXECUTE st1;
+f1 (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1))
+23 NULL
+set @@optimizer_switch = @old_optimizer_switch;
+drop table t1, t2, t3;
+#
+# LP BUG#611382 RQG: Query returns extra rows when executed with materialization=on
+#
+CREATE TABLE t1 ( f4 varchar(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2 ( f2 date, f3 varchar(1), f4 varchar(1)) ;
+INSERT INTO t2 VALUES ('2005-05-03','c','c'),('1900-01-01','d','d');
+CREATE TABLE t3 ( f3 varchar(1)) ;
+INSERT INTO t3 VALUES ('c');
+set @old_optimizer_switch = @@optimizer_switch;
+set @@optimizer_switch = 'materialization=on,in_to_exists=off,semijoin=off';
+EXPLAIN SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t3 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+f4
+set @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off';
+EXPLAIN SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t3 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+f4
+set @@optimizer_switch = @old_optimizer_switch;
+drop table t1, t2, t3;
+#
+# LP BUG#782305: Wrong result/valgrind warning in Item_sum_hybrid::any_value()
+#
+CREATE TABLE t1 ( f1 int) ;
+INSERT INTO t1 VALUES (2),(3);
+CREATE TABLE t2 (f2 int) ;
+INSERT INTO t2 VALUES (2),(3);
+PREPARE st1 FROM '
+SELECT * FROM t2
+WHERE f2 <= SOME ( SELECT f1 FROM t1 );
+';
+EXECUTE st1;
+f2
+2
+3
+EXECUTE st1;
+f2
+2
+3
+PREPARE st2 FROM '
+SELECT * FROM t2
+WHERE f2 <= SOME (SELECT f1-2 FROM t1 UNION SELECT f1-1 FROM t1);
+';
+EXECUTE st2;
+f2
+2
+EXECUTE st2;
+f2
+2
+drop table t1, t2;
+#
+# LP BUG#825018: Crash in check_and_do_in_subquery_rewrites() with corrlated subquery in select list
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (10,1),(11,7);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (2),(3);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (1,1);
+CREATE PROCEDURE sp1 () LANGUAGE SQL
+SELECT (SELECT t1.a
+FROM t1
+WHERE t1.b = t3.b
+AND t1.b IN ( SELECT a FROM t2 )) sq
+FROM t3
+GROUP BY 1;
+CALL sp1();
+sq
+NULL
+CALL sp1();
+sq
+NULL
+drop procedure sp1;
+prepare st1 from "
+SELECT (SELECT t1.a
+ FROM t1
+ WHERE t1.b = t3.b
+ AND t1.b IN ( SELECT a FROM t2 )) sq
+FROM t3
+GROUP BY 1";
+execute st1;
+sq
+NULL
+execute st1;
+sq
+NULL
+deallocate prepare st1;
+drop table t1, t2, t3;
+set optimizer_switch=@subselect4_tmp;
+#
+# LP BUG#833702 Wrong result with nested IN and singlerow subqueries and equality propagation
+#
+CREATE TABLE t2 (c int , a int, b int);
+INSERT INTO t2 VALUES (10,7,0);
+CREATE TABLE t3 (a int, b int) ;
+INSERT INTO t3 VALUES (5,0),(7,0);
+CREATE TABLE t4 (a int);
+INSERT INTO t4 VALUES (2),(8);
+set @@optimizer_switch='semijoin=off,in_to_exists=on,materialization=off,subquery_cache=off';
+SELECT * FROM t2
+WHERE t2.b IN (SELECT b FROM t3 WHERE t3.a = t2.a AND a < SOME (SELECT * FROM t4))
+OR ( t2.c > 242 );
+c a b
+10 7 0
+EXPLAIN SELECT * FROM t2
+WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.a < ANY (SELECT t4.a FROM t4) and t3.a = 7);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+3 SUBQUERY t4 ALL NULL NULL NULL NULL 2
+SELECT * FROM t2
+WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.a < ANY (SELECT t4.a FROM t4) and t3.a = 7);
+c a b
+10 7 0
+drop table t2, t3, t4;
+#
+# BUG#934597: Assertion `! is_set()' failed in Diagnostics_area::set_ok_status(THD...
+#
+CREATE TABLE t1 ( a VARCHAR(1) );
+INSERT INTO t1 VALUES ('u'),('k');
+CREATE TABLE t2 AS
+SELECT a AS field1 FROM t1
+WHERE ( SELECT alias1.a
+FROM t1 AS alias1
+) IS NOT NULL;
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t2;
+ERROR 42S02: Unknown table 't2'
+DROP TABLE t1;
+#
+# LP BUG#1000649 EXPLAIN shows incorrectly a non-correlated constant IN subquery is correlated
+#
+create table ten (a int);
+insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, c int);
+insert into t1 select a,a,a from ten;
+create table five (a int, b int, c int);
+insert into five select a,a,a from ten limit 5;
+set @@optimizer_switch='semijoin=on,in_to_exists=on,materialization=off';
+explain select * from t1 where 33 in (select b from five) or c > 11;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using where
+2 SUBQUERY five ALL NULL NULL NULL NULL 5 Using where
+drop table ten, t1, five;
+#
+# LP BUG#1008773 Wrong result (NULL instead of a value) with no matching rows, subquery in FROM and HAVING
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1);
+EXPLAIN
+SELECT MAX(a), ( SELECT 1 FROM t2 ) AS bb FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 1
+SELECT MAX(a), ( SELECT 1 FROM t2 ) AS bb FROM t1;
+MAX(a) bb
+NULL 1
+EXPLAIN
+SELECT MAX(a), 1 in ( SELECT b FROM t2 ) AS bb FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+2 SUBQUERY t2 system NULL NULL NULL NULL 1
+SELECT MAX(a), 1 in ( SELECT b FROM t2 ) AS bb FROM t1;
+MAX(a) bb
+NULL 1
+EXPLAIN
+SELECT MAX(a), 1 >= ALL ( SELECT b FROM t2 ) AS bb FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT MAX(a), 1 >= ALL ( SELECT b FROM t2 ) AS bb FROM t1;
+MAX(a) bb
+NULL 1
+EXPLAIN
+SELECT MAX(a), ( SELECT 1 FROM t2 where b = a) AS bb FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT MAX(a), ( SELECT 1 FROM t2 where b = a) AS bb FROM t1;
+MAX(a) bb
+NULL NULL
+EXPLAIN
+SELECT MAX(a), a in ( SELECT b FROM t2 ) AS bb FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
+SELECT MAX(a), a in ( SELECT b FROM t2 ) AS bb FROM t1;
+MAX(a) bb
+NULL NULL
+EXPLAIN
+SELECT MAX(a), a >= ALL ( SELECT b FROM t2 ) AS bb FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
+SELECT MAX(a), a >= ALL ( SELECT b FROM t2 ) AS bb FROM t1;
+MAX(a) bb
+NULL NULL
+drop table t1, t2;
+set optimizer_switch=@subselect4_tmp;
+#
+# MDEV-3928 Assertion `example' failed in Item_cache::is_expensive_processor with a 2-level IN subquery
+#
+CREATE TABLE t1 (a1 INT, b1 TIME) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4,'21:22:34'),(6,'10:50:38');
+CREATE TABLE t2 (a2 INT, b2 TIME) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (8, '06:17:39');
+CREATE TABLE t3 (a3 INT, b3 TIME) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (1,'00:00:01'),(7,'00:00:02');
+EXPLAIN
+SELECT * FROM t1 WHERE a1 IN (
+SELECT a2 FROM t2 WHERE a2 IN (
+SELECT a3 FROM t3 WHERE b2 = b1 AND b2 <= b1 ORDER BY b3
+)
+);
+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 ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1 WHERE a1 IN (
+SELECT a2 FROM t2 WHERE a2 IN (
+SELECT a3 FROM t3 WHERE b2 = b1 AND b2 <= b1 ORDER BY b3
+)
+);
+a1 b1
+drop table t1, t2, t3;
+#
+# MDEV-4056:Server crashes in Item_func_trig_cond::val_int
+# with FROM and NOT IN subqueries, LEFT JOIN, derived_merge+in_to_exists
+#
+set @optimizer_switch_MDEV4056 = @@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on,in_to_exists=on';
+CREATE TABLE t1 (a VARCHAR(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('x'),('d');
+CREATE TABLE t2 (pk INT PRIMARY KEY, b INT, c VARCHAR(1)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,2,'v'),(2,150,'v');
+SELECT * FROM t1 LEFT JOIN (
+SELECT * FROM t2 WHERE ( pk, pk ) NOT IN (
+SELECT MIN(b), SUM(pk) FROM t1
+)
+) AS alias1 ON (a = c)
+WHERE b IS NULL OR a < 'u';
+a pk b c
+x NULL NULL NULL
+d NULL NULL NULL
+drop table t1,t2;
+set @@optimizer_switch = @optimizer_switch_MDEV4056;
+SET optimizer_switch= @@global.optimizer_switch;
+set @@tmp_table_size= @@global.tmp_table_size;
diff --git a/mysql-test/r/subselect_cache.result b/mysql-test/r/subselect_cache.result
new file mode 100644
index 00000000000..1f9fcdeca6e
--- /dev/null
+++ b/mysql-test/r/subselect_cache.result
@@ -0,0 +1,3420 @@
+drop table if exists t1,t2,t3,t4,t5;
+drop view if exists v1;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+SET optimizer_switch='semijoin_with_cache=off';
+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_deleted 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_deleted 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_deleted 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_deleted 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_deleted 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_deleted 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_deleted 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_deleted 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_deleted 0
+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_deleted 0
+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_deleted 0
+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_deleted 0
+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 10
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 42
+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 10
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 72
+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_deleted 1
+Handler_read_rnd_next 36
+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_deleted 1
+Handler_read_rnd_next 66
+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_deleted 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_deleted 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_deleted 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_deleted 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_deleted 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_deleted 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_deleted 0
+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_deleted 0
+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_deleted 0
+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_deleted 0
+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_deleted 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_deleted 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_deleted 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 MATERIALIZED 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_deleted 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 `test`.`t2`.`b` 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;
+set optimizer_switch='subquery_cache=on';
+# LP BUG#615378 (incorrect NULL result returning in Item_cache)
+CREATE TABLE `t1` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`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;
+#
+# Test aggregate functions as parameters to subquery cache
+#
+CREATE TABLE t1 ( a INT, b INT, c INT, KEY (a, b));
+INSERT INTO t1 VALUES
+( 1, 1, 1 ),
+( 1, 2, 2 ),
+( 1, 3, 3 ),
+( 1, 4, 6 ),
+( 1, 5, 5 ),
+( 1, 9, 13 ),
+( 2, 1, 6 ),
+( 2, 2, 7 ),
+( 2, 3, 8 );
+SELECT a, AVG(t1.b),
+(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c
+FROM t1 GROUP BY a;
+a AVG(t1.b) t11c
+1 4.0000 6
+2 2.0000 7
+DROP TABLE t1;
+#
+# Test of LP BUG#800696 (deleting list of Items (OR arguments)
+# in optimization)
+#
+set optimizer_switch='subquery_cache=on,in_to_exists=on';
+CREATE TABLE t1 ( f3 int) ;
+INSERT INTO t1 VALUES (0),(0);
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+CREATE TABLE t2 ( f1 int, f2 int, f3 int) ;
+INSERT INTO t2 VALUES (7,0,0);
+SELECT *
+FROM t2, t3
+WHERE t2.f2 OR t3.f3 IN
+(
+SELECT t2.f2
+FROM t1
+WHERE t2.f1 OR t2.f3 );
+f1 f2 f3 f3
+7 0 0 0
+7 0 0 0
+drop tables t1, t2, t3;
+#
+# Test of LP BUG#872775 view with "outer references" bug
+#
+set @@optimizer_switch= default;
+set optimizer_switch='subquery_cache=on';
+CREATE TABLE t1 (a int) ;
+CREATE TABLE t2 (b int, c varchar(1) NOT NULL ) ;
+INSERT INTO t2 VALUES (1,'x'),(2,'y');
+CREATE TABLE t3 (a int) ;
+CREATE TABLE t4 ( pk int(11) NOT NULL , b int(11) NOT NULL ) ;
+INSERT INTO t4 VALUES (26,9),(27,5),(28,0),(29,3);
+CREATE OR REPLACE VIEW v1 AS
+SELECT t2.b
+FROM t1
+JOIN t2
+WHERE t2 .c > (
+SELECT t2.c FROM t3
+);
+SELECT * FROM t4 WHERE b NOT IN ( SELECT * FROM v1 );
+pk b
+26 9
+27 5
+28 0
+29 3
+drop view v1;
+drop table t1,t2,t3,t4;
+SET optimizer_switch=@save_optimizer_switch;
+# restore default
+set @@optimizer_switch= default;
diff --git a/mysql-test/r/subselect_extra.result b/mysql-test/r/subselect_extra.result
new file mode 100644
index 00000000000..53a38bf6e8e
--- /dev/null
+++ b/mysql-test/r/subselect_extra.result
@@ -0,0 +1,480 @@
+drop table if exists t1,t2,t3,t4;
+drop view if exists v1,v2,v3;
+set @subselect_extra_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_extra_test,
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+# From explain.test:
+#
+# Bug#37870: Usage of uninitialized value caused failed assertion.
+#
+create table t1 (dt datetime not null, t time not null);
+create table t2 (dt datetime not null);
+insert into t1 values ('2001-01-01 1:1:1', '1:1:1'),
+('2001-01-01 1:1:1', '1:1:1');
+insert into t2 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1');
+flush tables;
+EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY INNR ALL NULL NULL NULL NULL 2 Using where; FirstMatch(OUTR); 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
+1 PRIMARY INNR ALL NULL NULL NULL NULL 2 Using where; FirstMatch(OUTR); Using join buffer (flat, BNL join)
+flush tables;
+SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+dt
+2001-01-01 01:01:01
+2001-01-01 01:01:01
+drop tables t1, t2;
+# From type_datetime.test:
+#
+# Bug #32694: NOT NULL table field in a subquery produces invalid results
+#
+create table t1 (id int(10) not null, cur_date datetime not null);
+create table t2 (id int(10) not null, cur_date date not null);
+insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22');
+insert into t2 (id, cur_date) values (1, '2007-04-25');
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select 1 AS `id`,'2007-04-25 18:30:22' AS `cur_date` from `test`.`t1` semi join (`test`.`t1` `x1`) where (('2007-04-25 18:30:22' = 0))
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id cur_date
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select 1 AS `id`,'2007-04-25' AS `cur_date` from `test`.`t2` semi join (`test`.`t2` `x1`) where (('2007-04-25' = 0))
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id cur_date
+insert into t1 (id, cur_date) values (2, '2007-04-26 18:30:22');
+insert into t2 (id, cur_date) values (2, '2007-04-26');
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`cur_date` AS `cur_date` from `test`.`t1` semi join (`test`.`t1` `x1`) where ((`test`.`x1`.`id` = `test`.`t1`.`id`) and (`test`.`t1`.`cur_date` = 0))
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id cur_date
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t2); Using join buffer (flat, BNL join)
+Warnings:
+Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t2`.`id` AS `id`,`test`.`t2`.`cur_date` AS `cur_date` from `test`.`t2` semi join (`test`.`t2` `x1`) where ((`test`.`x1`.`id` = `test`.`t2`.`id`) and (`test`.`t2`.`cur_date` = 0))
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id cur_date
+drop table t1,t2;
+#
+# From group_min_max.test
+#
+create table t1 (
+a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
+);
+insert into t1 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'),
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4');
+create index idx_t1_0 on t1 (a1);
+create index idx_t1_1 on t1 (a1,a2,b,c);
+create index idx_t1_2 on t1 (a1,a2,b);
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Table is already up to date
+create table t2 (
+a1 char(64), a2 char(64) not null, b char(16), c char(16), d char(16), dummy char(64) default ' '
+);
+insert into t2 select * from t1;
+insert into t2 (a1, a2, b, c, d) values
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz');
+create index idx_t2_0 on t2 (a1);
+create index idx_t2_1 on t2 (a1,a2,b,c);
+create index idx_t2_2 on t2 (a1,a2,b);
+analyze table t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status Table is already up to date
+create table t3 (
+a1 char(1), a2 char(1), b char(1), c char(4) not null, d char(3), dummy char(1) default ' '
+);
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+create index idx_t3_0 on t3 (a1);
+create index idx_t3_1 on t3 (a1,a2,b,c);
+create index idx_t3_2 on t3 (a1,a2,b);
+analyze table t3;
+Table Op Msg_type Msg_text
+test.t3 analyze status Table is already up to date
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.b) and
+t2.c > 'b1' )
+group by a1,a2,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
+2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+2 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index; FirstMatch(t2); Using join buffer (flat, BNL join)
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.b) and
+t2.c > 'b1' )
+group by a1,a2,b;
+a1 a2 b c min(c) max(c)
+a a a d111 a111 d111
+a a b h112 e112 h112
+a b a l121 i121 l121
+a b b p122 m122 p122
+b a a d211 a211 d211
+b a b h212 e212 h212
+b b a l221 i221 l221
+b b b p222 m222 p222
+c a a d311 a311 d311
+c a b h312 e312 h312
+c b a l321 i321 l321
+c b b p322 m322 p322
+d a a d411 a411 d411
+d a b h412 e412 h412
+d b a l421 i421 l421
+d b b p422 m422 p422
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.c) and
+t2.c > 'b1' )
+group by a1,a2,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index
+2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+2 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index; FirstMatch(t2); Using join buffer (flat, BNL join)
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.c) and
+t2.c > 'b1' )
+group by a1,a2,b;
+a1 a2 b c min(c) max(c)
+a a a a111 a111 d111
+a a b e112 e112 h112
+a b a i121 i121 l121
+a b b m122 m122 p122
+b a a a211 a211 d211
+b a b e212 e212 h212
+b b a i221 i221 l221
+b b b m222 m222 p222
+c a a a311 a311 d311
+c a b e312 e312 h312
+c b a i321 i321 l321
+c b b m322 m322 o322
+d a a a411 a411 d411
+d a b e412 e412 h412
+d b a i421 i421 l421
+d b b m422 m422 o422
+drop table t1, t2, t3;
+#
+# From group_by.test
+#
+# Bug #21174: Index degrades sort performance and
+# optimizer does not honor IGNORE INDEX.
+# a.k.a WL3527.
+#
+CREATE TABLE t1 (a INT, b INT,
+PRIMARY KEY (a),
+KEY i2(a,b));
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8);
+INSERT INTO t1 SELECT a + 8,b FROM t1;
+INSERT INTO t1 SELECT a + 16,b FROM t1;
+INSERT INTO t1 SELECT a + 32,b FROM t1;
+INSERT INTO t1 SELECT a + 64,b FROM t1;
+INSERT INTO t1 SELECT a + 128,b FROM t1 limit 16;
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+EXPLAIN SELECT 1 FROM t1 WHERE a IN
+(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index PRIMARY,i2 PRIMARY 4 NULL 144 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED 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;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL a 5 NULL 2
+EXPLAIN SELECT a, SUM(b) FROM t2 IGNORE INDEX (a) GROUP BY a LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
+EXPLAIN SELECT 1 FROM t2 WHERE a IN
+(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index a a 5 NULL 4 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 144
+DROP TABLE t1, t2;
+#
+# From derived_view.test
+#
+set @tmp_subselect_extra_derived=@@optimizer_switch;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+#
+# LP bug #806504: right join over a view/derived table
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (0), (0);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+a a b
+NULL 0 0
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t1` semi join (`test`.`t1`) left join `test`.`t2` on((0 <> 0)) where 1
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+a a b
+NULL 0 0
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t1` semi join (`test`.`t1`) left join `test`.`t2` on((0 <> 0)) where 1
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #793448: materialized view accessed by two-component key
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (9,3), (2,5);
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (9,3), (3,7), (9,1), (2,5), (2,4), (3,8);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,3), (9,7), (9,1), (2,4);
+CREATE VIEW v1(a,b) AS SELECT a, MAX(b) FROM t2 GROUP BY a;
+CREATE VIEW v2(a,b) AS SELECT a,b FROM t2 UNION SELECT a,b FROM t3;
+SELECT * FROM v1;
+a b
+2 5
+3 8
+9 3
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+a
+9
+2
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1)
+3 DERIVED t2 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
+SELECT * FROM v2;
+a b
+9 3
+3 7
+9 1
+2 5
+2 4
+3 8
+10 3
+9 7
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+a
+9
+2
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1)
+3 DERIVED t2 ALL NULL NULL NULL NULL 6
+4 UNION t3 ALL NULL NULL NULL NULL 4
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+DROP VIEW v1,v2;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #874006: materialized view used in IN subquery
+#
+CREATE TABLE t3 (a int NOT NULL, b varchar(1), c varchar(1));
+INSERT INTO t3 VALUES (19,NULL,NULL), (20,'r','r');
+CREATE TABLE t1 (a int, b varchar(1) , c varchar(1));
+INSERT INTO t1 VALUES (1,NULL,NULL), (5,'r','r'), (7,'y','y');
+CREATE TABLE t2 (a int NOT NULL , b int, c varchar(1));
+INSERT INTO t2 VALUES (4,3,'r');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t3); Using join buffer (flat, BNL join)
+3 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+a b c
+20 r r
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY <derived3> ref key1 key1 10 const,const 0 Start temporary
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+3 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+a b c
+20 r r
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #873263: materialized view used in correlated IN subquery
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (5,4), (9,8);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (4,5), (5,1);
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.b,test.t1.a 2 FirstMatch(t1)
+3 DERIVED t2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+a b
+5 4
+DROP VIEW v2;
+DROP TABLE t1,t2;
+set optimizer_switch= @tmp_subselect_extra_derived;
diff --git a/mysql-test/r/subselect_extra_no_semijoin.result b/mysql-test/r/subselect_extra_no_semijoin.result
new file mode 100644
index 00000000000..cf789d5909c
--- /dev/null
+++ b/mysql-test/r/subselect_extra_no_semijoin.result
@@ -0,0 +1,484 @@
+set @subselect_extra_no_sj_tmp=@@optimizer_switch;
+set @optimizer_switch_for_subselect_extra_test='semijoin=off,firstmatch=off,loosescan=off,semijoin_with_cache=off';
+drop table if exists t1,t2,t3,t4;
+drop view if exists v1,v2,v3;
+set @subselect_extra_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_extra_test,
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+# From explain.test:
+#
+# Bug#37870: Usage of uninitialized value caused failed assertion.
+#
+create table t1 (dt datetime not null, t time not null);
+create table t2 (dt datetime not null);
+insert into t1 values ('2001-01-01 1:1:1', '1:1:1'),
+('2001-01-01 1:1:1', '1:1:1');
+insert into t2 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1');
+flush tables;
+EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY INNR ALL NULL NULL NULL NULL 2 Using where
+flush tables;
+SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
+dt
+flush tables;
+EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY INNR ALL NULL NULL NULL NULL 2 Using where
+flush tables;
+SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+dt
+2001-01-01 01:01:01
+2001-01-01 01:01:01
+drop tables t1, t2;
+# From type_datetime.test:
+#
+# Bug #32694: NOT NULL table field in a subquery produces invalid results
+#
+create table t1 (id int(10) not null, cur_date datetime not null);
+create table t2 (id int(10) not null, cur_date date not null);
+insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22');
+insert into t2 (id, cur_date) values (1, '2007-04-25');
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select 1 AS `id`,'2007-04-25 18:30:22' AS `cur_date` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,<exists>(select `test`.`x1`.`id` from `test`.`t1` `x1` where 0)))
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id cur_date
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select 1 AS `id`,'2007-04-25' AS `cur_date` from `test`.`t2` where <expr_cache><1>(<in_optimizer>(1,<exists>(select `test`.`x1`.`id` from `test`.`t2` `x1` where 0)))
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id cur_date
+insert into t1 (id, cur_date) values (2, '2007-04-26 18:30:22');
+insert into t2 (id, cur_date) values (2, '2007-04-26');
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY x1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`cur_date` AS `cur_date` from `test`.`t1` where <expr_cache><`test`.`t1`.`id`,`test`.`t1`.`cur_date`>(<in_optimizer>(`test`.`t1`.`id`,<exists>(select `test`.`x1`.`id` from `test`.`t1` `x1` where ((`test`.`t1`.`cur_date` = 0) and (<cache>(`test`.`t1`.`id`) = `test`.`x1`.`id`)))))
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id cur_date
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY x1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t2`.`id` AS `id`,`test`.`t2`.`cur_date` AS `cur_date` from `test`.`t2` where <expr_cache><`test`.`t2`.`id`,`test`.`t2`.`cur_date`>(<in_optimizer>(`test`.`t2`.`id`,<exists>(select `test`.`x1`.`id` from `test`.`t2` `x1` where ((`test`.`t2`.`cur_date` = 0) and (<cache>(`test`.`t2`.`id`) = `test`.`x1`.`id`)))))
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id cur_date
+drop table t1,t2;
+#
+# From group_min_max.test
+#
+create table t1 (
+a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
+);
+insert into t1 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'),
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4');
+create index idx_t1_0 on t1 (a1);
+create index idx_t1_1 on t1 (a1,a2,b,c);
+create index idx_t1_2 on t1 (a1,a2,b);
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Table is already up to date
+create table t2 (
+a1 char(64), a2 char(64) not null, b char(16), c char(16), d char(16), dummy char(64) default ' '
+);
+insert into t2 select * from t1;
+insert into t2 (a1, a2, b, c, d) values
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz');
+create index idx_t2_0 on t2 (a1);
+create index idx_t2_1 on t2 (a1,a2,b,c);
+create index idx_t2_2 on t2 (a1,a2,b);
+analyze table t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status Table is already up to date
+create table t3 (
+a1 char(1), a2 char(1), b char(1), c char(4) not null, d char(3), dummy char(1) default ' '
+);
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+create index idx_t3_0 on t3 (a1);
+create index idx_t3_1 on t3 (a1,a2,b,c);
+create index idx_t3_2 on t3 (a1,a2,b);
+analyze table t3;
+Table Op Msg_type Msg_text
+test.t3 analyze status Table is already up to date
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.b) and
+t2.c > 'b1' )
+group by a1,a2,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
+2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+3 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.b) and
+t2.c > 'b1' )
+group by a1,a2,b;
+a1 a2 b c min(c) max(c)
+a a a d111 a111 d111
+a a b h112 e112 h112
+a b a l121 i121 l121
+a b b p122 m122 p122
+b a a d211 a211 d211
+b a b h212 e212 h212
+b b a l221 i221 l221
+b b b p222 m222 p222
+c a a d311 a311 d311
+c a b h312 e312 h312
+c b a l321 i321 l321
+c b b p322 m322 p322
+d a a d411 a411 d411
+d a b h412 e412 h412
+d b a l421 i421 l421
+d b b p422 m422 p422
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.c) and
+t2.c > 'b1' )
+group by a1,a2,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index
+2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+3 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.c) and
+t2.c > 'b1' )
+group by a1,a2,b;
+a1 a2 b c min(c) max(c)
+a a a a111 a111 d111
+a a b e112 e112 h112
+a b a i121 i121 l121
+a b b m122 m122 p122
+b a a a211 a211 d211
+b a b e212 e212 h212
+b b a i221 i221 l221
+b b b m222 m222 p222
+c a a a311 a311 d311
+c a b e312 e312 h312
+c b a i321 i321 l321
+c b b m322 m322 o322
+d a a a411 a411 d411
+d a b e412 e412 h412
+d b a i421 i421 l421
+d b b m422 m422 o422
+drop table t1, t2, t3;
+#
+# From group_by.test
+#
+# Bug #21174: Index degrades sort performance and
+# optimizer does not honor IGNORE INDEX.
+# a.k.a WL3527.
+#
+CREATE TABLE t1 (a INT, b INT,
+PRIMARY KEY (a),
+KEY i2(a,b));
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8);
+INSERT INTO t1 SELECT a + 8,b FROM t1;
+INSERT INTO t1 SELECT a + 16,b FROM t1;
+INSERT INTO t1 SELECT a + 32,b FROM t1;
+INSERT INTO t1 SELECT a + 64,b FROM t1;
+INSERT INTO t1 SELECT a + 128,b FROM t1 limit 16;
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+EXPLAIN SELECT 1 FROM t1 WHERE a IN
+(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 144 Using where; Using index
+2 MATERIALIZED 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;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL a 5 NULL 2
+EXPLAIN SELECT a, SUM(b) FROM t2 IGNORE INDEX (a) GROUP BY a LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
+EXPLAIN SELECT 1 FROM t2 WHERE a IN
+(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index NULL a 5 NULL 4 Using where; Using index
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 144
+DROP TABLE t1, t2;
+#
+# From derived_view.test
+#
+set @tmp_subselect_extra_derived=@@optimizer_switch;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+#
+# LP bug #806504: right join over a view/derived table
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (0), (0);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+a a b
+NULL 0 0
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+3 MATERIALIZED t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t1` left join `test`.`t2` on((0 <> 0)) where <expr_cache><0>(<in_optimizer>(0,0 in ( <materialize> (select 0 from `test`.`t1` ), <primary_index_lookup>(0 in <temporary table> on distinct_key where ((0 = `<subquery3>`.`b`))))))
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+a a b
+NULL 0 0
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 MATERIALIZED t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t1` left join `test`.`t2` on((0 <> 0)) where <expr_cache><0>(<in_optimizer>(0,0 in ( <materialize> (select 0 from `test`.`t1` ), <primary_index_lookup>(0 in <temporary table> on distinct_key where ((0 = `<subquery2>`.`b`))))))
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #793448: materialized view accessed by two-component key
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (9,3), (2,5);
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (9,3), (3,7), (9,1), (2,5), (2,4), (3,8);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,3), (9,7), (9,1), (2,4);
+CREATE VIEW v1(a,b) AS SELECT a, MAX(b) FROM t2 GROUP BY a;
+CREATE VIEW v2(a,b) AS SELECT a,b FROM t2 UNION SELECT a,b FROM t3;
+SELECT * FROM v1;
+a b
+2 5
+3 8
+9 3
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+a
+9
+2
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY <derived3> index_subquery key0 key0 10 func,func 2 Using where
+3 DERIVED t2 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
+SELECT * FROM v2;
+a b
+9 3
+3 7
+9 1
+2 5
+2 4
+3 8
+10 3
+9 7
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+a
+9
+2
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY <derived3> index_subquery key0 key0 10 func,func 2 Using where
+3 DERIVED t2 ALL NULL NULL NULL NULL 6
+4 UNION t3 ALL NULL NULL NULL NULL 4
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+DROP VIEW v1,v2;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #874006: materialized view used in IN subquery
+#
+CREATE TABLE t3 (a int NOT NULL, b varchar(1), c varchar(1));
+INSERT INTO t3 VALUES (19,NULL,NULL), (20,'r','r');
+CREATE TABLE t1 (a int, b varchar(1) , c varchar(1));
+INSERT INTO t1 VALUES (1,NULL,NULL), (5,'r','r'), (7,'y','y');
+CREATE TABLE t2 (a int NOT NULL , b int, c varchar(1));
+INSERT INTO t2 VALUES (4,3,'r');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 3 Using where
+3 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+a b c
+20 r r
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY <derived3> ref key1 key1 10 const,const 0 Using where
+3 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+a b c
+20 r r
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #873263: materialized view used in correlated IN subquery
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (5,4), (9,8);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (4,5), (5,1);
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY <derived3> ref key0 key0 5 test.t1.a 2 Using where
+3 DERIVED t2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+a b
+5 4
+DROP VIEW v2;
+DROP TABLE t1,t2;
+set optimizer_switch= @tmp_subselect_extra_derived;
+set optimizer_switch= @subselect_extra_no_sj_tmp;
+set @optimizer_switch_for_subselect_extra_test=null;
diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result
index 4069958267a..9750a53a76c 100644
--- a/mysql-test/r/subselect_innodb.result
+++ b/mysql-test/r/subselect_innodb.result
@@ -1,3 +1,5 @@
+set @subselect_innodb_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
drop table if exists t1,t2,t3;
CREATE TABLE t1
(
@@ -292,7 +294,7 @@ FROM t1
LIMIT 1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 1
-2 DEPENDENT SUBQUERY t2 ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 Using where
+2 DEPENDENT SUBQUERY t2 ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 Using where; Using index
SELECT
(SELECT position FROM t2
WHERE t2.t1_id = t1.id
@@ -305,3 +307,95 @@ maxkey
NULL
DROP TABLE t1,t2;
End of 5.1 tests
+#
+# LP BUG#827416: Crash in select_describe() on EXPLAIN with DISTINCT in nested subqueries
+#
+CREATE TABLE t3 ( b int) ENGINE=InnoDB;
+CREATE TABLE t2 ( c int) ENGINE=InnoDB;
+CREATE TABLE t1 ( a int NOT NULL , PRIMARY KEY (a)) ENGINE=InnoDB;
+EXPLAIN SELECT *
+FROM t1
+WHERE t1.a = (
+SELECT SUM( c )
+FROM t2
+WHERE (SELECT DISTINCT b FROM t3) > 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using where; Using index
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 1
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 1 Using temporary
+SELECT *
+FROM t1
+WHERE t1.a = (
+SELECT SUM( c )
+FROM t2
+WHERE (SELECT DISTINCT b FROM t3) > 0);
+a
+DROP TABLE t1, t2, t3;
+#
+# LP BUG#858148 Fourth crash in select_describe() with nested subqueries
+#
+CREATE TABLE t1 ( f1 int(11)) ENGINE=InnoDB;
+CREATE TABLE t2 ( f1 int(11), f2 int(11), PRIMARY KEY (f1)) ;
+CREATE TABLE t3 ( f3 int(11)) ENGINE=InnoDB;
+EXPLAIN
+SELECT MAX( f1 ) FROM t2
+WHERE f2 >= (
+SELECT SUM( f1 )
+FROM t1
+WHERE EXISTS (
+SELECT f3
+FROM t3
+GROUP BY 1
+)
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 1
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 1
+SELECT MAX( f1 ) FROM t2
+WHERE f2 >= (
+SELECT SUM( f1 )
+FROM t1
+WHERE EXISTS (
+SELECT f3
+FROM t3
+GROUP BY 1
+)
+);
+MAX( f1 )
+NULL
+drop table t1, t2, t3;
+#
+# LP BUG#1006231 crash in select_describe
+#
+create table t1(a1 int) ENGINE=InnoDB;
+insert into t1 values (1);
+explain
+select 1 from t1 where 1 like (select 1 from t1 where 1 <=> (select 1 from t1 group by a1));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 1
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 1
+3 SUBQUERY t1 ALL NULL NULL NULL NULL 1 Using temporary; Using filesort
+select 1 from t1 where 1 like (select 1 from t1 where 1 <=> (select 1 from t1 group by a1));
+1
+1
+drop table t1;
+#
+# MDEV-3988 crash in create_tmp_table
+#
+drop table if exists `t1`,`t2`;
+Warnings:
+Note 1051 Unknown table 't1'
+Note 1051 Unknown table 't2'
+create table `t1`(`a` char(1) character set utf8)engine=innodb;
+create table `t2`(`b` char(1) character set utf8)engine=memory;
+select distinct (select 1 from `t2` where `a`) `d2` from `t1`;
+d2
+select distinct (select 1 from `t2` where `a`) `d2`, a from `t1`;
+d2 a
+select distinct a, (select 1 from `t2` where `a`) `d2` from `t1`;
+a d2
+select distinct (1 + (select 1 from `t2` where `a`)) `d2` from `t1`;
+d2
+drop table t1,t2;
+set optimizer_switch=@subselect_innodb_tmp;
diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result
new file mode 100644
index 00000000000..f3442b2018e
--- /dev/null
+++ b/mysql-test/r/subselect_mat.result
@@ -0,0 +1,2285 @@
+set @subselect_mat_test_optimizer_switch_value='materialization=on,in_to_exists=off,semijoin=off';
+set @subselect_sj_mat_tmp= @@optimizer_switch;
+set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on');
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @optimizer_switch_local_default= @@optimizer_switch;
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
+drop table if exists t1, t2, t3, t4, t5, t1i, t2i, t3i;
+drop table if exists columns;
+drop table if exists t1_16, t2_16, t3_16;
+drop view if exists v1, v2, v1m, v2m;
+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='materialization=on,in_to_exists=off,firstmatch=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 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`))))))
+select * from t1 where a1 in (select b1 from t2 where b1 > '0');
+a1 a2
+1 - 01 2 - 01
+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 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`))))))
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' 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 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`))))))
+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 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,min(`test`.`t2`.`b2`) from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`min(b2)`))))))
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+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 _it1_idx # NULL 3 100.00 Using where;
+2 MATERIALIZED t2i index it2i1,it2i3 it2i1 # NULL 5 100.00 Using where;
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`>(<in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (select `test`.`t2i`.`b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`))))))
+select * from t1i where a1 in (select b1 from t2i where b1 > '0');
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where a1 in (select max(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 # 18 # 3 100.00 #
+2 MATERIALIZED t2i index it2i1,it2i3 # 9 # 5 100.00 #
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`>(<in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (select max(`test`.`t2i`.`b1`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`max(b1)`))))))
+select * from t1i where a1 in (select max(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 _it1_idx # NULL 3 100.00 Using where;
+2 MATERIALIZED t2i index it2i1,it2i3 it2i3 # NULL 5 100.00 Using where;
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`))))))
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, max(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 # # # 3 100.00 #
+2 MATERIALIZED t2i range it2i1,it2i3 # # # 3 100.00 #
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`max(b2)`))))))
+select * from t1i where (a1, a2) in (select b1, max(b2) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+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 # # # 3 100.00 #
+2 MATERIALIZED t2i range it2i1,it2i3 # # # 3 100.00 #
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`min(b2)`))))))
+select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+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 MATERIALIZED t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`max(b2)`))))))
+select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
+a1 a2
+1 - 01 2 - 01
+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 MATERIALIZED 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 MATERIALIZED 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 MATERIALIZED t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`min(b2)`))))))
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+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 @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+prepare st1 from
+"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+prepare st1 from
+"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@save_optimizer_switch;
+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 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`))))))
+select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
+a1 a2
+1 - 01 2 - 01
+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 MATERIALIZED t2i index NULL it2i3 18 NULL 5 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`))))))
+select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
+a1 a2
+1 - 01 2 - 01
+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 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+4 MATERIALIZED t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery4>`.`b1`) and (`test`.`t3`.`c2` = `<subquery4>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery3>`.`c1`) and (`test`.`t1`.`a2` = `<subquery3>`.`c2`)))))))
+select * from t1
+where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
+(a1, a2) in (select c1, c2 from t3
+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 # # # 3 100.00 #
+3 MATERIALIZED t3i index NULL # # # 4 100.00 #
+4 MATERIALIZED t2i index it2i2 # # # 5 100.00 #
+2 MATERIALIZED t2i index it2i1,it2i3 # # # 5 100.00 #
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c1`,`test`.`t3i`.`c2`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `<subquery4>`.`b1`) and (`test`.`t3i`.`c2` = `<subquery4>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery3>`.`c1`) and (`test`.`t1i`.`a2` = `<subquery3>`.`c2`)))))))
+select * from t1i
+where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
+(a1, a2) in (select c1, c2 from t3i
+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 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+6 MATERIALIZED t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery6>`.`b1`) and (`test`.`t3`.`c2` = `<subquery6>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery5>`.`c1`) and (`test`.`t1`.`a2` = `<subquery5>`.`c2`)))))))
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+where b2 in (select c2 from t3 where c2 LIKE '%02') or
+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 MATERIALIZED t3c ALL NULL NULL NULL NULL 4 100.00 Using where
+6 MATERIALIZED 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 MATERIALIZED 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`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where <expr_cache><`test`.`t3c`.`c1`,`test`.`t3c`.`c2`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),(`test`.`t3c`.`c1`,`test`.`t3c`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3c`.`c1` in <temporary table> on distinct_key where ((`test`.`t3c`.`c1` = `<subquery6>`.`b1`) and (`test`.`t3c`.`c2` = `<subquery6>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery5>`.`c1`) and (`test`.`t1`.`a2` = `<subquery5>`.`c2`)))))))
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+where b2 in (select c2 from t3 t3a where c1 = a1) or
+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 # # # 3 100.00 #
+5 MATERIALIZED t3 ALL NULL # # # 4 100.00 #
+6 MATERIALIZED t2i index it2i2 # # # 5 100.00 #
+2 MATERIALIZED t2 ALL NULL # # # 5 100.00 #
+4 MATERIALIZED t3 ALL NULL # # # 4 100.00 #
+3 MATERIALIZED t3 ALL NULL # # # 4 100.00 #
+7 UNION t1i index NULL # # # 3 100.00 #
+9 MATERIALIZED t3i index NULL # # # 4 100.00 #
+10 MATERIALIZED t2i index it2i2 # # # 5 100.00 #
+8 MATERIALIZED t2i index it2i1,it2i3 # # # 5 100.00 #
+NULL UNION RESULT <union1,7> ALL NULL # # # NULL NULL #
+Warnings:
+Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery6>`.`b1`) and (`test`.`t3`.`c2` = `<subquery6>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery5>`.`c1`) and (`test`.`t1`.`a2` = `<subquery5>`.`c2`)))))))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery8>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery8>`.`b2`)))))) and <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c1`,`test`.`t3i`.`c2`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `<subquery10>`.`b1`) and (`test`.`t3i`.`c2` = `<subquery10>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery9>`.`c1`) and (`test`.`t1i`.`a2` = `<subquery9>`.`c2`))))))))
+(select * from t1
+where (a1, a2) in (select b1, b2 from t2
+where b2 in (select c2 from t3 where c2 LIKE '%02') or
+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 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+5 MATERIALIZED 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`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery5>`.`b1`) and (`test`.`t3`.`c2` = `<subquery5>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery4>`.`c1`) and (`test`.`t1`.`a2` = `<subquery4>`.`c2`)))))))
+select * from t1
+where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
+(a1, a2) in (select c1, c2 from t3
+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 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+5 MATERIALIZED 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`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery5>`.`b1`) and (`test`.`t3`.`c2` = `<subquery5>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery4>`.`c1`) and (`test`.`t3`.`c2` = `<subquery4>`.`c2`)))))))
+select * from t1, t3
+where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
+(c1, c2) in (select c1, c2 from t3
+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 `test`.`t1`.`a1` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t3`.`c1`) = `test`.`t1`.`a1`)) union select `test`.`t2`.`b1` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t3`.`c1`) = `test`.`t2`.`b1`)))))
+select * from t3
+where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
+c1 c2
+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 MATERIALIZED 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`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where (<expr_cache><`test`.`t3c`.`c1`,`test`.`t3c`.`c2`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),<exists>(<index_lookup>(<cache>(`test`.`t3c`.`c1`) in t2i on it2i3 where (((`test`.`t2i`.`b2` > '0') or (`test`.`t2i`.`b2` = `test`.`t1`.`a2`)) and (<cache>(`test`.`t3c`.`c1`) = `test`.`t2i`.`b1`) and (<cache>(`test`.`t3c`.`c2`) = `test`.`t2i`.`b2`)))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t3c`.`c1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t3c`.`c2`))))))
+explain extended
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (((<cache>(`test`.`t1`.`a1`) = '1 - 01') or isnull('1 - 01')) and ((<cache>(`test`.`t1`.`a2`) = '2 - 01') or isnull('2 - 01')) and <is_not_null_test>('1 - 01') and <is_not_null_test>('2 - 01')))))
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+a1 a2
+1 - 01 2 - 01
+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`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (((<cache>(`test`.`t1`.`a1`) = '1 - 01') or isnull('1 - 01')) and ((<cache>(`test`.`t1`.`a2`) = '2 - 01') or isnull('2 - 01')) and <is_not_null_test>('1 - 01') and <is_not_null_test>('2 - 01')))))
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
+a1 a2
+1 - 01 2 - 01
+/******************************************************************************
+* 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 @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 `test`.`t2_16`.`b1` from `test`.`t2_16` where ((`test`.`t2_16`.`b1` > '0') and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`)))))
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select b1 from t2_16 where b1 > '0');
+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`.`a1`,`test`.`t1_16`.`a2`>(<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1`,`test`.`t2_16`.`b2` from `test`.`t2_16` where ((`test`.`t2_16`.`b1` > '0') and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`)))))
+select left(a1,7), left(a2,7)
+from t1_16
+where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
+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 MATERIALIZED 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` = `<subquery2>`.`substring(b1,1,16)`))))))
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
+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 MATERIALIZED 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` = `<subquery2>`.`group_concat(b1)`))))))
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+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 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><concat(`test`.`t1`.`a1`,'x')>(<in_optimizer>(concat(`test`.`t1`.`a1`,'x'),<exists>(select left(`test`.`t1_16`.`a1`,8) from `test`.`t1_16` where (<expr_cache><`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`>(<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1`,`test`.`t2_16`.`b2` from `test`.`t2_16` join `test`.`t2` where ((`test`.`t2`.`b2` = substr(`test`.`t2_16`.`b2`,1,6)) and <expr_cache><`test`.`t2`.`b1`>(<in_optimizer>(`test`.`t2`.`b1`,`test`.`t2`.`b1` in ( <materialize> (select `test`.`t3`.`c1` from `test`.`t3` where (`test`.`t3`.`c2` > '0') ), <primary_index_lookup>(`test`.`t2`.`b1` in <temporary table> on distinct_key where ((`test`.`t2`.`b1` = `<subquery4>`.`c1`)))))) and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`))))) and (<cache>(concat(`test`.`t1`.`a1`,'x')) = left(`test`.`t1_16`.`a1`,8))))))
+drop table t1_16, t2_16, t3_16;
+set @blob_len = 512;
+set @suffix_len = @blob_len - @prefix_len;
+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 `test`.`t2_512`.`b1` from `test`.`t2_512` where ((`test`.`t2_512`.`b1` > '0') and (<cache>(`test`.`t1_512`.`a1`) = `test`.`t2_512`.`b1`)))))
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select b1 from t2_512 where b1 > '0');
+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`.`a1`,`test`.`t1_512`.`a2`>(<in_optimizer>((`test`.`t1_512`.`a1`,`test`.`t1_512`.`a2`),<exists>(select `test`.`t2_512`.`b1`,`test`.`t2_512`.`b2` from `test`.`t2_512` where ((`test`.`t2_512`.`b1` > '0') and (<cache>(`test`.`t1_512`.`a1`) = `test`.`t2_512`.`b1`) and (<cache>(`test`.`t1_512`.`a2`) = `test`.`t2_512`.`b2`)))))
+select left(a1,7), left(a2,7)
+from t1_512
+where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
+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 MATERIALIZED 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` = `<subquery2>`.`substring(b1,1,512)`))))))
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
+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 MATERIALIZED 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` = `<subquery2>`.`group_concat(b1)`))))))
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+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 MATERIALIZED 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` = `<subquery2>`.`group_concat(b1)`))))))
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+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 `test`.`t2_1024`.`b1` from `test`.`t2_1024` where ((`test`.`t2_1024`.`b1` > '0') and (<cache>(`test`.`t1_1024`.`a1`) = `test`.`t2_1024`.`b1`)))))
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select b1 from t2_1024 where b1 > '0');
+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`.`a1`,`test`.`t1_1024`.`a2`>(<in_optimizer>((`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a2`),<exists>(select `test`.`t2_1024`.`b1`,`test`.`t2_1024`.`b2` from `test`.`t2_1024` where ((`test`.`t2_1024`.`b1` > '0') and (<cache>(`test`.`t1_1024`.`a1`) = `test`.`t2_1024`.`b1`) and (<cache>(`test`.`t1_1024`.`a2`) = `test`.`t2_1024`.`b2`)))))
+select left(a1,7), left(a2,7)
+from t1_1024
+where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
+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`,<exists>(select substr(`test`.`t2_1024`.`b1`,1,1024) from `test`.`t2_1024` where ((`test`.`t2_1024`.`b1` > '0') and (<cache>(`test`.`t1_1024`.`a1`) = substr(`test`.`t2_1024`.`b1`,1,1024))))))
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
+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 MATERIALIZED 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` = `<subquery2>`.`group_concat(b1)`))))))
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+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 MATERIALIZED 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` = `<subquery2>`.`group_concat(b1)`))))))
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+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 `test`.`t2_1025`.`b1` from `test`.`t2_1025` where ((`test`.`t2_1025`.`b1` > '0') and (<cache>(`test`.`t1_1025`.`a1`) = `test`.`t2_1025`.`b1`)))))
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select b1 from t2_1025 where b1 > '0');
+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`.`a1`,`test`.`t1_1025`.`a2`>(<in_optimizer>((`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a2`),<exists>(select `test`.`t2_1025`.`b1`,`test`.`t2_1025`.`b2` from `test`.`t2_1025` where ((`test`.`t2_1025`.`b1` > '0') and (<cache>(`test`.`t1_1025`.`a1`) = `test`.`t2_1025`.`b1`) and (<cache>(`test`.`t1_1025`.`a2`) = `test`.`t2_1025`.`b2`)))))
+select left(a1,7), left(a2,7)
+from t1_1025
+where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
+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`,<exists>(select substr(`test`.`t2_1025`.`b1`,1,1025) from `test`.`t2_1025` where ((`test`.`t2_1025`.`b1` > '0') and (<cache>(`test`.`t1_1025`.`a1`) = substr(`test`.`t2_1025`.`b1`,1,1025))))))
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
+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 MATERIALIZED 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` = `<subquery2>`.`group_concat(b1)`))))))
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+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 MATERIALIZED 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` = `<subquery2>`.`group_concat(b1)`))))))
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+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');
+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 MATERIALIZED 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`.`a1`,`test`.`t1bit`.`a2`>(<in_optimizer>((`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`),(`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`) in ( <materialize> (select `test`.`t2bit`.`b1`,`test`.`t2bit`.`b2` from `test`.`t2bit` ), <primary_index_lookup>(`test`.`t1bit`.`a1` in <temporary table> on distinct_key where ((`test`.`t1bit`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1bit`.`a2` = `<subquery2>`.`b2`))))))
+select bin(a1), bin(a2)
+from t1bit
+where (a1, a2) in (select b1, b2 from t2bit);
+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`.`a1`,`test`.`t1bb`.`a2`>(<in_optimizer>((`test`.`t1bb`.`a1`,`test`.`t1bb`.`a2`),<exists>(select `test`.`t2bb`.`b1`,`test`.`t2bb`.`b2` from `test`.`t2bb` where ((<cache>(`test`.`t1bb`.`a1`) = `test`.`t2bb`.`b1`) and (<cache>(`test`.`t1bb`.`a2`) = `test`.`t2bb`.`b2`)))))
+select bin(a1), a2
+from t1bb
+where (a1, a2) in (select b1, b2 from t2bb);
+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.
+******************************************************************************/
+# 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);
+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 MATERIALIZED 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` = `<subquery2>`.`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 MATERIALIZED 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` = `<subquery2>`.`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 MATERIALIZED 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` = `<subquery2>`.`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 MATERIALIZED 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` = `<subquery2>`.`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 MATERIALIZED 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` = `<subquery2>`.`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`,`test`.`t1`.`b`,max(`test`.`t1`.`b`),max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`c` from `test`.`t2` where (<nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`,max(`test`.`t1`.`b`),max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where (max(`test`.`t1`.`b`) = `test`.`t3`.`e`) having (<cache>(`test`.`t2`.`d`) >= <ref_null_helper>(`test`.`t3`.`e`)))))) and (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`c`)))))
+select a from t1 group by a
+having a in (select c from t2 where d >= some(select e from t3 where max(b)=e));
+a
+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 `test`.`t2`.`c` from `test`.`t2` where (<nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`)))))) and (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`c`)))))
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+a
+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 max(b1) from t2 group by b1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 system NULL NULL NULL NULL 0 const row not found
+select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+min(a1)
+NULL
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+explain select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+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 0 const row not found
+select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+min(a1)
+NULL
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED 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)
+NULL
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+# with MariaDB and MWL#90, this particular case is solved:
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+select min(a1) from t1 where 7 in (select b1 from t2);
+min(a1)
+NULL
+# but when we go around MWL#90 code, the problem still shows up:
+explain select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
+min(a1)
+NULL
+set @@optimizer_switch= @save_optimizer_switch;
+drop table t1,t2;
+create table t1 (a char(2), b varchar(10));
+insert into t1 values ('a', 'aaa');
+insert into t1 values ('aa', 'aaaa');
+explain select a,b from t1 where b in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED 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;
+#
+# BUG#49630: Segfault in select_describe() with double
+# nested subquery and materialization
+#
+CREATE TABLE t1 (t1i int);
+CREATE TABLE t2 (t2i int);
+CREATE TABLE t3 (t3i int);
+CREATE TABLE t4 (t4i int);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1),(2);
+INSERT INTO t3 VALUES (1),(2);
+INSERT INTO t4 VALUES (1),(2);
+
+EXPLAIN
+SELECT t1i
+FROM t1 JOIN t4 ON t1i=t4i
+WHERE (t1i) IN (
+SELECT t2i
+FROM t2
+WHERE (t2i) IN (
+SELECT max(t3i)
+FROM t3
+GROUP BY t3i
+)
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using temporary
+DROP TABLE t1,t2,t3,t4;
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT,
+col_int_nokey INTEGER,
+col_int_key INTEGER,
+col_varchar_key VARCHAR(1),
+PRIMARY KEY (pk),
+KEY (col_int_key),
+KEY (col_varchar_key, col_int_key)
+)
+;
+INSERT INTO t1 (
+col_int_key, col_int_nokey, col_varchar_key
+)
+VALUES
+(2, NULL, 'w'),
+(9, 7, 'm'),
+(3, 9, 'm'),
+(9, 7, 'k'),
+(NULL, 4, 'r'),
+(9, 2, 't'),
+(3, 6, 'j'),
+(8, 8, 'u'),
+(8, NULL, 'h'),
+(53, 5, 'o'),
+(0, NULL, NULL),
+(5, 6, 'k'),
+(166, 188, 'e'),
+(3, 2, 'n'),
+(0, 1, 't'),
+(1, 1, 'c'),
+(9, 0, 'm'),
+(5, 9, 'y'),
+(6, NULL, 'f'),
+(2, 4, 'd')
+;
+SELECT table2.col_varchar_key AS field1,
+table2.col_int_nokey AS field2
+FROM ( t1 AS table1 LEFT OUTER JOIN t1 AS table2
+ON (table2.col_varchar_key = table1.col_varchar_key ) )
+WHERE table1.pk = 6
+HAVING ( field2 ) IN
+( SELECT SUBQUERY2_t2.col_int_nokey AS SUBQUERY2_field2
+FROM ( t1 AS SUBQUERY2_t1 JOIN t1 AS SUBQUERY2_t2
+ON (SUBQUERY2_t2.col_varchar_key = SUBQUERY2_t1.col_varchar_key ) ) )
+ORDER BY field2
+;
+field1 field2
+t 1
+t 2
+drop table t1;
+#
+# BUG#53103: MTR test ps crashes in optimize_cond()
+# when running with --debug
+#
+CREATE TABLE t1(track varchar(15));
+INSERT INTO t1 VALUES ('CAD'), ('CAD');
+PREPARE STMT FROM
+"SELECT 1 FROM t1
+ WHERE
+ track IN (SELECT track FROM t1
+ GROUP BY track
+ HAVING track>='CAD')";
+EXECUTE STMT ;
+1
+1
+1
+EXECUTE STMT ;
+1
+1
+1
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
+# End of BUG#53103
+#
+# BUG#54511 - Assertion failed: cache != 0L in file
+# sql_select.cc::sub_select_cache on HAVING
+#
+CREATE TABLE t1 (i int(11));
+CREATE TABLE t2 (c char(1));
+CREATE TABLE t3 (c char(1));
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES ('a'), ('b');
+INSERT INTO t3 VALUES ('x'), ('y');
+SELECT COUNT( i ),i
+FROM t1
+HAVING ('c')
+IN (SELECT t2.c FROM (t2 JOIN t3));
+COUNT( i ) i
+DROP TABLE t1,t2,t3;
+# End BUG#54511
+#
+# BUG#56367 - Assertion exec_method != EXEC_MATERIALIZATION...
+# on subquery in FROM
+#
+CREATE TABLE t1 (a INTEGER);
+CREATE TABLE t2 (b INTEGER);
+INSERT INTO t2 VALUES (1);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+explain SELECT a FROM (
+SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+3 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT a FROM (
+SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+a
+set optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1, t2;
+# End BUG#56367
+#
+# Bug#59833 - materialization=on/off leads to different result set
+# when using IN
+#
+CREATE TABLE t1 (
+pk int NOT NULL,
+f1 int DEFAULT NULL,
+PRIMARY KEY (pk)
+) ENGINE=MyISAM;
+CREATE TABLE t2 (
+pk int NOT NULL,
+f1 int DEFAULT NULL,
+PRIMARY KEY (pk)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (10,0);
+INSERT INTO t2 VALUES (10,0),(11,0);
+explain SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t1 system NULL NULL NULL NULL 1
+SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+f1 pk pk
+DROP TABLE t1, t2;
+# End Bug#59833
+#
+# Bug#11852644 - CRASH IN ITEM_REF::SAVE_IN_FIELD ON SELECT DISTINCT
+#
+CREATE TABLE t1 (
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_varchar_key (col_varchar_key))
+;
+INSERT INTO t1 VALUES
+('v','v'),('r','r');
+CREATE TABLE t2 (
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_varchar_key(col_varchar_key))
+;
+INSERT INTO t2 VALUES
+('r','r'),('c','c');
+CREATE VIEW v3 AS SELECT * FROM t2;
+SELECT DISTINCT alias2.col_varchar_key
+FROM t1 AS alias1 JOIN v3 AS alias2
+ON alias2.col_varchar_key = alias1.col_varchar_key
+HAVING col_varchar_key IN (SELECT col_varchar_nokey FROM t2)
+;
+col_varchar_key
+r
+DROP TABLE t1, t2;
+DROP VIEW v3;
+# End Bug#11852644
+
+# Bug#12668294 - GROUP BY ON EMPTY RESULT GIVES EMPTY ROW
+# INSTEAD OF NULL WHEN MATERIALIZATION ON
+
+CREATE TABLE t1 (col_int_nokey INT) ENGINE=MEMORY;
+CREATE TABLE t2 (col_int_nokey INT) ENGINE=MEMORY;
+INSERT INTO t2 VALUES (8),(7);
+CREATE TABLE t3 (col_int_nokey INT) ENGINE=MEMORY;
+INSERT INTO t3 VALUES (7);
+SELECT MIN(t3.col_int_nokey),t1.col_int_nokey AS field3
+FROM t3
+LEFT JOIN t1
+ON t1.col_int_nokey
+WHERE (194, 200) IN (
+SELECT SQ4_alias1.col_int_nokey,
+SQ4_alias2.col_int_nokey
+FROM t2 AS SQ4_alias1
+JOIN
+t2 AS SQ4_alias2
+ON SQ4_alias2.col_int_nokey = 5
+)
+GROUP BY field3 ;
+MIN(t3.col_int_nokey) field3
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+CREATE TABLE t1 (f1 INT, f2 DECIMAL(5,3)) ENGINE=MyISAM;
+INSERT INTO t1 (f1, f2) VALUES (1, 1.789);
+INSERT INTO t1 (f1, f2) VALUES (13, 1.454);
+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 @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch=@optimizer_switch_local_default;
+SET @@optimizer_switch='semijoin=on,materialization=on';
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+COUNT(*)
+2
+set @@optimizer_switch= @save_optimizer_switch;
+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 @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch=@optimizer_switch_local_default;
+SET @@optimizer_switch='semijoin=on,materialization=on';
+EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Rowid-ordered scan
+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;
+set optimizer_switch=@save_optimizer_switch;
+#
+# 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,in_to_exists=on';
+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 MATERIALIZED 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;
+set optimizer_switch='firstmatch=on';
+#
+# MWL#90, review feedback: check what happens when the subquery
+# looks like candidate for MWL#90 checking at the first glance
+# but then subselect_hash_sj_engine::init_permanent() discovers
+# that it's not possible to perform duplicate removal for the
+# selected datatypes, and so materialization isn't applicable after
+# all.
+#
+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));
+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)));
+explain select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 Using where
+select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+drop table t1_1024, t2_1024;
+#
+# BUG##836491: Crash in Item_field::Item_field from add_ref_to_table_cond() with semijoin+materialization
+#
+CREATE TABLE t1 (c int, d varchar(1), KEY(d)) ;
+INSERT INTO t1 VALUES (2,'x'),(2,'x'),(2,'j'),(2,'c');
+CREATE TABLE t2 (a int, d varchar(1)) ;
+INSERT INTO t2 VALUES (1,'x');
+CREATE TABLE t3 (d varchar(1)) ;
+INSERT INTO t3 VALUES ('x'),('x'),('j'),('c');
+SELECT t2.a, t1.c
+FROM t1, t2
+WHERE t2.d IN ( SELECT d FROM t3 )
+AND t1.d = t2.d
+GROUP BY 1 , 2;
+a c
+1 2
+drop table t1,t2,t3;
+#
+# BUG#836523: Crash in JOIN::get_partial_cost_and_fanout with semijoin+materialization
+#
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('a'),('a');
+CREATE TABLE t2 (a varchar(1));
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (1),(2);
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('a'),('a');
+SELECT t1.a
+FROM t1
+WHERE t1.a IN (
+SELECT t2.a
+FROM t2, t3
+)
+HAVING a IN (
+SELECT a
+FROM t4
+);
+a
+DROP TABLE t1, t2, t3, t4;
+#
+# BUG#836507: Crash in setup_sj_materialization_part1() with semijoin+materialization
+#
+CREATE TABLE t1 (a int) ;
+INSERT IGNORE INTO t1 VALUES (1),(1);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1);
+CREATE TABLE t3 (a int);
+CREATE TABLE t4 (a int);
+INSERT INTO t4 VALUES (2),(2);
+CREATE TABLE t5 (a int);
+INSERT INTO t5 VALUES (1);
+SELECT * FROM t1
+WHERE (a) IN (
+SELECT t5.a
+FROM (
+t2
+LEFT JOIN ( t3 , t4 )
+ON 1 = 1
+)
+JOIN t5
+);
+a
+1
+1
+DROP TABLE t1,t2,t3,t4,t5;
+#
+# BUG#836532: Crash in Item_equal_fields_iterator::get_curr_field with semijoin+materialization
+#
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES ('a'),('a');
+Warnings:
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 1
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 2
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('m'),('o');
+CREATE TABLE t3 (a varchar(1) , b varchar(1) ) ;
+INSERT INTO t3 VALUES ('b','b');
+CREATE TABLE t5 (a varchar(1), KEY (a)) ;
+INSERT INTO t5 VALUES ('d'),('e');
+SELECT *
+FROM t2
+WHERE t2.a = ALL (
+SELECT t4.a
+FROM t4
+WHERE t4.a IN (
+SELECT t3.a
+FROM t3 , t5
+WHERE ( t5.a = t3.b )
+)
+);
+a
+0
+0
+DROP TABLE t2,t3,t4,t5;
+#
+# BUG#860300: Second crash with get_fanout_with_deps() with semijoin + materialization
+#
+set @tmp_860300=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f2 int);
+INSERT INTO t1 VALUES (9),(6);
+CREATE TABLE t3 (f4 int);
+CREATE TABLE t4 (f6 varchar(1));
+SELECT *
+FROM t3
+WHERE 'h' IN (SELECT f6
+FROM t4
+WHERE 5 IN (SELECT f2 FROM t1)
+GROUP BY t4.f6);
+f4
+DROP TABLE t1,t3,t4;
+set optimizer_switch=@tmp_860300;
+#
+# BUG#860535: Assertion `keypart_map' failed in mi_rkey with semijoin
+#
+set @tmp_860535=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f3 int) ;
+INSERT INTO t1 VALUES (1),(7);
+CREATE TABLE t2 (f3 int , f5 varchar(1), KEY (f3)) ;
+INSERT INTO t2 VALUES (7,'b');
+CREATE TABLE t3 (f3 int , f4 varchar(1) , KEY(f3), KEY (f4,f3)) ;
+INSERT INTO t3 VALUES (1,'t'),(7,'g');
+CREATE TABLE t4
+SELECT f3
+FROM t1 WHERE ( f3 ) NOT IN (
+SELECT f3
+FROM t2
+WHERE f5 IN (
+SELECT f4
+FROM t3
+WHERE t3.f3 < 3
+)
+);
+SELECT * FROM t4;
+f3
+1
+7
+DROP TABLE t1, t2, t3, t4;
+set optimizer_switch=@tmp_860535;
+#
+# BUG#860553: Crash in create_ref_for_key with semijoin + materialization
+#
+CREATE TABLE t1 (f1 int) ;
+CREATE TABLE t2 (f5 varchar(52) NOT NULL) ;
+CREATE TABLE t3 (f1 varchar(3), f4 varchar(52) , KEY (f4), PRIMARY KEY (f1));
+CREATE TABLE t4 (f3 int, KEY (f3));
+INSERT INTO t4 VALUES (17),(20);
+CREATE TABLE t5 (f2 int);
+INSERT INTO t5 VALUES (0),(0);
+SELECT *
+FROM t1
+JOIN t2
+ON ( t2.f5 ) IN (
+SELECT t3.f4
+FROM t3
+WHERE ( 1 ) IN (
+SELECT t4.f3
+FROM t4 , t5
+)
+);
+f1 f5
+DROP TABLE t1, t2, t3, t4, t5;
+#
+# BUG#868908: Crash in check_simple_equality() with semijoin + materialization + prepared statement
+#
+CREATE TABLE t1 ( a int );
+CREATE TABLE t3 ( b int, c int) ;
+CREATE TABLE t2 ( a int ) ;
+CREATE TABLE t4 ( a int , c int) ;
+PREPARE st1 FROM "
+SELECT STRAIGHT_JOIN *
+FROM t1
+WHERE ( 3 ) IN (
+ SELECT t3.b
+ FROM t3
+ LEFT JOIN (
+ t2 STRAIGHT_JOIN t4 ON ( t4.c = t2.a )
+ ) ON ( t4.a = t3.c )
+);
+";
+EXECUTE st1;
+a
+EXECUTE st1;
+a
+DROP TABLE t1,t2,t3,t4;
+#
+# BUG#901032: Wrong result for MIN/MAX on an indexed column with materialization and semijoin
+#
+CREATE TABLE t1 ( a INT, KEY(a) );
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 ( b INT );
+INSERT INTO t2 VALUES (2);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (2);
+SELECT MIN(a) FROM t1, t2 WHERE b IN (SELECT c FROM t3 GROUP BY c);
+MIN(a)
+1
+DROP TABLE t1,t2,t3;
+#
+#
+# BUG#902632: Crash or invalid read at st_join_table::cleanup, st_table::disable_keyread
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 ( b INT );
+INSERT INTO t2 VALUES (3), (4);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (5), (6);
+SELECT * FROM t1 WHERE EXISTS (
+SELECT DISTINCT b FROM t2
+WHERE b <= a
+AND b IN ( SELECT c FROM t3 GROUP BY c )
+);
+a
+DROP TABLE t1,t2,t3;
+#
+# BUG#901506: Crash in TABLE_LIST::print on EXPLAIN EXTENDED
+#
+CREATE TABLE t1 ( a INT, KEY(a) );
+INSERT INTO t1 VALUES (8);
+EXPLAIN EXTENDED
+SELECT * FROM t1
+WHERE a IN ( SELECT MIN(a) 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 NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select 8 AS `a` from `test`.`t1` where <expr_cache><8>(<in_optimizer>(8,<exists>(select min(`test`.`t1`.`a`) from `test`.`t1` having (<cache>(8) = <ref_null_helper>(min(`test`.`t1`.`a`))))))
+DROP TABLE t1;
+#
+# BUG#904432: Wrong result with LEFT JOIN, constant table, semijoin=ON,materialization=ON
+#
+CREATE TABLE t1 ( a INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4);
+CREATE TABLE t2 ( b INT NOT NULL, c INT );
+INSERT INTO t2 VALUES (4,2),(4,2),(4,4),(1,1);
+SELECT * FROM t1 LEFT JOIN t2 ON ( a = b )
+WHERE a IN ( SELECT c FROM t2 );
+a b c
+4 4 2
+4 4 2
+4 4 4
+DROP TABLE t1,t2;
+#
+# BUG#922254: Assertion `0' failed at item_cmpfunc.cc:5899: Item* Item_equal::get_first(JOIN_TAB*, Item*)
+#
+CREATE TABLE t1 ( a VARCHAR(3) );
+CREATE TABLE t2 ( b VARCHAR(3), c VARCHAR(8), KEY(c) );
+INSERT INTO t2 VALUES ('USA','Abilene'),('USA','Akron');
+EXPLAIN
+SELECT * FROM
+( SELECT * FROM t1 ) AS alias1,
+t2 AS alias2
+WHERE b = a AND a IN (
+SELECT alias3.c
+FROM t2 AS alias3, t2 AS alias4
+WHERE alias4.c = alias3.b
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+3 MATERIALIZED alias3 ALL NULL NULL NULL NULL 2
+3 MATERIALIZED alias4 index c c 11 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
+DROP TABLE t1,t2;
+#
+# BUG#928048: Query containing IN subquery with OR in the where clause returns a wrong result
+#
+create table t1 (a int, b int);
+insert into t1 values (7,5), (3,3), (5,4), (9,3);
+create table t2 (a int, b int, index i_a(a));
+insert into t2 values
+(4,2), (7,9), (7,4), (3,1), (5,3), (3,1), (9,4), (8,1);
+explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1);
+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 MATERIALIZED t2 ALL i_a NULL NULL NULL 8 Using where
+select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1);
+a b
+7 5
+3 3
+drop table t1,t2;
+#
+# BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(8);
+SELECT STRAIGHT_JOIN MIN(a) FROM t1
+WHERE a IN (
+SELECT a FROM t1
+WHERE 'condition'='impossible'
+ );
+MIN(a)
+NULL
+DROP TABLE t1;
+#
+# BUG#938131: Subquery materialization is not used in CREATE TABLE SELECT
+#
+CREATE TABLE t1(a int);
+INSERT INTO t1 values(1),(2);
+CREATE TABLE t2(a int);
+INSERT INTO t2 values(1),(2);
+# Should use Materialization:
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
+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 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using temporary
+flush status;
+CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
+SHOW STATUS LIKE 'Created_tmp_tables';
+Variable_name Value
+Created_tmp_tables 3
+DROP TABLE t1,t2,t3;
+#
+# BUG#939009: Crash with aggregate function in IN subquery
+#
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='materialization=on,semijoin=on';
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (7,1), (4,2), (7,7);
+CREATE TABLE t2 ( c INT );
+INSERT INTO t2 VALUES (4), (7), (6);
+EXPLAIN EXTENDED
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where ((`test`.`t1`.`b` = 7) and (`test`.`t1`.`a` = `<subquery2>`.`MAX(c)`) and (isnull(`<subquery2>`.`MAX(c)`) or (`<subquery2>`.`MAX(c)` = 7)))
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
+a b
+7 7
+EXPLAIN
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
+a b
+SET optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2;
+#
+# BUG#946055: Crash with semijoin IN subquery when hash join is used
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (7);
+CREATE TABLE t2 (b int, c int, d varchar(1), e varchar(1), KEY (c), KEY (d, c));
+INSERT INTO t2 VALUES
+(4,2,'v','v'), (6,1,'v','v'), (0,5,'x','x'), (7,1,'x','x'),
+(7,3,'i','i'), (7,1,'e','e'), (1,4,'p','p'), (1,2,'j','j');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=2;
+EXPLAIN
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 index NULL c 5 NULL 8 Using where; Using index
+2 MATERIALIZED s2 ref d d 4 const 1 Using where; Using index
+2 MATERIALIZED s1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+3 SUBQUERY t2 ALL NULL NULL NULL NULL 8
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+a c
+7 1
+7 1
+7 1
+SET optimizer_switch='join_cache_hashed=on';
+SET join_cache_level=4;
+EXPLAIN
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 index NULL c 5 NULL 8 Using where; Using index
+2 MATERIALIZED s2 ref d d 4 const 1 Using where; Using index
+2 MATERIALIZED s1 hash_ALL NULL #hash#$hj 5 test.s2.d 8 Using where; Using join buffer (flat, BNLH join)
+3 SUBQUERY t2 ALL NULL NULL NULL NULL 8
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+a c
+7 1
+7 1
+7 1
+SET optimizer_switch=@save_optimizer_switch;
+SET join_cache_level=@save_join_cache_level;
+DROP TABLE t1,t2;
+#
+# BUG#952297: Server crashes on 2nd execution of PS in Field::is_null with semijoin+materialization
+#
+CREATE TABLE t1 ( a VARCHAR(1) );
+INSERT INTO t1 VALUES ('y'),('z');
+CREATE TABLE t2 ( b VARCHAR(1), c VARCHAR(1) );
+INSERT INTO t2 VALUES ('v','v'),('v','v');
+CREATE VIEW v2 AS SELECT * FROM t2;
+PREPARE ps FROM '
+SELECT a FROM t1, v2
+WHERE ( c, b ) IN ( SELECT b, b FROM t2 )
+GROUP BY a ';
+EXECUTE ps;
+a
+y
+z
+EXECUTE ps;
+a
+y
+z
+DROP VIEW v2;
+DROP TABLE t1, t2;
+#
+# BUG#1000269: Wrong result (extra rows) with semijoin+materialization, IN subqueries, join_cache_level>0
+#
+CREATE TABLE t1 (a1 VARCHAR(1), a2 VARCHAR(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('b','b'),('e','e');
+CREATE TABLE t2 (b1 VARCHAR(1), b2 VARCHAR(1), KEY(b1)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('v','v'),('s','s'),('l','l'), ('y','y'),('c','c'),('i','i');
+SELECT * FROM t1, t2 WHERE b1 IN ( SELECT b2 FROM t2 WHERE b1 > 'o' ) AND ( b1 < 'l' OR a1 IN ('b','c') );
+a1 a2 b1 b2
+b b v v
+b b s s
+b b y y
+DROP TABLE t1,t2;
+# This must be at the end:
+set optimizer_switch=@subselect_sj_mat_tmp;
+set join_cache_level=@save_join_cache_level;
+set @subselect_mat_test_optimizer_switch_value=null;
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+create table t0 (a int);
+insert into t0 values (0),(1),(2);
+create table t1 (a int);
+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 MATERIALIZED 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 MATERIALIZED 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 MATERIALIZED 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 ALL NULL NULL NULL NULL 1 Using where
+2 MATERIALIZED 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 ALL NULL NULL NULL NULL 1 Using where
+2 MATERIALIZED 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#611622/BUG#52344: Subquery materialization: Assertion
+# if subquery in on-clause of outer join
+#
+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 t2 t3 ON (8, 4) IN (SELECT c1, c1 FROM t1)";
+EXECUTE st1;
+c2 c2
+10 NULL
+EXECUTE st1;
+c2 c2
+10 NULL
+DROP TABLE t1, t2;
+#
+# Testcase backport: 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);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition
+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#724228: Wrong result with materialization=on and three aggregates in maria-5.3-mwl90
+#
+CREATE TABLE t1 ( f2 int(11)) ;
+INSERT IGNORE INTO t1 VALUES ('7'),('9'),('7'),('4'),('2'),('6'),('8'),('5'),('6'),('188'),('2'),('1'),('1'),('0'),('9'),('4');
+CREATE TABLE t2 ( f1 int(11), f2 int(11)) ENGINE=MyISAM;
+INSERT IGNORE INTO t2 VALUES ('1','1');
+CREATE TABLE t3 ( f1 int(11), f2 int(11), f3 int(11), PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES ('16','6','1'),('18','3','4'),('19',NULL,'9'),('20','0','6'),('41','2','0'),('42','2','5'),('43','9','6'),('44','7','4'),('45','1','4'),('46','222','238'),('47','3','6'),('48','6','6'),('49',NULL,'1'),('50','5','1');
+SET @_save_join_cache_level = @@join_cache_level;
+SET @_save_optimizer_switch = @@optimizer_switch;
+SET join_cache_level = 1;
+SET optimizer_switch='materialization=on';
+SELECT f1 FROM t3
+WHERE
+f1 NOT IN (SELECT MAX(f2) FROM t1) AND
+f3 IN (SELECT MIN(f1) FROM t2) AND
+f1 IN (SELECT COUNT(f2) FROM t1);
+f1
+16
+SET @@join_cache_level = @_save_join_cache_level;
+SET @@optimizer_switch = @_save_optimizer_switch;
+drop table t1, t2, t3;
+#
+# LPBUG#719198 Ordered_key::cmp_key_with_search_key(rownum_t): Assertion `!compare_pred[i]->null_value'
+# failed with subquery on both sides of NOT IN and materialization
+#
+CREATE TABLE t1 (f1a int, f1b int) ;
+INSERT IGNORE INTO t1 VALUES (1,1),(2,2);
+CREATE TABLE t2 ( f2 int);
+INSERT IGNORE INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (f3a int, f3b int);
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+EXPLAIN
+SELECT * FROM t2 WHERE (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+3 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT * FROM t2 WHERE (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1);
+f2
+EXPLAIN
+SELECT (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1);
+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
+3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1);
+(SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1)
+NULL
+EXPLAIN
+SELECT * FROM t2 WHERE (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+3 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT * FROM t2 WHERE (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1);
+f2
+EXPLAIN
+SELECT (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1);
+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
+3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+drop table t1, t2, t3;
+#
+# LPBUG#730604 Assertion `bit < (map)->n_bits' failed in maria-5.3 with
+# partial_match_rowid_merge
+#
+CREATE TABLE t1 (f1 int NOT NULL, f2 int, f3 int) ;
+CREATE TABLE t2 (f1 int NOT NULL, f2 int, f3 int) ;
+INSERT INTO t1 VALUES (60, 3, null), (61, null, 77);
+INSERT INTO t2 VALUES (1000,6,2);
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+EXPLAIN
+SELECT (f1, f2, f3) NOT IN
+(SELECT COUNT(DISTINCT f2), f1, f3 FROM t1 GROUP BY f1, f3)
+FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 Using filesort
+SELECT (f1, f2, f3) NOT IN
+(SELECT COUNT(DISTINCT f2), f1, f3 FROM t1 GROUP BY f1, f3)
+FROM t2;
+(f1, f2, f3) NOT IN
+(SELECT COUNT(DISTINCT f2), f1, f3 FROM t1 GROUP BY f1, f3)
+1
+drop table t1, t2;
+#
+# LPBUG#702301: MAX in select + always false WHERE with SQ
+#
+CREATE TABLE t1 (a int, b int, KEY (b));
+INSERT INTO t1 VALUES (3,1), (4,2);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (7), (8);
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+max_res
+NULL
+EXPLAIN EXTENDED
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL b 5 NULL 2 100.00 Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1003 select max(`test`.`t1`.`b`) AS `max_res` from `test`.`t1` where <expr_cache><9>(<in_optimizer>(9,9 in ( <materialize> (select `test`.`t2`.`a` from `test`.`t2` ), <primary_index_lookup>(9 in <temporary table> on distinct_key where ((9 = `<subquery2>`.`a`))))))
+set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off';
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+max_res
+NULL
+EXPLAIN EXTENDED
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL b 5 NULL 2 100.00 Using index
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select max(`test`.`t1`.`b`) AS `max_res` from `test`.`t1` where <expr_cache><9>(<in_optimizer>(9,<exists>(select `test`.`t2`.`a` from `test`.`t2` where (9 = `test`.`t2`.`a`))))
+DROP TABLE t1,t2;
+#
+# LPBUG#825095: Wrong result with materialization and NOT IN with 2 expressions
+#
+CREATE TABLE t1 (a int,b int);
+INSERT INTO t1 VALUES (4,4),(4,2);
+CREATE TABLE t2 (b int, a int);
+INSERT INTO t2 VALUES (4,3),(8,4);
+set @@optimizer_switch='semijoin=off,in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN SELECT *
+FROM t1
+WHERE (a, b) NOT IN (SELECT a, b FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT *
+FROM t1
+WHERE (a, b) NOT IN (SELECT a, b FROM t2);
+a b
+4 4
+4 2
+EXPLAIN
+SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
+FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
+FROM t1;
+a b sq
+4 4 1
+4 2 1
+drop table t1, t2;
diff --git a/mysql-test/r/subselect_mat_cost.result b/mysql-test/r/subselect_mat_cost.result
new file mode 100644
index 00000000000..900bad0183a
--- /dev/null
+++ b/mysql-test/r/subselect_mat_cost.result
@@ -0,0 +1,565 @@
+set @subselect_mat_cost=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set log_slow_time=0.1;
+TEST GROUP 1:
+Typical cases of in-to-exists and materialization subquery strategies
+=====================================================================
+drop database if exists world;
+set names utf8;
+create database world;
+use world;
+CREATE TABLE Country (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL,
+PRIMARY KEY (Code),
+UNIQUE INDEX (Name)
+);
+CREATE TABLE City (
+ID int(11) NOT NULL auto_increment,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID),
+INDEX (Population),
+INDEX (Country)
+);
+CREATE TABLE CountryLanguage (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0',
+PRIMARY KEY (Country, Language),
+INDEX (Percentage)
+);
+Make the schema and data more diverse by adding more indexes, nullable
+columns, and NULL data.
+create index SurfaceArea on Country(SurfaceArea);
+create index Language on CountryLanguage(Language);
+create index CityName on City(Name);
+alter table City change population population int(11) null default 0;
+select max(id) from City into @max_city_id;
+insert into City values (@max_city_id + 1,'Kilifarevo','BGR',NULL);
+SELECT COUNT(*) FROM Country;
+COUNT(*)
+239
+SELECT COUNT(*) FROM City;
+COUNT(*)
+4080
+SELECT COUNT(*) FROM CountryLanguage;
+COUNT(*)
+984
+set @@optimizer_switch = 'in_to_exists=on,semijoin=on,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on';
+
+1. Subquery in a disjunctive WHERE clause of the outer query.
+
+
+Q1.1m:
+MATERIALIZATION: there are too many rows in the outer query
+to be looked up in the inner table.
+EXPLAIN
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+Name LIKE 'L%') AND
+surfacearea > 1000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country ALL Name,SurfaceArea NULL NULL NULL 239 Using where
+2 MATERIALIZED City ALL Population,Country NULL NULL NULL 4080 Using where
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+Name LIKE 'L%') AND
+surfacearea > 1000000;
+Name
+Algeria
+Angola
+Argentina
+Australia
+Bolivia
+Brazil
+Egypt
+South Africa
+Ethiopia
+Indonesia
+India
+Iran
+Canada
+Kazakstan
+China
+Colombia
+Congo, The Democratic Republic of the
+Libyan Arab Jamahiriya
+Mali
+Mauritania
+Mexico
+Mongolia
+Niger
+Peru
+Saudi Arabia
+Sudan
+Chad
+Russian Federation
+United States
+Q1.1e:
+IN-EXISTS: the materialization cost is the same as above, but
+there are much fewer outer rows to be looked up, thus the
+materialization cost is too high to compensate for fast lookups.
+EXPLAIN
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+Name LIKE 'L%') AND
+surfacearea > 10*1000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range Name,SurfaceArea SurfaceArea 4 NULL 5 Using index condition; Using where; Rowid-ordered scan
+2 DEPENDENT SUBQUERY City index_subquery Population,Country Country 3 func 18 Using where
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+Name LIKE 'L%') AND
+surfacearea > 10*1000000;
+Name
+Russian Federation
+
+Q1.2m:
+MATERIALIZATION: the IN predicate is pushed (attached) to the last table
+in the join order (Country, City), therefore there are too many row
+combinations to filter by re-executing the subquery for each combination.
+EXPLAIN
+SELECT *
+FROM Country, City
+WHERE City.Country = Country.Code AND
+Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+(City.Name IN
+(select Language from CountryLanguage where Percentage > 50) OR
+City.name LIKE '%Island%');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 Using where
+1 PRIMARY City ref Country Country 3 world.Country.Code 18 Using where
+2 MATERIALIZED CountryLanguage ALL Percentage,Language NULL NULL NULL 984 Using where
+SELECT *
+FROM Country, City
+WHERE City.Country = Country.Code AND
+Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+(City.Name IN
+(select Language from CountryLanguage where Percentage > 50) OR
+City.name LIKE '%Island%');
+Code Name SurfaceArea Population Capital ID Name Country population
+CCK Cocos (Keeling) Islands 14.00 600 2317 2317 West Island CCK 167
+Q1.2e:
+IN_EXISTS: join order is the same, but the left IN operand refers to
+only the first table in the join order (Country), so there are much
+fewer rows to filter by subquery re-execution.
+EXPLAIN
+SELECT *
+FROM Country, City
+WHERE City.Country = Country.Code AND
+Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+(Country.Name IN
+(select Language from CountryLanguage where Percentage > 50) OR
+Country.name LIKE '%Island%');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 Using where
+1 PRIMARY City ref Country Country 3 world.Country.Code 18
+2 DEPENDENT SUBQUERY CountryLanguage index_subquery Percentage,Language Language 30 func 2 Using where
+SELECT *
+FROM Country, City
+WHERE City.Country = Country.Code AND
+Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+(Country.Name IN
+(select Language from CountryLanguage where Percentage > 50) OR
+Country.name LIKE '%Island%');
+Code Name SurfaceArea Population Capital ID Name Country population
+VGB Virgin Islands, British 151.00 21000 537 537 Road Town VGB 8000
+CYM Cayman Islands 264.00 38000 553 553 George Town CYM 19600
+COK Cook Islands 236.00 20000 583 583 Avarua COK 11900
+FRO Faroe Islands 1399.00 43000 901 901 Tórshavn FRO 14542
+CXR Christmas Island 135.00 2500 1791 1791 Flying Fish Cove CXR 700
+KIR Kiribati 726.00 83000 2256 2255 Bikenibeu KIR 5055
+KIR Kiribati 726.00 83000 2256 2256 Bairiki KIR 2226
+CCK Cocos (Keeling) Islands 14.00 600 2317 2316 Bantam CCK 503
+CCK Cocos (Keeling) Islands 14.00 600 2317 2317 West Island CCK 167
+MHL Marshall Islands 181.00 64000 2507 2507 Dalap-Uliga-Darrit MHL 28000
+NRU Nauru 21.00 12000 2728 2727 Yangor NRU 4050
+NRU Nauru 21.00 12000 2728 2728 Yaren NRU 559
+NFK Norfolk Island 36.00 2000 2806 2806 Kingston NFK 800
+PLW Palau 459.00 19000 2881 2881 Koror PLW 12000
+MNP Northern Mariana Islands 464.00 78000 2913 2913 Garapan MNP 9200
+TCA Turks and Caicos Islands 430.00 17000 3423 3423 Cockburn Town TCA 4800
+TUV Tuvalu 26.00 12000 3424 3424 Funafuti TUV 4600
+VIR Virgin Islands, U.S. 347.00 93000 4067 4067 Charlotte Amalie VIR 13000
+
+Q1.3:
+For the same reasons as in Q2 IN-EXISTS and MATERIALIZATION chosen
+for each respective subquery.
+EXPLAIN
+SELECT City.Name, Country.Name
+FROM City,Country
+WHERE City.Country = Country.Code AND
+Country.SurfaceArea < 30000 AND Country.SurfaceArea > 10 AND
+((Country.Code, Country.Name) IN
+(select Country, Language from CountryLanguage where Percentage > 50) AND
+Country.Population > 3000000
+OR
+(Country.Code, City.Name) IN
+(select Country, Language from CountryLanguage));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 Using where
+1 PRIMARY City ref Country Country 3 world.Country.Code 18 Using where
+3 MATERIALIZED CountryLanguage index PRIMARY,Language PRIMARY 33 NULL 984 Using index
+2 DEPENDENT SUBQUERY CountryLanguage unique_subquery PRIMARY,Percentage,Language PRIMARY 33 func,func 1 Using where
+SELECT City.Name, Country.Name
+FROM City,Country
+WHERE City.Country = Country.Code AND
+Country.SurfaceArea < 30000 AND Country.SurfaceArea > 10 AND
+((Country.Code, Country.Name) IN
+(select Country, Language from CountryLanguage where Percentage > 50) AND
+Country.Population > 3000000
+OR
+(Country.Code, City.Name) IN
+(select Country, Language from CountryLanguage));
+Name Name
+Kigali Rwanda
+
+2. NOT IN subqueries
+
+
+Q2.1:
+Number of cities that are not capitals in countries with small population.
+MATERIALIZATION is 50 times faster because the cost of each subquery
+re-execution is much higher than the cost of index lookups into the
+materialized subquery.
+EXPLAIN
+select count(*) from City
+where City.id not in (select capital from Country
+where capital is not null and population < 100000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY City index NULL PRIMARY 4 NULL 4080 Using where; Using index
+2 MATERIALIZED Country ALL NULL NULL NULL NULL 239 Using where
+
+Q2.2e:
+Countries that speak French, but do not speak English
+IN-EXISTS because the outer query filters many rows, thus
+there are few lookups to make.
+EXPLAIN
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+AND CountryLanguage.Language = 'French'
+ AND Code = Country;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY CountryLanguage ref PRIMARY,Language Language 30 const 20 Using index condition
+1 PRIMARY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where
+2 DEPENDENT SUBQUERY CountryLanguage unique_subquery PRIMARY,Language PRIMARY 33 func,const 1 Using index; Using where
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+AND CountryLanguage.Language = 'French'
+ AND Code = Country;
+Name
+France
+Saint Pierre and Miquelon
+Belgium
+Burundi
+Guadeloupe
+Haiti
+Madagascar
+Martinique
+Mayotte
+French Polynesia
+Rwanda
+Sao Tome and Principe
+Switzerland
+New Caledonia
+Lebanon
+Mauritius
+Andorra
+Italy
+Luxembourg
+Q2.2m:
+Countries that speak French OR Spanish, but do not speak English
+MATERIALIZATION because the outer query filters less rows than Q5-a,
+so there are more lookups.
+EXPLAIN
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish')
+AND Code = Country;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY CountryLanguage range PRIMARY,Language Language 30 NULL 45 Using index condition; Using where; Rowid-ordered scan
+1 PRIMARY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using where
+2 MATERIALIZED CountryLanguage ref PRIMARY,Language Language 30 const 47 Using index condition
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish')
+AND Code = Country;
+Name
+Andorra
+Argentina
+Bolivia
+Chile
+Costa Rica
+Dominican Republic
+Ecuador
+El Salvador
+Spain
+Guatemala
+Honduras
+Colombia
+Cuba
+Mexico
+Nicaragua
+Panama
+Paraguay
+Peru
+France
+Saint Pierre and Miquelon
+Uruguay
+Venezuela
+Belgium
+Burundi
+Guadeloupe
+Haiti
+Madagascar
+Martinique
+Mayotte
+French Polynesia
+Rwanda
+Sao Tome and Principe
+Switzerland
+New Caledonia
+Lebanon
+Mauritius
+Andorra
+Italy
+Luxembourg
+France
+Sweden
+
+Q2.3e:
+Not a very meaningful query that tests NOT IN.
+IN-EXISTS because the outer query is cheap enough to reexecute many times.
+EXPLAIN
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+(SELECT City.Name, Country.Code
+FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000))
+AND Language IN ('English','Spanish');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY CountryLanguage range Language Language 30 NULL 72 Using index condition; Using where; Rowid-ordered scan
+2 DEPENDENT SUBQUERY City ref CityName CityName 35 func 1 Using index condition; Using where
+2 DEPENDENT SUBQUERY Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using index
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+(SELECT City.Name, Country.Code
+FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000))
+AND Language IN ('English','Spanish');
+count(*)
+88
+Q2.3m:
+MATERIALIZATION with the PARTIAL_MATCH_MERGE strategy, because the HAVING
+clause prevents the use of the index on City(Name), and in practice reduces
+radically the size of the temp table.
+EXPLAIN
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+(SELECT City.Name, Country.Code
+FROM City LEFT JOIN Country ON (Country = Code)
+HAVING City.Name LIKE "Santa%");
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY CountryLanguage index NULL PRIMARY 33 NULL 984 Using where; Using index
+2 MATERIALIZED City ALL NULL NULL NULL NULL 4080
+2 MATERIALIZED Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using index
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+(SELECT City.Name, Country.Code
+FROM City LEFT JOIN Country ON (Country = Code)
+HAVING City.Name LIKE "Santa%");
+count(*)
+984
+
+3. Subqueries with GROUP BY, HAVING, and aggregate functions
+
+Q3.1:
+Languages that are spoken in countries with 10 or 11 languages
+MATERIALIZATION is about 100 times faster than IN-EXISTS.
+EXPLAIN
+select count(*)
+from CountryLanguage
+where
+(Country, 10) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+WHERE Code = Country GROUP BY Code)
+OR
+(Country, 11) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+WHERE Code = Country GROUP BY Code)
+order by Country;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY CountryLanguage index NULL PRIMARY 33 NULL 984 Using where; Using index
+3 MATERIALIZED CountryLanguage index PRIMARY PRIMARY 33 NULL 984 Using index; Using temporary
+3 MATERIALIZED Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using index
+2 MATERIALIZED CountryLanguage index PRIMARY PRIMARY 33 NULL 984 Using index; Using temporary
+2 MATERIALIZED Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using index
+select count(*)
+from CountryLanguage
+where
+(Country, 10) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+WHERE Code = Country GROUP BY Code)
+OR
+(Country, 11) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+WHERE Code = Country GROUP BY Code)
+order by Country;
+count(*)
+102
+
+Q3.2:
+Countries whose capital is a city name that names more than one
+cities.
+MATERIALIZATION because the cost of single subquery execution is
+close to that of materializing the subquery.
+EXPLAIN
+select * from Country, City
+where capital = id and
+(City.name in (SELECT name FROM City
+GROUP BY name HAVING Count(*) > 2) OR
+capital is null);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country ALL NULL NULL NULL NULL 239 Using where
+1 PRIMARY City eq_ref PRIMARY PRIMARY 4 world.Country.Capital 1 Using where
+2 MATERIALIZED City index NULL CityName 35 NULL 4080 Using index
+select * from Country, City
+where capital = id and
+(City.name in (SELECT name FROM City
+GROUP BY name HAVING Count(*) > 2) OR
+capital is null);
+Code Name SurfaceArea Population Capital ID Name Country population
+BMU Bermuda 53.00 65000 191 191 Hamilton BMU 1200
+BOL Bolivia 1098581.00 8329000 194 194 La Paz BOL 758141
+CRI Costa Rica 51100.00 4023000 584 584 San José CRI 339131
+HKG Hong Kong 1075.00 6782000 937 937 Victoria HKG 1312637
+SYC Seychelles 455.00 77000 3206 3206 Victoria SYC 41000
+
+Q3.3: MATERIALIZATION is 25 times faster than IN-EXISTS
+EXPLAIN
+SELECT Name
+FROM Country
+WHERE Country.Code NOT IN
+(SELECT Country FROM City GROUP BY Name HAVING COUNT(Name) = 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country ALL NULL NULL NULL NULL 239 Using where
+2 MATERIALIZED City ALL NULL NULL NULL NULL 4080 Using temporary
+SELECT Name
+FROM Country
+WHERE Country.Code NOT IN
+(SELECT Country FROM City GROUP BY Name HAVING COUNT(Name) = 1);
+Name
+Antigua and Barbuda
+Costa Rica
+Montserrat
+Norfolk Island
+Seychelles
+Antarctica
+Bouvet Island
+British Indian Ocean Territory
+South Georgia and the South Sandwich Islands
+Heard Island and McDonald Islands
+French Southern territories
+United States Minor Outlying Islands
+
+4. Subqueries in the SELECT and HAVING clauses
+
+Q4.1m:
+Capital information about very big cities
+MATERIALIZATION
+EXPLAIN
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY City range Population Population 5 NULL 4 Using index condition; Rowid-ordered scan
+2 MATERIALIZED Country ALL NULL NULL NULL NULL 239 Using where
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+Name is_capital
+Mumbai (Bombay) 0
+Q4.1e:
+IN-TO-EXISTS after adding an index to make the subquery re-execution
+efficient.
+create index CountryCapital on Country(capital);
+EXPLAIN
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY City range Population Population 5 NULL 4 Using index condition; Rowid-ordered scan
+2 DEPENDENT SUBQUERY Country index_subquery CountryCapital CountryCapital 5 func 2 Using index; Using where
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+Name is_capital
+Mumbai (Bombay) 0
+drop index CountryCapital on Country;
+
+Q4.2:
+MATERIALIZATION
+EXPLAIN
+SELECT City.Name, City.Population
+FROM City JOIN Country ON City.Country = Country.Code
+GROUP BY City.Name
+HAVING City.Name IN (select Name from Country where population < 1000000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country index PRIMARY PRIMARY 3 NULL 239 Using index; Using temporary; Using filesort
+1 PRIMARY City ref Country Country 3 world.Country.Code 18
+2 MATERIALIZED Country ALL Name NULL NULL NULL 239 Using where
+SELECT City.Name, City.Population
+FROM City JOIN Country ON City.Country = Country.Code
+GROUP BY City.Name
+HAVING City.Name IN (select Name from Country where population < 1000000);
+Name Population
+Djibouti 383000
+Gibraltar 27025
+Macao 437500
+San Marino 2294
+
+5. Subqueries with UNION
+
+Q5.1:
+EXPLAIN
+SELECT * from City where (Name, 91) in
+(SELECT Name, round(Population/1000)
+FROM City
+WHERE Country = "IND" AND Population > 2500000
+UNION
+SELECT Name, round(Population/1000)
+FROM City
+WHERE Country = "IND" AND Population < 100000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY City ALL NULL NULL NULL NULL 4080 Using where
+2 DEPENDENT SUBQUERY City ref Population,Country,CityName CityName 35 func 1 Using where
+3 DEPENDENT UNION City ref Population,Country,CityName CityName 35 func 1 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT * from City where (Name, 91) in
+(SELECT Name, round(Population/1000)
+FROM City
+WHERE Country = "IND" AND Population > 2500000
+UNION
+SELECT Name, round(Population/1000)
+FROM City
+WHERE Country = "IND" AND Population < 100000);
+ID Name Country population
+1359 Hassan IND 90803
+1360 Ambala Sadar IND 90712
+1361 Baidyabati IND 90601
+set @@optimizer_switch='default';
+drop database world;
+
+
+TEST GROUP 2:
+Tests of various combinations of optimizer switches, types of queries,
+available indexes, column nullability, constness of tables/predicates.
+=====================================================================
+set optimizer_switch=@subselect_mat_cost;
diff --git a/mysql-test/r/subselect_mat_cost_bugs.result b/mysql-test/r/subselect_mat_cost_bugs.result
new file mode 100644
index 00000000000..cb600f0947a
--- /dev/null
+++ b/mysql-test/r/subselect_mat_cost_bugs.result
@@ -0,0 +1,393 @@
+#
+# LP BUG#643424 valgrind warning in choose_subquery_plan()
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+c1 int(11) DEFAULT NULL,
+c2 int(11) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY c2 (c2));
+INSERT INTO t1 VALUES (1,NULL,2);
+INSERT INTO t1 VALUES (2,7,9);
+INSERT INTO t1 VALUES (9,NULL,8);
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+c1 int(11) DEFAULT NULL,
+c2 int(11) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY c2 (c2));
+INSERT INTO t2 VALUES (1,1,7);
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off';
+SELECT pk FROM t1 WHERE (c2, c1) IN (SELECT c2, c2 FROM t2);
+pk
+set session optimizer_switch=@save_optimizer_switch;
+drop table t1, t2;
+#
+# LP BUG#652727 Crash in create_ref_for_key()
+#
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+c1 int(11) DEFAULT NULL,
+PRIMARY KEY (pk));
+INSERT INTO t2 VALUES (10,7);
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (17,NULL);
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+c1 int(11) DEFAULT NULL,
+PRIMARY KEY (pk));
+INSERT INTO t1 VALUES (15,1);
+INSERT INTO t1 VALUES (19,NULL);
+CREATE TABLE t3 (c2 int(11) DEFAULT NULL, KEY c2 (c2));
+INSERT INTO t3 VALUES (1);
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off';
+SELECT c2
+FROM t3
+WHERE (2, 6) IN (SELECT t1.c1, t1.c1 FROM t1 STRAIGHT_JOIN t2 ON t2.pk = t1.pk);
+c2
+set session optimizer_switch=@save_optimizer_switch;
+drop table t1, t2, t3;
+#
+# LP BUG#641245 Crash in Item_equal::contains
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+c1 int(11) DEFAULT NULL,
+c2 int(11) DEFAULT NULL,
+c3 varchar(1) DEFAULT NULL,
+c4 varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY c2 (c2),
+KEY c3 (c3,c2));
+INSERT INTO t1 VALUES (10,7,8,'v','v');
+INSERT INTO t1 VALUES (11,1,9,'r','r');
+INSERT INTO t1 VALUES (12,5,9,'a','a');
+INSERT INTO t1 VALUES (13,7,18,'v','v');
+INSERT INTO t1 VALUES (14,1,19,'r','r');
+INSERT INTO t1 VALUES (15,5,29,'a','a');
+INSERT INTO t1 VALUES (17,7,38,'v','v');
+INSERT INTO t1 VALUES (18,1,39,'r','r');
+INSERT INTO t1 VALUES (19,5,49,'a','a');
+create table t1a like t1;
+insert into t1a select * from t1;
+create table t1b like t1;
+insert into t1b select * from t1;
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+c1 int(11) DEFAULT NULL,
+c2 int(11) DEFAULT NULL,
+c3 varchar(1) DEFAULT NULL,
+c4 varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY c2 (c2),
+KEY c3 (c3,c2));
+INSERT INTO t2 VALUES (1,NULL,2,'w','w');
+INSERT INTO t2 VALUES (2,7,9,'m','m');
+set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off';
+EXPLAIN EXTENDED SELECT pk
+FROM t1
+WHERE c1 IN
+(SELECT t1a.c1
+FROM (t1b JOIN t2 ON t2.c3 = t1b.c4) LEFT JOIN
+t1a ON (t1a.c2 = t1b.pk AND 2)
+WHERE t1.pk) ;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 100.00 Using where
+2 DEPENDENT SUBQUERY t1b ALL NULL NULL NULL NULL 9 100.00
+2 DEPENDENT SUBQUERY t1a ref c2 c2 5 test.t1b.pk 1 100.00 Using where
+2 DEPENDENT SUBQUERY t2 index c3 c3 9 NULL 2 100.00 Using where; Using index; Using join buffer (flat, BNL join)
+Warnings:
+Note 1276 Field or reference 'test.t1.pk' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` where <expr_cache><`test`.`t1`.`c1`,`test`.`t1`.`pk`>(<in_optimizer>(`test`.`t1`.`c1`,<exists>(select `test`.`t1a`.`c1` from `test`.`t1b` join `test`.`t2` left join `test`.`t1a` on(((`test`.`t1a`.`c2` = `test`.`t1b`.`pk`) and 2)) where ((`test`.`t1`.`pk` <> 0) and (<cache>(`test`.`t1`.`c1`) = `test`.`t1a`.`c1`) and (`test`.`t2`.`c3` = `test`.`t1b`.`c4`)))))
+SELECT pk
+FROM t1
+WHERE c1 IN
+(SELECT t1a.c1
+FROM (t1b JOIN t2 ON t2.c3 = t1b.c4) LEFT JOIN
+t1a ON (t1a.c2 = t1b.pk AND 2)
+WHERE t1.pk) ;
+pk
+DROP TABLE t1, t1a, t1b, t2;
+#
+# LP BUG#714808 Assertion `outer_lookup_keys <= outer_record_count'
+# failed with materialization
+CREATE TABLE t1 ( pk int(11), PRIMARY KEY (pk)) ;
+CREATE TABLE t2 ( f2 int(11)) ;
+CREATE TABLE t3 ( f1 int(11), f3 varchar(1), KEY (f1)) ;
+INSERT INTO t3 VALUES (7,'f');
+set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off';
+EXPLAIN
+SELECT t1.*
+FROM t3 RIGHT JOIN t1 ON t1.pk = t3.f1
+WHERE t3.f3 OR ( 3 ) IN ( SELECT f2 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
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT t1.*
+FROM t3 RIGHT JOIN t1 ON t1.pk = t3.f1
+WHERE t3.f3 OR ( 3 ) IN ( SELECT f2 FROM t2 );
+pk
+drop table t1,t2,t3;
+#
+# LP BUG#714999 Second crash in select_describe() with nested subqueries
+#
+CREATE TABLE t1 ( pk int(11)) ;
+INSERT INTO t1 VALUES (29);
+CREATE TABLE t2 ( f1 varchar(1)) ;
+INSERT INTO t2 VALUES ('f'),('d');
+CREATE TABLE t3 ( f2 varchar(1)) ;
+EXPLAIN SELECT f2 FROM t3 WHERE (
+SELECT MAX( pk ) FROM t1
+WHERE EXISTS (
+SELECT max(f1)
+FROM t2 GROUP BY f1
+)
+) IS 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
+2 SUBQUERY t1 system NULL NULL NULL NULL 1
+3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+drop table t1, t2, t3;
+#
+# LP BUG#715034 Item_sum_distinct::clear(): Assertion `tree != 0' failed
+#
+CREATE TABLE t2 ( f2 int(11)) ;
+CREATE TABLE t1 ( f3 int(11), KEY (f3)) ;
+INSERT INTO t1 VALUES (6),(4);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+EXPLAIN
+SELECT * FROM (SELECT * FROM t2) AS a2
+WHERE (SELECT distinct SUM(distinct f3 ) FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+3 SUBQUERY t1 index NULL f3 5 NULL 2 Using index
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+insert into t2 values (1),(2);
+EXPLAIN
+SELECT * FROM (SELECT * FROM t2) AS a2
+WHERE (SELECT distinct SUM(distinct f3 ) FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+3 SUBQUERY t1 index NULL f3 5 NULL 2 Using index
+2 DERIVED t2 ALL NULL NULL NULL NULL 2
+set optimizer_switch=@tmp_optimizer_switch;
+drop table t1,t2;
+#
+# LP BUG#715027 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed
+#
+CREATE TABLE t1 ( f1 int(11), PRIMARY KEY (f1)) ;
+INSERT INTO t1 VALUES (28),(29);
+CREATE TABLE t2 ( f2 int(11), f3 int(11), f10 varchar(1)) ;
+INSERT INTO t2 VALUES (NULL,6,'f'),(4,2,'d');
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+EXPLAIN
+SELECT alias2.f2 AS field1
+FROM t1 AS alias1 JOIN ( SELECT * FROM t2 ) AS alias2 ON alias2.f3 = alias1.f1
+WHERE (
+SELECT t2.f2
+FROM t2 JOIN t1 ON t1.f1
+WHERE t1.f1 AND alias2.f10
+)
+ORDER BY field1 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using where; Using filesort
+1 PRIMARY alias1 eq_ref PRIMARY PRIMARY 4 alias2.f3 1 Using index
+3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2
+3 DEPENDENT SUBQUERY t1 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
+2 DERIVED t2 ALL NULL NULL NULL NULL 2
+SELECT alias2.f2 AS field1
+FROM t1 AS alias1 JOIN ( SELECT * FROM t2 ) AS alias2 ON alias2.f3 = alias1.f1
+WHERE (
+SELECT t2.f2
+FROM t2 JOIN t1 ON t1.f1
+WHERE t1.f1 AND alias2.f10
+)
+ORDER BY field1 ;
+field1
+set optimizer_switch=@tmp_optimizer_switch;
+drop table t1,t2;
+#
+# LP BUG#718578 Yet another Assertion `!table ||
+# (!table->read_set || bitmap_is_set(table->read_set, field_index))'
+CREATE TABLE t1 ( f1 int(11), f2 int(11), f3 int(11)) ;
+INSERT IGNORE INTO t1 VALUES (28,5,6),(29,NULL,4);
+CREATE TABLE t2 ( f10 varchar(1) );
+INSERT IGNORE INTO t2 VALUES (NULL);
+SELECT f1 AS field1
+FROM ( SELECT * FROM t1 ) AS alias1
+WHERE (SELECT t1.f1
+FROM t2 JOIN t1 ON t1.f2
+WHERE alias1.f3 AND t1.f3) AND f2
+ORDER BY field1;
+field1
+28
+drop table t1,t2;
+#
+# LP BUG#601124 Bug in eliminate_item_equal
+# leads to crash in Item_func::Item_func
+CREATE TABLE t1 ( f1 int(11), f3 varchar(1)) ;
+INSERT INTO t1 VALUES (5,'m'),(NULL,'c');
+CREATE TABLE t2 ( f2 int(11), f3 varchar(1)) ;
+INSERT INTO t2 VALUES (6,'f'),(2,'d');
+CREATE TABLE t3 ( f2 int(11), f3 varchar(1)) ;
+INSERT INTO t3 VALUES (6,'f'),(2,'d');
+SELECT * FROM t3
+WHERE ( f2 ) IN (SELECT t1.f1
+FROM t1 STRAIGHT_JOIN t2 ON t2.f3 = t1.f3
+WHERE t2.f3 = 'c');
+f2 f3
+drop table t1,t2,t3;
+#
+# LP BUG#718593 Crash in substitute_for_best_equal_field -> eliminate_item_equal ->
+# Item_field::find_item_equal -> Item_equal::contains
+#
+set @save_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch = 'semijoin=off';
+CREATE TABLE t1 ( f3 int(11), f10 varchar(1), f11 varchar(1)) ;
+INSERT IGNORE INTO t1 VALUES (6,'f','f'),(2,'d','d');
+CREATE TABLE t2 ( f12 int(11), f13 int(11)) ;
+insert into t2 values (1,2), (3,4);
+EXPLAIN
+SELECT * FROM t2
+WHERE ( f12 ) IN (
+SELECT alias2.f3
+FROM t1 AS alias1 JOIN t1 AS alias2 ON alias2.f10 = alias1.f11
+WHERE alias1.f11 OR alias1.f3 = 50 AND alias1.f10
+);
+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 MATERIALIZED alias1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED alias2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t2
+WHERE ( f12 ) IN (
+SELECT alias2.f3
+FROM t1 AS alias1 JOIN t1 AS alias2 ON alias2.f10 = alias1.f11
+WHERE alias1.f11 OR alias1.f3 = 50 AND alias1.f10
+);
+f12 f13
+EXPLAIN
+SELECT * FROM t2
+WHERE ( f12 ) IN (
+SELECT alias2.f3
+FROM t1 AS alias1, t1 AS alias2
+WHERE (alias2.f10 = alias1.f11) AND (alias1.f11 OR alias1.f3 = 50 AND alias1.f10));
+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 MATERIALIZED alias1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED alias2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t2
+WHERE ( f12 ) IN (
+SELECT alias2.f3
+FROM t1 AS alias1, t1 AS alias2
+WHERE (alias2.f10 = alias1.f11) AND (alias1.f11 OR alias1.f3 = 50 AND alias1.f10));
+f12 f13
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t2;
+#
+# MWL#89: test introduced after Sergey Petrunia's review - test that
+# keyparts wihtout index prefix are used with the IN-EXISTS strategy.
+#
+create table t1 (c1 int);
+insert into t1 values (1), (2), (3);
+create table t2 (kp1 int, kp2 int, c2 int, filler char(100));
+insert into t2 values (0,0,0,'filler'),(0,1,1,'filler'),(0,2,2,'filler'),(0,3,3,'filler');
+create index key1 on t2 (kp1, kp2);
+create index key2 on t2 (kp1);
+create index key3 on t2 (kp2);
+SET @@optimizer_switch='materialization=off,semijoin=off,in_to_exists=on';
+analyze table t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+explain
+select c1 from t1 where c1 in (select kp1 from t2 where kp2 = 10 and c2 = 4) or c1 > 7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY t2 index_subquery key1,key2,key3 key1 10 func,const 1 Using where
+select c1 from t1 where c1 in (select kp1 from t2 where kp2 = 10 and c2 = 4) or c1 > 7;
+c1
+set @@optimizer_switch='default';
+drop table t1, t2;
+#
+# LP BUG#800679: Assertion `outer_join->table_count > 0' failed in
+# JOIN::choose_subquery_plan() with materialization=on,semijoin=off
+#
+CREATE TABLE t1 ( f1 int);
+insert into t1 values (1),(2);
+CREATE TABLE t2 ( f1 int);
+insert into t2 values (1),(2);
+SET @@optimizer_switch='materialization=on,semijoin=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE (f1) IN (SELECT f1 FROM t2)
+LIMIT 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1
+WHERE (f1) IN (SELECT f1 FROM t2)
+LIMIT 0;
+f1
+set @@optimizer_switch='default';
+drop table t1, t2;
+#
+# LP BUG#834492: Crash in fix_semijoin_strategies_for_picked_join_order
+# with nested subqueries and LooseScan=ON
+#
+CREATE TABLE t3 (b int) ;
+INSERT INTO t3 VALUES (0),(0);
+CREATE TABLE t4 (a int, b int, c int, d int, PRIMARY KEY (a)) ;
+INSERT INTO t4 VALUES (28,0,0,0),(29,3,0,0);
+CREATE TABLE t5 (a int, b int, c int, d int, KEY (c,b)) ;
+INSERT INTO t5 VALUES (28,0,0,0),(29,3,0,0);
+SET @@optimizer_switch='semijoin=ON,loosescan=ON,firstmatch=OFF,materialization=OFF';
+EXPLAIN SELECT *
+FROM t3
+WHERE t3.b > ALL (
+SELECT c
+FROM t4
+WHERE t4.a >= t3.b
+AND a = SOME (SELECT b FROM t5));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t5 index c c 10 NULL 2 Using where; Using index; Start temporary
+2 DEPENDENT SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t5.b 1 Using index condition; Using where; End temporary
+SELECT *
+FROM t3
+WHERE t3.b > ALL (
+SELECT c
+FROM t4
+WHERE t4.a >= t3.b
+AND a = SOME (SELECT b FROM t5));
+b
+0
+0
+set @@optimizer_switch='default';
+drop table t3, t4, t5;
+#
+# LP BUG#858038 The result of a query with NOT IN subquery depends on the state of the optimizer switch
+#
+create table t1 (c1 char(2) not null, c2 char(2));
+create table t2 (c3 char(2), c4 char(2));
+insert into t1 values ('a1', 'b1');
+insert into t1 values ('a2', 'b2');
+insert into t2 values ('x1', 'y1');
+insert into t2 values ('a2', null);
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=off,partial_match_table_scan=on';
+explain select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+c1 c2
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+explain select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+c1 c2
+drop table t1, t2;
diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
new file mode 100644
index 00000000000..d0c9555d976
--- /dev/null
+++ b/mysql-test/r/subselect_no_mat.result
@@ -0,0 +1,6296 @@
+select @@optimizer_switch like '%materialization=on%';
+@@optimizer_switch like '%materialization=on%'
+1
+set optimizer_switch='materialization=off';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set join_cache_level=1;
+set @join_cache_level_for_subselect_test=@@join_cache_level;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+drop view if exists v2;
+set @subselect_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test,
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+set join_cache_level=@join_cache_level_for_subselect_test;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+select (select 2);
+(select 2)
+2
+explain extended select (select 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select 2 AS `(select 2)`
+SELECT (SELECT 1) UNION SELECT (SELECT 2);
+(SELECT 1)
+1
+2
+explain extended SELECT (SELECT 1) UNION SELECT (SELECT 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1249 Select 4 was reduced during optimization
+Note 1003 select 1 AS `(SELECT 1)` union select 2 AS `(SELECT 2)`
+SELECT (SELECT (SELECT 0 UNION SELECT 0));
+(SELECT (SELECT 0 UNION SELECT 0))
+0
+explain extended SELECT (SELECT (SELECT 0 UNION SELECT 0));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (select 0 union select 0) AS `(SELECT (SELECT 0 UNION SELECT 0))`
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) as c HAVING a=1) as b;
+ERROR 42S22: Reference 'b' not supported (forward reference in item list)
+SELECT (SELECT 1),MAX(1) FROM (SELECT 1) as a;
+(SELECT 1) MAX(1)
+1 1
+SELECT (SELECT a) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<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
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 100.00
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
+Warnings:
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`tt`.`a` AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
+set optimizer_switch=@tmp_optimizer_switch;
+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`,<expr_cache><`test`.`t4`.`a`>((select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`)) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+select * from t3 where exists (select * from t2 where t2.b=t3.a);
+a
+7
+select * from t3 where not exists (select * from t2 where t2.b=t3.a);
+a
+6
+3
+select * from t3 where a in (select b from t2);
+a
+7
+select * from t3 where a not in (select b from t2);
+a
+6
+3
+select * from t3 where a = some (select b from t2);
+a
+7
+select * from t3 where a <> any (select b from t2);
+a
+6
+3
+select * from t3 where a = all (select b from t2);
+a
+7
+select * from t3 where a <> all (select b from t2);
+a
+6
+3
+insert into t2 values (100, 5);
+select * from t3 where a < any (select b from t2);
+a
+6
+3
+select * from t3 where a < all (select b from t2);
+a
+3
+select * from t3 where a >= any (select b from t2);
+a
+6
+7
+explain extended select * from t3 where a >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= all (select b from t2);
+a
+7
+delete from t2 where a=100;
+select * from t3 where a in (select a,b from t2);
+ERROR 21000: Operand should contain 1 column(s)
+select * from t3 where a in (select * from t2);
+ERROR 21000: Operand should contain 1 column(s)
+insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9),(1,10);
+select b,max(a) as ma from t4 group by b having b < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+insert into t2 values (2,10);
+select b,max(a) as ma from t4 group by b having ma < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+10 1
+delete from t2 where a=2 and b=10;
+select b,max(a) as ma from t4 group by b having b >= (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+7 12
+create table t5 (a int);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (5);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (2);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+explain extended select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT UNION t5 ALL NULL NULL NULL NULL 2 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t2.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select <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 where; Using index
+4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where
+3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
+t8 WHERE pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
+pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+pseudo
+joce
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo LIKE '%joce%');
+ERROR 21000: Subquery returns more than 1 row
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8;
+CREATE TABLE `t1` (
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (topic,date,pseudo) VALUES
+('43506','2002-10-02','joce'),('40143','2002-08-03','joce');
+EXPLAIN EXTENDED SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')
+EXPLAIN EXTENDED SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select (select distinct `test`.`t1`.`date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')) AS `(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')`
+SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+date
+2002-08-03
+SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')
+2002-08-03
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL SELECT 1;
+1
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1;
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL topic 3 NULL 2 100.00 Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where (1 = (select 1 union select 1))
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (40143,1),(43506,2);
+CREATE TABLE `t2` (
+`mot` varchar(30) NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t2 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce');
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+a
+40143
+SELECT numeropost,maxnumrep FROM t1 WHERE exists (SELECT 1 FROM t2 WHERE (mot='joce') AND date >= '2002-10-21' AND t1.numeropost = t2.topic) ORDER BY maxnumrep DESC LIMIT 0, 20;
+numeropost maxnumrep
+43506 2
+40143 1
+SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1) b;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT 1 IN (SELECT 1 FROM t2 HAVING a);
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic IN (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 1
+SELECT * from t2 where topic = all (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+SELECT * from t2 where topic <> any (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 0
+drop table t1,t2;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (1,0),(2,1);
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+show warnings;
+Level Code Message
+Error 1242 Subquery returns more than 1 row
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+(select * from t1) union (select * from t1) order by (select a from t1 limit 1);
+a
+1
+2
+3
+drop table t1;
+CREATE TABLE t1 (field char(1) NOT NULL DEFAULT 'b');
+INSERT INTO t1 VALUES ();
+SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) a HAVING field='b');
+ERROR 21000: Subquery returns more than 1 row
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL default '0',
+`numreponse` int(10) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`numeropost`,`numreponse`),
+UNIQUE KEY `numreponse` (`numreponse`),
+KEY `pseudo` (`pseudo`,`numeropost`)
+) ENGINE=MyISAM;
+SELECT (SELECT numeropost FROM t1 HAVING numreponse=a),numreponse FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Reference 'numreponse' not supported (forward reference in item list)
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=a) FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT * FROM t1) as a;
+numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
+INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY t1 ref PRIMARY PRIMARY 3 const 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select 1 from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+drop table t1;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1);
+SELECT 1 FROM (SELECT a FROM t1) b HAVING (SELECT b.a)=1;
+1
+1
+drop table t1;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 22),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+update t1 set b= (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+update t1 set b= (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+update t1 set b= (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 NULL
+1 21
+2 22
+drop table t1, t2;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+select * from t1 where b = (select b from t2 where t1.a = t2.a);
+a b
+2 12
+delete from t1 where b in (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+delete from t1 where b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete from t1 where b = (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 10
+1 11
+drop table t1, t2;
+create table t11 (a int NOT NULL, b int, primary key (a));
+create table t12 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t11 values (0, 10),(1, 11),(2, 12);
+insert into t12 values (33, 10),(22, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t11;
+a b
+0 10
+1 11
+2 12
+select * from t12;
+a b
+33 10
+22 11
+2 12
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a);
+ERROR HY000: You can't specify target table 't12' for update in FROM clause
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a);
+select * from t11;
+a b
+0 10
+1 11
+select * from t12;
+a b
+33 10
+22 11
+drop table t11, t12, t2;
+CREATE TABLE t1 (x int) ENGINE=MyISAM;
+create table t2 (a int) ENGINE=MyISAM;
+create table t3 (b int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
+ERROR 21000: Subquery returns more than 1 row
+INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
+select * from t1;
+x
+1
+insert into t2 values (1);
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
+ERROR 42S22: Unknown column 'x' in 'field list'
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+2
+drop table t1, t2, t3;
+CREATE TABLE t1 (x int not null, y int, primary key (x)) ENGINE=MyISAM;
+create table t2 (a int);
+create table t3 (a int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+select * from t1;
+x y
+replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
+ERROR 21000: Subquery returns more than 1 row
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 2
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+2 FROM t2));
+select * from t1;
+x y
+1 3
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 1
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+replace LOW_PRIORITY into t1 (x, y) VALUES ((SELECT a+1 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+2 1
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1) b WHERE 1 IN (SELECT *);
+ERROR HY000: No tables used
+CREATE TABLE t2 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (1),(2);
+SELECT * FROM t2 WHERE id IN (SELECT 1);
+id
+1
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = 1)
+SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id
+1
+SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id
+2
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 3 was reduced during optimization
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = (1 + 1))
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL id 5 NULL 2 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where <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 where; Using index
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`)))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
+drop table t1,t2,t3;
+# check correct NULL Processing for normal IN/ALL/ANY
+# and 2 ways of max/min optimization
+create table t1 (a int);
+insert into t1 values (1), (100), (NULL), (1000);
+create table t2 (a int not null);
+# subselect returns empty set (for NULL and non-NULL left part)
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 1
+100 1
+NULL 1
+1000 1
+select a from t1 where a in (select * from t2);
+a
+select a from t1 where a > any (select * from t2);
+a
+select a from t1 where a > all (select * from t2);
+a
+1
+100
+NULL
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+select a from t1 where a > any (select * from t2 group by a);
+a
+select a from t1 where a > all (select * from t2 group by a);
+a
+1
+100
+NULL
+1000
+insert into t2 values (1),(200);
+# sebselect returns non-empty set without NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 0
+NULL NULL
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 1
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+1000
+drop table t2;
+create table t2 (a int);
+insert into t2 values (1),(NULL),(200);
+# sebselect returns non-empty set with NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 NULL
+NULL NULL
+1000 NULL
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 NULL
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 NULL
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+drop table t1, t2;
+create table t1 (a float);
+select 10.5 IN (SELECT * from t1 LIMIT 1);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int, b int, c varchar(10));
+create table t2 (a int);
+insert into t1 values (1,2,'a'),(2,3,'b'),(3,4,'c');
+insert into t2 values (1),(2),(NULL);
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a') (select c from t1 where a=t2.a)
+1 1 a
+2 0 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b') (select c from t1 where a=t2.a)
+1 0 a
+2 1 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where a=t2.a)
+1 0 a
+2 0 b
+NULL NULL NULL
+drop table t1,t2;
+create table t1 (a int, b real, c varchar(10));
+insert into t1 values (1, 1, 'a'), (2,2,'b'), (NULL, 2, 'b');
+select ROW(1, 1, 'a') IN (select a,b,c from t1);
+ROW(1, 1, 'a') IN (select a,b,c from t1)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1);
+ROW(1, 2, 'a') IN (select a,b,c from t1)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1);
+ROW(1, 1, 'a') IN (select b,a,c from t1)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a')
+1
+select ROW(1, 1, 'a') IN (select b,a,c from t1 limit 2);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1);
+do @a:=(SELECT a from t1);
+select @a;
+@a
+1
+set @a:=2;
+set @a:=(SELECT a from t1);
+select @a;
+@a
+1
+drop table t1;
+do (SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+set @a:=(SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (a int, KEY(a));
+HANDLER t1 OPEN;
+HANDLER t1 READ a=((SELECT 1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT 1))' at line 1
+HANDLER t1 CLOSE;
+drop table t1;
+create table t1 (a int);
+create table t2 (b int);
+insert into t1 values (1),(2);
+insert into t2 values (1);
+select a from t1 where a in (select a from t1 where a in (select b from t2));
+a
+1
+drop table t1, t2;
+create table t1 (a int, b int);
+create table t2 like t1;
+insert into t1 values (1,2),(1,3),(1,4),(1,5);
+insert into t2 values (1,2),(1,3);
+select * from t1 where row(a,b) in (select a,b from t2);
+a b
+1 2
+1 3
+drop table t1, t2;
+CREATE TABLE `t1` (`i` int(11) NOT NULL default '0',PRIMARY KEY (`i`)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+select * from t1;
+i
+2
+drop table t1;
+CREATE TABLE t1 (a int(1));
+EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
+drop table t1;
+CREATE TABLE `t1` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t2` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t3` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t2 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t3 VALUES (1,1);
+SELECT DISTINCT topic FROM t2 WHERE NOT EXISTS(SELECT * FROM t3 WHERE
+numeropost=topic);
+topic
+2
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+test 2 0000-00-00 test
+DELETE FROM t1 WHERE topic IN (SELECT DISTINCT topic FROM t2 WHERE NOT
+EXISTS(SELECT * FROM t3 WHERE numeropost=topic));
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+a (SELECT a)
+1 1
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT 1)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a+0)` int(3) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
+select * from t1;
+a
+2
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+explain extended select a,(select (select rand() from t1 limit 1) from t1 limit 1)
+from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+2 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+3 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,(select (select rand() from `test`.`t1` limit 1) from `test`.`t1` limit 1) AS `(select (select rand() from t1 limit 1) from t1 limit 1)` from `test`.`t1`
+drop table t1;
+select t1.Continent, t2.Name, t2.Population from t1 LEFT JOIN t2 ON t1.Code = t2.Country where t2.Population IN (select max(t2.Population) AS Population from t2, t1 where t2.Country = t1.Code group by Continent);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+name char(35) NOT NULL default '',
+t2 char(3) NOT NULL default '',
+District char(20) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (130,'Sydney','AUS','New South Wales',3276207);
+INSERT INTO t1 VALUES (131,'Melbourne','AUS','Victoria',2865329);
+INSERT INTO t1 VALUES (132,'Brisbane','AUS','Queensland',1291117);
+CREATE TABLE t2 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default '',
+PRIMARY KEY (Code)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU');
+INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
+select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent);
+Continent Name Population
+Oceania Sydney 3276207
+drop table t1, t2;
+CREATE TABLE `t1` (
+`id` mediumint(8) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`id`),
+UNIQUE KEY `pseudo` (`pseudo`)
+) ENGINE=MyISAM PACK_KEYS=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (pseudo) VALUES ('test');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
+INSERT INTO t1 (pseudo) VALUES ('test1');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
+drop table t1;
+CREATE TABLE `t1` (
+`i` int(11) NOT NULL default '0',
+PRIMARY KEY (`i`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i));
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t);
+ERROR 42S22: Unknown column 't.i' in 'field list'
+select * from t1;
+i
+3
+drop table t1;
+CREATE TABLE t1 (
+id int(11) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(1),(2),(2),(1),(3);
+CREATE TABLE t2 (
+id int(11) default NULL,
+name varchar(15) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (4,'vita'), (1,'vita'), (2,'vita'), (1,'vita');
+update t1, t2 set t2.name='lenka' where t2.id in (select id from t1);
+select * from t2;
+id name
+4 vita
+1 lenka
+2 lenka
+1 lenka
+drop table t1,t2;
+create table t1 (a int, unique index indexa (a));
+insert into t1 values (-1), (-4), (-2), (NULL);
+select -10 IN (select a from t1 FORCE INDEX (indexa));
+-10 IN (select a from t1 FORCE INDEX (indexa))
+NULL
+drop table t1;
+create table t1 (id int not null auto_increment primary key, salary int, key(salary));
+insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
+explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using where
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
+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:
+Warning 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`.`t3`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t2`.`a`))
+drop table t1, t2, t3;
+create table t1 (a int, b int, index a (a,b));
+create table t2 (a int, index a (a));
+create table t3 (a int, b int, index a (a));
+insert into t1 values (1,10), (2,20), (3,30), (4,40);
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1
+select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D;
+insert into t2 values (2), (3), (4), (5);
+insert into t3 values (10,3), (20,4), (30,5);
+select * from t2 where t2.a in (select a from t1);
+a
+2
+3
+4
+explain extended select * from t2 where t2.a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where (`test`.`t1`.`a` = `test`.`t2`.`a`)
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+a
+2
+4
+explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
+select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
+a
+2
+3
+explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.00 Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`b` = `test`.`t3`.`a`) and (`test`.`t1`.`a` = `test`.`t2`.`a`))
+insert into t1 values (3,31);
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+a
+2
+3
+4
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31);
+a
+2
+4
+explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
+drop table t0, t1, t2, t3;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+create table t3 (a int, b int);
+insert into t1 values (0,100),(1,2), (1,3), (2,2), (2,7), (2,-1), (3,10);
+insert into t2 values (0,0), (1,1), (2,1), (3,1), (4,1);
+insert into t3 values (3,3), (2,2), (1,1);
+select a,(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3;
+a (select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1)
+3 1
+2 2
+1 2
+drop table t1,t2,t3;
+create table t1 (s1 int);
+create table t2 (s1 int);
+insert into t1 values (1);
+insert into t2 values (1);
+select * from t1 where exists (select s1 from t2 having max(t2.s1)=t1.s1);
+s1
+1
+drop table t1,t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+insert into t1 values (1);
+insert into t2 values (1);
+update t1 set s1 = s1 + 1 where 1 = (select x.s1 as A from t2 WHERE t2.s1 > t1.s1 order by A);
+ERROR 42S22: Unknown column 'x.s1' in 'field list'
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 CHAR(5) COLLATE latin1_german1_ci,
+s2 CHAR(5) COLLATE latin1_swedish_ci);
+INSERT INTO t1 VALUES ('z','?');
+select * from t1 where s1 > (select max(s2) from t1);
+ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+select * from t1 where s1 > any (select max(s2) from t1);
+ERROR HY000: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_german1_ci,IMPLICIT) for operation '<'
+drop table t1;
+create table t1(toid int,rd int);
+create table t2(userid int,pmnew int,pmtotal int);
+insert into t2 values(1,0,0),(2,0,0);
+insert into t1 values(1,0),(1,0),(1,0),(1,12),(1,15),(1,123),(1,12312),(1,12312),(1,123),(2,0),(2,0),(2,1),(2,2);
+select userid,pmtotal,pmnew, (select count(rd) from t1 where toid=t2.userid) calc_total, (select count(rd) from t1 where rd=0 and toid=t2.userid) calc_new from t2 where userid in (select distinct toid from t1);
+userid pmtotal pmnew calc_total calc_new
+1 0 0 9 3
+2 0 0 4 2
+drop table t1, t2;
+create table t1 (s1 char(5));
+select (select 'a','b' from t1 union select 'a','b' from t1) from t1;
+ERROR 21000: Operand should contain 1 column(s)
+insert into t1 values ('tttt');
+select * from t1 where ('a','b')=(select 'a','b' from t1 union select 'a','b' from t1);
+s1
+tttt
+explain extended (select * from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 (select 'tttt' AS `s1` from `test`.`t1`)
+(select * from t1);
+s1
+tttt
+drop table t1;
+create table t1 (s1 char(5), index s1(s1));
+create table t2 (s1 char(5), index s1(s1));
+insert into t1 values ('a1'),('a2'),('a3');
+insert into t2 values ('a1'),('a2');
+select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
+s1 s1 = ANY (SELECT s1 FROM t2)
+a1 1
+a2 1
+a3 0
+select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
+s1 s1 <> ALL (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')
+a1 0
+a2 1
+a3 1
+explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<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 not null);
+create table t3 (a int);
+insert into t3 values (6),(7),(3);
+select * from t3 where a >= all (select b from t2);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= some (select b from t2);
+a
+explain extended select * from t3 where a >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= all (select b from t2 group by 1);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where a >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where NULL >= any (select b from t2);
+a
+explain extended select * from t3 where NULL >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= any (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= some (select b from t2);
+a
+explain extended select * from t3 where NULL >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+insert into t2 values (2,2), (2,1), (3,3), (3,1);
+select * from t3 where a > all (select max(b) from t2 group by a);
+a
+6
+7
+explain extended select * from t3 where a > all (select max(b) from t2 group by a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= <cache>(`test`.`t3`.`a`))))
+drop table t2, t3;
+CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
+INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
+CREATE TABLE `t2` (`db_id` int(11) NOT NULL auto_increment,`name` varchar(200) NOT NULL default '',`primary_uid` smallint(6) NOT NULL default '0',`secondary_uid` smallint(6) NOT NULL default '0',PRIMARY KEY (`db_id`),UNIQUE KEY `name_2` (`name`),FULLTEXT KEY `name` (`name`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2147483647;
+INSERT INTO `t2` (`db_id`, `name`, `primary_uid`, `secondary_uid`) VALUES (18, 'Not Set 1', 0, 0),(19, 'Valid', 1, 2),(20, 'Valid 2', 1, 2),(21, 'Should Not Return', 1, 2),(26, 'Not Set 2', 0, 0),(-1, 'ALL DB\'S', 0, 0);
+CREATE TABLE `t3` (`taskgenid` mediumint(9) NOT NULL auto_increment,`dbid` int(11) NOT NULL default '0',`taskid` int(11) NOT NULL default '0',`mon` tinyint(4) NOT NULL default '1',`tues` tinyint(4) NOT NULL default '1',`wed` tinyint(4) NOT NULL default '1',`thur` tinyint(4) NOT NULL default '1',`fri` tinyint(4) NOT NULL default '1',`sat` tinyint(4) NOT NULL default '0',`sun` tinyint(4) NOT NULL default '0',`how_often` smallint(6) NOT NULL default '1',`userid` smallint(6) NOT NULL default '0',`active` tinyint(4) NOT NULL default '1',PRIMARY KEY (`taskgenid`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2 ;
+INSERT INTO `t3` (`taskgenid`, `dbid`, `taskid`, `mon`, `tues`,`wed`, `thur`, `fri`, `sat`, `sun`, `how_often`, `userid`, `active`) VALUES (1,-1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1);
+CREATE TABLE `t4` (`task_id` smallint(6) NOT NULL default '0',`description` varchar(200) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO `t4` (`task_id`, `description`) VALUES (1, 'Daily Check List'),(2, 'Weekly Status');
+select dbid, name, (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01') from t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND t4.task_id = taskid;
+dbid name (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')
+-1 Valid 1
+-1 Valid 2 1
+-1 Should Not Return 0
+SELECT dbid, name FROM t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND ((date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')) AND t4.task_id = taskid;
+dbid name
+-1 Valid
+-1 Valid 2
+drop table t1,t2,t3,t4;
+CREATE TABLE t1 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (2),(6);
+select * from t1 where (1,2,6) in (select * from t2);
+ERROR 21000: Operand should contain 3 column(s)
+DROP TABLE t1,t2;
+create table t1 (s1 int);
+insert into t1 values (1);
+insert into t1 values (2);
+set sort_buffer_size = (select s1 from t1);
+ERROR 21000: Subquery returns more than 1 row
+do (select * from t1);
+Warnings:
+Error 1242 Subquery returns more than 1 row
+drop table t1;
+create table t1 (s1 char);
+insert into t1 values ('e');
+select * from t1 where 'f' > any (select s1 from t1);
+s1
+e
+select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+s1
+e
+explain extended select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+2 SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 UNION t1 system NULL NULL NULL NULL 1 100.00
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',(<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`) < 'f')))
+drop table t1;
+CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
+CREATE TABLE t2 (code char(5) NOT NULL default '',UNIQUE KEY code (code)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES ('1'),('1226'),('1245'),('1862'),('18623'),('1874'),('1967'),('6');
+select c.number as phone,(select p.code from t2 p where c.number like concat(p.code, '%') order by length(p.code) desc limit 1) as code from t1 c;
+phone code
+69294728265 6
+18621828126 1862
+89356874041 NULL
+95895001874 NULL
+drop table t1, t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+select * from t1 where (select count(*) from t2 where t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'where clause'
+select * from t1 where (select count(*) from t2 group by t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+select count(*) from t2 group by t1.s2;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+drop table t1, t2;
+CREATE TABLE t1(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC VARCHAR(20) DEFAULT NULL,PRIMARY KEY (COLA, COLB));
+CREATE TABLE t2(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC CHAR(1) NOT NULL,PRIMARY KEY (COLA));
+INSERT INTO t1 VALUES (1,1,'1A3240'), (1,2,'4W2365');
+INSERT INTO t2 VALUES (100, 200, 'C');
+SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1);
+COLC
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1),(1),(1),(1),(1),(2),(3),(4),(5);
+SELECT DISTINCT (SELECT a) FROM t1 LIMIT 100;
+(SELECT a)
+1
+2
+3
+4
+5
+DROP TABLE t1;
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "../../tmp/subselect.out.file.1" from t1;
+delete from t1;
+load data infile "../../tmp/subselect.out.file.1" into table t1;
+select * from t1;
+a b
+1 0.123
+drop table t1;
+CREATE TABLE `t1` (
+`id` int(11) NOT NULL auto_increment,
+`id_cns` tinyint(3) unsigned NOT NULL default '0',
+`tipo` enum('','UNO','DUE') NOT NULL default '',
+`anno_dep` smallint(4) unsigned zerofill NOT NULL default '0000',
+`particolare` mediumint(8) unsigned NOT NULL default '0',
+`generale` mediumint(8) unsigned NOT NULL default '0',
+`bis` tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`),
+UNIQUE KEY `idx_cns_gen_anno` (`anno_dep`,`id_cns`,`generale`,`particolare`),
+UNIQUE KEY `idx_cns_par_anno` (`id_cns`,`anno_dep`,`tipo`,`particolare`,`bis`)
+);
+INSERT INTO `t1` VALUES (1,16,'UNO',1987,2048,9681,0),(2,50,'UNO',1987,1536,13987,0),(3,16,'UNO',1987,2432,14594,0),(4,16,'UNO',1987,1792,13422,0),(5,16,'UNO',1987,1025,10240,0),(6,16,'UNO',1987,1026,7089,0);
+CREATE TABLE `t2` (
+`id` tinyint(3) unsigned NOT NULL auto_increment,
+`max_anno_dep` smallint(6) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`)
+);
+INSERT INTO `t2` VALUES (16,1987),(50,1990),(51,1990);
+SELECT cns.id, cns.max_anno_dep, cns.max_anno_dep = (SELECT s.anno_dep FROM t1 AS s WHERE s.id_cns = cns.id ORDER BY s.anno_dep DESC LIMIT 1) AS PIPPO FROM t2 AS cns;
+id max_anno_dep PIPPO
+16 1987 1
+50 1990 0
+51 1990 NULL
+DROP TABLE t1, t2;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SET SQL_SELECT_LIMIT=1;
+select sum(a) from (select * from t1) as a;
+sum(a)
+6
+select 2 in (select * from t1);
+2 in (select * from t1)
+1
+SET SQL_SELECT_LIMIT=default;
+drop table t1;
+CREATE TABLE t1 (a int, b int, INDEX (a));
+INSERT INTO t1 VALUES (1, 1), (1, 2), (1, 3);
+SELECT * FROM t1 WHERE a = (SELECT MAX(a) FROM t1 WHERE a = 1) ORDER BY b;
+a b
+1 1
+1 2
+1 3
+DROP TABLE t1;
+create table t1(val varchar(10));
+insert into t1 values ('aaa'), ('bbb'),('eee'),('mmm'),('ppp');
+select count(*) from t1 as w1 where w1.val in (select w2.val from t1 as w2 where w2.val like 'm%') and w1.val in (select w3.val from t1 as w3 where w3.val like 'e%');
+count(*)
+0
+drop table t1;
+create table t1 (id int not null, text varchar(20) not null default '', primary key (id));
+insert into t1 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text11'), (12, 'text12');
+select * from t1 where id not in (select id from t1 where id < 8);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+explain extended select * from t1 where id not in (select id from t1 where id < 8);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00 Using where
+2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not(<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;
+set @tmp11867_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin_with_cache=off';
+CREATE TABLE t1 (one int, two int, flag char(1));
+CREATE TABLE t2 (one int, two int, flag char(1));
+INSERT INTO t1 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+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`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+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`.`flag` = 'N') and (`test`.`t2`.`one` = `test`.`t1`.`one`) and (`test`.`t2`.`two` = `test`.`t1`.`two`))
+explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+DROP TABLE t1,t2;
+set optimizer_switch=@tmp11867_optimizer_switch;
+CREATE TABLE t1 (a char(5), b char(5));
+INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
+SELECT * FROM t1 WHERE (a,b) IN (('aaa','aaa'), ('aaa','bbb'));
+a b
+aaa aaa
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int, b int);
+CREATE TABLE t3 (b int NOT NULL);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+INSERT INTO t2 VALUES (1,10), (3,30);
+SELECT * FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10;
+a b b
+SELECT * FROM t1
+WHERE t1.a NOT IN (SELECT a FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10);
+a
+1
+2
+3
+4
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (f1 INT);
+CREATE TABLE t2 (f2 INT);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2);
+f1
+1
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE 1=0);
+f1
+1
+INSERT INTO t2 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE f2=0);
+f1
+1
+DROP TABLE t1, t2;
+select 1 from dual where 1 < any (select 2);
+1
+1
+select 1 from dual where 1 < all (select 2);
+1
+1
+select 1 from dual where 2 > any (select 1);
+1
+1
+select 1 from dual where 2 > all (select 1);
+1
+1
+select 1 from dual where 1 < any (select 2 from dual);
+1
+1
+select 1 from dual where 1 < all (select 2 from dual where 1!=1);
+1
+1
+create table t1 (s1 char);
+insert into t1 values (1),(2);
+select * from t1 where (s1 < any (select s1 from t1));
+s1
+1
+select * from t1 where not (s1 < any (select s1 from t1));
+s1
+2
+select * from t1 where (s1 < ALL (select s1+1 from t1));
+s1
+1
+select * from t1 where not(s1 < ALL (select s1+1 from t1));
+s1
+2
+select * from t1 where (s1+1 = ANY (select s1 from t1));
+s1
+1
+select * from t1 where NOT(s1+1 = ANY (select s1 from t1));
+s1
+2
+select * from t1 where (s1 = ALL (select s1/s1 from t1));
+s1
+1
+select * from t1 where NOT(s1 = ALL (select s1/s1 from t1));
+s1
+2
+drop table t1;
+create table t1 (
+retailerID varchar(8) NOT NULL,
+statusID int(10) unsigned NOT NULL,
+changed datetime NOT NULL,
+UNIQUE KEY retailerID (retailerID, statusID, changed)
+);
+INSERT INTO t1 VALUES("0026", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0026", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0037", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50");
+INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50");
+select * from t1 r1
+where (r1.retailerID,(r1.changed)) in
+(SELECT r2.retailerId,(max(changed)) from t1 r2
+group by r2.retailerId);
+retailerID statusID changed
+0026 2 2006-01-06 12:25:53
+0037 2 2006-01-06 12:25:53
+0048 1 2006-01-06 12:37:50
+0059 1 2006-01-06 12:37:50
+drop table t1;
+create table t1(a int, primary key (a));
+insert into t1 values (10);
+create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b));
+insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989');
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using where
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+a a b
+10 3 35989
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+a a b
+10 1 359
+drop table t1,t2;
+CREATE TABLE t1 (
+field1 int NOT NULL,
+field2 int NOT NULL,
+field3 int NOT NULL,
+PRIMARY KEY (field1,field2,field3)
+);
+CREATE TABLE t2 (
+fieldA int NOT NULL,
+fieldB int NOT NULL,
+PRIMARY KEY (fieldA,fieldB)
+);
+INSERT INTO t1 VALUES
+(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
+INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
+SELECT field1, field2, COUNT(*)
+FROM t1 GROUP BY field1, field2;
+field1 field2 COUNT(*)
+1 1 2
+1 2 3
+1 3 1
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) >= ALL (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 2
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) < ANY (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 1
+1 3
+DROP TABLE t1, t2;
+CREATE TABLE t1(a int, INDEX (a));
+INSERT INTO t1 VALUES (1), (3), (5), (7);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES (1),(2),(3);
+EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3
+2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using index; Full scan on NULL key
+SELECT a, a IN (SELECT a FROM t1) FROM t2;
+a a IN (SELECT a FROM t1)
+1 1
+2 NULL
+3 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a DATETIME);
+INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
+CREATE TABLE t2 AS SELECT
+(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a
+FROM t1 WHERE a > '2000-01-01';
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `sub_a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01');
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) > 0;
+a
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+a
+1
+2
+EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2), (4), (1), (3);
+CREATE TABLE t2 (b int, c int);
+INSERT INTO t2 VALUES
+(2,1), (1,3), (2,1), (4,4), (2,2), (1,4);
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2 );
+a
+2
+4
+1
+3
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a;
+a
+1
+2
+3
+4
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1), a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2);
+b MAX(c)
+1 4
+2 2
+4 4
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+1
+2
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+1
+2
+3
+4
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+1
+2
+3
+4
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1,t2;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+insert into t1 values(2.2);
+select * from t1 where df <= all (select avg(df) from t1 group by df);
+df
+1.1
+select * from t1 where df >= all (select avg(df) from t1 group by df);
+df
+2.2
+drop table t1;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+select 1.1 * exists(select * from t1);
+1.1 * exists(select * from t1)
+1.1
+drop table t1;
+CREATE TABLE t1 (
+grp int(11) default NULL,
+a decimal(10,2) default NULL);
+insert into t1 values (1, 1), (2, 2), (2, 3), (3, 4), (3, 5), (3, 6), (NULL, NULL);
+select * from t1;
+grp a
+1 1.00
+2 2.00
+2 3.00
+3 4.00
+3 5.00
+3 6.00
+NULL NULL
+select min(a) from t1 group by grp;
+min(a)
+NULL
+1.00
+2.00
+4.00
+drop table t1;
+CREATE table t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2 WHERE c2 IN (1);
+c1 c2
+1 1
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE c2 IN ( SELECT c2 FROM t2 WHERE c2 IN ( 1 ) );
+c1 c2
+1 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+INSERT INTO t1 VALUES ( 6 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+INSERT INTO t2 VALUES ( 6 );
+CREATE TABLE t3 ( c3 integer );
+INSERT INTO t3 VALUES ( 7 );
+INSERT INTO t3 VALUES ( 8 );
+SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL );
+c1 c2
+2 NULL
+3 NULL
+DROP TABLE t1,t2,t3;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+CREATE TABLE t1 (EMPNUM CHAR(3));
+CREATE TABLE t2 (EMPNUM CHAR(3) );
+INSERT INTO t1 VALUES ('E1'),('E2');
+INSERT INTO t2 VALUES ('E1');
+DELETE FROM t1
+WHERE t1.EMPNUM NOT IN
+(SELECT t2.EMPNUM
+FROM t2
+WHERE t1.EMPNUM = t2.EMPNUM);
+select * from t1;
+EMPNUM
+E1
+DROP TABLE t1,t2;
+CREATE TABLE t1(select_id BIGINT, values_id BIGINT);
+INSERT INTO t1 VALUES (1, 1);
+CREATE TABLE t2 (select_id BIGINT, values_id BIGINT,
+PRIMARY KEY(select_id,values_id));
+INSERT INTO t2 VALUES (0, 1), (0, 2), (0, 3), (1, 5);
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id IN (1, 0));
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id BETWEEN 0 AND 1);
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id = 0 OR select_id = 1);
+values_id
+1
+DROP TABLE t1, t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (c int, d int);
+CREATE TABLE t3 (e int);
+INSERT INTO t1 VALUES
+(1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40);
+INSERT INTO t2 VALUES
+(2,10), (2,20), (4,10), (5,10), (3,20), (2,40);
+INSERT INTO t3 VALUES (10), (30), (10), (20) ;
+SELECT a, MAX(b), MIN(b) FROM t1 GROUP BY a;
+a MAX(b) MIN(b)
+1 20 10
+2 30 10
+3 20 20
+4 40 40
+SELECT * FROM t2;
+c d
+2 10
+2 20
+4 10
+5 10
+3 20
+2 40
+SELECT * FROM t3;
+e
+10
+30
+10
+20
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>20);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)<d);
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>d);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d >= SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d > SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e < d));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE MIN(b) < d AND
+EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+SELECT a, SUM(a) FROM t1 GROUP BY a;
+a SUM(a)
+1 2
+2 6
+3 3
+4 4
+SELECT a FROM t1
+WHERE EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c) GROUP BY a;
+a
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c);
+a
+1
+3
+4
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c) GROUP BY a;
+a
+1
+2
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c);
+a
+1
+2
+1
+2
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a < ALL(SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+1
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3
+WHERE SUM(t1.a+t2.c) < t3.e/4));
+ERROR HY000: Invalid use of group function
+SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20;
+ERROR HY000: Invalid use of group function
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(t2.c+SUM(t1.b)) > 20);
+a
+2
+3
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(SUM(t1.b)) > 20);
+a
+2
+4
+SELECT t1.a, SUM(b) AS sum FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING t2.c+sum > 20);
+a sum
+2 60
+3 20
+4 40
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a varchar(5), b varchar(10));
+INSERT INTO t1 VALUES
+('AAA', 5), ('BBB', 4), ('BBB', 1), ('CCC', 2),
+('CCC', 7), ('AAA', 2), ('AAA', 4), ('BBB', 3), ('AAA', 8);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary
+ALTER TABLE t1 ADD INDEX(a);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 DEPENDENT SUBQUERY t1 index NULL a 8 NULL 1
+DROP TABLE t1;
+create table t1( f1 int,f2 int);
+insert into t1 values (1,1),(2,2);
+select tt.t from (select 'crash1' as t, f2 from t1) as tt left join t1 on tt.t = 'crash2' and tt.f2 = t1.f2 where tt.t = 'crash1';
+t
+crash1
+crash1
+drop table t1;
+create table t1 (c int, key(c));
+insert into t1 values (1142477582), (1142455969);
+create table t2 (a int, b int);
+insert into t2 values (2, 1), (1, 0);
+delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
+drop table t1, t2;
+CREATE TABLE t1 (a INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'IN/ALL/ANY subquery'
+DROP TABLE t1;
+create table t1 (i int, j bigint);
+insert into t1 values (1, 2), (2, 2), (3, 2);
+select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
+min(i)
+1
+drop table t1;
+CREATE TABLE t1 (i BIGINT UNSIGNED);
+INSERT INTO t1 VALUES (10000000000000000000);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (i BIGINT UNSIGNED);
+INSERT INTO t2 VALUES (10000000000000000000);
+INSERT INTO t2 VALUES (1);
+/* simple test */
+SELECT t1.i FROM t1 JOIN t2 ON t1.i = t2.i;
+i
+10000000000000000000
+1
+/* subquery test */
+SELECT t1.i FROM t1 WHERE t1.i = (SELECT MAX(i) FROM t2);
+i
+10000000000000000000
+/* subquery test with cast*/
+SELECT t1.i FROM t1 WHERE t1.i = CAST((SELECT MAX(i) FROM t2) AS UNSIGNED);
+i
+10000000000000000000
+DROP TABLE t1;
+DROP TABLE t2;
+CREATE TABLE t1 (
+id bigint(20) unsigned NOT NULL auto_increment,
+name varchar(255) NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES
+(1, 'Balazs'), (2, 'Joe'), (3, 'Frank');
+CREATE TABLE t2 (
+id bigint(20) unsigned NOT NULL auto_increment,
+mid bigint(20) unsigned NOT NULL,
+date date NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t2 VALUES
+(1, 1, '2006-03-30'), (2, 2, '2006-04-06'), (3, 3, '2006-04-13'),
+(4, 2, '2006-04-20'), (5, 1, '2006-05-01');
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 3, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 NULL
+2 Joe 2006-04-20 NULL
+3 Frank 2006-04-13 NULL
+SELECT *,
+(SELECT COUNT(*) FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_count
+FROM t1;
+id name date_count
+1 Balazs NULL
+2 Joe NULL
+3 Frank NULL
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 2006-03-30
+2 Joe 2006-04-20 2006-04-06
+3 Frank 2006-04-13 NULL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime NOT NULL default '0000-00-00 00:00:00',
+PRIMARY KEY (i1,i2,t)
+);
+INSERT INTO t1 VALUES
+(24,1,'2005-03-03 16:31:31'),(24,1,'2005-05-27 12:40:07'),
+(24,1,'2005-05-27 12:40:08'),(24,1,'2005-05-27 12:40:10'),
+(24,1,'2005-05-27 12:40:25'),(24,1,'2005-05-27 12:40:30'),
+(24,2,'2005-03-03 13:43:05'),(24,2,'2005-03-03 16:23:31'),
+(24,2,'2005-03-03 16:31:30'),(24,2,'2005-05-27 12:37:02'),
+(24,2,'2005-05-27 12:40:06');
+CREATE TABLE t2 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime default NULL,
+PRIMARY KEY (i1)
+);
+INSERT INTO t2 VALUES (24,1,'2006-06-20 12:29:40');
+EXPLAIN
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index
+2 DEPENDENT SUBQUERY t1 range PRIMARY PRIMARY 16 NULL 5 Using where; Using index
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+i1 i2 t i1 i2 t
+24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b));
+insert into t1 (a) values (FLOOR(rand() * 100));
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+SELECT a,
+(SELECT REPEAT(' ',250) FROM t1 i1
+WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a
+FROM t1 ORDER BY a LIMIT 5;
+a a
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 values (1);
+INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4);
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2)
+2
+1
+1
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+2
+1
+1
+SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b))
+2 2
+1 1
+1 1
+SELECT COUNT(DISTINCT t1.b),
+(SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+2 2
+1 1
+1 1
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a;
+(
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+2
+1
+1
+SELECT (
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+FROM t1 t2
+GROUP BY t2.a;
+(
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+2
+2
+2
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (b));
+CREATE TABLE t2 (x int auto_increment, y int, z int,
+PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1 select RAND()*1000, A.a + 10*(B.a+10*(C.a+10*D.a))
+from t3 A, t3 B, t3 C, t3 D where D.a<3;
+insert into t2(y,z) select t1.b, RAND()*1000 from t1, t3;
+SET SESSION sort_buffer_size = 32 * 1024;
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+SET SESSION sort_buffer_size = 8 * 1024 * 1024;
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
+CREATE TABLE t2 (c int);
+INSERT INTO t1 VALUES ('aa', 1);
+INSERT INTO t2 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+INSERT INTO t1 VALUES ('bb', 2), ('cc', 3), ('dd',1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+INSERT INTO t2 VALUES (2);
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT t2.c FROM t2 JOIN t3 ON t2.c=t3.c WHERE t2.c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1(f1 int);
+CREATE TABLE t2(f2 int, f21 int, f3 timestamp);
+INSERT INTO t1 VALUES (1),(1),(2),(2);
+INSERT INTO t2 VALUES (1,1,"2004-02-29 11:11:11"), (2,2,"2004-02-29 11:11:11");
+SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1;
+sq
+2
+4
+SELECT (SELECT SUM(1) FROM t2 ttt GROUP BY t2.f3 LIMIT 1) AS tt FROM t2;
+tt
+2
+2
+PREPARE stmt1 FROM 'SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1';
+EXECUTE stmt1;
+sq
+2
+4
+EXECUTE stmt1;
+sq
+2
+4
+DEALLOCATE PREPARE stmt1;
+SELECT f2, AVG(f21),
+(SELECT t.f3 FROM t2 AS t WHERE t2.f2=t.f2 AND t.f3=MAX(t2.f3)) AS test
+FROM t2 GROUP BY f2;
+f2 AVG(f21) test
+1 1.0000 2004-02-29 11:11:11
+2 2.0000 2004-02-29 11:11:11
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL);
+INSERT INTO t1 VALUES
+(1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
+(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'),
+(3,2,'k'), (3,1,'l'), (1,9,'m');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t1xt2;
+CREATE TABLE t1 (
+id_1 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t2 (
+id_2 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t1xt2 (
+id_1 int(5) NOT NULL,
+id_2 int(5) NOT NULL
+);
+INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
+INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
+INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+3
+4
+insert INTO t1xt2 VALUES (1, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+2
+3
+4
+insert INTO t1xt2 VALUES (2, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+3
+4
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t1xt2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (3), (1), (2);
+SELECT 'this is ' 'a test.' AS col1, a AS col2 FROM t1;
+col1 col2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+SELECT * FROM (SELECT 'this is ' 'a test.' AS col1, a AS t2 FROM t1) t;
+col1 t2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+DROP table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*), a,
+(SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a,
+(SELECT MIN(m) FROM t2 WHERE m = count(*))
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT MIN(m) FROM t2 WHERE m = count(*))
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a
+FROM t1 GROUP BY a
+HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1;
+COUNT(*) a
+2 2
+3 3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+2 2 2
+3 3 3
+1 4 1,1
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+2 2 3
+3 3 4
+1 4 2,2
+DROP table t1,t2;
+CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
+INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'),
+(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'),
+(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a x, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+x MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a, AVG(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test
+FROM t1 WHERE t1.d=0 GROUP BY a;
+a AVG(b) test
+1 4.0000 d
+2 2.0000 g
+3 2.5000 NULL
+SELECT tt.a,
+(SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt;
+a test
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+2 o
+2 o
+2 o
+2 o
+3 p
+3 p
+3 p
+3 p
+3 p
+SELECT tt.a,
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+SELECT tt.a, MAX(
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+a
+1
+2
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+a
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+a
+1
+2
+SET @@sql_mode='ansi';
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+ERROR HY000: Invalid use of group function
+SET @@sql_mode=default;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 values (1),(1),(1),(1);
+CREATE TABLE t2 (x INT);
+INSERT INTO t1 values (1000),(1001),(1002);
+SELECT SUM( (SELECT COUNT(a) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT SUM( (SELECT SUM(COUNT(a)) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT COUNT(1) FROM DUAL;
+COUNT(1)
+1
+SELECT SUM( (SELECT AVG( (SELECT t1.a FROM t2) ) FROM DUAL) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING t1.a < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT t1.a as XXA,
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, KEY (a));
+INSERT INTO t1 VALUES (1,1),(2,1);
+EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref a a 5 const 0 Using where; Using index
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+DROP TABLE t1;
+CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
+INSERT INTO t1 VALUES
+(3,'FL'), (2,'GA'), (4,'FL'), (1,'GA'), (5,'NY'), (7,'FL'), (6,'NY');
+CREATE TABLE t2 (id int NOT NULL, INDEX idx(id));
+INSERT INTO t2 VALUES (7), (5), (1), (3);
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+3 FL
+1 GA
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+1 GA
+3 FL
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+2 GA
+4 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+2 GA
+4 FL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT count(*) FROM t1 GROUP BY a) as res;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `res`.`count(*)` AS `count(*)` from (select count(0) AS `count(*)` from `test`.`t1` group by `test`.`t1`.`a`) `res`
+DROP TABLE t1;
+CREATE TABLE t1 (
+a varchar(255) default NULL,
+b timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+INDEX idx(a,b)
+);
+CREATE TABLE t2 (
+a varchar(255) default NULL
+);
+INSERT INTO t1 VALUES ('abcdefghijk','2007-05-07 06:00:24');
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26');
+INSERT INTO `t2` VALUES ('abcdefghijk');
+INSERT INTO `t2` VALUES ('asdf');
+SET session sort_buffer_size=8192;
+SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
+d1
+1
+1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INTEGER, b INTEGER);
+CREATE TABLE t2 (x INTEGER);
+INSERT INTO t1 VALUES (1,11), (2,22), (2,22);
+INSERT INTO t2 VALUES (1), (2);
+SELECT a, COUNT(b), (SELECT COUNT(b) FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a, COUNT(b), (SELECT COUNT(b)+0 FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a)/AVG(t2.x) FROM t2) FROM t1;
+(SELECT SUM(t1.a)/AVG(t2.x) FROM t2)
+3.3333
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1, 2), (1,3), (1,4), (2,1), (2,2);
+SELECT a1.a, COUNT(*) FROM t1 a1 WHERE a1.a = 1
+AND EXISTS( SELECT a2.a FROM t1 a2 WHERE a2.a = a1.a)
+GROUP BY a1.a;
+a COUNT(*)
+1 3
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+INSERT INTO t2 VALUES (1),(2);
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=0) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=0)
+NULL
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a!=0) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=1) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=1)
+3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a1 INT, a2 INT);
+CREATE TABLE t2 (b1 INT, b2 INT);
+INSERT INTO t1 VALUES (100, 200);
+INSERT INTO t1 VALUES (101, 201);
+INSERT INTO t2 VALUES (101, 201);
+INSERT INTO t2 VALUES (103, 203);
+SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1;
+((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL
+0
+0
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5));
+INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+CREATE INDEX I1 ON t1 (s1);
+CREATE INDEX I2 ON t1 (s2);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+TRUNCATE t1;
+INSERT INTO t1 VALUES (0x41,0x41);
+SELECT * FROM t1 WHERE s1 = (SELECT s2 FROM t1);
+s1 s2
+DROP TABLE t1;
+CREATE TABLE t1 (a1 VARBINARY(2) NOT NULL DEFAULT '0', PRIMARY KEY (a1));
+CREATE TABLE t2 (a2 BINARY(2) default '0', INDEX (a2));
+CREATE TABLE t3 (a3 BINARY(2) default '0');
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+INSERT INTO t3 VALUES (1),(2),(3);
+SELECT LEFT(t2.a2, 1) FROM t2,t3 WHERE t3.a3=t2.a2;
+LEFT(t2.a2, 1)
+1
+2
+3
+SELECT t1.a1, t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2) FROM t1;
+a1 t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2)
+1 0
+2 0
+3 0
+4 0
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a1 BINARY(3) PRIMARY KEY, b1 VARBINARY(3));
+CREATE TABLE t2 (a2 VARBINARY(3) PRIMARY KEY);
+CREATE TABLE t3 (a3 VARBINARY(3) PRIMARY KEY);
+INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40);
+INSERT INTO t2 VALUES (2), (3), (4), (5);
+INSERT INTO t3 VALUES (10), (20), (30);
+SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3;
+LEFT(t1.a1,1)
+1
+2
+3
+SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
+a2
+DROP TABLE t1, t2, t3;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+SET optimizer_switch='materialization=off';
+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;
+SET optimizer_switch= @save_optimizer_switch;
+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);
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) 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 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,<exists>(select min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a` having (1 = <ref_null_helper>(min(`test`.`t1`.`a`))))))
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 WHERE a > 3 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,<exists>(select min(`test`.`t1`.`a`) from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` having (1 = <ref_null_helper>(min(`test`.`t1`.`a`))))))
+SET join_cache_level=@save_join_cache_level;
+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 NULL
+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;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+EXPLAIN EXTENDED
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+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 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <nop>(<in_optimizer>(1,((select max(`test`.`t1`.`a1`) from `test`.`t1`) > 1)))
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+1
+1
+1
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1, t2;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
+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
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
+INSERT INTO t1 VALUES (1,NULL), (9,NULL);
+CREATE TABLE t2 (
+a INT,
+b INT,
+c INT,
+d INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c,d),
+KEY b_2 (b),
+KEY c (c),
+KEY d (d)
+);
+INSERT INTO t2 VALUES
+(43, 2, 11 ,30),
+(44, 2, 12 ,30),
+(45, 1, 1 ,10000),
+(46, 1, 2 ,10000),
+(556,1, 32 ,10000);
+CREATE TABLE t3 (
+a INT,
+b INT,
+c INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c),
+KEY c (c),
+KEY b_2 (b)
+);
+INSERT INTO t3 VALUES (1,1,1), (2,32,1);
+explain
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 PRIMARY t3 ref b,b_2 b 5 test.t1.a 1 Using index
+2 DEPENDENT SUBQUERY t2 ref b,b_2,c b 10 test.t3.c,test.t1.a 1 Using where; Using index; Using filesort
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+a incorrect
+1 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int, c int);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+CREATE VIEW v1 AS
+SELECT t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+UPDATE v1 SET c=1;
+CREATE VIEW v2 (a,b) AS
+SELECT t2.id, t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+INSERT INTO v2(a,b) VALUES (2,2);
+ERROR HY000: CHECK OPTION failed 'test.v2'
+SELECT * FROM v1;
+c
+1
+1
+1
+1
+CREATE VIEW v3 AS
+SELECT t2.c AS c FROM t2
+WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+DELETE FROM v3;
+DROP VIEW v1,v2,v3;
+DROP TABLE t1,t2;
+#
+# BUG#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+#
+# Bug#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+CREATE TABLE t1 (a ENUM('rainbow'));
+INSERT INTO t1 VALUES (),(),(),(),();
+SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
+1
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGBLOB);
+INSERT INTO t1 SET a = 'aaaa';
+INSERT INTO t1 SET a = 'aaaa';
+SELECT 1 FROM t1 GROUP BY
+(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
+1
+1
+DROP TABLE t1;
+#
+# Bug #49512 : subquery with aggregate function crash
+# subselect_single_select_engine::exec()
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES();
+# should not crash
+SELECT 1 FROM t1 WHERE a <> SOME
+(
+SELECT MAX((SELECT a FROM t1 LIMIT 1)) AS d
+FROM t1,t1 a
+);
+1
+DROP TABLE t1;
+#
+# Bug #45989 take 2 : memory leak after explain encounters an
+# error in the query
+#
+CREATE TABLE t1(a LONGTEXT);
+INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet));
+INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet));
+EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1,
+(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) AS d1
+WHERE t1.a = d1.a;
+ERROR 42S22: Unknown column 'd1.a' in 'where clause'
+DROP TABLE t1;
+Set up test tables.
+CREATE TABLE t1 (
+t1_id INT UNSIGNED,
+PRIMARY KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t1 (t1_id) VALUES (1), (2), (3), (4), (5);
+CREATE TABLE t2 SELECT * FROM t1;
+CREATE TABLE t3 (
+t3_id INT UNSIGNED AUTO_INCREMENT,
+t1_id INT UNSIGNED,
+amount DECIMAL(16,2),
+PRIMARY KEY(t3_id),
+KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t3 (t1_id, t3_id, amount)
+VALUES (1, 1, 100.00), (2, 2, 200.00), (4, 4, 400.00);
+This is the 'inner query' running by itself.
+Produces correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query)
+Produces correct results.
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+Now make t2.t1_id part of a key.
+ALTER TABLE t2 ADD PRIMARY KEY(t1_id);
+Same inner query by itself.
+Still correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query), now with indexes on the LEFT JOIN
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+DROP TABLE t3;
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# Bug #52711: Segfault when doing EXPLAIN SELECT with
+# union...order by (select... where...)
+#
+CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a));
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (1),(2);
+# Should not crash
+EXPLAIN
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+# Should not crash
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+DROP TABLE t1,t2;
+# LP BUG#675248 - select->prep_where references on freed memory
+CREATE TABLE t1 (a int, b int);
+insert into t1 values (1,1),(0,0);
+CREATE TABLE t2 (c int);
+insert into t2 values (1),(2);
+prepare stmt1 from "select sum(a),(select sum(c) from t2 where table1.b) as sub
+from t1 as table1 group by sub";
+execute stmt1;
+sum(a) sub
+0 NULL
+1 3
+deallocate prepare stmt1;
+prepare stmt1 from "select sum(a),(select sum(c) from t2 having table1.b) as sub
+from t1 as table1";
+execute stmt1;
+sum(a) sub
+1 3
+deallocate prepare stmt1;
+drop table t1,t2;
+#
+# Bug LP#693935/#58727: Assertion failure with
+# a single row subquery returning more than one row
+#
+create table t1 (a char(1) charset utf8);
+insert into t1 values ('a'), ('b');
+create table t2 (a binary(1));
+insert into t2 values ('x'), ('y');
+select * from t2 where a=(select a from t1) and a='x';
+ERROR 21000: Subquery returns more than 1 row
+drop table t1,t2;
+End of 5.1 tests
+#
+# No BUG#, a case brought from 5.2's innodb_mysql_lock.test
+#
+create table t1 (i int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+create table t2 (j int not null primary key);
+insert into t2 values (1),(2),(3),(4),(5);
+create table t3 (k int not null primary key);
+insert into t3 values (1),(2),(3);
+create view v2 as select t2.j as j from t2 where t2.j in (select t1.i from t1);
+select * from t3 where k in (select j from v2);
+k
+1
+2
+3
+drop table t1,t2,t3;
+drop view v2;
+#
+# Bug#52068: Optimizer generates invalid semijoin materialization plan
+#
+drop table if exists ot1, ot2, it1, it2;
+CREATE TABLE ot1(a INTEGER);
+INSERT INTO ot1 VALUES(5), (8);
+CREATE TABLE it2(a INTEGER);
+INSERT INTO it2 VALUES(9), (5), (1), (8);
+CREATE TABLE it3(a INTEGER);
+INSERT INTO it3 VALUES(7), (1), (0), (5), (1), (4);
+CREATE TABLE ot4(a INTEGER);
+INSERT INTO ot4 VALUES(1), (3), (5), (7), (9), (7), (3), (1);
+SELECT * FROM ot1,ot4
+WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
+FROM it2,it3);
+a a
+5 1
+8 1
+5 5
+8 5
+5 7
+8 7
+5 7
+8 7
+5 1
+8 1
+explain SELECT * FROM ot1,ot4
+WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
+FROM it2,it3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 2
+1 PRIMARY ot4 ALL NULL NULL NULL NULL 8 Using join buffer (flat, BNL join)
+1 PRIMARY it2 ALL NULL NULL NULL NULL 4 Using where
+1 PRIMARY it3 ALL NULL NULL NULL NULL 6 Using where; FirstMatch(ot4)
+DROP TABLE IF EXISTS ot1, ot4, it2, it3;
+#
+# Bug#729039: NULL keys used to evaluate subquery
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (NULL), (1), (NULL), (2);
+CREATE TABLE t2 (a int, INDEX idx(a)) ;
+INSERT INTO t2 VALUES (NULL), (1), (NULL);
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a);
+a
+1
+EXPLAIN
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+a
+1
+EXPLAIN
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
+DROP TABLE t1,t2;
+#
+# BUG#752992: Wrong results for a subquery with 'semijoin=on'
+#
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
+EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 3
+1 PRIMARY it eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index
+1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; FirstMatch(it)
+SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+pk i
+11 0
+12 5
+15 0
+SET join_cache_level=@save_join_cache_level;
+DROP table t1,t2;
+#
+# Bug#751350: crash with pushed condition for outer references when
+# there should be none of such conditions
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0),(0,0);
+set @optimizer_switch_save=@@optimizer_switch;
+set @@optimizer_switch='semijoin=off,materialization=on,in_to_exists=on';
+EXPLAIN
+SELECT b FROM t1
+WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT b FROM t1
+WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+GROUP BY b;
+b
+0
+set @@optimizer_switch=@optimizer_switch_save;
+DROP TABLE t1;
+#
+# Bug #11765713 58705:
+# OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES
+# CREATED BY OPT_SUM_QUERY
+#
+CREATE TABLE t1(a INT NOT NULL, KEY (a));
+INSERT INTO t1 VALUES (0), (1);
+SELECT 1 as foo FROM t1 WHERE a < SOME
+(SELECT a FROM t1 WHERE a <=>
+(SELECT a FROM t1)
+);
+ERROR 21000: Subquery returns more than 1 row
+SELECT 1 as foo FROM t1 WHERE a < SOME
+(SELECT a FROM t1 WHERE a <=>
+(SELECT a FROM t1 where a is null)
+);
+foo
+DROP TABLE t1;
+CREATE TABLE t1 (a int(11), b varchar(1));
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+delete from t1;
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+drop table t1;
+#
+# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3)) ;
+INSERT IGNORE INTO t2 VALUES (NULL,NULL),(5,0);
+DROP TABLE IF EXISTS t3;
+Warnings:
+Note 1051 Unknown table 't3'
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ;
+r
+NULL
+5
+NULL
+5
+DROP TABLE t1, t2, t3;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+1
+1
+1
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1, t2;
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
+#
+# BUG#50257: Missing info in REF column of the EXPLAIN
+# lines for subselects
+#
+CREATE TABLE t1 (a INT, b INT, INDEX (a));
+INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref a a 5 const 1
+EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 SUBQUERY t1 ref a a 5 const 1 Using index
+DROP TABLE t1;
+#
+# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS)
+# (duplicate of LP bug #888456)
+#
+CREATE TABLE t1 (f1 varchar(1));
+INSERT INTO t1 VALUES ('v'),('s');
+CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key));
+INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'),
+('d'),('y'),('t'),('d'),('s');
+EXPLAIN
+SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2
+WHERE EXISTS (SELECT DISTINCT f1_key FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY table1 ALL NULL NULL NULL NULL 2
+1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index
+SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2
+WHERE EXISTS (SELECT DISTINCT f1_key FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1);
+f1 f1_key
+v j
+s j
+v v
+s v
+v c
+s c
+v m
+s m
+v d
+s d
+v d
+s d
+v y
+s y
+v t
+s t
+v d
+s d
+v s
+s s
+DROP TABLE t1,t2;
+#
+# LP bug 919427: EXPLAIN for a query over a single-row table
+# with IN subquery in WHERE condition
+#
+CREATE TABLE ot (
+col_int_nokey int(11),
+col_varchar_nokey varchar(1)
+) ;
+INSERT INTO ot VALUES (1,'x');
+CREATE TABLE it1(
+col_int_key int(11),
+col_varchar_key varchar(1),
+KEY idx_cvk_cik (col_varchar_key,col_int_key)
+);
+INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f');
+CREATE TABLE it2 (
+col_int_key int(11),
+col_varchar_key varchar(1),
+col_varchar_key2 varchar(1),
+KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key),
+KEY idx_cvk_cik (col_varchar_key, col_int_key)
+);
+INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f');
+EXPLAIN
+SELECT col_int_nokey FROM ot
+WHERE col_varchar_nokey IN
+(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot system NULL NULL NULL NULL 1
+1 PRIMARY it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index; FirstMatch(ot)
+SELECT col_int_nokey FROM ot
+WHERE col_varchar_nokey IN
+(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL);
+col_int_nokey
+1
+EXPLAIN
+SELECT col_int_nokey FROM ot
+WHERE (col_varchar_nokey, 'x') IN
+(SELECT col_varchar_key, col_varchar_key2 FROM it2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot system NULL NULL NULL NULL 1
+1 PRIMARY it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index; FirstMatch(ot)
+SELECT col_int_nokey FROM ot
+WHERE (col_varchar_nokey, 'x') IN
+(SELECT col_varchar_key, col_varchar_key2 FROM it2);
+col_int_nokey
+1
+DROP TABLE ot,it1,it2;
+#
+# MDEV-746
+# Bug#13651009 WRONG RESULT FROM DERIVED TABLE IF THE SUBQUERY
+# HAS AN EMPTY RESULT
+#
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_int_nokey int NOT NULL,
+col_int_key int NOT NULL,
+col_time_key time 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_time_key (col_time_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM;
+CREATE TABLE t2 (
+pk int NOT NULL AUTO_INCREMENT,
+col_int_nokey int NOT NULL,
+col_int_key int NOT NULL,
+col_time_key time 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_time_key (col_time_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,4,4,'00:00:00','b','b');
+SET @var2:=4, @var3:=8;
+
+Testcase without inner subquery
+EXPLAIN SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3;
+@var3:=12 pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+SELECT @var3;
+@var3
+8
+EXPLAIN SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3 ) AS alias3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE <derived2> system NULL NULL NULL NULL 0 const row not found
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3 ) AS alias3;
+@var3:=12 pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+SELECT @var3;
+@var3
+8
+
+Testcase with inner subquery; crashed WL#6095
+SET @var3=8;
+EXPLAIN SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3));
+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 c_sq1_alias1 system PRIMARY NULL NULL NULL 1
+SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3));
+pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+EXPLAIN SELECT * FROM ( SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3)) ) AS alias3;
+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
+3 DEPENDENT SUBQUERY c_sq1_alias1 system PRIMARY NULL NULL NULL 1
+SELECT * FROM ( SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3)) ) AS alias3;
+pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+DROP TABLE t1,t2;
+End of 5.2 tests
+#
+# BUG#779885: Crash in eliminate_item_equal with materialization=on in
+#
+CREATE TABLE t1 ( f1 int );
+INSERT INTO t1 VALUES (19), (20);
+CREATE TABLE t2 ( f10 varchar(32) );
+INSERT INTO t2 VALUES ('c'),('d');
+CREATE TABLE t3 ( f10 varchar(32) );
+INSERT INTO t3 VALUES ('a'),('b');
+SELECT *
+FROM t1
+WHERE
+( 't' ) IN (
+SELECT t3.f10
+FROM t3
+JOIN t2
+ON t2.f10 = t3.f10
+);
+f1
+DROP TABLE t1,t2,t3;
+#
+# BUG LP:813473: Wrong result with outer join + NOT IN subquery
+# This bug is a duplicate of Bug#11764086 whose test case is added below
+#
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (5),(6);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (20,9),(20,9);
+create table t3 (d int, e int);
+insert into t3 values (2, 9), (3,10);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+EXPLAIN
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b , t1.c) NOT IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b, t1.c) NOT IN (SELECT * from t3);
+b c
+9 NULL
+9 NULL
+SET optimizer_switch=@save_optimizer_switch;
+drop table t1, t2, t3;
+#
+# Bug#11764086: Null left operand to NOT IN in WHERE clause
+# behaves differently than real NULL
+#
+CREATE TABLE parent (id int);
+INSERT INTO parent VALUES (1), (2);
+CREATE TABLE child (parent_id int, other int);
+INSERT INTO child VALUES (1,NULL);
+# Offending query (c.parent_id is NULL for null-complemented rows only)
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id NOT IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+);
+id parent_id
+1 1
+2 NULL
+# Some syntactic variations with IS FALSE and IS NOT TRUE
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS NOT TRUE;
+id parent_id
+1 1
+2 NULL
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS FALSE;
+id parent_id
+1 1
+2 NULL
+DROP TABLE parent, child;
+# End of test for bug#11764086.
+#
+# Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET ||
+# BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0), (1);
+CREATE TABLE t2(
+b TEXT,
+c INT,
+PRIMARY KEY (b(1))
+);
+INSERT INTO t2 VALUES ('a', 2), ('b', 3);
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ORDER BY b
+);
+1
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+GROUP BY b
+);
+1
+DROP TABLE t1, t2;
+#
+# LP bug #826279: assertion failure with GROUP BY a result of subquery
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0), (0);
+CREATE TABLE t2 (a int, b int, c int);
+INSERT INTO t2 VALUES (10,7,0), (0,7,0);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,7), (0,7);
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+7 NULL
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+7 NULL
+7 10
+DROP TABLE t1,t2,t3;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+#
+# LP BUG#833777 Performance regression with deeply nested subqueries
+#
+create table t1 (a int not null, b char(10) not null);
+insert into t1 values (1, 'a');
+set @@optimizer_switch='in_to_exists=on,semijoin=off,materialization=off,subquery_cache=off';
+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)))))))))))))))))))))))))))));
+a
+1
+set @@optimizer_switch=@subselect_tmp;
+drop table t1;
+#
+# LP BUG#894397 Wrong result with in_to_exists, constant table , semijoin=OFF,materialization=OFF
+#
+CREATE TABLE t1 (a varchar(3));
+INSERT INTO t1 VALUES ('AAA'),('BBB');
+CREATE TABLE t2 (a varchar(3));
+INSERT INTO t2 VALUES ('CCC');
+set @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquery_cache=off';
+SELECT * FROM t1 WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.a < 'ZZZ');
+a
+set @@optimizer_switch=@subselect_tmp;
+drop table t1, t2;
+#
+# LP bug #859375: Assertion `0' failed in st_select_lex_unit::optimize
+# with view , UNION and prepared statement (rewriting fake_select
+# condition).
+#
+CREATE TABLE t1 ( f1 int NOT NULL, f4 varchar(1) NOT NULL) ;
+INSERT INTO t1 VALUES (6,'d'),(7,'y');
+CREATE TABLE t2 ( f1 int NOT NULL, f2 int NOT NULL) ;
+INSERT INTO t2 VALUES (10,7);
+CREATE VIEW v2 AS SELECT * FROM t2;
+PREPARE st1 FROM "
+ SELECT *
+ FROM t1
+ LEFT JOIN v2 ON ( v2.f2 = t1.f1 )
+ WHERE v2.f1 NOT IN (
+ SELECT 1 UNION
+ SELECT 247
+ )
+";
+EXECUTE st1;
+f1 f4 f1 f2
+7 y 10 7
+deallocate prepare st1;
+DROP VIEW v2;
+DROP TABLE t1,t2;
+#
+# LP bug #887458 Crash in subselect_union_engine::no_rows with
+# double UNION and join_cache_level=3,8
+# (IN/ALL/ANY optimizations should not be applied to fake_select)
+CREATE TABLE t2 ( a int, b varchar(1)) ;
+INSERT IGNORE INTO t2 VALUES (8,'y'),(8,'y');
+CREATE TABLE t1 ( b varchar(1)) ;
+INSERT IGNORE INTO t1 VALUES (NULL),(NULL);
+set @save_join_cache_level=@@join_cache_level;
+SET SESSION join_cache_level=3;
+SELECT *
+FROM t1, t2
+WHERE t2.b IN (
+SELECT 'm' UNION
+SELECT 'm'
+) OR t1.b <> SOME (
+SELECT 'v' UNION
+SELECT 't'
+);
+b a b
+set @@join_cache_level= @save_join_cache_level;
+drop table t1,t2;
+#
+# LP bug #885162 Got error 124 from storage engine with UNION inside
+# subquery and join_cache_level=3..8
+# (IN/ALL/ANY optimizations should not be applied to fake_select)
+#
+CREATE TABLE t1 (
+f1 varchar(1) DEFAULT NULL
+);
+INSERT INTO t1 VALUES ('c');
+set @save_join_cache_level=@@join_cache_level;
+SET SESSION join_cache_level=8;
+SELECT * FROM t1 WHERE t1.f1 IN ( SELECT 'k' UNION SELECT 'e' );
+f1
+set @@join_cache_level= @save_join_cache_level;
+drop table t1;
+#
+# LP BUG#747278 incorrect values of the NULL (no rows) single
+# row subquery requested via element_index() interface
+#
+CREATE TABLE t1 (f1a int, f1b int) ;
+INSERT IGNORE INTO t1 VALUES (1,1),(2,2);
+CREATE TABLE t2 ( f2 int);
+INSERT IGNORE INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (f3a int default 1, f3b int default 2);
+INSERT INTO t3 VALUES (1,1),(2,2);
+set @old_optimizer_switch = @@session.optimizer_switch;
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,subquery_cache=off,semijoin=off';
+SELECT (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+SELECT (SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+set @@session.optimizer_switch=@old_optimizer_switch;
+SELECT (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+SELECT (SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+select (null, null) = (null, null);
+(null, null) = (null, null)
+NULL
+SELECT (SELECT f3a, f3a FROM t3 where f3a > 3) = (0, 0);
+(SELECT f3a, f3a FROM t3 where f3a > 3) = (0, 0)
+NULL
+drop tables t1,t2,t3;
+#
+# LP BUG#825051 Wrong result with date/datetime and subquery with GROUP BY and in_to_exists
+#
+CREATE TABLE t1 (a date, KEY (a)) ;
+INSERT INTO t1 VALUES ('2009-01-01'),('2009-02-02');
+set @old_optimizer_switch = @@optimizer_switch;
+SET @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index
+2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 2 Using index
+SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+a
+2009-01-01
+2009-02-02
+SET @@optimizer_switch='semijoin=off,materialization=on,in_to_exists=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index
+2 MATERIALIZED t1 index NULL a 4 NULL 2 Using index
+SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+a
+2009-01-01
+2009-02-02
+set @@optimizer_switch=@old_optimizer_switch;
+drop table t1;
+#
+# LP BUG#908269 incorrect condition in case of subqueries depending
+# on constant tables
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 ( b INT ) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (4),(5);
+SET optimizer_switch='subquery_cache=off';
+SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) )
+1
+NULL
+SELECT ( SELECT b FROM t2 WHERE b = a OR b * 0) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR b * 0)
+1
+NULL
+SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR rand() * 0)
+1
+NULL
+drop table t1,t2,t3;
+set optimizer_switch=@subselect_tmp;
+#
+# LP BUG#905353 Wrong non-empty result with a constant table,
+# aggregate function in subquery, MyISAM or Aria
+#
+CREATE TABLE t1 ( a INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1);
+SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 );
+a
+drop table t1;
+#
+# LP BUG#985667 Wrong result with subquery in SELECT clause, and constant table in
+# main query and implicit grouping
+#
+CREATE TABLE t1 (f1 int) engine=MyISAM;
+INSERT INTO t1 VALUES (7),(8);
+CREATE TABLE t2 (f2 int, f3 varchar(1)) engine=MyISAM;
+INSERT INTO t2 VALUES (3,'f');
+EXPLAIN
+SELECT COUNT(f1), (SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2
+SELECT COUNT(f1), (SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 NULL
+EXPLAIN
+SELECT COUNT(f1), exists(SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2
+SELECT COUNT(f1), exists(SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 0
+EXPLAIN
+SELECT COUNT(f1), f2 > ALL (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2 Using where
+SELECT COUNT(f1), f2 > ALL (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 1
+EXPLAIN
+SELECT COUNT(f1), f2 IN (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2 Using where
+SELECT COUNT(f1), f2 IN (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 0
+drop table t1,t2;
+#
+# LP BUG#1002079 Server crashes in Item_singlerow_subselect::val_int with constant table,
+# HAVING, UNION in subquery
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (7),(0);
+CREATE TABLE t2 (b INT);
+EXPLAIN
+SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
+f1 f2
+drop table t1,t2;
+#
+# LP BUG#1008686 Server crashes in subselect_union_engine::no_rows on SELECT with impossible
+# WHERE and UNION in HAVING
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(7);
+EXPLAIN
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 0 HAVING a NOT IN ( SELECT 2 UNION SELECT 5 ) OR min_a != 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 NULL NULL NULL NULL NULL NULL NULL No tables used
+3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 0 HAVING a NOT IN ( SELECT 2 UNION SELECT 5 ) OR min_a != 1;
+min_a a
+EXPLAIN
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 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 ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 2 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 1;
+min_a a
+drop table t1;
+#
+# MDEV-367: Different results with and without subquery_cache on
+# a query with a constant NOT IN condition
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2),(3);
+set @mdev367_optimizer_switch = @@optimizer_switch;
+set optimizer_switch = 'subquery_cache=on';
+SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
+a
+SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
+a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
+1 NULL
+2 NULL
+3 NULL
+set optimizer_switch=@mdev367_optimizer_switch;
+set optimizer_switch = 'subquery_cache=off';
+SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
+a
+SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
+a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
+1 NULL
+2 NULL
+3 NULL
+set optimizer_switch=@mdev367_optimizer_switch;
+DROP TABLE t1;
+#
+# MDEV-521 single value subselect transformation problem
+#
+CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('u1'),('u2');
+SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) );
+f1
+u1
+u2
+FLUSH TABLES;
+SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) );
+f1
+u1
+u2
+DROP TABLE t1;
+# return optimizer switch changed in the beginning of this test
+set optimizer_switch=@subselect_tmp;
+set optimizer_switch=default;
+select @@optimizer_switch like '%materialization=on%';
+@@optimizer_switch like '%materialization=on%'
+1
+set @join_cache_level_for_subselect_test=NULL;
diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
new file mode 100644
index 00000000000..47f6d3a0ed4
--- /dev/null
+++ b/mysql-test/r/subselect_no_opts.result
@@ -0,0 +1,6288 @@
+set @optimizer_switch_for_subselect_test='materialization=off,semijoin=off,subquery_cache=off,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set join_cache_level=1;
+set @join_cache_level_for_subselect_test=@@join_cache_level;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+drop view if exists v2;
+set @subselect_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test,
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+set join_cache_level=@join_cache_level_for_subselect_test;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+select (select 2);
+(select 2)
+2
+explain extended select (select 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select 2 AS `(select 2)`
+SELECT (SELECT 1) UNION SELECT (SELECT 2);
+(SELECT 1)
+1
+2
+explain extended SELECT (SELECT 1) UNION SELECT (SELECT 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1249 Select 4 was reduced during optimization
+Note 1003 select 1 AS `(SELECT 1)` union select 2 AS `(SELECT 2)`
+SELECT (SELECT (SELECT 0 UNION SELECT 0));
+(SELECT (SELECT 0 UNION SELECT 0))
+0
+explain extended SELECT (SELECT (SELECT 0 UNION SELECT 0));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (select 0 union select 0) AS `(SELECT (SELECT 0 UNION SELECT 0))`
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) as c HAVING a=1) as b;
+ERROR 42S22: Reference 'b' not supported (forward reference in item list)
+SELECT (SELECT 1),MAX(1) FROM (SELECT 1) as a;
+(SELECT 1) MAX(1)
+1 1
+SELECT (SELECT a) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having ((select 1) = 1)
+SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+1
+1
+SELECT (SELECT 1), a;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT 1 as a FROM (SELECT 1) as b HAVING (SELECT a)=1;
+a
+1
+SELECT 1 FROM (SELECT (SELECT a) b) c;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT * FROM (SELECT 1 as id) b WHERE id IN (SELECT * FROM (SELECT 1 as id) c ORDER BY id);
+id
+1
+SELECT * FROM (SELECT 1) a WHERE 1 IN (SELECT 1,1);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT 1 IN (SELECT 1);
+1 IN (SELECT 1)
+1
+SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
+1
+1
+select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
+ERROR HY000: Incorrect usage of PROCEDURE and subquery
+SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
+ERROR HY000: Incorrect parameters to procedure 'ANALYSE'
+SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT (SELECT 1,2,3) = ROW(1,2,3);
+(SELECT 1,2,3) = ROW(1,2,3)
+1
+SELECT (SELECT 1,2,3) = ROW(1,2,1);
+(SELECT 1,2,3) = ROW(1,2,1)
+0
+SELECT (SELECT 1,2,3) < ROW(1,2,1);
+(SELECT 1,2,3) < ROW(1,2,1)
+0
+SELECT (SELECT 1,2,3) > ROW(1,2,1);
+(SELECT 1,2,3) > ROW(1,2,1)
+1
+SELECT (SELECT 1,2,3) = ROW(1,2,NULL);
+(SELECT 1,2,3) = ROW(1,2,NULL)
+NULL
+SELECT ROW(1,2,3) = (SELECT 1,2,3);
+ROW(1,2,3) = (SELECT 1,2,3)
+1
+SELECT ROW(1,2,3) = (SELECT 1,2,1);
+ROW(1,2,3) = (SELECT 1,2,1)
+0
+SELECT ROW(1,2,3) < (SELECT 1,2,1);
+ROW(1,2,3) < (SELECT 1,2,1)
+0
+SELECT ROW(1,2,3) > (SELECT 1,2,1);
+ROW(1,2,3) > (SELECT 1,2,1)
+1
+SELECT ROW(1,2,3) = (SELECT 1,2,NULL);
+ROW(1,2,3) = (SELECT 1,2,NULL)
+NULL
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'a');
+(SELECT 1.5,2,'a') = ROW(1.5,2,'a')
+1
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'b');
+(SELECT 1.5,2,'a') = ROW(1.5,2,'b')
+0
+SELECT (SELECT 1.5,2,'a') = ROW('1.5b',2,'b');
+(SELECT 1.5,2,'a') = ROW('1.5b',2,'b')
+0
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: '1.5b'
+SELECT (SELECT 'b',2,'a') = ROW(1.5,2,'a');
+(SELECT 'b',2,'a') = ROW(1.5,2,'a')
+0
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,'2','a');
+(SELECT 1.5,2,'a') = ROW(1.5,'2','a')
+1
+SELECT (SELECT 1.5,'c','a') = ROW(1.5,2,'a');
+(SELECT 1.5,'c','a') = ROW(1.5,2,'a')
+0
+SELECT (SELECT * FROM (SELECT 'test' a,'test' b) a);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT 1 as a,(SELECT a+a) b,(SELECT b);
+a b (SELECT b)
+1 2 2
+create table t1 (a int);
+create table t2 (a int, b int);
+create table t3 (a int);
+create table t4 (a int not null, b int not null);
+insert into t1 values (2);
+insert into t2 values (1,7),(2,7);
+insert into t4 values (4,8),(3,8),(5,9);
+select (select a from t1 where t1.a = a1) as a2, (select b from t2 where t2.b=a2) as a1;
+ERROR 42S22: Reference 'a1' not supported (forward reference in item list)
+select (select a from t1 where t1.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a) a
+NULL 1
+2 2
+select (select a from t1 where t1.a=t2.b), a from t2;
+(select a from t1 where t1.a=t2.b) a
+NULL 1
+NULL 2
+select (select a from t1), a, (select 1 union select 2 limit 1) from t2;
+(select a from t1) a (select 1 union select 2 limit 1)
+2 1 1
+2 2 1
+select (select a from t3), a from t2;
+(select a from t3) a
+NULL 1
+NULL 2
+select * from t2 where t2.a=(select a from t1);
+a b
+2 7
+insert into t3 values (6),(7),(3);
+select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
+a b
+1 7
+2 7
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
+a b
+1 7
+2 7
+3 8
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
+a b
+1 7
+2 7
+4 8
+3 8
+explain extended (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+3 UNION t4 ALL NULL NULL NULL NULL 3 100.00 Using where
+4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`)
+select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
+(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
+3 1
+7 2
+select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+(select t3.a from t3 where a<8 order by 1 desc limit 1) a
+7 2
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 100.00
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
+Warnings:
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`tt`.`a` AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
+set optimizer_switch=@tmp_optimizer_switch;
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
+a
+2
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a > t1.a) order by 1 desc limit 1);
+a
+2
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a < t1.a) order by 1 desc limit 1);
+a
+select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
+b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
+8 7.5000
+8 4.5000
+9 7.5000
+explain extended select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t4 ALL NULL NULL NULL NULL 3 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t4.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select `test`.`t4`.`b` AS `b`,(select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+select * from t3 where exists (select * from t2 where t2.b=t3.a);
+a
+7
+select * from t3 where not exists (select * from t2 where t2.b=t3.a);
+a
+6
+3
+select * from t3 where a in (select b from t2);
+a
+7
+select * from t3 where a not in (select b from t2);
+a
+6
+3
+select * from t3 where a = some (select b from t2);
+a
+7
+select * from t3 where a <> any (select b from t2);
+a
+6
+3
+select * from t3 where a = all (select b from t2);
+a
+7
+select * from t3 where a <> all (select b from t2);
+a
+6
+3
+insert into t2 values (100, 5);
+select * from t3 where a < any (select b from t2);
+a
+6
+3
+select * from t3 where a < all (select b from t2);
+a
+3
+select * from t3 where a >= any (select b from t2);
+a
+6
+7
+explain extended select * from t3 where a >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= all (select b from t2);
+a
+7
+delete from t2 where a=100;
+select * from t3 where a in (select a,b from t2);
+ERROR 21000: Operand should contain 1 column(s)
+select * from t3 where a in (select * from t2);
+ERROR 21000: Operand should contain 1 column(s)
+insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9),(1,10);
+select b,max(a) as ma from t4 group by b having b < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+insert into t2 values (2,10);
+select b,max(a) as ma from t4 group by b having ma < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+10 1
+delete from t2 where a=2 and b=10;
+select b,max(a) as ma from t4 group by b having b >= (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+7 12
+create table t5 (a int);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (5);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (2);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+explain extended select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT UNION t5 ALL NULL NULL NULL NULL 2 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t2.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select (select 2 from `test`.`t1` where (2 = `test`.`t2`.`a`) union select `test`.`t5`.`a` from `test`.`t5` where (`test`.`t5`.`a` = `test`.`t2`.`a`)) AS `(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a)`,`test`.`t2`.`a` AS `a` from `test`.`t2`
+select (select a from t1 where t1.a=t2.a union all select a from t5 where t5.a=t2.a), a from t2;
+ERROR 21000: Subquery returns more than 1 row
+create table t6 (patient_uq int, clinic_uq int, index i1 (clinic_uq));
+create table t7( uq int primary key, name char(25));
+insert into t7 values(1,"Oblastnaia bolnitsa"),(2,"Bolnitsa Krasnogo Kresta");
+insert into t6 values (1,1),(1,2),(2,2),(1,3);
+select * from t6 where exists (select * from t7 where uq = clinic_uq);
+patient_uq clinic_uq
+1 1
+1 2
+2 2
+explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t6 ALL NULL NULL NULL NULL 4 100.00 Using where
+2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
+Warnings:
+Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where exists(select 1 from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`))
+select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
+ERROR 23000: Column 'a' in field list is ambiguous
+drop table t1,t2,t3;
+CREATE TABLE t3 (a varchar(20),b char(1) NOT NULL default '0');
+INSERT INTO t3 VALUES ('W','a'),('A','c'),('J','b');
+CREATE TABLE t2 (a varchar(20),b int NOT NULL default '0');
+INSERT INTO t2 VALUES ('W','1'),('A','3'),('J','2');
+CREATE TABLE t1 (a varchar(20),b date NOT NULL default '0000-00-00');
+INSERT INTO t1 VALUES ('W','1732-02-22'),('A','1735-10-30'),('J','1743-04-13');
+SELECT * FROM t1 WHERE b = (SELECT MIN(b) FROM t1);
+a b
+W 1732-02-22
+SELECT * FROM t2 WHERE b = (SELECT MIN(b) FROM t2);
+a b
+W 1
+SELECT * FROM t3 WHERE b = (SELECT MIN(b) FROM t3);
+a b
+W a
+CREATE TABLE `t8` (
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+`email` varchar(60) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`),
+UNIQUE KEY `email` (`email`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t8 (pseudo,email) VALUES ('joce','test');
+INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
+INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
+EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where; Using index
+4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where
+3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
+t8 WHERE pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
+pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+pseudo
+joce
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo LIKE '%joce%');
+ERROR 21000: Subquery returns more than 1 row
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8;
+CREATE TABLE `t1` (
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (topic,date,pseudo) VALUES
+('43506','2002-10-02','joce'),('40143','2002-08-03','joce');
+EXPLAIN EXTENDED SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')
+EXPLAIN EXTENDED SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select (select distinct `test`.`t1`.`date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')) AS `(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')`
+SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+date
+2002-08-03
+SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')
+2002-08-03
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL SELECT 1;
+1
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1;
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL topic 3 NULL 2 100.00 Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where (1 = (select 1 union select 1))
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (40143,1),(43506,2);
+CREATE TABLE `t2` (
+`mot` varchar(30) NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t2 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce');
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+a
+40143
+SELECT numeropost,maxnumrep FROM t1 WHERE exists (SELECT 1 FROM t2 WHERE (mot='joce') AND date >= '2002-10-21' AND t1.numeropost = t2.topic) ORDER BY maxnumrep DESC LIMIT 0, 20;
+numeropost maxnumrep
+43506 2
+40143 1
+SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1) b;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT 1 IN (SELECT 1 FROM t2 HAVING a);
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic IN (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 1
+SELECT * from t2 where topic = all (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+SELECT * from t2 where topic <> any (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 0
+drop table t1,t2;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (1,0),(2,1);
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+show warnings;
+Level Code Message
+Error 1242 Subquery returns more than 1 row
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+(select * from t1) union (select * from t1) order by (select a from t1 limit 1);
+a
+1
+2
+3
+drop table t1;
+CREATE TABLE t1 (field char(1) NOT NULL DEFAULT 'b');
+INSERT INTO t1 VALUES ();
+SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) a HAVING field='b');
+ERROR 21000: Subquery returns more than 1 row
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL default '0',
+`numreponse` int(10) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`numeropost`,`numreponse`),
+UNIQUE KEY `numreponse` (`numreponse`),
+KEY `pseudo` (`pseudo`,`numeropost`)
+) ENGINE=MyISAM;
+SELECT (SELECT numeropost FROM t1 HAVING numreponse=a),numreponse FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Reference 'numreponse' not supported (forward reference in item list)
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=a) FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT * FROM t1) as a;
+numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
+INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY t1 ref PRIMARY PRIMARY 3 const 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select 1 from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+drop table t1;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1);
+SELECT 1 FROM (SELECT a FROM t1) b HAVING (SELECT b.a)=1;
+1
+1
+drop table t1;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 22),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+update t1 set b= (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+update t1 set b= (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+update t1 set b= (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 NULL
+1 21
+2 22
+drop table t1, t2;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+select * from t1 where b = (select b from t2 where t1.a = t2.a);
+a b
+2 12
+delete from t1 where b in (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+delete from t1 where b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete from t1 where b = (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 10
+1 11
+drop table t1, t2;
+create table t11 (a int NOT NULL, b int, primary key (a));
+create table t12 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t11 values (0, 10),(1, 11),(2, 12);
+insert into t12 values (33, 10),(22, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t11;
+a b
+0 10
+1 11
+2 12
+select * from t12;
+a b
+33 10
+22 11
+2 12
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a);
+ERROR HY000: You can't specify target table 't12' for update in FROM clause
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a);
+select * from t11;
+a b
+0 10
+1 11
+select * from t12;
+a b
+33 10
+22 11
+drop table t11, t12, t2;
+CREATE TABLE t1 (x int) ENGINE=MyISAM;
+create table t2 (a int) ENGINE=MyISAM;
+create table t3 (b int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
+ERROR 21000: Subquery returns more than 1 row
+INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
+select * from t1;
+x
+1
+insert into t2 values (1);
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
+ERROR 42S22: Unknown column 'x' in 'field list'
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+2
+drop table t1, t2, t3;
+CREATE TABLE t1 (x int not null, y int, primary key (x)) ENGINE=MyISAM;
+create table t2 (a int);
+create table t3 (a int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+select * from t1;
+x y
+replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
+ERROR 21000: Subquery returns more than 1 row
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 2
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+2 FROM t2));
+select * from t1;
+x y
+1 3
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 1
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+replace LOW_PRIORITY into t1 (x, y) VALUES ((SELECT a+1 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+2 1
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1) b WHERE 1 IN (SELECT *);
+ERROR HY000: No tables used
+CREATE TABLE t2 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (1),(2);
+SELECT * FROM t2 WHERE id IN (SELECT 1);
+id
+1
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = 1)
+SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id
+1
+SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id
+2
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 3 was reduced during optimization
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = (1 + 1))
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL id 5 NULL 2 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`id`,<exists>(select 1 having (<cache>(`test`.`t2`.`id`) = <ref_null_helper>(1)) union select 3 having (<cache>(`test`.`t2`.`id`) = <ref_null_helper>(3))))
+SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
+id
+SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
+id
+2
+INSERT INTO t2 VALUES ((SELECT * FROM t2));
+ERROR HY000: You can't specify target table 't2' for update in FROM clause
+INSERT INTO t2 VALUES ((SELECT id FROM t2));
+ERROR HY000: You can't specify target table 't2' for update in FROM clause
+SELECT * FROM t2;
+id
+1
+2
+CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 values (1),(1);
+UPDATE t2 SET id=(SELECT * FROM t1);
+ERROR 21000: Subquery returns more than 1 row
+drop table t2, t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+select 1 IN (SELECT * from t1);
+1 IN (SELECT * from t1)
+1
+select 10 IN (SELECT * from t1);
+10 IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a=2;
+select 1 IN (SELECT * from t1);
+1 IN (SELECT * from t1)
+1
+select 3 IN (SELECT * from t1);
+3 IN (SELECT * from t1)
+1
+select 10 IN (SELECT * from t1);
+10 IN (SELECT * from t1)
+NULL
+select 1 > ALL (SELECT * from t1);
+1 > ALL (SELECT * from t1)
+0
+select 10 > ALL (SELECT * from t1);
+10 > ALL (SELECT * from t1)
+NULL
+select 1 > ANY (SELECT * from t1);
+1 > ANY (SELECT * from t1)
+NULL
+select 10 > ANY (SELECT * from t1);
+10 > ANY (SELECT * from t1)
+1
+drop table t1;
+create table t1 (a varchar(20));
+insert into t1 values ('A'),('BC'),('DEF');
+select 'A' IN (SELECT * from t1);
+'A' IN (SELECT * from t1)
+1
+select 'XYZS' IN (SELECT * from t1);
+'XYZS' IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a='BC';
+select 'A' IN (SELECT * from t1);
+'A' IN (SELECT * from t1)
+1
+select 'DEF' IN (SELECT * from t1);
+'DEF' IN (SELECT * from t1)
+1
+select 'XYZS' IN (SELECT * from t1);
+'XYZS' IN (SELECT * from t1)
+NULL
+select 'A' > ALL (SELECT * from t1);
+'A' > ALL (SELECT * from t1)
+0
+select 'XYZS' > ALL (SELECT * from t1);
+'XYZS' > ALL (SELECT * from t1)
+NULL
+select 'A' > ANY (SELECT * from t1);
+'A' > ANY (SELECT * from t1)
+NULL
+select 'XYZS' > ANY (SELECT * from t1);
+'XYZS' > ANY (SELECT * from t1)
+1
+drop table t1;
+create table t1 (a float);
+insert into t1 values (1.5),(2.5),(3.5);
+select 1.5 IN (SELECT * from t1);
+1.5 IN (SELECT * from t1)
+1
+select 10.5 IN (SELECT * from t1);
+10.5 IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a=2.5;
+select 1.5 IN (SELECT * from t1);
+1.5 IN (SELECT * from t1)
+1
+select 3.5 IN (SELECT * from t1);
+3.5 IN (SELECT * from t1)
+1
+select 10.5 IN (SELECT * from t1);
+10.5 IN (SELECT * from t1)
+NULL
+select 1.5 > ALL (SELECT * from t1);
+1.5 > ALL (SELECT * from t1)
+0
+select 10.5 > ALL (SELECT * from t1);
+10.5 > ALL (SELECT * from t1)
+NULL
+select 1.5 > ANY (SELECT * from t1);
+1.5 > ANY (SELECT * from t1)
+NULL
+select 10.5 > ANY (SELECT * from t1);
+10.5 > ANY (SELECT * from t1)
+1
+explain extended select (select a+1) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (`test`.`t1`.`a` + 1) AS `(select a+1)` from `test`.`t1`
+select (select a+1) from t1;
+(select a+1)
+2.5
+NULL
+4.5
+drop table t1;
+CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a));
+CREATE TABLE t2 (a int(11) default '0', INDEX (a));
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
+a t1.a in (select t2.a from t2)
+1 1
+2 1
+3 1
+4 0
+explain extended SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on a checking NULL having <is_not_null_test>(`test`.`t2`.`a`)))) AS `t1.a in (select t2.a from t2)` from `test`.`t1`
+CREATE TABLE t3 (a int(11) default '0');
+INSERT INTO t3 VALUES (1),(2),(3);
+SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
+a t1.a in (select t2.a from t2,t3 where t3.a=t2.a)
+1 1
+2 1
+3 1
+4 0
+explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
+drop table t1,t2,t3;
+# check correct NULL Processing for normal IN/ALL/ANY
+# and 2 ways of max/min optimization
+create table t1 (a int);
+insert into t1 values (1), (100), (NULL), (1000);
+create table t2 (a int not null);
+# subselect returns empty set (for NULL and non-NULL left part)
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 1
+100 1
+NULL 1
+1000 1
+select a from t1 where a in (select * from t2);
+a
+select a from t1 where a > any (select * from t2);
+a
+select a from t1 where a > all (select * from t2);
+a
+1
+100
+NULL
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+select a from t1 where a > any (select * from t2 group by a);
+a
+select a from t1 where a > all (select * from t2 group by a);
+a
+1
+100
+NULL
+1000
+insert into t2 values (1),(200);
+# sebselect returns non-empty set without NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 0
+NULL NULL
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 1
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+1000
+drop table t2;
+create table t2 (a int);
+insert into t2 values (1),(NULL),(200);
+# sebselect returns non-empty set with NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 NULL
+NULL NULL
+1000 NULL
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 NULL
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 NULL
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+drop table t1, t2;
+create table t1 (a float);
+select 10.5 IN (SELECT * from t1 LIMIT 1);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int, b int, c varchar(10));
+create table t2 (a int);
+insert into t1 values (1,2,'a'),(2,3,'b'),(3,4,'c');
+insert into t2 values (1),(2),(NULL);
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a') (select c from t1 where a=t2.a)
+1 1 a
+2 0 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b') (select c from t1 where a=t2.a)
+1 0 a
+2 1 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where a=t2.a)
+1 0 a
+2 0 b
+NULL NULL NULL
+drop table t1,t2;
+create table t1 (a int, b real, c varchar(10));
+insert into t1 values (1, 1, 'a'), (2,2,'b'), (NULL, 2, 'b');
+select ROW(1, 1, 'a') IN (select a,b,c from t1);
+ROW(1, 1, 'a') IN (select a,b,c from t1)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1);
+ROW(1, 2, 'a') IN (select a,b,c from t1)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1);
+ROW(1, 1, 'a') IN (select b,a,c from t1)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a')
+1
+select ROW(1, 1, 'a') IN (select b,a,c from t1 limit 2);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1);
+do @a:=(SELECT a from t1);
+select @a;
+@a
+1
+set @a:=2;
+set @a:=(SELECT a from t1);
+select @a;
+@a
+1
+drop table t1;
+do (SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+set @a:=(SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (a int, KEY(a));
+HANDLER t1 OPEN;
+HANDLER t1 READ a=((SELECT 1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT 1))' at line 1
+HANDLER t1 CLOSE;
+drop table t1;
+create table t1 (a int);
+create table t2 (b int);
+insert into t1 values (1),(2);
+insert into t2 values (1);
+select a from t1 where a in (select a from t1 where a in (select b from t2));
+a
+1
+drop table t1, t2;
+create table t1 (a int, b int);
+create table t2 like t1;
+insert into t1 values (1,2),(1,3),(1,4),(1,5);
+insert into t2 values (1,2),(1,3);
+select * from t1 where row(a,b) in (select a,b from t2);
+a b
+1 2
+1 3
+drop table t1, t2;
+CREATE TABLE `t1` (`i` int(11) NOT NULL default '0',PRIMARY KEY (`i`)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+select * from t1;
+i
+2
+drop table t1;
+CREATE TABLE t1 (a int(1));
+EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
+drop table t1;
+CREATE TABLE `t1` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t2` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t3` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t2 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t3 VALUES (1,1);
+SELECT DISTINCT topic FROM t2 WHERE NOT EXISTS(SELECT * FROM t3 WHERE
+numeropost=topic);
+topic
+2
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+test 2 0000-00-00 test
+DELETE FROM t1 WHERE topic IN (SELECT DISTINCT topic FROM t2 WHERE NOT
+EXISTS(SELECT * FROM t3 WHERE numeropost=topic));
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+a (SELECT a)
+1 1
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT 1)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a+0)` int(3) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
+select * from t1;
+a
+2
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+explain extended select a,(select (select rand() from t1 limit 1) from t1 limit 1)
+from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+2 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+3 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,(select (select rand() from `test`.`t1` limit 1) from `test`.`t1` limit 1) AS `(select (select rand() from t1 limit 1) from t1 limit 1)` from `test`.`t1`
+drop table t1;
+select t1.Continent, t2.Name, t2.Population from t1 LEFT JOIN t2 ON t1.Code = t2.Country where t2.Population IN (select max(t2.Population) AS Population from t2, t1 where t2.Country = t1.Code group by Continent);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+name char(35) NOT NULL default '',
+t2 char(3) NOT NULL default '',
+District char(20) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (130,'Sydney','AUS','New South Wales',3276207);
+INSERT INTO t1 VALUES (131,'Melbourne','AUS','Victoria',2865329);
+INSERT INTO t1 VALUES (132,'Brisbane','AUS','Queensland',1291117);
+CREATE TABLE t2 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default '',
+PRIMARY KEY (Code)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU');
+INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
+select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent);
+Continent Name Population
+Oceania Sydney 3276207
+drop table t1, t2;
+CREATE TABLE `t1` (
+`id` mediumint(8) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`id`),
+UNIQUE KEY `pseudo` (`pseudo`)
+) ENGINE=MyISAM PACK_KEYS=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (pseudo) VALUES ('test');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
+INSERT INTO t1 (pseudo) VALUES ('test1');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
+drop table t1;
+CREATE TABLE `t1` (
+`i` int(11) NOT NULL default '0',
+PRIMARY KEY (`i`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i));
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t);
+ERROR 42S22: Unknown column 't.i' in 'field list'
+select * from t1;
+i
+3
+drop table t1;
+CREATE TABLE t1 (
+id int(11) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(1),(2),(2),(1),(3);
+CREATE TABLE t2 (
+id int(11) default NULL,
+name varchar(15) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (4,'vita'), (1,'vita'), (2,'vita'), (1,'vita');
+update t1, t2 set t2.name='lenka' where t2.id in (select id from t1);
+select * from t2;
+id name
+4 vita
+1 lenka
+2 lenka
+1 lenka
+drop table t1,t2;
+create table t1 (a int, unique index indexa (a));
+insert into t1 values (-1), (-4), (-2), (NULL);
+select -10 IN (select a from t1 FORCE INDEX (indexa));
+-10 IN (select a from t1 FORCE INDEX (indexa))
+NULL
+drop table t1;
+create table t1 (id int not null auto_increment primary key, salary int, key(salary));
+insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
+explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using where
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
+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:
+Warning 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 <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 <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 <in_optimizer>(`test`.`t2`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))
+drop table t1, t2, t3;
+create table t1 (a int, b int, index a (a,b));
+create table t2 (a int, index a (a));
+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 <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 <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 t3 index a a 5 NULL 3 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t1 ref a a 10 func,test.t3.a 1167 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`a`) 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 <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_swedish_ci,IMPLICIT) and (latin1_german1_ci,IMPLICIT) for operation '<'
+drop table t1;
+create table t1(toid int,rd int);
+create table t2(userid int,pmnew int,pmtotal int);
+insert into t2 values(1,0,0),(2,0,0);
+insert into t1 values(1,0),(1,0),(1,0),(1,12),(1,15),(1,123),(1,12312),(1,12312),(1,123),(2,0),(2,0),(2,1),(2,2);
+select userid,pmtotal,pmnew, (select count(rd) from t1 where toid=t2.userid) calc_total, (select count(rd) from t1 where rd=0 and toid=t2.userid) calc_new from t2 where userid in (select distinct toid from t1);
+userid pmtotal pmnew calc_total calc_new
+1 0 0 9 3
+2 0 0 4 2
+drop table t1, t2;
+create table t1 (s1 char(5));
+select (select 'a','b' from t1 union select 'a','b' from t1) from t1;
+ERROR 21000: Operand should contain 1 column(s)
+insert into t1 values ('tttt');
+select * from t1 where ('a','b')=(select 'a','b' from t1 union select 'a','b' from t1);
+s1
+tttt
+explain extended (select * from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 (select 'tttt' AS `s1` from `test`.`t1`)
+(select * from t1);
+s1
+tttt
+drop table t1;
+create table t1 (s1 char(5), index s1(s1));
+create table t2 (s1 char(5), index s1(s1));
+insert into t1 values ('a1'),('a2'),('a3');
+insert into t2 values ('a1'),('a2');
+select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
+s1 s1 = ANY (SELECT s1 FROM t2)
+a1 1
+a2 1
+a3 0
+select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
+s1 s1 <> ALL (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')
+a1 0
+a2 1
+a3 1
+explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1`
+explain extended select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1`
+explain extended select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1`
+explain extended select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < 'a2') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
+drop table t1,t2;
+create table t2 (a int, b int not null);
+create table t3 (a int);
+insert into t3 values (6),(7),(3);
+select * from t3 where a >= all (select b from t2);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= some (select b from t2);
+a
+explain extended select * from t3 where a >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= all (select b from t2 group by 1);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where a >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where NULL >= any (select b from t2);
+a
+explain extended select * from t3 where NULL >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= any (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= some (select b from t2);
+a
+explain extended select * from t3 where NULL >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+insert into t2 values (2,2), (2,1), (3,3), (3,1);
+select * from t3 where a > all (select max(b) from t2 group by a);
+a
+6
+7
+explain extended select * from t3 where a > all (select max(b) from t2 group by a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= <cache>(`test`.`t3`.`a`))))
+drop table t2, t3;
+CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
+INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
+CREATE TABLE `t2` (`db_id` int(11) NOT NULL auto_increment,`name` varchar(200) NOT NULL default '',`primary_uid` smallint(6) NOT NULL default '0',`secondary_uid` smallint(6) NOT NULL default '0',PRIMARY KEY (`db_id`),UNIQUE KEY `name_2` (`name`),FULLTEXT KEY `name` (`name`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2147483647;
+INSERT INTO `t2` (`db_id`, `name`, `primary_uid`, `secondary_uid`) VALUES (18, 'Not Set 1', 0, 0),(19, 'Valid', 1, 2),(20, 'Valid 2', 1, 2),(21, 'Should Not Return', 1, 2),(26, 'Not Set 2', 0, 0),(-1, 'ALL DB\'S', 0, 0);
+CREATE TABLE `t3` (`taskgenid` mediumint(9) NOT NULL auto_increment,`dbid` int(11) NOT NULL default '0',`taskid` int(11) NOT NULL default '0',`mon` tinyint(4) NOT NULL default '1',`tues` tinyint(4) NOT NULL default '1',`wed` tinyint(4) NOT NULL default '1',`thur` tinyint(4) NOT NULL default '1',`fri` tinyint(4) NOT NULL default '1',`sat` tinyint(4) NOT NULL default '0',`sun` tinyint(4) NOT NULL default '0',`how_often` smallint(6) NOT NULL default '1',`userid` smallint(6) NOT NULL default '0',`active` tinyint(4) NOT NULL default '1',PRIMARY KEY (`taskgenid`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2 ;
+INSERT INTO `t3` (`taskgenid`, `dbid`, `taskid`, `mon`, `tues`,`wed`, `thur`, `fri`, `sat`, `sun`, `how_often`, `userid`, `active`) VALUES (1,-1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1);
+CREATE TABLE `t4` (`task_id` smallint(6) NOT NULL default '0',`description` varchar(200) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO `t4` (`task_id`, `description`) VALUES (1, 'Daily Check List'),(2, 'Weekly Status');
+select dbid, name, (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01') from t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND t4.task_id = taskid;
+dbid name (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')
+-1 Valid 1
+-1 Valid 2 1
+-1 Should Not Return 0
+SELECT dbid, name FROM t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND ((date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')) AND t4.task_id = taskid;
+dbid name
+-1 Valid
+-1 Valid 2
+drop table t1,t2,t3,t4;
+CREATE TABLE t1 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (2),(6);
+select * from t1 where (1,2,6) in (select * from t2);
+ERROR 21000: Operand should contain 3 column(s)
+DROP TABLE t1,t2;
+create table t1 (s1 int);
+insert into t1 values (1);
+insert into t1 values (2);
+set sort_buffer_size = (select s1 from t1);
+ERROR 21000: Subquery returns more than 1 row
+do (select * from t1);
+Warnings:
+Error 1242 Subquery returns more than 1 row
+drop table t1;
+create table t1 (s1 char);
+insert into t1 values ('e');
+select * from t1 where 'f' > any (select s1 from t1);
+s1
+e
+select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+s1
+e
+explain extended select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+2 SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 UNION t1 system NULL NULL NULL NULL 1 100.00
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',(<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`) < 'f')))
+drop table t1;
+CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
+CREATE TABLE t2 (code char(5) NOT NULL default '',UNIQUE KEY code (code)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES ('1'),('1226'),('1245'),('1862'),('18623'),('1874'),('1967'),('6');
+select c.number as phone,(select p.code from t2 p where c.number like concat(p.code, '%') order by length(p.code) desc limit 1) as code from t1 c;
+phone code
+69294728265 6
+18621828126 1862
+89356874041 NULL
+95895001874 NULL
+drop table t1, t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+select * from t1 where (select count(*) from t2 where t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'where clause'
+select * from t1 where (select count(*) from t2 group by t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+select count(*) from t2 group by t1.s2;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+drop table t1, t2;
+CREATE TABLE t1(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC VARCHAR(20) DEFAULT NULL,PRIMARY KEY (COLA, COLB));
+CREATE TABLE t2(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC CHAR(1) NOT NULL,PRIMARY KEY (COLA));
+INSERT INTO t1 VALUES (1,1,'1A3240'), (1,2,'4W2365');
+INSERT INTO t2 VALUES (100, 200, 'C');
+SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1);
+COLC
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1),(1),(1),(1),(1),(2),(3),(4),(5);
+SELECT DISTINCT (SELECT a) FROM t1 LIMIT 100;
+(SELECT a)
+1
+2
+3
+4
+5
+DROP TABLE t1;
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "../../tmp/subselect.out.file.1" from t1;
+delete from t1;
+load data infile "../../tmp/subselect.out.file.1" into table t1;
+select * from t1;
+a b
+1 0.123
+drop table t1;
+CREATE TABLE `t1` (
+`id` int(11) NOT NULL auto_increment,
+`id_cns` tinyint(3) unsigned NOT NULL default '0',
+`tipo` enum('','UNO','DUE') NOT NULL default '',
+`anno_dep` smallint(4) unsigned zerofill NOT NULL default '0000',
+`particolare` mediumint(8) unsigned NOT NULL default '0',
+`generale` mediumint(8) unsigned NOT NULL default '0',
+`bis` tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`),
+UNIQUE KEY `idx_cns_gen_anno` (`anno_dep`,`id_cns`,`generale`,`particolare`),
+UNIQUE KEY `idx_cns_par_anno` (`id_cns`,`anno_dep`,`tipo`,`particolare`,`bis`)
+);
+INSERT INTO `t1` VALUES (1,16,'UNO',1987,2048,9681,0),(2,50,'UNO',1987,1536,13987,0),(3,16,'UNO',1987,2432,14594,0),(4,16,'UNO',1987,1792,13422,0),(5,16,'UNO',1987,1025,10240,0),(6,16,'UNO',1987,1026,7089,0);
+CREATE TABLE `t2` (
+`id` tinyint(3) unsigned NOT NULL auto_increment,
+`max_anno_dep` smallint(6) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`)
+);
+INSERT INTO `t2` VALUES (16,1987),(50,1990),(51,1990);
+SELECT cns.id, cns.max_anno_dep, cns.max_anno_dep = (SELECT s.anno_dep FROM t1 AS s WHERE s.id_cns = cns.id ORDER BY s.anno_dep DESC LIMIT 1) AS PIPPO FROM t2 AS cns;
+id max_anno_dep PIPPO
+16 1987 1
+50 1990 0
+51 1990 NULL
+DROP TABLE t1, t2;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SET SQL_SELECT_LIMIT=1;
+select sum(a) from (select * from t1) as a;
+sum(a)
+6
+select 2 in (select * from t1);
+2 in (select * from t1)
+1
+SET SQL_SELECT_LIMIT=default;
+drop table t1;
+CREATE TABLE t1 (a int, b int, INDEX (a));
+INSERT INTO t1 VALUES (1, 1), (1, 2), (1, 3);
+SELECT * FROM t1 WHERE a = (SELECT MAX(a) FROM t1 WHERE a = 1) ORDER BY b;
+a b
+1 1
+1 2
+1 3
+DROP TABLE t1;
+create table t1(val varchar(10));
+insert into t1 values ('aaa'), ('bbb'),('eee'),('mmm'),('ppp');
+select count(*) from t1 as w1 where w1.val in (select w2.val from t1 as w2 where w2.val like 'm%') and w1.val in (select w3.val from t1 as w3 where w3.val like 'e%');
+count(*)
+0
+drop table t1;
+create table t1 (id int not null, text varchar(20) not null default '', primary key (id));
+insert into t1 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text11'), (12, 'text12');
+select * from t1 where id not in (select id from t1 where id < 8);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+explain extended select * from t1 where id not in (select id from t1 where id < 8);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00 Using where
+2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not(<in_optimizer>(`test`.`t1`.`id`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`id`) in t1 on PRIMARY where ((`test`.`t1`.`id` < 8) and (<cache>(`test`.`t1`.`id`) = `test`.`t1`.`id`)))))))
+explain extended select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY tt ALL NULL NULL NULL NULL 12 100.00 Using where
+2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 100.00 Using where; Using index
+Warnings:
+Note 1276 Field or reference 'test.tt.id' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null))))
+insert into t1 (id, text) values (1000, 'text1000'), (1001, 'text1001');
+create table t2 (id int not null, text varchar(20) not null default '', primary key (id));
+insert into t2 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text1'), (12, 'text2'), (13, 'text3'), (14, 'text4'), (15, 'text5'), (16, 'text6'), (17, 'text7'), (18, 'text8'), (19, 'text9'), (20, 'text10'),(21, 'text1'), (22, 'text2'), (23, 'text3'), (24, 'text4'), (25, 'text5'), (26, 'text6'), (27, 'text7'), (28, 'text8'), (29, 'text9'), (30, 'text10'), (31, 'text1'), (32, 'text2'), (33, 'text3'), (34, 'text4'), (35, 'text5'), (36, 'text6'), (37, 'text7'), (38, 'text8'), (39, 'text9'), (40, 'text10'), (41, 'text1'), (42, 'text2'), (43, 'text3'), (44, 'text4'), (45, 'text5'), (46, 'text6'), (47, 'text7'), (48, 'text8'), (49, 'text9'), (50, 'text10');
+select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (if(isnull(b.id), 1000, b.id)=c.id);
+id text id text id text
+1 text1 1 text1 1 text1
+2 text2 2 text2 2 text2
+3 text3 3 text3 3 text3
+4 text4 4 text4 4 text4
+5 text5 5 text5 5 text5
+6 text6 6 text6 6 text6
+7 text7 7 text7 7 text7
+8 text8 8 text8 8 text8
+9 text9 9 text9 9 text9
+10 text10 10 text10 10 text10
+11 text11 11 text1 11 text11
+12 text12 12 text2 12 text12
+1000 text1000 NULL NULL 1000 text1000
+1001 text1001 NULL NULL 1000 text1000
+explain extended select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (if(isnull(b.id), 1000, b.id)=c.id);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE a ALL NULL NULL NULL NULL 14 100.00
+1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.id 2 100.00
+1 SIMPLE c eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using index condition
+Warnings:
+Note 1003 select `test`.`a`.`id` AS `id`,`test`.`a`.`text` AS `text`,`test`.`b`.`id` AS `id`,`test`.`b`.`text` AS `text`,`test`.`c`.`id` AS `id`,`test`.`c`.`text` AS `text` from `test`.`t1` `a` left join `test`.`t2` `b` on(((`test`.`b`.`id` = `test`.`a`.`id`) or isnull(`test`.`b`.`id`))) join `test`.`t1` `c` where (if(isnull(`test`.`b`.`id`),1000,`test`.`b`.`id`) = `test`.`c`.`id`)
+drop table t1,t2;
+create table t1 (a int);
+insert into t1 values (1);
+explain select benchmark(1000, (select a from t1 where a=sha(rand())));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 1
+drop table t1;
+create table t1(id int);
+create table t2(id int);
+create table t3(flag int);
+select (select * from t3 where id not null) from t1, t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null) from t1, t2' at line 1
+drop table t1,t2,t3;
+CREATE TABLE t1 (id INT);
+CREATE TABLE t2 (id INT);
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1);
+SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id);
+id c
+1 1
+2 0
+SELECT id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id);
+id c
+1 1
+2 0
+SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id) ORDER BY t1.id;
+id c
+1 1
+2 0
+SELECT id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id) ORDER BY id;
+id c
+1 1
+2 0
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+ALTER TABLE t1 ADD INDEX (a);
+SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE a > ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE a > ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) <> ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 2 column(s)
+SELECT a FROM t1 WHERE a = ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a,2 FROM t1 WHERE b = 2);
+a
+SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 2 column(s)
+SELECT a FROM t1 WHERE a <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
+a
+1
+2
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+3
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-')
+0-
+0-
+1-
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-')
+1-
+0-
+0-
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-')
+0-
+1-
+0-
+DROP TABLE t1;
+CREATE TABLE t1 ( a double, b double );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+3
+DROP TABLE t1;
+CREATE TABLE t1 ( a char(1), b char(1));
+INSERT INTO t1 VALUES ('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = '2');
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = '2');
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = '2');
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = '2');
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = '2');
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = '2');
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+create table t1 (a int, b int);
+insert into t1 values (1,2),(3,4);
+select * from t1 up where exists (select * from t1 where t1.a=up.a);
+a b
+1 2
+3 4
+explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where exists(select 1 from `test`.`t1` where (`test`.`t1`.`a` = `test`.`up`.`a`))
+drop table t1;
+CREATE TABLE t1 (t1_a int);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (t2_a int, t2_b int, PRIMARY KEY (t2_a, t2_b));
+INSERT INTO t2 VALUES (1, 1), (1, 2);
+SELECT * FROM t1, t2 table2 WHERE t1_a = 1 AND table2.t2_a = 1
+HAVING table2.t2_b = (SELECT MAX(t2_b) FROM t2 WHERE t2_a = table2.t2_a);
+t1_a t2_a t2_b
+1 1 2
+DROP TABLE t1, t2;
+CREATE TABLE t1 (id int(11) default NULL,name varchar(10) default NULL);
+INSERT INTO t1 VALUES (1,'Tim'),(2,'Rebecca'),(3,NULL);
+CREATE TABLE t2 (id int(11) default NULL, pet varchar(10) default NULL);
+INSERT INTO t2 VALUES (1,'Fido'),(2,'Spot'),(3,'Felix');
+SELECT a.*, b.* FROM (SELECT * FROM t1) AS a JOIN t2 as b on a.id=b.id;
+id name id pet
+1 Tim 1 Fido
+2 Rebecca 2 Spot
+3 NULL 3 Felix
+drop table t1,t2;
+CREATE TABLE t1 ( a int, b int );
+CREATE TABLE t2 ( c int, d int );
+INSERT INTO t1 VALUES (1,2), (2,3), (3,4);
+SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+abc b
+1 2
+2 3
+3 4
+INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+select * from t2;
+c d
+1 2
+2 3
+3 4
+CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+select * from t3;
+abc b
+1 2
+2 3
+3 4
+prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
+execute stmt1;
+deallocate prepare stmt1;
+select * from t2;
+c d
+1 2
+2 3
+3 4
+1 2
+2 3
+3 4
+drop table t3;
+prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
+execute stmt1;
+select * from t3;
+abc b
+1 2
+2 3
+3 4
+deallocate prepare stmt1;
+DROP TABLE t1, t2, t3;
+CREATE TABLE `t1` ( `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t1 values (1);
+CREATE TABLE `t2` ( `b` int(11) default NULL, `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t2 values (1,2);
+select t000.a, count(*) `C` FROM t1 t000 GROUP BY t000.a HAVING count(*) > ALL (SELECT count(*) FROM t2 t001 WHERE t001.a=1);
+a C
+1 1
+drop table t1,t2;
+create table t1 (a int not null auto_increment primary key, b varchar(40), fulltext(b));
+insert into t1 (b) values ('ball'),('ball games'), ('games'), ('foo'), ('foobar'), ('Serg'), ('Sergei'),('Georg'), ('Patrik'),('Hakan');
+create table t2 (a int);
+insert into t2 values (1),(3),(2),(7);
+select a,b from t1 where match(b) against ('Ball') > 0;
+a b
+1 ball
+2 ball games
+select a from t2 where a in (select a from t1 where match(b) against ('Ball') > 0);
+a
+1
+2
+drop table t1,t2;
+CREATE TABLE t1(`IZAVORGANG_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`KUERZEL` VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_bin,`IZAANALYSEART_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`IZAPMKZ_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin);
+CREATE INDEX AK01IZAVORGANG ON t1(izaAnalyseart_id,Kuerzel);
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000001','601','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000002','602','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000003','603','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000004','101','D0000000001','I0000000001');
+SELECT `IZAVORGANG_ID` FROM t1 WHERE `KUERZEL` IN(SELECT MIN(`KUERZEL`)`Feld1` FROM t1 WHERE `KUERZEL` LIKE'601%'And`IZAANALYSEART_ID`='D0000000001');
+IZAVORGANG_ID
+D0000000001
+drop table t1;
+CREATE TABLE `t1` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
+CREATE TABLE `t2` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
+insert into t1 values (1,1),(1,2),(2,1),(2,2);
+insert into t2 values (1,2),(2,2);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+alter table t2 drop primary key;
+alter table t2 add key KEY1 (aid, bid);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+alter table t2 drop key KEY1;
+alter table t2 add primary key (bid, aid);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+drop table t1,t2;
+CREATE TABLE t1 (howmanyvalues bigint, avalue int);
+INSERT INTO t1 VALUES (1, 1),(2, 1),(2, 2),(3, 1),(3, 2),(3, 3),(4, 1),(4, 2),(4, 3),(4, 4);
+SELECT howmanyvalues, count(*) from t1 group by howmanyvalues;
+howmanyvalues count(*)
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+CREATE INDEX t1_howmanyvalues_idx ON t1 (howmanyvalues);
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues+1 = a.howmanyvalues+1) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.avalue) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 1
+3 1
+4 1
+drop table t1;
+create table t1 (x int);
+select (select b.x from t1 as b where b.x=a.x) from t1 as a where a.x=2 group by a.x;
+(select b.x from t1 as b where b.x=a.x)
+drop table t1;
+CREATE TABLE `t1` ( `master` int(10) unsigned NOT NULL default '0', `map` smallint(6) unsigned NOT NULL default '0', `slave` int(10) unsigned NOT NULL default '0', `access` int(10) unsigned NOT NULL default '0', UNIQUE KEY `access_u` (`master`,`map`,`slave`));
+INSERT INTO `t1` VALUES (1,0,0,700),(1,1,1,400),(1,5,5,400),(1,12,12,400),(1,12,32,400),(4,12,32,400);
+CREATE TABLE `t2` ( `id` int(10) unsigned NOT NULL default '0', `pid` int(10) unsigned NOT NULL default '0', `map` smallint(6) unsigned NOT NULL default '0', `level` tinyint(4) unsigned NOT NULL default '0', `title` varchar(255) default NULL, PRIMARY KEY (`id`,`pid`,`map`), KEY `level` (`level`), KEY `id` (`id`,`map`)) ;
+INSERT INTO `t2` VALUES (6,5,12,7,'a'),(12,0,0,7,'a'),(12,1,0,7,'a'),(12,5,5,7,'a'),(12,5,12,7,'a');
+SELECT b.sc FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
+ERROR 42S22: Unknown column 'b.sc' in 'field list'
+SELECT b.ac FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
+ac
+700
+NULL
+drop tables t1,t2;
+create table t1 (a int not null, b int not null, c int, primary key (a,b));
+insert into t1 values (1,1,1), (2,2,2), (3,3,3);
+set @b:= 0;
+explain select sum(a) from t1 where b > @b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 8 NULL 3 Using where; Using index
+set @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+do @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+drop table t1;
+set @got_val= (SELECT 1 FROM (SELECT 'A' as my_col) as T1 ) ;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1,1),(1,2),(1,3),(2,4),(2,5);
+insert into t2 values (1,3),(2,1);
+select distinct a,b, (select max(b) from t2 where t1.b=t2.a) from t1 order by t1.b;
+a b (select max(b) from t2 where t1.b=t2.a)
+1 1 3
+1 2 1
+1 3 NULL
+2 4 NULL
+2 5 NULL
+drop table t1, t2;
+create table t1 (id int);
+create table t2 (id int, body text, fulltext (body));
+insert into t1 values(1),(2),(3);
+insert into t2 values (1,'test'), (2,'mysql'), (3,'test'), (4,'test');
+select count(distinct id) from t1 where id in (select id from t2 where match(body) against ('mysql' in boolean mode));
+count(distinct id)
+1
+drop table t2,t1;
+create table t1 (s1 int,s2 int);
+insert into t1 values (20,15);
+select * from t1 where (('a',null) <=> (select 'a',s2 from t1 where s1 = 0));
+s1 s2
+drop table t1;
+create table t1 (s1 int);
+insert into t1 values (1),(null);
+select * from t1 where s1 < all (select s1 from t1);
+s1
+select s1, s1 < all (select s1 from t1) from t1;
+s1 s1 < all (select s1 from t1)
+1 0
+NULL NULL
+drop table t1;
+CREATE TABLE t1 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default ''
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
+INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
+INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
+INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
+/*!40000 ALTER TABLE t1 ENABLE KEYS */;
+SELECT DISTINCT Continent AS c FROM t1 outr WHERE
+Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND
+Population < 200);
+c
+Oceania
+drop table t1;
+create table t1 (a1 int);
+create table t2 (b1 int);
+select * from t1 where a2 > any(select b1 from t2);
+ERROR 42S22: Unknown column 'a2' in 'IN/ALL/ANY subquery'
+select * from t1 where a1 > any(select b1 from t2);
+a1
+drop table t1,t2;
+create table t1 (a integer, b integer);
+select (select * from t1) = (select 1,2);
+(select * from t1) = (select 1,2)
+NULL
+select (select 1,2) = (select * from t1);
+(select 1,2) = (select * from t1)
+NULL
+select row(1,2) = ANY (select * from t1);
+row(1,2) = ANY (select * from t1)
+0
+select row(1,2) != ALL (select * from t1);
+row(1,2) != ALL (select * from t1)
+1
+drop table t1;
+create table t1 (a integer, b integer);
+select row(1,(2,2)) in (select * from t1 );
+ERROR 21000: Operand should contain 2 column(s)
+select row(1,(2,2)) = (select * from t1 );
+ERROR 21000: Operand should contain 2 column(s)
+select (select * from t1) = row(1,(2,2));
+ERROR 21000: Operand should contain 1 column(s)
+drop table t1;
+create table t1 (a integer);
+insert into t1 values (1);
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx ;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 as xx, 1 = ALL ( select 1 from t1 where 1 = xx );
+xx 1 = ALL ( select 1 from t1 where 1 = xx )
+1 1
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+drop table t1;
+CREATE TABLE t1 (
+categoryId int(11) NOT NULL,
+courseId int(11) NOT NULL,
+startDate datetime NOT NULL,
+endDate datetime NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL,
+attributes text NOT NULL
+);
+INSERT INTO t1 VALUES (1,41,'2004-02-09','2010-01-01','2004-02-09','2004-02-09',''),
+(1,86,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(1,87,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(2,52,'2004-03-15','2004-10-01','2004-03-15','2004-09-17',''),
+(2,53,'2004-03-16','2004-10-01','2004-03-16','2004-09-17',''),
+(2,88,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(2,89,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(3,51,'2004-02-09','2010-01-01','2004-02-09','2004-02-09',''),
+(5,12,'2004-02-18','2010-01-01','2004-02-18','2004-02-18','');
+CREATE TABLE t2 (
+userId int(11) NOT NULL,
+courseId int(11) NOT NULL,
+date datetime NOT NULL
+);
+INSERT INTO t2 VALUES (5141,71,'2003-11-18'),
+(5141,72,'2003-11-25'),(5141,41,'2004-08-06'),
+(5141,52,'2004-08-06'),(5141,53,'2004-08-06'),
+(5141,12,'2004-08-06'),(5141,86,'2004-10-21'),
+(5141,87,'2004-10-21'),(5141,88,'2004-10-21'),
+(5141,89,'2004-10-22'),(5141,51,'2004-10-26');
+CREATE TABLE t3 (
+groupId int(11) NOT NULL,
+parentId int(11) NOT NULL,
+startDate datetime NOT NULL,
+endDate datetime NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL,
+ordering int(11)
+);
+INSERT INTO t3 VALUES (12,9,'1000-01-01','3999-12-31','2004-01-29','2004-01-29',NULL);
+CREATE TABLE t4 (
+id int(11) NOT NULL,
+groupTypeId int(11) NOT NULL,
+groupKey varchar(50) NOT NULL,
+name text,
+ordering int(11),
+description text,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL
+);
+INSERT INTO t4 VALUES (9,5,'stationer','stationer',0,'Stationer','2004-01-29','2004-01-29'),
+(12,5,'group2','group2',0,'group2','2004-01-29','2004-01-29');
+CREATE TABLE t5 (
+userId int(11) NOT NULL,
+groupId int(11) NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL
+);
+INSERT INTO t5 VALUES (5141,12,'2004-08-06','2004-08-06');
+select
+count(distinct t2.userid) pass,
+groupstuff.*,
+count(t2.courseid) crse,
+t1.categoryid,
+t2.courseid,
+date_format(date, '%b%y') as colhead
+from t2
+join t1 on t2.courseid=t1.courseid
+join
+(
+select
+t5.userid,
+parentid,
+parentgroup,
+childid,
+groupname,
+grouptypeid
+from t5
+join
+(
+select t4.id as parentid,
+t4.name as parentgroup,
+t4.id as childid,
+t4.name as groupname,
+t4.grouptypeid
+from t4
+) as gin on t5.groupid=gin.childid
+) as groupstuff on t2.userid = groupstuff.userid
+group by
+groupstuff.groupname, colhead , t2.courseid;
+pass userid parentid parentgroup childid groupname grouptypeid crse categoryid courseid colhead
+1 5141 12 group2 12 group2 5 1 5 12 Aug04
+1 5141 12 group2 12 group2 5 1 1 41 Aug04
+1 5141 12 group2 12 group2 5 1 2 52 Aug04
+1 5141 12 group2 12 group2 5 1 2 53 Aug04
+1 5141 12 group2 12 group2 5 1 3 51 Oct04
+1 5141 12 group2 12 group2 5 1 1 86 Oct04
+1 5141 12 group2 12 group2 5 1 1 87 Oct04
+1 5141 12 group2 12 group2 5 1 2 88 Oct04
+1 5141 12 group2 12 group2 5 1 2 89 Oct04
+drop table t1, t2, t3, t4, t5;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SELECT 1 FROM t1 WHERE (SELECT 1) in (SELECT 1);
+1
+1
+1
+1
+drop table t1;
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(2);
+insert into t2 values (0),(1),(2),(3);
+select a from t2 where a in (select a from t1);
+a
+1
+2
+select a from t2 having a in (select a from t1);
+a
+1
+2
+prepare stmt1 from "select a from t2 where a in (select a from t1)";
+execute stmt1;
+a
+1
+2
+execute stmt1;
+a
+1
+2
+deallocate prepare stmt1;
+prepare stmt1 from "select a from t2 having a in (select a from t1)";
+execute stmt1;
+a
+1
+2
+execute stmt1;
+a
+1
+2
+deallocate prepare stmt1;
+drop table t1, t2;
+create table t1 (a int, b int);
+insert into t1 values (1,2);
+select 1 = (select * from t1);
+ERROR 21000: Operand should contain 1 column(s)
+select (select * from t1) = 1;
+ERROR 21000: Operand should contain 2 column(s)
+select (1,2) = (select a from t1);
+ERROR 21000: Operand should contain 2 column(s)
+select (select a from t1) = (1,2);
+ERROR 21000: Operand should contain 1 column(s)
+select (1,2,3) = (select * from t1);
+ERROR 21000: Operand should contain 3 column(s)
+select (select * from t1) = (1,2,3);
+ERROR 21000: Operand should contain 2 column(s)
+drop table t1;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+set @tmp11867_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin_with_cache=off';
+CREATE TABLE t1 (one int, two int, flag char(1));
+CREATE TABLE t2 (one int, two int, flag char(1));
+INSERT INTO t1 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+INSERT INTO t2 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+SELECT * FROM t1
+WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t2 WHERE flag = 'N');
+one two flag
+5 6 N
+7 8 N
+SELECT * FROM t1
+WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t1 WHERE flag = 'N');
+one two flag
+5 6 N
+7 8 N
+insert into t2 values (null,null,'N');
+insert into t2 values (null,3,'0');
+insert into t2 values (null,5,'0');
+insert into t2 values (10,null,'0');
+insert into t1 values (10,3,'0');
+insert into t1 values (10,5,'0');
+insert into t1 values (10,10,'0');
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N') as 'test' from t1;
+one two test
+1 2 NULL
+2 3 NULL
+3 4 NULL
+5 6 1
+7 8 1
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
+one two
+5 6
+7 8
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N' group by one,two) as 'test' from t1;
+one two test
+1 2 NULL
+2 3 NULL
+3 4 NULL
+5 6 1
+7 8 1
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0') as 'test' from t1;
+one two test
+1 2 0
+2 3 NULL
+3 4 0
+5 6 0
+7 8 0
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
+one two test
+1 2 0
+2 3 NULL
+3 4 0
+5 6 0
+7 8 0
+10 3 NULL
+10 5 NULL
+10 10 NULL
+explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0') as 'test' from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
+explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = 'N') and (<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) and (<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`))))
+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
+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`
+DROP TABLE t1,t2;
+set optimizer_switch=@tmp11867_optimizer_switch;
+CREATE TABLE t1 (a char(5), b char(5));
+INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
+SELECT * FROM t1 WHERE (a,b) IN (('aaa','aaa'), ('aaa','bbb'));
+a b
+aaa aaa
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int, b int);
+CREATE TABLE t3 (b int NOT NULL);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+INSERT INTO t2 VALUES (1,10), (3,30);
+SELECT * FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10;
+a b b
+SELECT * FROM t1
+WHERE t1.a NOT IN (SELECT a FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10);
+a
+1
+2
+3
+4
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (f1 INT);
+CREATE TABLE t2 (f2 INT);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2);
+f1
+1
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE 1=0);
+f1
+1
+INSERT INTO t2 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE f2=0);
+f1
+1
+DROP TABLE t1, t2;
+select 1 from dual where 1 < any (select 2);
+1
+1
+select 1 from dual where 1 < all (select 2);
+1
+1
+select 1 from dual where 2 > any (select 1);
+1
+1
+select 1 from dual where 2 > all (select 1);
+1
+1
+select 1 from dual where 1 < any (select 2 from dual);
+1
+1
+select 1 from dual where 1 < all (select 2 from dual where 1!=1);
+1
+1
+create table t1 (s1 char);
+insert into t1 values (1),(2);
+select * from t1 where (s1 < any (select s1 from t1));
+s1
+1
+select * from t1 where not (s1 < any (select s1 from t1));
+s1
+2
+select * from t1 where (s1 < ALL (select s1+1 from t1));
+s1
+1
+select * from t1 where not(s1 < ALL (select s1+1 from t1));
+s1
+2
+select * from t1 where (s1+1 = ANY (select s1 from t1));
+s1
+1
+select * from t1 where NOT(s1+1 = ANY (select s1 from t1));
+s1
+2
+select * from t1 where (s1 = ALL (select s1/s1 from t1));
+s1
+1
+select * from t1 where NOT(s1 = ALL (select s1/s1 from t1));
+s1
+2
+drop table t1;
+create table t1 (
+retailerID varchar(8) NOT NULL,
+statusID int(10) unsigned NOT NULL,
+changed datetime NOT NULL,
+UNIQUE KEY retailerID (retailerID, statusID, changed)
+);
+INSERT INTO t1 VALUES("0026", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0026", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0037", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50");
+INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50");
+select * from t1 r1
+where (r1.retailerID,(r1.changed)) in
+(SELECT r2.retailerId,(max(changed)) from t1 r2
+group by r2.retailerId);
+retailerID statusID changed
+0026 2 2006-01-06 12:25:53
+0037 2 2006-01-06 12:25:53
+0048 1 2006-01-06 12:37:50
+0059 1 2006-01-06 12:37:50
+drop table t1;
+create table t1(a int, primary key (a));
+insert into t1 values (10);
+create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b));
+insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989');
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using where
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+a a b
+10 3 35989
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+a a b
+10 1 359
+drop table t1,t2;
+CREATE TABLE t1 (
+field1 int NOT NULL,
+field2 int NOT NULL,
+field3 int NOT NULL,
+PRIMARY KEY (field1,field2,field3)
+);
+CREATE TABLE t2 (
+fieldA int NOT NULL,
+fieldB int NOT NULL,
+PRIMARY KEY (fieldA,fieldB)
+);
+INSERT INTO t1 VALUES
+(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
+INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
+SELECT field1, field2, COUNT(*)
+FROM t1 GROUP BY field1, field2;
+field1 field2 COUNT(*)
+1 1 2
+1 2 3
+1 3 1
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) >= ALL (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 2
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) < ANY (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 1
+1 3
+DROP TABLE t1, t2;
+CREATE TABLE t1(a int, INDEX (a));
+INSERT INTO t1 VALUES (1), (3), (5), (7);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES (1),(2),(3);
+EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3
+2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using index; Full scan on NULL key
+SELECT a, a IN (SELECT a FROM t1) FROM t2;
+a a IN (SELECT a FROM t1)
+1 1
+2 NULL
+3 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a DATETIME);
+INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
+CREATE TABLE t2 AS SELECT
+(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a
+FROM t1 WHERE a > '2000-01-01';
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `sub_a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01');
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) > 0;
+a
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+a
+1
+2
+EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2), (4), (1), (3);
+CREATE TABLE t2 (b int, c int);
+INSERT INTO t2 VALUES
+(2,1), (1,3), (2,1), (4,4), (2,2), (1,4);
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2 );
+a
+2
+4
+1
+3
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a;
+a
+1
+2
+3
+4
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1), a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2);
+b MAX(c)
+1 4
+2 2
+4 4
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+1
+2
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+1
+2
+3
+4
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+1
+2
+3
+4
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1,t2;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+insert into t1 values(2.2);
+select * from t1 where df <= all (select avg(df) from t1 group by df);
+df
+1.1
+select * from t1 where df >= all (select avg(df) from t1 group by df);
+df
+2.2
+drop table t1;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+select 1.1 * exists(select * from t1);
+1.1 * exists(select * from t1)
+1.1
+drop table t1;
+CREATE TABLE t1 (
+grp int(11) default NULL,
+a decimal(10,2) default NULL);
+insert into t1 values (1, 1), (2, 2), (2, 3), (3, 4), (3, 5), (3, 6), (NULL, NULL);
+select * from t1;
+grp a
+1 1.00
+2 2.00
+2 3.00
+3 4.00
+3 5.00
+3 6.00
+NULL NULL
+select min(a) from t1 group by grp;
+min(a)
+NULL
+1.00
+2.00
+4.00
+drop table t1;
+CREATE table t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2 WHERE c2 IN (1);
+c1 c2
+1 1
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE c2 IN ( SELECT c2 FROM t2 WHERE c2 IN ( 1 ) );
+c1 c2
+1 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+INSERT INTO t1 VALUES ( 6 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+INSERT INTO t2 VALUES ( 6 );
+CREATE TABLE t3 ( c3 integer );
+INSERT INTO t3 VALUES ( 7 );
+INSERT INTO t3 VALUES ( 8 );
+SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL );
+c1 c2
+2 NULL
+3 NULL
+DROP TABLE t1,t2,t3;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+CREATE TABLE t1 (EMPNUM CHAR(3));
+CREATE TABLE t2 (EMPNUM CHAR(3) );
+INSERT INTO t1 VALUES ('E1'),('E2');
+INSERT INTO t2 VALUES ('E1');
+DELETE FROM t1
+WHERE t1.EMPNUM NOT IN
+(SELECT t2.EMPNUM
+FROM t2
+WHERE t1.EMPNUM = t2.EMPNUM);
+select * from t1;
+EMPNUM
+E1
+DROP TABLE t1,t2;
+CREATE TABLE t1(select_id BIGINT, values_id BIGINT);
+INSERT INTO t1 VALUES (1, 1);
+CREATE TABLE t2 (select_id BIGINT, values_id BIGINT,
+PRIMARY KEY(select_id,values_id));
+INSERT INTO t2 VALUES (0, 1), (0, 2), (0, 3), (1, 5);
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id IN (1, 0));
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id BETWEEN 0 AND 1);
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id = 0 OR select_id = 1);
+values_id
+1
+DROP TABLE t1, t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (c int, d int);
+CREATE TABLE t3 (e int);
+INSERT INTO t1 VALUES
+(1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40);
+INSERT INTO t2 VALUES
+(2,10), (2,20), (4,10), (5,10), (3,20), (2,40);
+INSERT INTO t3 VALUES (10), (30), (10), (20) ;
+SELECT a, MAX(b), MIN(b) FROM t1 GROUP BY a;
+a MAX(b) MIN(b)
+1 20 10
+2 30 10
+3 20 20
+4 40 40
+SELECT * FROM t2;
+c d
+2 10
+2 20
+4 10
+5 10
+3 20
+2 40
+SELECT * FROM t3;
+e
+10
+30
+10
+20
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>20);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)<d);
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>d);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d >= SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d > SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e < d));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE MIN(b) < d AND
+EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+SELECT a, SUM(a) FROM t1 GROUP BY a;
+a SUM(a)
+1 2
+2 6
+3 3
+4 4
+SELECT a FROM t1
+WHERE EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c) GROUP BY a;
+a
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c);
+a
+1
+3
+4
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c) GROUP BY a;
+a
+1
+2
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c);
+a
+1
+2
+1
+2
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a < ALL(SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+1
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3
+WHERE SUM(t1.a+t2.c) < t3.e/4));
+ERROR HY000: Invalid use of group function
+SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20;
+ERROR HY000: Invalid use of group function
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(t2.c+SUM(t1.b)) > 20);
+a
+2
+3
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(SUM(t1.b)) > 20);
+a
+2
+4
+SELECT t1.a, SUM(b) AS sum FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING t2.c+sum > 20);
+a sum
+2 60
+3 20
+4 40
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a varchar(5), b varchar(10));
+INSERT INTO t1 VALUES
+('AAA', 5), ('BBB', 4), ('BBB', 1), ('CCC', 2),
+('CCC', 7), ('AAA', 2), ('AAA', 4), ('BBB', 3), ('AAA', 8);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary
+ALTER TABLE t1 ADD INDEX(a);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 DEPENDENT SUBQUERY t1 index NULL a 8 NULL 1
+DROP TABLE t1;
+create table t1( f1 int,f2 int);
+insert into t1 values (1,1),(2,2);
+select tt.t from (select 'crash1' as t, f2 from t1) as tt left join t1 on tt.t = 'crash2' and tt.f2 = t1.f2 where tt.t = 'crash1';
+t
+crash1
+crash1
+drop table t1;
+create table t1 (c int, key(c));
+insert into t1 values (1142477582), (1142455969);
+create table t2 (a int, b int);
+insert into t2 values (2, 1), (1, 0);
+delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
+drop table t1, t2;
+CREATE TABLE t1 (a INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'IN/ALL/ANY subquery'
+DROP TABLE t1;
+create table t1 (i int, j bigint);
+insert into t1 values (1, 2), (2, 2), (3, 2);
+select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
+min(i)
+1
+drop table t1;
+CREATE TABLE t1 (i BIGINT UNSIGNED);
+INSERT INTO t1 VALUES (10000000000000000000);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (i BIGINT UNSIGNED);
+INSERT INTO t2 VALUES (10000000000000000000);
+INSERT INTO t2 VALUES (1);
+/* simple test */
+SELECT t1.i FROM t1 JOIN t2 ON t1.i = t2.i;
+i
+10000000000000000000
+1
+/* subquery test */
+SELECT t1.i FROM t1 WHERE t1.i = (SELECT MAX(i) FROM t2);
+i
+10000000000000000000
+/* subquery test with cast*/
+SELECT t1.i FROM t1 WHERE t1.i = CAST((SELECT MAX(i) FROM t2) AS UNSIGNED);
+i
+10000000000000000000
+DROP TABLE t1;
+DROP TABLE t2;
+CREATE TABLE t1 (
+id bigint(20) unsigned NOT NULL auto_increment,
+name varchar(255) NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES
+(1, 'Balazs'), (2, 'Joe'), (3, 'Frank');
+CREATE TABLE t2 (
+id bigint(20) unsigned NOT NULL auto_increment,
+mid bigint(20) unsigned NOT NULL,
+date date NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t2 VALUES
+(1, 1, '2006-03-30'), (2, 2, '2006-04-06'), (3, 3, '2006-04-13'),
+(4, 2, '2006-04-20'), (5, 1, '2006-05-01');
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 3, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 NULL
+2 Joe 2006-04-20 NULL
+3 Frank 2006-04-13 NULL
+SELECT *,
+(SELECT COUNT(*) FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_count
+FROM t1;
+id name date_count
+1 Balazs NULL
+2 Joe NULL
+3 Frank NULL
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 2006-03-30
+2 Joe 2006-04-20 2006-04-06
+3 Frank 2006-04-13 NULL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime NOT NULL default '0000-00-00 00:00:00',
+PRIMARY KEY (i1,i2,t)
+);
+INSERT INTO t1 VALUES
+(24,1,'2005-03-03 16:31:31'),(24,1,'2005-05-27 12:40:07'),
+(24,1,'2005-05-27 12:40:08'),(24,1,'2005-05-27 12:40:10'),
+(24,1,'2005-05-27 12:40:25'),(24,1,'2005-05-27 12:40:30'),
+(24,2,'2005-03-03 13:43:05'),(24,2,'2005-03-03 16:23:31'),
+(24,2,'2005-03-03 16:31:30'),(24,2,'2005-05-27 12:37:02'),
+(24,2,'2005-05-27 12:40:06');
+CREATE TABLE t2 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime default NULL,
+PRIMARY KEY (i1)
+);
+INSERT INTO t2 VALUES (24,1,'2006-06-20 12:29:40');
+EXPLAIN
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index
+2 DEPENDENT SUBQUERY t1 range PRIMARY PRIMARY 16 NULL 5 Using where; Using index
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+i1 i2 t i1 i2 t
+24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b));
+insert into t1 (a) values (FLOOR(rand() * 100));
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+SELECT a,
+(SELECT REPEAT(' ',250) FROM t1 i1
+WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a
+FROM t1 ORDER BY a LIMIT 5;
+a a
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 values (1);
+INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4);
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2)
+2
+1
+1
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+2
+1
+1
+SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b))
+2 2
+1 1
+1 1
+SELECT COUNT(DISTINCT t1.b),
+(SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+2 2
+1 1
+1 1
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a;
+(
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+2
+1
+1
+SELECT (
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+FROM t1 t2
+GROUP BY t2.a;
+(
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+2
+2
+2
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (b));
+CREATE TABLE t2 (x int auto_increment, y int, z int,
+PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1 select RAND()*1000, A.a + 10*(B.a+10*(C.a+10*D.a))
+from t3 A, t3 B, t3 C, t3 D where D.a<3;
+insert into t2(y,z) select t1.b, RAND()*1000 from t1, t3;
+SET SESSION sort_buffer_size = 32 * 1024;
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+SET SESSION sort_buffer_size = 8 * 1024 * 1024;
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
+CREATE TABLE t2 (c int);
+INSERT INTO t1 VALUES ('aa', 1);
+INSERT INTO t2 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+INSERT INTO t1 VALUES ('bb', 2), ('cc', 3), ('dd',1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+INSERT INTO t2 VALUES (2);
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT t2.c FROM t2 JOIN t3 ON t2.c=t3.c WHERE t2.c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1(f1 int);
+CREATE TABLE t2(f2 int, f21 int, f3 timestamp);
+INSERT INTO t1 VALUES (1),(1),(2),(2);
+INSERT INTO t2 VALUES (1,1,"2004-02-29 11:11:11"), (2,2,"2004-02-29 11:11:11");
+SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1;
+sq
+2
+4
+SELECT (SELECT SUM(1) FROM t2 ttt GROUP BY t2.f3 LIMIT 1) AS tt FROM t2;
+tt
+2
+2
+PREPARE stmt1 FROM 'SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1';
+EXECUTE stmt1;
+sq
+2
+4
+EXECUTE stmt1;
+sq
+2
+4
+DEALLOCATE PREPARE stmt1;
+SELECT f2, AVG(f21),
+(SELECT t.f3 FROM t2 AS t WHERE t2.f2=t.f2 AND t.f3=MAX(t2.f3)) AS test
+FROM t2 GROUP BY f2;
+f2 AVG(f21) test
+1 1.0000 2004-02-29 11:11:11
+2 2.0000 2004-02-29 11:11:11
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL);
+INSERT INTO t1 VALUES
+(1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
+(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'),
+(3,2,'k'), (3,1,'l'), (1,9,'m');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t1xt2;
+CREATE TABLE t1 (
+id_1 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t2 (
+id_2 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t1xt2 (
+id_1 int(5) NOT NULL,
+id_2 int(5) NOT NULL
+);
+INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
+INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
+INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+3
+4
+insert INTO t1xt2 VALUES (1, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+2
+3
+4
+insert INTO t1xt2 VALUES (2, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+3
+4
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t1xt2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (3), (1), (2);
+SELECT 'this is ' 'a test.' AS col1, a AS col2 FROM t1;
+col1 col2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+SELECT * FROM (SELECT 'this is ' 'a test.' AS col1, a AS t2 FROM t1) t;
+col1 t2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+DROP table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*), a,
+(SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a,
+(SELECT MIN(m) FROM t2 WHERE m = count(*))
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT MIN(m) FROM t2 WHERE m = count(*))
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a
+FROM t1 GROUP BY a
+HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1;
+COUNT(*) a
+2 2
+3 3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+2 2 2
+3 3 3
+1 4 1,1
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+2 2 3
+3 3 4
+1 4 2,2
+DROP table t1,t2;
+CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
+INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'),
+(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'),
+(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a x, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+x MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a, AVG(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test
+FROM t1 WHERE t1.d=0 GROUP BY a;
+a AVG(b) test
+1 4.0000 d
+2 2.0000 g
+3 2.5000 NULL
+SELECT tt.a,
+(SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt;
+a test
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+2 o
+2 o
+2 o
+2 o
+3 p
+3 p
+3 p
+3 p
+3 p
+SELECT tt.a,
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+SELECT tt.a, MAX(
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+a
+1
+2
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+a
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+a
+1
+2
+SET @@sql_mode='ansi';
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+ERROR HY000: Invalid use of group function
+SET @@sql_mode=default;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 values (1),(1),(1),(1);
+CREATE TABLE t2 (x INT);
+INSERT INTO t1 values (1000),(1001),(1002);
+SELECT SUM( (SELECT COUNT(a) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT SUM( (SELECT SUM(COUNT(a)) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT COUNT(1) FROM DUAL;
+COUNT(1)
+1
+SELECT SUM( (SELECT AVG( (SELECT t1.a FROM t2) ) FROM DUAL) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING t1.a < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT t1.a as XXA,
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, KEY (a));
+INSERT INTO t1 VALUES (1,1),(2,1);
+EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref a a 5 const 0 Using where; Using index
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+DROP TABLE t1;
+CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
+INSERT INTO t1 VALUES
+(3,'FL'), (2,'GA'), (4,'FL'), (1,'GA'), (5,'NY'), (7,'FL'), (6,'NY');
+CREATE TABLE t2 (id int NOT NULL, INDEX idx(id));
+INSERT INTO t2 VALUES (7), (5), (1), (3);
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+3 FL
+1 GA
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+1 GA
+3 FL
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+2 GA
+4 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+2 GA
+4 FL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT count(*) FROM t1 GROUP BY a) as res;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `res`.`count(*)` AS `count(*)` from (select count(0) AS `count(*)` from `test`.`t1` group by `test`.`t1`.`a`) `res`
+DROP TABLE t1;
+CREATE TABLE t1 (
+a varchar(255) default NULL,
+b timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+INDEX idx(a,b)
+);
+CREATE TABLE t2 (
+a varchar(255) default NULL
+);
+INSERT INTO t1 VALUES ('abcdefghijk','2007-05-07 06:00:24');
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26');
+INSERT INTO `t2` VALUES ('abcdefghijk');
+INSERT INTO `t2` VALUES ('asdf');
+SET session sort_buffer_size=8192;
+SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
+d1
+1
+1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INTEGER, b INTEGER);
+CREATE TABLE t2 (x INTEGER);
+INSERT INTO t1 VALUES (1,11), (2,22), (2,22);
+INSERT INTO t2 VALUES (1), (2);
+SELECT a, COUNT(b), (SELECT COUNT(b) FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a, COUNT(b), (SELECT COUNT(b)+0 FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a)/AVG(t2.x) FROM t2) FROM t1;
+(SELECT SUM(t1.a)/AVG(t2.x) FROM t2)
+3.3333
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1, 2), (1,3), (1,4), (2,1), (2,2);
+SELECT a1.a, COUNT(*) FROM t1 a1 WHERE a1.a = 1
+AND EXISTS( SELECT a2.a FROM t1 a2 WHERE a2.a = a1.a)
+GROUP BY a1.a;
+a COUNT(*)
+1 3
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+INSERT INTO t2 VALUES (1),(2);
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=0) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=0)
+NULL
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a!=0) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=1) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=1)
+3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a1 INT, a2 INT);
+CREATE TABLE t2 (b1 INT, b2 INT);
+INSERT INTO t1 VALUES (100, 200);
+INSERT INTO t1 VALUES (101, 201);
+INSERT INTO t2 VALUES (101, 201);
+INSERT INTO t2 VALUES (103, 203);
+SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1;
+((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL
+0
+0
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5));
+INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+CREATE INDEX I1 ON t1 (s1);
+CREATE INDEX I2 ON t1 (s2);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+TRUNCATE t1;
+INSERT INTO t1 VALUES (0x41,0x41);
+SELECT * FROM t1 WHERE s1 = (SELECT s2 FROM t1);
+s1 s2
+DROP TABLE t1;
+CREATE TABLE t1 (a1 VARBINARY(2) NOT NULL DEFAULT '0', PRIMARY KEY (a1));
+CREATE TABLE t2 (a2 BINARY(2) default '0', INDEX (a2));
+CREATE TABLE t3 (a3 BINARY(2) default '0');
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+INSERT INTO t3 VALUES (1),(2),(3);
+SELECT LEFT(t2.a2, 1) FROM t2,t3 WHERE t3.a3=t2.a2;
+LEFT(t2.a2, 1)
+1
+2
+3
+SELECT t1.a1, t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2) FROM t1;
+a1 t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2)
+1 0
+2 0
+3 0
+4 0
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a1 BINARY(3) PRIMARY KEY, b1 VARBINARY(3));
+CREATE TABLE t2 (a2 VARBINARY(3) PRIMARY KEY);
+CREATE TABLE t3 (a3 VARBINARY(3) PRIMARY KEY);
+INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40);
+INSERT INTO t2 VALUES (2), (3), (4), (5);
+INSERT INTO t3 VALUES (10), (20), (30);
+SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3;
+LEFT(t1.a1,1)
+1
+2
+3
+SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
+a2
+DROP TABLE t1, t2, t3;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+SET optimizer_switch='materialization=off';
+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;
+SET optimizer_switch= @save_optimizer_switch;
+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);
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) 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 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,<exists>(select min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a` having (1 = <ref_null_helper>(min(`test`.`t1`.`a`)))))
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 WHERE a > 3 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,<exists>(select min(`test`.`t1`.`a`) from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` having (1 = <ref_null_helper>(min(`test`.`t1`.`a`)))))
+SET join_cache_level=@save_join_cache_level;
+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 NULL
+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;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+EXPLAIN EXTENDED
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+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 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <nop>(<in_optimizer>(1,((select max(`test`.`t1`.`a1`) from `test`.`t1`) > 1)))
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+1
+1
+1
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1, t2;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
+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
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
+INSERT INTO t1 VALUES (1,NULL), (9,NULL);
+CREATE TABLE t2 (
+a INT,
+b INT,
+c INT,
+d INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c,d),
+KEY b_2 (b),
+KEY c (c),
+KEY d (d)
+);
+INSERT INTO t2 VALUES
+(43, 2, 11 ,30),
+(44, 2, 12 ,30),
+(45, 1, 1 ,10000),
+(46, 1, 2 ,10000),
+(556,1, 32 ,10000);
+CREATE TABLE t3 (
+a INT,
+b INT,
+c INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c),
+KEY c (c),
+KEY b_2 (b)
+);
+INSERT INTO t3 VALUES (1,1,1), (2,32,1);
+explain
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 PRIMARY t3 ref b,b_2 b 5 test.t1.a 1 Using index
+2 DEPENDENT SUBQUERY t2 ref b,b_2,c b 10 test.t3.c,test.t1.a 1 Using where; Using index; Using filesort
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+a incorrect
+1 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int, c int);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+CREATE VIEW v1 AS
+SELECT t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+UPDATE v1 SET c=1;
+CREATE VIEW v2 (a,b) AS
+SELECT t2.id, t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+INSERT INTO v2(a,b) VALUES (2,2);
+ERROR HY000: CHECK OPTION failed 'test.v2'
+SELECT * FROM v1;
+c
+1
+1
+1
+1
+CREATE VIEW v3 AS
+SELECT t2.c AS c FROM t2
+WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+DELETE FROM v3;
+DROP VIEW v1,v2,v3;
+DROP TABLE t1,t2;
+#
+# BUG#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+#
+# Bug#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+CREATE TABLE t1 (a ENUM('rainbow'));
+INSERT INTO t1 VALUES (),(),(),(),();
+SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
+1
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGBLOB);
+INSERT INTO t1 SET a = 'aaaa';
+INSERT INTO t1 SET a = 'aaaa';
+SELECT 1 FROM t1 GROUP BY
+(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
+1
+1
+DROP TABLE t1;
+#
+# Bug #49512 : subquery with aggregate function crash
+# subselect_single_select_engine::exec()
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES();
+# should not crash
+SELECT 1 FROM t1 WHERE a <> SOME
+(
+SELECT MAX((SELECT a FROM t1 LIMIT 1)) AS d
+FROM t1,t1 a
+);
+1
+DROP TABLE t1;
+#
+# Bug #45989 take 2 : memory leak after explain encounters an
+# error in the query
+#
+CREATE TABLE t1(a LONGTEXT);
+INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet));
+INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet));
+EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1,
+(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) AS d1
+WHERE t1.a = d1.a;
+ERROR 42S22: Unknown column 'd1.a' in 'where clause'
+DROP TABLE t1;
+Set up test tables.
+CREATE TABLE t1 (
+t1_id INT UNSIGNED,
+PRIMARY KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t1 (t1_id) VALUES (1), (2), (3), (4), (5);
+CREATE TABLE t2 SELECT * FROM t1;
+CREATE TABLE t3 (
+t3_id INT UNSIGNED AUTO_INCREMENT,
+t1_id INT UNSIGNED,
+amount DECIMAL(16,2),
+PRIMARY KEY(t3_id),
+KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t3 (t1_id, t3_id, amount)
+VALUES (1, 1, 100.00), (2, 2, 200.00), (4, 4, 400.00);
+This is the 'inner query' running by itself.
+Produces correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query)
+Produces correct results.
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+Now make t2.t1_id part of a key.
+ALTER TABLE t2 ADD PRIMARY KEY(t1_id);
+Same inner query by itself.
+Still correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query), now with indexes on the LEFT JOIN
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+DROP TABLE t3;
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# Bug #52711: Segfault when doing EXPLAIN SELECT with
+# union...order by (select... where...)
+#
+CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a));
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (1),(2);
+# Should not crash
+EXPLAIN
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+# Should not crash
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+DROP TABLE t1,t2;
+# LP BUG#675248 - select->prep_where references on freed memory
+CREATE TABLE t1 (a int, b int);
+insert into t1 values (1,1),(0,0);
+CREATE TABLE t2 (c int);
+insert into t2 values (1),(2);
+prepare stmt1 from "select sum(a),(select sum(c) from t2 where table1.b) as sub
+from t1 as table1 group by sub";
+execute stmt1;
+sum(a) sub
+0 NULL
+1 3
+deallocate prepare stmt1;
+prepare stmt1 from "select sum(a),(select sum(c) from t2 having table1.b) as sub
+from t1 as table1";
+execute stmt1;
+sum(a) sub
+1 3
+deallocate prepare stmt1;
+drop table t1,t2;
+#
+# Bug LP#693935/#58727: Assertion failure with
+# a single row subquery returning more than one row
+#
+create table t1 (a char(1) charset utf8);
+insert into t1 values ('a'), ('b');
+create table t2 (a binary(1));
+insert into t2 values ('x'), ('y');
+select * from t2 where a=(select a from t1) and a='x';
+ERROR 21000: Subquery returns more than 1 row
+drop table t1,t2;
+End of 5.1 tests
+#
+# No BUG#, a case brought from 5.2's innodb_mysql_lock.test
+#
+create table t1 (i int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+create table t2 (j int not null primary key);
+insert into t2 values (1),(2),(3),(4),(5);
+create table t3 (k int not null primary key);
+insert into t3 values (1),(2),(3);
+create view v2 as select t2.j as j from t2 where t2.j in (select t1.i from t1);
+select * from t3 where k in (select j from v2);
+k
+1
+2
+3
+drop table t1,t2,t3;
+drop view v2;
+#
+# Bug#52068: Optimizer generates invalid semijoin materialization plan
+#
+drop table if exists ot1, ot2, it1, it2;
+CREATE TABLE ot1(a INTEGER);
+INSERT INTO ot1 VALUES(5), (8);
+CREATE TABLE it2(a INTEGER);
+INSERT INTO it2 VALUES(9), (5), (1), (8);
+CREATE TABLE it3(a INTEGER);
+INSERT INTO it3 VALUES(7), (1), (0), (5), (1), (4);
+CREATE TABLE ot4(a INTEGER);
+INSERT INTO ot4 VALUES(1), (3), (5), (7), (9), (7), (3), (1);
+SELECT * FROM ot1,ot4
+WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
+FROM it2,it3);
+a a
+5 1
+8 1
+5 5
+8 5
+5 7
+8 7
+5 7
+8 7
+5 1
+8 1
+explain SELECT * FROM ot1,ot4
+WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
+FROM it2,it3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 2
+1 PRIMARY ot4 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY it2 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY it3 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+DROP TABLE IF EXISTS ot1, ot4, it2, it3;
+#
+# Bug#729039: NULL keys used to evaluate subquery
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (NULL), (1), (NULL), (2);
+CREATE TABLE t2 (a int, INDEX idx(a)) ;
+INSERT INTO t2 VALUES (NULL), (1), (NULL);
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a);
+a
+1
+EXPLAIN
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+a
+1
+EXPLAIN
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
+DROP TABLE t1,t2;
+#
+# BUG#752992: Wrong results for a subquery with 'semijoin=on'
+#
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
+EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index
+2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using index
+SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+pk i
+11 0
+12 5
+15 0
+SET join_cache_level=@save_join_cache_level;
+DROP table t1,t2;
+#
+# Bug#751350: crash with pushed condition for outer references when
+# there should be none of such conditions
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0),(0,0);
+set @optimizer_switch_save=@@optimizer_switch;
+set @@optimizer_switch='semijoin=off,materialization=on,in_to_exists=on';
+EXPLAIN
+SELECT b FROM t1
+WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT b FROM t1
+WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+GROUP BY b;
+b
+0
+set @@optimizer_switch=@optimizer_switch_save;
+DROP TABLE t1;
+#
+# Bug #11765713 58705:
+# OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES
+# CREATED BY OPT_SUM_QUERY
+#
+CREATE TABLE t1(a INT NOT NULL, KEY (a));
+INSERT INTO t1 VALUES (0), (1);
+SELECT 1 as foo FROM t1 WHERE a < SOME
+(SELECT a FROM t1 WHERE a <=>
+(SELECT a FROM t1)
+);
+ERROR 21000: Subquery returns more than 1 row
+SELECT 1 as foo FROM t1 WHERE a < SOME
+(SELECT a FROM t1 WHERE a <=>
+(SELECT a FROM t1 where a is null)
+);
+foo
+DROP TABLE t1;
+CREATE TABLE t1 (a int(11), b varchar(1));
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+delete from t1;
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+drop table t1;
+#
+# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3)) ;
+INSERT IGNORE INTO t2 VALUES (NULL,NULL),(5,0);
+DROP TABLE IF EXISTS t3;
+Warnings:
+Note 1051 Unknown table 't3'
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ;
+r
+NULL
+5
+NULL
+5
+DROP TABLE t1, t2, t3;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+1
+1
+1
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1, t2;
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
+#
+# BUG#50257: Missing info in REF column of the EXPLAIN
+# lines for subselects
+#
+CREATE TABLE t1 (a INT, b INT, INDEX (a));
+INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref a a 5 const 1
+EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 SUBQUERY t1 ref a a 5 const 1 Using index
+DROP TABLE t1;
+#
+# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS)
+# (duplicate of LP bug #888456)
+#
+CREATE TABLE t1 (f1 varchar(1));
+INSERT INTO t1 VALUES ('v'),('s');
+CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key));
+INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'),
+('d'),('y'),('t'),('d'),('s');
+EXPLAIN
+SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2
+WHERE EXISTS (SELECT DISTINCT f1_key FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY table1 ALL NULL NULL NULL NULL 2
+1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index
+SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2
+WHERE EXISTS (SELECT DISTINCT f1_key FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1);
+f1 f1_key
+v j
+s j
+v v
+s v
+v c
+s c
+v m
+s m
+v d
+s d
+v d
+s d
+v y
+s y
+v t
+s t
+v d
+s d
+v s
+s s
+DROP TABLE t1,t2;
+#
+# LP bug 919427: EXPLAIN for a query over a single-row table
+# with IN subquery in WHERE condition
+#
+CREATE TABLE ot (
+col_int_nokey int(11),
+col_varchar_nokey varchar(1)
+) ;
+INSERT INTO ot VALUES (1,'x');
+CREATE TABLE it1(
+col_int_key int(11),
+col_varchar_key varchar(1),
+KEY idx_cvk_cik (col_varchar_key,col_int_key)
+);
+INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f');
+CREATE TABLE it2 (
+col_int_key int(11),
+col_varchar_key varchar(1),
+col_varchar_key2 varchar(1),
+KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key),
+KEY idx_cvk_cik (col_varchar_key, col_int_key)
+);
+INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f');
+EXPLAIN
+SELECT col_int_nokey FROM ot
+WHERE col_varchar_nokey IN
+(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY it1 index_subquery idx_cvk_cik idx_cvk_cik 9 func,const 2 Using index; Using where
+SELECT col_int_nokey FROM ot
+WHERE col_varchar_nokey IN
+(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL);
+col_int_nokey
+1
+EXPLAIN
+SELECT col_int_nokey FROM ot
+WHERE (col_varchar_nokey, 'x') IN
+(SELECT col_varchar_key, col_varchar_key2 FROM it2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY it2 index_subquery idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 func,const 1 Using index; Using where
+SELECT col_int_nokey FROM ot
+WHERE (col_varchar_nokey, 'x') IN
+(SELECT col_varchar_key, col_varchar_key2 FROM it2);
+col_int_nokey
+1
+DROP TABLE ot,it1,it2;
+#
+# MDEV-746
+# Bug#13651009 WRONG RESULT FROM DERIVED TABLE IF THE SUBQUERY
+# HAS AN EMPTY RESULT
+#
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_int_nokey int NOT NULL,
+col_int_key int NOT NULL,
+col_time_key time 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_time_key (col_time_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM;
+CREATE TABLE t2 (
+pk int NOT NULL AUTO_INCREMENT,
+col_int_nokey int NOT NULL,
+col_int_key int NOT NULL,
+col_time_key time 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_time_key (col_time_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,4,4,'00:00:00','b','b');
+SET @var2:=4, @var3:=8;
+
+Testcase without inner subquery
+EXPLAIN SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3;
+@var3:=12 pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+SELECT @var3;
+@var3
+8
+EXPLAIN SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3 ) AS alias3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE <derived2> system NULL NULL NULL NULL 0 const row not found
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3 ) AS alias3;
+@var3:=12 pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+SELECT @var3;
+@var3
+8
+
+Testcase with inner subquery; crashed WL#6095
+SET @var3=8;
+EXPLAIN SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3));
+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 c_sq1_alias1 system PRIMARY NULL NULL NULL 1
+SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3));
+pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+EXPLAIN SELECT * FROM ( SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3)) ) AS alias3;
+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
+3 DEPENDENT SUBQUERY c_sq1_alias1 system PRIMARY NULL NULL NULL 1
+SELECT * FROM ( SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3)) ) AS alias3;
+pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+DROP TABLE t1,t2;
+End of 5.2 tests
+#
+# BUG#779885: Crash in eliminate_item_equal with materialization=on in
+#
+CREATE TABLE t1 ( f1 int );
+INSERT INTO t1 VALUES (19), (20);
+CREATE TABLE t2 ( f10 varchar(32) );
+INSERT INTO t2 VALUES ('c'),('d');
+CREATE TABLE t3 ( f10 varchar(32) );
+INSERT INTO t3 VALUES ('a'),('b');
+SELECT *
+FROM t1
+WHERE
+( 't' ) IN (
+SELECT t3.f10
+FROM t3
+JOIN t2
+ON t2.f10 = t3.f10
+);
+f1
+DROP TABLE t1,t2,t3;
+#
+# BUG LP:813473: Wrong result with outer join + NOT IN subquery
+# This bug is a duplicate of Bug#11764086 whose test case is added below
+#
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (5),(6);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (20,9),(20,9);
+create table t3 (d int, e int);
+insert into t3 values (2, 9), (3,10);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+EXPLAIN
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b , t1.c) NOT IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b, t1.c) NOT IN (SELECT * from t3);
+b c
+9 NULL
+9 NULL
+SET optimizer_switch=@save_optimizer_switch;
+drop table t1, t2, t3;
+#
+# Bug#11764086: Null left operand to NOT IN in WHERE clause
+# behaves differently than real NULL
+#
+CREATE TABLE parent (id int);
+INSERT INTO parent VALUES (1), (2);
+CREATE TABLE child (parent_id int, other int);
+INSERT INTO child VALUES (1,NULL);
+# Offending query (c.parent_id is NULL for null-complemented rows only)
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id NOT IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+);
+id parent_id
+1 1
+2 NULL
+# Some syntactic variations with IS FALSE and IS NOT TRUE
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS NOT TRUE;
+id parent_id
+1 1
+2 NULL
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS FALSE;
+id parent_id
+1 1
+2 NULL
+DROP TABLE parent, child;
+# End of test for bug#11764086.
+#
+# Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET ||
+# BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0), (1);
+CREATE TABLE t2(
+b TEXT,
+c INT,
+PRIMARY KEY (b(1))
+);
+INSERT INTO t2 VALUES ('a', 2), ('b', 3);
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ORDER BY b
+);
+1
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+GROUP BY b
+);
+1
+DROP TABLE t1, t2;
+#
+# LP bug #826279: assertion failure with GROUP BY a result of subquery
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0), (0);
+CREATE TABLE t2 (a int, b int, c int);
+INSERT INTO t2 VALUES (10,7,0), (0,7,0);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,7), (0,7);
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+7 NULL
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+7 NULL
+7 10
+DROP TABLE t1,t2,t3;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+#
+# LP BUG#833777 Performance regression with deeply nested subqueries
+#
+create table t1 (a int not null, b char(10) not null);
+insert into t1 values (1, 'a');
+set @@optimizer_switch='in_to_exists=on,semijoin=off,materialization=off,subquery_cache=off';
+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)))))))))))))))))))))))))))));
+a
+1
+set @@optimizer_switch=@subselect_tmp;
+drop table t1;
+#
+# LP BUG#894397 Wrong result with in_to_exists, constant table , semijoin=OFF,materialization=OFF
+#
+CREATE TABLE t1 (a varchar(3));
+INSERT INTO t1 VALUES ('AAA'),('BBB');
+CREATE TABLE t2 (a varchar(3));
+INSERT INTO t2 VALUES ('CCC');
+set @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquery_cache=off';
+SELECT * FROM t1 WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.a < 'ZZZ');
+a
+set @@optimizer_switch=@subselect_tmp;
+drop table t1, t2;
+#
+# LP bug #859375: Assertion `0' failed in st_select_lex_unit::optimize
+# with view , UNION and prepared statement (rewriting fake_select
+# condition).
+#
+CREATE TABLE t1 ( f1 int NOT NULL, f4 varchar(1) NOT NULL) ;
+INSERT INTO t1 VALUES (6,'d'),(7,'y');
+CREATE TABLE t2 ( f1 int NOT NULL, f2 int NOT NULL) ;
+INSERT INTO t2 VALUES (10,7);
+CREATE VIEW v2 AS SELECT * FROM t2;
+PREPARE st1 FROM "
+ SELECT *
+ FROM t1
+ LEFT JOIN v2 ON ( v2.f2 = t1.f1 )
+ WHERE v2.f1 NOT IN (
+ SELECT 1 UNION
+ SELECT 247
+ )
+";
+EXECUTE st1;
+f1 f4 f1 f2
+7 y 10 7
+deallocate prepare st1;
+DROP VIEW v2;
+DROP TABLE t1,t2;
+#
+# LP bug #887458 Crash in subselect_union_engine::no_rows with
+# double UNION and join_cache_level=3,8
+# (IN/ALL/ANY optimizations should not be applied to fake_select)
+CREATE TABLE t2 ( a int, b varchar(1)) ;
+INSERT IGNORE INTO t2 VALUES (8,'y'),(8,'y');
+CREATE TABLE t1 ( b varchar(1)) ;
+INSERT IGNORE INTO t1 VALUES (NULL),(NULL);
+set @save_join_cache_level=@@join_cache_level;
+SET SESSION join_cache_level=3;
+SELECT *
+FROM t1, t2
+WHERE t2.b IN (
+SELECT 'm' UNION
+SELECT 'm'
+) OR t1.b <> SOME (
+SELECT 'v' UNION
+SELECT 't'
+);
+b a b
+set @@join_cache_level= @save_join_cache_level;
+drop table t1,t2;
+#
+# LP bug #885162 Got error 124 from storage engine with UNION inside
+# subquery and join_cache_level=3..8
+# (IN/ALL/ANY optimizations should not be applied to fake_select)
+#
+CREATE TABLE t1 (
+f1 varchar(1) DEFAULT NULL
+);
+INSERT INTO t1 VALUES ('c');
+set @save_join_cache_level=@@join_cache_level;
+SET SESSION join_cache_level=8;
+SELECT * FROM t1 WHERE t1.f1 IN ( SELECT 'k' UNION SELECT 'e' );
+f1
+set @@join_cache_level= @save_join_cache_level;
+drop table t1;
+#
+# LP BUG#747278 incorrect values of the NULL (no rows) single
+# row subquery requested via element_index() interface
+#
+CREATE TABLE t1 (f1a int, f1b int) ;
+INSERT IGNORE INTO t1 VALUES (1,1),(2,2);
+CREATE TABLE t2 ( f2 int);
+INSERT IGNORE INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (f3a int default 1, f3b int default 2);
+INSERT INTO t3 VALUES (1,1),(2,2);
+set @old_optimizer_switch = @@session.optimizer_switch;
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,subquery_cache=off,semijoin=off';
+SELECT (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+SELECT (SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+set @@session.optimizer_switch=@old_optimizer_switch;
+SELECT (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+SELECT (SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+select (null, null) = (null, null);
+(null, null) = (null, null)
+NULL
+SELECT (SELECT f3a, f3a FROM t3 where f3a > 3) = (0, 0);
+(SELECT f3a, f3a FROM t3 where f3a > 3) = (0, 0)
+NULL
+drop tables t1,t2,t3;
+#
+# LP BUG#825051 Wrong result with date/datetime and subquery with GROUP BY and in_to_exists
+#
+CREATE TABLE t1 (a date, KEY (a)) ;
+INSERT INTO t1 VALUES ('2009-01-01'),('2009-02-02');
+set @old_optimizer_switch = @@optimizer_switch;
+SET @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index
+2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 2 Using index
+SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+a
+2009-01-01
+2009-02-02
+SET @@optimizer_switch='semijoin=off,materialization=on,in_to_exists=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index
+2 MATERIALIZED t1 index NULL a 4 NULL 2 Using index
+SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+a
+2009-01-01
+2009-02-02
+set @@optimizer_switch=@old_optimizer_switch;
+drop table t1;
+#
+# LP BUG#908269 incorrect condition in case of subqueries depending
+# on constant tables
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 ( b INT ) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (4),(5);
+SET optimizer_switch='subquery_cache=off';
+SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) )
+1
+NULL
+SELECT ( SELECT b FROM t2 WHERE b = a OR b * 0) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR b * 0)
+1
+NULL
+SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR rand() * 0)
+1
+NULL
+drop table t1,t2,t3;
+set optimizer_switch=@subselect_tmp;
+#
+# LP BUG#905353 Wrong non-empty result with a constant table,
+# aggregate function in subquery, MyISAM or Aria
+#
+CREATE TABLE t1 ( a INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1);
+SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 );
+a
+drop table t1;
+#
+# LP BUG#985667 Wrong result with subquery in SELECT clause, and constant table in
+# main query and implicit grouping
+#
+CREATE TABLE t1 (f1 int) engine=MyISAM;
+INSERT INTO t1 VALUES (7),(8);
+CREATE TABLE t2 (f2 int, f3 varchar(1)) engine=MyISAM;
+INSERT INTO t2 VALUES (3,'f');
+EXPLAIN
+SELECT COUNT(f1), (SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2
+SELECT COUNT(f1), (SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 NULL
+EXPLAIN
+SELECT COUNT(f1), exists(SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2
+SELECT COUNT(f1), exists(SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 0
+EXPLAIN
+SELECT COUNT(f1), f2 > ALL (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2 Using where
+SELECT COUNT(f1), f2 > ALL (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 1
+EXPLAIN
+SELECT COUNT(f1), f2 IN (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2 Using where
+SELECT COUNT(f1), f2 IN (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 0
+drop table t1,t2;
+#
+# LP BUG#1002079 Server crashes in Item_singlerow_subselect::val_int with constant table,
+# HAVING, UNION in subquery
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (7),(0);
+CREATE TABLE t2 (b INT);
+EXPLAIN
+SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
+f1 f2
+drop table t1,t2;
+#
+# LP BUG#1008686 Server crashes in subselect_union_engine::no_rows on SELECT with impossible
+# WHERE and UNION in HAVING
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(7);
+EXPLAIN
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 0 HAVING a NOT IN ( SELECT 2 UNION SELECT 5 ) OR min_a != 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 NULL NULL NULL NULL NULL NULL NULL No tables used
+3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 0 HAVING a NOT IN ( SELECT 2 UNION SELECT 5 ) OR min_a != 1;
+min_a a
+EXPLAIN
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 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 ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 2 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 1;
+min_a a
+drop table t1;
+#
+# MDEV-367: Different results with and without subquery_cache on
+# a query with a constant NOT IN condition
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2),(3);
+set @mdev367_optimizer_switch = @@optimizer_switch;
+set optimizer_switch = 'subquery_cache=on';
+SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
+a
+SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
+a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
+1 NULL
+2 NULL
+3 NULL
+set optimizer_switch=@mdev367_optimizer_switch;
+set optimizer_switch = 'subquery_cache=off';
+SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
+a
+SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
+a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
+1 NULL
+2 NULL
+3 NULL
+set optimizer_switch=@mdev367_optimizer_switch;
+DROP TABLE t1;
+#
+# MDEV-521 single value subselect transformation problem
+#
+CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('u1'),('u2');
+SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) );
+f1
+u1
+u2
+FLUSH TABLES;
+SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) );
+f1
+u1
+u2
+DROP TABLE t1;
+# return optimizer switch changed in the beginning of this test
+set optimizer_switch=@subselect_tmp;
+set @optimizer_switch_for_subselect_test=null;
diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
new file mode 100644
index 00000000000..f3a01618eff
--- /dev/null
+++ b/mysql-test/r/subselect_no_scache.result
@@ -0,0 +1,6303 @@
+select @@optimizer_switch like '%subquery_cache=on%';
+@@optimizer_switch like '%subquery_cache=on%'
+1
+set optimizer_switch='subquery_cache=off';
+set join_cache_level=1;
+set @join_cache_level_for_subselect_test=@@join_cache_level;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+drop view if exists v2;
+set @subselect_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test,
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+set join_cache_level=@join_cache_level_for_subselect_test;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+select (select 2);
+(select 2)
+2
+explain extended select (select 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select 2 AS `(select 2)`
+SELECT (SELECT 1) UNION SELECT (SELECT 2);
+(SELECT 1)
+1
+2
+explain extended SELECT (SELECT 1) UNION SELECT (SELECT 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1249 Select 4 was reduced during optimization
+Note 1003 select 1 AS `(SELECT 1)` union select 2 AS `(SELECT 2)`
+SELECT (SELECT (SELECT 0 UNION SELECT 0));
+(SELECT (SELECT 0 UNION SELECT 0))
+0
+explain extended SELECT (SELECT (SELECT 0 UNION SELECT 0));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (select 0 union select 0) AS `(SELECT (SELECT 0 UNION SELECT 0))`
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) as c HAVING a=1) as b;
+ERROR 42S22: Reference 'b' not supported (forward reference in item list)
+SELECT (SELECT 1),MAX(1) FROM (SELECT 1) as a;
+(SELECT 1) MAX(1)
+1 1
+SELECT (SELECT a) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having ((select 1) = 1)
+SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+1
+1
+SELECT (SELECT 1), a;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT 1 as a FROM (SELECT 1) as b HAVING (SELECT a)=1;
+a
+1
+SELECT 1 FROM (SELECT (SELECT a) b) c;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT * FROM (SELECT 1 as id) b WHERE id IN (SELECT * FROM (SELECT 1 as id) c ORDER BY id);
+id
+1
+SELECT * FROM (SELECT 1) a WHERE 1 IN (SELECT 1,1);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT 1 IN (SELECT 1);
+1 IN (SELECT 1)
+1
+SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
+1
+1
+select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
+ERROR HY000: Incorrect usage of PROCEDURE and subquery
+SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
+ERROR HY000: Incorrect parameters to procedure 'ANALYSE'
+SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT (SELECT 1,2,3) = ROW(1,2,3);
+(SELECT 1,2,3) = ROW(1,2,3)
+1
+SELECT (SELECT 1,2,3) = ROW(1,2,1);
+(SELECT 1,2,3) = ROW(1,2,1)
+0
+SELECT (SELECT 1,2,3) < ROW(1,2,1);
+(SELECT 1,2,3) < ROW(1,2,1)
+0
+SELECT (SELECT 1,2,3) > ROW(1,2,1);
+(SELECT 1,2,3) > ROW(1,2,1)
+1
+SELECT (SELECT 1,2,3) = ROW(1,2,NULL);
+(SELECT 1,2,3) = ROW(1,2,NULL)
+NULL
+SELECT ROW(1,2,3) = (SELECT 1,2,3);
+ROW(1,2,3) = (SELECT 1,2,3)
+1
+SELECT ROW(1,2,3) = (SELECT 1,2,1);
+ROW(1,2,3) = (SELECT 1,2,1)
+0
+SELECT ROW(1,2,3) < (SELECT 1,2,1);
+ROW(1,2,3) < (SELECT 1,2,1)
+0
+SELECT ROW(1,2,3) > (SELECT 1,2,1);
+ROW(1,2,3) > (SELECT 1,2,1)
+1
+SELECT ROW(1,2,3) = (SELECT 1,2,NULL);
+ROW(1,2,3) = (SELECT 1,2,NULL)
+NULL
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'a');
+(SELECT 1.5,2,'a') = ROW(1.5,2,'a')
+1
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'b');
+(SELECT 1.5,2,'a') = ROW(1.5,2,'b')
+0
+SELECT (SELECT 1.5,2,'a') = ROW('1.5b',2,'b');
+(SELECT 1.5,2,'a') = ROW('1.5b',2,'b')
+0
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: '1.5b'
+SELECT (SELECT 'b',2,'a') = ROW(1.5,2,'a');
+(SELECT 'b',2,'a') = ROW(1.5,2,'a')
+0
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,'2','a');
+(SELECT 1.5,2,'a') = ROW(1.5,'2','a')
+1
+SELECT (SELECT 1.5,'c','a') = ROW(1.5,2,'a');
+(SELECT 1.5,'c','a') = ROW(1.5,2,'a')
+0
+SELECT (SELECT * FROM (SELECT 'test' a,'test' b) a);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT 1 as a,(SELECT a+a) b,(SELECT b);
+a b (SELECT b)
+1 2 2
+create table t1 (a int);
+create table t2 (a int, b int);
+create table t3 (a int);
+create table t4 (a int not null, b int not null);
+insert into t1 values (2);
+insert into t2 values (1,7),(2,7);
+insert into t4 values (4,8),(3,8),(5,9);
+select (select a from t1 where t1.a = a1) as a2, (select b from t2 where t2.b=a2) as a1;
+ERROR 42S22: Reference 'a1' not supported (forward reference in item list)
+select (select a from t1 where t1.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a) a
+NULL 1
+2 2
+select (select a from t1 where t1.a=t2.b), a from t2;
+(select a from t1 where t1.a=t2.b) a
+NULL 1
+NULL 2
+select (select a from t1), a, (select 1 union select 2 limit 1) from t2;
+(select a from t1) a (select 1 union select 2 limit 1)
+2 1 1
+2 2 1
+select (select a from t3), a from t2;
+(select a from t3) a
+NULL 1
+NULL 2
+select * from t2 where t2.a=(select a from t1);
+a b
+2 7
+insert into t3 values (6),(7),(3);
+select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
+a b
+1 7
+2 7
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
+a b
+1 7
+2 7
+3 8
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
+a b
+1 7
+2 7
+4 8
+3 8
+explain extended (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+3 UNION t4 ALL NULL NULL NULL NULL 3 100.00 Using where
+4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`)
+select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
+(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
+3 1
+7 2
+select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+(select t3.a from t3 where a<8 order by 1 desc limit 1) a
+7 2
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 100.00
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
+Warnings:
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`tt`.`a` AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
+set optimizer_switch=@tmp_optimizer_switch;
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
+a
+2
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a > t1.a) order by 1 desc limit 1);
+a
+2
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a < t1.a) order by 1 desc limit 1);
+a
+select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
+b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
+8 7.5000
+8 4.5000
+9 7.5000
+explain extended select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t4 ALL NULL NULL NULL NULL 3 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t4.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select `test`.`t4`.`b` AS `b`,(select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+select * from t3 where exists (select * from t2 where t2.b=t3.a);
+a
+7
+select * from t3 where not exists (select * from t2 where t2.b=t3.a);
+a
+6
+3
+select * from t3 where a in (select b from t2);
+a
+7
+select * from t3 where a not in (select b from t2);
+a
+6
+3
+select * from t3 where a = some (select b from t2);
+a
+7
+select * from t3 where a <> any (select b from t2);
+a
+6
+3
+select * from t3 where a = all (select b from t2);
+a
+7
+select * from t3 where a <> all (select b from t2);
+a
+6
+3
+insert into t2 values (100, 5);
+select * from t3 where a < any (select b from t2);
+a
+6
+3
+select * from t3 where a < all (select b from t2);
+a
+3
+select * from t3 where a >= any (select b from t2);
+a
+6
+7
+explain extended select * from t3 where a >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= all (select b from t2);
+a
+7
+delete from t2 where a=100;
+select * from t3 where a in (select a,b from t2);
+ERROR 21000: Operand should contain 1 column(s)
+select * from t3 where a in (select * from t2);
+ERROR 21000: Operand should contain 1 column(s)
+insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9),(1,10);
+select b,max(a) as ma from t4 group by b having b < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+insert into t2 values (2,10);
+select b,max(a) as ma from t4 group by b having ma < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+10 1
+delete from t2 where a=2 and b=10;
+select b,max(a) as ma from t4 group by b having b >= (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+7 12
+create table t5 (a int);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (5);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (2);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+explain extended select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT UNION t5 ALL NULL NULL NULL NULL 2 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t2.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select (select 2 from `test`.`t1` where (2 = `test`.`t2`.`a`) union select `test`.`t5`.`a` from `test`.`t5` where (`test`.`t5`.`a` = `test`.`t2`.`a`)) AS `(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a)`,`test`.`t2`.`a` AS `a` from `test`.`t2`
+select (select a from t1 where t1.a=t2.a union all select a from t5 where t5.a=t2.a), a from t2;
+ERROR 21000: Subquery returns more than 1 row
+create table t6 (patient_uq int, clinic_uq int, index i1 (clinic_uq));
+create table t7( uq int primary key, name char(25));
+insert into t7 values(1,"Oblastnaia bolnitsa"),(2,"Bolnitsa Krasnogo Kresta");
+insert into t6 values (1,1),(1,2),(2,2),(1,3);
+select * from t6 where exists (select * from t7 where uq = clinic_uq);
+patient_uq clinic_uq
+1 1
+1 2
+2 2
+explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t6 ALL NULL NULL NULL NULL 4 100.00 Using where
+2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
+Warnings:
+Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where exists(select 1 from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`))
+select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
+ERROR 23000: Column 'a' in field list is ambiguous
+drop table t1,t2,t3;
+CREATE TABLE t3 (a varchar(20),b char(1) NOT NULL default '0');
+INSERT INTO t3 VALUES ('W','a'),('A','c'),('J','b');
+CREATE TABLE t2 (a varchar(20),b int NOT NULL default '0');
+INSERT INTO t2 VALUES ('W','1'),('A','3'),('J','2');
+CREATE TABLE t1 (a varchar(20),b date NOT NULL default '0000-00-00');
+INSERT INTO t1 VALUES ('W','1732-02-22'),('A','1735-10-30'),('J','1743-04-13');
+SELECT * FROM t1 WHERE b = (SELECT MIN(b) FROM t1);
+a b
+W 1732-02-22
+SELECT * FROM t2 WHERE b = (SELECT MIN(b) FROM t2);
+a b
+W 1
+SELECT * FROM t3 WHERE b = (SELECT MIN(b) FROM t3);
+a b
+W a
+CREATE TABLE `t8` (
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+`email` varchar(60) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`),
+UNIQUE KEY `email` (`email`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t8 (pseudo,email) VALUES ('joce','test');
+INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
+INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
+EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where; Using index
+4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where
+3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
+t8 WHERE pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
+pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+pseudo
+joce
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo LIKE '%joce%');
+ERROR 21000: Subquery returns more than 1 row
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8;
+CREATE TABLE `t1` (
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (topic,date,pseudo) VALUES
+('43506','2002-10-02','joce'),('40143','2002-08-03','joce');
+EXPLAIN EXTENDED SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')
+EXPLAIN EXTENDED SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select (select distinct `test`.`t1`.`date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')) AS `(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')`
+SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+date
+2002-08-03
+SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')
+2002-08-03
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL SELECT 1;
+1
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1;
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL topic 3 NULL 2 100.00 Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where (1 = (select 1 union select 1))
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (40143,1),(43506,2);
+CREATE TABLE `t2` (
+`mot` varchar(30) NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t2 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce');
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+a
+40143
+SELECT numeropost,maxnumrep FROM t1 WHERE exists (SELECT 1 FROM t2 WHERE (mot='joce') AND date >= '2002-10-21' AND t1.numeropost = t2.topic) ORDER BY maxnumrep DESC LIMIT 0, 20;
+numeropost maxnumrep
+43506 2
+40143 1
+SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1) b;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT 1 IN (SELECT 1 FROM t2 HAVING a);
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic IN (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 1
+SELECT * from t2 where topic = all (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+SELECT * from t2 where topic <> any (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 0
+drop table t1,t2;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (1,0),(2,1);
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+show warnings;
+Level Code Message
+Error 1242 Subquery returns more than 1 row
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+(select * from t1) union (select * from t1) order by (select a from t1 limit 1);
+a
+1
+2
+3
+drop table t1;
+CREATE TABLE t1 (field char(1) NOT NULL DEFAULT 'b');
+INSERT INTO t1 VALUES ();
+SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) a HAVING field='b');
+ERROR 21000: Subquery returns more than 1 row
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL default '0',
+`numreponse` int(10) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`numeropost`,`numreponse`),
+UNIQUE KEY `numreponse` (`numreponse`),
+KEY `pseudo` (`pseudo`,`numeropost`)
+) ENGINE=MyISAM;
+SELECT (SELECT numeropost FROM t1 HAVING numreponse=a),numreponse FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Reference 'numreponse' not supported (forward reference in item list)
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=a) FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT * FROM t1) as a;
+numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
+INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY t1 ref PRIMARY PRIMARY 3 const 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select 1 from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+drop table t1;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1);
+SELECT 1 FROM (SELECT a FROM t1) b HAVING (SELECT b.a)=1;
+1
+1
+drop table t1;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 22),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+update t1 set b= (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+update t1 set b= (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+update t1 set b= (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 NULL
+1 21
+2 22
+drop table t1, t2;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+select * from t1 where b = (select b from t2 where t1.a = t2.a);
+a b
+2 12
+delete from t1 where b in (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+delete from t1 where b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete from t1 where b = (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 10
+1 11
+drop table t1, t2;
+create table t11 (a int NOT NULL, b int, primary key (a));
+create table t12 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t11 values (0, 10),(1, 11),(2, 12);
+insert into t12 values (33, 10),(22, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t11;
+a b
+0 10
+1 11
+2 12
+select * from t12;
+a b
+33 10
+22 11
+2 12
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a);
+ERROR HY000: You can't specify target table 't12' for update in FROM clause
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a);
+select * from t11;
+a b
+0 10
+1 11
+select * from t12;
+a b
+33 10
+22 11
+drop table t11, t12, t2;
+CREATE TABLE t1 (x int) ENGINE=MyISAM;
+create table t2 (a int) ENGINE=MyISAM;
+create table t3 (b int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
+ERROR 21000: Subquery returns more than 1 row
+INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
+select * from t1;
+x
+1
+insert into t2 values (1);
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
+ERROR 42S22: Unknown column 'x' in 'field list'
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+2
+drop table t1, t2, t3;
+CREATE TABLE t1 (x int not null, y int, primary key (x)) ENGINE=MyISAM;
+create table t2 (a int);
+create table t3 (a int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+select * from t1;
+x y
+replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
+ERROR 21000: Subquery returns more than 1 row
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 2
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+2 FROM t2));
+select * from t1;
+x y
+1 3
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 1
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+replace LOW_PRIORITY into t1 (x, y) VALUES ((SELECT a+1 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+2 1
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1) b WHERE 1 IN (SELECT *);
+ERROR HY000: No tables used
+CREATE TABLE t2 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (1),(2);
+SELECT * FROM t2 WHERE id IN (SELECT 1);
+id
+1
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = 1)
+SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id
+1
+SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id
+2
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 3 was reduced during optimization
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = (1 + 1))
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL id 5 NULL 2 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`id`,<exists>(select 1 having (<cache>(`test`.`t2`.`id`) = <ref_null_helper>(1)) union select 3 having (<cache>(`test`.`t2`.`id`) = <ref_null_helper>(3))))
+SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
+id
+SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
+id
+2
+INSERT INTO t2 VALUES ((SELECT * FROM t2));
+ERROR HY000: You can't specify target table 't2' for update in FROM clause
+INSERT INTO t2 VALUES ((SELECT id FROM t2));
+ERROR HY000: You can't specify target table 't2' for update in FROM clause
+SELECT * FROM t2;
+id
+1
+2
+CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 values (1),(1);
+UPDATE t2 SET id=(SELECT * FROM t1);
+ERROR 21000: Subquery returns more than 1 row
+drop table t2, t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+select 1 IN (SELECT * from t1);
+1 IN (SELECT * from t1)
+1
+select 10 IN (SELECT * from t1);
+10 IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a=2;
+select 1 IN (SELECT * from t1);
+1 IN (SELECT * from t1)
+1
+select 3 IN (SELECT * from t1);
+3 IN (SELECT * from t1)
+1
+select 10 IN (SELECT * from t1);
+10 IN (SELECT * from t1)
+NULL
+select 1 > ALL (SELECT * from t1);
+1 > ALL (SELECT * from t1)
+0
+select 10 > ALL (SELECT * from t1);
+10 > ALL (SELECT * from t1)
+NULL
+select 1 > ANY (SELECT * from t1);
+1 > ANY (SELECT * from t1)
+NULL
+select 10 > ANY (SELECT * from t1);
+10 > ANY (SELECT * from t1)
+1
+drop table t1;
+create table t1 (a varchar(20));
+insert into t1 values ('A'),('BC'),('DEF');
+select 'A' IN (SELECT * from t1);
+'A' IN (SELECT * from t1)
+1
+select 'XYZS' IN (SELECT * from t1);
+'XYZS' IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a='BC';
+select 'A' IN (SELECT * from t1);
+'A' IN (SELECT * from t1)
+1
+select 'DEF' IN (SELECT * from t1);
+'DEF' IN (SELECT * from t1)
+1
+select 'XYZS' IN (SELECT * from t1);
+'XYZS' IN (SELECT * from t1)
+NULL
+select 'A' > ALL (SELECT * from t1);
+'A' > ALL (SELECT * from t1)
+0
+select 'XYZS' > ALL (SELECT * from t1);
+'XYZS' > ALL (SELECT * from t1)
+NULL
+select 'A' > ANY (SELECT * from t1);
+'A' > ANY (SELECT * from t1)
+NULL
+select 'XYZS' > ANY (SELECT * from t1);
+'XYZS' > ANY (SELECT * from t1)
+1
+drop table t1;
+create table t1 (a float);
+insert into t1 values (1.5),(2.5),(3.5);
+select 1.5 IN (SELECT * from t1);
+1.5 IN (SELECT * from t1)
+1
+select 10.5 IN (SELECT * from t1);
+10.5 IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a=2.5;
+select 1.5 IN (SELECT * from t1);
+1.5 IN (SELECT * from t1)
+1
+select 3.5 IN (SELECT * from t1);
+3.5 IN (SELECT * from t1)
+1
+select 10.5 IN (SELECT * from t1);
+10.5 IN (SELECT * from t1)
+NULL
+select 1.5 > ALL (SELECT * from t1);
+1.5 > ALL (SELECT * from t1)
+0
+select 10.5 > ALL (SELECT * from t1);
+10.5 > ALL (SELECT * from t1)
+NULL
+select 1.5 > ANY (SELECT * from t1);
+1.5 > ANY (SELECT * from t1)
+NULL
+select 10.5 > ANY (SELECT * from t1);
+10.5 > ANY (SELECT * from t1)
+1
+explain extended select (select a+1) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (`test`.`t1`.`a` + 1) AS `(select a+1)` from `test`.`t1`
+select (select a+1) from t1;
+(select a+1)
+2.5
+NULL
+4.5
+drop table t1;
+CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a));
+CREATE TABLE t2 (a int(11) default '0', INDEX (a));
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
+a t1.a in (select t2.a from t2)
+1 1
+2 1
+3 1
+4 0
+explain extended SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on a checking NULL having <is_not_null_test>(`test`.`t2`.`a`)))) AS `t1.a in (select t2.a from t2)` from `test`.`t1`
+CREATE TABLE t3 (a int(11) default '0');
+INSERT INTO t3 VALUES (1),(2),(3);
+SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
+a t1.a in (select t2.a from t2,t3 where t3.a=t2.a)
+1 1
+2 1
+3 1
+4 0
+explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
+drop table t1,t2,t3;
+# check correct NULL Processing for normal IN/ALL/ANY
+# and 2 ways of max/min optimization
+create table t1 (a int);
+insert into t1 values (1), (100), (NULL), (1000);
+create table t2 (a int not null);
+# subselect returns empty set (for NULL and non-NULL left part)
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 1
+100 1
+NULL 1
+1000 1
+select a from t1 where a in (select * from t2);
+a
+select a from t1 where a > any (select * from t2);
+a
+select a from t1 where a > all (select * from t2);
+a
+1
+100
+NULL
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+select a from t1 where a > any (select * from t2 group by a);
+a
+select a from t1 where a > all (select * from t2 group by a);
+a
+1
+100
+NULL
+1000
+insert into t2 values (1),(200);
+# sebselect returns non-empty set without NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 0
+NULL NULL
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 1
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+1000
+drop table t2;
+create table t2 (a int);
+insert into t2 values (1),(NULL),(200);
+# sebselect returns non-empty set with NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 NULL
+NULL NULL
+1000 NULL
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 NULL
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 NULL
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+drop table t1, t2;
+create table t1 (a float);
+select 10.5 IN (SELECT * from t1 LIMIT 1);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int, b int, c varchar(10));
+create table t2 (a int);
+insert into t1 values (1,2,'a'),(2,3,'b'),(3,4,'c');
+insert into t2 values (1),(2),(NULL);
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a') (select c from t1 where a=t2.a)
+1 1 a
+2 0 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b') (select c from t1 where a=t2.a)
+1 0 a
+2 1 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where a=t2.a)
+1 0 a
+2 0 b
+NULL NULL NULL
+drop table t1,t2;
+create table t1 (a int, b real, c varchar(10));
+insert into t1 values (1, 1, 'a'), (2,2,'b'), (NULL, 2, 'b');
+select ROW(1, 1, 'a') IN (select a,b,c from t1);
+ROW(1, 1, 'a') IN (select a,b,c from t1)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1);
+ROW(1, 2, 'a') IN (select a,b,c from t1)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1);
+ROW(1, 1, 'a') IN (select b,a,c from t1)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a')
+1
+select ROW(1, 1, 'a') IN (select b,a,c from t1 limit 2);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1);
+do @a:=(SELECT a from t1);
+select @a;
+@a
+1
+set @a:=2;
+set @a:=(SELECT a from t1);
+select @a;
+@a
+1
+drop table t1;
+do (SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+set @a:=(SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (a int, KEY(a));
+HANDLER t1 OPEN;
+HANDLER t1 READ a=((SELECT 1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT 1))' at line 1
+HANDLER t1 CLOSE;
+drop table t1;
+create table t1 (a int);
+create table t2 (b int);
+insert into t1 values (1),(2);
+insert into t2 values (1);
+select a from t1 where a in (select a from t1 where a in (select b from t2));
+a
+1
+drop table t1, t2;
+create table t1 (a int, b int);
+create table t2 like t1;
+insert into t1 values (1,2),(1,3),(1,4),(1,5);
+insert into t2 values (1,2),(1,3);
+select * from t1 where row(a,b) in (select a,b from t2);
+a b
+1 2
+1 3
+drop table t1, t2;
+CREATE TABLE `t1` (`i` int(11) NOT NULL default '0',PRIMARY KEY (`i`)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+select * from t1;
+i
+2
+drop table t1;
+CREATE TABLE t1 (a int(1));
+EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
+drop table t1;
+CREATE TABLE `t1` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t2` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t3` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t2 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t3 VALUES (1,1);
+SELECT DISTINCT topic FROM t2 WHERE NOT EXISTS(SELECT * FROM t3 WHERE
+numeropost=topic);
+topic
+2
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+test 2 0000-00-00 test
+DELETE FROM t1 WHERE topic IN (SELECT DISTINCT topic FROM t2 WHERE NOT
+EXISTS(SELECT * FROM t3 WHERE numeropost=topic));
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+a (SELECT a)
+1 1
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT 1)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a+0)` int(3) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
+select * from t1;
+a
+2
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+explain extended select a,(select (select rand() from t1 limit 1) from t1 limit 1)
+from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+2 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+3 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,(select (select rand() from `test`.`t1` limit 1) from `test`.`t1` limit 1) AS `(select (select rand() from t1 limit 1) from t1 limit 1)` from `test`.`t1`
+drop table t1;
+select t1.Continent, t2.Name, t2.Population from t1 LEFT JOIN t2 ON t1.Code = t2.Country where t2.Population IN (select max(t2.Population) AS Population from t2, t1 where t2.Country = t1.Code group by Continent);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+name char(35) NOT NULL default '',
+t2 char(3) NOT NULL default '',
+District char(20) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (130,'Sydney','AUS','New South Wales',3276207);
+INSERT INTO t1 VALUES (131,'Melbourne','AUS','Victoria',2865329);
+INSERT INTO t1 VALUES (132,'Brisbane','AUS','Queensland',1291117);
+CREATE TABLE t2 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default '',
+PRIMARY KEY (Code)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU');
+INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
+select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent);
+Continent Name Population
+Oceania Sydney 3276207
+drop table t1, t2;
+CREATE TABLE `t1` (
+`id` mediumint(8) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`id`),
+UNIQUE KEY `pseudo` (`pseudo`)
+) ENGINE=MyISAM PACK_KEYS=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (pseudo) VALUES ('test');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
+INSERT INTO t1 (pseudo) VALUES ('test1');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
+drop table t1;
+CREATE TABLE `t1` (
+`i` int(11) NOT NULL default '0',
+PRIMARY KEY (`i`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i));
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t);
+ERROR 42S22: Unknown column 't.i' in 'field list'
+select * from t1;
+i
+3
+drop table t1;
+CREATE TABLE t1 (
+id int(11) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(1),(2),(2),(1),(3);
+CREATE TABLE t2 (
+id int(11) default NULL,
+name varchar(15) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (4,'vita'), (1,'vita'), (2,'vita'), (1,'vita');
+update t1, t2 set t2.name='lenka' where t2.id in (select id from t1);
+select * from t2;
+id name
+4 vita
+1 lenka
+2 lenka
+1 lenka
+drop table t1,t2;
+create table t1 (a int, unique index indexa (a));
+insert into t1 values (-1), (-4), (-2), (NULL);
+select -10 IN (select a from t1 FORCE INDEX (indexa));
+-10 IN (select a from t1 FORCE INDEX (indexa))
+NULL
+drop table t1;
+create table t1 (id int not null auto_increment primary key, salary int, key(salary));
+insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
+explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using where
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
+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:
+Warning 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`.`t3`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t2`.`a`))
+drop table t1, t2, t3;
+create table t1 (a int, b int, index a (a,b));
+create table t2 (a int, index a (a));
+create table t3 (a int, b int, index a (a));
+insert into t1 values (1,10), (2,20), (3,30), (4,40);
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1
+select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D;
+insert into t2 values (2), (3), (4), (5);
+insert into t3 values (10,3), (20,4), (30,5);
+select * from t2 where t2.a in (select a from t1);
+a
+2
+3
+4
+explain extended select * from t2 where t2.a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where (`test`.`t1`.`a` = `test`.`t2`.`a`)
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+a
+2
+4
+explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
+select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
+a
+2
+3
+explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.00 Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`b` = `test`.`t3`.`a`) and (`test`.`t1`.`a` = `test`.`t2`.`a`))
+insert into t1 values (3,31);
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+a
+2
+3
+4
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31);
+a
+2
+4
+explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
+drop table t0, t1, t2, t3;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+create table t3 (a int, b int);
+insert into t1 values (0,100),(1,2), (1,3), (2,2), (2,7), (2,-1), (3,10);
+insert into t2 values (0,0), (1,1), (2,1), (3,1), (4,1);
+insert into t3 values (3,3), (2,2), (1,1);
+select a,(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3;
+a (select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1)
+3 1
+2 2
+1 2
+drop table t1,t2,t3;
+create table t1 (s1 int);
+create table t2 (s1 int);
+insert into t1 values (1);
+insert into t2 values (1);
+select * from t1 where exists (select s1 from t2 having max(t2.s1)=t1.s1);
+s1
+1
+drop table t1,t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+insert into t1 values (1);
+insert into t2 values (1);
+update t1 set s1 = s1 + 1 where 1 = (select x.s1 as A from t2 WHERE t2.s1 > t1.s1 order by A);
+ERROR 42S22: Unknown column 'x.s1' in 'field list'
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 CHAR(5) COLLATE latin1_german1_ci,
+s2 CHAR(5) COLLATE latin1_swedish_ci);
+INSERT INTO t1 VALUES ('z','?');
+select * from t1 where s1 > (select max(s2) from t1);
+ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+select * from t1 where s1 > any (select max(s2) from t1);
+ERROR HY000: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_german1_ci,IMPLICIT) for operation '<'
+drop table t1;
+create table t1(toid int,rd int);
+create table t2(userid int,pmnew int,pmtotal int);
+insert into t2 values(1,0,0),(2,0,0);
+insert into t1 values(1,0),(1,0),(1,0),(1,12),(1,15),(1,123),(1,12312),(1,12312),(1,123),(2,0),(2,0),(2,1),(2,2);
+select userid,pmtotal,pmnew, (select count(rd) from t1 where toid=t2.userid) calc_total, (select count(rd) from t1 where rd=0 and toid=t2.userid) calc_new from t2 where userid in (select distinct toid from t1);
+userid pmtotal pmnew calc_total calc_new
+1 0 0 9 3
+2 0 0 4 2
+drop table t1, t2;
+create table t1 (s1 char(5));
+select (select 'a','b' from t1 union select 'a','b' from t1) from t1;
+ERROR 21000: Operand should contain 1 column(s)
+insert into t1 values ('tttt');
+select * from t1 where ('a','b')=(select 'a','b' from t1 union select 'a','b' from t1);
+s1
+tttt
+explain extended (select * from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 (select 'tttt' AS `s1` from `test`.`t1`)
+(select * from t1);
+s1
+tttt
+drop table t1;
+create table t1 (s1 char(5), index s1(s1));
+create table t2 (s1 char(5), index s1(s1));
+insert into t1 values ('a1'),('a2'),('a3');
+insert into t2 values ('a1'),('a2');
+select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
+s1 s1 = ANY (SELECT s1 FROM t2)
+a1 1
+a2 1
+a3 0
+select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
+s1 s1 <> ALL (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')
+a1 0
+a2 1
+a3 1
+explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1`
+explain extended select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1`
+explain extended select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1`
+explain extended select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < 'a2') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
+drop table t1,t2;
+create table t2 (a int, b int not null);
+create table t3 (a int);
+insert into t3 values (6),(7),(3);
+select * from t3 where a >= all (select b from t2);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= some (select b from t2);
+a
+explain extended select * from t3 where a >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= all (select b from t2 group by 1);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where a >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where NULL >= any (select b from t2);
+a
+explain extended select * from t3 where NULL >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= any (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= some (select b from t2);
+a
+explain extended select * from t3 where NULL >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+insert into t2 values (2,2), (2,1), (3,3), (3,1);
+select * from t3 where a > all (select max(b) from t2 group by a);
+a
+6
+7
+explain extended select * from t3 where a > all (select max(b) from t2 group by a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= <cache>(`test`.`t3`.`a`))))
+drop table t2, t3;
+CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
+INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
+CREATE TABLE `t2` (`db_id` int(11) NOT NULL auto_increment,`name` varchar(200) NOT NULL default '',`primary_uid` smallint(6) NOT NULL default '0',`secondary_uid` smallint(6) NOT NULL default '0',PRIMARY KEY (`db_id`),UNIQUE KEY `name_2` (`name`),FULLTEXT KEY `name` (`name`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2147483647;
+INSERT INTO `t2` (`db_id`, `name`, `primary_uid`, `secondary_uid`) VALUES (18, 'Not Set 1', 0, 0),(19, 'Valid', 1, 2),(20, 'Valid 2', 1, 2),(21, 'Should Not Return', 1, 2),(26, 'Not Set 2', 0, 0),(-1, 'ALL DB\'S', 0, 0);
+CREATE TABLE `t3` (`taskgenid` mediumint(9) NOT NULL auto_increment,`dbid` int(11) NOT NULL default '0',`taskid` int(11) NOT NULL default '0',`mon` tinyint(4) NOT NULL default '1',`tues` tinyint(4) NOT NULL default '1',`wed` tinyint(4) NOT NULL default '1',`thur` tinyint(4) NOT NULL default '1',`fri` tinyint(4) NOT NULL default '1',`sat` tinyint(4) NOT NULL default '0',`sun` tinyint(4) NOT NULL default '0',`how_often` smallint(6) NOT NULL default '1',`userid` smallint(6) NOT NULL default '0',`active` tinyint(4) NOT NULL default '1',PRIMARY KEY (`taskgenid`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2 ;
+INSERT INTO `t3` (`taskgenid`, `dbid`, `taskid`, `mon`, `tues`,`wed`, `thur`, `fri`, `sat`, `sun`, `how_often`, `userid`, `active`) VALUES (1,-1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1);
+CREATE TABLE `t4` (`task_id` smallint(6) NOT NULL default '0',`description` varchar(200) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO `t4` (`task_id`, `description`) VALUES (1, 'Daily Check List'),(2, 'Weekly Status');
+select dbid, name, (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01') from t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND t4.task_id = taskid;
+dbid name (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')
+-1 Valid 1
+-1 Valid 2 1
+-1 Should Not Return 0
+SELECT dbid, name FROM t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND ((date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')) AND t4.task_id = taskid;
+dbid name
+-1 Valid
+-1 Valid 2
+drop table t1,t2,t3,t4;
+CREATE TABLE t1 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (2),(6);
+select * from t1 where (1,2,6) in (select * from t2);
+ERROR 21000: Operand should contain 3 column(s)
+DROP TABLE t1,t2;
+create table t1 (s1 int);
+insert into t1 values (1);
+insert into t1 values (2);
+set sort_buffer_size = (select s1 from t1);
+ERROR 21000: Subquery returns more than 1 row
+do (select * from t1);
+Warnings:
+Error 1242 Subquery returns more than 1 row
+drop table t1;
+create table t1 (s1 char);
+insert into t1 values ('e');
+select * from t1 where 'f' > any (select s1 from t1);
+s1
+e
+select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+s1
+e
+explain extended select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+2 SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 UNION t1 system NULL NULL NULL NULL 1 100.00
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',(<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`) < 'f')))
+drop table t1;
+CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
+CREATE TABLE t2 (code char(5) NOT NULL default '',UNIQUE KEY code (code)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES ('1'),('1226'),('1245'),('1862'),('18623'),('1874'),('1967'),('6');
+select c.number as phone,(select p.code from t2 p where c.number like concat(p.code, '%') order by length(p.code) desc limit 1) as code from t1 c;
+phone code
+69294728265 6
+18621828126 1862
+89356874041 NULL
+95895001874 NULL
+drop table t1, t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+select * from t1 where (select count(*) from t2 where t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'where clause'
+select * from t1 where (select count(*) from t2 group by t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+select count(*) from t2 group by t1.s2;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+drop table t1, t2;
+CREATE TABLE t1(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC VARCHAR(20) DEFAULT NULL,PRIMARY KEY (COLA, COLB));
+CREATE TABLE t2(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC CHAR(1) NOT NULL,PRIMARY KEY (COLA));
+INSERT INTO t1 VALUES (1,1,'1A3240'), (1,2,'4W2365');
+INSERT INTO t2 VALUES (100, 200, 'C');
+SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1);
+COLC
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1),(1),(1),(1),(1),(2),(3),(4),(5);
+SELECT DISTINCT (SELECT a) FROM t1 LIMIT 100;
+(SELECT a)
+1
+2
+3
+4
+5
+DROP TABLE t1;
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "../../tmp/subselect.out.file.1" from t1;
+delete from t1;
+load data infile "../../tmp/subselect.out.file.1" into table t1;
+select * from t1;
+a b
+1 0.123
+drop table t1;
+CREATE TABLE `t1` (
+`id` int(11) NOT NULL auto_increment,
+`id_cns` tinyint(3) unsigned NOT NULL default '0',
+`tipo` enum('','UNO','DUE') NOT NULL default '',
+`anno_dep` smallint(4) unsigned zerofill NOT NULL default '0000',
+`particolare` mediumint(8) unsigned NOT NULL default '0',
+`generale` mediumint(8) unsigned NOT NULL default '0',
+`bis` tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`),
+UNIQUE KEY `idx_cns_gen_anno` (`anno_dep`,`id_cns`,`generale`,`particolare`),
+UNIQUE KEY `idx_cns_par_anno` (`id_cns`,`anno_dep`,`tipo`,`particolare`,`bis`)
+);
+INSERT INTO `t1` VALUES (1,16,'UNO',1987,2048,9681,0),(2,50,'UNO',1987,1536,13987,0),(3,16,'UNO',1987,2432,14594,0),(4,16,'UNO',1987,1792,13422,0),(5,16,'UNO',1987,1025,10240,0),(6,16,'UNO',1987,1026,7089,0);
+CREATE TABLE `t2` (
+`id` tinyint(3) unsigned NOT NULL auto_increment,
+`max_anno_dep` smallint(6) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`)
+);
+INSERT INTO `t2` VALUES (16,1987),(50,1990),(51,1990);
+SELECT cns.id, cns.max_anno_dep, cns.max_anno_dep = (SELECT s.anno_dep FROM t1 AS s WHERE s.id_cns = cns.id ORDER BY s.anno_dep DESC LIMIT 1) AS PIPPO FROM t2 AS cns;
+id max_anno_dep PIPPO
+16 1987 1
+50 1990 0
+51 1990 NULL
+DROP TABLE t1, t2;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SET SQL_SELECT_LIMIT=1;
+select sum(a) from (select * from t1) as a;
+sum(a)
+6
+select 2 in (select * from t1);
+2 in (select * from t1)
+1
+SET SQL_SELECT_LIMIT=default;
+drop table t1;
+CREATE TABLE t1 (a int, b int, INDEX (a));
+INSERT INTO t1 VALUES (1, 1), (1, 2), (1, 3);
+SELECT * FROM t1 WHERE a = (SELECT MAX(a) FROM t1 WHERE a = 1) ORDER BY b;
+a b
+1 1
+1 2
+1 3
+DROP TABLE t1;
+create table t1(val varchar(10));
+insert into t1 values ('aaa'), ('bbb'),('eee'),('mmm'),('ppp');
+select count(*) from t1 as w1 where w1.val in (select w2.val from t1 as w2 where w2.val like 'm%') and w1.val in (select w3.val from t1 as w3 where w3.val like 'e%');
+count(*)
+0
+drop table t1;
+create table t1 (id int not null, text varchar(20) not null default '', primary key (id));
+insert into t1 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text11'), (12, 'text12');
+select * from t1 where id not in (select id from t1 where id < 8);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+explain extended select * from t1 where id not in (select id from t1 where id < 8);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00 Using where
+2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not(<in_optimizer>(`test`.`t1`.`id`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`id`) in t1 on PRIMARY where ((`test`.`t1`.`id` < 8) and (<cache>(`test`.`t1`.`id`) = `test`.`t1`.`id`)))))))
+explain extended select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY tt ALL NULL NULL NULL NULL 12 100.00 Using where
+2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 100.00 Using where; Using index
+Warnings:
+Note 1276 Field or reference 'test.tt.id' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null))))
+insert into t1 (id, text) values (1000, 'text1000'), (1001, 'text1001');
+create table t2 (id int not null, text varchar(20) not null default '', primary key (id));
+insert into t2 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text1'), (12, 'text2'), (13, 'text3'), (14, 'text4'), (15, 'text5'), (16, 'text6'), (17, 'text7'), (18, 'text8'), (19, 'text9'), (20, 'text10'),(21, 'text1'), (22, 'text2'), (23, 'text3'), (24, 'text4'), (25, 'text5'), (26, 'text6'), (27, 'text7'), (28, 'text8'), (29, 'text9'), (30, 'text10'), (31, 'text1'), (32, 'text2'), (33, 'text3'), (34, 'text4'), (35, 'text5'), (36, 'text6'), (37, 'text7'), (38, 'text8'), (39, 'text9'), (40, 'text10'), (41, 'text1'), (42, 'text2'), (43, 'text3'), (44, 'text4'), (45, 'text5'), (46, 'text6'), (47, 'text7'), (48, 'text8'), (49, 'text9'), (50, 'text10');
+select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (if(isnull(b.id), 1000, b.id)=c.id);
+id text id text id text
+1 text1 1 text1 1 text1
+2 text2 2 text2 2 text2
+3 text3 3 text3 3 text3
+4 text4 4 text4 4 text4
+5 text5 5 text5 5 text5
+6 text6 6 text6 6 text6
+7 text7 7 text7 7 text7
+8 text8 8 text8 8 text8
+9 text9 9 text9 9 text9
+10 text10 10 text10 10 text10
+11 text11 11 text1 11 text11
+12 text12 12 text2 12 text12
+1000 text1000 NULL NULL 1000 text1000
+1001 text1001 NULL NULL 1000 text1000
+explain extended select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (if(isnull(b.id), 1000, b.id)=c.id);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE a ALL NULL NULL NULL NULL 14 100.00
+1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.id 2 100.00
+1 SIMPLE c eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using index condition
+Warnings:
+Note 1003 select `test`.`a`.`id` AS `id`,`test`.`a`.`text` AS `text`,`test`.`b`.`id` AS `id`,`test`.`b`.`text` AS `text`,`test`.`c`.`id` AS `id`,`test`.`c`.`text` AS `text` from `test`.`t1` `a` left join `test`.`t2` `b` on(((`test`.`b`.`id` = `test`.`a`.`id`) or isnull(`test`.`b`.`id`))) join `test`.`t1` `c` where (if(isnull(`test`.`b`.`id`),1000,`test`.`b`.`id`) = `test`.`c`.`id`)
+drop table t1,t2;
+create table t1 (a int);
+insert into t1 values (1);
+explain select benchmark(1000, (select a from t1 where a=sha(rand())));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 1
+drop table t1;
+create table t1(id int);
+create table t2(id int);
+create table t3(flag int);
+select (select * from t3 where id not null) from t1, t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null) from t1, t2' at line 1
+drop table t1,t2,t3;
+CREATE TABLE t1 (id INT);
+CREATE TABLE t2 (id INT);
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1);
+SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id);
+id c
+1 1
+2 0
+SELECT id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id);
+id c
+1 1
+2 0
+SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id) ORDER BY t1.id;
+id c
+1 1
+2 0
+SELECT id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id) ORDER BY id;
+id c
+1 1
+2 0
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+ALTER TABLE t1 ADD INDEX (a);
+SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE a > ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE a > ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) <> ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 2 column(s)
+SELECT a FROM t1 WHERE a = ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a,2 FROM t1 WHERE b = 2);
+a
+SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 2 column(s)
+SELECT a FROM t1 WHERE a <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
+a
+1
+2
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+3
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-')
+0-
+0-
+1-
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-')
+1-
+0-
+0-
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-')
+0-
+1-
+0-
+DROP TABLE t1;
+CREATE TABLE t1 ( a double, b double );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+3
+DROP TABLE t1;
+CREATE TABLE t1 ( a char(1), b char(1));
+INSERT INTO t1 VALUES ('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = '2');
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = '2');
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = '2');
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = '2');
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = '2');
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = '2');
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+create table t1 (a int, b int);
+insert into t1 values (1,2),(3,4);
+select * from t1 up where exists (select * from t1 where t1.a=up.a);
+a b
+1 2
+3 4
+explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where exists(select 1 from `test`.`t1` where (`test`.`t1`.`a` = `test`.`up`.`a`))
+drop table t1;
+CREATE TABLE t1 (t1_a int);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (t2_a int, t2_b int, PRIMARY KEY (t2_a, t2_b));
+INSERT INTO t2 VALUES (1, 1), (1, 2);
+SELECT * FROM t1, t2 table2 WHERE t1_a = 1 AND table2.t2_a = 1
+HAVING table2.t2_b = (SELECT MAX(t2_b) FROM t2 WHERE t2_a = table2.t2_a);
+t1_a t2_a t2_b
+1 1 2
+DROP TABLE t1, t2;
+CREATE TABLE t1 (id int(11) default NULL,name varchar(10) default NULL);
+INSERT INTO t1 VALUES (1,'Tim'),(2,'Rebecca'),(3,NULL);
+CREATE TABLE t2 (id int(11) default NULL, pet varchar(10) default NULL);
+INSERT INTO t2 VALUES (1,'Fido'),(2,'Spot'),(3,'Felix');
+SELECT a.*, b.* FROM (SELECT * FROM t1) AS a JOIN t2 as b on a.id=b.id;
+id name id pet
+1 Tim 1 Fido
+2 Rebecca 2 Spot
+3 NULL 3 Felix
+drop table t1,t2;
+CREATE TABLE t1 ( a int, b int );
+CREATE TABLE t2 ( c int, d int );
+INSERT INTO t1 VALUES (1,2), (2,3), (3,4);
+SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+abc b
+1 2
+2 3
+3 4
+INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+select * from t2;
+c d
+1 2
+2 3
+3 4
+CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+select * from t3;
+abc b
+1 2
+2 3
+3 4
+prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
+execute stmt1;
+deallocate prepare stmt1;
+select * from t2;
+c d
+1 2
+2 3
+3 4
+1 2
+2 3
+3 4
+drop table t3;
+prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
+execute stmt1;
+select * from t3;
+abc b
+1 2
+2 3
+3 4
+deallocate prepare stmt1;
+DROP TABLE t1, t2, t3;
+CREATE TABLE `t1` ( `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t1 values (1);
+CREATE TABLE `t2` ( `b` int(11) default NULL, `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t2 values (1,2);
+select t000.a, count(*) `C` FROM t1 t000 GROUP BY t000.a HAVING count(*) > ALL (SELECT count(*) FROM t2 t001 WHERE t001.a=1);
+a C
+1 1
+drop table t1,t2;
+create table t1 (a int not null auto_increment primary key, b varchar(40), fulltext(b));
+insert into t1 (b) values ('ball'),('ball games'), ('games'), ('foo'), ('foobar'), ('Serg'), ('Sergei'),('Georg'), ('Patrik'),('Hakan');
+create table t2 (a int);
+insert into t2 values (1),(3),(2),(7);
+select a,b from t1 where match(b) against ('Ball') > 0;
+a b
+1 ball
+2 ball games
+select a from t2 where a in (select a from t1 where match(b) against ('Ball') > 0);
+a
+1
+2
+drop table t1,t2;
+CREATE TABLE t1(`IZAVORGANG_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`KUERZEL` VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_bin,`IZAANALYSEART_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`IZAPMKZ_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin);
+CREATE INDEX AK01IZAVORGANG ON t1(izaAnalyseart_id,Kuerzel);
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000001','601','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000002','602','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000003','603','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000004','101','D0000000001','I0000000001');
+SELECT `IZAVORGANG_ID` FROM t1 WHERE `KUERZEL` IN(SELECT MIN(`KUERZEL`)`Feld1` FROM t1 WHERE `KUERZEL` LIKE'601%'And`IZAANALYSEART_ID`='D0000000001');
+IZAVORGANG_ID
+D0000000001
+drop table t1;
+CREATE TABLE `t1` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
+CREATE TABLE `t2` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
+insert into t1 values (1,1),(1,2),(2,1),(2,2);
+insert into t2 values (1,2),(2,2);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+alter table t2 drop primary key;
+alter table t2 add key KEY1 (aid, bid);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+alter table t2 drop key KEY1;
+alter table t2 add primary key (bid, aid);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+drop table t1,t2;
+CREATE TABLE t1 (howmanyvalues bigint, avalue int);
+INSERT INTO t1 VALUES (1, 1),(2, 1),(2, 2),(3, 1),(3, 2),(3, 3),(4, 1),(4, 2),(4, 3),(4, 4);
+SELECT howmanyvalues, count(*) from t1 group by howmanyvalues;
+howmanyvalues count(*)
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+CREATE INDEX t1_howmanyvalues_idx ON t1 (howmanyvalues);
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues+1 = a.howmanyvalues+1) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.avalue) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 1
+3 1
+4 1
+drop table t1;
+create table t1 (x int);
+select (select b.x from t1 as b where b.x=a.x) from t1 as a where a.x=2 group by a.x;
+(select b.x from t1 as b where b.x=a.x)
+drop table t1;
+CREATE TABLE `t1` ( `master` int(10) unsigned NOT NULL default '0', `map` smallint(6) unsigned NOT NULL default '0', `slave` int(10) unsigned NOT NULL default '0', `access` int(10) unsigned NOT NULL default '0', UNIQUE KEY `access_u` (`master`,`map`,`slave`));
+INSERT INTO `t1` VALUES (1,0,0,700),(1,1,1,400),(1,5,5,400),(1,12,12,400),(1,12,32,400),(4,12,32,400);
+CREATE TABLE `t2` ( `id` int(10) unsigned NOT NULL default '0', `pid` int(10) unsigned NOT NULL default '0', `map` smallint(6) unsigned NOT NULL default '0', `level` tinyint(4) unsigned NOT NULL default '0', `title` varchar(255) default NULL, PRIMARY KEY (`id`,`pid`,`map`), KEY `level` (`level`), KEY `id` (`id`,`map`)) ;
+INSERT INTO `t2` VALUES (6,5,12,7,'a'),(12,0,0,7,'a'),(12,1,0,7,'a'),(12,5,5,7,'a'),(12,5,12,7,'a');
+SELECT b.sc FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
+ERROR 42S22: Unknown column 'b.sc' in 'field list'
+SELECT b.ac FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
+ac
+700
+NULL
+drop tables t1,t2;
+create table t1 (a int not null, b int not null, c int, primary key (a,b));
+insert into t1 values (1,1,1), (2,2,2), (3,3,3);
+set @b:= 0;
+explain select sum(a) from t1 where b > @b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 8 NULL 3 Using where; Using index
+set @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+do @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+drop table t1;
+set @got_val= (SELECT 1 FROM (SELECT 'A' as my_col) as T1 ) ;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1,1),(1,2),(1,3),(2,4),(2,5);
+insert into t2 values (1,3),(2,1);
+select distinct a,b, (select max(b) from t2 where t1.b=t2.a) from t1 order by t1.b;
+a b (select max(b) from t2 where t1.b=t2.a)
+1 1 3
+1 2 1
+1 3 NULL
+2 4 NULL
+2 5 NULL
+drop table t1, t2;
+create table t1 (id int);
+create table t2 (id int, body text, fulltext (body));
+insert into t1 values(1),(2),(3);
+insert into t2 values (1,'test'), (2,'mysql'), (3,'test'), (4,'test');
+select count(distinct id) from t1 where id in (select id from t2 where match(body) against ('mysql' in boolean mode));
+count(distinct id)
+1
+drop table t2,t1;
+create table t1 (s1 int,s2 int);
+insert into t1 values (20,15);
+select * from t1 where (('a',null) <=> (select 'a',s2 from t1 where s1 = 0));
+s1 s2
+drop table t1;
+create table t1 (s1 int);
+insert into t1 values (1),(null);
+select * from t1 where s1 < all (select s1 from t1);
+s1
+select s1, s1 < all (select s1 from t1) from t1;
+s1 s1 < all (select s1 from t1)
+1 0
+NULL NULL
+drop table t1;
+CREATE TABLE t1 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default ''
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
+INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
+INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
+INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
+/*!40000 ALTER TABLE t1 ENABLE KEYS */;
+SELECT DISTINCT Continent AS c FROM t1 outr WHERE
+Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND
+Population < 200);
+c
+Oceania
+drop table t1;
+create table t1 (a1 int);
+create table t2 (b1 int);
+select * from t1 where a2 > any(select b1 from t2);
+ERROR 42S22: Unknown column 'a2' in 'IN/ALL/ANY subquery'
+select * from t1 where a1 > any(select b1 from t2);
+a1
+drop table t1,t2;
+create table t1 (a integer, b integer);
+select (select * from t1) = (select 1,2);
+(select * from t1) = (select 1,2)
+NULL
+select (select 1,2) = (select * from t1);
+(select 1,2) = (select * from t1)
+NULL
+select row(1,2) = ANY (select * from t1);
+row(1,2) = ANY (select * from t1)
+0
+select row(1,2) != ALL (select * from t1);
+row(1,2) != ALL (select * from t1)
+1
+drop table t1;
+create table t1 (a integer, b integer);
+select row(1,(2,2)) in (select * from t1 );
+ERROR 21000: Operand should contain 2 column(s)
+select row(1,(2,2)) = (select * from t1 );
+ERROR 21000: Operand should contain 2 column(s)
+select (select * from t1) = row(1,(2,2));
+ERROR 21000: Operand should contain 1 column(s)
+drop table t1;
+create table t1 (a integer);
+insert into t1 values (1);
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx ;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 as xx, 1 = ALL ( select 1 from t1 where 1 = xx );
+xx 1 = ALL ( select 1 from t1 where 1 = xx )
+1 1
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+drop table t1;
+CREATE TABLE t1 (
+categoryId int(11) NOT NULL,
+courseId int(11) NOT NULL,
+startDate datetime NOT NULL,
+endDate datetime NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL,
+attributes text NOT NULL
+);
+INSERT INTO t1 VALUES (1,41,'2004-02-09','2010-01-01','2004-02-09','2004-02-09',''),
+(1,86,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(1,87,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(2,52,'2004-03-15','2004-10-01','2004-03-15','2004-09-17',''),
+(2,53,'2004-03-16','2004-10-01','2004-03-16','2004-09-17',''),
+(2,88,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(2,89,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(3,51,'2004-02-09','2010-01-01','2004-02-09','2004-02-09',''),
+(5,12,'2004-02-18','2010-01-01','2004-02-18','2004-02-18','');
+CREATE TABLE t2 (
+userId int(11) NOT NULL,
+courseId int(11) NOT NULL,
+date datetime NOT NULL
+);
+INSERT INTO t2 VALUES (5141,71,'2003-11-18'),
+(5141,72,'2003-11-25'),(5141,41,'2004-08-06'),
+(5141,52,'2004-08-06'),(5141,53,'2004-08-06'),
+(5141,12,'2004-08-06'),(5141,86,'2004-10-21'),
+(5141,87,'2004-10-21'),(5141,88,'2004-10-21'),
+(5141,89,'2004-10-22'),(5141,51,'2004-10-26');
+CREATE TABLE t3 (
+groupId int(11) NOT NULL,
+parentId int(11) NOT NULL,
+startDate datetime NOT NULL,
+endDate datetime NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL,
+ordering int(11)
+);
+INSERT INTO t3 VALUES (12,9,'1000-01-01','3999-12-31','2004-01-29','2004-01-29',NULL);
+CREATE TABLE t4 (
+id int(11) NOT NULL,
+groupTypeId int(11) NOT NULL,
+groupKey varchar(50) NOT NULL,
+name text,
+ordering int(11),
+description text,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL
+);
+INSERT INTO t4 VALUES (9,5,'stationer','stationer',0,'Stationer','2004-01-29','2004-01-29'),
+(12,5,'group2','group2',0,'group2','2004-01-29','2004-01-29');
+CREATE TABLE t5 (
+userId int(11) NOT NULL,
+groupId int(11) NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL
+);
+INSERT INTO t5 VALUES (5141,12,'2004-08-06','2004-08-06');
+select
+count(distinct t2.userid) pass,
+groupstuff.*,
+count(t2.courseid) crse,
+t1.categoryid,
+t2.courseid,
+date_format(date, '%b%y') as colhead
+from t2
+join t1 on t2.courseid=t1.courseid
+join
+(
+select
+t5.userid,
+parentid,
+parentgroup,
+childid,
+groupname,
+grouptypeid
+from t5
+join
+(
+select t4.id as parentid,
+t4.name as parentgroup,
+t4.id as childid,
+t4.name as groupname,
+t4.grouptypeid
+from t4
+) as gin on t5.groupid=gin.childid
+) as groupstuff on t2.userid = groupstuff.userid
+group by
+groupstuff.groupname, colhead , t2.courseid;
+pass userid parentid parentgroup childid groupname grouptypeid crse categoryid courseid colhead
+1 5141 12 group2 12 group2 5 1 5 12 Aug04
+1 5141 12 group2 12 group2 5 1 1 41 Aug04
+1 5141 12 group2 12 group2 5 1 2 52 Aug04
+1 5141 12 group2 12 group2 5 1 2 53 Aug04
+1 5141 12 group2 12 group2 5 1 3 51 Oct04
+1 5141 12 group2 12 group2 5 1 1 86 Oct04
+1 5141 12 group2 12 group2 5 1 1 87 Oct04
+1 5141 12 group2 12 group2 5 1 2 88 Oct04
+1 5141 12 group2 12 group2 5 1 2 89 Oct04
+drop table t1, t2, t3, t4, t5;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SELECT 1 FROM t1 WHERE (SELECT 1) in (SELECT 1);
+1
+1
+1
+1
+drop table t1;
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(2);
+insert into t2 values (0),(1),(2),(3);
+select a from t2 where a in (select a from t1);
+a
+1
+2
+select a from t2 having a in (select a from t1);
+a
+1
+2
+prepare stmt1 from "select a from t2 where a in (select a from t1)";
+execute stmt1;
+a
+1
+2
+execute stmt1;
+a
+1
+2
+deallocate prepare stmt1;
+prepare stmt1 from "select a from t2 having a in (select a from t1)";
+execute stmt1;
+a
+1
+2
+execute stmt1;
+a
+1
+2
+deallocate prepare stmt1;
+drop table t1, t2;
+create table t1 (a int, b int);
+insert into t1 values (1,2);
+select 1 = (select * from t1);
+ERROR 21000: Operand should contain 1 column(s)
+select (select * from t1) = 1;
+ERROR 21000: Operand should contain 2 column(s)
+select (1,2) = (select a from t1);
+ERROR 21000: Operand should contain 2 column(s)
+select (select a from t1) = (1,2);
+ERROR 21000: Operand should contain 1 column(s)
+select (1,2,3) = (select * from t1);
+ERROR 21000: Operand should contain 3 column(s)
+select (select * from t1) = (1,2,3);
+ERROR 21000: Operand should contain 2 column(s)
+drop table t1;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+set @tmp11867_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin_with_cache=off';
+CREATE TABLE t1 (one int, two int, flag char(1));
+CREATE TABLE t2 (one int, two int, flag char(1));
+INSERT INTO t1 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+INSERT INTO t2 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+SELECT * FROM t1
+WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t2 WHERE flag = 'N');
+one two flag
+5 6 N
+7 8 N
+SELECT * FROM t1
+WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t1 WHERE flag = 'N');
+one two flag
+5 6 N
+7 8 N
+insert into t2 values (null,null,'N');
+insert into t2 values (null,3,'0');
+insert into t2 values (null,5,'0');
+insert into t2 values (10,null,'0');
+insert into t1 values (10,3,'0');
+insert into t1 values (10,5,'0');
+insert into t1 values (10,10,'0');
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N') as 'test' from t1;
+one two test
+1 2 NULL
+2 3 NULL
+3 4 NULL
+5 6 1
+7 8 1
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
+one two
+5 6
+7 8
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N' group by one,two) as 'test' from t1;
+one two test
+1 2 NULL
+2 3 NULL
+3 4 NULL
+5 6 1
+7 8 1
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0') as 'test' from t1;
+one two test
+1 2 0
+2 3 NULL
+3 4 0
+5 6 0
+7 8 0
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
+one two test
+1 2 0
+2 3 NULL
+3 4 0
+5 6 0
+7 8 0
+10 3 NULL
+10 5 NULL
+10 10 NULL
+explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0') as 'test' from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
+explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where (`test`.`t2`.`flag` = 'N')
+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
+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`
+DROP TABLE t1,t2;
+set optimizer_switch=@tmp11867_optimizer_switch;
+CREATE TABLE t1 (a char(5), b char(5));
+INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
+SELECT * FROM t1 WHERE (a,b) IN (('aaa','aaa'), ('aaa','bbb'));
+a b
+aaa aaa
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int, b int);
+CREATE TABLE t3 (b int NOT NULL);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+INSERT INTO t2 VALUES (1,10), (3,30);
+SELECT * FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10;
+a b b
+SELECT * FROM t1
+WHERE t1.a NOT IN (SELECT a FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10);
+a
+1
+2
+3
+4
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (f1 INT);
+CREATE TABLE t2 (f2 INT);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2);
+f1
+1
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE 1=0);
+f1
+1
+INSERT INTO t2 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE f2=0);
+f1
+1
+DROP TABLE t1, t2;
+select 1 from dual where 1 < any (select 2);
+1
+1
+select 1 from dual where 1 < all (select 2);
+1
+1
+select 1 from dual where 2 > any (select 1);
+1
+1
+select 1 from dual where 2 > all (select 1);
+1
+1
+select 1 from dual where 1 < any (select 2 from dual);
+1
+1
+select 1 from dual where 1 < all (select 2 from dual where 1!=1);
+1
+1
+create table t1 (s1 char);
+insert into t1 values (1),(2);
+select * from t1 where (s1 < any (select s1 from t1));
+s1
+1
+select * from t1 where not (s1 < any (select s1 from t1));
+s1
+2
+select * from t1 where (s1 < ALL (select s1+1 from t1));
+s1
+1
+select * from t1 where not(s1 < ALL (select s1+1 from t1));
+s1
+2
+select * from t1 where (s1+1 = ANY (select s1 from t1));
+s1
+1
+select * from t1 where NOT(s1+1 = ANY (select s1 from t1));
+s1
+2
+select * from t1 where (s1 = ALL (select s1/s1 from t1));
+s1
+1
+select * from t1 where NOT(s1 = ALL (select s1/s1 from t1));
+s1
+2
+drop table t1;
+create table t1 (
+retailerID varchar(8) NOT NULL,
+statusID int(10) unsigned NOT NULL,
+changed datetime NOT NULL,
+UNIQUE KEY retailerID (retailerID, statusID, changed)
+);
+INSERT INTO t1 VALUES("0026", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0026", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0037", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50");
+INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50");
+select * from t1 r1
+where (r1.retailerID,(r1.changed)) in
+(SELECT r2.retailerId,(max(changed)) from t1 r2
+group by r2.retailerId);
+retailerID statusID changed
+0026 2 2006-01-06 12:25:53
+0037 2 2006-01-06 12:25:53
+0048 1 2006-01-06 12:37:50
+0059 1 2006-01-06 12:37:50
+drop table t1;
+create table t1(a int, primary key (a));
+insert into t1 values (10);
+create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b));
+insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989');
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using where
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+a a b
+10 3 35989
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+a a b
+10 1 359
+drop table t1,t2;
+CREATE TABLE t1 (
+field1 int NOT NULL,
+field2 int NOT NULL,
+field3 int NOT NULL,
+PRIMARY KEY (field1,field2,field3)
+);
+CREATE TABLE t2 (
+fieldA int NOT NULL,
+fieldB int NOT NULL,
+PRIMARY KEY (fieldA,fieldB)
+);
+INSERT INTO t1 VALUES
+(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
+INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
+SELECT field1, field2, COUNT(*)
+FROM t1 GROUP BY field1, field2;
+field1 field2 COUNT(*)
+1 1 2
+1 2 3
+1 3 1
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) >= ALL (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 2
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) < ANY (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 1
+1 3
+DROP TABLE t1, t2;
+CREATE TABLE t1(a int, INDEX (a));
+INSERT INTO t1 VALUES (1), (3), (5), (7);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES (1),(2),(3);
+EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3
+2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using index; Full scan on NULL key
+SELECT a, a IN (SELECT a FROM t1) FROM t2;
+a a IN (SELECT a FROM t1)
+1 1
+2 NULL
+3 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a DATETIME);
+INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
+CREATE TABLE t2 AS SELECT
+(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a
+FROM t1 WHERE a > '2000-01-01';
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `sub_a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01');
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) > 0;
+a
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+a
+1
+2
+EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2), (4), (1), (3);
+CREATE TABLE t2 (b int, c int);
+INSERT INTO t2 VALUES
+(2,1), (1,3), (2,1), (4,4), (2,2), (1,4);
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2 );
+a
+2
+4
+1
+3
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a;
+a
+1
+2
+3
+4
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1), a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2);
+b MAX(c)
+1 4
+2 2
+4 4
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+1
+2
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+1
+2
+3
+4
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+1
+2
+3
+4
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1,t2;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+insert into t1 values(2.2);
+select * from t1 where df <= all (select avg(df) from t1 group by df);
+df
+1.1
+select * from t1 where df >= all (select avg(df) from t1 group by df);
+df
+2.2
+drop table t1;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+select 1.1 * exists(select * from t1);
+1.1 * exists(select * from t1)
+1.1
+drop table t1;
+CREATE TABLE t1 (
+grp int(11) default NULL,
+a decimal(10,2) default NULL);
+insert into t1 values (1, 1), (2, 2), (2, 3), (3, 4), (3, 5), (3, 6), (NULL, NULL);
+select * from t1;
+grp a
+1 1.00
+2 2.00
+2 3.00
+3 4.00
+3 5.00
+3 6.00
+NULL NULL
+select min(a) from t1 group by grp;
+min(a)
+NULL
+1.00
+2.00
+4.00
+drop table t1;
+CREATE table t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2 WHERE c2 IN (1);
+c1 c2
+1 1
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE c2 IN ( SELECT c2 FROM t2 WHERE c2 IN ( 1 ) );
+c1 c2
+1 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+INSERT INTO t1 VALUES ( 6 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+INSERT INTO t2 VALUES ( 6 );
+CREATE TABLE t3 ( c3 integer );
+INSERT INTO t3 VALUES ( 7 );
+INSERT INTO t3 VALUES ( 8 );
+SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL );
+c1 c2
+2 NULL
+3 NULL
+DROP TABLE t1,t2,t3;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+CREATE TABLE t1 (EMPNUM CHAR(3));
+CREATE TABLE t2 (EMPNUM CHAR(3) );
+INSERT INTO t1 VALUES ('E1'),('E2');
+INSERT INTO t2 VALUES ('E1');
+DELETE FROM t1
+WHERE t1.EMPNUM NOT IN
+(SELECT t2.EMPNUM
+FROM t2
+WHERE t1.EMPNUM = t2.EMPNUM);
+select * from t1;
+EMPNUM
+E1
+DROP TABLE t1,t2;
+CREATE TABLE t1(select_id BIGINT, values_id BIGINT);
+INSERT INTO t1 VALUES (1, 1);
+CREATE TABLE t2 (select_id BIGINT, values_id BIGINT,
+PRIMARY KEY(select_id,values_id));
+INSERT INTO t2 VALUES (0, 1), (0, 2), (0, 3), (1, 5);
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id IN (1, 0));
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id BETWEEN 0 AND 1);
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id = 0 OR select_id = 1);
+values_id
+1
+DROP TABLE t1, t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (c int, d int);
+CREATE TABLE t3 (e int);
+INSERT INTO t1 VALUES
+(1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40);
+INSERT INTO t2 VALUES
+(2,10), (2,20), (4,10), (5,10), (3,20), (2,40);
+INSERT INTO t3 VALUES (10), (30), (10), (20) ;
+SELECT a, MAX(b), MIN(b) FROM t1 GROUP BY a;
+a MAX(b) MIN(b)
+1 20 10
+2 30 10
+3 20 20
+4 40 40
+SELECT * FROM t2;
+c d
+2 10
+2 20
+4 10
+5 10
+3 20
+2 40
+SELECT * FROM t3;
+e
+10
+30
+10
+20
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>20);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)<d);
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>d);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d >= SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d > SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e < d));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE MIN(b) < d AND
+EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+SELECT a, SUM(a) FROM t1 GROUP BY a;
+a SUM(a)
+1 2
+2 6
+3 3
+4 4
+SELECT a FROM t1
+WHERE EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c) GROUP BY a;
+a
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c);
+a
+1
+3
+4
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c) GROUP BY a;
+a
+1
+2
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c);
+a
+1
+2
+1
+2
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a < ALL(SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+1
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3
+WHERE SUM(t1.a+t2.c) < t3.e/4));
+ERROR HY000: Invalid use of group function
+SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20;
+ERROR HY000: Invalid use of group function
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(t2.c+SUM(t1.b)) > 20);
+a
+2
+3
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(SUM(t1.b)) > 20);
+a
+2
+4
+SELECT t1.a, SUM(b) AS sum FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING t2.c+sum > 20);
+a sum
+2 60
+3 20
+4 40
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a varchar(5), b varchar(10));
+INSERT INTO t1 VALUES
+('AAA', 5), ('BBB', 4), ('BBB', 1), ('CCC', 2),
+('CCC', 7), ('AAA', 2), ('AAA', 4), ('BBB', 3), ('AAA', 8);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
+ALTER TABLE t1 ADD INDEX(a);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL a NULL NULL NULL 9 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
+DROP TABLE t1;
+create table t1( f1 int,f2 int);
+insert into t1 values (1,1),(2,2);
+select tt.t from (select 'crash1' as t, f2 from t1) as tt left join t1 on tt.t = 'crash2' and tt.f2 = t1.f2 where tt.t = 'crash1';
+t
+crash1
+crash1
+drop table t1;
+create table t1 (c int, key(c));
+insert into t1 values (1142477582), (1142455969);
+create table t2 (a int, b int);
+insert into t2 values (2, 1), (1, 0);
+delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
+drop table t1, t2;
+CREATE TABLE t1 (a INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'IN/ALL/ANY subquery'
+DROP TABLE t1;
+create table t1 (i int, j bigint);
+insert into t1 values (1, 2), (2, 2), (3, 2);
+select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
+min(i)
+1
+drop table t1;
+CREATE TABLE t1 (i BIGINT UNSIGNED);
+INSERT INTO t1 VALUES (10000000000000000000);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (i BIGINT UNSIGNED);
+INSERT INTO t2 VALUES (10000000000000000000);
+INSERT INTO t2 VALUES (1);
+/* simple test */
+SELECT t1.i FROM t1 JOIN t2 ON t1.i = t2.i;
+i
+10000000000000000000
+1
+/* subquery test */
+SELECT t1.i FROM t1 WHERE t1.i = (SELECT MAX(i) FROM t2);
+i
+10000000000000000000
+/* subquery test with cast*/
+SELECT t1.i FROM t1 WHERE t1.i = CAST((SELECT MAX(i) FROM t2) AS UNSIGNED);
+i
+10000000000000000000
+DROP TABLE t1;
+DROP TABLE t2;
+CREATE TABLE t1 (
+id bigint(20) unsigned NOT NULL auto_increment,
+name varchar(255) NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES
+(1, 'Balazs'), (2, 'Joe'), (3, 'Frank');
+CREATE TABLE t2 (
+id bigint(20) unsigned NOT NULL auto_increment,
+mid bigint(20) unsigned NOT NULL,
+date date NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t2 VALUES
+(1, 1, '2006-03-30'), (2, 2, '2006-04-06'), (3, 3, '2006-04-13'),
+(4, 2, '2006-04-20'), (5, 1, '2006-05-01');
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 3, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 NULL
+2 Joe 2006-04-20 NULL
+3 Frank 2006-04-13 NULL
+SELECT *,
+(SELECT COUNT(*) FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_count
+FROM t1;
+id name date_count
+1 Balazs NULL
+2 Joe NULL
+3 Frank NULL
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 2006-03-30
+2 Joe 2006-04-20 2006-04-06
+3 Frank 2006-04-13 NULL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime NOT NULL default '0000-00-00 00:00:00',
+PRIMARY KEY (i1,i2,t)
+);
+INSERT INTO t1 VALUES
+(24,1,'2005-03-03 16:31:31'),(24,1,'2005-05-27 12:40:07'),
+(24,1,'2005-05-27 12:40:08'),(24,1,'2005-05-27 12:40:10'),
+(24,1,'2005-05-27 12:40:25'),(24,1,'2005-05-27 12:40:30'),
+(24,2,'2005-03-03 13:43:05'),(24,2,'2005-03-03 16:23:31'),
+(24,2,'2005-03-03 16:31:30'),(24,2,'2005-05-27 12:37:02'),
+(24,2,'2005-05-27 12:40:06');
+CREATE TABLE t2 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime default NULL,
+PRIMARY KEY (i1)
+);
+INSERT INTO t2 VALUES (24,1,'2006-06-20 12:29:40');
+EXPLAIN
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index
+2 DEPENDENT SUBQUERY t1 range PRIMARY PRIMARY 16 NULL 5 Using where; Using index
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+i1 i2 t i1 i2 t
+24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b));
+insert into t1 (a) values (FLOOR(rand() * 100));
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+SELECT a,
+(SELECT REPEAT(' ',250) FROM t1 i1
+WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a
+FROM t1 ORDER BY a LIMIT 5;
+a a
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 values (1);
+INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4);
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2)
+2
+1
+1
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+2
+1
+1
+SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b))
+2 2
+1 1
+1 1
+SELECT COUNT(DISTINCT t1.b),
+(SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+2 2
+1 1
+1 1
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a;
+(
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+2
+1
+1
+SELECT (
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+FROM t1 t2
+GROUP BY t2.a;
+(
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+2
+2
+2
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (b));
+CREATE TABLE t2 (x int auto_increment, y int, z int,
+PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1 select RAND()*1000, A.a + 10*(B.a+10*(C.a+10*D.a))
+from t3 A, t3 B, t3 C, t3 D where D.a<3;
+insert into t2(y,z) select t1.b, RAND()*1000 from t1, t3;
+SET SESSION sort_buffer_size = 32 * 1024;
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+SET SESSION sort_buffer_size = 8 * 1024 * 1024;
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
+CREATE TABLE t2 (c int);
+INSERT INTO t1 VALUES ('aa', 1);
+INSERT INTO t2 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+INSERT INTO t1 VALUES ('bb', 2), ('cc', 3), ('dd',1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+INSERT INTO t2 VALUES (2);
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT t2.c FROM t2 JOIN t3 ON t2.c=t3.c WHERE t2.c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1(f1 int);
+CREATE TABLE t2(f2 int, f21 int, f3 timestamp);
+INSERT INTO t1 VALUES (1),(1),(2),(2);
+INSERT INTO t2 VALUES (1,1,"2004-02-29 11:11:11"), (2,2,"2004-02-29 11:11:11");
+SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1;
+sq
+2
+4
+SELECT (SELECT SUM(1) FROM t2 ttt GROUP BY t2.f3 LIMIT 1) AS tt FROM t2;
+tt
+2
+2
+PREPARE stmt1 FROM 'SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1';
+EXECUTE stmt1;
+sq
+2
+4
+EXECUTE stmt1;
+sq
+2
+4
+DEALLOCATE PREPARE stmt1;
+SELECT f2, AVG(f21),
+(SELECT t.f3 FROM t2 AS t WHERE t2.f2=t.f2 AND t.f3=MAX(t2.f3)) AS test
+FROM t2 GROUP BY f2;
+f2 AVG(f21) test
+1 1.0000 2004-02-29 11:11:11
+2 2.0000 2004-02-29 11:11:11
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL);
+INSERT INTO t1 VALUES
+(1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
+(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'),
+(3,2,'k'), (3,1,'l'), (1,9,'m');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t1xt2;
+CREATE TABLE t1 (
+id_1 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t2 (
+id_2 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t1xt2 (
+id_1 int(5) NOT NULL,
+id_2 int(5) NOT NULL
+);
+INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
+INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
+INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+3
+4
+insert INTO t1xt2 VALUES (1, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+2
+3
+4
+insert INTO t1xt2 VALUES (2, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+3
+4
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t1xt2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (3), (1), (2);
+SELECT 'this is ' 'a test.' AS col1, a AS col2 FROM t1;
+col1 col2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+SELECT * FROM (SELECT 'this is ' 'a test.' AS col1, a AS t2 FROM t1) t;
+col1 t2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+DROP table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*), a,
+(SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a,
+(SELECT MIN(m) FROM t2 WHERE m = count(*))
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT MIN(m) FROM t2 WHERE m = count(*))
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a
+FROM t1 GROUP BY a
+HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1;
+COUNT(*) a
+2 2
+3 3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+2 2 2
+3 3 3
+1 4 1,1
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+2 2 3
+3 3 4
+1 4 2,2
+DROP table t1,t2;
+CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
+INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'),
+(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'),
+(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a x, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+x MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a, AVG(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test
+FROM t1 WHERE t1.d=0 GROUP BY a;
+a AVG(b) test
+1 4.0000 d
+2 2.0000 g
+3 2.5000 NULL
+SELECT tt.a,
+(SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt;
+a test
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+2 o
+2 o
+2 o
+2 o
+3 p
+3 p
+3 p
+3 p
+3 p
+SELECT tt.a,
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+SELECT tt.a, MAX(
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+a
+1
+2
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+a
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+a
+1
+2
+SET @@sql_mode='ansi';
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+ERROR HY000: Invalid use of group function
+SET @@sql_mode=default;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 values (1),(1),(1),(1);
+CREATE TABLE t2 (x INT);
+INSERT INTO t1 values (1000),(1001),(1002);
+SELECT SUM( (SELECT COUNT(a) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT SUM( (SELECT SUM(COUNT(a)) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT COUNT(1) FROM DUAL;
+COUNT(1)
+1
+SELECT SUM( (SELECT AVG( (SELECT t1.a FROM t2) ) FROM DUAL) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING t1.a < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT t1.a as XXA,
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, KEY (a));
+INSERT INTO t1 VALUES (1,1),(2,1);
+EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref a a 5 const 0 Using where; Using index
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+DROP TABLE t1;
+CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
+INSERT INTO t1 VALUES
+(3,'FL'), (2,'GA'), (4,'FL'), (1,'GA'), (5,'NY'), (7,'FL'), (6,'NY');
+CREATE TABLE t2 (id int NOT NULL, INDEX idx(id));
+INSERT INTO t2 VALUES (7), (5), (1), (3);
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+3 FL
+1 GA
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+1 GA
+3 FL
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+2 GA
+4 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+2 GA
+4 FL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT count(*) FROM t1 GROUP BY a) as res;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `res`.`count(*)` AS `count(*)` from (select count(0) AS `count(*)` from `test`.`t1` group by `test`.`t1`.`a`) `res`
+DROP TABLE t1;
+CREATE TABLE t1 (
+a varchar(255) default NULL,
+b timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+INDEX idx(a,b)
+);
+CREATE TABLE t2 (
+a varchar(255) default NULL
+);
+INSERT INTO t1 VALUES ('abcdefghijk','2007-05-07 06:00:24');
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26');
+INSERT INTO `t2` VALUES ('abcdefghijk');
+INSERT INTO `t2` VALUES ('asdf');
+SET session sort_buffer_size=8192;
+SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
+d1
+1
+1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INTEGER, b INTEGER);
+CREATE TABLE t2 (x INTEGER);
+INSERT INTO t1 VALUES (1,11), (2,22), (2,22);
+INSERT INTO t2 VALUES (1), (2);
+SELECT a, COUNT(b), (SELECT COUNT(b) FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a, COUNT(b), (SELECT COUNT(b)+0 FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a)/AVG(t2.x) FROM t2) FROM t1;
+(SELECT SUM(t1.a)/AVG(t2.x) FROM t2)
+3.3333
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1, 2), (1,3), (1,4), (2,1), (2,2);
+SELECT a1.a, COUNT(*) FROM t1 a1 WHERE a1.a = 1
+AND EXISTS( SELECT a2.a FROM t1 a2 WHERE a2.a = a1.a)
+GROUP BY a1.a;
+a COUNT(*)
+1 3
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+INSERT INTO t2 VALUES (1),(2);
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=0) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=0)
+NULL
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a!=0) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=1) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=1)
+3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a1 INT, a2 INT);
+CREATE TABLE t2 (b1 INT, b2 INT);
+INSERT INTO t1 VALUES (100, 200);
+INSERT INTO t1 VALUES (101, 201);
+INSERT INTO t2 VALUES (101, 201);
+INSERT INTO t2 VALUES (103, 203);
+SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1;
+((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL
+0
+0
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5));
+INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+CREATE INDEX I1 ON t1 (s1);
+CREATE INDEX I2 ON t1 (s2);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+TRUNCATE t1;
+INSERT INTO t1 VALUES (0x41,0x41);
+SELECT * FROM t1 WHERE s1 = (SELECT s2 FROM t1);
+s1 s2
+DROP TABLE t1;
+CREATE TABLE t1 (a1 VARBINARY(2) NOT NULL DEFAULT '0', PRIMARY KEY (a1));
+CREATE TABLE t2 (a2 BINARY(2) default '0', INDEX (a2));
+CREATE TABLE t3 (a3 BINARY(2) default '0');
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+INSERT INTO t3 VALUES (1),(2),(3);
+SELECT LEFT(t2.a2, 1) FROM t2,t3 WHERE t3.a3=t2.a2;
+LEFT(t2.a2, 1)
+1
+2
+3
+SELECT t1.a1, t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2) FROM t1;
+a1 t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2)
+1 0
+2 0
+3 0
+4 0
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a1 BINARY(3) PRIMARY KEY, b1 VARBINARY(3));
+CREATE TABLE t2 (a2 VARBINARY(3) PRIMARY KEY);
+CREATE TABLE t3 (a3 VARBINARY(3) PRIMARY KEY);
+INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40);
+INSERT INTO t2 VALUES (2), (3), (4), (5);
+INSERT INTO t3 VALUES (10), (20), (30);
+SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3;
+LEFT(t1.a1,1)
+1
+2
+3
+SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
+a2
+DROP TABLE t1, t2, t3;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+SET optimizer_switch='materialization=off';
+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;
+SET optimizer_switch= @save_optimizer_switch;
+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);
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
+Warnings:
+Note 1003 select 1 AS `1` from <materialize> (select min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (`<subquery2>`.`min(a)` = 1)
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 WHERE a > 3 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
+Warnings:
+Note 1003 select 1 AS `1` from <materialize> (select min(`test`.`t1`.`a`) from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a`) join `test`.`t1` where (`<subquery2>`.`min(a)` = 1)
+SET join_cache_level=@save_join_cache_level;
+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 NULL
+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;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+EXPLAIN EXTENDED
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+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 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <nop>(<in_optimizer>(1,((select max(`test`.`t1`.`a1`) from `test`.`t1`) > 1)))
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+1
+1
+1
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1, t2;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
+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
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
+INSERT INTO t1 VALUES (1,NULL), (9,NULL);
+CREATE TABLE t2 (
+a INT,
+b INT,
+c INT,
+d INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c,d),
+KEY b_2 (b),
+KEY c (c),
+KEY d (d)
+);
+INSERT INTO t2 VALUES
+(43, 2, 11 ,30),
+(44, 2, 12 ,30),
+(45, 1, 1 ,10000),
+(46, 1, 2 ,10000),
+(556,1, 32 ,10000);
+CREATE TABLE t3 (
+a INT,
+b INT,
+c INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c),
+KEY c (c),
+KEY b_2 (b)
+);
+INSERT INTO t3 VALUES (1,1,1), (2,32,1);
+explain
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 PRIMARY t3 ref b,b_2 b 5 test.t1.a 1 Using index
+2 DEPENDENT SUBQUERY t2 ref b,b_2,c b 10 test.t3.c,test.t1.a 1 Using where; Using index; Using filesort
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+a incorrect
+1 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int, c int);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+CREATE VIEW v1 AS
+SELECT t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+UPDATE v1 SET c=1;
+CREATE VIEW v2 (a,b) AS
+SELECT t2.id, t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+INSERT INTO v2(a,b) VALUES (2,2);
+ERROR HY000: CHECK OPTION failed 'test.v2'
+SELECT * FROM v1;
+c
+1
+1
+1
+1
+CREATE VIEW v3 AS
+SELECT t2.c AS c FROM t2
+WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+DELETE FROM v3;
+DROP VIEW v1,v2,v3;
+DROP TABLE t1,t2;
+#
+# BUG#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+#
+# Bug#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+CREATE TABLE t1 (a ENUM('rainbow'));
+INSERT INTO t1 VALUES (),(),(),(),();
+SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
+1
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGBLOB);
+INSERT INTO t1 SET a = 'aaaa';
+INSERT INTO t1 SET a = 'aaaa';
+SELECT 1 FROM t1 GROUP BY
+(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
+1
+1
+DROP TABLE t1;
+#
+# Bug #49512 : subquery with aggregate function crash
+# subselect_single_select_engine::exec()
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES();
+# should not crash
+SELECT 1 FROM t1 WHERE a <> SOME
+(
+SELECT MAX((SELECT a FROM t1 LIMIT 1)) AS d
+FROM t1,t1 a
+);
+1
+DROP TABLE t1;
+#
+# Bug #45989 take 2 : memory leak after explain encounters an
+# error in the query
+#
+CREATE TABLE t1(a LONGTEXT);
+INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet));
+INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet));
+EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1,
+(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) AS d1
+WHERE t1.a = d1.a;
+ERROR 42S22: Unknown column 'd1.a' in 'where clause'
+DROP TABLE t1;
+Set up test tables.
+CREATE TABLE t1 (
+t1_id INT UNSIGNED,
+PRIMARY KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t1 (t1_id) VALUES (1), (2), (3), (4), (5);
+CREATE TABLE t2 SELECT * FROM t1;
+CREATE TABLE t3 (
+t3_id INT UNSIGNED AUTO_INCREMENT,
+t1_id INT UNSIGNED,
+amount DECIMAL(16,2),
+PRIMARY KEY(t3_id),
+KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t3 (t1_id, t3_id, amount)
+VALUES (1, 1, 100.00), (2, 2, 200.00), (4, 4, 400.00);
+This is the 'inner query' running by itself.
+Produces correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query)
+Produces correct results.
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+Now make t2.t1_id part of a key.
+ALTER TABLE t2 ADD PRIMARY KEY(t1_id);
+Same inner query by itself.
+Still correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query), now with indexes on the LEFT JOIN
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+DROP TABLE t3;
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# Bug #52711: Segfault when doing EXPLAIN SELECT with
+# union...order by (select... where...)
+#
+CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a));
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (1),(2);
+# Should not crash
+EXPLAIN
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+# Should not crash
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+DROP TABLE t1,t2;
+# LP BUG#675248 - select->prep_where references on freed memory
+CREATE TABLE t1 (a int, b int);
+insert into t1 values (1,1),(0,0);
+CREATE TABLE t2 (c int);
+insert into t2 values (1),(2);
+prepare stmt1 from "select sum(a),(select sum(c) from t2 where table1.b) as sub
+from t1 as table1 group by sub";
+execute stmt1;
+sum(a) sub
+0 NULL
+1 3
+deallocate prepare stmt1;
+prepare stmt1 from "select sum(a),(select sum(c) from t2 having table1.b) as sub
+from t1 as table1";
+execute stmt1;
+sum(a) sub
+1 3
+deallocate prepare stmt1;
+drop table t1,t2;
+#
+# Bug LP#693935/#58727: Assertion failure with
+# a single row subquery returning more than one row
+#
+create table t1 (a char(1) charset utf8);
+insert into t1 values ('a'), ('b');
+create table t2 (a binary(1));
+insert into t2 values ('x'), ('y');
+select * from t2 where a=(select a from t1) and a='x';
+ERROR 21000: Subquery returns more than 1 row
+drop table t1,t2;
+End of 5.1 tests
+#
+# No BUG#, a case brought from 5.2's innodb_mysql_lock.test
+#
+create table t1 (i int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+create table t2 (j int not null primary key);
+insert into t2 values (1),(2),(3),(4),(5);
+create table t3 (k int not null primary key);
+insert into t3 values (1),(2),(3);
+create view v2 as select t2.j as j from t2 where t2.j in (select t1.i from t1);
+select * from t3 where k in (select j from v2);
+k
+1
+2
+3
+drop table t1,t2,t3;
+drop view v2;
+#
+# Bug#52068: Optimizer generates invalid semijoin materialization plan
+#
+drop table if exists ot1, ot2, it1, it2;
+CREATE TABLE ot1(a INTEGER);
+INSERT INTO ot1 VALUES(5), (8);
+CREATE TABLE it2(a INTEGER);
+INSERT INTO it2 VALUES(9), (5), (1), (8);
+CREATE TABLE it3(a INTEGER);
+INSERT INTO it3 VALUES(7), (1), (0), (5), (1), (4);
+CREATE TABLE ot4(a INTEGER);
+INSERT INTO ot4 VALUES(1), (3), (5), (7), (9), (7), (3), (1);
+SELECT * FROM ot1,ot4
+WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
+FROM it2,it3);
+a a
+5 1
+8 1
+5 5
+8 5
+5 7
+8 7
+5 7
+8 7
+5 1
+8 1
+explain SELECT * FROM ot1,ot4
+WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
+FROM it2,it3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 2
+1 PRIMARY ot4 ALL NULL NULL NULL NULL 8 Using join buffer (flat, BNL join)
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED it2 ALL NULL NULL NULL NULL 4
+2 MATERIALIZED it3 ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
+DROP TABLE IF EXISTS ot1, ot4, it2, it3;
+#
+# Bug#729039: NULL keys used to evaluate subquery
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (NULL), (1), (NULL), (2);
+CREATE TABLE t2 (a int, INDEX idx(a)) ;
+INSERT INTO t2 VALUES (NULL), (1), (NULL);
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a);
+a
+1
+EXPLAIN
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+a
+1
+EXPLAIN
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
+DROP TABLE t1,t2;
+#
+# BUG#752992: Wrong results for a subquery with 'semijoin=on'
+#
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
+EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 3
+1 PRIMARY it eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index
+1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; FirstMatch(it)
+SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+pk i
+11 0
+12 5
+15 0
+SET join_cache_level=@save_join_cache_level;
+DROP table t1,t2;
+#
+# Bug#751350: crash with pushed condition for outer references when
+# there should be none of such conditions
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0),(0,0);
+set @optimizer_switch_save=@@optimizer_switch;
+set @@optimizer_switch='semijoin=off,materialization=on,in_to_exists=on';
+EXPLAIN
+SELECT b FROM t1
+WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT b FROM t1
+WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+GROUP BY b;
+b
+0
+set @@optimizer_switch=@optimizer_switch_save;
+DROP TABLE t1;
+#
+# Bug #11765713 58705:
+# OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES
+# CREATED BY OPT_SUM_QUERY
+#
+CREATE TABLE t1(a INT NOT NULL, KEY (a));
+INSERT INTO t1 VALUES (0), (1);
+SELECT 1 as foo FROM t1 WHERE a < SOME
+(SELECT a FROM t1 WHERE a <=>
+(SELECT a FROM t1)
+);
+ERROR 21000: Subquery returns more than 1 row
+SELECT 1 as foo FROM t1 WHERE a < SOME
+(SELECT a FROM t1 WHERE a <=>
+(SELECT a FROM t1 where a is null)
+);
+foo
+DROP TABLE t1;
+CREATE TABLE t1 (a int(11), b varchar(1));
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+delete from t1;
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+drop table t1;
+#
+# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3)) ;
+INSERT IGNORE INTO t2 VALUES (NULL,NULL),(5,0);
+DROP TABLE IF EXISTS t3;
+Warnings:
+Note 1051 Unknown table 't3'
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ;
+r
+NULL
+5
+NULL
+5
+DROP TABLE t1, t2, t3;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+1
+1
+1
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1, t2;
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
+#
+# BUG#50257: Missing info in REF column of the EXPLAIN
+# lines for subselects
+#
+CREATE TABLE t1 (a INT, b INT, INDEX (a));
+INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref a a 5 const 1
+EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 SUBQUERY t1 ref a a 5 const 1 Using index
+DROP TABLE t1;
+#
+# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS)
+# (duplicate of LP bug #888456)
+#
+CREATE TABLE t1 (f1 varchar(1));
+INSERT INTO t1 VALUES ('v'),('s');
+CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key));
+INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'),
+('d'),('y'),('t'),('d'),('s');
+EXPLAIN
+SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2
+WHERE EXISTS (SELECT DISTINCT f1_key FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY table1 ALL NULL NULL NULL NULL 2
+1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index
+SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2
+WHERE EXISTS (SELECT DISTINCT f1_key FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1);
+f1 f1_key
+v j
+s j
+v v
+s v
+v c
+s c
+v m
+s m
+v d
+s d
+v d
+s d
+v y
+s y
+v t
+s t
+v d
+s d
+v s
+s s
+DROP TABLE t1,t2;
+#
+# LP bug 919427: EXPLAIN for a query over a single-row table
+# with IN subquery in WHERE condition
+#
+CREATE TABLE ot (
+col_int_nokey int(11),
+col_varchar_nokey varchar(1)
+) ;
+INSERT INTO ot VALUES (1,'x');
+CREATE TABLE it1(
+col_int_key int(11),
+col_varchar_key varchar(1),
+KEY idx_cvk_cik (col_varchar_key,col_int_key)
+);
+INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f');
+CREATE TABLE it2 (
+col_int_key int(11),
+col_varchar_key varchar(1),
+col_varchar_key2 varchar(1),
+KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key),
+KEY idx_cvk_cik (col_varchar_key, col_int_key)
+);
+INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f');
+EXPLAIN
+SELECT col_int_nokey FROM ot
+WHERE col_varchar_nokey IN
+(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot system NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index
+SELECT col_int_nokey FROM ot
+WHERE col_varchar_nokey IN
+(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL);
+col_int_nokey
+1
+EXPLAIN
+SELECT col_int_nokey FROM ot
+WHERE (col_varchar_nokey, 'x') IN
+(SELECT col_varchar_key, col_varchar_key2 FROM it2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot system NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index
+SELECT col_int_nokey FROM ot
+WHERE (col_varchar_nokey, 'x') IN
+(SELECT col_varchar_key, col_varchar_key2 FROM it2);
+col_int_nokey
+1
+DROP TABLE ot,it1,it2;
+#
+# MDEV-746
+# Bug#13651009 WRONG RESULT FROM DERIVED TABLE IF THE SUBQUERY
+# HAS AN EMPTY RESULT
+#
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_int_nokey int NOT NULL,
+col_int_key int NOT NULL,
+col_time_key time 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_time_key (col_time_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM;
+CREATE TABLE t2 (
+pk int NOT NULL AUTO_INCREMENT,
+col_int_nokey int NOT NULL,
+col_int_key int NOT NULL,
+col_time_key time 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_time_key (col_time_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,4,4,'00:00:00','b','b');
+SET @var2:=4, @var3:=8;
+
+Testcase without inner subquery
+EXPLAIN SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3;
+@var3:=12 pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+SELECT @var3;
+@var3
+8
+EXPLAIN SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3 ) AS alias3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE <derived2> system NULL NULL NULL NULL 0 const row not found
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3 ) AS alias3;
+@var3:=12 pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+SELECT @var3;
+@var3
+8
+
+Testcase with inner subquery; crashed WL#6095
+SET @var3=8;
+EXPLAIN SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3));
+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 c_sq1_alias1 system PRIMARY NULL NULL NULL 1
+SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3));
+pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+EXPLAIN SELECT * FROM ( SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3)) ) AS alias3;
+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
+3 DEPENDENT SUBQUERY c_sq1_alias1 system PRIMARY NULL NULL NULL 1
+SELECT * FROM ( SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3)) ) AS alias3;
+pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+DROP TABLE t1,t2;
+End of 5.2 tests
+#
+# BUG#779885: Crash in eliminate_item_equal with materialization=on in
+#
+CREATE TABLE t1 ( f1 int );
+INSERT INTO t1 VALUES (19), (20);
+CREATE TABLE t2 ( f10 varchar(32) );
+INSERT INTO t2 VALUES ('c'),('d');
+CREATE TABLE t3 ( f10 varchar(32) );
+INSERT INTO t3 VALUES ('a'),('b');
+SELECT *
+FROM t1
+WHERE
+( 't' ) IN (
+SELECT t3.f10
+FROM t3
+JOIN t2
+ON t2.f10 = t3.f10
+);
+f1
+DROP TABLE t1,t2,t3;
+#
+# BUG LP:813473: Wrong result with outer join + NOT IN subquery
+# This bug is a duplicate of Bug#11764086 whose test case is added below
+#
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (5),(6);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (20,9),(20,9);
+create table t3 (d int, e int);
+insert into t3 values (2, 9), (3,10);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+EXPLAIN
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b , t1.c) NOT IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b, t1.c) NOT IN (SELECT * from t3);
+b c
+9 NULL
+9 NULL
+SET optimizer_switch=@save_optimizer_switch;
+drop table t1, t2, t3;
+#
+# Bug#11764086: Null left operand to NOT IN in WHERE clause
+# behaves differently than real NULL
+#
+CREATE TABLE parent (id int);
+INSERT INTO parent VALUES (1), (2);
+CREATE TABLE child (parent_id int, other int);
+INSERT INTO child VALUES (1,NULL);
+# Offending query (c.parent_id is NULL for null-complemented rows only)
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id NOT IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+);
+id parent_id
+1 1
+2 NULL
+# Some syntactic variations with IS FALSE and IS NOT TRUE
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS NOT TRUE;
+id parent_id
+1 1
+2 NULL
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS FALSE;
+id parent_id
+1 1
+2 NULL
+DROP TABLE parent, child;
+# End of test for bug#11764086.
+#
+# Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET ||
+# BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0), (1);
+CREATE TABLE t2(
+b TEXT,
+c INT,
+PRIMARY KEY (b(1))
+);
+INSERT INTO t2 VALUES ('a', 2), ('b', 3);
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ORDER BY b
+);
+1
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+GROUP BY b
+);
+1
+DROP TABLE t1, t2;
+#
+# LP bug #826279: assertion failure with GROUP BY a result of subquery
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0), (0);
+CREATE TABLE t2 (a int, b int, c int);
+INSERT INTO t2 VALUES (10,7,0), (0,7,0);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,7), (0,7);
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+7 NULL
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+7 NULL
+7 10
+DROP TABLE t1,t2,t3;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+#
+# LP BUG#833777 Performance regression with deeply nested subqueries
+#
+create table t1 (a int not null, b char(10) not null);
+insert into t1 values (1, 'a');
+set @@optimizer_switch='in_to_exists=on,semijoin=off,materialization=off,subquery_cache=off';
+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)))))))))))))))))))))))))))));
+a
+1
+set @@optimizer_switch=@subselect_tmp;
+drop table t1;
+#
+# LP BUG#894397 Wrong result with in_to_exists, constant table , semijoin=OFF,materialization=OFF
+#
+CREATE TABLE t1 (a varchar(3));
+INSERT INTO t1 VALUES ('AAA'),('BBB');
+CREATE TABLE t2 (a varchar(3));
+INSERT INTO t2 VALUES ('CCC');
+set @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquery_cache=off';
+SELECT * FROM t1 WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.a < 'ZZZ');
+a
+set @@optimizer_switch=@subselect_tmp;
+drop table t1, t2;
+#
+# LP bug #859375: Assertion `0' failed in st_select_lex_unit::optimize
+# with view , UNION and prepared statement (rewriting fake_select
+# condition).
+#
+CREATE TABLE t1 ( f1 int NOT NULL, f4 varchar(1) NOT NULL) ;
+INSERT INTO t1 VALUES (6,'d'),(7,'y');
+CREATE TABLE t2 ( f1 int NOT NULL, f2 int NOT NULL) ;
+INSERT INTO t2 VALUES (10,7);
+CREATE VIEW v2 AS SELECT * FROM t2;
+PREPARE st1 FROM "
+ SELECT *
+ FROM t1
+ LEFT JOIN v2 ON ( v2.f2 = t1.f1 )
+ WHERE v2.f1 NOT IN (
+ SELECT 1 UNION
+ SELECT 247
+ )
+";
+EXECUTE st1;
+f1 f4 f1 f2
+7 y 10 7
+deallocate prepare st1;
+DROP VIEW v2;
+DROP TABLE t1,t2;
+#
+# LP bug #887458 Crash in subselect_union_engine::no_rows with
+# double UNION and join_cache_level=3,8
+# (IN/ALL/ANY optimizations should not be applied to fake_select)
+CREATE TABLE t2 ( a int, b varchar(1)) ;
+INSERT IGNORE INTO t2 VALUES (8,'y'),(8,'y');
+CREATE TABLE t1 ( b varchar(1)) ;
+INSERT IGNORE INTO t1 VALUES (NULL),(NULL);
+set @save_join_cache_level=@@join_cache_level;
+SET SESSION join_cache_level=3;
+SELECT *
+FROM t1, t2
+WHERE t2.b IN (
+SELECT 'm' UNION
+SELECT 'm'
+) OR t1.b <> SOME (
+SELECT 'v' UNION
+SELECT 't'
+);
+b a b
+set @@join_cache_level= @save_join_cache_level;
+drop table t1,t2;
+#
+# LP bug #885162 Got error 124 from storage engine with UNION inside
+# subquery and join_cache_level=3..8
+# (IN/ALL/ANY optimizations should not be applied to fake_select)
+#
+CREATE TABLE t1 (
+f1 varchar(1) DEFAULT NULL
+);
+INSERT INTO t1 VALUES ('c');
+set @save_join_cache_level=@@join_cache_level;
+SET SESSION join_cache_level=8;
+SELECT * FROM t1 WHERE t1.f1 IN ( SELECT 'k' UNION SELECT 'e' );
+f1
+set @@join_cache_level= @save_join_cache_level;
+drop table t1;
+#
+# LP BUG#747278 incorrect values of the NULL (no rows) single
+# row subquery requested via element_index() interface
+#
+CREATE TABLE t1 (f1a int, f1b int) ;
+INSERT IGNORE INTO t1 VALUES (1,1),(2,2);
+CREATE TABLE t2 ( f2 int);
+INSERT IGNORE INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (f3a int default 1, f3b int default 2);
+INSERT INTO t3 VALUES (1,1),(2,2);
+set @old_optimizer_switch = @@session.optimizer_switch;
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,subquery_cache=off,semijoin=off';
+SELECT (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+SELECT (SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+set @@session.optimizer_switch=@old_optimizer_switch;
+SELECT (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+SELECT (SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+select (null, null) = (null, null);
+(null, null) = (null, null)
+NULL
+SELECT (SELECT f3a, f3a FROM t3 where f3a > 3) = (0, 0);
+(SELECT f3a, f3a FROM t3 where f3a > 3) = (0, 0)
+NULL
+drop tables t1,t2,t3;
+#
+# LP BUG#825051 Wrong result with date/datetime and subquery with GROUP BY and in_to_exists
+#
+CREATE TABLE t1 (a date, KEY (a)) ;
+INSERT INTO t1 VALUES ('2009-01-01'),('2009-02-02');
+set @old_optimizer_switch = @@optimizer_switch;
+SET @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index
+2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 2 Using index
+SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+a
+2009-01-01
+2009-02-02
+SET @@optimizer_switch='semijoin=off,materialization=on,in_to_exists=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index
+2 MATERIALIZED t1 index NULL a 4 NULL 2 Using index
+SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+a
+2009-01-01
+2009-02-02
+set @@optimizer_switch=@old_optimizer_switch;
+drop table t1;
+#
+# LP BUG#908269 incorrect condition in case of subqueries depending
+# on constant tables
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 ( b INT ) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (4),(5);
+SET optimizer_switch='subquery_cache=off';
+SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) )
+1
+NULL
+SELECT ( SELECT b FROM t2 WHERE b = a OR b * 0) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR b * 0)
+1
+NULL
+SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR rand() * 0)
+1
+NULL
+drop table t1,t2,t3;
+set optimizer_switch=@subselect_tmp;
+#
+# LP BUG#905353 Wrong non-empty result with a constant table,
+# aggregate function in subquery, MyISAM or Aria
+#
+CREATE TABLE t1 ( a INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1);
+SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 );
+a
+drop table t1;
+#
+# LP BUG#985667 Wrong result with subquery in SELECT clause, and constant table in
+# main query and implicit grouping
+#
+CREATE TABLE t1 (f1 int) engine=MyISAM;
+INSERT INTO t1 VALUES (7),(8);
+CREATE TABLE t2 (f2 int, f3 varchar(1)) engine=MyISAM;
+INSERT INTO t2 VALUES (3,'f');
+EXPLAIN
+SELECT COUNT(f1), (SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2
+SELECT COUNT(f1), (SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 NULL
+EXPLAIN
+SELECT COUNT(f1), exists(SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2
+SELECT COUNT(f1), exists(SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 0
+EXPLAIN
+SELECT COUNT(f1), f2 > ALL (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2 Using where
+SELECT COUNT(f1), f2 > ALL (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 1
+EXPLAIN
+SELECT COUNT(f1), f2 IN (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2 Using where
+SELECT COUNT(f1), f2 IN (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 0
+drop table t1,t2;
+#
+# LP BUG#1002079 Server crashes in Item_singlerow_subselect::val_int with constant table,
+# HAVING, UNION in subquery
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (7),(0);
+CREATE TABLE t2 (b INT);
+EXPLAIN
+SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
+f1 f2
+drop table t1,t2;
+#
+# LP BUG#1008686 Server crashes in subselect_union_engine::no_rows on SELECT with impossible
+# WHERE and UNION in HAVING
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(7);
+EXPLAIN
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 0 HAVING a NOT IN ( SELECT 2 UNION SELECT 5 ) OR min_a != 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 NULL NULL NULL NULL NULL NULL NULL No tables used
+3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 0 HAVING a NOT IN ( SELECT 2 UNION SELECT 5 ) OR min_a != 1;
+min_a a
+EXPLAIN
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 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 ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 2 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 1;
+min_a a
+drop table t1;
+#
+# MDEV-367: Different results with and without subquery_cache on
+# a query with a constant NOT IN condition
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2),(3);
+set @mdev367_optimizer_switch = @@optimizer_switch;
+set optimizer_switch = 'subquery_cache=on';
+SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
+a
+SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
+a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
+1 NULL
+2 NULL
+3 NULL
+set optimizer_switch=@mdev367_optimizer_switch;
+set optimizer_switch = 'subquery_cache=off';
+SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
+a
+SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
+a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
+1 NULL
+2 NULL
+3 NULL
+set optimizer_switch=@mdev367_optimizer_switch;
+DROP TABLE t1;
+#
+# MDEV-521 single value subselect transformation problem
+#
+CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('u1'),('u2');
+SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) );
+f1
+u1
+u2
+FLUSH TABLES;
+SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) );
+f1
+u1
+u2
+DROP TABLE t1;
+# return optimizer switch changed in the beginning of this test
+set optimizer_switch=@subselect_tmp;
+set optimizer_switch=default;
+select @@optimizer_switch like '%subquery_cache=on%';
+@@optimizer_switch like '%subquery_cache=on%'
+1
+set @join_cache_level_for_subselect_test=NULL;
diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
new file mode 100644
index 00000000000..964704e0695
--- /dev/null
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -0,0 +1,6289 @@
+set @optimizer_switch_for_subselect_test='semijoin=off,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set join_cache_level=1;
+set @join_cache_level_for_subselect_test=@@join_cache_level;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+drop view if exists v2;
+set @subselect_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test,
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+set join_cache_level=@join_cache_level_for_subselect_test;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+select (select 2);
+(select 2)
+2
+explain extended select (select 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select 2 AS `(select 2)`
+SELECT (SELECT 1) UNION SELECT (SELECT 2);
+(SELECT 1)
+1
+2
+explain extended SELECT (SELECT 1) UNION SELECT (SELECT 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1249 Select 4 was reduced during optimization
+Note 1003 select 1 AS `(SELECT 1)` union select 2 AS `(SELECT 2)`
+SELECT (SELECT (SELECT 0 UNION SELECT 0));
+(SELECT (SELECT 0 UNION SELECT 0))
+0
+explain extended SELECT (SELECT (SELECT 0 UNION SELECT 0));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (select 0 union select 0) AS `(SELECT (SELECT 0 UNION SELECT 0))`
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) as c HAVING a=1) as b;
+ERROR 42S22: Reference 'b' not supported (forward reference in item list)
+SELECT (SELECT 1),MAX(1) FROM (SELECT 1) as a;
+(SELECT 1) MAX(1)
+1 1
+SELECT (SELECT a) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<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
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 100.00
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
+Warnings:
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`tt`.`a` AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
+set optimizer_switch=@tmp_optimizer_switch;
+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`,<expr_cache><`test`.`t4`.`a`>((select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`)) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+select * from t3 where exists (select * from t2 where t2.b=t3.a);
+a
+7
+select * from t3 where not exists (select * from t2 where t2.b=t3.a);
+a
+6
+3
+select * from t3 where a in (select b from t2);
+a
+7
+select * from t3 where a not in (select b from t2);
+a
+6
+3
+select * from t3 where a = some (select b from t2);
+a
+7
+select * from t3 where a <> any (select b from t2);
+a
+6
+3
+select * from t3 where a = all (select b from t2);
+a
+7
+select * from t3 where a <> all (select b from t2);
+a
+6
+3
+insert into t2 values (100, 5);
+select * from t3 where a < any (select b from t2);
+a
+6
+3
+select * from t3 where a < all (select b from t2);
+a
+3
+select * from t3 where a >= any (select b from t2);
+a
+6
+7
+explain extended select * from t3 where a >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= all (select b from t2);
+a
+7
+delete from t2 where a=100;
+select * from t3 where a in (select a,b from t2);
+ERROR 21000: Operand should contain 1 column(s)
+select * from t3 where a in (select * from t2);
+ERROR 21000: Operand should contain 1 column(s)
+insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9),(1,10);
+select b,max(a) as ma from t4 group by b having b < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+insert into t2 values (2,10);
+select b,max(a) as ma from t4 group by b having ma < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+10 1
+delete from t2 where a=2 and b=10;
+select b,max(a) as ma from t4 group by b having b >= (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+7 12
+create table t5 (a int);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (5);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (2);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+explain extended select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT UNION t5 ALL NULL NULL NULL NULL 2 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t2.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select <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 where; Using index
+4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where
+3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
+t8 WHERE pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
+pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+pseudo
+joce
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo LIKE '%joce%');
+ERROR 21000: Subquery returns more than 1 row
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8;
+CREATE TABLE `t1` (
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (topic,date,pseudo) VALUES
+('43506','2002-10-02','joce'),('40143','2002-08-03','joce');
+EXPLAIN EXTENDED SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')
+EXPLAIN EXTENDED SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select (select distinct `test`.`t1`.`date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')) AS `(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')`
+SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+date
+2002-08-03
+SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')
+2002-08-03
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL SELECT 1;
+1
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1;
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL topic 3 NULL 2 100.00 Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where (1 = (select 1 union select 1))
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (40143,1),(43506,2);
+CREATE TABLE `t2` (
+`mot` varchar(30) NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t2 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce');
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+a
+40143
+SELECT numeropost,maxnumrep FROM t1 WHERE exists (SELECT 1 FROM t2 WHERE (mot='joce') AND date >= '2002-10-21' AND t1.numeropost = t2.topic) ORDER BY maxnumrep DESC LIMIT 0, 20;
+numeropost maxnumrep
+43506 2
+40143 1
+SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1) b;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT 1 IN (SELECT 1 FROM t2 HAVING a);
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic IN (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 1
+SELECT * from t2 where topic = all (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+SELECT * from t2 where topic <> any (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 0
+drop table t1,t2;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (1,0),(2,1);
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+show warnings;
+Level Code Message
+Error 1242 Subquery returns more than 1 row
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+(select * from t1) union (select * from t1) order by (select a from t1 limit 1);
+a
+1
+2
+3
+drop table t1;
+CREATE TABLE t1 (field char(1) NOT NULL DEFAULT 'b');
+INSERT INTO t1 VALUES ();
+SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) a HAVING field='b');
+ERROR 21000: Subquery returns more than 1 row
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL default '0',
+`numreponse` int(10) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`numeropost`,`numreponse`),
+UNIQUE KEY `numreponse` (`numreponse`),
+KEY `pseudo` (`pseudo`,`numeropost`)
+) ENGINE=MyISAM;
+SELECT (SELECT numeropost FROM t1 HAVING numreponse=a),numreponse FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Reference 'numreponse' not supported (forward reference in item list)
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=a) FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT * FROM t1) as a;
+numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
+INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY t1 ref PRIMARY PRIMARY 3 const 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select 1 from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+drop table t1;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1);
+SELECT 1 FROM (SELECT a FROM t1) b HAVING (SELECT b.a)=1;
+1
+1
+drop table t1;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 22),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+update t1 set b= (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+update t1 set b= (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+update t1 set b= (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 NULL
+1 21
+2 22
+drop table t1, t2;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+select * from t1 where b = (select b from t2 where t1.a = t2.a);
+a b
+2 12
+delete from t1 where b in (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+delete from t1 where b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete from t1 where b = (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 10
+1 11
+drop table t1, t2;
+create table t11 (a int NOT NULL, b int, primary key (a));
+create table t12 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t11 values (0, 10),(1, 11),(2, 12);
+insert into t12 values (33, 10),(22, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t11;
+a b
+0 10
+1 11
+2 12
+select * from t12;
+a b
+33 10
+22 11
+2 12
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a);
+ERROR HY000: You can't specify target table 't12' for update in FROM clause
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a);
+select * from t11;
+a b
+0 10
+1 11
+select * from t12;
+a b
+33 10
+22 11
+drop table t11, t12, t2;
+CREATE TABLE t1 (x int) ENGINE=MyISAM;
+create table t2 (a int) ENGINE=MyISAM;
+create table t3 (b int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
+ERROR 21000: Subquery returns more than 1 row
+INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
+select * from t1;
+x
+1
+insert into t2 values (1);
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
+ERROR 42S22: Unknown column 'x' in 'field list'
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+2
+drop table t1, t2, t3;
+CREATE TABLE t1 (x int not null, y int, primary key (x)) ENGINE=MyISAM;
+create table t2 (a int);
+create table t3 (a int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+select * from t1;
+x y
+replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
+ERROR 21000: Subquery returns more than 1 row
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 2
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+2 FROM t2));
+select * from t1;
+x y
+1 3
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 1
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+replace LOW_PRIORITY into t1 (x, y) VALUES ((SELECT a+1 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+2 1
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1) b WHERE 1 IN (SELECT *);
+ERROR HY000: No tables used
+CREATE TABLE t2 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (1),(2);
+SELECT * FROM t2 WHERE id IN (SELECT 1);
+id
+1
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = 1)
+SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id
+1
+SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id
+2
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 3 was reduced during optimization
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = (1 + 1))
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL id 5 NULL 2 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where <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 MATERIALIZED t2 index a a 5 NULL 3 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`a` from `test`.`t2` ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`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 MATERIALIZED t2 index a a 5 NULL 3 100.00 Using index
+2 MATERIALIZED 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`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where (`test`.`t3`.`a` = `test`.`t2`.`a`) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`a`)))))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
+drop table t1,t2,t3;
+# check correct NULL Processing for normal IN/ALL/ANY
+# and 2 ways of max/min optimization
+create table t1 (a int);
+insert into t1 values (1), (100), (NULL), (1000);
+create table t2 (a int not null);
+# subselect returns empty set (for NULL and non-NULL left part)
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 1
+100 1
+NULL 1
+1000 1
+select a from t1 where a in (select * from t2);
+a
+select a from t1 where a > any (select * from t2);
+a
+select a from t1 where a > all (select * from t2);
+a
+1
+100
+NULL
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+select a from t1 where a > any (select * from t2 group by a);
+a
+select a from t1 where a > all (select * from t2 group by a);
+a
+1
+100
+NULL
+1000
+insert into t2 values (1),(200);
+# sebselect returns non-empty set without NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 0
+NULL NULL
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 1
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+1000
+drop table t2;
+create table t2 (a int);
+insert into t2 values (1),(NULL),(200);
+# sebselect returns non-empty set with NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 NULL
+NULL NULL
+1000 NULL
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 NULL
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 NULL
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+drop table t1, t2;
+create table t1 (a float);
+select 10.5 IN (SELECT * from t1 LIMIT 1);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int, b int, c varchar(10));
+create table t2 (a int);
+insert into t1 values (1,2,'a'),(2,3,'b'),(3,4,'c');
+insert into t2 values (1),(2),(NULL);
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a') (select c from t1 where a=t2.a)
+1 1 a
+2 0 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b') (select c from t1 where a=t2.a)
+1 0 a
+2 1 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where a=t2.a)
+1 0 a
+2 0 b
+NULL NULL NULL
+drop table t1,t2;
+create table t1 (a int, b real, c varchar(10));
+insert into t1 values (1, 1, 'a'), (2,2,'b'), (NULL, 2, 'b');
+select ROW(1, 1, 'a') IN (select a,b,c from t1);
+ROW(1, 1, 'a') IN (select a,b,c from t1)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1);
+ROW(1, 2, 'a') IN (select a,b,c from t1)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1);
+ROW(1, 1, 'a') IN (select b,a,c from t1)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a')
+1
+select ROW(1, 1, 'a') IN (select b,a,c from t1 limit 2);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1);
+do @a:=(SELECT a from t1);
+select @a;
+@a
+1
+set @a:=2;
+set @a:=(SELECT a from t1);
+select @a;
+@a
+1
+drop table t1;
+do (SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+set @a:=(SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (a int, KEY(a));
+HANDLER t1 OPEN;
+HANDLER t1 READ a=((SELECT 1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT 1))' at line 1
+HANDLER t1 CLOSE;
+drop table t1;
+create table t1 (a int);
+create table t2 (b int);
+insert into t1 values (1),(2);
+insert into t2 values (1);
+select a from t1 where a in (select a from t1 where a in (select b from t2));
+a
+1
+drop table t1, t2;
+create table t1 (a int, b int);
+create table t2 like t1;
+insert into t1 values (1,2),(1,3),(1,4),(1,5);
+insert into t2 values (1,2),(1,3);
+select * from t1 where row(a,b) in (select a,b from t2);
+a b
+1 2
+1 3
+drop table t1, t2;
+CREATE TABLE `t1` (`i` int(11) NOT NULL default '0',PRIMARY KEY (`i`)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+select * from t1;
+i
+2
+drop table t1;
+CREATE TABLE t1 (a int(1));
+EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
+drop table t1;
+CREATE TABLE `t1` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t2` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t3` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t2 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t3 VALUES (1,1);
+SELECT DISTINCT topic FROM t2 WHERE NOT EXISTS(SELECT * FROM t3 WHERE
+numeropost=topic);
+topic
+2
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+test 2 0000-00-00 test
+DELETE FROM t1 WHERE topic IN (SELECT DISTINCT topic FROM t2 WHERE NOT
+EXISTS(SELECT * FROM t3 WHERE numeropost=topic));
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+a (SELECT a)
+1 1
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT 1)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a+0)` int(3) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
+select * from t1;
+a
+2
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+explain extended select a,(select (select rand() from t1 limit 1) from t1 limit 1)
+from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+2 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+3 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,(select (select rand() from `test`.`t1` limit 1) from `test`.`t1` limit 1) AS `(select (select rand() from t1 limit 1) from t1 limit 1)` from `test`.`t1`
+drop table t1;
+select t1.Continent, t2.Name, t2.Population from t1 LEFT JOIN t2 ON t1.Code = t2.Country where t2.Population IN (select max(t2.Population) AS Population from t2, t1 where t2.Country = t1.Code group by Continent);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+name char(35) NOT NULL default '',
+t2 char(3) NOT NULL default '',
+District char(20) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (130,'Sydney','AUS','New South Wales',3276207);
+INSERT INTO t1 VALUES (131,'Melbourne','AUS','Victoria',2865329);
+INSERT INTO t1 VALUES (132,'Brisbane','AUS','Queensland',1291117);
+CREATE TABLE t2 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default '',
+PRIMARY KEY (Code)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU');
+INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
+select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent);
+Continent Name Population
+Oceania Sydney 3276207
+drop table t1, t2;
+CREATE TABLE `t1` (
+`id` mediumint(8) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`id`),
+UNIQUE KEY `pseudo` (`pseudo`)
+) ENGINE=MyISAM PACK_KEYS=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (pseudo) VALUES ('test');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
+INSERT INTO t1 (pseudo) VALUES ('test1');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
+drop table t1;
+CREATE TABLE `t1` (
+`i` int(11) NOT NULL default '0',
+PRIMARY KEY (`i`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i));
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t);
+ERROR 42S22: Unknown column 't.i' in 'field list'
+select * from t1;
+i
+3
+drop table t1;
+CREATE TABLE t1 (
+id int(11) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(1),(2),(2),(1),(3);
+CREATE TABLE t2 (
+id int(11) default NULL,
+name varchar(15) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (4,'vita'), (1,'vita'), (2,'vita'), (1,'vita');
+update t1, t2 set t2.name='lenka' where t2.id in (select id from t1);
+select * from t2;
+id name
+4 vita
+1 lenka
+2 lenka
+1 lenka
+drop table t1,t2;
+create table t1 (a int, unique index indexa (a));
+insert into t1 values (-1), (-4), (-2), (NULL);
+select -10 IN (select a from t1 FORCE INDEX (indexa));
+-10 IN (select a from t1 FORCE INDEX (indexa))
+NULL
+drop table t1;
+create table t1 (id int not null auto_increment primary key, salary int, key(salary));
+insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
+explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using where
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
+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:
+Warning 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 MATERIALIZED t1 index PRIMARY 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` = `<subquery2>`.`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 MATERIALIZED t1 ALL PRIMARY 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` = `<subquery2>`.`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 MATERIALIZED t3 index PRIMARY PRIMARY 4 NULL 3 100.00 Using index
+2 MATERIALIZED t1 ALL PRIMARY 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` = `<subquery2>`.`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 t3 index a a 5 NULL 3 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t1 ref a a 10 func,test.t3.a 1167 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`a`) 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_swedish_ci,IMPLICIT) and (latin1_german1_ci,IMPLICIT) for operation '<'
+drop table t1;
+create table t1(toid int,rd int);
+create table t2(userid int,pmnew int,pmtotal int);
+insert into t2 values(1,0,0),(2,0,0);
+insert into t1 values(1,0),(1,0),(1,0),(1,12),(1,15),(1,123),(1,12312),(1,12312),(1,123),(2,0),(2,0),(2,1),(2,2);
+select userid,pmtotal,pmnew, (select count(rd) from t1 where toid=t2.userid) calc_total, (select count(rd) from t1 where rd=0 and toid=t2.userid) calc_new from t2 where userid in (select distinct toid from t1);
+userid pmtotal pmnew calc_total calc_new
+1 0 0 9 3
+2 0 0 4 2
+drop table t1, t2;
+create table t1 (s1 char(5));
+select (select 'a','b' from t1 union select 'a','b' from t1) from t1;
+ERROR 21000: Operand should contain 1 column(s)
+insert into t1 values ('tttt');
+select * from t1 where ('a','b')=(select 'a','b' from t1 union select 'a','b' from t1);
+s1
+tttt
+explain extended (select * from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 (select 'tttt' AS `s1` from `test`.`t1`)
+(select * from t1);
+s1
+tttt
+drop table t1;
+create table t1 (s1 char(5), index s1(s1));
+create table t2 (s1 char(5), index s1(s1));
+insert into t1 values ('a1'),('a2'),('a3');
+insert into t2 values ('a1'),('a2');
+select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
+s1 s1 = ANY (SELECT s1 FROM t2)
+a1 1
+a2 1
+a3 0
+select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
+s1 s1 <> ALL (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')
+a1 0
+a2 1
+a3 1
+explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 MATERIALIZED t2 index s1 s1 6 NULL 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,`test`.`t1`.`s1` in ( <materialize> (select `test`.`t2`.`s1` from `test`.`t2` ), <primary_index_lookup>(`test`.`t1`.`s1` in <temporary table> on distinct_key where ((`test`.`t1`.`s1` = `<subquery2>`.`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 MATERIALIZED t2 index s1 s1 6 NULL 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,`test`.`t1`.`s1` in ( <materialize> (select `test`.`t2`.`s1` from `test`.`t2` ), <primary_index_lookup>(`test`.`t1`.`s1` in <temporary table> on distinct_key where ((`test`.`t1`.`s1` = `<subquery2>`.`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 MATERIALIZED t2 index s1 s1 6 NULL 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,`test`.`t1`.`s1` in ( <materialize> (select `test`.`t2`.`s1` from `test`.`t2` ), <primary_index_lookup>(`test`.`t1`.`s1` in <temporary table> on distinct_key where ((`test`.`t1`.`s1` = `<subquery2>`.`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 MATERIALIZED t2 index s1 s1 6 NULL 2 50.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,`test`.`t1`.`s1` in ( <materialize> (select `test`.`t2`.`s1` from `test`.`t2` where (`test`.`t2`.`s1` < 'a2') ), <primary_index_lookup>(`test`.`t1`.`s1` in <temporary table> on distinct_key where ((`test`.`t1`.`s1` = `<subquery2>`.`s1`)))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
+drop table t1,t2;
+create table t2 (a int, b int not null);
+create table t3 (a int);
+insert into t3 values (6),(7),(3);
+select * from t3 where a >= all (select b from t2);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= some (select b from t2);
+a
+explain extended select * from t3 where a >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= all (select b from t2 group by 1);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where a >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where NULL >= any (select b from t2);
+a
+explain extended select * from t3 where NULL >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= any (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= some (select b from t2);
+a
+explain extended select * from t3 where NULL >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+insert into t2 values (2,2), (2,1), (3,3), (3,1);
+select * from t3 where a > all (select max(b) from t2 group by a);
+a
+6
+7
+explain extended select * from t3 where a > all (select max(b) from t2 group by a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= <cache>(`test`.`t3`.`a`))))
+drop table t2, t3;
+CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
+INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
+CREATE TABLE `t2` (`db_id` int(11) NOT NULL auto_increment,`name` varchar(200) NOT NULL default '',`primary_uid` smallint(6) NOT NULL default '0',`secondary_uid` smallint(6) NOT NULL default '0',PRIMARY KEY (`db_id`),UNIQUE KEY `name_2` (`name`),FULLTEXT KEY `name` (`name`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2147483647;
+INSERT INTO `t2` (`db_id`, `name`, `primary_uid`, `secondary_uid`) VALUES (18, 'Not Set 1', 0, 0),(19, 'Valid', 1, 2),(20, 'Valid 2', 1, 2),(21, 'Should Not Return', 1, 2),(26, 'Not Set 2', 0, 0),(-1, 'ALL DB\'S', 0, 0);
+CREATE TABLE `t3` (`taskgenid` mediumint(9) NOT NULL auto_increment,`dbid` int(11) NOT NULL default '0',`taskid` int(11) NOT NULL default '0',`mon` tinyint(4) NOT NULL default '1',`tues` tinyint(4) NOT NULL default '1',`wed` tinyint(4) NOT NULL default '1',`thur` tinyint(4) NOT NULL default '1',`fri` tinyint(4) NOT NULL default '1',`sat` tinyint(4) NOT NULL default '0',`sun` tinyint(4) NOT NULL default '0',`how_often` smallint(6) NOT NULL default '1',`userid` smallint(6) NOT NULL default '0',`active` tinyint(4) NOT NULL default '1',PRIMARY KEY (`taskgenid`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2 ;
+INSERT INTO `t3` (`taskgenid`, `dbid`, `taskid`, `mon`, `tues`,`wed`, `thur`, `fri`, `sat`, `sun`, `how_often`, `userid`, `active`) VALUES (1,-1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1);
+CREATE TABLE `t4` (`task_id` smallint(6) NOT NULL default '0',`description` varchar(200) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO `t4` (`task_id`, `description`) VALUES (1, 'Daily Check List'),(2, 'Weekly Status');
+select dbid, name, (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01') from t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND t4.task_id = taskid;
+dbid name (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')
+-1 Valid 1
+-1 Valid 2 1
+-1 Should Not Return 0
+SELECT dbid, name FROM t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND ((date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')) AND t4.task_id = taskid;
+dbid name
+-1 Valid
+-1 Valid 2
+drop table t1,t2,t3,t4;
+CREATE TABLE t1 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (2),(6);
+select * from t1 where (1,2,6) in (select * from t2);
+ERROR 21000: Operand should contain 3 column(s)
+DROP TABLE t1,t2;
+create table t1 (s1 int);
+insert into t1 values (1);
+insert into t1 values (2);
+set sort_buffer_size = (select s1 from t1);
+ERROR 21000: Subquery returns more than 1 row
+do (select * from t1);
+Warnings:
+Error 1242 Subquery returns more than 1 row
+drop table t1;
+create table t1 (s1 char);
+insert into t1 values ('e');
+select * from t1 where 'f' > any (select s1 from t1);
+s1
+e
+select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+s1
+e
+explain extended select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+2 SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 UNION t1 system NULL NULL NULL NULL 1 100.00
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',(<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`) < 'f')))
+drop table t1;
+CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
+CREATE TABLE t2 (code char(5) NOT NULL default '',UNIQUE KEY code (code)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES ('1'),('1226'),('1245'),('1862'),('18623'),('1874'),('1967'),('6');
+select c.number as phone,(select p.code from t2 p where c.number like concat(p.code, '%') order by length(p.code) desc limit 1) as code from t1 c;
+phone code
+69294728265 6
+18621828126 1862
+89356874041 NULL
+95895001874 NULL
+drop table t1, t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+select * from t1 where (select count(*) from t2 where t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'where clause'
+select * from t1 where (select count(*) from t2 group by t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+select count(*) from t2 group by t1.s2;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+drop table t1, t2;
+CREATE TABLE t1(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC VARCHAR(20) DEFAULT NULL,PRIMARY KEY (COLA, COLB));
+CREATE TABLE t2(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC CHAR(1) NOT NULL,PRIMARY KEY (COLA));
+INSERT INTO t1 VALUES (1,1,'1A3240'), (1,2,'4W2365');
+INSERT INTO t2 VALUES (100, 200, 'C');
+SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1);
+COLC
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1),(1),(1),(1),(1),(2),(3),(4),(5);
+SELECT DISTINCT (SELECT a) FROM t1 LIMIT 100;
+(SELECT a)
+1
+2
+3
+4
+5
+DROP TABLE t1;
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "../../tmp/subselect.out.file.1" from t1;
+delete from t1;
+load data infile "../../tmp/subselect.out.file.1" into table t1;
+select * from t1;
+a b
+1 0.123
+drop table t1;
+CREATE TABLE `t1` (
+`id` int(11) NOT NULL auto_increment,
+`id_cns` tinyint(3) unsigned NOT NULL default '0',
+`tipo` enum('','UNO','DUE') NOT NULL default '',
+`anno_dep` smallint(4) unsigned zerofill NOT NULL default '0000',
+`particolare` mediumint(8) unsigned NOT NULL default '0',
+`generale` mediumint(8) unsigned NOT NULL default '0',
+`bis` tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`),
+UNIQUE KEY `idx_cns_gen_anno` (`anno_dep`,`id_cns`,`generale`,`particolare`),
+UNIQUE KEY `idx_cns_par_anno` (`id_cns`,`anno_dep`,`tipo`,`particolare`,`bis`)
+);
+INSERT INTO `t1` VALUES (1,16,'UNO',1987,2048,9681,0),(2,50,'UNO',1987,1536,13987,0),(3,16,'UNO',1987,2432,14594,0),(4,16,'UNO',1987,1792,13422,0),(5,16,'UNO',1987,1025,10240,0),(6,16,'UNO',1987,1026,7089,0);
+CREATE TABLE `t2` (
+`id` tinyint(3) unsigned NOT NULL auto_increment,
+`max_anno_dep` smallint(6) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`)
+);
+INSERT INTO `t2` VALUES (16,1987),(50,1990),(51,1990);
+SELECT cns.id, cns.max_anno_dep, cns.max_anno_dep = (SELECT s.anno_dep FROM t1 AS s WHERE s.id_cns = cns.id ORDER BY s.anno_dep DESC LIMIT 1) AS PIPPO FROM t2 AS cns;
+id max_anno_dep PIPPO
+16 1987 1
+50 1990 0
+51 1990 NULL
+DROP TABLE t1, t2;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SET SQL_SELECT_LIMIT=1;
+select sum(a) from (select * from t1) as a;
+sum(a)
+6
+select 2 in (select * from t1);
+2 in (select * from t1)
+1
+SET SQL_SELECT_LIMIT=default;
+drop table t1;
+CREATE TABLE t1 (a int, b int, INDEX (a));
+INSERT INTO t1 VALUES (1, 1), (1, 2), (1, 3);
+SELECT * FROM t1 WHERE a = (SELECT MAX(a) FROM t1 WHERE a = 1) ORDER BY b;
+a b
+1 1
+1 2
+1 3
+DROP TABLE t1;
+create table t1(val varchar(10));
+insert into t1 values ('aaa'), ('bbb'),('eee'),('mmm'),('ppp');
+select count(*) from t1 as w1 where w1.val in (select w2.val from t1 as w2 where w2.val like 'm%') and w1.val in (select w3.val from t1 as w3 where w3.val like 'e%');
+count(*)
+0
+drop table t1;
+create table t1 (id int not null, text varchar(20) not null default '', primary key (id));
+insert into t1 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text11'), (12, 'text12');
+select * from t1 where id not in (select id from t1 where id < 8);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+explain extended select * from t1 where id not in (select id from t1 where id < 8);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00 Using where
+2 MATERIALIZED t1 range PRIMARY PRIMARY 4 NULL 7 100.00 Using where; Using index
+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`,`test`.`t1`.`id` in ( <materialize> (select `test`.`t1`.`id` from `test`.`t1` where (`test`.`t1`.`id` < 8) ), <primary_index_lookup>(`test`.`t1`.`id` in <temporary table> on distinct_key where ((`test`.`t1`.`id` = `<subquery2>`.`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;
+set @tmp11867_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin_with_cache=off';
+CREATE TABLE t1 (one int, two int, flag char(1));
+CREATE TABLE t2 (one int, two int, flag char(1));
+INSERT INTO t1 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+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 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<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` = '0') ), <primary_index_lookup>(`test`.`t1`.`one` in <temporary table> on distinct_key where ((`test`.`t1`.`one` = `<subquery2>`.`one`) and (`test`.`t1`.`two` = `<subquery2>`.`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 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<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` = `<subquery2>`.`one`) and (`test`.`t1`.`two` = `<subquery2>`.`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 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<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` = '0') ), <primary_index_lookup>(`test`.`t1`.`one` in <temporary table> on distinct_key where ((`test`.`t1`.`one` = `<subquery2>`.`one`) and (`test`.`t1`.`two` = `<subquery2>`.`two`)))))) AS `test` from `test`.`t1`
+DROP TABLE t1,t2;
+set optimizer_switch=@tmp11867_optimizer_switch;
+CREATE TABLE t1 (a char(5), b char(5));
+INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
+SELECT * FROM t1 WHERE (a,b) IN (('aaa','aaa'), ('aaa','bbb'));
+a b
+aaa aaa
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int, b int);
+CREATE TABLE t3 (b int NOT NULL);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+INSERT INTO t2 VALUES (1,10), (3,30);
+SELECT * FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10;
+a b b
+SELECT * FROM t1
+WHERE t1.a NOT IN (SELECT a FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10);
+a
+1
+2
+3
+4
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (f1 INT);
+CREATE TABLE t2 (f2 INT);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2);
+f1
+1
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE 1=0);
+f1
+1
+INSERT INTO t2 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE f2=0);
+f1
+1
+DROP TABLE t1, t2;
+select 1 from dual where 1 < any (select 2);
+1
+1
+select 1 from dual where 1 < all (select 2);
+1
+1
+select 1 from dual where 2 > any (select 1);
+1
+1
+select 1 from dual where 2 > all (select 1);
+1
+1
+select 1 from dual where 1 < any (select 2 from dual);
+1
+1
+select 1 from dual where 1 < all (select 2 from dual where 1!=1);
+1
+1
+create table t1 (s1 char);
+insert into t1 values (1),(2);
+select * from t1 where (s1 < any (select s1 from t1));
+s1
+1
+select * from t1 where not (s1 < any (select s1 from t1));
+s1
+2
+select * from t1 where (s1 < ALL (select s1+1 from t1));
+s1
+1
+select * from t1 where not(s1 < ALL (select s1+1 from t1));
+s1
+2
+select * from t1 where (s1+1 = ANY (select s1 from t1));
+s1
+1
+select * from t1 where NOT(s1+1 = ANY (select s1 from t1));
+s1
+2
+select * from t1 where (s1 = ALL (select s1/s1 from t1));
+s1
+1
+select * from t1 where NOT(s1 = ALL (select s1/s1 from t1));
+s1
+2
+drop table t1;
+create table t1 (
+retailerID varchar(8) NOT NULL,
+statusID int(10) unsigned NOT NULL,
+changed datetime NOT NULL,
+UNIQUE KEY retailerID (retailerID, statusID, changed)
+);
+INSERT INTO t1 VALUES("0026", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0026", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0037", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50");
+INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50");
+select * from t1 r1
+where (r1.retailerID,(r1.changed)) in
+(SELECT r2.retailerId,(max(changed)) from t1 r2
+group by r2.retailerId);
+retailerID statusID changed
+0026 2 2006-01-06 12:25:53
+0037 2 2006-01-06 12:25:53
+0048 1 2006-01-06 12:37:50
+0059 1 2006-01-06 12:37:50
+drop table t1;
+create table t1(a int, primary key (a));
+insert into t1 values (10);
+create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b));
+insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989');
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using where
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+a a b
+10 3 35989
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+a a b
+10 1 359
+drop table t1,t2;
+CREATE TABLE t1 (
+field1 int NOT NULL,
+field2 int NOT NULL,
+field3 int NOT NULL,
+PRIMARY KEY (field1,field2,field3)
+);
+CREATE TABLE t2 (
+fieldA int NOT NULL,
+fieldB int NOT NULL,
+PRIMARY KEY (fieldA,fieldB)
+);
+INSERT INTO t1 VALUES
+(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
+INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
+SELECT field1, field2, COUNT(*)
+FROM t1 GROUP BY field1, field2;
+field1 field2 COUNT(*)
+1 1 2
+1 2 3
+1 3 1
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) >= ALL (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 2
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) < ANY (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 1
+1 3
+DROP TABLE t1, t2;
+CREATE TABLE t1(a int, INDEX (a));
+INSERT INTO t1 VALUES (1), (3), (5), (7);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES (1),(2),(3);
+EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3
+2 MATERIALIZED t1 index a a 5 NULL 5 Using index
+SELECT a, a IN (SELECT a FROM t1) FROM t2;
+a a IN (SELECT a FROM t1)
+1 1
+2 NULL
+3 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a DATETIME);
+INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
+CREATE TABLE t2 AS SELECT
+(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a
+FROM t1 WHERE a > '2000-01-01';
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `sub_a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01');
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) > 0;
+a
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+a
+1
+2
+EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2), (4), (1), (3);
+CREATE TABLE t2 (b int, c int);
+INSERT INTO t2 VALUES
+(2,1), (1,3), (2,1), (4,4), (2,2), (1,4);
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2 );
+a
+2
+4
+1
+3
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a;
+a
+1
+2
+3
+4
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1), a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2);
+b MAX(c)
+1 4
+2 2
+4 4
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+1
+2
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+1
+2
+3
+4
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+1
+2
+3
+4
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1,t2;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+insert into t1 values(2.2);
+select * from t1 where df <= all (select avg(df) from t1 group by df);
+df
+1.1
+select * from t1 where df >= all (select avg(df) from t1 group by df);
+df
+2.2
+drop table t1;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+select 1.1 * exists(select * from t1);
+1.1 * exists(select * from t1)
+1.1
+drop table t1;
+CREATE TABLE t1 (
+grp int(11) default NULL,
+a decimal(10,2) default NULL);
+insert into t1 values (1, 1), (2, 2), (2, 3), (3, 4), (3, 5), (3, 6), (NULL, NULL);
+select * from t1;
+grp a
+1 1.00
+2 2.00
+2 3.00
+3 4.00
+3 5.00
+3 6.00
+NULL NULL
+select min(a) from t1 group by grp;
+min(a)
+NULL
+1.00
+2.00
+4.00
+drop table t1;
+CREATE table t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2 WHERE c2 IN (1);
+c1 c2
+1 1
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE c2 IN ( SELECT c2 FROM t2 WHERE c2 IN ( 1 ) );
+c1 c2
+1 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+INSERT INTO t1 VALUES ( 6 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+INSERT INTO t2 VALUES ( 6 );
+CREATE TABLE t3 ( c3 integer );
+INSERT INTO t3 VALUES ( 7 );
+INSERT INTO t3 VALUES ( 8 );
+SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL );
+c1 c2
+2 NULL
+3 NULL
+DROP TABLE t1,t2,t3;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+CREATE TABLE t1 (EMPNUM CHAR(3));
+CREATE TABLE t2 (EMPNUM CHAR(3) );
+INSERT INTO t1 VALUES ('E1'),('E2');
+INSERT INTO t2 VALUES ('E1');
+DELETE FROM t1
+WHERE t1.EMPNUM NOT IN
+(SELECT t2.EMPNUM
+FROM t2
+WHERE t1.EMPNUM = t2.EMPNUM);
+select * from t1;
+EMPNUM
+E1
+DROP TABLE t1,t2;
+CREATE TABLE t1(select_id BIGINT, values_id BIGINT);
+INSERT INTO t1 VALUES (1, 1);
+CREATE TABLE t2 (select_id BIGINT, values_id BIGINT,
+PRIMARY KEY(select_id,values_id));
+INSERT INTO t2 VALUES (0, 1), (0, 2), (0, 3), (1, 5);
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id IN (1, 0));
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id BETWEEN 0 AND 1);
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id = 0 OR select_id = 1);
+values_id
+1
+DROP TABLE t1, t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (c int, d int);
+CREATE TABLE t3 (e int);
+INSERT INTO t1 VALUES
+(1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40);
+INSERT INTO t2 VALUES
+(2,10), (2,20), (4,10), (5,10), (3,20), (2,40);
+INSERT INTO t3 VALUES (10), (30), (10), (20) ;
+SELECT a, MAX(b), MIN(b) FROM t1 GROUP BY a;
+a MAX(b) MIN(b)
+1 20 10
+2 30 10
+3 20 20
+4 40 40
+SELECT * FROM t2;
+c d
+2 10
+2 20
+4 10
+5 10
+3 20
+2 40
+SELECT * FROM t3;
+e
+10
+30
+10
+20
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>20);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)<d);
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>d);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d >= SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d > SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e < d));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE MIN(b) < d AND
+EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+SELECT a, SUM(a) FROM t1 GROUP BY a;
+a SUM(a)
+1 2
+2 6
+3 3
+4 4
+SELECT a FROM t1
+WHERE EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c) GROUP BY a;
+a
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c);
+a
+1
+3
+4
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c) GROUP BY a;
+a
+1
+2
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c);
+a
+1
+2
+1
+2
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a < ALL(SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+1
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3
+WHERE SUM(t1.a+t2.c) < t3.e/4));
+ERROR HY000: Invalid use of group function
+SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20;
+ERROR HY000: Invalid use of group function
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(t2.c+SUM(t1.b)) > 20);
+a
+2
+3
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(SUM(t1.b)) > 20);
+a
+2
+4
+SELECT t1.a, SUM(b) AS sum FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING t2.c+sum > 20);
+a sum
+2 60
+3 20
+4 40
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a varchar(5), b varchar(10));
+INSERT INTO t1 VALUES
+('AAA', 5), ('BBB', 4), ('BBB', 1), ('CCC', 2),
+('CCC', 7), ('AAA', 2), ('AAA', 4), ('BBB', 3), ('AAA', 8);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
+ALTER TABLE t1 ADD INDEX(a);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
+DROP TABLE t1;
+create table t1( f1 int,f2 int);
+insert into t1 values (1,1),(2,2);
+select tt.t from (select 'crash1' as t, f2 from t1) as tt left join t1 on tt.t = 'crash2' and tt.f2 = t1.f2 where tt.t = 'crash1';
+t
+crash1
+crash1
+drop table t1;
+create table t1 (c int, key(c));
+insert into t1 values (1142477582), (1142455969);
+create table t2 (a int, b int);
+insert into t2 values (2, 1), (1, 0);
+delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
+drop table t1, t2;
+CREATE TABLE t1 (a INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'IN/ALL/ANY subquery'
+DROP TABLE t1;
+create table t1 (i int, j bigint);
+insert into t1 values (1, 2), (2, 2), (3, 2);
+select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
+min(i)
+1
+drop table t1;
+CREATE TABLE t1 (i BIGINT UNSIGNED);
+INSERT INTO t1 VALUES (10000000000000000000);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (i BIGINT UNSIGNED);
+INSERT INTO t2 VALUES (10000000000000000000);
+INSERT INTO t2 VALUES (1);
+/* simple test */
+SELECT t1.i FROM t1 JOIN t2 ON t1.i = t2.i;
+i
+10000000000000000000
+1
+/* subquery test */
+SELECT t1.i FROM t1 WHERE t1.i = (SELECT MAX(i) FROM t2);
+i
+10000000000000000000
+/* subquery test with cast*/
+SELECT t1.i FROM t1 WHERE t1.i = CAST((SELECT MAX(i) FROM t2) AS UNSIGNED);
+i
+10000000000000000000
+DROP TABLE t1;
+DROP TABLE t2;
+CREATE TABLE t1 (
+id bigint(20) unsigned NOT NULL auto_increment,
+name varchar(255) NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES
+(1, 'Balazs'), (2, 'Joe'), (3, 'Frank');
+CREATE TABLE t2 (
+id bigint(20) unsigned NOT NULL auto_increment,
+mid bigint(20) unsigned NOT NULL,
+date date NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t2 VALUES
+(1, 1, '2006-03-30'), (2, 2, '2006-04-06'), (3, 3, '2006-04-13'),
+(4, 2, '2006-04-20'), (5, 1, '2006-05-01');
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 3, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 NULL
+2 Joe 2006-04-20 NULL
+3 Frank 2006-04-13 NULL
+SELECT *,
+(SELECT COUNT(*) FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_count
+FROM t1;
+id name date_count
+1 Balazs NULL
+2 Joe NULL
+3 Frank NULL
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 2006-03-30
+2 Joe 2006-04-20 2006-04-06
+3 Frank 2006-04-13 NULL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime NOT NULL default '0000-00-00 00:00:00',
+PRIMARY KEY (i1,i2,t)
+);
+INSERT INTO t1 VALUES
+(24,1,'2005-03-03 16:31:31'),(24,1,'2005-05-27 12:40:07'),
+(24,1,'2005-05-27 12:40:08'),(24,1,'2005-05-27 12:40:10'),
+(24,1,'2005-05-27 12:40:25'),(24,1,'2005-05-27 12:40:30'),
+(24,2,'2005-03-03 13:43:05'),(24,2,'2005-03-03 16:23:31'),
+(24,2,'2005-03-03 16:31:30'),(24,2,'2005-05-27 12:37:02'),
+(24,2,'2005-05-27 12:40:06');
+CREATE TABLE t2 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime default NULL,
+PRIMARY KEY (i1)
+);
+INSERT INTO t2 VALUES (24,1,'2006-06-20 12:29:40');
+EXPLAIN
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index
+2 DEPENDENT SUBQUERY t1 range PRIMARY PRIMARY 16 NULL 5 Using where; Using index
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+i1 i2 t i1 i2 t
+24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b));
+insert into t1 (a) values (FLOOR(rand() * 100));
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+SELECT a,
+(SELECT REPEAT(' ',250) FROM t1 i1
+WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a
+FROM t1 ORDER BY a LIMIT 5;
+a a
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 values (1);
+INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4);
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2)
+2
+1
+1
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+2
+1
+1
+SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b))
+2 2
+1 1
+1 1
+SELECT COUNT(DISTINCT t1.b),
+(SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+2 2
+1 1
+1 1
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a;
+(
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+2
+1
+1
+SELECT (
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+FROM t1 t2
+GROUP BY t2.a;
+(
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+2
+2
+2
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (b));
+CREATE TABLE t2 (x int auto_increment, y int, z int,
+PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1 select RAND()*1000, A.a + 10*(B.a+10*(C.a+10*D.a))
+from t3 A, t3 B, t3 C, t3 D where D.a<3;
+insert into t2(y,z) select t1.b, RAND()*1000 from t1, t3;
+SET SESSION sort_buffer_size = 32 * 1024;
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+SET SESSION sort_buffer_size = 8 * 1024 * 1024;
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
+CREATE TABLE t2 (c int);
+INSERT INTO t1 VALUES ('aa', 1);
+INSERT INTO t2 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+INSERT INTO t1 VALUES ('bb', 2), ('cc', 3), ('dd',1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+INSERT INTO t2 VALUES (2);
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT t2.c FROM t2 JOIN t3 ON t2.c=t3.c WHERE t2.c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1(f1 int);
+CREATE TABLE t2(f2 int, f21 int, f3 timestamp);
+INSERT INTO t1 VALUES (1),(1),(2),(2);
+INSERT INTO t2 VALUES (1,1,"2004-02-29 11:11:11"), (2,2,"2004-02-29 11:11:11");
+SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1;
+sq
+2
+4
+SELECT (SELECT SUM(1) FROM t2 ttt GROUP BY t2.f3 LIMIT 1) AS tt FROM t2;
+tt
+2
+2
+PREPARE stmt1 FROM 'SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1';
+EXECUTE stmt1;
+sq
+2
+4
+EXECUTE stmt1;
+sq
+2
+4
+DEALLOCATE PREPARE stmt1;
+SELECT f2, AVG(f21),
+(SELECT t.f3 FROM t2 AS t WHERE t2.f2=t.f2 AND t.f3=MAX(t2.f3)) AS test
+FROM t2 GROUP BY f2;
+f2 AVG(f21) test
+1 1.0000 2004-02-29 11:11:11
+2 2.0000 2004-02-29 11:11:11
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL);
+INSERT INTO t1 VALUES
+(1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
+(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'),
+(3,2,'k'), (3,1,'l'), (1,9,'m');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t1xt2;
+CREATE TABLE t1 (
+id_1 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t2 (
+id_2 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t1xt2 (
+id_1 int(5) NOT NULL,
+id_2 int(5) NOT NULL
+);
+INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
+INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
+INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+3
+4
+insert INTO t1xt2 VALUES (1, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+2
+3
+4
+insert INTO t1xt2 VALUES (2, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+3
+4
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t1xt2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (3), (1), (2);
+SELECT 'this is ' 'a test.' AS col1, a AS col2 FROM t1;
+col1 col2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+SELECT * FROM (SELECT 'this is ' 'a test.' AS col1, a AS t2 FROM t1) t;
+col1 t2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+DROP table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*), a,
+(SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a,
+(SELECT MIN(m) FROM t2 WHERE m = count(*))
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT MIN(m) FROM t2 WHERE m = count(*))
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a
+FROM t1 GROUP BY a
+HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1;
+COUNT(*) a
+2 2
+3 3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+2 2 2
+3 3 3
+1 4 1,1
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+2 2 3
+3 3 4
+1 4 2,2
+DROP table t1,t2;
+CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
+INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'),
+(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'),
+(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a x, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+x MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a, AVG(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test
+FROM t1 WHERE t1.d=0 GROUP BY a;
+a AVG(b) test
+1 4.0000 d
+2 2.0000 g
+3 2.5000 NULL
+SELECT tt.a,
+(SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt;
+a test
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+2 o
+2 o
+2 o
+2 o
+3 p
+3 p
+3 p
+3 p
+3 p
+SELECT tt.a,
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+SELECT tt.a, MAX(
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+a
+1
+2
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+a
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+a
+1
+2
+SET @@sql_mode='ansi';
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+ERROR HY000: Invalid use of group function
+SET @@sql_mode=default;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 values (1),(1),(1),(1);
+CREATE TABLE t2 (x INT);
+INSERT INTO t1 values (1000),(1001),(1002);
+SELECT SUM( (SELECT COUNT(a) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT SUM( (SELECT SUM(COUNT(a)) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT COUNT(1) FROM DUAL;
+COUNT(1)
+1
+SELECT SUM( (SELECT AVG( (SELECT t1.a FROM t2) ) FROM DUAL) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING t1.a < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT t1.a as XXA,
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, KEY (a));
+INSERT INTO t1 VALUES (1,1),(2,1);
+EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref a a 5 const 0 Using where; Using index
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+DROP TABLE t1;
+CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
+INSERT INTO t1 VALUES
+(3,'FL'), (2,'GA'), (4,'FL'), (1,'GA'), (5,'NY'), (7,'FL'), (6,'NY');
+CREATE TABLE t2 (id int NOT NULL, INDEX idx(id));
+INSERT INTO t2 VALUES (7), (5), (1), (3);
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+3 FL
+1 GA
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+1 GA
+3 FL
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+2 GA
+4 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+2 GA
+4 FL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT count(*) FROM t1 GROUP BY a) as res;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `res`.`count(*)` AS `count(*)` from (select count(0) AS `count(*)` from `test`.`t1` group by `test`.`t1`.`a`) `res`
+DROP TABLE t1;
+CREATE TABLE t1 (
+a varchar(255) default NULL,
+b timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+INDEX idx(a,b)
+);
+CREATE TABLE t2 (
+a varchar(255) default NULL
+);
+INSERT INTO t1 VALUES ('abcdefghijk','2007-05-07 06:00:24');
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26');
+INSERT INTO `t2` VALUES ('abcdefghijk');
+INSERT INTO `t2` VALUES ('asdf');
+SET session sort_buffer_size=8192;
+SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
+d1
+1
+1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INTEGER, b INTEGER);
+CREATE TABLE t2 (x INTEGER);
+INSERT INTO t1 VALUES (1,11), (2,22), (2,22);
+INSERT INTO t2 VALUES (1), (2);
+SELECT a, COUNT(b), (SELECT COUNT(b) FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a, COUNT(b), (SELECT COUNT(b)+0 FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a)/AVG(t2.x) FROM t2) FROM t1;
+(SELECT SUM(t1.a)/AVG(t2.x) FROM t2)
+3.3333
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1, 2), (1,3), (1,4), (2,1), (2,2);
+SELECT a1.a, COUNT(*) FROM t1 a1 WHERE a1.a = 1
+AND EXISTS( SELECT a2.a FROM t1 a2 WHERE a2.a = a1.a)
+GROUP BY a1.a;
+a COUNT(*)
+1 3
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+INSERT INTO t2 VALUES (1),(2);
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=0) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=0)
+NULL
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a!=0) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=1) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=1)
+3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a1 INT, a2 INT);
+CREATE TABLE t2 (b1 INT, b2 INT);
+INSERT INTO t1 VALUES (100, 200);
+INSERT INTO t1 VALUES (101, 201);
+INSERT INTO t2 VALUES (101, 201);
+INSERT INTO t2 VALUES (103, 203);
+SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1;
+((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL
+0
+0
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5));
+INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+CREATE INDEX I1 ON t1 (s1);
+CREATE INDEX I2 ON t1 (s2);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+TRUNCATE t1;
+INSERT INTO t1 VALUES (0x41,0x41);
+SELECT * FROM t1 WHERE s1 = (SELECT s2 FROM t1);
+s1 s2
+DROP TABLE t1;
+CREATE TABLE t1 (a1 VARBINARY(2) NOT NULL DEFAULT '0', PRIMARY KEY (a1));
+CREATE TABLE t2 (a2 BINARY(2) default '0', INDEX (a2));
+CREATE TABLE t3 (a3 BINARY(2) default '0');
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+INSERT INTO t3 VALUES (1),(2),(3);
+SELECT LEFT(t2.a2, 1) FROM t2,t3 WHERE t3.a3=t2.a2;
+LEFT(t2.a2, 1)
+1
+2
+3
+SELECT t1.a1, t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2) FROM t1;
+a1 t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2)
+1 0
+2 0
+3 0
+4 0
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a1 BINARY(3) PRIMARY KEY, b1 VARBINARY(3));
+CREATE TABLE t2 (a2 VARBINARY(3) PRIMARY KEY);
+CREATE TABLE t3 (a3 VARBINARY(3) PRIMARY KEY);
+INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40);
+INSERT INTO t2 VALUES (2), (3), (4), (5);
+INSERT INTO t3 VALUES (10), (20), (30);
+SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3;
+LEFT(t1.a1,1)
+1
+2
+3
+SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
+a2
+DROP TABLE t1, t2, t3;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+SET optimizer_switch='materialization=off';
+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;
+SET optimizer_switch= @save_optimizer_switch;
+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);
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) 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 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,1 in ( <materialize> (select min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `<subquery2>`.`min(a)`))))))
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 WHERE a > 3 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,1 in ( <materialize> (select min(`test`.`t1`.`a`) 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 = `<subquery2>`.`min(a)`))))))
+SET join_cache_level=@save_join_cache_level;
+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 NULL
+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 index 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;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+EXPLAIN EXTENDED
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+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 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <nop>(<in_optimizer>(1,((select max(`test`.`t1`.`a1`) from `test`.`t1`) > 1)))
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+1
+1
+1
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1, t2;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
+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
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
+INSERT INTO t1 VALUES (1,NULL), (9,NULL);
+CREATE TABLE t2 (
+a INT,
+b INT,
+c INT,
+d INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c,d),
+KEY b_2 (b),
+KEY c (c),
+KEY d (d)
+);
+INSERT INTO t2 VALUES
+(43, 2, 11 ,30),
+(44, 2, 12 ,30),
+(45, 1, 1 ,10000),
+(46, 1, 2 ,10000),
+(556,1, 32 ,10000);
+CREATE TABLE t3 (
+a INT,
+b INT,
+c INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c),
+KEY c (c),
+KEY b_2 (b)
+);
+INSERT INTO t3 VALUES (1,1,1), (2,32,1);
+explain
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 PRIMARY t3 ref b,b_2 b 5 test.t1.a 1 Using index
+2 DEPENDENT SUBQUERY t2 ref b,b_2,c b 10 test.t3.c,test.t1.a 1 Using where; Using index; Using filesort
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+a incorrect
+1 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int, c int);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+CREATE VIEW v1 AS
+SELECT t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+UPDATE v1 SET c=1;
+CREATE VIEW v2 (a,b) AS
+SELECT t2.id, t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+INSERT INTO v2(a,b) VALUES (2,2);
+ERROR HY000: CHECK OPTION failed 'test.v2'
+SELECT * FROM v1;
+c
+1
+1
+1
+1
+CREATE VIEW v3 AS
+SELECT t2.c AS c FROM t2
+WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+DELETE FROM v3;
+DROP VIEW v1,v2,v3;
+DROP TABLE t1,t2;
+#
+# BUG#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+#
+# Bug#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+CREATE TABLE t1 (a ENUM('rainbow'));
+INSERT INTO t1 VALUES (),(),(),(),();
+SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
+1
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGBLOB);
+INSERT INTO t1 SET a = 'aaaa';
+INSERT INTO t1 SET a = 'aaaa';
+SELECT 1 FROM t1 GROUP BY
+(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
+1
+1
+DROP TABLE t1;
+#
+# Bug #49512 : subquery with aggregate function crash
+# subselect_single_select_engine::exec()
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES();
+# should not crash
+SELECT 1 FROM t1 WHERE a <> SOME
+(
+SELECT MAX((SELECT a FROM t1 LIMIT 1)) AS d
+FROM t1,t1 a
+);
+1
+DROP TABLE t1;
+#
+# Bug #45989 take 2 : memory leak after explain encounters an
+# error in the query
+#
+CREATE TABLE t1(a LONGTEXT);
+INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet));
+INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet));
+EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1,
+(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) AS d1
+WHERE t1.a = d1.a;
+ERROR 42S22: Unknown column 'd1.a' in 'where clause'
+DROP TABLE t1;
+Set up test tables.
+CREATE TABLE t1 (
+t1_id INT UNSIGNED,
+PRIMARY KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t1 (t1_id) VALUES (1), (2), (3), (4), (5);
+CREATE TABLE t2 SELECT * FROM t1;
+CREATE TABLE t3 (
+t3_id INT UNSIGNED AUTO_INCREMENT,
+t1_id INT UNSIGNED,
+amount DECIMAL(16,2),
+PRIMARY KEY(t3_id),
+KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t3 (t1_id, t3_id, amount)
+VALUES (1, 1, 100.00), (2, 2, 200.00), (4, 4, 400.00);
+This is the 'inner query' running by itself.
+Produces correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query)
+Produces correct results.
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+Now make t2.t1_id part of a key.
+ALTER TABLE t2 ADD PRIMARY KEY(t1_id);
+Same inner query by itself.
+Still correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query), now with indexes on the LEFT JOIN
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+DROP TABLE t3;
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# Bug #52711: Segfault when doing EXPLAIN SELECT with
+# union...order by (select... where...)
+#
+CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a));
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (1),(2);
+# Should not crash
+EXPLAIN
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+# Should not crash
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+DROP TABLE t1,t2;
+# LP BUG#675248 - select->prep_where references on freed memory
+CREATE TABLE t1 (a int, b int);
+insert into t1 values (1,1),(0,0);
+CREATE TABLE t2 (c int);
+insert into t2 values (1),(2);
+prepare stmt1 from "select sum(a),(select sum(c) from t2 where table1.b) as sub
+from t1 as table1 group by sub";
+execute stmt1;
+sum(a) sub
+0 NULL
+1 3
+deallocate prepare stmt1;
+prepare stmt1 from "select sum(a),(select sum(c) from t2 having table1.b) as sub
+from t1 as table1";
+execute stmt1;
+sum(a) sub
+1 3
+deallocate prepare stmt1;
+drop table t1,t2;
+#
+# Bug LP#693935/#58727: Assertion failure with
+# a single row subquery returning more than one row
+#
+create table t1 (a char(1) charset utf8);
+insert into t1 values ('a'), ('b');
+create table t2 (a binary(1));
+insert into t2 values ('x'), ('y');
+select * from t2 where a=(select a from t1) and a='x';
+ERROR 21000: Subquery returns more than 1 row
+drop table t1,t2;
+End of 5.1 tests
+#
+# No BUG#, a case brought from 5.2's innodb_mysql_lock.test
+#
+create table t1 (i int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+create table t2 (j int not null primary key);
+insert into t2 values (1),(2),(3),(4),(5);
+create table t3 (k int not null primary key);
+insert into t3 values (1),(2),(3);
+create view v2 as select t2.j as j from t2 where t2.j in (select t1.i from t1);
+select * from t3 where k in (select j from v2);
+k
+1
+2
+3
+drop table t1,t2,t3;
+drop view v2;
+#
+# Bug#52068: Optimizer generates invalid semijoin materialization plan
+#
+drop table if exists ot1, ot2, it1, it2;
+CREATE TABLE ot1(a INTEGER);
+INSERT INTO ot1 VALUES(5), (8);
+CREATE TABLE it2(a INTEGER);
+INSERT INTO it2 VALUES(9), (5), (1), (8);
+CREATE TABLE it3(a INTEGER);
+INSERT INTO it3 VALUES(7), (1), (0), (5), (1), (4);
+CREATE TABLE ot4(a INTEGER);
+INSERT INTO ot4 VALUES(1), (3), (5), (7), (9), (7), (3), (1);
+SELECT * FROM ot1,ot4
+WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
+FROM it2,it3);
+a a
+5 1
+8 1
+5 5
+8 5
+5 7
+8 7
+5 7
+8 7
+5 1
+8 1
+explain SELECT * FROM ot1,ot4
+WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
+FROM it2,it3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 2
+1 PRIMARY ot4 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED it2 ALL NULL NULL NULL NULL 4
+2 MATERIALIZED it3 ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
+DROP TABLE IF EXISTS ot1, ot4, it2, it3;
+#
+# Bug#729039: NULL keys used to evaluate subquery
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (NULL), (1), (NULL), (2);
+CREATE TABLE t2 (a int, INDEX idx(a)) ;
+INSERT INTO t2 VALUES (NULL), (1), (NULL);
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a);
+a
+1
+EXPLAIN
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+a
+1
+EXPLAIN
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
+DROP TABLE t1,t2;
+#
+# BUG#752992: Wrong results for a subquery with 'semijoin=on'
+#
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
+EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+2 MATERIALIZED t2 index NULL PRIMARY 4 NULL 3 Using index
+2 MATERIALIZED it index PRIMARY PRIMARY 4 NULL 3 Using index
+SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+pk i
+11 0
+12 5
+15 0
+SET join_cache_level=@save_join_cache_level;
+DROP table t1,t2;
+#
+# Bug#751350: crash with pushed condition for outer references when
+# there should be none of such conditions
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0),(0,0);
+set @optimizer_switch_save=@@optimizer_switch;
+set @@optimizer_switch='semijoin=off,materialization=on,in_to_exists=on';
+EXPLAIN
+SELECT b FROM t1
+WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT b FROM t1
+WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+GROUP BY b;
+b
+0
+set @@optimizer_switch=@optimizer_switch_save;
+DROP TABLE t1;
+#
+# Bug #11765713 58705:
+# OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES
+# CREATED BY OPT_SUM_QUERY
+#
+CREATE TABLE t1(a INT NOT NULL, KEY (a));
+INSERT INTO t1 VALUES (0), (1);
+SELECT 1 as foo FROM t1 WHERE a < SOME
+(SELECT a FROM t1 WHERE a <=>
+(SELECT a FROM t1)
+);
+ERROR 21000: Subquery returns more than 1 row
+SELECT 1 as foo FROM t1 WHERE a < SOME
+(SELECT a FROM t1 WHERE a <=>
+(SELECT a FROM t1 where a is null)
+);
+foo
+DROP TABLE t1;
+CREATE TABLE t1 (a int(11), b varchar(1));
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+delete from t1;
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+drop table t1;
+#
+# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3)) ;
+INSERT IGNORE INTO t2 VALUES (NULL,NULL),(5,0);
+DROP TABLE IF EXISTS t3;
+Warnings:
+Note 1051 Unknown table 't3'
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ;
+r
+NULL
+5
+NULL
+5
+DROP TABLE t1, t2, t3;
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+1
+1
+1
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1, t2;
+create table t2(i int);
+insert into t2 values(0);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+CREATE VIEW v1 AS
+SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2
+;
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key)
+);
+SELECT t1.pk
+FROM t1
+WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 )
+;
+pk
+SET SESSION sql_mode=@old_sql_mode;
+drop table t2, t1;
+drop view v1;
+#
+# BUG#50257: Missing info in REF column of the EXPLAIN
+# lines for subselects
+#
+CREATE TABLE t1 (a INT, b INT, INDEX (a));
+INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref a a 5 const 1
+EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 SUBQUERY t1 ref a a 5 const 1 Using index
+DROP TABLE t1;
+#
+# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS)
+# (duplicate of LP bug #888456)
+#
+CREATE TABLE t1 (f1 varchar(1));
+INSERT INTO t1 VALUES ('v'),('s');
+CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key));
+INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'),
+('d'),('y'),('t'),('d'),('s');
+EXPLAIN
+SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2
+WHERE EXISTS (SELECT DISTINCT f1_key FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY table1 ALL NULL NULL NULL NULL 2
+1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index
+SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2
+WHERE EXISTS (SELECT DISTINCT f1_key FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1);
+f1 f1_key
+v j
+s j
+v v
+s v
+v c
+s c
+v m
+s m
+v d
+s d
+v d
+s d
+v y
+s y
+v t
+s t
+v d
+s d
+v s
+s s
+DROP TABLE t1,t2;
+#
+# LP bug 919427: EXPLAIN for a query over a single-row table
+# with IN subquery in WHERE condition
+#
+CREATE TABLE ot (
+col_int_nokey int(11),
+col_varchar_nokey varchar(1)
+) ;
+INSERT INTO ot VALUES (1,'x');
+CREATE TABLE it1(
+col_int_key int(11),
+col_varchar_key varchar(1),
+KEY idx_cvk_cik (col_varchar_key,col_int_key)
+);
+INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f');
+CREATE TABLE it2 (
+col_int_key int(11),
+col_varchar_key varchar(1),
+col_varchar_key2 varchar(1),
+KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key),
+KEY idx_cvk_cik (col_varchar_key, col_int_key)
+);
+INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f');
+EXPLAIN
+SELECT col_int_nokey FROM ot
+WHERE col_varchar_nokey IN
+(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY it1 index_subquery idx_cvk_cik idx_cvk_cik 9 func,const 2 Using index; Using where
+SELECT col_int_nokey FROM ot
+WHERE col_varchar_nokey IN
+(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL);
+col_int_nokey
+1
+EXPLAIN
+SELECT col_int_nokey FROM ot
+WHERE (col_varchar_nokey, 'x') IN
+(SELECT col_varchar_key, col_varchar_key2 FROM it2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY it2 index_subquery idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 func,const 1 Using index; Using where
+SELECT col_int_nokey FROM ot
+WHERE (col_varchar_nokey, 'x') IN
+(SELECT col_varchar_key, col_varchar_key2 FROM it2);
+col_int_nokey
+1
+DROP TABLE ot,it1,it2;
+#
+# MDEV-746
+# Bug#13651009 WRONG RESULT FROM DERIVED TABLE IF THE SUBQUERY
+# HAS AN EMPTY RESULT
+#
+CREATE TABLE t1 (
+pk int NOT NULL,
+col_int_nokey int NOT NULL,
+col_int_key int NOT NULL,
+col_time_key time 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_time_key (col_time_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM;
+CREATE TABLE t2 (
+pk int NOT NULL AUTO_INCREMENT,
+col_int_nokey int NOT NULL,
+col_int_key int NOT NULL,
+col_time_key time 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_time_key (col_time_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,4,4,'00:00:00','b','b');
+SET @var2:=4, @var3:=8;
+
+Testcase without inner subquery
+EXPLAIN SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3;
+@var3:=12 pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+SELECT @var3;
+@var3
+8
+EXPLAIN SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3 ) AS alias3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE <derived2> system NULL NULL NULL NULL 0 const row not found
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT * FROM ( SELECT @var3:=12, sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key + NULL) IS NULL OR
+sq4_alias1.col_varchar_key = @var3 ) AS alias3;
+@var3:=12 pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+SELECT @var3;
+@var3
+8
+
+Testcase with inner subquery; crashed WL#6095
+SET @var3=8;
+EXPLAIN SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3));
+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 c_sq1_alias1 system PRIMARY NULL NULL NULL 1
+SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3));
+pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+EXPLAIN SELECT * FROM ( SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3)) ) AS alias3;
+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
+3 DEPENDENT SUBQUERY c_sq1_alias1 system PRIMARY NULL NULL NULL 1
+SELECT * FROM ( SELECT sq4_alias1.*
+FROM t1 AS sq4_alias1
+WHERE (sq4_alias1.col_varchar_key , sq4_alias1.col_varchar_nokey)
+NOT IN
+(SELECT c_sq1_alias1.col_varchar_key AS c_sq1_field1,
+c_sq1_alias1.col_varchar_nokey AS c_sq1_field2
+FROM t2 AS c_sq1_alias1
+WHERE (c_sq1_alias1.col_int_nokey != @var2
+OR c_sq1_alias1.pk != @var3)) ) AS alias3;
+pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
+DROP TABLE t1,t2;
+End of 5.2 tests
+#
+# BUG#779885: Crash in eliminate_item_equal with materialization=on in
+#
+CREATE TABLE t1 ( f1 int );
+INSERT INTO t1 VALUES (19), (20);
+CREATE TABLE t2 ( f10 varchar(32) );
+INSERT INTO t2 VALUES ('c'),('d');
+CREATE TABLE t3 ( f10 varchar(32) );
+INSERT INTO t3 VALUES ('a'),('b');
+SELECT *
+FROM t1
+WHERE
+( 't' ) IN (
+SELECT t3.f10
+FROM t3
+JOIN t2
+ON t2.f10 = t3.f10
+);
+f1
+DROP TABLE t1,t2,t3;
+#
+# BUG LP:813473: Wrong result with outer join + NOT IN subquery
+# This bug is a duplicate of Bug#11764086 whose test case is added below
+#
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (5),(6);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (20,9),(20,9);
+create table t3 (d int, e int);
+insert into t3 values (2, 9), (3,10);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+EXPLAIN
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b , t1.c) NOT IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b, t1.c) NOT IN (SELECT * from t3);
+b c
+9 NULL
+9 NULL
+SET optimizer_switch=@save_optimizer_switch;
+drop table t1, t2, t3;
+#
+# Bug#11764086: Null left operand to NOT IN in WHERE clause
+# behaves differently than real NULL
+#
+CREATE TABLE parent (id int);
+INSERT INTO parent VALUES (1), (2);
+CREATE TABLE child (parent_id int, other int);
+INSERT INTO child VALUES (1,NULL);
+# Offending query (c.parent_id is NULL for null-complemented rows only)
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id NOT IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+);
+id parent_id
+1 1
+2 NULL
+# Some syntactic variations with IS FALSE and IS NOT TRUE
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS NOT TRUE;
+id parent_id
+1 1
+2 NULL
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS FALSE;
+id parent_id
+1 1
+2 NULL
+DROP TABLE parent, child;
+# End of test for bug#11764086.
+#
+# Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET ||
+# BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0), (1);
+CREATE TABLE t2(
+b TEXT,
+c INT,
+PRIMARY KEY (b(1))
+);
+INSERT INTO t2 VALUES ('a', 2), ('b', 3);
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ORDER BY b
+);
+1
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+GROUP BY b
+);
+1
+DROP TABLE t1, t2;
+#
+# LP bug #826279: assertion failure with GROUP BY a result of subquery
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0), (0);
+CREATE TABLE t2 (a int, b int, c int);
+INSERT INTO t2 VALUES (10,7,0), (0,7,0);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,7), (0,7);
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+7 NULL
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+7 NULL
+7 10
+DROP TABLE t1,t2,t3;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+#
+# LP BUG#833777 Performance regression with deeply nested subqueries
+#
+create table t1 (a int not null, b char(10) not null);
+insert into t1 values (1, 'a');
+set @@optimizer_switch='in_to_exists=on,semijoin=off,materialization=off,subquery_cache=off';
+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)))))))))))))))))))))))))))));
+a
+1
+set @@optimizer_switch=@subselect_tmp;
+drop table t1;
+#
+# LP BUG#894397 Wrong result with in_to_exists, constant table , semijoin=OFF,materialization=OFF
+#
+CREATE TABLE t1 (a varchar(3));
+INSERT INTO t1 VALUES ('AAA'),('BBB');
+CREATE TABLE t2 (a varchar(3));
+INSERT INTO t2 VALUES ('CCC');
+set @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquery_cache=off';
+SELECT * FROM t1 WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.a < 'ZZZ');
+a
+set @@optimizer_switch=@subselect_tmp;
+drop table t1, t2;
+#
+# LP bug #859375: Assertion `0' failed in st_select_lex_unit::optimize
+# with view , UNION and prepared statement (rewriting fake_select
+# condition).
+#
+CREATE TABLE t1 ( f1 int NOT NULL, f4 varchar(1) NOT NULL) ;
+INSERT INTO t1 VALUES (6,'d'),(7,'y');
+CREATE TABLE t2 ( f1 int NOT NULL, f2 int NOT NULL) ;
+INSERT INTO t2 VALUES (10,7);
+CREATE VIEW v2 AS SELECT * FROM t2;
+PREPARE st1 FROM "
+ SELECT *
+ FROM t1
+ LEFT JOIN v2 ON ( v2.f2 = t1.f1 )
+ WHERE v2.f1 NOT IN (
+ SELECT 1 UNION
+ SELECT 247
+ )
+";
+EXECUTE st1;
+f1 f4 f1 f2
+7 y 10 7
+deallocate prepare st1;
+DROP VIEW v2;
+DROP TABLE t1,t2;
+#
+# LP bug #887458 Crash in subselect_union_engine::no_rows with
+# double UNION and join_cache_level=3,8
+# (IN/ALL/ANY optimizations should not be applied to fake_select)
+CREATE TABLE t2 ( a int, b varchar(1)) ;
+INSERT IGNORE INTO t2 VALUES (8,'y'),(8,'y');
+CREATE TABLE t1 ( b varchar(1)) ;
+INSERT IGNORE INTO t1 VALUES (NULL),(NULL);
+set @save_join_cache_level=@@join_cache_level;
+SET SESSION join_cache_level=3;
+SELECT *
+FROM t1, t2
+WHERE t2.b IN (
+SELECT 'm' UNION
+SELECT 'm'
+) OR t1.b <> SOME (
+SELECT 'v' UNION
+SELECT 't'
+);
+b a b
+set @@join_cache_level= @save_join_cache_level;
+drop table t1,t2;
+#
+# LP bug #885162 Got error 124 from storage engine with UNION inside
+# subquery and join_cache_level=3..8
+# (IN/ALL/ANY optimizations should not be applied to fake_select)
+#
+CREATE TABLE t1 (
+f1 varchar(1) DEFAULT NULL
+);
+INSERT INTO t1 VALUES ('c');
+set @save_join_cache_level=@@join_cache_level;
+SET SESSION join_cache_level=8;
+SELECT * FROM t1 WHERE t1.f1 IN ( SELECT 'k' UNION SELECT 'e' );
+f1
+set @@join_cache_level= @save_join_cache_level;
+drop table t1;
+#
+# LP BUG#747278 incorrect values of the NULL (no rows) single
+# row subquery requested via element_index() interface
+#
+CREATE TABLE t1 (f1a int, f1b int) ;
+INSERT IGNORE INTO t1 VALUES (1,1),(2,2);
+CREATE TABLE t2 ( f2 int);
+INSERT IGNORE INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (f3a int default 1, f3b int default 2);
+INSERT INTO t3 VALUES (1,1),(2,2);
+set @old_optimizer_switch = @@session.optimizer_switch;
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,subquery_cache=off,semijoin=off';
+SELECT (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+SELECT (SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+set @@session.optimizer_switch=@old_optimizer_switch;
+SELECT (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+SELECT (SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1) FROM t2;
+(SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1) FROM t2;
+(SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1) FROM t2;
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+NULL
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1)
+NULL
+select (null, null) = (null, null);
+(null, null) = (null, null)
+NULL
+SELECT (SELECT f3a, f3a FROM t3 where f3a > 3) = (0, 0);
+(SELECT f3a, f3a FROM t3 where f3a > 3) = (0, 0)
+NULL
+drop tables t1,t2,t3;
+#
+# LP BUG#825051 Wrong result with date/datetime and subquery with GROUP BY and in_to_exists
+#
+CREATE TABLE t1 (a date, KEY (a)) ;
+INSERT INTO t1 VALUES ('2009-01-01'),('2009-02-02');
+set @old_optimizer_switch = @@optimizer_switch;
+SET @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index
+2 DEPENDENT SUBQUERY t1 index_subquery a a 4 func 2 Using index
+SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+a
+2009-01-01
+2009-02-02
+SET @@optimizer_switch='semijoin=off,materialization=on,in_to_exists=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL a 4 NULL 2 Using where; Using index
+2 MATERIALIZED t1 index NULL a 4 NULL 2 Using index
+SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+a
+2009-01-01
+2009-02-02
+set @@optimizer_switch=@old_optimizer_switch;
+drop table t1;
+#
+# LP BUG#908269 incorrect condition in case of subqueries depending
+# on constant tables
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 ( b INT ) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (4),(5);
+SET optimizer_switch='subquery_cache=off';
+SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) )
+1
+NULL
+SELECT ( SELECT b FROM t2 WHERE b = a OR b * 0) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR b * 0)
+1
+NULL
+SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1;
+( SELECT b FROM t2 WHERE b = a OR rand() * 0)
+1
+NULL
+drop table t1,t2,t3;
+set optimizer_switch=@subselect_tmp;
+#
+# LP BUG#905353 Wrong non-empty result with a constant table,
+# aggregate function in subquery, MyISAM or Aria
+#
+CREATE TABLE t1 ( a INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1);
+SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 );
+a
+drop table t1;
+#
+# LP BUG#985667 Wrong result with subquery in SELECT clause, and constant table in
+# main query and implicit grouping
+#
+CREATE TABLE t1 (f1 int) engine=MyISAM;
+INSERT INTO t1 VALUES (7),(8);
+CREATE TABLE t2 (f2 int, f3 varchar(1)) engine=MyISAM;
+INSERT INTO t2 VALUES (3,'f');
+EXPLAIN
+SELECT COUNT(f1), (SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2
+SELECT COUNT(f1), (SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 NULL
+EXPLAIN
+SELECT COUNT(f1), exists(SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2
+SELECT COUNT(f1), exists(SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 0
+EXPLAIN
+SELECT COUNT(f1), f2 > ALL (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2 Using where
+SELECT COUNT(f1), f2 > ALL (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 1
+EXPLAIN
+SELECT COUNT(f1), f2 IN (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+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 ALL NULL NULL NULL NULL 2 Using where
+SELECT COUNT(f1), f2 IN (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+COUNT(f1) f4
+0 0
+drop table t1,t2;
+#
+# LP BUG#1002079 Server crashes in Item_singlerow_subselect::val_int with constant table,
+# HAVING, UNION in subquery
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (7),(0);
+CREATE TABLE t2 (b INT);
+EXPLAIN
+SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
+f1 f2
+drop table t1,t2;
+#
+# LP BUG#1008686 Server crashes in subselect_union_engine::no_rows on SELECT with impossible
+# WHERE and UNION in HAVING
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(7);
+EXPLAIN
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 0 HAVING a NOT IN ( SELECT 2 UNION SELECT 5 ) OR min_a != 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 NULL NULL NULL NULL NULL NULL NULL No tables used
+3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 0 HAVING a NOT IN ( SELECT 2 UNION SELECT 5 ) OR min_a != 1;
+min_a a
+EXPLAIN
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 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 ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 2 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 1;
+min_a a
+drop table t1;
+#
+# MDEV-367: Different results with and without subquery_cache on
+# a query with a constant NOT IN condition
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2),(3);
+set @mdev367_optimizer_switch = @@optimizer_switch;
+set optimizer_switch = 'subquery_cache=on';
+SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
+a
+SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
+a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
+1 NULL
+2 NULL
+3 NULL
+set optimizer_switch=@mdev367_optimizer_switch;
+set optimizer_switch = 'subquery_cache=off';
+SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
+a
+SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
+a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
+1 NULL
+2 NULL
+3 NULL
+set optimizer_switch=@mdev367_optimizer_switch;
+DROP TABLE t1;
+#
+# MDEV-521 single value subselect transformation problem
+#
+CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('u1'),('u2');
+SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) );
+f1
+u1
+u2
+FLUSH TABLES;
+SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) );
+f1
+u1
+u2
+DROP TABLE t1;
+# return optimizer switch changed in the beginning of this test
+set optimizer_switch=@subselect_tmp;
+set @optimizer_switch_for_subselect_test=null;
+set @join_cache_level_for_subselect_test=NULL;
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..584c184870d
--- /dev/null
+++ b/mysql-test/r/subselect_nulls.result
@@ -0,0 +1,117 @@
+drop table if exists x1;
+drop table if exists x2;
+set @tmp_subselect_nulls=@@optimizer_switch;
+set optimizer_switch='semijoin=off';
+create table x1(k int primary key, d1 int, d2 int);
+create table x2(k int primary key, d1 int, d2 int);
+insert into x1 values
+(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
+set optimizer_switch= @tmp_subselect_nulls;
+drop table x1;
+drop table x2;
diff --git a/mysql-test/r/subselect_partial_match.result b/mysql-test/r/subselect_partial_match.result
new file mode 100644
index 00000000000..9dc2b44fd30
--- /dev/null
+++ b/mysql-test/r/subselect_partial_match.result
@@ -0,0 +1,985 @@
+set @save_optimizer_switch=@@optimizer_switch;
+-------------------------------
+Part 1: Feature tests.
+-------------------------------
+Default for all tests.
+set @@optimizer_switch = "materialization=on,in_to_exists=off,semijoin=off,subquery_cache=off";
+set @test_default_opt_switch = @@optimizer_switch;
+set @in_exists = "materialization=off,in_to_exists=on,semijoin=off,subquery_cache=off";
+-------------------------------------------------------------------------
+Schema requires partial matching, but data analysis discoveres there is
+no need. This is possible only if all outer columns are not NULL.
+-------------------------------------------------------------------------
+create table t1 (a1 char(8) not null, a2 char(8) not null);
+create table t2 (b1 char(8), b2 char(8));
+insert into t1 values ('1 - 00', '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 00', '2 - 00');
+insert into t2 values ('1 - 01', NULL );
+insert into t2 values (NULL , '2 - 02');
+insert into t2 values (NULL , NULL );
+insert into t2 values ('1 - 02', '2 - 02');
+select * from t1
+where (a1, a2) not in (select * from t2 where b1 is not null and b2 is not null);
+a1 a2
+1 - 01 2 - 01
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+a1 a2 in_res
+1 - 00 2 - 00 0
+1 - 01 2 - 01 NULL
+drop table t1, t2;
+-------------------------------------------------------------------------
+NULLs in the outer columns, no NULLs in the suqbuery
+-------------------------------------------------------------------------
+create table t1 (a1 char(8), a2 char(8));
+create table t2 (b1 char(8) not null, b2 char(8) not null);
+insert into t1 values (NULL , '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+insert into t1 values (NULL , NULL );
+insert into t2 values ('1 - 00', '2 - 00');
+insert into t2 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 02', '2 - 00');
+select * from t1
+where (a1, a2) not in (select * from t2 where b1 is not null and b2 is not null);
+a1 a2
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+a1 a2 in_res
+NULL 2 - 00 NULL
+1 - 01 2 - 01 0
+NULL NULL NULL
+select * from t1
+where (a1, a2) in (select * from t2 where b1 is not null and b2 is not null);
+a1 a2
+1 - 01 2 - 01
+select a1, a2, (a1, a2) in (select * from t2) as in_res from t1;
+a1 a2 in_res
+NULL 2 - 00 NULL
+1 - 01 2 - 01 1
+NULL NULL NULL
+drop table t1, t2;
+-------------------------------------------------------------------------
+NULLs in the outer column, NULLs in the subquery, there is
+no value match in any column, but there is a partial match
+such that some of the matching NULLs are in the outer columns,
+the other NULLs are in the inner columns.
+-------------------------------------------------------------------------
+create table t1 (a1 char(1), a2 char(1), a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+insert into t1 values ('c', NULL, 'a');
+insert into t2 values (NULL, 'x', NULL);
+insert into t2 values (NULL, 'y', NULL);
+insert into t2 values ('o', 'z', 'p');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+c NULL a NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+c NULL a NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+c NULL a NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch = @test_default_opt_switch;
+drop table t1, t2;
+create table t1 (a1 char(1), a2 char(1) not null, a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+insert into t1 values (NULL, 'y', NULL);
+insert into t2 values ('v', 'x', NULL);
+insert into t2 values (NULL, 'y', 'w');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+NULL y NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+NULL y NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+NULL y NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch = @test_default_opt_switch;
+drop table t1, t2;
+-------------------------------------------------------------------------
+There is only one column in the subquery to complement the NULLs in the
+outer reference. It is a NULL column, so a match is guaranteed.
+-------------------------------------------------------------------------
+create table t1 (a1 char(1), a2 char(1), a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+insert into t1 values (NULL, 'g', NULL);
+insert into t2 values ('z', NULL, 'y');
+insert into t2 values (NULL, 'z', 'y');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+NULL g NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+NULL g NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+NULL g NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch = @test_default_opt_switch;
+drop table t1, t2;
+-------------------------------------------------------------------------
+The intersection of the NULL bitmaps is empty because the ranges
+of NULL bits do not overlap.
+-------------------------------------------------------------------------
+create table t1 (a1 char(1), a2 char(1), a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+insert into t1 values ('b', 'g', NULL);
+insert into t2 values ('z', NULL, 'y');
+insert into t2 values (NULL, 'z', 'y');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+b g NULL 0
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+b g NULL
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+b g NULL 0
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+b g NULL
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+b g NULL 0
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+b g NULL
+drop table t1, t2;
+-------------------------------------------------------------------------
+The intersection of the NULL bitmaps is non-empty, and there is a
+non-NULL column.
+-------------------------------------------------------------------------
+create table t1 (a1 char(1), a2 char(1), a3 char(1) not null, a4 char(10));
+create table t2 (b1 char(1), b2 char(1), b3 char(1), b4 char(1));
+insert into t1 values ('a', 'g', 'x', NULL);
+insert into t2 values ('z', NULL, 'y', 'x');
+insert into t2 values (NULL, NULL, 'x', 'y');
+insert into t2 values ('x', 'w', 'z', NULL);
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+a g x NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+a g x NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+a g x NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+drop table t1, t2;
+-------------------------------------------------------------------------
+Value match in one row, but the NULL complement match in another.
+The result must be false.
+-------------------------------------------------------------------------
+create table t1 (a1 char(2), a2 char(1), a3 char(1) not null, a4 char(10));
+create table t2 (b1 char(2), b2 char(1), b3 char(1), b4 char(1));
+insert into t1 values ('99', NULL, 'j', 'f');
+insert into t2 values ('01', NULL, 'y', NULL);
+insert into t2 values ('02', NULL, 'x', 'y');
+insert into t2 values ('03', 'q', 'y', 'x');
+insert into t2 values (NULL, 'q', 'm', 'p');
+insert into t2 values ('m', 'z', 'j', NULL);
+insert into t2 values (NULL, 'z', 'b', NULL);
+insert into t2 values (NULL, 'z', 'a', NULL);
+insert into t2 values ('34', 'q', 'y', 'x');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+99 NULL j f 0
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+99 NULL j f
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+99 NULL j f 0
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+99 NULL j f
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+99 NULL j f 0
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 8 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+99 NULL j f
+drop table t1, t2;
+-------------------------------------------------------------------------
+Test the intersection of larger number of rows with NULL, such that
+the number is at the boundary 32. This test is based on the implementation
+of MY_BITMAP which uses 32 bit words, and the intersection operation works
+by intersecting the bitmap word by word.
+-------------------------------------------------------------------------
+create table t1 (a1 char(2), a2 char(2), a3 char(1), a4 char(10)) ENGINE=MyISAM;
+create table t2 (b1 char(2), b2 char(2), b3 char(1), b4 char(1)) ENGINE=MyISAM;
+insert into t1 values (NULL, '98', NULL, 'b');
+insert into t1 values (NULL, '99', NULL, 'c');
+insert into t2 values ('00', 'rr', 'y', NULL);
+insert into t2 values ('01', 'rr', 'y', NULL);
+insert into t2 values ('02', NULL, 'x', 'y');
+insert into t2 values ('03', 'qq', 'y', 'x');
+insert into t2 values ('04', 'qq', 'm', 'p');
+insert into t2 values ('05', 'rr', 'y', NULL);
+insert into t2 values ('06', NULL, 'x', 'y');
+insert into t2 values ('07', 'qq', 'y', 'x');
+insert into t2 values ('08', 'qq', 'm', 'q');
+insert into t2 values ('09', 'rr', 'y', NULL);
+insert into t2 values ('10', NULL, 'x', 'y');
+insert into t2 values ('11', 'qq', 'y', 'x');
+insert into t2 values ('12', 'qq', 'm', 'k');
+insert into t2 values ('13', 'rr', 'y', NULL);
+insert into t2 values ('14', NULL, 'x', 'y');
+insert into t2 values ('15', 'qq', 'y', 'x');
+insert into t2 values ('16', 'qq', 'm', 's');
+insert into t2 values ('17', 'rr', 'y', NULL);
+insert into t2 values ('18', NULL, 'x', 'y');
+insert into t2 values ('19', 'qq', 'y', 'x');
+insert into t2 values ('20', 'qq', 'm', 't');
+insert into t2 values ('21', 'rr', 'y', NULL);
+insert into t2 values ('22', NULL, 'x', 'y');
+insert into t2 values ('23', 'qq', 'y', 'x');
+insert into t2 values ('24', 'qq', 'm', 'u');
+insert into t2 values ('25', 'rr', 'y', NULL);
+insert into t2 values ('26', NULL, 'x', 'y');
+insert into t2 values ('27', 'qq', 'y', 'x');
+insert into t2 values ('28', 'qq', 'm', 'y');
+insert into t2 values ('29', 'rr', 'y', NULL);
+insert into t2 values ('30', NULL, 'x', 'z');
+insert into t2 values ('31', 'ss', 'h', NULL);
+insert into t2 values ('32', 'vv', 'i', NULL);
+the only partial matching row
+insert into t2 values ('33', NULL, 'j', NULL);
+insert into t2 values ('34', 'qq', 'y', 'x');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b NULL
+NULL 99 NULL c NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b NULL
+NULL 99 NULL c NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b NULL
+NULL 99 NULL c NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+change the mathcing row to be the last one in the first bitmap word
+update t2 set b2 = 'zz' where b1 = 33;
+update t2 set b2 = NULL where b1 = 31;
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b NULL
+NULL 99 NULL c NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b NULL
+NULL 99 NULL c NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b NULL
+NULL 99 NULL c NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+drop table t1, t2;
+-------------------------------------------------------------------------
+All columns require partial matching (no non-null columns)
+-------------------------------------------------------------------------
+TODO
+-------------------------------------------------------------------------
+Both non-NULL columns and columns with NULLs
+-------------------------------------------------------------------------
+TODO
+-------------------------------------------------------------------------
+Covering NULL rows
+-------------------------------------------------------------------------
+create table t1 (a1 char(8), a2 char(8));
+create table t2 (b1 char(8), b2 char(8));
+insert into t1 values ('1 - 00', '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 01', NULL );
+insert into t2 values (NULL , '2 - 02');
+insert into t2 values (NULL , NULL );
+insert into t2 values ('1 - 02', '2 - 02');
+select * from t1
+where (a1, a2) not in (select * from t2);
+a1 a2
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+a1 a2 in_res
+1 - 00 2 - 00 NULL
+1 - 01 2 - 01 NULL
+insert into t2 values ('1 - 01', '2 - 01');
+select * from t1
+where (a1, a2) not in (select * from t2);
+a1 a2
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+a1 a2 in_res
+1 - 00 2 - 00 NULL
+1 - 01 2 - 01 0
+select * from t1
+where (a1, a2) in (select * from t2);
+a1 a2
+1 - 01 2 - 01
+select a1, a2, (a1, a2) in (select * from t2) as in_res from t1;
+a1 a2 in_res
+1 - 00 2 - 00 NULL
+1 - 01 2 - 01 1
+drop table t1, t2;
+-------------------------------------------------------------------------
+Covering NULL columns
+-------------------------------------------------------------------------
+this case affects only the rowid-merge algorithm
+set @@optimizer_switch="partial_match_rowid_merge=on,partial_match_table_scan=off";
+create table t1 (a1 char(8) not null, a2 char(8), a3 char(8) not null);
+create table t2 (b1 char(8) not null, b2 char(8), b3 char(8) not null);
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+insert into t2 values ('1 - 01', NULL, '3 - x1');
+insert into t2 values ('1 - 02', NULL, '3 - 02');
+insert into t2 values ('1 - 00', NULL, '3 - 00');
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+a1 a2 a3
+1 - 01 2 - 01 3 - 01
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 1
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+a1 a2 a3
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 0
+drop table t1, t2;
+create table t1 (a1 char(8), a2 char(8), a3 char(8) not null);
+create table t2 (b1 char(8), b2 char(8), b3 char(8) not null);
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+insert into t2 values (NULL, NULL, '3 - x1');
+insert into t2 values (NULL, NULL, '3 - 02');
+insert into t2 values (NULL, NULL, '3 - 00');
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+a1 a2 a3
+1 - 01 2 - 01 3 - 01
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 1
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+a1 a2 a3
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 0
+drop table t1, t2;
+-------------------------------------------------------------------------
+Covering NULL row, and a NULL column
+-------------------------------------------------------------------------
+create table t1 (a1 char(8) not null, a2 char(8), a3 char(8));
+create table t2 (b1 char(8), b2 char(8), b3 char(8));
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+insert into t2 values ('1 - 01', NULL, '3 - x1');
+insert into t2 values (NULL , NULL, NULL );
+insert into t2 values ('1 - 00', NULL, '3 - 00');
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+a1 a2 a3
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 NULL
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+a1 a2 a3
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 NULL
+drop table t1, t2;
+-------------------------------------------------------------------------
+Covering NULL row, and covering NULL columns
+-------------------------------------------------------------------------
+create table t1 (a1 char(8) not null, a2 char(8), a3 char(8));
+create table t2 (b1 char(8), b2 char(8), b3 char(8));
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+insert into t2 values (NULL, NULL, NULL);
+insert into t2 values (NULL, NULL, NULL);
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+a1 a2 a3
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 NULL
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+a1 a2 a3
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 NULL
+drop table t1, t2;
+-------------------------------------------------------------------------
+Small buffer for the rowid_merge partial match algorithm that forces
+reverting to table scan partial match.
+-------------------------------------------------------------------------
+set @save_rowid_merge_buff_size = @@rowid_merge_buff_size;
+set @@rowid_merge_buff_size = 0;
+create table t1 (a1 char(2), a2 char(2), a3 char(1), a4 char(10));
+create table t2 (b1 char(2), b2 char(2), b3 char(1), b4 char(1));
+insert into t1 values (NULL, '98', NULL, 'b');
+insert into t1 values (NULL, '99', NULL, 'c');
+insert into t2 values ('00', 'rr', 'y', NULL);
+insert into t2 values ('01', 'rr', 'y', NULL);
+insert into t2 values ('02', NULL, 'x', 'y');
+insert into t2 values ('03', 'qq', 'y', 'x');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b 0
+NULL 99 NULL c 0
+drop table t1, t2;
+set @@rowid_merge_buff_size = @save_rowid_merge_buff_size;
+-------------------------------
+Part 2: Test cases for bugs.
+-------------------------------
+drop table if exists t1, t2;
+#
+# LP BUG#608744
+#
+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;
+#
+# 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 @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on';
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+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> ALL NULL NULL NULL NULL 2 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+3 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1003 select `table1`.`a1` AS `a1`,`table1`.`a2` AS `a2` from (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (not(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b2` from `test`.`t2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery3>`.`b2`)))))))) `table1`
+set optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1, t2;
+#
+# LP BUG#613009 Crash in Ordered_key::get_field_idx
+#
+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 MATERIALIZED 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;
+#
+# 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 @@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
+drop table t1, t2;
+#
+# LP BUG#809245 Second assertion `bit < (map)->n_bits' with partial_match_merge
+#
+CREATE TABLE t1 (d varchar(32)) ;
+INSERT INTO t1 VALUES ('r');
+CREATE TABLE t2 ( a int, c varchar(32)) ;
+INSERT INTO t2 VALUES (5,'r');
+CREATE TABLE t3 ( a int NOT NULL , d varchar(32)) ;
+INSERT INTO t3 VALUES (10,'g');
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+EXPLAIN SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+SELECT t3.d , t2.c
+FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t3 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 system NULL NULL NULL NULL 1
+SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+SELECT t3.d , t2.c
+FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+d
+r
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+EXPLAIN SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+SELECT t3.d , t2.c
+FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
+SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+SELECT t3.d , t2.c
+FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+d
+r
+drop table t1, t2, t3;
+#
+# LP BUG#809266 Diverging results with partial_match_rowid_merge=on
+#
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (0),(0);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (6,3), (9,NULL);
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+c
+0
+0
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+c
+0
+0
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+c
+0
+0
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+c
+0
+0
+drop table t1, t2;
+#
+# LP BUG#856152 Wrong result with NOT IN subquery and partial_match_rowid_merge
+#
+CREATE TABLE t1 ( f1 integer NOT NULL , f2 integer) ;
+INSERT INTO t1 VALUES (3,3),(48,NULL),(49,1);
+CREATE TABLE t2 ( f3 int) ;
+INSERT INTO t2 VALUES (5);
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+f3
+5
+set @@optimizer_switch='in_to_exists=on,materialization=off';
+EXPLAIN SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
+SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+f3
+5
+drop table t1, t2;
+#
+# LP BUG#869036 Wrong result with in_to_exists=ON and NOT IN
+#
+create table outer_sq (f1 char(1), f2 char(1));
+insert into outer_sq values (NULL, 'c'), ('g', 'c');
+create table inner_sq (f3 char(1), f4 char(1));
+insert into inner_sq values(null, 'i'), ('v', null);
+All three strategies below must produce the same result.
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+SELECT outer_sq.*, (f1, f2) IN (select * from inner_sq) from outer_sq;
+f1 f2 (f1, f2) IN (select * from inner_sq)
+NULL c NULL
+g c 0
+SELECT * from outer_sq where (f1, f2) NOT IN (select * from inner_sq);
+f1 f2
+g c
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=off,partial_match_table_scan=on';
+SELECT outer_sq.*, (f1, f2) IN (select * from inner_sq) from outer_sq;
+f1 f2 (f1, f2) IN (select * from inner_sq)
+NULL c NULL
+g c 0
+SELECT * from outer_sq where (f1, f2) NOT IN (select * from inner_sq);
+f1 f2
+g c
+set @@optimizer_switch='in_to_exists=on,materialization=off';
+SELECT outer_sq.*, (f1, f2) IN (select * from inner_sq) from outer_sq;
+f1 f2 (f1, f2) IN (select * from inner_sq)
+NULL c NULL
+g c 0
+SELECT * from outer_sq where (f1, f2) NOT IN (select * from inner_sq);
+f1 f2
+g c
+drop table outer_sq, inner_sq;
+#
+# LP BUG#893486 Wrong result with partial_match_rowid_merge , NOT IN , NULLs
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (0,NULL),(2,NULL);
+CREATE TABLE t2 (c int, d int);
+INSERT INTO t2 VALUES (2,3),(4,5),(6, NULL);
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+EXPLAIN SELECT * FROM t1 WHERE (a, b) NOT IN (SELECT c, d FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3
+SELECT * FROM t1 WHERE (a, b) NOT IN (SELECT c, d FROM t2);
+a b
+0 NULL
+SELECT a, b, (a, b) NOT IN (SELECT c, d FROM t2) subq_res FROM t1;
+a b subq_res
+0 NULL 1
+2 NULL NULL
+EXPLAIN SELECT * FROM t1 WHERE (a, b) NOT IN (SELECT c, d FROM t2 WHERE d is not 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 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * FROM t1 WHERE (a, b) NOT IN (SELECT c, d FROM t2 WHERE d is not NULL);
+a b
+0 NULL
+SELECT a, b, (a, b) NOT IN (SELECT c, d FROM t2 WHERE d is not NULL) subq_res FROM t1;
+a b subq_res
+0 NULL 1
+2 NULL NULL
+drop table t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result
new file mode 100644
index 00000000000..2f9f3da3cfd
--- /dev/null
+++ b/mysql-test/r/subselect_sj.result
@@ -0,0 +1,2775 @@
+drop table if exists t0, t1, t2, t3, t4, t5, t10, t11, t12;
+drop view if exists v1, v2, v3, v4;
+drop procedure if exists p1;
+set @subselect_sj_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj_test,'outer_join_with_cache=off');
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj_test,'semijoin_with_cache=off');
+set join_cache_level=1;
+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`.`t12`.`pk` = `test`.`t10`.`a`) and (`test`.`t10`.`pk` = `test`.`t1`.`a`))
+subqueries within outer joins go into ON expr.
+explAin extended
+select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
+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 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,`test`.`B`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`B`.`A` in <temporAry tABle> on distinct_key where ((`test`.`B`.`A` = `<suBquery2>`.`pk`))))))) where 1
+t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
+explAin extended
+select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
+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 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t1`.`A`,`test`.`t1`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`t1`.`A` in <temporAry tABle> on distinct_key where ((`test`.`t1`.`A` = `<suBquery2>`.`pk`))))))) where 1
+we shouldn't flatten if we're going to get a join of > MAX_TABLES.
+explain select * from
+t1 s00, t1 s01, t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
+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
+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`.`t1`.`pk` = `test`.`t0`.`pk`) and (`test`.`t2`.`vkey` = `test`.`t1`.`vnokey`))
+SELECT vkey FROM t0 WHERE pk IN
+(SELECT t1.pk FROM t0 t1 JOIN t0 t2 ON t2.vkey = t1.vnokey);
+vkey
+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
+0
+0
+0
+0
+2
+2
+3
+5
+5
+7
+7
+7
+8
+9
+9
+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 <subquery2> ALL distinct_key NULL NULL NULL 11
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED it1 index NULL int_key 4 NULL 2 Using index
+2 MATERIALIZED it2 ALL int_key,datetime_key NULL NULL NULL 20 Using where
+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 t1 ALL NULL NULL NULL NULL 7 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 100.00 Using where; FirstMatch(t1)
+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`.`t2`.`c` = `test`.`t1`.`a`) and <nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`)))))))
+show warnings;
+Level Code Message
+Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and <nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`)))))))
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+a
+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 <subquery2> eq_ref distinct_key distinct_key 11 func,func 1 100.00
+2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Rowid-ordered scan
+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; Rowid-ordered scan; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`c` = `test`.`t1`.`c`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`d` = `test`.`t1`.`d`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0);
+pk
+2
+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; Rowid-ordered scan; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`e` = `test`.`t1`.`e`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`f` = `test`.`t1`.`f`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`g` = `test`.`t1`.`g`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`h` = `test`.`t1`.`h`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`i` = `test`.`t1`.`i`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`j` = `test`.`t1`.`j`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`k` = `test`.`t1`.`k`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0);
+pk
+1
+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 <subquery2> ALL distinct_key NULL NULL NULL 15 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 18 100.00 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED 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`.`t2`.`varchar_nokey` = `test`.`t1`.`varchar_key`) and ((`test`.`t1`.`varchar_key` < '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 <subquery3> eq_ref distinct_key distinct_key 13 func 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 13 func 1
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 5 Using where
+2 MATERIALIZED 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;
+#
+# Bug#46692 "Crash occurring on queries with nested FROM subqueries
+# using materialization."
+#
+CREATE TABLE t1 (
+pk INTEGER PRIMARY KEY,
+int_key INTEGER,
+KEY int_key(int_key)
+);
+INSERT INTO t1 VALUES (10,186),(11,NULL),(12,2),(13,3),(14,0),(15,133),(16,1);
+CREATE TABLE t2 (
+pk INTEGER PRIMARY KEY,
+int_key INTEGER,
+KEY int_key(int_key)
+);
+INSERT INTO t2 VALUES (1,7),(2,2);
+SELECT * FROM t1 WHERE (140, 4) IN
+(SELECT t2.int_key, t2 .pk FROM t2 STRAIGHT_JOIN t1 ON t2.int_key);
+pk int_key
+DROP TABLE t1, t2;
+#
+# Bug#42353 "SELECT ... WHERE oe IN (SELECT w/ LEFT JOIN) query
+# causes crash."
+#
+CREATE TABLE t1 (
+pk INTEGER PRIMARY KEY,
+int_nokey INTEGER,
+int_key INTEGER,
+date_key DATE,
+datetime_nokey DATETIME,
+varchar_nokey VARCHAR(1)
+);
+CREATE TABLE t2 (
+date_nokey DATE
+);
+CREATE TABLE t3 (
+pk INTEGER PRIMARY KEY,
+int_nokey INTEGER,
+date_key date,
+varchar_key VARCHAR(1),
+varchar_nokey VARCHAR(1),
+KEY date_key (date_key)
+);
+SELECT date_key FROM t1
+WHERE (int_key, int_nokey)
+IN (SELECT t3.int_nokey, t3.pk
+FROM t2 LEFT JOIN t3 ON (t2.date_nokey < t3.date_key)
+WHERE t3.varchar_key <= t3.varchar_nokey OR t3.int_nokey <= t3.pk
+)
+AND (varchar_nokey <> 'f' OR NOT int_key < 7);
+date_key
+#
+# Bug#45933 "Crash in optimize_semijoin_nests on JOIN in subquery
+# + AND in outer query".
+#
+INSERT INTO t1 VALUES (10,7,5,'2009-06-16','2002-04-10 14:25:30','w'),
+(11,7,0,'0000-00-00','0000-00-00 00:00:00','s'),
+(12,4,0,'2003-07-14','2006-09-14 04:01:02','y'),
+(13,0,4,'2002-07-25','0000-00-00 00:00:00','c'),
+(14,1,8,'2007-07-03','0000-00-00 00:00:00','q'),
+(15,6,5,'2001-11-12','0000-00-00 00:00:00',''),
+(16,2,9,'0000-00-00','0000-00-00 00:00:00','j'),
+(29,9,1,'0000-00-00','2003-08-11 00:00:00','m');
+INSERT INTO t3 VALUES (1,9,'0000-00-00','b','b'),
+(2,2,'2002-09-17','h','h');
+SELECT t1.varchar_nokey FROM t1 JOIN t3 ON t1.datetime_nokey
+WHERE t1.varchar_nokey
+IN (SELECT varchar_nokey FROM t1
+WHERE (pk)
+IN (SELECT t3.int_nokey
+FROM t3 LEFT JOIN t1 ON t1.varchar_nokey
+WHERE t3.date_key BETWEEN '2008-06-07' AND '2006-06-26'
+ )
+);
+varchar_nokey
+DROP TABLE t1, t2, t3;
+#
+# Bug#45219 "Crash on SELECT DISTINCT query containing a
+# LEFT JOIN in subquery"
+#
+CREATE TABLE t1 (
+pk INTEGER NOT NULL,
+int_nokey INTEGER 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)
+);
+INSERT INTO t1 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 t2 LIKE t1;
+INSERT INTO t2 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 t3 LIKE t1;
+INSERT INTO t3 VALUES
+(10,8,'2007-08-19 08:08:38','i'),(11,0,'2000-05-21 03:51:51','');
+SELECT DISTINCT datetime_key FROM t1
+WHERE (int_nokey, pk)
+IN (SELECT t3.pk, t3.pk FROM t2 LEFT JOIN t3 ON t3.varchar_key)
+AND pk = 9;
+datetime_key
+DROP TABLE t1, t2, t3;
+#
+# BUG#53060: LooseScan semijoin strategy does not return all rows
+#
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=off';
+set optimizer_switch='firstmatch=off,loosescan=on';
+CREATE TABLE t1 (i INTEGER);
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
+CREATE TABLE t2 (i INTEGER, j INTEGER, KEY k(i, j));
+INSERT INTO t2 VALUES (1, 0), (1, 1), (2, 0), (2, 1);
+EXPLAIN
+SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index k k 10 NULL 4 Using where; Using index; LooseScan
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0);
+i
+1
+2
+DROP TABLE t1, t2;
+set optimizer_switch=@save_optimizer_switch;
+#
+# BUG#49453: re-execution of prepared statement with view
+# and semijoin crashes
+#
+CREATE TABLE t1 (city VARCHAR(50), country_id INT);
+CREATE TABLE t2 (country_id INT, country VARCHAR(50));
+INSERT INTO t1 VALUES
+('Batna',2),('Bchar',2),('Skikda',2),('Tafuna',3),('Algeria',2) ;
+INSERT INTO t2 VALUES (2,'Algeria'),(2,'AlgeriaDup'),(3,'XAmerican Samoa');
+CREATE VIEW v1 AS
+SELECT country_id as vf_country_id
+FROM t2
+WHERE LEFT(country,1) = "A";
+PREPARE stmt FROM "
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (SELECT vf_country_id FROM v1);
+";
+
+EXECUTE stmt;
+city country_id
+Batna 2
+Bchar 2
+Skikda 2
+Algeria 2
+EXECUTE stmt;
+city country_id
+Batna 2
+Bchar 2
+Skikda 2
+Algeria 2
+DROP TABLE t1,t2;
+DROP VIEW v1;
+#
+# Bug#54437 Extra rows with LEFT JOIN + semijoin
+#
+create table t1 (a int);
+create table t2 (a int);
+create table t3 (a int);
+insert into t1 values(1),(1);
+insert into t2 values(1),(1),(1),(1);
+insert into t3 values(2),(2);
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+set optimizer_switch='semijoin=off';
+explain
+select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a);
+a
+1
+1
+set optimizer_switch='semijoin=on';
+explain
+select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.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 t2 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary
+select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a);
+a
+1
+1
+set optimizer_switch=@save_optimizer_switch;
+drop table t1,t2,t3;
+#
+# Bug#55955: crash in MEMORY engine with IN(LEFT JOIN (JOIN))
+#
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+CREATE TABLE t3 (a INT);
+INSERT INTO t1 VALUES(1),(1);
+INSERT INTO t2 VALUES(1),(1);
+INSERT INTO t3 VALUES(2),(2);
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=off,materialization=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2inner ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+a
+1
+1
+set optimizer_switch='semijoin=off,materialization=on';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2inner ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+a
+1
+1
+set optimizer_switch='semijoin=on,materialization=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.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 t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary
+1 PRIMARY t2inner ALL NULL NULL NULL NULL 2
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+a
+1
+1
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# BUG#52329 - Wrong result: subquery materialization, IN,
+# non-null field followed by nullable
+#
+CREATE TABLE t1 (a1 CHAR(8) NOT NULL, a2 char(8) NOT NULL);
+CREATE TABLE t2a (b1 char(8), b2 char(8));
+CREATE TABLE t2b (b1 CHAR(8), b2 char(8) NOT NULL);
+CREATE TABLE t2c (b1 CHAR(8) NOT NULL, b2 char(8));
+INSERT INTO t1 VALUES ('1 - 12', '2 - 22');
+INSERT INTO t2a VALUES ('1 - 11', '2 - 21'),
+('1 - 11', '2 - 21'),
+('1 - 12', '2 - 22'),
+('1 - 12', '2 - 22'),
+('1 - 13', '2 - 23');
+INSERT INTO t2b SELECT * FROM t2a;
+INSERT INTO t2c SELECT * FROM t2a;
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=off,materialization=on';
+SELECT * FROM t1
+WHERE (a1, a2) IN (
+SELECT b1, b2 FROM t2c WHERE b1 > '0' GROUP BY b1, b2);
+a1 a2
+1 - 12 2 - 22
+SELECT * FROM t1
+WHERE (a1, a2) IN (
+SELECT b1, b2 FROM t2a WHERE b1 > '0');
+a1 a2
+1 - 12 2 - 22
+SELECT * FROM t1
+WHERE (a1, a2) IN (
+SELECT b1, b2 FROM t2b WHERE b1 > '0');
+a1 a2
+1 - 12 2 - 22
+SELECT * FROM t1
+WHERE (a1, a2) IN (
+SELECT b1, b2 FROM t2c WHERE b1 > '0');
+a1 a2
+1 - 12 2 - 22
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2a,t2b,t2c;
+#
+# Bug#57623: subquery within before insert trigger causes crash (sj=on)
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=on';
+set optimizer_switch='materialization=off';
+explain SELECT *
+FROM ot1
+LEFT JOIN
+(ot2 JOIN ot3 on ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 8
+1 PRIMARY ot3 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY ot2 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY it1 ALL NULL NULL NULL NULL 8 Using where
+SELECT *
+FROM ot1
+LEFT JOIN
+(ot2 JOIN ot3 on ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
+a a a
+0 0 0
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+5 NULL NULL
+6 6 6
+7 NULL NULL
+prepare s from 'SELECT *
+FROM ot1
+LEFT JOIN
+(ot2 JOIN ot3 on ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1)';
+execute s;
+a a a
+0 0 0
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+5 NULL NULL
+6 6 6
+7 NULL NULL
+execute s;
+a a a
+0 0 0
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+5 NULL NULL
+6 6 6
+7 NULL NULL
+deallocate prepare s;
+set optimizer_switch='materialization=on';
+explain SELECT *
+FROM ot1
+LEFT JOIN
+(ot2 JOIN ot3 on ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 8
+1 PRIMARY ot3 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY ot2 ALL NULL NULL NULL NULL 4 Using where
+2 MATERIALIZED it1 ALL NULL NULL NULL NULL 8
+SELECT *
+FROM ot1
+LEFT JOIN
+(ot2 JOIN ot3 on ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
+a a a
+0 0 0
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+5 NULL NULL
+6 6 6
+7 NULL NULL
+prepare s from 'SELECT *
+FROM ot1
+LEFT JOIN
+(ot2 JOIN ot3 on ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1)';
+execute s;
+a a a
+0 0 0
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+5 NULL NULL
+6 6 6
+7 NULL NULL
+execute s;
+a a a
+0 0 0
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+5 NULL NULL
+6 6 6
+7 NULL NULL
+deallocate prepare s;
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE ot1, ot2, ot3, it1;
+#
+# Bug#59919/11766739: Crash in tmp_table_param::init() with semijoin=on
+#
+CREATE TABLE t1 (f1 INTEGER) ENGINE=MyISAM;
+CREATE TABLE t2 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM;
+CREATE TABLE t3 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1,1), (2,1);
+INSERT INTO t3 VALUES
+(1,1), (2,1), (5,4), (7,3), (8,2), (8,1), (7,3),
+(9,5), (4,3), (7,2), (7,7), (3,1), (5,8), (9,7);
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=off,materialization=on';
+EXPLAIN
+SELECT * FROM t3
+WHERE f2 IN (SELECT t1.f1
+FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 14 Using where
+2 MATERIALIZED t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED b1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED b2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t3
+WHERE f2 IN (SELECT t1.f1
+FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE);
+f1 f2
+1 1
+2 1
+8 1
+3 1
+set optimizer_switch='semijoin=on,materialization=on';
+EXPLAIN
+SELECT * FROM t3
+WHERE f2 IN (SELECT t1.f1
+FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1
+1 PRIMARY t3 ALL NULL NULL NULL NULL 14 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED b1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED b2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t3
+WHERE f2 IN (SELECT t1.f1
+FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE);
+f1 f2
+1 1
+2 1
+8 1
+3 1
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1, t2, t3 ;
+#
+#
+# BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3
+#
+CREATE TABLE t1 ( t1field integer, primary key (t1field));
+CREATE TABLE t2 ( t2field integer, primary key (t2field));
+INSERT INTO t1 VALUES (1),(2),(3);
+INSERT INTO t2 VALUES (2),(3),(4);
+explain
+SELECT * FROM t1 A
+WHERE
+A.t1field IN (SELECT A.t1field FROM t2 B) AND
+A.t1field IN (SELECT C.t2field FROM t2 C
+WHERE C.t2field IN (SELECT D.t2field FROM t2 D));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY A index PRIMARY PRIMARY 4 NULL 3 Using index
+1 PRIMARY B index NULL PRIMARY 4 NULL 3 Using index; Start temporary; End temporary
+1 PRIMARY C eq_ref PRIMARY PRIMARY 4 test.A.t1field 1 Using index
+1 PRIMARY D eq_ref PRIMARY PRIMARY 4 test.A.t1field 1 Using index
+SELECT * FROM t1 A
+WHERE
+A.t1field IN (SELECT A.t1field FROM t2 B) AND
+A.t1field IN (SELECT C.t2field FROM t2 C
+WHERE C.t2field IN (SELECT D.t2field FROM t2 D));
+t1field
+2
+3
+drop table t1,t2;
+#
+# BUG#787299: Valgrind complains on a join query with two IN subqueries
+#
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+create table t2 as select * from t1;
+select * from t1 A, t1 B
+where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D);
+a a
+1 1
+2 2
+3 3
+explain
+select * from t1 A, t1 B
+where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY A ALL NULL NULL NULL NULL 3
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY B ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED C ALL NULL NULL NULL NULL 3
+3 MATERIALIZED D ALL NULL NULL NULL NULL 3
+drop table t1, t2;
+#
+# BUG#784441: Abort on semijoin with a view as the inner table
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (1), (1);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (1), (1);
+CREATE VIEW v1 AS SELECT 1;
+EXPLAIN
+SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED <derived3> system NULL NULL NULL NULL 1
+3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
+a a
+1 1
+1 1
+1 1
+1 1
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# BUG#751439 Assertion `!table->file || table->file->inited == handler::NONE' failed with subquery
+#
+CREATE TABLE t1 ( f10 int, f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0,0),(0,0);
+CREATE TABLE t2 ( f11 int);
+INSERT IGNORE INTO t2 VALUES (0),(0);
+CREATE TABLE t3 ( f11 int) ;
+INSERT IGNORE INTO t3 VALUES (0);
+SELECT alias1.f11 AS field2
+FROM ( t3 AS alias2 JOIN t1 AS alias3 ON alias3.f10 = 1)
+LEFT JOIN ( t2 AS alias1 ) ON alias3.f11 = 1
+WHERE alias2.f11 IN ( SELECT f11 FROM t2 )
+GROUP BY field2 ;
+field2
+drop table t1, t2, t3;
+#
+# BUG#778406 Crash in hp_movelink with Aria engine and subqueries
+#
+CREATE TABLE t4 (f10 varchar(32) , KEY (f10)) ENGINE=Aria;
+INSERT INTO t4 VALUES ('x'),('m'),('c');
+CREATE TABLE t1 (f11 int) ENGINE=Aria;
+INSERT INTO t1 VALUES (0),(0),(0);
+CREATE TABLE t2 ( f10 int) ENGINE=Aria;
+INSERT INTO t2 VALUES (0),(0),(0);
+CREATE TABLE t3 ( f10 int, f11 int) ENGINE=Aria;
+SELECT *
+FROM t4
+WHERE f10 IN
+( SELECT t1.f11
+FROM t1
+LEFT JOIN t2 JOIN t3 ON t3.f10 = t2.f10 ON t3.f11 != 0 );
+f10
+x
+m
+c
+drop table t1,t2,t3,t4;
+#
+# BUG#751484: Valgrind warning / sporadic crash in evaluate_join_record sql_select.cc:14099 with semijoin
+#
+CREATE TABLE t1 ( f10 int, f11 int, KEY (f10));
+INSERT IGNORE INTO t1 VALUES (0, 0),(0, 0);
+CREATE TABLE t3 ( f10 int);
+INSERT IGNORE INTO t3 VALUES (0);
+set @tmp_751484= @@optimizer_switch;
+set optimizer_switch='materialization=on';
+SELECT * FROM t1
+WHERE f11 IN (
+SELECT C_SQ1_alias1.f11
+FROM t1 AS C_SQ1_alias1
+JOIN t3 AS C_SQ1_alias2
+ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10
+);
+f10 f11
+0 0
+0 0
+set optimizer_switch='materialization=off';
+SELECT * FROM t1
+WHERE f11 IN (
+SELECT C_SQ1_alias1.f11
+FROM t1 AS C_SQ1_alias1
+JOIN t3 AS C_SQ1_alias2
+ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10
+);
+f10 f11
+0 0
+0 0
+set optimizer_switch=@tmp_751484;
+drop table t1, t3;
+# BUG#795530 Wrong result with subquery semijoin materialization and outer join
+# Simplified testcase that uses DuplicateElimination
+#
+create table t1 (a int);
+create table t2 (a int, b char(10));
+insert into t1 values (1),(2);
+insert into t2 values (1, 'one'), (3, 'three');
+create table t3 (b char(10));
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+explain select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where
+select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
+b
+drop table t1, t2, t3;
+#
+# BUG#600958 RQG: Crash in optimize_semijoin_nests
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) DEFAULT NULL,
+col_date_key date DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key),
+KEY col_date_key (col_date_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (10,8,'2002-02-21',NULL);
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) DEFAULT NULL,
+col_date_key date DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key),
+KEY col_date_key (col_date_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (1,7,'1900-01-01','f');
+SELECT col_date_key FROM t1
+WHERE 5 IN (
+SELECT SUBQUERY3_t1 .col_int_key
+FROM t2 SUBQUERY3_t1
+LEFT JOIN t1 SUBQUERY3_t2 ON SUBQUERY3_t1 .col_varchar_key
+);
+col_date_key
+drop table t2, t1;
+#
+# No BUG#: Duplicate weedout check is not done for outer joins
+#
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(1),(2),(2);
+insert into t2 values (1);
+create table t0 (a int);
+insert into t0 values (1),(2);
+set @tmp_20110622= @@optimizer_switch;
+set optimizer_switch='firstmatch=off,loosescan=off,materialization=off';
+# Check DuplicateWeedout + join buffer
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+a
+1
+2
+# Check DuplicateWeedout without join buffer
+set @tmp_jcl_20110622= @@join_cache_level;
+set join_cache_level= 0;
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+a
+1
+2
+# Check FirstMatch without join buffer:
+set optimizer_switch='firstmatch=on';
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+a
+1
+2
+#
+# Now, check the same for multiple inner tables:
+alter table t2 add b int;
+update t2 set b=a;
+create table t3 as select * from t2;
+set optimizer_switch='firstmatch=off';
+set join_cache_level= 0;
+# DuplicateWeedout without join buffer
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+a
+1
+2
+set @@join_cache_level=@tmp_jcl_20110622;
+# DuplicateWeedout + join buffer
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+a
+1
+2
+# Now, let the inner join side have a 'partial' match
+select * from t3;
+a b
+1 1
+insert into t3 values(2,2);
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+a
+1
+2
+set @@optimizer_switch=@tmp_20110622;
+drop table t0, t1, t2, t3;
+#
+# BUG#802965: Crash in do_copy_not_null with semijoin=on in maria-5.3
+#
+set @save_802965= @@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=off,firstmatch=off,loosescan=off';
+CREATE TABLE t2 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t2 VALUES (19),(20);
+CREATE TABLE t1 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t1 VALUES (21),(22),(23),(24);
+SELECT *
+FROM t2 , t1
+WHERE t2.f1 IN
+(
+SELECT SQ1_alias1.f1
+FROM t1 AS SQ1_alias1 LEFT JOIN t2 AS SQ1_alias2 JOIN t2 AS SQ1_alias3 ON SQ1_alias3.f1 ON SQ1_alias3.f1
+)
+AND t1.f1 = t2.f1 ;
+f1 f1
+DROP TABLE t1, t2;
+set optimizer_switch=@save_802965;
+#
+# BUG#803365: Crash in pull_out_semijoin_tables with outer join + semijoin + derived tables in maria-5.3 with WL#106
+#
+CREATE TABLE t1 ( f1 int) ;
+INSERT INTO t1 VALUES (1),(1);
+CREATE TABLE t2 ( f2 int) ;
+INSERT INTO t2 VALUES (1),(1);
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (1),(1);
+SELECT *
+FROM t1
+WHERE t1.f1 IN (
+SELECT t2.f2
+FROM t2
+LEFT JOIN (
+SELECT *
+FROM t3
+) AS alias1
+ON alias1.f3 = t2.f2
+);
+f1
+1
+1
+DROP TABLE t1,t2,t3;
+#
+# BUG#611704: Crash in replace_where_subcondition with nested subquery and semijoin=on
+#
+CREATE TABLE t1 ( f1 int) ;
+CREATE TABLE t2 ( f1 int) ;
+CREATE TABLE t3 ( f1 int) ;
+SELECT * FROM (
+SELECT t3.*
+FROM t2 STRAIGHT_JOIN t3
+ON t3.f1
+AND (t3.f1 ) IN (
+SELECT t1.f1
+FROM t1
+)
+) AS alias1;
+f1
+DROP TABLE t1,t2,t3;
+# BUG#611704: another testcase:
+CREATE TABLE t1 ( f1 int(11), f3 varchar(1), f4 varchar(1)) ;
+CREATE TABLE t2 ( f2 int(11), KEY (f2));
+CREATE TABLE t3 ( f4 varchar(1)) ;
+PREPARE st1 FROM '
+SELECT *
+FROM t1
+STRAIGHT_JOIN ( t2 STRAIGHT_JOIN t3 ON t2.f2 )
+ON (t1.f3) IN ( SELECT f4 FROM t1 )
+';
+EXECUTE st1;
+f1 f3 f4 f2 f4
+DROP TABLE t1,t2,t3;
+#
+# BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90
+# (Original testcase)
+#
+CREATE TABLE t1 (f1 int, f2 int );
+INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL);
+CREATE TABLE t2 (f2 int, f3 int );
+INSERT INTO t2 VALUES (NULL,NULL),(0,0);
+CREATE TABLE t3 ( f1 int, f3 int );
+INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0);
+CREATE TABLE t4 ( f2 int, KEY (f2) );
+INSERT INTO t4 VALUES (0),(NULL);
+CREATE VIEW v4 AS SELECT DISTINCT f2 FROM t4 ;
+# The following must not have outer joins:
+explain extended
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY t4 ref f2 f2 5 test.t2.f3 2 100.00 Using index; FirstMatch(t2)
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` semi join (`test`.`t4`) join `test`.`t2` join `test`.`t3` where ((`test`.`t4`.`f2` = `test`.`t2`.`f3`) and (`test`.`t3`.`f1` = `test`.`t1`.`f1`) and (`test`.`t1`.`f2` = `test`.`t2`.`f2`))
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
+f1 f2 f3 f3
+2 0 0 0
+4 0 0 0
+4 0 0 0
+drop view v4;
+drop table t1, t2, t3, t4;
+#
+# BUG#803303: Wrong result with semijoin=on, outer join in maria-5.3-subqueries-mwl90
+#
+# Testcase#1:
+set @tmp803303= @@optimizer_switch;
+set optimizer_switch = 'semijoin=on,materialization=off,firstmatch=off,loosescan=off';
+CREATE TABLE t2 ( f1 int) ;
+INSERT IGNORE INTO t2 VALUES (6),(8);
+CREATE TABLE t1 ( f1 int, f2 int, f3 int) ;
+INSERT IGNORE INTO t1 VALUES (8,0,0),(7,0,0),(9,0,0);
+SELECT alias2.f1
+FROM t2 AS alias1
+LEFT JOIN ( t1 AS alias2 JOIN t1 AS alias3 ON alias3.f2 = alias2.f3 )
+ON alias3.f2 = alias2.f2
+WHERE alias2.f1 IN ( SELECT f1 FROM t2 AS alias4 ) ;
+f1
+8
+8
+8
+8
+8
+8
+drop table t1,t2;
+set optimizer_switch= @tmp803303;
+# Testcase #2:
+CREATE TABLE t1 ( f10 int) ;
+INSERT INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f10 int, f11 varchar(1)) ;
+INSERT INTO t2 VALUES (0,'a'),(0,'b');
+CREATE TABLE t3 ( f10 int) ;
+INSERT INTO t3 VALUES (0),(0),(0),(0),(0);
+CREATE TABLE t4 ( f10 varchar(1), f11 int) ;
+INSERT INTO t4 VALUES ('a',0),('b',0);
+SELECT * FROM t1
+LEFT JOIN ( t2 JOIN t3 ON t3.f10 = t2.f10 ) ON t1.f10 = t2.f10
+WHERE t2.f10 IN (
+SELECT t4.f11
+FROM t4
+WHERE t4.f10 != t2.f11
+);
+f10 f10 f11 f10
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+drop table t1,t2,t3,t4;
+#
+# BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90
+#
+set @tmp803457=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+CREATE TABLE t1 (f1 int, f2 int );
+INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL);
+CREATE TABLE t2 (f2 int, f3 int );
+INSERT INTO t2 VALUES (NULL,NULL),(0,0);
+CREATE TABLE t3 ( f1 int, f3 int );
+INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0);
+CREATE TABLE t4 ( f2 int);
+INSERT INTO t4 VALUES (0),(NULL);
+# The following uses Duplicate Weedout, and "End temporary" must not be
+# in the middle of the inner side of an outer join:
+explain
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t3 ALL NULL NULL NULL NULL 5 Using where
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; Start temporary; End temporary
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3 ) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
+f1 f2 f3 f3
+2 0 0 0
+4 0 0 0
+4 0 0 0
+0 NULL NULL NULL
+DROP TABLE t1, t2, t3, t4;
+set @tmp803457=@@optimizer_switch;
+#
+# BUG#818280: crash in do_copy_not_null() in maria-5.3 with semijoin
+#
+CREATE TABLE t1 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ;
+INSERT IGNORE INTO t1 VALUES (2,7),(1,3),(5,6);
+CREATE TABLE t3 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ;
+INSERT IGNORE INTO t3 VALUES (2,7),(1,3),(5,6);
+CREATE TABLE t2 ( c1 int NOT NULL , c5 int NOT NULL );
+INSERT IGNORE INTO t2 VALUES (2,2),(2,2),(5,6);
+SELECT * FROM t1 WHERE c1 IN ( SELECT t3.c1 FROM t3 LEFT JOIN t2 ON t2 .c1 = t3 .c1 WHERE t2.c5 != 0 );
+c1 c2
+2 7
+5 6
+DROP TABLE t1, t2, t3;
+#
+# BUG#834534: Assertion `0' failed in replace_where_subcondition with semijoin subquery in HAVING
+#
+CREATE TABLE t1 ( d int );
+INSERT INTO t1 VALUES (2),(2),(0),(2),(2);
+CREATE TABLE t2 ( b int );
+INSERT INTO t2 VALUES (4),(3),(3);
+CREATE TABLE t3 ( a int );
+SELECT *
+FROM t3
+WHERE (t3.a) IN (
+SELECT t1.d
+FROM t1
+HAVING ( 4 ) IN (
+SELECT t2.b
+FROM t2
+)
+);
+a
+drop table t1, t2,t3;
+#
+# BUG#834758: Wrong result with innner join, LooseScan, two-column IN() predicate
+#
+set @tmp835758=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
+CREATE TABLE t1 (b int) ;
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (6),(10);
+CREATE TABLE t3 (a int, b int, KEY (b)) ;
+INSERT INTO t3 VALUES (6,5),(6,2),(8,0),(9,1),(6,5);
+# This used to incorrectly pick a join order of (t1, LooseScan(t3), t2):
+explain
+SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 2 Using index; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL b NULL NULL NULL 5 Using where; Start temporary; End temporary
+SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
+b a
+5 6
+DROP TABLE t1, t2, t3;
+set @@optimizer_switch= @tmp835758;
+#
+# BUG#834739: Wrong result with 3-way inner join, LooseScan,multipart keys
+#
+set @tmp834739=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
+CREATE TABLE t2 ( b int, c int, KEY (b)) ;
+INSERT INTO t2 VALUES (1,0),(1,0),(9,0),(1,0),(5,0);
+INSERT INTO t2 VALUES (2,0),(3,0),(8,0),(6,0),(5,0);
+CREATE TABLE t3 ( a int);
+INSERT INTO t3 VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+CREATE TABLE t4 ( a int);
+INSERT INTO t4 VALUES (0),(0),(0);
+CREATE TABLE t5 ( b int, a int , KEY (a,b)) ;
+INSERT INTO t5 VALUES (7,0),(9,0);
+explain
+SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t5 index a a 10 NULL 2 Using index; Start temporary
+1 PRIMARY t4 ALL NULL NULL NULL NULL 3
+1 PRIMARY t2 ALL b NULL NULL NULL 10 Using where
+1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; End temporary; Using join buffer (flat, BNL join)
+SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
+a
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+DROP TABLE t2, t3, t4, t5;
+set @@optimizer_switch=@tmp834739;
+#
+# BUG#830993: Crash in end_read_record with derived table
+#
+set @tmp_830993=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=off,materialization=off,firstmatch=off';
+set @tmp_830993_jbs= @@join_buffer_size;
+set join_buffer_size=160;
+CREATE TABLE t1 (
+a int(11) NOT NULL AUTO_INCREMENT,
+b int(11) DEFAULT NULL,
+c int(11) DEFAULT NULL,
+d time DEFAULT NULL,
+e varchar(1) DEFAULT NULL,
+f varchar(1) DEFAULT NULL,
+PRIMARY KEY (a),
+KEY c (c),
+KEY d (d),
+KEY e (e,c)
+);
+INSERT INTO t1 VALUES (10,NULL,8,'22:55:23','x','x'),
+(11,8,7,'10:19:31','d','d'),(12,1,1,'14:40:36','r','r'),
+(13,9,7,'04:37:47','f','f'),(14,4,9,'19:34:06','y','y'),
+(15,3,NULL,'20:35:33','u','u'),(16,2,1,NULL,'m','m'),
+(17,NULL,9,'14:43:37',NULL,NULL),(18,2,2,'02:23:09','o','o'),
+(19,NULL,9,'01:22:45','w','w'),(20,6,2,'00:00:00','m','m'),
+(21,7,4,'00:13:25','q','q'),(22,2,0,'03:47:16',NULL,NULL),
+(23,5,4,'01:41:48','d','d'),(24,7,8,'00:00:00','g','g'),
+(25,6,NULL,'22:32:04','x','x'),(26,6,NULL,'16:44:14','f','f'),
+(27,2,0,'17:38:37','p','p'),(28,9,NULL,'08:46:48','j','j'),
+(29,6,8,'14:11:27','c','c');
+CREATE TABLE t2 like t1;
+INSERT INTO t2 VALUES (1,2,4,'22:34:09','v','v'),
+(2,150,62,'14:26:02','v','v'),(3,NULL,7,'14:03:03','c','c'),
+(4,2,1,'01:46:09',NULL,NULL),(5,5,0,'16:21:18','x','x'),
+(6,3,7,'18:56:33','i','i'),(7,1,7,NULL,'e','e'),
+(8,4,1,'09:29:08','p','p'),(9,NULL,7,'19:11:10','s','s'),
+(10,2,1,'11:57:26','j','j'),(11,6,5,'00:39:46','z','z'),
+(12,6,2,'03:28:15','c','c'),(13,8,0,'06:44:18','a','a'),
+(14,2,1,'14:36:39','q','q'),(15,6,8,'18:42:45','y','y'),
+(16,8,1,'02:57:29',NULL,NULL),(17,3,1,'16:46:13','r','r'),
+(18,3,9,'19:39:02','v','v'),(19,9,1,NULL,NULL,NULL),
+(20,6,5,'20:58:33','r','r');
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+explain
+SELECT
+alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
+alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
+alias2.e as a2_e, alias2.f as a2_f,
+t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
+FROM
+(SELECT * FROM t2) AS alias1,
+t1 AS alias2,
+t2
+WHERE
+alias1.c IN (SELECT SQ3_alias1.b
+FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
+LIMIT 100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Start temporary
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY SQ3_alias2 index NULL PRIMARY 4 NULL 20 Using index; End temporary
+1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
+2 DERIVED t2 ALL NULL NULL NULL NULL 20
+create table t3 as
+SELECT
+alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
+alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
+alias2.e as a2_e, alias2.f as a2_f,
+t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
+FROM
+(SELECT * FROM t2) AS alias1,
+t1 AS alias2,
+t2
+WHERE
+alias1.c IN (SELECT SQ3_alias1.b
+FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
+LIMIT 100;
+set optimizer_switch=@tmp_optimizer_switch;
+drop table t1,t2, t3;
+set optimizer_switch=@tmp_830993;
+set join_buffer_size= @tmp_830993_jbs;
+#
+# BUG##849717: Crash in Item_func::fix_fields on second execution of a prepared statement with semijoin
+#
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int, b int) ;
+PREPARE st1 FROM "SELECT * FROM t2 LEFT JOIN t1 ON t2.a != 0 AND ('j','r') IN ( SELECT b,a FROM t3)";
+EXECUTE st1;
+a a
+EXECUTE st1;
+a a
+DROP TABLE t1, t2, t3;
+#
+# BUG#849776: Wrong result with semijoin + "Impossible where"
+#
+CREATE TABLE t1 ( b varchar(1), a integer) ;
+INSERT INTO t1 VALUES ('z',8);
+CREATE TABLE t2 ( a integer, b varchar(1)) ;
+CREATE TABLE t4 ( a integer, b varchar(1)) ;
+CREATE TABLE t5 ( a integer) ;
+INSERT INTO t5 VALUES (8);
+select * from t5 where (a) in (
+SELECT t1.a
+FROM t1 LEFT JOIN t2 ON t1.a = t2.a
+WHERE t2.b NOT IN (SELECT t4.b FROM t4 WHERE t4.b < t1.b)
+);
+a
+8
+DROP TABLE t1, t2, t4, t5;
+#
+# BUG#861147: Assertion `fixed == 1' failed in Item_func_eq::val_int() with semijoin + materialization + max_join_size
+#
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+set @tmp_mjs_861147= @@max_join_size;
+SET max_join_size=10;
+set @tmp_os_861147= @@optimizer_switch;
+set @@optimizer_switch='semijoin=on,materialization=on';
+explain
+select * from t1 where a in (select max(A.a + B.a + C.a) from t1 A, t1 B, t1 C);
+ERROR 42000: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay
+set max_join_size= @tmp_mjs_861147;
+set optimizer_switch= @tmp_os_861147;
+drop table t1;
+#
+# BUG#877288: Wrong result with semijoin + materialization + multipart key
+#
+set @tmp_877288=@@optimizer_switch;
+set optimizer_switch='semijoin=ON,materialization=ON';
+CREATE TABLE t1 ( a int) ;
+INSERT INTO t1 VALUES (19),(19),(19),(20),(20),(20),(20),(20),(20);
+CREATE TABLE t2 ( b int NOT NULL , c int NOT NULL , KEY (b,c)) ;
+INSERT INTO t2 VALUES (14,1),(15,1),(16,1),(17,1),(18,1),(19,1),(20,1);
+CREATE TABLE t3 ( a int, d int) ;
+INSERT INTO t3 VALUES (19,1),(7,1),(3,1),(3,1),(20,1),(3,1),(16,1),(17,1),(9,1),(4,1),(6,1),(15,1),(17,1);
+explain
+SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 13 Using where
+2 MATERIALIZED t2 ref b b 4 test.t3.a 1 Using index
+SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
+a
+19
+19
+19
+20
+20
+20
+20
+20
+20
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@tmp_877288;
+#
+# BUG#878753: Assertion '0' failed in replace_where_subcondition with derived_merge
+#
+set @tmp878753= @@optimizer_switch;
+set optimizer_switch= 'semijoin=on,derived_merge=on';
+CREATE TABLE t1 (b int(11)) ;
+CREATE TABLE t2 (c int, b int, d varchar(52) NOT NULL) ;
+CREATE TABLE t3 (b int(11)) ;
+PREPARE st1 FROM '
+ SELECT * FROM t1
+ JOIN (
+ SELECT t2.* FROM t2
+ WHERE t2.d <> "a"
+ AND t2.c IN (
+ SELECT t3.b
+ FROM t3
+ )
+ ) AS alias2
+ ON ( alias2.b = t1.b );
+';
+EXECUTE st1;
+b c b d
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@tmp878753;
+#
+# Bug #889750: semijoin=on + firstmatch=off + semijoin_with_cache=off
+#
+create table t1 (a int);
+insert into t1 values (7), (1), (5), (3);
+create table t2 (a int);
+insert into t2 values (4), (1), (8), (3), (9), (2);
+set @tmp_otimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=on';
+set optimizer_switch='firstmatch=off';
+set optimizer_switch='semijoin_with_cache=on';
+explain
+select * from t1 where t1.a in (select t2.a from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+select * from t1 where t1.a in (select t2.a from t2);
+a
+1
+3
+set optimizer_switch='semijoin_with_cache=off';
+explain
+select * from t1 where t1.a in (select t2.a from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; Start temporary; End temporary
+select * from t1 where t1.a in (select t2.a from t2);
+a
+1
+3
+set optimizer_switch= @tmp_otimizer_switch;
+drop table t1,t2;
+#
+# Bug #887496: semijoin with IN equality for the second part of an index
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (9), (0), (8), (5);
+CREATE TABLE t2 (a int, b varchar(1), INDEX idx (b,a));
+INSERT INTO t2 VALUES (5,'r'), (5,'z');
+CREATE TABLE t3 (a int, b varchar(1), INDEX idx (b,a));
+INSERT INTO t3 VALUES (5,'r'), (5,'z');
+set @tmp_otimizer_switch= @@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on,firstmatch=on';
+SET SESSION optimizer_switch='loosescan=off';
+EXPLAIN
+SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index idx idx 9 NULL 2 Using where; Using index; Start temporary
+1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
+SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
+a
+5
+SET SESSION optimizer_switch='loosescan=on';
+EXPLAIN
+SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index idx idx 9 NULL 2 Using where; Using index; Start temporary
+1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
+SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
+a
+5
+set optimizer_switch= @tmp_otimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# Bug #901312: materialized semijoin + right join
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (4), (1);
+CREATE TABLE t2 (b int);
+INSERT INTO t2 VALUES (4), (1);
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (4), (1);
+set @tmp_otimizer_switch= @@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on,materialization=on';
+EXPLAIN
+SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2
+SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3);
+a b
+4 4
+1 1
+set optimizer_switch= @tmp_otimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# Bug #901709: assertion failure with record count == 0
+#
+CREATE TABLE t1 (a int, KEY (a));
+INSERT INTO t1 VALUES (4), (6);
+CREATE TABLE t2 (a int, KEY (a));
+INSERT INTO t2 VALUES (4), (6);
+CREATE TABLE t3 (b int);
+INSERT INTO t3 VALUES (4);
+CREATE TABLE t4 (c int);
+SET @tmp_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch='semijoin=on';
+SET @@optimizer_switch='materialization=on';
+SET @@optimizer_switch='firstmatch=on';
+SET optimizer_switch='semijoin_with_cache=on';
+SET optimizer_prune_level=0;
+EXPLAIN
+SELECT * FROM t1, t2
+WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 system NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1
+1 PRIMARY t1 ref a a 5 const 1 Using index
+1 PRIMARY t2 ref a a 5 test.t3.b 1 Using index
+2 MATERIALIZED t4 ALL NULL NULL NULL NULL 0
+SELECT * FROM t1, t2
+WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4);
+a a
+SET optimizer_prune_level=DEFAULT;
+SET optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1,t2,t3,t4;
+#
+# BUG#901399: Wrong result (extra row) with semijoin=ON, materialization=OFF, optimizer_prune_level=0
+#
+set @opl_901399= @@optimizer_prune_level;
+set @os_091399= @@optimizer_switch;
+SET optimizer_prune_level=0;
+SET optimizer_switch = 'materialization=off';
+CREATE TABLE t1 ( c INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+(0),(1),(2),(3),(4),(5),
+(6),(7),(8),(9),(10),(11),(12);
+CREATE TABLE t2 ( a INT, b INT, KEY(a)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (3,20),(2,21),(3,22);
+SELECT *
+FROM t1 AS alias1, t1 AS alias2
+WHERE ( alias1.c, alias2.c )
+IN (
+SELECT alias3.a, alias3.a
+FROM t2 AS alias3, t2 alias4
+WHERE alias3.b = alias4.b
+);
+c c
+2 2
+3 3
+set optimizer_prune_level= @opl_901399;
+set optimizer_switch= @os_091399;
+DROP TABLE t1,t2;
+#
+# BUG#912510: Crash in do_copy_not_null with semijoin=ON, firstmatch=ON, aggregate ...
+#
+CREATE TABLE t1 ( a VARCHAR(1) NOT NULL );
+INSERT INTO t1 VALUES ('k'),('l');
+CREATE TABLE t2 ( b VARCHAR(1) NOT NULL, KEY(b) );
+INSERT INTO t2 VALUES ('k'),('l');
+CREATE TABLE t3 ( c VARCHAR(1) NOT NULL, KEY(c) );
+INSERT INTO t3 VALUES ('m'),('n');
+SELECT a, COUNT(*) FROM t1
+WHERE a IN (
+SELECT b FROM t2 force index(b), t3 force index(c)
+WHERE c = b AND b = a
+);
+a COUNT(*)
+NULL 0
+DROP TABLE t1, t2, t3;
+#
+# BUG#920255: Wrong result (extra rows) with loosescan and IN subquery
+#
+CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, KEY(b) );
+INSERT INTO t1 VALUES
+(1,2),(2,1),(3,3),(4,2),(5,5),
+(6,3),(7,1),(8,4),(9,3),(10,2);
+CREATE TABLE t2 ( c INT, d INT, UNIQUE KEY(c) );
+INSERT INTO t2 VALUES
+(1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1);
+SELECT a, b, d FROM t1, t2
+WHERE ( b, d ) IN
+( SELECT b, d FROM t1, t2 WHERE b = c );
+a b d
+2 1 2
+7 1 2
+2 1 2
+7 1 2
+1 2 1
+4 2 1
+10 2 1
+1 2 1
+4 2 1
+10 2 1
+3 3 3
+6 3 3
+9 3 3
+3 3 3
+6 3 3
+9 3 3
+8 4 2
+8 4 2
+5 5 5
+DROP TABLE t1, t2;
+#
+# BUG#920713: Wrong result (missing rows) with firstmatch+BNL, IN subquery, ...
+#
+CREATE TABLE t1 ( a VARCHAR(1) ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('e'),('w'),('a'),('h'),('x'),('k'),('g');
+CREATE TABLE t2 ( b INT, c VARCHAR(1) );
+INSERT INTO t2 VALUES (0,'j'),(8,'v');
+SELECT * FROM t1 alias1, t2 alias2
+WHERE alias2.c IN (
+SELECT alias4.c FROM t1 alias3, t2 alias4
+);
+a b c
+e 0 j
+e 8 v
+w 0 j
+w 8 v
+a 0 j
+a 8 v
+h 0 j
+h 8 v
+x 0 j
+x 8 v
+k 0 j
+k 8 v
+g 0 j
+g 8 v
+DROP TABLE t1, t2;
+#
+# BUG#923246: Loosescan reports different result than other semijoin methods
+#
+set @tmp_923246= @@optimizer_switch;
+set optimizer_switch='mrr=on,materialization=off';
+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;
+select * from t3 where a in (select kp1 from t1 where kp1<20);
+a
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+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 t1 range kp1 kp1 5 NULL 48 Using where; Using index; LooseScan
+1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
+drop table t0,t1,t3;
+set optimizer_switch= @tmp_923246;
+#
+# BUG#952583: Server crashes in Item_field::fix_after_pullout on INSERT .. SELECT
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 ( b INT );
+INSERT INTO t2 VALUES (3),(4);
+INSERT INTO t1
+SELECT * FROM ( SELECT * FROM t1 ) AS alias
+WHERE a IN ( SELECT b FROM t2 );
+DROP TABLE t1, t2;
+#
+# BUG#952372: Server crashes on 2nd execution of PS in find_field_in_tables with semijoin+materialization
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (2),(3);
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE TABLE t2 ( b VARCHAR(1) );
+INSERT INTO t2 VALUES ('v'),('v');
+PREPARE pstmt FROM
+'SELECT DISTINCT a FROM v1, t2
+ WHERE b IN ( SELECT MIN(b) FROM t2 )';
+EXECUTE pstmt;
+a
+2
+3
+EXECUTE pstmt;
+a
+2
+3
+DEALLOCATE PREPARE pstmt;
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
+# BUG#978479: Wrong result (extra rows) with derived_with_keys+loosescan+semijoin=ON, materialization=OFF
+#
+set @tmp_jcl_978479= @@join_cache_level;
+set join_cache_level=0;
+set @tmp_os_978479= @@optimizer_switch;
+set optimizer_switch = 'derived_with_keys=on,loosescan=on,semijoin=on,materialization=off';
+# Part#1: make sure EXPLAIN is using LooseScan:
+CREATE TABLE t1 ( a INT, b INT );
+INSERT INTO t1 VALUES
+(4,0),(6,8),(3,1),(5,8),(3,9),(2,4),
+(2,6),(9,1),(5,4),(7,7),(5,4);
+CREATE ALGORITHM=TEMPTABLE
+VIEW v1 AS SELECT * FROM t1;
+# This will use LooseScan:
+EXPLAIN
+SELECT * FROM t1 AS t1_1, t1 AS t1_2
+WHERE (t1_1.a, t1_2.a) IN ( SELECT a, b FROM v1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1_1 ALL NULL NULL NULL NULL 11 Using where
+1 PRIMARY <derived3> ref key0 key0 5 test.t1_1.a 2 Start temporary
+1 PRIMARY t1_2 ALL NULL NULL NULL NULL 11 Using where; End temporary
+3 DERIVED t1 ALL NULL NULL NULL NULL 11
+SELECT * FROM t1 AS t1_1, t1 AS t1_2
+WHERE (t1_1.a, t1_2.a) IN ( SELECT a, b FROM v1 );
+a b a b
+3 1 9 1
+5 8 4 0
+3 9 9 1
+2 4 6 8
+2 4 4 0
+2 6 6 8
+2 6 4 0
+5 4 4 0
+7 7 7 7
+5 4 4 0
+DROP VIEW v1;
+DROP TABLE t1;
+set @@join_cache_level= @tmp_jcl_978479;
+set @@optimizer_switch= @tmp_os_978479;
+#
+# BUG#998236: Assertion failure or valgrind errors at best_access_path ...
+#
+CREATE TABLE t1 (a1 VARCHAR(3), a2 VARCHAR(35), KEY(a1,a2)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+('USA','Arvada'),('USA','Athens'),('USA','Atlanta'),('USA','Augusta'),
+('USA','Aurora'),('USA','Aurora'),('USA','Austin'),('USA','Bakersfield'),
+('USA','Baltimore'),('USA','Baton'),('USA','Beaumont'),('USA','Bellevue'),
+('USA','Berkeley'),('USA','Billings'),('USA','Birmingham'),('USA','Boise'),
+('USA','Boston'),('USA','Boulder'),('USA','Bridgeport'),('USA','Brockton'),
+('USA','Brownsville'),('USA','Buffalo'),('USA','Burbank'),('USA','Cambridge'),
+('USA','Cape'),('USA','Carrollton'),('USA','Carson'),('USA','Cary'),
+('USA','Cedar'),('USA','Chandler'),('USA','Charleston'),('USA','Charlotte'),
+('USA','Chattanooga'),('USA','Chesapeake'),('USA','Chicago'),('USA','Chula'),
+('USA','Cincinnati'),('USA','Citrus'),('USA','Clarksville'),('USA','Clearwater'),
+('USA','Cleveland'),('USA','Colorado'),('USA','Columbia'),('USA','Columbus'),
+('USA','Columbus'),('USA','Compton'),('USA','Concord'),('USA','Coral'),
+('USA','Corona'),('USA','Corpus'),('USA','Costa'),('USA','Dallas'),('USA','Daly'),
+('USA','Davenport'),('USA','Dayton'),('USA','Denver'),('USA','DesMoines'),
+('USA','Detroit'),('USA','Downey'),('USA','Durham'),('USA','East'),('USA','ElCajon'),
+('USA','ElMonte'),('USA','ElPaso'),('USA','Elgin'),('USA','Elizabeth'),
+('USA','Erie'),('USA','Escondido'),('USA','Eugene'),('USA','Evansville'),
+('USA','Fairfield'),('USA','Fall'),('USA','Fayetteville'),('USA','Flint'),
+('USA','Fontana'),('USA','FortCollins'),('USA','FortLauderdale'),('USA','FortWayne'),
+('USA','FortWorth'),('USA','Fremont'),('USA','Fresno'),('USA','Fullerton'),
+('USA','Gainesville'),('USA','GardenGrove'),('USA','Garland'),('USA','Gary'),
+('USA','Gilbert'),('USA','Glendale'),('USA','Glendale'),('USA','GrandPrairie'),
+('USA','GrandRapids'),('USA','Green Bay'),('USA','Greensboro'),('USA','Hampton'),
+('USA','Hartford'),('USA','Hayward'),('USA','Henderson'),('USA','Hialeah'),
+('USA','Inglewood'),('USA','Livonia');
+CREATE TABLE t3 (c1 VARCHAR(3), c2 VARCHAR(16), PRIMARY KEY (c1,c2)) ENGINE=MyISAM;
+INSERT INTO t3 VALUES ('USA','Chinese'), ('USA','English');
+CREATE TABLE t2 (b1 INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1);
+SELECT alias1.a1 AS field1
+FROM t1 AS alias1, t1 AS alias2
+WHERE alias1.a2 IN ( SELECT a1 FROM t1, t2 )
+AND alias1.a1 IS NULL
+AND ( alias1.a1, alias2.a1 ) IN ( SELECT c1, c1 FROM t3 )
+GROUP BY field1;
+field1
+DROP TABLE t1,t3,t2;
+#
+# BUG#1002630: Valgrind warnings 'Invalid read' in subselect_engine::calc_const_tables with SELECT
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(7);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (4),(6);
+SELECT ( SELECT SUM(a) FROM t1 ) AS t1sum, b
+FROM t2
+WHERE (1,1) IN ( SELECT MAX(a), MIN(a) FROM t1 )
+GROUP BY b
+HAVING t1sum <> 1;
+t1sum b
+DROP TABLE t1, t2;
+#
+# MDEV-3911: Assertion `fixed == 0' failed in Item_field::fix_fields
+# on 2nd execution of PS with semijoin=on and IN subquery
+#
+CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (0,4),(8,6);
+CREATE TABLE t2 (c INT, d INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (7,1),(0,7);
+PREPARE stmt FROM ' SELECT * FROM t1 WHERE ( a, b ) IN ( SELECT c, d FROM t2 ) ';
+execute stmt;
+a b
+execute stmt;
+a b
+deallocate prepare stmt;
+drop table t1,t2;
+set optimizer_switch=@subselect_sj_tmp;
diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result
new file mode 100644
index 00000000000..267ed06d89b
--- /dev/null
+++ b/mysql-test/r/subselect_sj2.result
@@ -0,0 +1,1101 @@
+set @subselect_sj2_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj2_test,'outer_join_with_cache=off');
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj2_test,'semijoin_with_cache=off');
+set join_cache_level=1;
+drop table if exists t0, t1, t2, t3, t4, t5;
+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;
+insert into t2 select a+10, a+10/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
+10 5
+11 6
+12 7
+13 8
+14 9
+15 10
+16 11
+17 12
+18 13
+19 14
+explain select * from t2 where b in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL b NULL NULL NULL 20
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3
+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;
+insert into t3 select a,a, a+100,a+100,a+100 from t0;
+explain select * from t3 where b in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL b NULL NULL NULL 20
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3
+select * from t3 where b in (select a from t1);
+a b pk1 pk2 pk3
+1 1 1 1 1
+1 1 101 101 101
+2 2 102 102 102
+2 2 2 2 2
+set @save_max_heap_table_size= @@max_heap_table_size;
+set max_heap_table_size=16384;
+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 t3 ALL b NULL NULL NULL #
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func #
+2 MATERIALIZED t0 ALL NULL NULL NULL NULL #
+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
+10 10 10 10
+11 11 11 11
+12 12 12 12
+13 13 13 13
+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
+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 Using where
+1 PRIMARY t2 ref b b 5 test.t1.a 2 Using index; FirstMatch(t1)
+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 <subquery2> ALL distinct_key NULL NULL NULL 22
+1 PRIMARY ot ALL NULL NULL NULL NULL 32 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED 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 <subquery2> ALL distinct_key NULL NULL NULL 22
+1 PRIMARY ot ALL NULL NULL NULL NULL 52 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED 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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func 1 Using where
+2 MATERIALIZED t1 index a a 5 NULL 10 Using where; Using index
+2 MATERIALIZED t2 ref a a 5 test.t1.a 1 Using index
+2 MATERIALIZED t3 ref a a 5 test.t1.a 1 Using index
+drop table t0, t1,t2,t3;
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+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)
+);
+set @bug35674_save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+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; Rowid-ordered scan; Start temporary
+1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t1.Country 1 Using where; End temporary
+1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where
+set optimizer_switch=@bug35674_save_optimizer_switch;
+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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED 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;
+drop procedure if exists p1;
+drop procedure if exists p2;
+drop procedure if exists p3;
+drop procedure if exists p4;
+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;
+insert into t1 select a+5,a from t0;
+create table t2 (a int, b int, primary key(a));
+insert into t2 select * from t1;
+Table t2, unlike table t1, should be displayed as pulled out
+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 t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 100.00
+1 PRIMARY t1 ref a a 5 test.t0.a 1 100.00 Using where; FirstMatch(t2)
+Warnings:
+Note 1276 Field or reference 'test.t0.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) join `test`.`t0` where ((`test`.`t2`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`b` = `test`.`t2`.`b`))
+update t1 set a=3, b=11 where a=4;
+update t2 set b=11 where a=3;
+select * from t0 where t0.a in
+(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 MATERIALIZED t3 index PRIMARY PRIMARY 4 NULL 10 Using index
+drop table t0, t1, t2, t3;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+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 <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED 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 where; FirstMatch(t2)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 FirstMatch(t2)
+drop table t2, t3;
+#
+# BUG#761598: InnoDB: Error: row_search_for_mysql() is called without ha_innobase::external_lock() in maria-5.3
+#
+CREATE TABLE t1 ( f1 int NOT NULL , f10 int) ;
+INSERT IGNORE INTO t1 VALUES (25,0),(29,0);
+CREATE TABLE t2 ( f10 int) ENGINE=InnoDB;
+CREATE TABLE t3 ( f11 int) ;
+INSERT IGNORE INTO t3 VALUES (0);
+SELECT alias1.f10 AS field2
+FROM t2 AS alias1
+JOIN (
+t3 AS alias2
+JOIN t1 AS alias3
+ON alias3.f10
+) ON alias3.f1
+WHERE alias2.f11 IN (
+SELECT SQ4_alias1.f10
+FROM t1 AS SQ4_alias1
+LEFT JOIN t2 AS SQ4_alias3 ON SQ4_alias3.f10
+)
+GROUP BY field2;
+field2
+drop table t1, t2, t3;
+#
+# BUG#849763: Wrong result with second execution of prepared statement with semijoin + view
+#
+CREATE TABLE t1 ( c varchar(1)) engine=innodb;
+INSERT INTO t1 VALUES ('r');
+CREATE TABLE t2 ( a integer, b varchar(1), c varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES (1,'r','r');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+PREPARE st1 FROM 'SELECT * FROM t2 WHERE a = SOME (SELECT a FROM v1 WHERE v1.c = t2.c)';
+EXECUTE st1;
+a b c
+1 r r
+EXECUTE st1;
+a b c
+1 r r
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
+# BUG#858732: Wrong result with semijoin + loosescan + comma join
+#
+CREATE TABLE t1 (f13 int(11) NOT NULL , PRIMARY KEY (f13)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (16),(24);
+CREATE TABLE t2 (f14 int(11) NOT NULL, f12 varchar(1) NOT NULL, KEY (f12,f14)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (6,'y');
+CREATE TABLE t3 (f12 varchar(1) NOT NULL) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('r'),('s'),('t'),('v'),('w'),('x'),('y');
+# The following must use LooseScan but not join buffering
+explain
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY alias1 const PRIMARY PRIMARY 4 const 1 Using index
+1 PRIMARY alias2 index f12 f12 7 NULL 1 Using index; LooseScan
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 2 Using index; FirstMatch(alias2)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 7 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+f12
+y
+DROP TABLE t1,t2,t3;
+#
+# BUG#869012: Wrong result with semijoin + materialization + AND in WHERE
+#
+CREATE TABLE t1 (f3 varchar(1) , f4 varchar(1) ) engine=InnoDB;
+INSERT IGNORE INTO t1 VALUES ('x','x'),('x','x');
+CREATE TABLE t2 ( f4 varchar(1) ) ;
+INSERT IGNORE INTO t2 VALUES ('g');
+CREATE TABLE t3 (f4 varchar(1) ) Engine=InnoDB;
+INSERT IGNORE INTO t3 VALUES ('x');
+set @tmp_869012=@@optimizer_switch;
+SET optimizer_switch='semijoin=on,materialization=on';
+SELECT *
+FROM t1 , t2
+WHERE ( t1.f4 ) IN ( SELECT f4 FROM t3 )
+AND t2.f4 != t1.f3 ;
+f3 f4 f4
+x x g
+x x g
+set optimizer_switch= @tmp_869012;
+DROP TABLE t1,t2,t3;
+#
+# BUG#869001: Wrong result with semijoin + materialization + firstmatch + multipart key
+#
+set @tmp869001_jcl= @@join_cache_level;
+set @tmp869001_os= @@optimizer_switch;
+SET join_cache_level=0;
+SET optimizer_switch='materialization=on,semijoin=on,firstmatch=on,loosescan=off';
+CREATE TABLE t1 ( f2 int, f3 varchar(1), KEY (f3,f2)) engine=innodb;
+INSERT INTO t1 VALUES (8,'x'),(NULL,'x'),(8,'c');
+CREATE TABLE t2 ( f4 varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES ('x');
+CREATE TABLE t3 ( f1 int) engine=innodb;
+INSERT INTO t3 VALUES (8),(6),(2),(9),(6);
+CREATE TABLE t4 ( f3 varchar(1)) engine=innodb;
+INSERT INTO t4 VALUES ('p'),('j'),('c');
+SELECT *
+FROM t1 JOIN t2 ON (t2.f4 = t1.f3 )
+WHERE ( 8 ) IN (
+SELECT t3.f1 FROM t3 , t4
+);
+f2 f3 f4
+NULL x x
+8 x x
+DROP TABLE t1, t2, t3, t4;
+set join_cache_level= @tmp869001_jcl;
+set optimizer_switch= @tmp869001_os;
+#
+# Bug #881318: join cache + duplicate elimination + left join
+# with empty materialized derived inner table
+#
+CREATE TABLE t1 (b varchar(1)) ENGINE=InnoDB;
+CREATE TABLE t2 (a varchar(1)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('a');
+CREATE TABLE t3 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('c','c');
+CREATE TABLE t4 (b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t4 VALUES ('c'), ('b');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+WHERE t3.b IN (SELECT b FROM t4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2
+3 DERIVED t1 ALL NULL NULL NULL NULL 1
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+WHERE t3.b IN (SELECT b FROM t4);
+a b b a
+c c NULL NULL
+DROP VIEW v1;
+DROP TABLE t1,t2,t3,t4;
+#
+# BUG#912538: Wrong result (missing rows) with semijoin=on, firstmatch=on, ...
+#
+CREATE TABLE t1 ( a INT NOT NULL, UNIQUE KEY(a) );
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+CREATE TABLE t2 ( b INT, c INT ) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1,1);
+SELECT * FROM t1, t2 WHERE c IN (SELECT c FROM t1, t2 WHERE a = b);
+a b c
+1 1 1
+2 1 1
+3 1 1
+4 1 1
+DROP TABLE t1,t2;
+#
+# BUG#962667: Assertion `0' failed in QUICK_INDEX_SORT_SELECT::need_sorted_output()
+# with index_merge+index_merge_sort_union+loosescan+semijoin
+#
+CREATE TABLE t1 (
+a INT, b VARCHAR(1), c INT,
+KEY(a), KEY(b)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(1,'v',9),(2,'v',8),(3,'c',7),(4,'m',6),(5,'x',5),
+(6,'i',4),(7,'e',3),(8,'p',2),(9,'s',1),(10,'j',9),
+(11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4),
+(16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0);
+CREATE TABLE t2 (
+pk INT, d VARCHAR(1), e INT,
+PRIMARY KEY(pk), KEY(d,e)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES
+(1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5),
+(6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1),
+(11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5),
+(15,'g',6),(16,'x',7),(17,'f',8);
+explain
+SELECT * FROM t1 WHERE b IN (
+SELECT d FROM t2, t1
+WHERE a = d AND ( pk < 2 OR d = 'z' )
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t1 ref b b 4 test.t2.d 1
+2 MATERIALIZED t2 index_merge PRIMARY,d d,PRIMARY 4,4 NULL 2 Using sort_union(d,PRIMARY); Using where
+2 MATERIALIZED t1 ref a a 5 test.t2.d 1 Using where; Using index
+SELECT * FROM t1 WHERE b IN (
+SELECT d FROM t2, t1
+WHERE a = d AND ( pk < 2 OR d = 'z' )
+);
+a b c
+DROP TABLE t1, t2;
+#
+# BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view
+#
+CREATE TABLE t1 (
+a VARCHAR(1),
+b VARCHAR(1) NOT NULL,
+KEY(a)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+('j','j'),('v','v'),('c','c'),('m','m'),('d','d'),
+('y','y'),('t','t'),('d','d'),('s','s'),('r','r'),
+('m','m'),('b','b'),('x','x'),('g','g'),('p','p'),
+('q','q'),('w','w'),('d','d'),('e','e');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+# This query returned 6 rows instead of 19
+SELECT * FROM v1
+WHERE ( a, a ) IN (
+SELECT alias2.b, alias2.a
+FROM t1 AS alias1, t1 AS alias2
+WHERE alias2.b = alias1.a
+AND ( alias1.b >= alias1.a OR alias2.b = 'z' )
+);
+a b
+b b
+c c
+d d
+d d
+d d
+e e
+g g
+j j
+m m
+m m
+p p
+q q
+r r
+s s
+t t
+v v
+w w
+x x
+y y
+# Another testcase, without the VIEW:
+CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(1) NOT NULL, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t2 SELECT * FROM t1;
+INSERT INTO t2 SELECT * FROM t1;
+EXPLAIN
+SELECT * FROM t2
+WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
+WHERE
+alias2.b = alias1.a AND
+(alias1.b >= alias1.a OR alias2.b = 'z'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL a NULL NULL NULL 38
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED alias1 ALL a NULL NULL NULL 19 Using where
+2 MATERIALIZED alias2 ref a a 4 test.alias1.a 1 Using where
+SELECT * FROM t2
+WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
+WHERE
+alias2.b = alias1.a AND
+(alias1.b >= alias1.a OR alias2.b = 'z'));
+a b
+b b
+b b
+c c
+c c
+d d
+d d
+d d
+d d
+d d
+d d
+e e
+e e
+g g
+g g
+j j
+j j
+m m
+m m
+m m
+m m
+p p
+p p
+q q
+q q
+r r
+r r
+s s
+s s
+t t
+t t
+v v
+v v
+w w
+w w
+x x
+x x
+y y
+y y
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
+# BUG#965872: Server crashes in embedding_sjm on a simple 1-table select with AND and OR
+# (this is a regression caused by the fix for BUG#951937)
+CREATE TABLE t1 ( a INT, b INT, c INT, d INT );
+INSERT INTO t1 VALUES (4,2,8,9),(4,2,7,8);
+SELECT * FROM t1
+WHERE a = d AND ( b = 50 AND b = d OR a = c );
+a b c d
+DROP TABLE t1;
+#
+# BUG#951283: Wrong result (missing rows) with semijoin+firstmatch, IN/ANY subquery
+#
+set @tmp_951283=@@optimizer_prune_level;
+SET optimizer_prune_level=0;
+CREATE TABLE t1 ( a INT ) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(10),(11),(12),(13),(14),(15),(16),
+(17),(18),(19),(20),(21),(22),(23);
+CREATE TABLE t2 (
+b INT PRIMARY KEY,
+c VARCHAR(1),
+d VARCHAR(1),
+KEY(c)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES
+(1,'j','j'),(2,'v','v'),(3,'c','c'),(4,'m','m'),
+(5,'d','d'),(6,'d','d'),(7,'y','y'),(8,'t','t'),
+(9,'d','d'),(10,'s','s'),(11,'r','r'),(12,'m','m'),
+(13,'b','b'),(14,'x','x'),(15,'g','g'),(16,'p','p'),
+(17,'q','q'),(18,'w','w'),(19,'d','d');
+EXPLAIN
+SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
+WHERE alias3.d IN (
+SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
+WHERE alias5.b = alias4.b
+AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 Using where
+1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d 1 Using index
+1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b 1 Using where; FirstMatch(alias3)
+1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
+1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
+SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
+WHERE alias3.d IN (
+SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
+WHERE alias5.b = alias4.b
+AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
+);
+COUNT(*)
+3724
+set optimizer_prune_level=@tmp_951283;
+DROP TABLE t1,t2;
+# This must be the last in the file:
+set optimizer_switch=@subselect_sj2_tmp;
diff --git a/mysql-test/r/subselect_sj2_jcl6.result b/mysql-test/r/subselect_sj2_jcl6.result
new file mode 100644
index 00000000000..33bf5e9859d
--- /dev/null
+++ b/mysql-test/r/subselect_sj2_jcl6.result
@@ -0,0 +1,1211 @@
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+set @optimizer_switch_for_subselect_sj2_test=@@optimizer_switch;
+set @join_cache_level_for_subselect_sj2_test=@@join_cache_level;
+set @subselect_sj2_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj2_test,'outer_join_with_cache=off');
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj2_test,'semijoin_with_cache=off');
+set join_cache_level=@join_cache_level_for_subselect_sj2_test;
+drop table if exists t0, t1, t2, t3, t4, t5;
+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;
+insert into t2 select a+10, a+10/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
+10 5
+11 6
+12 7
+13 8
+14 9
+15 10
+16 11
+17 12
+18 13
+19 14
+explain select * from t2 where b in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL b NULL NULL NULL 20
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3
+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;
+insert into t3 select a,a, a+100,a+100,a+100 from t0;
+explain select * from t3 where b in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL b NULL NULL NULL 20
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3
+select * from t3 where b in (select a from t1);
+a b pk1 pk2 pk3
+1 1 1 1 1
+1 1 101 101 101
+2 2 102 102 102
+2 2 2 2 2
+set @save_max_heap_table_size= @@max_heap_table_size;
+set max_heap_table_size=16384;
+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 t3 ALL b NULL NULL NULL #
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func #
+2 MATERIALIZED t0 ALL NULL NULL NULL NULL #
+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
+10 10 10 10
+11 11 11 11
+12 12 12 12
+13 13 13 13
+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
+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 <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t2 index b b 5 NULL 20 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 <subquery2> ALL distinct_key NULL NULL NULL 22
+1 PRIMARY ot hash_ALL NULL #hash#$hj 5 test.it.a 32 Using where; Using join buffer (flat, BNLH join)
+2 MATERIALIZED it ALL NULL NULL NULL NULL 22 Using where
+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 <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED 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 <subquery2> ALL distinct_key NULL NULL NULL 22
+1 PRIMARY ot hash_ALL NULL #hash#$hj 5 test.it.a 52 Using where; Using join buffer (flat, BNLH join)
+2 MATERIALIZED it ALL NULL NULL NULL NULL 22 Using where
+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 <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED 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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func 1 Using where
+2 MATERIALIZED t1 index a a 5 NULL 10 Using where; Using index
+2 MATERIALIZED t2 ref a a 5 test.t1.a 1 Using index
+2 MATERIALIZED t3 ref a a 5 test.t1.a 1 Using index
+drop table t0, t1,t2,t3;
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+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)
+);
+set @bug35674_save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+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; Rowid-ordered scan; Start temporary
+1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t1.Country 1 Using where; End temporary; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+set optimizer_switch=@bug35674_save_optimizer_switch;
+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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED 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;
+drop procedure if exists p1;
+drop procedure if exists p2;
+drop procedure if exists p3;
+drop procedure if exists p4;
+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;
+insert into t1 select a+5,a from t0;
+create table t2 (a int, b int, primary key(a));
+insert into t2 select * from t1;
+Table t2, unlike table t1, should be displayed as pulled out
+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 t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 PRIMARY t1 ref a a 5 test.t0.a 1 100.00 Using where; FirstMatch(t2); Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+Warnings:
+Note 1276 Field or reference 'test.t0.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) join `test`.`t0` where ((`test`.`t2`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`b` = `test`.`t2`.`b`))
+update t1 set a=3, b=11 where a=4;
+update t2 set b=11 where a=3;
+# Not anymore:
+# 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 hash_ALL NULL #hash#$hj 5 test.t1.a 3 Using where; Using join buffer (flat, BNLH join)
+2 MATERIALIZED t3 index PRIMARY PRIMARY 4 NULL 10 Using index
+drop table t0, t1, t2, t3;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+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 <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED 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 <subquery3> eq_ref distinct_key distinct_key 4 func 1 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 FirstMatch((sj-nest)); Using join buffer (incremental, BNL join)
+3 MATERIALIZED t2 ALL NULL NULL NULL NULL 1
+drop table t2, t3;
+#
+# BUG#761598: InnoDB: Error: row_search_for_mysql() is called without ha_innobase::external_lock() in maria-5.3
+#
+CREATE TABLE t1 ( f1 int NOT NULL , f10 int) ;
+INSERT IGNORE INTO t1 VALUES (25,0),(29,0);
+CREATE TABLE t2 ( f10 int) ENGINE=InnoDB;
+CREATE TABLE t3 ( f11 int) ;
+INSERT IGNORE INTO t3 VALUES (0);
+SELECT alias1.f10 AS field2
+FROM t2 AS alias1
+JOIN (
+t3 AS alias2
+JOIN t1 AS alias3
+ON alias3.f10
+) ON alias3.f1
+WHERE alias2.f11 IN (
+SELECT SQ4_alias1.f10
+FROM t1 AS SQ4_alias1
+LEFT JOIN t2 AS SQ4_alias3 ON SQ4_alias3.f10
+)
+GROUP BY field2;
+field2
+drop table t1, t2, t3;
+#
+# BUG#849763: Wrong result with second execution of prepared statement with semijoin + view
+#
+CREATE TABLE t1 ( c varchar(1)) engine=innodb;
+INSERT INTO t1 VALUES ('r');
+CREATE TABLE t2 ( a integer, b varchar(1), c varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES (1,'r','r');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+PREPARE st1 FROM 'SELECT * FROM t2 WHERE a = SOME (SELECT a FROM v1 WHERE v1.c = t2.c)';
+EXECUTE st1;
+a b c
+1 r r
+EXECUTE st1;
+a b c
+1 r r
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
+# BUG#858732: Wrong result with semijoin + loosescan + comma join
+#
+CREATE TABLE t1 (f13 int(11) NOT NULL , PRIMARY KEY (f13)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (16),(24);
+CREATE TABLE t2 (f14 int(11) NOT NULL, f12 varchar(1) NOT NULL, KEY (f12,f14)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (6,'y');
+CREATE TABLE t3 (f12 varchar(1) NOT NULL) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('r'),('s'),('t'),('v'),('w'),('x'),('y');
+# The following must use LooseScan but not join buffering
+explain
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY alias1 const PRIMARY PRIMARY 4 const 1 Using index
+1 PRIMARY alias2 index f12 f12 7 NULL 1 Using index; LooseScan
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 2 Using index; FirstMatch(alias2)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 7 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+f12
+y
+DROP TABLE t1,t2,t3;
+#
+# BUG#869012: Wrong result with semijoin + materialization + AND in WHERE
+#
+CREATE TABLE t1 (f3 varchar(1) , f4 varchar(1) ) engine=InnoDB;
+INSERT IGNORE INTO t1 VALUES ('x','x'),('x','x');
+CREATE TABLE t2 ( f4 varchar(1) ) ;
+INSERT IGNORE INTO t2 VALUES ('g');
+CREATE TABLE t3 (f4 varchar(1) ) Engine=InnoDB;
+INSERT IGNORE INTO t3 VALUES ('x');
+set @tmp_869012=@@optimizer_switch;
+SET optimizer_switch='semijoin=on,materialization=on';
+SELECT *
+FROM t1 , t2
+WHERE ( t1.f4 ) IN ( SELECT f4 FROM t3 )
+AND t2.f4 != t1.f3 ;
+f3 f4 f4
+x x g
+x x g
+set optimizer_switch= @tmp_869012;
+DROP TABLE t1,t2,t3;
+#
+# BUG#869001: Wrong result with semijoin + materialization + firstmatch + multipart key
+#
+set @tmp869001_jcl= @@join_cache_level;
+set @tmp869001_os= @@optimizer_switch;
+SET join_cache_level=0;
+SET optimizer_switch='materialization=on,semijoin=on,firstmatch=on,loosescan=off';
+CREATE TABLE t1 ( f2 int, f3 varchar(1), KEY (f3,f2)) engine=innodb;
+INSERT INTO t1 VALUES (8,'x'),(NULL,'x'),(8,'c');
+CREATE TABLE t2 ( f4 varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES ('x');
+CREATE TABLE t3 ( f1 int) engine=innodb;
+INSERT INTO t3 VALUES (8),(6),(2),(9),(6);
+CREATE TABLE t4 ( f3 varchar(1)) engine=innodb;
+INSERT INTO t4 VALUES ('p'),('j'),('c');
+SELECT *
+FROM t1 JOIN t2 ON (t2.f4 = t1.f3 )
+WHERE ( 8 ) IN (
+SELECT t3.f1 FROM t3 , t4
+);
+f2 f3 f4
+NULL x x
+8 x x
+DROP TABLE t1, t2, t3, t4;
+set join_cache_level= @tmp869001_jcl;
+set optimizer_switch= @tmp869001_os;
+#
+# Bug #881318: join cache + duplicate elimination + left join
+# with empty materialized derived inner table
+#
+CREATE TABLE t1 (b varchar(1)) ENGINE=InnoDB;
+CREATE TABLE t2 (a varchar(1)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('a');
+CREATE TABLE t3 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('c','c');
+CREATE TABLE t4 (b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t4 VALUES ('c'), ('b');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+WHERE t3.b IN (SELECT b FROM t4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY t2 hash_ALL NULL #hash#$hj 5 test.t3.a 1 Using where; Using join buffer (flat, BNLH join)
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 Using join buffer (incremental, BNL join)
+2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2
+3 DERIVED t1 ALL NULL NULL NULL NULL 1
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+WHERE t3.b IN (SELECT b FROM t4);
+a b b a
+c c NULL NULL
+DROP VIEW v1;
+DROP TABLE t1,t2,t3,t4;
+#
+# BUG#912538: Wrong result (missing rows) with semijoin=on, firstmatch=on, ...
+#
+CREATE TABLE t1 ( a INT NOT NULL, UNIQUE KEY(a) );
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+CREATE TABLE t2 ( b INT, c INT ) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1,1);
+SELECT * FROM t1, t2 WHERE c IN (SELECT c FROM t1, t2 WHERE a = b);
+a b c
+1 1 1
+2 1 1
+3 1 1
+4 1 1
+DROP TABLE t1,t2;
+#
+# BUG#962667: Assertion `0' failed in QUICK_INDEX_SORT_SELECT::need_sorted_output()
+# with index_merge+index_merge_sort_union+loosescan+semijoin
+#
+CREATE TABLE t1 (
+a INT, b VARCHAR(1), c INT,
+KEY(a), KEY(b)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(1,'v',9),(2,'v',8),(3,'c',7),(4,'m',6),(5,'x',5),
+(6,'i',4),(7,'e',3),(8,'p',2),(9,'s',1),(10,'j',9),
+(11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4),
+(16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0);
+CREATE TABLE t2 (
+pk INT, d VARCHAR(1), e INT,
+PRIMARY KEY(pk), KEY(d,e)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES
+(1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5),
+(6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1),
+(11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5),
+(15,'g',6),(16,'x',7),(17,'f',8);
+explain
+SELECT * FROM t1 WHERE b IN (
+SELECT d FROM t2, t1
+WHERE a = d AND ( pk < 2 OR d = 'z' )
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t1 ref b b 4 test.t2.d 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+2 MATERIALIZED t2 index_merge PRIMARY,d d,PRIMARY 4,4 NULL 2 Using sort_union(d,PRIMARY); Using where
+2 MATERIALIZED t1 ref a a 5 test.t2.d 1 Using where; Using index
+SELECT * FROM t1 WHERE b IN (
+SELECT d FROM t2, t1
+WHERE a = d AND ( pk < 2 OR d = 'z' )
+);
+a b c
+DROP TABLE t1, t2;
+#
+# BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view
+#
+CREATE TABLE t1 (
+a VARCHAR(1),
+b VARCHAR(1) NOT NULL,
+KEY(a)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+('j','j'),('v','v'),('c','c'),('m','m'),('d','d'),
+('y','y'),('t','t'),('d','d'),('s','s'),('r','r'),
+('m','m'),('b','b'),('x','x'),('g','g'),('p','p'),
+('q','q'),('w','w'),('d','d'),('e','e');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+# This query returned 6 rows instead of 19
+SELECT * FROM v1
+WHERE ( a, a ) IN (
+SELECT alias2.b, alias2.a
+FROM t1 AS alias1, t1 AS alias2
+WHERE alias2.b = alias1.a
+AND ( alias1.b >= alias1.a OR alias2.b = 'z' )
+);
+a b
+b b
+c c
+d d
+d d
+d d
+e e
+g g
+j j
+m m
+m m
+p p
+q q
+r r
+s s
+t t
+v v
+w w
+x x
+y y
+# Another testcase, without the VIEW:
+CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(1) NOT NULL, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t2 SELECT * FROM t1;
+INSERT INTO t2 SELECT * FROM t1;
+EXPLAIN
+SELECT * FROM t2
+WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
+WHERE
+alias2.b = alias1.a AND
+(alias1.b >= alias1.a OR alias2.b = 'z'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL a NULL NULL NULL 38
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED alias1 ALL a NULL NULL NULL 19 Using where
+2 MATERIALIZED alias2 ref a a 4 test.alias1.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+SELECT * FROM t2
+WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
+WHERE
+alias2.b = alias1.a AND
+(alias1.b >= alias1.a OR alias2.b = 'z'));
+a b
+b b
+b b
+c c
+c c
+d d
+d d
+d d
+d d
+d d
+d d
+e e
+e e
+g g
+g g
+j j
+j j
+m m
+m m
+m m
+m m
+p p
+p p
+q q
+q q
+r r
+r r
+s s
+s s
+t t
+t t
+v v
+v v
+w w
+w w
+x x
+x x
+y y
+y y
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
+# BUG#965872: Server crashes in embedding_sjm on a simple 1-table select with AND and OR
+# (this is a regression caused by the fix for BUG#951937)
+CREATE TABLE t1 ( a INT, b INT, c INT, d INT );
+INSERT INTO t1 VALUES (4,2,8,9),(4,2,7,8);
+SELECT * FROM t1
+WHERE a = d AND ( b = 50 AND b = d OR a = c );
+a b c d
+DROP TABLE t1;
+#
+# BUG#951283: Wrong result (missing rows) with semijoin+firstmatch, IN/ANY subquery
+#
+set @tmp_951283=@@optimizer_prune_level;
+SET optimizer_prune_level=0;
+CREATE TABLE t1 ( a INT ) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(10),(11),(12),(13),(14),(15),(16),
+(17),(18),(19),(20),(21),(22),(23);
+CREATE TABLE t2 (
+b INT PRIMARY KEY,
+c VARCHAR(1),
+d VARCHAR(1),
+KEY(c)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES
+(1,'j','j'),(2,'v','v'),(3,'c','c'),(4,'m','m'),
+(5,'d','d'),(6,'d','d'),(7,'y','y'),(8,'t','t'),
+(9,'d','d'),(10,'s','s'),(11,'r','r'),(12,'m','m'),
+(13,'b','b'),(14,'x','x'),(15,'g','g'),(16,'p','p'),
+(17,'q','q'),(18,'w','w'),(19,'d','d');
+EXPLAIN
+SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
+WHERE alias3.d IN (
+SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
+WHERE alias5.b = alias4.b
+AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 Using where
+1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d 1 Using index
+1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b 1 Using where; FirstMatch(alias3)
+1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
+1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (incremental, BNL join)
+SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
+WHERE alias3.d IN (
+SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
+WHERE alias5.b = alias4.b
+AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
+);
+COUNT(*)
+3724
+set optimizer_prune_level=@tmp_951283;
+DROP TABLE t1,t2;
+# This must be the last in the file:
+set optimizer_switch=@subselect_sj2_tmp;
+#
+# Bug #898073: potential incremental join cache for semijoin
+#
+CREATE TABLE t1 (a int, b varchar(1), KEY (b,a));
+INSERT INTO t1 VALUES (0,'x'), (5,'r');
+CREATE TABLE t2 (a int) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (8);
+CREATE TABLE t3 (b varchar(1), c varchar(1)) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('x','x');
+CREATE TABLE t4 (a int NOT NULL, b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t4 VALUES (20,'r'), (10,'x');
+set @tmp_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin_with_cache=on';
+SET SESSION join_cache_level=2;
+EXPLAIN
+SELECT t3.* FROM t1 JOIN t3 ON t3.b = t1.b
+WHERE c IN (SELECT t4.b FROM t4 JOIN t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 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 t4 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t3); Using join buffer (incremental, BNL join)
+1 PRIMARY t1 ref b b 4 test.t3.b 1 Using index
+SELECT t3.* FROM t1 JOIN t3 ON t3.b = t1.b
+WHERE c IN (SELECT t4.b FROM t4 JOIN t2);
+b c
+x x
+set optimizer_switch=@tmp_optimizer_switch;
+set join_cache_level=default;
+DROP TABLE t1,t2,t3,t4;
+#
+# Bug #899696: potential incremental join cache for semijoin
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, a int);
+INSERT INTO t1 VALUES (1, 6), (2, 8);
+CREATE TABLE t2 (b int) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (8);
+CREATE TABLE t3 (pk int PRIMARY KEY, a int);
+INSERT INTO t3 VALUES (1, 6), (2, 8);
+CREATE TABLE t4 (b int) ENGINE=InnoDB;
+INSERT INTO t4 VALUES (2);
+set @tmp_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'semijoin_with_cache=on';
+SET join_cache_level = 2;
+EXPLAIN
+SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1
+1 PRIMARY t4 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.b 1 Using where; FirstMatch(t2)
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk);
+pk a b
+1 6 8
+2 8 8
+set optimizer_switch=@tmp_optimizer_switch;
+set join_cache_level=default;
+DROP TABLE t1,t2,t3,t4;
+#
+# Bug #899962: materialized subquery with join_cache_level=3
+#
+CREATE TABLE t1 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('v','v');
+CREATE TABLE t2 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v','v');
+set @tmp_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'semijoin_with_cache=on';
+SET join_cache_level = 3;
+EXPLAIN
+SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1
+SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a);
+a b
+v v
+EXPLAIN
+SELECT * FROM t1 WHERE b IN (SELECT max(a) FROM t2 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY <subquery2> hash_ALL distinct_key #hash#distinct_key 4 test.t1.b 1 Using join buffer (flat, BNLH join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 Using temporary
+SELECT * FROM t1 WHERE b IN (SELECT max(a) FROM t2 GROUP BY a);
+a b
+v v
+set optimizer_switch=@tmp_optimizer_switch;
+set join_cache_level=default;
+DROP TABLE t1,t2;
+set join_cache_level=default;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 2
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
+set @optimizer_switch_for_subselect_sj2_test=NULL;
+set @join_cache_level_subselect_sj2_test=NULL;
diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result
new file mode 100644
index 00000000000..bf5b95d2d8f
--- /dev/null
+++ b/mysql-test/r/subselect_sj2_mat.result
@@ -0,0 +1,1393 @@
+set optimizer_switch='materialization=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @subselect_sj2_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj2_test,'outer_join_with_cache=off');
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj2_test,'semijoin_with_cache=off');
+set join_cache_level=1;
+drop table if exists t0, t1, t2, t3, t4, t5;
+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;
+insert into t2 select a+10, a+10/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
+10 5
+11 6
+12 7
+13 8
+14 9
+15 10
+16 11
+17 12
+18 13
+19 14
+explain select * from t2 where b in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL b NULL NULL NULL 20
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3
+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;
+insert into t3 select a,a, a+100,a+100,a+100 from t0;
+explain select * from t3 where b in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL b NULL NULL NULL 20
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3
+select * from t3 where b in (select a from t1);
+a b pk1 pk2 pk3
+1 1 1 1 1
+1 1 101 101 101
+2 2 102 102 102
+2 2 2 2 2
+set @save_max_heap_table_size= @@max_heap_table_size;
+set max_heap_table_size=16384;
+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 t3 ALL b NULL NULL NULL #
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func #
+2 MATERIALIZED t0 ALL NULL NULL NULL NULL #
+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
+10 10 10 10
+11 11 11 11
+12 12 12 12
+13 13 13 13
+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
+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 Using where
+1 PRIMARY t2 ref b b 5 test.t1.a 2 Using index; FirstMatch(t1)
+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 <subquery2> ALL distinct_key NULL NULL NULL 22
+1 PRIMARY ot ALL NULL NULL NULL NULL 32 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED 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 <subquery2> ALL distinct_key NULL NULL NULL 22
+1 PRIMARY ot ALL NULL NULL NULL NULL 52 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED 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 <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED 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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func 1 Using where
+2 MATERIALIZED t1 index a a 5 NULL 10 Using where; Using index
+2 MATERIALIZED t2 ref a a 5 test.t1.a 1 Using index
+2 MATERIALIZED t3 ref a a 5 test.t1.a 1 Using index
+drop table t0, t1,t2,t3;
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+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)
+);
+set @bug35674_save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+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; Rowid-ordered scan; Start temporary
+1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t1.Country 1 Using where; End temporary
+1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where
+set optimizer_switch=@bug35674_save_optimizer_switch;
+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 <subquery2> eq_ref distinct_key distinct_key 3 func 1
+2 MATERIALIZED 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;
+drop procedure if exists p1;
+drop procedure if exists p2;
+drop procedure if exists p3;
+drop procedure if exists p4;
+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;
+insert into t1 select a+5,a from t0;
+create table t2 (a int, b int, primary key(a));
+insert into t2 select * from t1;
+Table t2, unlike table t1, should be displayed as pulled out
+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 t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 100.00
+1 PRIMARY t1 ref a a 5 test.t0.a 1 100.00 Using where; FirstMatch(t2)
+Warnings:
+Note 1276 Field or reference 'test.t0.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) join `test`.`t0` where ((`test`.`t2`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`b` = `test`.`t2`.`b`))
+update t1 set a=3, b=11 where a=4;
+update t2 set b=11 where a=3;
+select * from t0 where t0.a in
+(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 MATERIALIZED t3 index PRIMARY PRIMARY 4 NULL 10 Using index
+drop table t0, t1, t2, t3;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+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 <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED 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 where; FirstMatch(t2)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 FirstMatch(t2)
+drop table t2, t3;
+#
+# BUG#761598: InnoDB: Error: row_search_for_mysql() is called without ha_innobase::external_lock() in maria-5.3
+#
+CREATE TABLE t1 ( f1 int NOT NULL , f10 int) ;
+INSERT IGNORE INTO t1 VALUES (25,0),(29,0);
+CREATE TABLE t2 ( f10 int) ENGINE=InnoDB;
+CREATE TABLE t3 ( f11 int) ;
+INSERT IGNORE INTO t3 VALUES (0);
+SELECT alias1.f10 AS field2
+FROM t2 AS alias1
+JOIN (
+t3 AS alias2
+JOIN t1 AS alias3
+ON alias3.f10
+) ON alias3.f1
+WHERE alias2.f11 IN (
+SELECT SQ4_alias1.f10
+FROM t1 AS SQ4_alias1
+LEFT JOIN t2 AS SQ4_alias3 ON SQ4_alias3.f10
+)
+GROUP BY field2;
+field2
+drop table t1, t2, t3;
+#
+# BUG#849763: Wrong result with second execution of prepared statement with semijoin + view
+#
+CREATE TABLE t1 ( c varchar(1)) engine=innodb;
+INSERT INTO t1 VALUES ('r');
+CREATE TABLE t2 ( a integer, b varchar(1), c varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES (1,'r','r');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+PREPARE st1 FROM 'SELECT * FROM t2 WHERE a = SOME (SELECT a FROM v1 WHERE v1.c = t2.c)';
+EXECUTE st1;
+a b c
+1 r r
+EXECUTE st1;
+a b c
+1 r r
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
+# BUG#858732: Wrong result with semijoin + loosescan + comma join
+#
+CREATE TABLE t1 (f13 int(11) NOT NULL , PRIMARY KEY (f13)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (16),(24);
+CREATE TABLE t2 (f14 int(11) NOT NULL, f12 varchar(1) NOT NULL, KEY (f12,f14)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (6,'y');
+CREATE TABLE t3 (f12 varchar(1) NOT NULL) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('r'),('s'),('t'),('v'),('w'),('x'),('y');
+# The following must use LooseScan but not join buffering
+explain
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY alias1 const PRIMARY PRIMARY 4 const 1 Using index
+1 PRIMARY alias2 index f12 f12 7 NULL 1 Using index; LooseScan
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 2 Using index; FirstMatch(alias2)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 7 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+f12
+y
+DROP TABLE t1,t2,t3;
+#
+# BUG#869012: Wrong result with semijoin + materialization + AND in WHERE
+#
+CREATE TABLE t1 (f3 varchar(1) , f4 varchar(1) ) engine=InnoDB;
+INSERT IGNORE INTO t1 VALUES ('x','x'),('x','x');
+CREATE TABLE t2 ( f4 varchar(1) ) ;
+INSERT IGNORE INTO t2 VALUES ('g');
+CREATE TABLE t3 (f4 varchar(1) ) Engine=InnoDB;
+INSERT IGNORE INTO t3 VALUES ('x');
+set @tmp_869012=@@optimizer_switch;
+SET optimizer_switch='semijoin=on,materialization=on';
+SELECT *
+FROM t1 , t2
+WHERE ( t1.f4 ) IN ( SELECT f4 FROM t3 )
+AND t2.f4 != t1.f3 ;
+f3 f4 f4
+x x g
+x x g
+set optimizer_switch= @tmp_869012;
+DROP TABLE t1,t2,t3;
+#
+# BUG#869001: Wrong result with semijoin + materialization + firstmatch + multipart key
+#
+set @tmp869001_jcl= @@join_cache_level;
+set @tmp869001_os= @@optimizer_switch;
+SET join_cache_level=0;
+SET optimizer_switch='materialization=on,semijoin=on,firstmatch=on,loosescan=off';
+CREATE TABLE t1 ( f2 int, f3 varchar(1), KEY (f3,f2)) engine=innodb;
+INSERT INTO t1 VALUES (8,'x'),(NULL,'x'),(8,'c');
+CREATE TABLE t2 ( f4 varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES ('x');
+CREATE TABLE t3 ( f1 int) engine=innodb;
+INSERT INTO t3 VALUES (8),(6),(2),(9),(6);
+CREATE TABLE t4 ( f3 varchar(1)) engine=innodb;
+INSERT INTO t4 VALUES ('p'),('j'),('c');
+SELECT *
+FROM t1 JOIN t2 ON (t2.f4 = t1.f3 )
+WHERE ( 8 ) IN (
+SELECT t3.f1 FROM t3 , t4
+);
+f2 f3 f4
+NULL x x
+8 x x
+DROP TABLE t1, t2, t3, t4;
+set join_cache_level= @tmp869001_jcl;
+set optimizer_switch= @tmp869001_os;
+#
+# Bug #881318: join cache + duplicate elimination + left join
+# with empty materialized derived inner table
+#
+CREATE TABLE t1 (b varchar(1)) ENGINE=InnoDB;
+CREATE TABLE t2 (a varchar(1)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('a');
+CREATE TABLE t3 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('c','c');
+CREATE TABLE t4 (b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t4 VALUES ('c'), ('b');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+WHERE t3.b IN (SELECT b FROM t4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2
+3 DERIVED t1 ALL NULL NULL NULL NULL 1
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+WHERE t3.b IN (SELECT b FROM t4);
+a b b a
+c c NULL NULL
+DROP VIEW v1;
+DROP TABLE t1,t2,t3,t4;
+#
+# BUG#912538: Wrong result (missing rows) with semijoin=on, firstmatch=on, ...
+#
+CREATE TABLE t1 ( a INT NOT NULL, UNIQUE KEY(a) );
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+CREATE TABLE t2 ( b INT, c INT ) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1,1);
+SELECT * FROM t1, t2 WHERE c IN (SELECT c FROM t1, t2 WHERE a = b);
+a b c
+1 1 1
+2 1 1
+3 1 1
+4 1 1
+DROP TABLE t1,t2;
+#
+# BUG#962667: Assertion `0' failed in QUICK_INDEX_SORT_SELECT::need_sorted_output()
+# with index_merge+index_merge_sort_union+loosescan+semijoin
+#
+CREATE TABLE t1 (
+a INT, b VARCHAR(1), c INT,
+KEY(a), KEY(b)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(1,'v',9),(2,'v',8),(3,'c',7),(4,'m',6),(5,'x',5),
+(6,'i',4),(7,'e',3),(8,'p',2),(9,'s',1),(10,'j',9),
+(11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4),
+(16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0);
+CREATE TABLE t2 (
+pk INT, d VARCHAR(1), e INT,
+PRIMARY KEY(pk), KEY(d,e)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES
+(1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5),
+(6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1),
+(11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5),
+(15,'g',6),(16,'x',7),(17,'f',8);
+explain
+SELECT * FROM t1 WHERE b IN (
+SELECT d FROM t2, t1
+WHERE a = d AND ( pk < 2 OR d = 'z' )
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t1 ref b b 4 test.t2.d 1
+2 MATERIALIZED t2 index_merge PRIMARY,d d,PRIMARY 4,4 NULL 2 Using sort_union(d,PRIMARY); Using where
+2 MATERIALIZED t1 ref a a 5 test.t2.d 1 Using where; Using index
+SELECT * FROM t1 WHERE b IN (
+SELECT d FROM t2, t1
+WHERE a = d AND ( pk < 2 OR d = 'z' )
+);
+a b c
+DROP TABLE t1, t2;
+#
+# BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view
+#
+CREATE TABLE t1 (
+a VARCHAR(1),
+b VARCHAR(1) NOT NULL,
+KEY(a)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+('j','j'),('v','v'),('c','c'),('m','m'),('d','d'),
+('y','y'),('t','t'),('d','d'),('s','s'),('r','r'),
+('m','m'),('b','b'),('x','x'),('g','g'),('p','p'),
+('q','q'),('w','w'),('d','d'),('e','e');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+# This query returned 6 rows instead of 19
+SELECT * FROM v1
+WHERE ( a, a ) IN (
+SELECT alias2.b, alias2.a
+FROM t1 AS alias1, t1 AS alias2
+WHERE alias2.b = alias1.a
+AND ( alias1.b >= alias1.a OR alias2.b = 'z' )
+);
+a b
+b b
+c c
+d d
+d d
+d d
+e e
+g g
+j j
+m m
+m m
+p p
+q q
+r r
+s s
+t t
+v v
+w w
+x x
+y y
+# Another testcase, without the VIEW:
+CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(1) NOT NULL, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t2 SELECT * FROM t1;
+INSERT INTO t2 SELECT * FROM t1;
+EXPLAIN
+SELECT * FROM t2
+WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
+WHERE
+alias2.b = alias1.a AND
+(alias1.b >= alias1.a OR alias2.b = 'z'));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL a NULL NULL NULL 38
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED alias1 ALL a NULL NULL NULL 19 Using where
+2 MATERIALIZED alias2 ref a a 4 test.alias1.a 1 Using where
+SELECT * FROM t2
+WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
+WHERE
+alias2.b = alias1.a AND
+(alias1.b >= alias1.a OR alias2.b = 'z'));
+a b
+b b
+b b
+c c
+c c
+d d
+d d
+d d
+d d
+d d
+d d
+e e
+e e
+g g
+g g
+j j
+j j
+m m
+m m
+m m
+m m
+p p
+p p
+q q
+q q
+r r
+r r
+s s
+s s
+t t
+t t
+v v
+v v
+w w
+w w
+x x
+x x
+y y
+y y
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
+# BUG#965872: Server crashes in embedding_sjm on a simple 1-table select with AND and OR
+# (this is a regression caused by the fix for BUG#951937)
+CREATE TABLE t1 ( a INT, b INT, c INT, d INT );
+INSERT INTO t1 VALUES (4,2,8,9),(4,2,7,8);
+SELECT * FROM t1
+WHERE a = d AND ( b = 50 AND b = d OR a = c );
+a b c d
+DROP TABLE t1;
+#
+# BUG#951283: Wrong result (missing rows) with semijoin+firstmatch, IN/ANY subquery
+#
+set @tmp_951283=@@optimizer_prune_level;
+SET optimizer_prune_level=0;
+CREATE TABLE t1 ( a INT ) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(10),(11),(12),(13),(14),(15),(16),
+(17),(18),(19),(20),(21),(22),(23);
+CREATE TABLE t2 (
+b INT PRIMARY KEY,
+c VARCHAR(1),
+d VARCHAR(1),
+KEY(c)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES
+(1,'j','j'),(2,'v','v'),(3,'c','c'),(4,'m','m'),
+(5,'d','d'),(6,'d','d'),(7,'y','y'),(8,'t','t'),
+(9,'d','d'),(10,'s','s'),(11,'r','r'),(12,'m','m'),
+(13,'b','b'),(14,'x','x'),(15,'g','g'),(16,'p','p'),
+(17,'q','q'),(18,'w','w'),(19,'d','d');
+EXPLAIN
+SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
+WHERE alias3.d IN (
+SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
+WHERE alias5.b = alias4.b
+AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 Using where
+1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d 1 Using index
+1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b 1 Using where; FirstMatch(alias3)
+1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
+1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
+SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
+WHERE alias3.d IN (
+SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
+WHERE alias5.b = alias4.b
+AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
+);
+COUNT(*)
+3724
+set optimizer_prune_level=@tmp_951283;
+DROP TABLE t1,t2;
+# This must be the last in the file:
+set optimizer_switch=@subselect_sj2_tmp;
+set optimizer_switch=default;
+select @@optimizer_switch like '%materialization=on%';
+@@optimizer_switch like '%materialization=on%'
+1
+#
+# BUG#906385: EXPLAIN EXTENDED crashes in TABLE_LIST::print with limited max_join_size
+#
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( b INT );
+INSERT INTO t1 VALUES (1),(2);
+INSERT INTO t2 VALUES
+(1),(2),(3),(4),(5),
+(6),(7),(8),(9),(10),
+(11),(12),(13),(14),(15),
+(16),(17),(18),(19),(20);
+set @tmp_906385=@@max_join_size;
+SET max_join_size = 80;
+EXPLAIN EXTENDED
+SELECT COUNT(*) FROM t1
+WHERE a IN
+( SELECT b FROM t2 GROUP BY b )
+AND ( 6 ) IN
+( SELECT MIN( t2.b ) FROM t2 alias1, t2 );
+ERROR 42000: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay
+DROP TABLE t1, t2;
+set max_join_size= @tmp_906385;
+#
+# mdev-3995: Wrong result for semijoin with materialization
+#
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (
+cat_id int(10) unsigned NOT NULL,
+PRIMARY KEY (cat_id)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+(709411),(709412),(709413),(709414),(709416),(709417),(709418),(709419),(709421),(709422),
+(709424),(709425),(709427),(709428),(709429),(709431),(709432),(709433),(709434),(709435),
+(709438),(709439),(709441),(709442),(709443),(709444),(709445),(709446),(709447),(709450),
+(709451),(709454),(709455),(709456),(709457),(709459),(709460),(709461),(709462),(709463),
+(709464),(709465),(709467),(709469),(709470),(709471),(709472),(709473),(709474),(709475),
+(709476),(709477),(709478),(709479),(709480),(709481),(709483),(709484),(709485),(709487),
+(709490),(709491),(709492),(709493),(709494),(709495),(709496),(709497),(709498),(709499),
+(709500),(709501),(709502),(709503),(709504),(709505),(709506),(709507),(709509),(709510),
+(709511),(709512),(709513),(709514),(709515),(709516),(709517),(709518),(709519),(709520),
+(709521),(709522),(709523),(709524),(709525),(709526),(709527),(709528),(709529),(709530),
+(709531),(709532),(709533),(709534),(709535),(709536),(709537),(709538),(709539),(709540),
+(709541),(709542),(709543),(709544),(709545),(709546),(709548),(709549),(709551),(709552),
+(709553),(709555),(709556),(709557),(709558),(709559),(709560),(709561),(709562),(709563),
+(709564),(709565),(709566),(709567),(709568),(709569),(709570),(709571),(709572),(709573),
+(709574),(709575),(709576),(709577),(709578),(709579),(709580),(709581),(709582),(709583),
+(709584),(709585),(709586),(709587),(709588),(709590),(709591),(709592),(709593),(709594),
+(709595),(709596),(709597),(709598),(709600),(709601),(709602),(709603),(709604),(709605),
+(709606),(709608),(709609),(709610),(709611),(709612),(709613),(709614),(709615),(709616),
+(709617),(709618),(709619),(709620),(709621),(709622),(709623),(709624),(709625),(709626),
+(709627),(709628),(709629),(709630),(709631),(709632),(709633),(709634),(709635),(709637),
+(709638),(709639),(709640),(709641),(709642),(709643),(709644),(709645),(709646),(709649),
+(709650),(709651),(709652),(709653),(709654),(709655),(709656),(709657),(709658),(709659);
+CREATE TABLE t2 (
+cat_id int(10) NOT NULL,
+KEY cat_id (cat_id)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES
+(708742),(708755),(708759),(708761),(708766),(708769),(708796),(708798),(708824),(708825),
+(708838),(708844),(708861),(708882),(708887),(708889),(708890),(709586),(709626);
+CREATE TABLE t3 (
+sack_id int(10) unsigned NOT NULL,
+kit_id tinyint(3) unsigned NOT NULL DEFAULT '0',
+cat_id int(10) unsigned NOT NULL,
+PRIMARY KEY (sack_id,kit_id,cat_id)
+) ENGINE=MyISAM;
+INSERT INTO t3 VALUES
+(33479,6,708523),(33479,6,708632),(33479,6,709085),(33479,6,709586),(33479,6,709626);
+CREATE TABLE t4 (
+cat_id int(10) unsigned NOT NULL,
+KEY cat_id (cat_id)
+) ENGINE=MyISAM;
+INSERT INTO t4 (cat_id) SELECT cat_id from t2;
+set optimizer_switch='materialization=off';
+EXPLAIN
+SELECT count(*) FROM t1, t3
+WHERE t1.cat_id = t3.cat_id AND
+t3.cat_id IN (SELECT cat_id FROM t2) AND
+t3.sack_id = 33479 AND t3.kit_id = 6;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 4 Using index
+1 PRIMARY t2 ref cat_id cat_id 4 test.t3.cat_id 2 Using where; Using index; FirstMatch(t3)
+1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.cat_id 1 Using where; Using index
+SELECT count(*) FROM t1, t3
+WHERE t1.cat_id = t3.cat_id AND
+t3.cat_id IN (SELECT cat_id FROM t2) AND
+t3.sack_id = 33479 AND t3.kit_id = 6;
+count(*)
+2
+set optimizer_switch='materialization=on';
+EXPLAIN
+SELECT count(*) FROM t1, t3
+WHERE t1.cat_id = t3.cat_id AND
+t3.cat_id IN (SELECT cat_id FROM t4) AND
+t3.sack_id = 33479 AND t3.kit_id = 6;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 4 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.cat_id 1 Using index
+2 MATERIALIZED t4 index cat_id cat_id 4 NULL 19 Using index
+SELECT count(*) FROM t1, t3
+WHERE t1.cat_id = t3.cat_id AND
+t3.cat_id IN (SELECT cat_id FROM t4) AND
+t3.sack_id = 33479 AND t3.kit_id = 6;
+count(*)
+2
+EXPLAIN
+SELECT count(*) FROM t1, t3
+WHERE t1.cat_id = t3.cat_id AND
+t3.cat_id IN (SELECT cat_id FROM t2) AND
+t3.sack_id = 33479 AND t3.kit_id = 6;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 4 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 Using where
+1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.cat_id 1 Using index
+2 MATERIALIZED t2 index cat_id cat_id 4 NULL 19 Using index
+SELECT count(*) FROM t1, t3
+WHERE t1.cat_id = t3.cat_id AND
+t3.cat_id IN (SELECT cat_id FROM t2) AND
+t3.sack_id = 33479 AND t3.kit_id = 6;
+count(*)
+2
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch=@save_optimizer_switch;
+#
+# mdev-3913: LEFT JOIN with materialized multi-table IN subquery in WHERE
+#
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (a1 char(1), b1 char(1), index idx(b1,a1));
+INSERT INTO t1 VALUES ('f','c'),('d','m'),('g','y');
+INSERT INTO t1 VALUES ('f','c'),('d','m'),('g','y');
+CREATE TABLE t2 (a2 char(1), b2 char(1));
+INSERT INTO t2 VALUES ('y','y'),('y','y'),('w','w');
+CREATE TABLE t3 (a3 int);
+INSERT INTO t3 VALUES (8),(6);
+CREATE TABLE t4 (a4 char(1), b4 char(1));
+INSERT INTO t4 VALUES ('y','y'),('y','y'),('w','w');
+set optimizer_switch='materialization=off';
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 Start temporary
+1 PRIMARY t4 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t1 ref idx idx 2 test.t4.a4 1 100.00 Using index; End temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t4`) left join `test`.`t2` on((`test`.`t2`.`a2` = `test`.`t4`.`a4`)) where ((`test`.`t4`.`b4` = `test`.`t4`.`a4`) and (`test`.`t1`.`b1` = `test`.`t4`.`a4`))
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+a1 b1 a2 b2
+g y y y
+g y y y
+g y y y
+g y y y
+set optimizer_switch='materialization=on';
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 100.00
+1 PRIMARY t1 ref idx idx 2 test.t4.a4 1 100.00 Using index
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 100.00
+2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t4`) left join `test`.`t2` on(((`test`.`t1`.`b1` = `test`.`t4`.`a4`) and (`test`.`t2`.`a2` = `test`.`t4`.`a4`))) where ((`test`.`t4`.`b4` = `test`.`t4`.`a4`) and (`test`.`t1`.`b1` = `test`.`t4`.`a4`))
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+a1 b1 a2 b2
+g y y y
+g y y y
+g y y y
+g y y y
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch=@save_optimizer_switch;
+#
+# mdev-4172: LEFT JOIN with materialized multi-table IN subquery in WHERE
+# and OR in ON condition
+#
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (a1 int, c1 varchar(1));
+INSERT t1 VALUES (7,'v'), (3,'y');
+CREATE TABLE t2 (c2 varchar(1));
+INSERT INTO t2 VALUES ('y'), ('y');
+CREATE TABLE t3 (c3 varchar(1));
+INSERT INTO t3 VALUES
+('j'), ('v'), ('c'), ('m'), ('d'),
+('d'), ('y'), ('t'), ('d'), ('s');
+CREATE TABLE t4 (a4 int, c4 varchar(1));
+INSERT INTO t4 SELECT * FROM t1;
+set optimizer_switch='materialization=off';
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 10 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t4`) left join `test`.`t2` on(((`test`.`t2`.`c2` = `test`.`t1`.`c1`) or (`test`.`t1`.`c1` > 'z'))) where ((`test`.`t4`.`c4` = `test`.`t1`.`c1`) and (`test`.`t3`.`c3` = `test`.`t1`.`c1`))
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+a1 c1 c2
+3 y y
+3 y y
+7 v NULL
+set optimizer_switch='materialization=on';
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 100.00
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 10 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t4`) left join `test`.`t2` on(((`test`.`t2`.`c2` = `test`.`t1`.`c1`) or (`test`.`t1`.`c1` > 'z'))) where (`test`.`t3`.`c3` = `test`.`t4`.`c4`)
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+a1 c1 c2
+3 y y
+3 y y
+7 v NULL
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch=@save_optimizer_switch;
+#
+# mdev-4177: materialization of a subquery whose WHERE condition is OR
+# formula with two disjucts such that the second one is always false
+#
+set @save_optimizer_switch=@@optimizer_switch;
+set @save_join_cache_level=@@join_cache_level;
+CREATE TABLE t1 (i1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1), (7), (4), (8), (4);
+CREATE TABLE t2 (i2 int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (7), (5);
+CREATE TABLE t3 (i3 int) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (7), (2), (9);
+set join_cache_level=3;
+set optimizer_switch='materialization=off,semijoin=off';
+EXPLAIN EXTENDED
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t3 hash_ALL NULL #hash#$hj 5 func 3 100.00 Using where; Using join buffer (flat, BNLH join)
+Warnings:
+Note 1003 select `test`.`t1`.`i1` AS `i1` from `test`.`t1` where <expr_cache><`test`.`t1`.`i1`>(<in_optimizer>(`test`.`t1`.`i1`,<exists>(select `test`.`t3`.`i3` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`i3` = `test`.`t2`.`i2`) and (<cache>(`test`.`t1`.`i1`) = `test`.`t3`.`i3`)))))
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+i1
+7
+set optimizer_switch='materialization=on,semijoin=on';
+EXPLAIN EXTENDED
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 100.00
+1 PRIMARY t1 hash_ALL NULL #hash#$hj 5 test.t2.i2 5 100.00 Using where; Using join buffer (flat, BNLH join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 MATERIALIZED t3 hash_ALL NULL #hash#$hj 5 test.t2.i2 3 100.00 Using where; Using join buffer (flat, BNLH join)
+Warnings:
+Note 1003 select `test`.`t1`.`i1` AS `i1` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where ((`test`.`t3`.`i3` = `test`.`t2`.`i2`) and (`test`.`t1`.`i1` = `test`.`t2`.`i2`))
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+i1
+7
+EXPLAIN EXTENDED
+SELECT * FROM t1
+WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 0 AND i3 = i2 OR 1=2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 100.00
+1 PRIMARY t1 hash_ALL NULL #hash#$hj 5 test.t2.i2 5 100.00 Using where; Using join buffer (flat, BNLH join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 MATERIALIZED t3 hash_ALL NULL #hash#$hj 5 test.t2.i2 3 100.00 Using where; Using join buffer (flat, BNLH join)
+Warnings:
+Note 1003 select `test`.`t1`.`i1` AS `i1` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where ((`test`.`t3`.`i3` = `test`.`t2`.`i2`) and (`test`.`t1`.`i1` = `test`.`t2`.`i2`) and (`test`.`t3`.`i3` > 0))
+SELECT * FROM t1
+WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 0 AND i3 = i2 OR 1=2);
+i1
+7
+SELECT * FROM t1
+WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 7 AND i3 = i2 OR 1=2);
+i1
+DROP TABLE t1,t2,t3;
+set join_cache_level= @save_join_cache_level;
+set optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/subselect_sj_aria.result b/mysql-test/r/subselect_sj_aria.result
new file mode 100644
index 00000000000..ea6cc8d14c4
--- /dev/null
+++ b/mysql-test/r/subselect_sj_aria.result
@@ -0,0 +1,59 @@
+drop table if exists t1,t2,t3,t4;
+#
+# BUG#887468: Second assertion `keypart_map' failed in maria_rkey with semijoin
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+dummy char(30),
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=Aria AUTO_INCREMENT=30 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1;
+INSERT INTO t1 (pk, col_varchar_key, col_int_key) VALUES
+(10,NULL,0), (11,'d',4), (12,'g',8), (13,'x',NULL), (14,'f',NULL),
+(15,'p',0), (16,'j',NULL), (17,'c',8), (18,'z',8), (19,'j',6), (20,NULL,2),
+(21,'p',3), (22,'w',1), (23,'c',NULL), (24,'j',1), (25,'f',10), (26,'v',2),
+(27,'f',103), (28,'q',3), (29,'y',6);
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) DEFAULT NULL,
+dummy char(36),
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key)
+) ENGINE=Aria AUTO_INCREMENT=101 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1;
+INSERT INTO t2 ( pk, col_int_key) VALUES
+(1,8), (2,2), (3,9), (4,6), (5,NULL), (6,NULL), (7,48), (8,228), (9,3), (10,5),
+(11,39), (12,6), (13,8), (14,3), (15,NULL), (16,2), (17,6), (18,3), (19,1), (20,4),
+(21,3), (22,1), (23,NULL), (24,97), (25,0), (26,0), (27,9), (28,5), (29,9), (30,0),
+(31,2), (32,172), (33,NULL), (34,5), (35,119), (36,1), (37,4), (38,8), (39,NULL), (40,6),
+(41,5), (42,5), (43,1), (44,7), (45,2), (46,8), (47,9), (48,NULL), (49,NULL), (50,3),
+(51,172), (52,NULL), (53,6), (54,6), (55,5), (56,4), (57,3), (58,2), (59,7), (60,4),
+(61,6), (62,0), (63,8), (64,5), (65,8), (66,2), (67,9), (68,7), (69,5), (70,7),
+(71,0), (72,4), (73,3), (74,1), (75,0), (76,6), (77,2), (78,NULL), (79,8), (80,NULL),
+(81,NULL), (82,NULL), (83,3), (84,7), (85,3), (86,5), (87,5), (88,1), (89,2), (90,1),
+(91,7), (92,1), (93,9), (94,9), (95,8), (96,3), (97,7), (98,4), (99,9), (100,0);
+CREATE TABLE t3 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+dummy char(34),
+col_varchar_key varchar(1) DEFAULT NULL,
+col_int_key int(11) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=Aria AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1;
+INSERT INTO t3 (pk, col_varchar_key) VALUES (1,'v'), (2,'c'), (3,NULL);
+CREATE TABLE t4 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+dummy char (38),
+PRIMARY KEY (pk)
+) ENGINE=Aria AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1;
+INSERT INTO t4 (pk) VALUES (1), (2), (3);
+SELECT *
+FROM t1
+JOIN t2
+ON ( t2.col_int_key = t1.pk )
+WHERE t1.col_varchar_key IN (
+SELECT t3.col_varchar_key FROM t3, t4
+);
+pk col_int_key col_varchar_key dummy pk col_int_key dummy
+drop table t1, t2, t3, t4;
diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result
new file mode 100644
index 00000000000..de95dd80529
--- /dev/null
+++ b/mysql-test/r/subselect_sj_jcl6.result
@@ -0,0 +1,3029 @@
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set @@optimizer_switch='join_cache_hashed=off';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set join_cache_level=6;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 6
+set @optimizer_switch_for_subselect_sj_test=@@optimizer_switch;
+set @join_cache_level_for_subselect_sj_test=@@join_cache_level;
+drop table if exists t0, t1, t2, t3, t4, t5, t10, t11, t12;
+drop view if exists v1, v2, v3, v4;
+drop procedure if exists p1;
+set @subselect_sj_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj_test,'outer_join_with_cache=off');
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj_test,'semijoin_with_cache=off');
+set join_cache_level=@join_cache_level_for_subselect_sj_test;
+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); Key-ordered Rowid-ordered scan
+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); Key-ordered Rowid-ordered scan
+1 PRIMARY t12 eq_ref PRIMARY PRIMARY 4 test.t10.a 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t12` join `test`.`t1` where ((`test`.`t12`.`pk` = `test`.`t10`.`a`) and (`test`.`t10`.`pk` = `test`.`t1`.`a`))
+subqueries within outer joins go into ON expr.
+explAin extended
+select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
+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 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,`test`.`B`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`B`.`A` in <temporAry tABle> on distinct_key where ((`test`.`B`.`A` = `<suBquery2>`.`pk`))))))) where 1
+t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
+explAin extended
+select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
+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 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t1`.`A`,`test`.`t1`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`t1`.`A` in <temporAry tABle> on distinct_key where ((`test`.`t1`.`A` = `<suBquery2>`.`pk`))))))) where 1
+we shouldn't flatten if we're going to get a join of > MAX_TABLES.
+explain select * from
+t1 s00, t1 s01, t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
+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
+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); Key-ordered Rowid-ordered scan
+1 PRIMARY t2 ref vkey vkey 4 test.t1.vnokey 2 100.00 Using index; FirstMatch(t1)
+Warnings:
+Note 1003 select `test`.`t0`.`vkey` AS `vkey` from `test`.`t0` `t1` semi join (`test`.`t0` `t2`) join `test`.`t0` where ((`test`.`t1`.`pk` = `test`.`t0`.`pk`) and (`test`.`t2`.`vkey` = `test`.`t1`.`vnokey`))
+SELECT vkey FROM t0 WHERE pk IN
+(SELECT t1.pk FROM t0 t1 JOIN t0 t2 ON t2.vkey = t1.vnokey);
+vkey
+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
+0
+0
+0
+0
+2
+2
+3
+5
+5
+7
+7
+7
+8
+9
+9
+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 <subquery2> ALL distinct_key NULL NULL NULL 11
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED it1 index NULL int_key 4 NULL 2 Using index
+2 MATERIALIZED it2 ALL int_key,datetime_key NULL NULL NULL 20 Using where; Using join buffer (flat, 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 t1 ALL NULL NULL NULL NULL 7 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 100.00 Using where; FirstMatch(t1); 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`.`t2`.`c` = `test`.`t1`.`a`) and <nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`)))))))
+show warnings;
+Level Code Message
+Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and <nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`)))))))
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+a
+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 <subquery2> eq_ref distinct_key distinct_key 11 func,func 1 100.00
+2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Rowid-ordered scan
+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; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`c` = `test`.`t1`.`c`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`d` = `test`.`t1`.`d`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0);
+pk
+2
+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; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`e` = `test`.`t1`.`e`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`f` = `test`.`t1`.`f`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`g` = `test`.`t1`.`g`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`h` = `test`.`t1`.`h`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`i` = `test`.`t1`.`i`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`j` = `test`.`t1`.`j`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0);
+pk
+1
+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; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`k` = `test`.`t1`.`k`) and (`test`.`t2`.`pk` > 0))
+SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0);
+pk
+1
+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 <subquery2> ALL distinct_key NULL NULL NULL 15 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 18 100.00 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED 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`.`t2`.`varchar_nokey` = `test`.`t1`.`varchar_key`) and ((`test`.`t1`.`varchar_key` < '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 <subquery3> eq_ref distinct_key distinct_key 13 func 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 13 func 1
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 5 Using where
+2 MATERIALIZED 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;
+#
+# Bug#46692 "Crash occurring on queries with nested FROM subqueries
+# using materialization."
+#
+CREATE TABLE t1 (
+pk INTEGER PRIMARY KEY,
+int_key INTEGER,
+KEY int_key(int_key)
+);
+INSERT INTO t1 VALUES (10,186),(11,NULL),(12,2),(13,3),(14,0),(15,133),(16,1);
+CREATE TABLE t2 (
+pk INTEGER PRIMARY KEY,
+int_key INTEGER,
+KEY int_key(int_key)
+);
+INSERT INTO t2 VALUES (1,7),(2,2);
+SELECT * FROM t1 WHERE (140, 4) IN
+(SELECT t2.int_key, t2 .pk FROM t2 STRAIGHT_JOIN t1 ON t2.int_key);
+pk int_key
+DROP TABLE t1, t2;
+#
+# Bug#42353 "SELECT ... WHERE oe IN (SELECT w/ LEFT JOIN) query
+# causes crash."
+#
+CREATE TABLE t1 (
+pk INTEGER PRIMARY KEY,
+int_nokey INTEGER,
+int_key INTEGER,
+date_key DATE,
+datetime_nokey DATETIME,
+varchar_nokey VARCHAR(1)
+);
+CREATE TABLE t2 (
+date_nokey DATE
+);
+CREATE TABLE t3 (
+pk INTEGER PRIMARY KEY,
+int_nokey INTEGER,
+date_key date,
+varchar_key VARCHAR(1),
+varchar_nokey VARCHAR(1),
+KEY date_key (date_key)
+);
+SELECT date_key FROM t1
+WHERE (int_key, int_nokey)
+IN (SELECT t3.int_nokey, t3.pk
+FROM t2 LEFT JOIN t3 ON (t2.date_nokey < t3.date_key)
+WHERE t3.varchar_key <= t3.varchar_nokey OR t3.int_nokey <= t3.pk
+)
+AND (varchar_nokey <> 'f' OR NOT int_key < 7);
+date_key
+#
+# Bug#45933 "Crash in optimize_semijoin_nests on JOIN in subquery
+# + AND in outer query".
+#
+INSERT INTO t1 VALUES (10,7,5,'2009-06-16','2002-04-10 14:25:30','w'),
+(11,7,0,'0000-00-00','0000-00-00 00:00:00','s'),
+(12,4,0,'2003-07-14','2006-09-14 04:01:02','y'),
+(13,0,4,'2002-07-25','0000-00-00 00:00:00','c'),
+(14,1,8,'2007-07-03','0000-00-00 00:00:00','q'),
+(15,6,5,'2001-11-12','0000-00-00 00:00:00',''),
+(16,2,9,'0000-00-00','0000-00-00 00:00:00','j'),
+(29,9,1,'0000-00-00','2003-08-11 00:00:00','m');
+INSERT INTO t3 VALUES (1,9,'0000-00-00','b','b'),
+(2,2,'2002-09-17','h','h');
+SELECT t1.varchar_nokey FROM t1 JOIN t3 ON t1.datetime_nokey
+WHERE t1.varchar_nokey
+IN (SELECT varchar_nokey FROM t1
+WHERE (pk)
+IN (SELECT t3.int_nokey
+FROM t3 LEFT JOIN t1 ON t1.varchar_nokey
+WHERE t3.date_key BETWEEN '2008-06-07' AND '2006-06-26'
+ )
+);
+varchar_nokey
+DROP TABLE t1, t2, t3;
+#
+# Bug#45219 "Crash on SELECT DISTINCT query containing a
+# LEFT JOIN in subquery"
+#
+CREATE TABLE t1 (
+pk INTEGER NOT NULL,
+int_nokey INTEGER 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)
+);
+INSERT INTO t1 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 t2 LIKE t1;
+INSERT INTO t2 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 t3 LIKE t1;
+INSERT INTO t3 VALUES
+(10,8,'2007-08-19 08:08:38','i'),(11,0,'2000-05-21 03:51:51','');
+SELECT DISTINCT datetime_key FROM t1
+WHERE (int_nokey, pk)
+IN (SELECT t3.pk, t3.pk FROM t2 LEFT JOIN t3 ON t3.varchar_key)
+AND pk = 9;
+datetime_key
+DROP TABLE t1, t2, t3;
+#
+# BUG#53060: LooseScan semijoin strategy does not return all rows
+#
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=off';
+set optimizer_switch='firstmatch=off,loosescan=on';
+CREATE TABLE t1 (i INTEGER);
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
+CREATE TABLE t2 (i INTEGER, j INTEGER, KEY k(i, j));
+INSERT INTO t2 VALUES (1, 0), (1, 1), (2, 0), (2, 1);
+EXPLAIN
+SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index k k 10 NULL 4 Using where; Using index; LooseScan
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0);
+i
+1
+2
+DROP TABLE t1, t2;
+set optimizer_switch=@save_optimizer_switch;
+#
+# BUG#49453: re-execution of prepared statement with view
+# and semijoin crashes
+#
+CREATE TABLE t1 (city VARCHAR(50), country_id INT);
+CREATE TABLE t2 (country_id INT, country VARCHAR(50));
+INSERT INTO t1 VALUES
+('Batna',2),('Bchar',2),('Skikda',2),('Tafuna',3),('Algeria',2) ;
+INSERT INTO t2 VALUES (2,'Algeria'),(2,'AlgeriaDup'),(3,'XAmerican Samoa');
+CREATE VIEW v1 AS
+SELECT country_id as vf_country_id
+FROM t2
+WHERE LEFT(country,1) = "A";
+PREPARE stmt FROM "
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (SELECT vf_country_id FROM v1);
+";
+
+EXECUTE stmt;
+city country_id
+Batna 2
+Bchar 2
+Skikda 2
+Algeria 2
+EXECUTE stmt;
+city country_id
+Batna 2
+Bchar 2
+Skikda 2
+Algeria 2
+DROP TABLE t1,t2;
+DROP VIEW v1;
+#
+# Bug#54437 Extra rows with LEFT JOIN + semijoin
+#
+create table t1 (a int);
+create table t2 (a int);
+create table t3 (a int);
+insert into t1 values(1),(1);
+insert into t2 values(1),(1),(1),(1);
+insert into t3 values(2),(2);
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+set optimizer_switch='semijoin=off';
+explain
+select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a);
+a
+1
+1
+set optimizer_switch='semijoin=on';
+explain
+select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.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 t2 ALL NULL NULL NULL NULL 4 Using where; Start temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (incremental, BNL join)
+select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a);
+a
+1
+1
+set optimizer_switch=@save_optimizer_switch;
+drop table t1,t2,t3;
+#
+# Bug#55955: crash in MEMORY engine with IN(LEFT JOIN (JOIN))
+#
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+CREATE TABLE t3 (a INT);
+INSERT INTO t1 VALUES(1),(1);
+INSERT INTO t2 VALUES(1),(1);
+INSERT INTO t3 VALUES(2),(2);
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=off,materialization=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2inner ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+a
+1
+1
+set optimizer_switch='semijoin=off,materialization=on';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2inner ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+a
+1
+1
+set optimizer_switch='semijoin=on,materialization=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.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 t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t2inner ALL NULL NULL NULL NULL 2 Using join buffer (incremental, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (incremental, BNL join)
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+a
+1
+1
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# BUG#52329 - Wrong result: subquery materialization, IN,
+# non-null field followed by nullable
+#
+CREATE TABLE t1 (a1 CHAR(8) NOT NULL, a2 char(8) NOT NULL);
+CREATE TABLE t2a (b1 char(8), b2 char(8));
+CREATE TABLE t2b (b1 CHAR(8), b2 char(8) NOT NULL);
+CREATE TABLE t2c (b1 CHAR(8) NOT NULL, b2 char(8));
+INSERT INTO t1 VALUES ('1 - 12', '2 - 22');
+INSERT INTO t2a VALUES ('1 - 11', '2 - 21'),
+('1 - 11', '2 - 21'),
+('1 - 12', '2 - 22'),
+('1 - 12', '2 - 22'),
+('1 - 13', '2 - 23');
+INSERT INTO t2b SELECT * FROM t2a;
+INSERT INTO t2c SELECT * FROM t2a;
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=off,materialization=on';
+SELECT * FROM t1
+WHERE (a1, a2) IN (
+SELECT b1, b2 FROM t2c WHERE b1 > '0' GROUP BY b1, b2);
+a1 a2
+1 - 12 2 - 22
+SELECT * FROM t1
+WHERE (a1, a2) IN (
+SELECT b1, b2 FROM t2a WHERE b1 > '0');
+a1 a2
+1 - 12 2 - 22
+SELECT * FROM t1
+WHERE (a1, a2) IN (
+SELECT b1, b2 FROM t2b WHERE b1 > '0');
+a1 a2
+1 - 12 2 - 22
+SELECT * FROM t1
+WHERE (a1, a2) IN (
+SELECT b1, b2 FROM t2c WHERE b1 > '0');
+a1 a2
+1 - 12 2 - 22
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2a,t2b,t2c;
+#
+# Bug#57623: subquery within before insert trigger causes crash (sj=on)
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=on';
+set optimizer_switch='materialization=off';
+explain SELECT *
+FROM ot1
+LEFT JOIN
+(ot2 JOIN ot3 on ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 8
+1 PRIMARY ot3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY ot2 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (incremental, BNL join)
+2 DEPENDENT SUBQUERY it1 ALL NULL NULL NULL NULL 8 Using where
+SELECT *
+FROM ot1
+LEFT JOIN
+(ot2 JOIN ot3 on ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
+a a a
+0 0 0
+6 6 6
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+5 NULL NULL
+7 NULL NULL
+prepare s from 'SELECT *
+FROM ot1
+LEFT JOIN
+(ot2 JOIN ot3 on ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1)';
+execute s;
+a a a
+0 0 0
+6 6 6
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+5 NULL NULL
+7 NULL NULL
+execute s;
+a a a
+0 0 0
+6 6 6
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+5 NULL NULL
+7 NULL NULL
+deallocate prepare s;
+set optimizer_switch='materialization=on';
+explain SELECT *
+FROM ot1
+LEFT JOIN
+(ot2 JOIN ot3 on ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 8
+1 PRIMARY ot3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY ot2 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (incremental, BNL join)
+2 MATERIALIZED it1 ALL NULL NULL NULL NULL 8
+SELECT *
+FROM ot1
+LEFT JOIN
+(ot2 JOIN ot3 on ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
+a a a
+0 0 0
+6 6 6
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+5 NULL NULL
+7 NULL NULL
+prepare s from 'SELECT *
+FROM ot1
+LEFT JOIN
+(ot2 JOIN ot3 on ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1)';
+execute s;
+a a a
+0 0 0
+6 6 6
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+5 NULL NULL
+7 NULL NULL
+execute s;
+a a a
+0 0 0
+6 6 6
+1 NULL NULL
+2 NULL NULL
+3 NULL NULL
+4 NULL NULL
+5 NULL NULL
+7 NULL NULL
+deallocate prepare s;
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE ot1, ot2, ot3, it1;
+#
+# Bug#59919/11766739: Crash in tmp_table_param::init() with semijoin=on
+#
+CREATE TABLE t1 (f1 INTEGER) ENGINE=MyISAM;
+CREATE TABLE t2 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM;
+CREATE TABLE t3 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1,1), (2,1);
+INSERT INTO t3 VALUES
+(1,1), (2,1), (5,4), (7,3), (8,2), (8,1), (7,3),
+(9,5), (4,3), (7,2), (7,7), (3,1), (5,8), (9,7);
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=off,materialization=on';
+EXPLAIN
+SELECT * FROM t3
+WHERE f2 IN (SELECT t1.f1
+FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 14 Using where
+2 MATERIALIZED t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED b1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED b2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t3
+WHERE f2 IN (SELECT t1.f1
+FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE);
+f1 f2
+1 1
+2 1
+8 1
+3 1
+set optimizer_switch='semijoin=on,materialization=on';
+EXPLAIN
+SELECT * FROM t3
+WHERE f2 IN (SELECT t1.f1
+FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1
+1 PRIMARY t3 ALL NULL NULL NULL NULL 14 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED b1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED b2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t3
+WHERE f2 IN (SELECT t1.f1
+FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE);
+f1 f2
+1 1
+2 1
+8 1
+3 1
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1, t2, t3 ;
+#
+#
+# BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3
+#
+CREATE TABLE t1 ( t1field integer, primary key (t1field));
+CREATE TABLE t2 ( t2field integer, primary key (t2field));
+INSERT INTO t1 VALUES (1),(2),(3);
+INSERT INTO t2 VALUES (2),(3),(4);
+explain
+SELECT * FROM t1 A
+WHERE
+A.t1field IN (SELECT A.t1field FROM t2 B) AND
+A.t1field IN (SELECT C.t2field FROM t2 C
+WHERE C.t2field IN (SELECT D.t2field FROM t2 D));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY A index PRIMARY PRIMARY 4 NULL 3 Using index
+1 PRIMARY B index NULL PRIMARY 4 NULL 3 Using index; FirstMatch(A); Using join buffer (flat, BNL join)
+1 PRIMARY C eq_ref PRIMARY PRIMARY 4 test.A.t1field 1 Using index
+1 PRIMARY D eq_ref PRIMARY PRIMARY 4 test.A.t1field 1 Using index
+SELECT * FROM t1 A
+WHERE
+A.t1field IN (SELECT A.t1field FROM t2 B) AND
+A.t1field IN (SELECT C.t2field FROM t2 C
+WHERE C.t2field IN (SELECT D.t2field FROM t2 D));
+t1field
+2
+3
+drop table t1,t2;
+#
+# BUG#787299: Valgrind complains on a join query with two IN subqueries
+#
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+create table t2 as select * from t1;
+select * from t1 A, t1 B
+where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D);
+a a
+1 1
+2 2
+3 3
+explain
+select * from t1 A, t1 B
+where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY A ALL NULL NULL NULL NULL 3
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY B ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED C ALL NULL NULL NULL NULL 3
+3 MATERIALIZED D ALL NULL NULL NULL NULL 3
+drop table t1, t2;
+#
+# BUG#784441: Abort on semijoin with a view as the inner table
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (1), (1);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (1), (1);
+CREATE VIEW v1 AS SELECT 1;
+EXPLAIN
+SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED <derived3> system NULL NULL NULL NULL 1
+3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
+a a
+1 1
+1 1
+1 1
+1 1
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# BUG#751439 Assertion `!table->file || table->file->inited == handler::NONE' failed with subquery
+#
+CREATE TABLE t1 ( f10 int, f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0,0),(0,0);
+CREATE TABLE t2 ( f11 int);
+INSERT IGNORE INTO t2 VALUES (0),(0);
+CREATE TABLE t3 ( f11 int) ;
+INSERT IGNORE INTO t3 VALUES (0);
+SELECT alias1.f11 AS field2
+FROM ( t3 AS alias2 JOIN t1 AS alias3 ON alias3.f10 = 1)
+LEFT JOIN ( t2 AS alias1 ) ON alias3.f11 = 1
+WHERE alias2.f11 IN ( SELECT f11 FROM t2 )
+GROUP BY field2 ;
+field2
+drop table t1, t2, t3;
+#
+# BUG#778406 Crash in hp_movelink with Aria engine and subqueries
+#
+CREATE TABLE t4 (f10 varchar(32) , KEY (f10)) ENGINE=Aria;
+INSERT INTO t4 VALUES ('x'),('m'),('c');
+CREATE TABLE t1 (f11 int) ENGINE=Aria;
+INSERT INTO t1 VALUES (0),(0),(0);
+CREATE TABLE t2 ( f10 int) ENGINE=Aria;
+INSERT INTO t2 VALUES (0),(0),(0);
+CREATE TABLE t3 ( f10 int, f11 int) ENGINE=Aria;
+SELECT *
+FROM t4
+WHERE f10 IN
+( SELECT t1.f11
+FROM t1
+LEFT JOIN t2 JOIN t3 ON t3.f10 = t2.f10 ON t3.f11 != 0 );
+f10
+x
+m
+c
+drop table t1,t2,t3,t4;
+#
+# BUG#751484: Valgrind warning / sporadic crash in evaluate_join_record sql_select.cc:14099 with semijoin
+#
+CREATE TABLE t1 ( f10 int, f11 int, KEY (f10));
+INSERT IGNORE INTO t1 VALUES (0, 0),(0, 0);
+CREATE TABLE t3 ( f10 int);
+INSERT IGNORE INTO t3 VALUES (0);
+set @tmp_751484= @@optimizer_switch;
+set optimizer_switch='materialization=on';
+SELECT * FROM t1
+WHERE f11 IN (
+SELECT C_SQ1_alias1.f11
+FROM t1 AS C_SQ1_alias1
+JOIN t3 AS C_SQ1_alias2
+ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10
+);
+f10 f11
+0 0
+0 0
+set optimizer_switch='materialization=off';
+SELECT * FROM t1
+WHERE f11 IN (
+SELECT C_SQ1_alias1.f11
+FROM t1 AS C_SQ1_alias1
+JOIN t3 AS C_SQ1_alias2
+ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10
+);
+f10 f11
+0 0
+0 0
+set optimizer_switch=@tmp_751484;
+drop table t1, t3;
+# BUG#795530 Wrong result with subquery semijoin materialization and outer join
+# Simplified testcase that uses DuplicateElimination
+#
+create table t1 (a int);
+create table t2 (a int, b char(10));
+insert into t1 values (1),(2);
+insert into t2 values (1, 'one'), (3, 'three');
+create table t3 (b char(10));
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+explain select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
+b
+drop table t1, t2, t3;
+#
+# BUG#600958 RQG: Crash in optimize_semijoin_nests
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) DEFAULT NULL,
+col_date_key date DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key),
+KEY col_date_key (col_date_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (10,8,'2002-02-21',NULL);
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) DEFAULT NULL,
+col_date_key date DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key),
+KEY col_date_key (col_date_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (1,7,'1900-01-01','f');
+SELECT col_date_key FROM t1
+WHERE 5 IN (
+SELECT SUBQUERY3_t1 .col_int_key
+FROM t2 SUBQUERY3_t1
+LEFT JOIN t1 SUBQUERY3_t2 ON SUBQUERY3_t1 .col_varchar_key
+);
+col_date_key
+drop table t2, t1;
+#
+# No BUG#: Duplicate weedout check is not done for outer joins
+#
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(1),(2),(2);
+insert into t2 values (1);
+create table t0 (a int);
+insert into t0 values (1),(2);
+set @tmp_20110622= @@optimizer_switch;
+set optimizer_switch='firstmatch=off,loosescan=off,materialization=off';
+# Check DuplicateWeedout + join buffer
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary; Using join buffer (incremental, BNL join)
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+a
+1
+2
+# Check DuplicateWeedout without join buffer
+set @tmp_jcl_20110622= @@join_cache_level;
+set join_cache_level= 0;
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+a
+1
+2
+# Check FirstMatch without join buffer:
+set optimizer_switch='firstmatch=on';
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+a
+1
+2
+#
+# Now, check the same for multiple inner tables:
+alter table t2 add b int;
+update t2 set b=a;
+create table t3 as select * from t2;
+set optimizer_switch='firstmatch=off';
+set join_cache_level= 0;
+# DuplicateWeedout without join buffer
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+a
+1
+2
+set @@join_cache_level=@tmp_jcl_20110622;
+# DuplicateWeedout + join buffer
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary; Using join buffer (incremental, BNL join)
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+a
+1
+2
+# Now, let the inner join side have a 'partial' match
+select * from t3;
+a b
+1 1
+insert into t3 values(2,2);
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using join buffer (incremental, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (incremental, BNL join)
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+a
+1
+2
+set @@optimizer_switch=@tmp_20110622;
+drop table t0, t1, t2, t3;
+#
+# BUG#802965: Crash in do_copy_not_null with semijoin=on in maria-5.3
+#
+set @save_802965= @@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=off,firstmatch=off,loosescan=off';
+CREATE TABLE t2 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t2 VALUES (19),(20);
+CREATE TABLE t1 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t1 VALUES (21),(22),(23),(24);
+SELECT *
+FROM t2 , t1
+WHERE t2.f1 IN
+(
+SELECT SQ1_alias1.f1
+FROM t1 AS SQ1_alias1 LEFT JOIN t2 AS SQ1_alias2 JOIN t2 AS SQ1_alias3 ON SQ1_alias3.f1 ON SQ1_alias3.f1
+)
+AND t1.f1 = t2.f1 ;
+f1 f1
+DROP TABLE t1, t2;
+set optimizer_switch=@save_802965;
+#
+# BUG#803365: Crash in pull_out_semijoin_tables with outer join + semijoin + derived tables in maria-5.3 with WL#106
+#
+CREATE TABLE t1 ( f1 int) ;
+INSERT INTO t1 VALUES (1),(1);
+CREATE TABLE t2 ( f2 int) ;
+INSERT INTO t2 VALUES (1),(1);
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (1),(1);
+SELECT *
+FROM t1
+WHERE t1.f1 IN (
+SELECT t2.f2
+FROM t2
+LEFT JOIN (
+SELECT *
+FROM t3
+) AS alias1
+ON alias1.f3 = t2.f2
+);
+f1
+1
+1
+DROP TABLE t1,t2,t3;
+#
+# BUG#611704: Crash in replace_where_subcondition with nested subquery and semijoin=on
+#
+CREATE TABLE t1 ( f1 int) ;
+CREATE TABLE t2 ( f1 int) ;
+CREATE TABLE t3 ( f1 int) ;
+SELECT * FROM (
+SELECT t3.*
+FROM t2 STRAIGHT_JOIN t3
+ON t3.f1
+AND (t3.f1 ) IN (
+SELECT t1.f1
+FROM t1
+)
+) AS alias1;
+f1
+DROP TABLE t1,t2,t3;
+# BUG#611704: another testcase:
+CREATE TABLE t1 ( f1 int(11), f3 varchar(1), f4 varchar(1)) ;
+CREATE TABLE t2 ( f2 int(11), KEY (f2));
+CREATE TABLE t3 ( f4 varchar(1)) ;
+PREPARE st1 FROM '
+SELECT *
+FROM t1
+STRAIGHT_JOIN ( t2 STRAIGHT_JOIN t3 ON t2.f2 )
+ON (t1.f3) IN ( SELECT f4 FROM t1 )
+';
+EXECUTE st1;
+f1 f3 f4 f2 f4
+DROP TABLE t1,t2,t3;
+#
+# BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90
+# (Original testcase)
+#
+CREATE TABLE t1 (f1 int, f2 int );
+INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL);
+CREATE TABLE t2 (f2 int, f3 int );
+INSERT INTO t2 VALUES (NULL,NULL),(0,0);
+CREATE TABLE t3 ( f1 int, f3 int );
+INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0);
+CREATE TABLE t4 ( f2 int, KEY (f2) );
+INSERT INTO t4 VALUES (0),(NULL);
+CREATE VIEW v4 AS SELECT DISTINCT f2 FROM t4 ;
+# The following must not have outer joins:
+explain extended
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (incremental, BNL join)
+2 MATERIALIZED t4 index f2 f2 5 NULL 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` semi join (`test`.`t4`) join `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`f1` = `test`.`t1`.`f1`) and (`test`.`t1`.`f2` = `test`.`t2`.`f2`))
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
+f1 f2 f3 f3
+2 0 0 0
+4 0 0 0
+4 0 0 0
+drop view v4;
+drop table t1, t2, t3, t4;
+#
+# BUG#803303: Wrong result with semijoin=on, outer join in maria-5.3-subqueries-mwl90
+#
+# Testcase#1:
+set @tmp803303= @@optimizer_switch;
+set optimizer_switch = 'semijoin=on,materialization=off,firstmatch=off,loosescan=off';
+CREATE TABLE t2 ( f1 int) ;
+INSERT IGNORE INTO t2 VALUES (6),(8);
+CREATE TABLE t1 ( f1 int, f2 int, f3 int) ;
+INSERT IGNORE INTO t1 VALUES (8,0,0),(7,0,0),(9,0,0);
+SELECT alias2.f1
+FROM t2 AS alias1
+LEFT JOIN ( t1 AS alias2 JOIN t1 AS alias3 ON alias3.f2 = alias2.f3 )
+ON alias3.f2 = alias2.f2
+WHERE alias2.f1 IN ( SELECT f1 FROM t2 AS alias4 ) ;
+f1
+8
+8
+8
+8
+8
+8
+drop table t1,t2;
+set optimizer_switch= @tmp803303;
+# Testcase #2:
+CREATE TABLE t1 ( f10 int) ;
+INSERT INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f10 int, f11 varchar(1)) ;
+INSERT INTO t2 VALUES (0,'a'),(0,'b');
+CREATE TABLE t3 ( f10 int) ;
+INSERT INTO t3 VALUES (0),(0),(0),(0),(0);
+CREATE TABLE t4 ( f10 varchar(1), f11 int) ;
+INSERT INTO t4 VALUES ('a',0),('b',0);
+SELECT * FROM t1
+LEFT JOIN ( t2 JOIN t3 ON t3.f10 = t2.f10 ) ON t1.f10 = t2.f10
+WHERE t2.f10 IN (
+SELECT t4.f11
+FROM t4
+WHERE t4.f10 != t2.f11
+);
+f10 f10 f11 f10
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+drop table t1,t2,t3,t4;
+#
+# BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90
+#
+set @tmp803457=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+CREATE TABLE t1 (f1 int, f2 int );
+INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL);
+CREATE TABLE t2 (f2 int, f3 int );
+INSERT INTO t2 VALUES (NULL,NULL),(0,0);
+CREATE TABLE t3 ( f1 int, f3 int );
+INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0);
+CREATE TABLE t4 ( f2 int);
+INSERT INTO t4 VALUES (0),(NULL);
+# The following uses Duplicate Weedout, and "End temporary" must not be
+# in the middle of the inner side of an outer join:
+explain
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; Start temporary; End temporary; Using join buffer (incremental, BNL join)
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3 ) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
+f1 f2 f3 f3
+2 0 0 0
+4 0 0 0
+4 0 0 0
+0 NULL NULL NULL
+DROP TABLE t1, t2, t3, t4;
+set @tmp803457=@@optimizer_switch;
+#
+# BUG#818280: crash in do_copy_not_null() in maria-5.3 with semijoin
+#
+CREATE TABLE t1 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ;
+INSERT IGNORE INTO t1 VALUES (2,7),(1,3),(5,6);
+CREATE TABLE t3 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ;
+INSERT IGNORE INTO t3 VALUES (2,7),(1,3),(5,6);
+CREATE TABLE t2 ( c1 int NOT NULL , c5 int NOT NULL );
+INSERT IGNORE INTO t2 VALUES (2,2),(2,2),(5,6);
+SELECT * FROM t1 WHERE c1 IN ( SELECT t3.c1 FROM t3 LEFT JOIN t2 ON t2 .c1 = t3 .c1 WHERE t2.c5 != 0 );
+c1 c2
+2 7
+5 6
+DROP TABLE t1, t2, t3;
+#
+# BUG#834534: Assertion `0' failed in replace_where_subcondition with semijoin subquery in HAVING
+#
+CREATE TABLE t1 ( d int );
+INSERT INTO t1 VALUES (2),(2),(0),(2),(2);
+CREATE TABLE t2 ( b int );
+INSERT INTO t2 VALUES (4),(3),(3);
+CREATE TABLE t3 ( a int );
+SELECT *
+FROM t3
+WHERE (t3.a) IN (
+SELECT t1.d
+FROM t1
+HAVING ( 4 ) IN (
+SELECT t2.b
+FROM t2
+)
+);
+a
+drop table t1, t2,t3;
+#
+# BUG#834758: Wrong result with innner join, LooseScan, two-column IN() predicate
+#
+set @tmp835758=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
+CREATE TABLE t1 (b int) ;
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (6),(10);
+CREATE TABLE t3 (a int, b int, KEY (b)) ;
+INSERT INTO t3 VALUES (6,5),(6,2),(8,0),(9,1),(6,5);
+# This used to incorrectly pick a join order of (t1, LooseScan(t3), t2):
+explain
+SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 2 Using index; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL b NULL NULL NULL 5 Using where; Start temporary; End temporary; Using join buffer (incremental, BNL join)
+SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
+b a
+5 6
+DROP TABLE t1, t2, t3;
+set @@optimizer_switch= @tmp835758;
+#
+# BUG#834739: Wrong result with 3-way inner join, LooseScan,multipart keys
+#
+set @tmp834739=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
+CREATE TABLE t2 ( b int, c int, KEY (b)) ;
+INSERT INTO t2 VALUES (1,0),(1,0),(9,0),(1,0),(5,0);
+INSERT INTO t2 VALUES (2,0),(3,0),(8,0),(6,0),(5,0);
+CREATE TABLE t3 ( a int);
+INSERT INTO t3 VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+CREATE TABLE t4 ( a int);
+INSERT INTO t4 VALUES (0),(0),(0);
+CREATE TABLE t5 ( b int, a int , KEY (a,b)) ;
+INSERT INTO t5 VALUES (7,0),(9,0);
+explain
+SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t5 index a a 10 NULL 2 Using index; Start temporary
+1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL b NULL NULL NULL 10 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; End temporary; Using join buffer (incremental, BNL join)
+SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
+a
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+DROP TABLE t2, t3, t4, t5;
+set @@optimizer_switch=@tmp834739;
+#
+# BUG#830993: Crash in end_read_record with derived table
+#
+set @tmp_830993=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=off,materialization=off,firstmatch=off';
+set @tmp_830993_jbs= @@join_buffer_size;
+set join_buffer_size=160;
+CREATE TABLE t1 (
+a int(11) NOT NULL AUTO_INCREMENT,
+b int(11) DEFAULT NULL,
+c int(11) DEFAULT NULL,
+d time DEFAULT NULL,
+e varchar(1) DEFAULT NULL,
+f varchar(1) DEFAULT NULL,
+PRIMARY KEY (a),
+KEY c (c),
+KEY d (d),
+KEY e (e,c)
+);
+INSERT INTO t1 VALUES (10,NULL,8,'22:55:23','x','x'),
+(11,8,7,'10:19:31','d','d'),(12,1,1,'14:40:36','r','r'),
+(13,9,7,'04:37:47','f','f'),(14,4,9,'19:34:06','y','y'),
+(15,3,NULL,'20:35:33','u','u'),(16,2,1,NULL,'m','m'),
+(17,NULL,9,'14:43:37',NULL,NULL),(18,2,2,'02:23:09','o','o'),
+(19,NULL,9,'01:22:45','w','w'),(20,6,2,'00:00:00','m','m'),
+(21,7,4,'00:13:25','q','q'),(22,2,0,'03:47:16',NULL,NULL),
+(23,5,4,'01:41:48','d','d'),(24,7,8,'00:00:00','g','g'),
+(25,6,NULL,'22:32:04','x','x'),(26,6,NULL,'16:44:14','f','f'),
+(27,2,0,'17:38:37','p','p'),(28,9,NULL,'08:46:48','j','j'),
+(29,6,8,'14:11:27','c','c');
+CREATE TABLE t2 like t1;
+INSERT INTO t2 VALUES (1,2,4,'22:34:09','v','v'),
+(2,150,62,'14:26:02','v','v'),(3,NULL,7,'14:03:03','c','c'),
+(4,2,1,'01:46:09',NULL,NULL),(5,5,0,'16:21:18','x','x'),
+(6,3,7,'18:56:33','i','i'),(7,1,7,NULL,'e','e'),
+(8,4,1,'09:29:08','p','p'),(9,NULL,7,'19:11:10','s','s'),
+(10,2,1,'11:57:26','j','j'),(11,6,5,'00:39:46','z','z'),
+(12,6,2,'03:28:15','c','c'),(13,8,0,'06:44:18','a','a'),
+(14,2,1,'14:36:39','q','q'),(15,6,8,'18:42:45','y','y'),
+(16,8,1,'02:57:29',NULL,NULL),(17,3,1,'16:46:13','r','r'),
+(18,3,9,'19:39:02','v','v'),(19,9,1,NULL,NULL,NULL),
+(20,6,5,'20:58:33','r','r');
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+explain
+SELECT
+alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
+alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
+alias2.e as a2_e, alias2.f as a2_f,
+t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
+FROM
+(SELECT * FROM t2) AS alias1,
+t1 AS alias2,
+t2
+WHERE
+alias1.c IN (SELECT SQ3_alias1.b
+FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
+LIMIT 100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Start temporary
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY SQ3_alias2 index NULL PRIMARY 4 NULL 20 Using index; End temporary; Using join buffer (incremental, BNL join)
+1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 Using join buffer (incremental, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (incremental, BNL join)
+2 DERIVED t2 ALL NULL NULL NULL NULL 20
+create table t3 as
+SELECT
+alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
+alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
+alias2.e as a2_e, alias2.f as a2_f,
+t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
+FROM
+(SELECT * FROM t2) AS alias1,
+t1 AS alias2,
+t2
+WHERE
+alias1.c IN (SELECT SQ3_alias1.b
+FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
+LIMIT 100;
+set optimizer_switch=@tmp_optimizer_switch;
+drop table t1,t2, t3;
+set optimizer_switch=@tmp_830993;
+set join_buffer_size= @tmp_830993_jbs;
+#
+# BUG##849717: Crash in Item_func::fix_fields on second execution of a prepared statement with semijoin
+#
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int, b int) ;
+PREPARE st1 FROM "SELECT * FROM t2 LEFT JOIN t1 ON t2.a != 0 AND ('j','r') IN ( SELECT b,a FROM t3)";
+EXECUTE st1;
+a a
+EXECUTE st1;
+a a
+DROP TABLE t1, t2, t3;
+#
+# BUG#849776: Wrong result with semijoin + "Impossible where"
+#
+CREATE TABLE t1 ( b varchar(1), a integer) ;
+INSERT INTO t1 VALUES ('z',8);
+CREATE TABLE t2 ( a integer, b varchar(1)) ;
+CREATE TABLE t4 ( a integer, b varchar(1)) ;
+CREATE TABLE t5 ( a integer) ;
+INSERT INTO t5 VALUES (8);
+select * from t5 where (a) in (
+SELECT t1.a
+FROM t1 LEFT JOIN t2 ON t1.a = t2.a
+WHERE t2.b NOT IN (SELECT t4.b FROM t4 WHERE t4.b < t1.b)
+);
+a
+8
+DROP TABLE t1, t2, t4, t5;
+#
+# BUG#861147: Assertion `fixed == 1' failed in Item_func_eq::val_int() with semijoin + materialization + max_join_size
+#
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+set @tmp_mjs_861147= @@max_join_size;
+SET max_join_size=10;
+set @tmp_os_861147= @@optimizer_switch;
+set @@optimizer_switch='semijoin=on,materialization=on';
+explain
+select * from t1 where a in (select max(A.a + B.a + C.a) from t1 A, t1 B, t1 C);
+ERROR 42000: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay
+set max_join_size= @tmp_mjs_861147;
+set optimizer_switch= @tmp_os_861147;
+drop table t1;
+#
+# BUG#877288: Wrong result with semijoin + materialization + multipart key
+#
+set @tmp_877288=@@optimizer_switch;
+set optimizer_switch='semijoin=ON,materialization=ON';
+CREATE TABLE t1 ( a int) ;
+INSERT INTO t1 VALUES (19),(19),(19),(20),(20),(20),(20),(20),(20);
+CREATE TABLE t2 ( b int NOT NULL , c int NOT NULL , KEY (b,c)) ;
+INSERT INTO t2 VALUES (14,1),(15,1),(16,1),(17,1),(18,1),(19,1),(20,1);
+CREATE TABLE t3 ( a int, d int) ;
+INSERT INTO t3 VALUES (19,1),(7,1),(3,1),(3,1),(20,1),(3,1),(16,1),(17,1),(9,1),(4,1),(6,1),(15,1),(17,1);
+explain
+SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 13 Using where
+2 MATERIALIZED t2 ref b b 4 test.t3.a 1 Using index
+SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
+a
+19
+19
+19
+20
+20
+20
+20
+20
+20
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@tmp_877288;
+#
+# BUG#878753: Assertion '0' failed in replace_where_subcondition with derived_merge
+#
+set @tmp878753= @@optimizer_switch;
+set optimizer_switch= 'semijoin=on,derived_merge=on';
+CREATE TABLE t1 (b int(11)) ;
+CREATE TABLE t2 (c int, b int, d varchar(52) NOT NULL) ;
+CREATE TABLE t3 (b int(11)) ;
+PREPARE st1 FROM '
+ SELECT * FROM t1
+ JOIN (
+ SELECT t2.* FROM t2
+ WHERE t2.d <> "a"
+ AND t2.c IN (
+ SELECT t3.b
+ FROM t3
+ )
+ ) AS alias2
+ ON ( alias2.b = t1.b );
+';
+EXECUTE st1;
+b c b d
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@tmp878753;
+#
+# Bug #889750: semijoin=on + firstmatch=off + semijoin_with_cache=off
+#
+create table t1 (a int);
+insert into t1 values (7), (1), (5), (3);
+create table t2 (a int);
+insert into t2 values (4), (1), (8), (3), (9), (2);
+set @tmp_otimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=on';
+set optimizer_switch='firstmatch=off';
+set optimizer_switch='semijoin_with_cache=on';
+explain
+select * from t1 where t1.a in (select t2.a from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+select * from t1 where t1.a in (select t2.a from t2);
+a
+1
+3
+set optimizer_switch='semijoin_with_cache=off';
+explain
+select * from t1 where t1.a in (select t2.a from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; Start temporary; End temporary
+select * from t1 where t1.a in (select t2.a from t2);
+a
+1
+3
+set optimizer_switch= @tmp_otimizer_switch;
+drop table t1,t2;
+#
+# Bug #887496: semijoin with IN equality for the second part of an index
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (9), (0), (8), (5);
+CREATE TABLE t2 (a int, b varchar(1), INDEX idx (b,a));
+INSERT INTO t2 VALUES (5,'r'), (5,'z');
+CREATE TABLE t3 (a int, b varchar(1), INDEX idx (b,a));
+INSERT INTO t3 VALUES (5,'r'), (5,'z');
+set @tmp_otimizer_switch= @@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on,firstmatch=on';
+SET SESSION optimizer_switch='loosescan=off';
+EXPLAIN
+SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index idx idx 9 NULL 2 Using where; Using index; Start temporary
+1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
+SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
+a
+5
+SET SESSION optimizer_switch='loosescan=on';
+EXPLAIN
+SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index idx idx 9 NULL 2 Using where; Using index; Start temporary
+1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
+SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
+a
+5
+set optimizer_switch= @tmp_otimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# Bug #901312: materialized semijoin + right join
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (4), (1);
+CREATE TABLE t2 (b int);
+INSERT INTO t2 VALUES (4), (1);
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (4), (1);
+set @tmp_otimizer_switch= @@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on,materialization=on';
+EXPLAIN
+SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2
+SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3);
+a b
+4 4
+1 1
+set optimizer_switch= @tmp_otimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# Bug #901709: assertion failure with record count == 0
+#
+CREATE TABLE t1 (a int, KEY (a));
+INSERT INTO t1 VALUES (4), (6);
+CREATE TABLE t2 (a int, KEY (a));
+INSERT INTO t2 VALUES (4), (6);
+CREATE TABLE t3 (b int);
+INSERT INTO t3 VALUES (4);
+CREATE TABLE t4 (c int);
+SET @tmp_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch='semijoin=on';
+SET @@optimizer_switch='materialization=on';
+SET @@optimizer_switch='firstmatch=on';
+SET optimizer_switch='semijoin_with_cache=on';
+SET optimizer_prune_level=0;
+EXPLAIN
+SELECT * FROM t1, t2
+WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 system NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1
+1 PRIMARY t1 ref a a 5 const 1 Using index
+1 PRIMARY t2 ref a a 5 test.t3.b 1 Using index
+2 MATERIALIZED t4 ALL NULL NULL NULL NULL 0
+SELECT * FROM t1, t2
+WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4);
+a a
+SET optimizer_prune_level=DEFAULT;
+SET optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1,t2,t3,t4;
+#
+# BUG#901399: Wrong result (extra row) with semijoin=ON, materialization=OFF, optimizer_prune_level=0
+#
+set @opl_901399= @@optimizer_prune_level;
+set @os_091399= @@optimizer_switch;
+SET optimizer_prune_level=0;
+SET optimizer_switch = 'materialization=off';
+CREATE TABLE t1 ( c INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+(0),(1),(2),(3),(4),(5),
+(6),(7),(8),(9),(10),(11),(12);
+CREATE TABLE t2 ( a INT, b INT, KEY(a)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (3,20),(2,21),(3,22);
+SELECT *
+FROM t1 AS alias1, t1 AS alias2
+WHERE ( alias1.c, alias2.c )
+IN (
+SELECT alias3.a, alias3.a
+FROM t2 AS alias3, t2 alias4
+WHERE alias3.b = alias4.b
+);
+c c
+2 2
+3 3
+set optimizer_prune_level= @opl_901399;
+set optimizer_switch= @os_091399;
+DROP TABLE t1,t2;
+#
+# BUG#912510: Crash in do_copy_not_null with semijoin=ON, firstmatch=ON, aggregate ...
+#
+CREATE TABLE t1 ( a VARCHAR(1) NOT NULL );
+INSERT INTO t1 VALUES ('k'),('l');
+CREATE TABLE t2 ( b VARCHAR(1) NOT NULL, KEY(b) );
+INSERT INTO t2 VALUES ('k'),('l');
+CREATE TABLE t3 ( c VARCHAR(1) NOT NULL, KEY(c) );
+INSERT INTO t3 VALUES ('m'),('n');
+SELECT a, COUNT(*) FROM t1
+WHERE a IN (
+SELECT b FROM t2 force index(b), t3 force index(c)
+WHERE c = b AND b = a
+);
+a COUNT(*)
+NULL 0
+DROP TABLE t1, t2, t3;
+#
+# BUG#920255: Wrong result (extra rows) with loosescan and IN subquery
+#
+CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, KEY(b) );
+INSERT INTO t1 VALUES
+(1,2),(2,1),(3,3),(4,2),(5,5),
+(6,3),(7,1),(8,4),(9,3),(10,2);
+CREATE TABLE t2 ( c INT, d INT, UNIQUE KEY(c) );
+INSERT INTO t2 VALUES
+(1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1);
+SELECT a, b, d FROM t1, t2
+WHERE ( b, d ) IN
+( SELECT b, d FROM t1, t2 WHERE b = c );
+a b d
+1 2 1
+1 2 1
+2 1 2
+2 1 2
+3 3 3
+3 3 3
+4 2 1
+4 2 1
+5 5 5
+6 3 3
+6 3 3
+7 1 2
+7 1 2
+8 4 2
+8 4 2
+9 3 3
+9 3 3
+10 2 1
+10 2 1
+DROP TABLE t1, t2;
+#
+# BUG#920713: Wrong result (missing rows) with firstmatch+BNL, IN subquery, ...
+#
+CREATE TABLE t1 ( a VARCHAR(1) ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('e'),('w'),('a'),('h'),('x'),('k'),('g');
+CREATE TABLE t2 ( b INT, c VARCHAR(1) );
+INSERT INTO t2 VALUES (0,'j'),(8,'v');
+SELECT * FROM t1 alias1, t2 alias2
+WHERE alias2.c IN (
+SELECT alias4.c FROM t1 alias3, t2 alias4
+);
+a b c
+e 0 j
+e 8 v
+w 0 j
+w 8 v
+a 0 j
+a 8 v
+h 0 j
+h 8 v
+x 0 j
+x 8 v
+k 0 j
+k 8 v
+g 0 j
+g 8 v
+DROP TABLE t1, t2;
+#
+# BUG#923246: Loosescan reports different result than other semijoin methods
+#
+set @tmp_923246= @@optimizer_switch;
+set optimizer_switch='mrr=on,materialization=off';
+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;
+select * from t3 where a in (select kp1 from t1 where kp1<20);
+a
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+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 t1 range kp1 kp1 5 NULL 48 Using where; Using index; LooseScan
+1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
+drop table t0,t1,t3;
+set optimizer_switch= @tmp_923246;
+#
+# BUG#952583: Server crashes in Item_field::fix_after_pullout on INSERT .. SELECT
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 ( b INT );
+INSERT INTO t2 VALUES (3),(4);
+INSERT INTO t1
+SELECT * FROM ( SELECT * FROM t1 ) AS alias
+WHERE a IN ( SELECT b FROM t2 );
+DROP TABLE t1, t2;
+#
+# BUG#952372: Server crashes on 2nd execution of PS in find_field_in_tables with semijoin+materialization
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (2),(3);
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE TABLE t2 ( b VARCHAR(1) );
+INSERT INTO t2 VALUES ('v'),('v');
+PREPARE pstmt FROM
+'SELECT DISTINCT a FROM v1, t2
+ WHERE b IN ( SELECT MIN(b) FROM t2 )';
+EXECUTE pstmt;
+a
+2
+3
+EXECUTE pstmt;
+a
+2
+3
+DEALLOCATE PREPARE pstmt;
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
+# BUG#978479: Wrong result (extra rows) with derived_with_keys+loosescan+semijoin=ON, materialization=OFF
+#
+set @tmp_jcl_978479= @@join_cache_level;
+set join_cache_level=0;
+set @tmp_os_978479= @@optimizer_switch;
+set optimizer_switch = 'derived_with_keys=on,loosescan=on,semijoin=on,materialization=off';
+# Part#1: make sure EXPLAIN is using LooseScan:
+CREATE TABLE t1 ( a INT, b INT );
+INSERT INTO t1 VALUES
+(4,0),(6,8),(3,1),(5,8),(3,9),(2,4),
+(2,6),(9,1),(5,4),(7,7),(5,4);
+CREATE ALGORITHM=TEMPTABLE
+VIEW v1 AS SELECT * FROM t1;
+# This will use LooseScan:
+EXPLAIN
+SELECT * FROM t1 AS t1_1, t1 AS t1_2
+WHERE (t1_1.a, t1_2.a) IN ( SELECT a, b FROM v1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1_1 ALL NULL NULL NULL NULL 11 Using where
+1 PRIMARY <derived3> ref key0 key0 5 test.t1_1.a 2 Start temporary
+1 PRIMARY t1_2 ALL NULL NULL NULL NULL 11 Using where; End temporary
+3 DERIVED t1 ALL NULL NULL NULL NULL 11
+SELECT * FROM t1 AS t1_1, t1 AS t1_2
+WHERE (t1_1.a, t1_2.a) IN ( SELECT a, b FROM v1 );
+a b a b
+3 1 9 1
+5 8 4 0
+3 9 9 1
+2 4 6 8
+2 4 4 0
+2 6 6 8
+2 6 4 0
+5 4 4 0
+7 7 7 7
+5 4 4 0
+DROP VIEW v1;
+DROP TABLE t1;
+set @@join_cache_level= @tmp_jcl_978479;
+set @@optimizer_switch= @tmp_os_978479;
+#
+# BUG#998236: Assertion failure or valgrind errors at best_access_path ...
+#
+CREATE TABLE t1 (a1 VARCHAR(3), a2 VARCHAR(35), KEY(a1,a2)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+('USA','Arvada'),('USA','Athens'),('USA','Atlanta'),('USA','Augusta'),
+('USA','Aurora'),('USA','Aurora'),('USA','Austin'),('USA','Bakersfield'),
+('USA','Baltimore'),('USA','Baton'),('USA','Beaumont'),('USA','Bellevue'),
+('USA','Berkeley'),('USA','Billings'),('USA','Birmingham'),('USA','Boise'),
+('USA','Boston'),('USA','Boulder'),('USA','Bridgeport'),('USA','Brockton'),
+('USA','Brownsville'),('USA','Buffalo'),('USA','Burbank'),('USA','Cambridge'),
+('USA','Cape'),('USA','Carrollton'),('USA','Carson'),('USA','Cary'),
+('USA','Cedar'),('USA','Chandler'),('USA','Charleston'),('USA','Charlotte'),
+('USA','Chattanooga'),('USA','Chesapeake'),('USA','Chicago'),('USA','Chula'),
+('USA','Cincinnati'),('USA','Citrus'),('USA','Clarksville'),('USA','Clearwater'),
+('USA','Cleveland'),('USA','Colorado'),('USA','Columbia'),('USA','Columbus'),
+('USA','Columbus'),('USA','Compton'),('USA','Concord'),('USA','Coral'),
+('USA','Corona'),('USA','Corpus'),('USA','Costa'),('USA','Dallas'),('USA','Daly'),
+('USA','Davenport'),('USA','Dayton'),('USA','Denver'),('USA','DesMoines'),
+('USA','Detroit'),('USA','Downey'),('USA','Durham'),('USA','East'),('USA','ElCajon'),
+('USA','ElMonte'),('USA','ElPaso'),('USA','Elgin'),('USA','Elizabeth'),
+('USA','Erie'),('USA','Escondido'),('USA','Eugene'),('USA','Evansville'),
+('USA','Fairfield'),('USA','Fall'),('USA','Fayetteville'),('USA','Flint'),
+('USA','Fontana'),('USA','FortCollins'),('USA','FortLauderdale'),('USA','FortWayne'),
+('USA','FortWorth'),('USA','Fremont'),('USA','Fresno'),('USA','Fullerton'),
+('USA','Gainesville'),('USA','GardenGrove'),('USA','Garland'),('USA','Gary'),
+('USA','Gilbert'),('USA','Glendale'),('USA','Glendale'),('USA','GrandPrairie'),
+('USA','GrandRapids'),('USA','Green Bay'),('USA','Greensboro'),('USA','Hampton'),
+('USA','Hartford'),('USA','Hayward'),('USA','Henderson'),('USA','Hialeah'),
+('USA','Inglewood'),('USA','Livonia');
+CREATE TABLE t3 (c1 VARCHAR(3), c2 VARCHAR(16), PRIMARY KEY (c1,c2)) ENGINE=MyISAM;
+INSERT INTO t3 VALUES ('USA','Chinese'), ('USA','English');
+CREATE TABLE t2 (b1 INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1);
+SELECT alias1.a1 AS field1
+FROM t1 AS alias1, t1 AS alias2
+WHERE alias1.a2 IN ( SELECT a1 FROM t1, t2 )
+AND alias1.a1 IS NULL
+AND ( alias1.a1, alias2.a1 ) IN ( SELECT c1, c1 FROM t3 )
+GROUP BY field1;
+field1
+DROP TABLE t1,t3,t2;
+#
+# BUG#1002630: Valgrind warnings 'Invalid read' in subselect_engine::calc_const_tables with SELECT
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(7);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (4),(6);
+SELECT ( SELECT SUM(a) FROM t1 ) AS t1sum, b
+FROM t2
+WHERE (1,1) IN ( SELECT MAX(a), MIN(a) FROM t1 )
+GROUP BY b
+HAVING t1sum <> 1;
+t1sum b
+DROP TABLE t1, t2;
+#
+# MDEV-3911: Assertion `fixed == 0' failed in Item_field::fix_fields
+# on 2nd execution of PS with semijoin=on and IN subquery
+#
+CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (0,4),(8,6);
+CREATE TABLE t2 (c INT, d INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (7,1),(0,7);
+PREPARE stmt FROM ' SELECT * FROM t1 WHERE ( a, b ) IN ( SELECT c, d FROM t2 ) ';
+execute stmt;
+a b
+execute stmt;
+a b
+deallocate prepare stmt;
+drop table t1,t2;
+set optimizer_switch=@subselect_sj_tmp;
+#
+# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
+#
+CREATE TABLE t0 (a INT);
+INSERT INTO t0 VALUES (0),(1),(2),(3),(4);
+CREATE TABLE t1 (a INT, b INT, KEY(a));
+INSERT INTO t1 SELECT a, a from t0;
+INSERT INTO t1 SELECT a+5, a from t0;
+INSERT INTO t1 SELECT a+10, a from t0;
+CREATE TABLE t2 (a INT, b INT, PRIMARY KEY(a));
+INSERT INTO t2 SELECT * FROM t1;
+UPDATE t1 SET a=3, b=11 WHERE a=4;
+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
+1 PRIMARY t1 ref a a 5 test.t0.a 1 Start temporary; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 Using where; End temporary; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+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;
+#
+# Bug #891995: IN subquery with join_cache_level >= 3
+#
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('w'),('q');
+CREATE TABLE t2 (a int NOT NULL, b time, PRIMARY KEY (a));
+INSERT INTO t2 VALUES
+(2,'18:56:33'), (5,'19:11:10'), (3,'18:56:33'), (7,'19:11:10');
+CREATE TABLE t3 (
+a int NOT NULL, b int, c int, d varchar(1), PRIMARY KEY (a), KEY (d,c)
+);
+INSERT INTO t3 VALUES
+(25,158,10,'f'), (26,5,2,'v'), (27,163,103,'f'), (28,2,3,'q'), (29,8,6,'y');
+set @save_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on';
+SET SESSION optimizer_switch='join_cache_hashed=on';
+SET SESSION join_cache_level=3;
+EXPLAIN
+SELECT * FROM t1, t2
+WHERE t2.a IN (SELECT b FROM t3 WHERE t3.d <= 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 t2 ALL PRIMARY NULL NULL NULL 4 Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL d NULL NULL NULL 5 Range checked for each record (index map: 0x2); FirstMatch(t2)
+SELECT * FROM t1, t2
+WHERE t2.a IN (SELECT b FROM t3 WHERE t3.d <= t1.a);
+a a b
+w 2 18:56:33
+q 2 18:56:33
+w 5 19:11:10
+SET SESSION optimizer_switch='mrr=on';
+SET SESSION join_cache_level=6;
+EXPLAIN
+SELECT * FROM t1, t2
+WHERE t2.a IN (SELECT b FROM t3 WHERE t3.d <= 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 t2 ALL PRIMARY NULL NULL NULL 4 Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL d NULL NULL NULL 5 Range checked for each record (index map: 0x2); FirstMatch(t2)
+SELECT * FROM t1, t2
+WHERE t2.a IN (SELECT b FROM t3 WHERE t3.d <= t1.a);
+a a b
+w 2 18:56:33
+q 2 18:56:33
+w 5 19:11:10
+set optimizer_switch=@save_optimizer_switch;
+set join_cache_level=default;
+DROP TABLE t1,t2,t3;
+#
+# BUG#912513: Wrong result (missing rows) with join_cache_hashed+materialization+semijoin=on
+#
+set @os_912513= @@optimizer_switch;
+set @jcl_912513= @@join_cache_level;
+SET optimizer_switch = 'semijoin=on,materialization=on,join_cache_hashed=on';
+SET join_cache_level = 3;
+CREATE TABLE t1 ( a INT, b INT, KEY(a) );
+INSERT INTO t1 VALUES
+(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7);
+CREATE TABLE t2 ( c INT );
+INSERT INTO t2 VALUES (1),(2),(3),(4),(5),(6),(7);
+SELECT alias1.* FROM
+t1 AS alias1 INNER JOIN t1 AS alias2
+ON alias2.a = alias1.b
+WHERE alias1.b IN (
+SELECT a FROM t1, t2
+);
+a b
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+7 7
+DROP table t1, t2;
+set @@optimizer_switch= @os_912513;
+set @@join_cache_level= @jcl_912513;
+# End
+#
+# BUG#934342: outer join + semijoin materialization
+# + join_cache_level > 2
+#
+CREATE TABLE t1 (a varchar(1), b varchar(1), INDEX idx_a(a) );
+INSERT INTO t1 VALUES ('v','v'), ('w','w'), ('t','t');
+CREATE TABLE t2 (c varchar(1), INDEX idx_c(c) );
+INSERT INTO t2 VALUES ('v'), ('v'), ('s'), ('j');
+CREATE TABLE t3 (c varchar(1), d varchar(1), INDEX idx_c(c) );
+INSERT INTO t3 VALUES ('v','v'), ('v','v'), ('s','s'), ('j','j');
+INSERT INTO t3 VALUES ('m','m'), ('d','d'), ('k','k'), ('m','m');
+set @tmp_otimizer_switch= @@optimizer_switch;
+set @tmp_join_cache_level=@@join_cache_level;
+set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on';
+set join_cache_level=0;
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 ON (c = b)
+WHERE (a, b) IN (SELECT a, b FROM t1 t);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL idx_a NULL NULL NULL 3
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index
+2 MATERIALIZED t ALL idx_a NULL NULL NULL 3
+SELECT * FROM t1 LEFT JOIN t2 ON (c = b)
+WHERE (a, b) IN (SELECT a, b FROM t1 t);
+a b c
+v v v
+v v v
+w w NULL
+t t NULL
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t3 ON (c = b)
+WHERE (a, b) IN (SELECT a, b FROM t1 t);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL idx_a NULL NULL NULL 3
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where
+2 MATERIALIZED t ALL idx_a NULL NULL NULL 3
+SELECT * FROM t1 LEFT JOIN t3 ON (c = b)
+WHERE (a, b) IN (SELECT a, b FROM t1 t);
+a b c d
+v v v v
+v v v v
+w w NULL NULL
+t t NULL NULL
+set join_cache_level=6;
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 ON (c = b)
+WHERE (a, b) IN (SELECT a, b FROM t1 t);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL idx_a NULL NULL NULL 3
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index
+2 MATERIALIZED t ALL idx_a NULL NULL NULL 3
+SELECT * FROM t1 LEFT JOIN t2 ON (c = b)
+WHERE (a, b) IN (SELECT a, b FROM t1 t);
+a b c
+v v v
+v v v
+w w NULL
+t t NULL
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t3 ON (c = b)
+WHERE (a, b) IN (SELECT a, b FROM t1 t);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL idx_a NULL NULL NULL 3
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+2 MATERIALIZED t ALL idx_a NULL NULL NULL 3
+SELECT * FROM t1 LEFT JOIN t3 ON (c = b)
+WHERE (a, b) IN (SELECT a, b FROM t1 t);
+a b c d
+v v v v
+v v v v
+w w NULL NULL
+t t NULL NULL
+set optimizer_switch=@tmp_optimizer_switch;
+set join_cache_level=@tmp_join_cache_level;
+DROP TABLE t1,t2,t3;
+# End
+#
+# BUG#934348: GROUP BY with HAVING + semijoin materialization
+# + join_cache_level > 2
+#
+CREATE TABLE t1 (a varchar(1), INDEX idx_a(a));
+INSERT INTO t1 VALUES ('c'), ('v'), ('c');
+CREATE TABLE t2 (b varchar(1));
+INSERT INTO t2 VALUES ('v'), ('c');
+set @tmp_otimizer_switch= @@optimizer_switch;
+set @tmp_join_cache_level=@@join_cache_level;
+set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on';
+set join_cache_level=0;
+EXPLAIN
+SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a)
+GROUP BY a HAVING a != 'z';
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t index idx_a idx_a 4 NULL 3 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t1 ref idx_a idx_a 4 test.t2.b 2 Using index
+SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a)
+GROUP BY a HAVING a != 'z';
+a
+c
+v
+set join_cache_level=6;
+EXPLAIN
+SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a)
+GROUP BY a HAVING a != 'z';
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t index idx_a idx_a 4 NULL 3 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t1 ref idx_a idx_a 4 test.t2.b 2 Using index
+SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a)
+GROUP BY a HAVING a != 'z';
+a
+c
+v
+set optimizer_switch=@tmp_optimizer_switch;
+set join_cache_level=@tmp_join_cache_level;
+DROP TABLE t1,t2;
+# End
+set join_cache_level=default;
+show variables like 'join_cache_level';
+Variable_name Value
+join_cache_level 2
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
+set @optimizer_switch_for_subselect_sj_test=NULL;
+set @join_cache_level_subselect_sj_test=NULL;
diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result
new file mode 100644
index 00000000000..8368318ea3d
--- /dev/null
+++ b/mysql-test/r/subselect_sj_mat.result
@@ -0,0 +1,2044 @@
+set @subselect_sj_mat_tmp= @@optimizer_switch;
+set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on');
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @optimizer_switch_local_default= @@optimizer_switch;
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
+drop table if exists t1, t2, t3, t4, t5, t1i, t2i, t3i;
+drop table if exists columns;
+drop table if exists t1_16, t2_16, t3_16;
+drop view if exists v1, v2, v1m, v2m;
+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='materialization=on,in_to_exists=off,firstmatch=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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b1` > '0'))
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b1` > '0'))
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b1` > '0'))
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1`,min(`test`.`t2`.`b2`) from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`) join `test`.`t1` where ((`<subquery2>`.`b1` = `test`.`t1`.`a1`) and (`<subquery2>`.`min(b2)` = `test`.`t1`.`a2`))
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+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 t2i index it2i1,it2i3 it2i1 # NULL 5 40.00 Using where; Using index; LooseScan
+1 PRIMARY t1i ref _it1_idx _it1_idx # _ref_ 1 100.00
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) where ((`test`.`t1i`.`a1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` > '0'))
+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 max(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 it1i1,it1i3 # 18 # 3 100.00 #
+1 PRIMARY <subquery2> eq_ref distinct_key # 8 # 1 100.00 #
+2 MATERIALIZED t2i index it2i1,it2i3 # 9 # 5 100.00 #
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select max(`test`.`t2i`.`b1`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where (`<subquery2>`.`max(b1)` = `test`.`t1i`.`a1`)
+select * from t1i where a1 in (select max(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 t2i index it2i1,it2i2,it2i3 it2i3 # NULL 5 40.00 Using where; Using index; LooseScan
+1 PRIMARY t1i ref _it1_idx _it1_idx # _ref_ 1 100.00
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) where ((`test`.`t1i`.`a1` = `test`.`t2i`.`b1`) and (`test`.`t1i`.`a2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b1` > '0'))
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, max(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 it1i1,it1i2,it1i3 # # # 3 100.00 #
+1 PRIMARY <subquery2> eq_ref distinct_key # # # 1 100.00 #
+2 MATERIALIZED t2i range it2i1,it2i3 # # # 3 100.00 #
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where ((`<subquery2>`.`b1` = `test`.`t1i`.`a1`) and (`<subquery2>`.`max(b2)` = `test`.`t1i`.`a2`))
+select * from t1i where (a1, a2) in (select b1, max(b2) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+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 it1i1,it1i2,it1i3 # # # 3 100.00 #
+1 PRIMARY <subquery2> eq_ref distinct_key # # # 1 100.00 #
+2 MATERIALIZED t2i range it2i1,it2i3 # # # 3 100.00 #
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where ((`<subquery2>`.`b1` = `test`.`t1i`.`a1`) and (`<subquery2>`.`min(b2)` = `test`.`t1i`.`a2`))
+select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00
+2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`<subquery2>`.`b1` = `test`.`t1`.`a1`) and (`<subquery2>`.`max(b2)` = `test`.`t1`.`a2`))
+select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
+a1 a2
+1 - 01 2 - 01
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1
+2 MATERIALIZED 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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1
+2 MATERIALIZED 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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00
+2 MATERIALIZED t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`<subquery2>`.`b1` = `test`.`t1`.`a1`) and (`<subquery2>`.`min(b2)` = `test`.`t1`.`a2`))
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+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 @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+prepare st1 from
+"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+prepare st1 from
+"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@save_optimizer_switch;
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`<subquery2>`.`b1` = `test`.`t1`.`a1`) and (`<subquery2>`.`b2` = `test`.`t1`.`a2`))
+select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
+a1 a2
+1 - 01 2 - 01
+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 it1i1,it1i2,it1i3 it1i3 18 NULL 3 100.00 Using where; Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1i.a1,test.t1i.a2 1 100.00
+2 MATERIALIZED t2i index NULL it2i3 18 NULL 5 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where ((`<subquery2>`.`b1` = `test`.`t1i`.`a1`) and (`<subquery2>`.`b2` = `test`.`t1i`.`a2`))
+select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
+a1 a2
+1 - 01 2 - 01
+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
+1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+3 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (`test`.`t2`.`b1` > '0') and (`test`.`t3`.`c2` > '0'))
+select * from t1
+where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
+(a1, a2) in (select c1, c2 from t3
+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 t2i index it2i1,it2i2,it2i3 # # # 5 40.00 #
+1 PRIMARY t1i ref it1i1,it1i2,it1i3 # # # 1 100.00 #
+1 PRIMARY t3i ref it3i1,it3i2,it3i3 # # # 1 100.00 #
+1 PRIMARY t2i ref it2i1,it2i2,it2i3 # # # 2 100.00 #
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where ((`test`.`t1i`.`a1` = `test`.`t2i`.`b1`) and (`test`.`t3i`.`c1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` = `test`.`t2i`.`b1`) and (`test`.`t1i`.`a2` = `test`.`t2i`.`b2`) and (`test`.`t3i`.`c2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b1` > '0') and (`test`.`t2i`.`b2` > '0'))
+select * from t1i
+where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
+(a1, a2) in (select c1, c2 from t3i
+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
+1 PRIMARY <subquery5> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+5 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+5 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3`.`c2` > '0'))
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+where b2 in (select c2 from t3 where c2 LIKE '%02') or
+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
+1 PRIMARY <subquery5> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+5 MATERIALIZED t3c ALL NULL NULL NULL NULL 4 100.00 Using where
+5 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
+4 MATERIALIZED 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` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2i`.`b1` = `test`.`t3c`.`c1`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2i`.`b2` = `test`.`t3c`.`c2`) and (`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3c`.`c2` > '0'))
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+where b2 in (select c2 from t3 t3a where c1 = a1) or
+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 # # # 3 100.00 #
+1 PRIMARY <subquery5> eq_ref distinct_key # # # 1 100.00 #
+1 PRIMARY <subquery2> eq_ref distinct_key # # # 1 100.00 #
+5 MATERIALIZED t3 ALL NULL # # # 4 100.00 #
+5 MATERIALIZED t2i index it2i1,it2i2,it2i3 # # # 5 80.00 #
+2 MATERIALIZED t2 ALL NULL # # # 5 100.00 #
+4 MATERIALIZED t3 ALL NULL # # # 4 100.00 #
+3 MATERIALIZED t3 ALL NULL # # # 4 100.00 #
+7 UNION t2i index it2i1,it2i2,it2i3 # # # 5 40.00 #
+7 UNION t1i ref it1i1,it1i2,it1i3 # # # 1 100.00 #
+7 UNION t3i ref it3i1,it3i2,it3i3 # # # 1 100.00 #
+7 UNION t2i ref it2i1,it2i2,it2i3 # # # 2 100.00 #
+NULL UNION RESULT <union1,7> ALL NULL # # # NULL NULL #
+Warnings:
+Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3`.`c2` > '0'))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where ((`test`.`t1i`.`a1` = `test`.`t2i`.`b1`) and (`test`.`t3i`.`c1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` = `test`.`t2i`.`b1`) and (`test`.`t1i`.`a2` = `test`.`t2i`.`b2`) and (`test`.`t3i`.`c2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b1` > '0') and (`test`.`t2i`.`b2` > '0')))
+(select * from t1
+where (a1, a2) in (select b1, b2 from t2
+where b2 in (select c2 from t3 where c2 LIKE '%02') or
+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
+1 PRIMARY <subquery4> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+4 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
+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` semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and (`test`.`t3`.`c2` > '0'))
+select * from t1
+where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
+(a1, a2) in (select c1, c2 from t3
+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)
+1 PRIMARY <subquery4> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+4 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
+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` semi join (`test`.`t2i` join `test`.`t3`) join `test`.`t3` where ((`test`.`t3`.`c1` = `test`.`t1`.`a1`) and (`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and (`test`.`t3`.`c2` > '0'))
+select * from t1, t3
+where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
+(c1, c2) in (select c1, c2 from t3
+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 `test`.`t1`.`a1` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t3`.`c1`) = `test`.`t1`.`a1`)) union select `test`.`t2`.`b1` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t3`.`c1`) = `test`.`t2`.`b1`)))))
+select * from t3
+where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
+c1 c2
+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
+1 PRIMARY t2i ref it2i1,it2i2,it2i3 it2i3 18 test.t1.a1,test.t1.a2 2 100.00 Using index; Start temporary
+1 PRIMARY t3c ALL NULL NULL NULL NULL 4 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+4 MATERIALIZED 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` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2i`.`b1` = `test`.`t1`.`a1`) and (`test`.`t3c`.`c1` = `test`.`t1`.`a1`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2i`.`b2` = `test`.`t1`.`a2`) and (`test`.`t3c`.`c2` = `test`.`t1`.`a2`) and (`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))))
+explain extended
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+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`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (((<cache>(`test`.`t1`.`a1`) = '1 - 01') or isnull('1 - 01')) and ((<cache>(`test`.`t1`.`a2`) = '2 - 01') or isnull('2 - 01')) and <is_not_null_test>('1 - 01') and <is_not_null_test>('2 - 01')))))
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+a1 a2
+1 - 01 2 - 01
+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`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (((<cache>(`test`.`t1`.`a1`) = '1 - 01') or isnull('1 - 01')) and ((<cache>(`test`.`t1`.`a2`) = '2 - 01') or isnull('2 - 01')) and <is_not_null_test>('1 - 01') and <is_not_null_test>('2 - 01')))))
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
+a1 a2
+1 - 01 2 - 01
+/******************************************************************************
+* 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 @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
+1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` semi join (`test`.`t2_16`) where ((`test`.`t2_16`.`b1` = `test`.`t1_16`.`a1`) and (`test`.`t1_16`.`a1` > '0'))
+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
+1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` semi join (`test`.`t2_16`) where ((`test`.`t2_16`.`b1` = `test`.`t1_16`.`a1`) and (`test`.`t2_16`.`b2` = `test`.`t1_16`.`a2`) and (`test`.`t1_16`.`a1` > '0'))
+select left(a1,7), left(a2,7)
+from t1_16
+where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 19 func 1 100.00 Using where
+2 MATERIALIZED t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` semi join (`test`.`t2_16`) where ((`test`.`t2_16`.`b1` > '0') and (`test`.`t1_16`.`a1` = substr(`test`.`t2_16`.`b1`,1,16)))
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_16.a1 1 100.00 Using where
+2 MATERIALIZED 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 <materialize> (select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2`) join `test`.`t1_16` where (`test`.`t1_16`.`a1` = `<subquery2>`.`group_concat(b1)`)
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+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
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2_16` join `test`.`t2` join `test`.`t1_16`) where ((`test`.`t2`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2_16`.`b1` = `test`.`t1_16`.`a1`) and (`test`.`t2_16`.`b2` = `test`.`t1_16`.`a2`) and (`test`.`t2`.`b2` = substr(`test`.`t1_16`.`a2`,1,6)) and (`test`.`t3`.`c2` > '0') and (concat(`test`.`t1`.`a1`,'x') = left(`test`.`t1_16`.`a1`,8)))
+drop table t1_16, t2_16, t3_16;
+set @blob_len = 512;
+set @suffix_len = @blob_len - @prefix_len;
+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
+1 PRIMARY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` semi join (`test`.`t2_512`) where ((`test`.`t2_512`.`b1` = `test`.`t1_512`.`a1`) and (`test`.`t1_512`.`a1` > '0'))
+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
+1 PRIMARY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` semi join (`test`.`t2_512`) where ((`test`.`t2_512`.`b1` = `test`.`t1_512`.`a1`) and (`test`.`t2_512`.`b2` = `test`.`t1_512`.`a2`) and (`test`.`t1_512`.`a1` > '0'))
+select left(a1,7), left(a2,7)
+from t1_512
+where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 516 func 1 100.00 Using where
+2 MATERIALIZED t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` semi join (`test`.`t2_512`) where ((`test`.`t2_512`.`b1` > '0') and (`test`.`t1_512`.`a1` = substr(`test`.`t2_512`.`b1`,1,512)))
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_512.a1 1 100.00 Using where
+2 MATERIALIZED 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 <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2`) join `test`.`t1_512` where (`test`.`t1_512`.`a1` = `<subquery2>`.`group_concat(b1)`)
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_512.a1 1 100.00 Using where
+2 MATERIALIZED 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 <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2`) join `test`.`t1_512` where (`test`.`t1_512`.`a1` = `<subquery2>`.`group_concat(b1)`)
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+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
+1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` semi join (`test`.`t2_1024`) where ((`test`.`t2_1024`.`b1` = `test`.`t1_1024`.`a1`) and (`test`.`t1_1024`.`a1` > '0'))
+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
+1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` semi join (`test`.`t2_1024`) where ((`test`.`t2_1024`.`b1` = `test`.`t1_1024`.`a1`) and (`test`.`t2_1024`.`b2` = `test`.`t1_1024`.`a2`) and (`test`.`t1_1024`.`a1` > '0'))
+select left(a1,7), left(a2,7)
+from t1_1024
+where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
+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
+1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` semi join (`test`.`t2_1024`) where ((`test`.`t2_1024`.`b1` > '0') and (`test`.`t1_1024`.`a1` = substr(`test`.`t2_1024`.`b1`,1,1024)))
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+explain extended select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_1024.a1 1 100.00 Using where
+2 MATERIALIZED 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 <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2`) join `test`.`t1_1024` where (`test`.`t1_1024`.`a1` = `<subquery2>`.`group_concat(b1)`)
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_1024.a1 1 100.00 Using where
+2 MATERIALIZED 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 <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2`) join `test`.`t1_1024` where (`test`.`t1_1024`.`a1` = `<subquery2>`.`group_concat(b1)`)
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+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
+1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` semi join (`test`.`t2_1025`) where ((`test`.`t2_1025`.`b1` = `test`.`t1_1025`.`a1`) and (`test`.`t1_1025`.`a1` > '0'))
+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
+1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` semi join (`test`.`t2_1025`) where ((`test`.`t2_1025`.`b1` = `test`.`t1_1025`.`a1`) and (`test`.`t2_1025`.`b2` = `test`.`t1_1025`.`a2`) and (`test`.`t1_1025`.`a1` > '0'))
+select left(a1,7), left(a2,7)
+from t1_1025
+where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
+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
+1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` semi join (`test`.`t2_1025`) where ((`test`.`t2_1025`.`b1` > '0') and (`test`.`t1_1025`.`a1` = substr(`test`.`t2_1025`.`b1`,1,1025)))
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+explain extended select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_1025.a1 1 100.00 Using where
+2 MATERIALIZED 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 <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2`) join `test`.`t1_1025` where (`test`.`t1_1025`.`a1` = `<subquery2>`.`group_concat(b1)`)
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_1025.a1 1 100.00 Using where
+2 MATERIALIZED 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 <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2`) join `test`.`t1_1025` where (`test`.`t1_1025`.`a1` = `<subquery2>`.`group_concat(b1)`)
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+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');
+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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
+2 MATERIALIZED 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` semi join (`test`.`t2bit`) where 1
+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
+1 PRIMARY t2bb ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select conv(`test`.`t1bb`.`a1`,10,2) AS `bin(a1)`,`test`.`t1bb`.`a2` AS `a2` from `test`.`t1bb` semi join (`test`.`t2bb`) where ((`test`.`t2bb`.`b1` = `test`.`t1bb`.`a1`) and (`test`.`t2bb`.`b2` = `test`.`t1bb`.`a2`))
+select bin(a1), a2
+from t1bb
+where (a1, a2) in (select b1, b2 from t2bb);
+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.
+******************************************************************************/
+# 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);
+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 <subquery2> ALL distinct_key NULL NULL NULL 6 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`c`) and (`test`.`t2`.`d` >= 20))
+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 it1a it1a 4 NULL 7 100.00 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`d` >= 20))
+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 it1a it1a 4 NULL 7 100.00 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`d` >= 20))
+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 MATERIALIZED 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` = `<subquery2>`.`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 MATERIALIZED 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` = `<subquery2>`.`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`,`test`.`t1`.`b`,max(`test`.`t1`.`b`),max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`c` from `test`.`t2` where (<nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`,max(`test`.`t1`.`b`),max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where (max(`test`.`t1`.`b`) = `test`.`t3`.`e`) having (<cache>(`test`.`t2`.`d`) >= <ref_null_helper>(`test`.`t3`.`e`)))))) and (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`c`)))))
+select a from t1 group by a
+having a in (select c from t2 where d >= some(select e from t3 where max(b)=e));
+a
+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 t2 ALL NULL NULL NULL NULL 7 100.00 Start temporary
+1 PRIMARY t1 ref it1a,iab iab 4 test.t2.c 1 100.00 Using where; Using index; End temporary
+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 `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`)))))))
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+a
+2
+2
+2
+3
+1
+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 max(b1) from t2 group by b1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1
+2 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+min(a1)
+NULL
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+explain select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+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 0 const row not found
+select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+min(a1)
+NULL
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+select min(a1) from t1 where 7 in (select b1 from t2);
+min(a1)
+NULL
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+# with MariaDB and MWL#90, this particular case is solved:
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+select min(a1) from t1 where 7 in (select b1 from t2);
+min(a1)
+NULL
+# but when we go around MWL#90 code, the problem still shows up:
+explain select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
+min(a1)
+NULL
+set @@optimizer_switch= @save_optimizer_switch;
+drop table t1,t2;
+create table t1 (a char(2), b varchar(10));
+insert into t1 values ('a', 'aaa');
+insert into t1 values ('aa', 'aaaa');
+explain select a,b from t1 where b in (select a from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 2 func 1 Using where
+2 MATERIALIZED 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;
+#
+# BUG#49630: Segfault in select_describe() with double
+# nested subquery and materialization
+#
+CREATE TABLE t1 (t1i int);
+CREATE TABLE t2 (t2i int);
+CREATE TABLE t3 (t3i int);
+CREATE TABLE t4 (t4i int);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1),(2);
+INSERT INTO t3 VALUES (1),(2);
+INSERT INTO t4 VALUES (1),(2);
+
+EXPLAIN
+SELECT t1i
+FROM t1 JOIN t4 ON t1i=t4i
+WHERE (t1i) IN (
+SELECT t2i
+FROM t2
+WHERE (t2i) IN (
+SELECT max(t3i)
+FROM t3
+GROUP BY t3i
+)
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 const 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using temporary
+DROP TABLE t1,t2,t3,t4;
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT,
+col_int_nokey INTEGER,
+col_int_key INTEGER,
+col_varchar_key VARCHAR(1),
+PRIMARY KEY (pk),
+KEY (col_int_key),
+KEY (col_varchar_key, col_int_key)
+)
+;
+INSERT INTO t1 (
+col_int_key, col_int_nokey, col_varchar_key
+)
+VALUES
+(2, NULL, 'w'),
+(9, 7, 'm'),
+(3, 9, 'm'),
+(9, 7, 'k'),
+(NULL, 4, 'r'),
+(9, 2, 't'),
+(3, 6, 'j'),
+(8, 8, 'u'),
+(8, NULL, 'h'),
+(53, 5, 'o'),
+(0, NULL, NULL),
+(5, 6, 'k'),
+(166, 188, 'e'),
+(3, 2, 'n'),
+(0, 1, 't'),
+(1, 1, 'c'),
+(9, 0, 'm'),
+(5, 9, 'y'),
+(6, NULL, 'f'),
+(2, 4, 'd')
+;
+SELECT table2.col_varchar_key AS field1,
+table2.col_int_nokey AS field2
+FROM ( t1 AS table1 LEFT OUTER JOIN t1 AS table2
+ON (table2.col_varchar_key = table1.col_varchar_key ) )
+WHERE table1.pk = 6
+HAVING ( field2 ) IN
+( SELECT SUBQUERY2_t2.col_int_nokey AS SUBQUERY2_field2
+FROM ( t1 AS SUBQUERY2_t1 JOIN t1 AS SUBQUERY2_t2
+ON (SUBQUERY2_t2.col_varchar_key = SUBQUERY2_t1.col_varchar_key ) ) )
+ORDER BY field2
+;
+field1 field2
+t 1
+t 2
+drop table t1;
+#
+# BUG#53103: MTR test ps crashes in optimize_cond()
+# when running with --debug
+#
+CREATE TABLE t1(track varchar(15));
+INSERT INTO t1 VALUES ('CAD'), ('CAD');
+PREPARE STMT FROM
+"SELECT 1 FROM t1
+ WHERE
+ track IN (SELECT track FROM t1
+ GROUP BY track
+ HAVING track>='CAD')";
+EXECUTE STMT ;
+1
+1
+1
+EXECUTE STMT ;
+1
+1
+1
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
+# End of BUG#53103
+#
+# BUG#54511 - Assertion failed: cache != 0L in file
+# sql_select.cc::sub_select_cache on HAVING
+#
+CREATE TABLE t1 (i int(11));
+CREATE TABLE t2 (c char(1));
+CREATE TABLE t3 (c char(1));
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES ('a'), ('b');
+INSERT INTO t3 VALUES ('x'), ('y');
+SELECT COUNT( i ),i
+FROM t1
+HAVING ('c')
+IN (SELECT t2.c FROM (t2 JOIN t3));
+COUNT( i ) i
+DROP TABLE t1,t2,t3;
+# End BUG#54511
+#
+# BUG#56367 - Assertion exec_method != EXEC_MATERIALIZATION...
+# on subquery in FROM
+#
+CREATE TABLE t1 (a INTEGER);
+CREATE TABLE t2 (b INTEGER);
+INSERT INTO t2 VALUES (1);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+explain SELECT a FROM (
+SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+3 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT a FROM (
+SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+a
+set optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1, t2;
+# End BUG#56367
+#
+# Bug#59833 - materialization=on/off leads to different result set
+# when using IN
+#
+CREATE TABLE t1 (
+pk int NOT NULL,
+f1 int DEFAULT NULL,
+PRIMARY KEY (pk)
+) ENGINE=MyISAM;
+CREATE TABLE t2 (
+pk int NOT NULL,
+f1 int DEFAULT NULL,
+PRIMARY KEY (pk)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (10,0);
+INSERT INTO t2 VALUES (10,0),(11,0);
+explain SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 const 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t1 system NULL NULL NULL NULL 1
+SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+f1 pk pk
+DROP TABLE t1, t2;
+# End Bug#59833
+#
+# Bug#11852644 - CRASH IN ITEM_REF::SAVE_IN_FIELD ON SELECT DISTINCT
+#
+CREATE TABLE t1 (
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_varchar_key (col_varchar_key))
+;
+INSERT INTO t1 VALUES
+('v','v'),('r','r');
+CREATE TABLE t2 (
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_varchar_key(col_varchar_key))
+;
+INSERT INTO t2 VALUES
+('r','r'),('c','c');
+CREATE VIEW v3 AS SELECT * FROM t2;
+SELECT DISTINCT alias2.col_varchar_key
+FROM t1 AS alias1 JOIN v3 AS alias2
+ON alias2.col_varchar_key = alias1.col_varchar_key
+HAVING col_varchar_key IN (SELECT col_varchar_nokey FROM t2)
+;
+col_varchar_key
+r
+DROP TABLE t1, t2;
+DROP VIEW v3;
+# End Bug#11852644
+
+# Bug#12668294 - GROUP BY ON EMPTY RESULT GIVES EMPTY ROW
+# INSTEAD OF NULL WHEN MATERIALIZATION ON
+
+CREATE TABLE t1 (col_int_nokey INT) ENGINE=MEMORY;
+CREATE TABLE t2 (col_int_nokey INT) ENGINE=MEMORY;
+INSERT INTO t2 VALUES (8),(7);
+CREATE TABLE t3 (col_int_nokey INT) ENGINE=MEMORY;
+INSERT INTO t3 VALUES (7);
+SELECT MIN(t3.col_int_nokey),t1.col_int_nokey AS field3
+FROM t3
+LEFT JOIN t1
+ON t1.col_int_nokey
+WHERE (194, 200) IN (
+SELECT SQ4_alias1.col_int_nokey,
+SQ4_alias2.col_int_nokey
+FROM t2 AS SQ4_alias1
+JOIN
+t2 AS SQ4_alias2
+ON SQ4_alias2.col_int_nokey = 5
+)
+GROUP BY field3 ;
+MIN(t3.col_int_nokey) field3
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+CREATE TABLE t1 (f1 INT, f2 DECIMAL(5,3)) ENGINE=MyISAM;
+INSERT INTO t1 (f1, f2) VALUES (1, 1.789);
+INSERT INTO t1 (f1, f2) VALUES (13, 1.454);
+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 @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch=@optimizer_switch_local_default;
+SET @@optimizer_switch='semijoin=on,materialization=on';
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+COUNT(*)
+2
+set @@optimizer_switch= @save_optimizer_switch;
+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 @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch=@optimizer_switch_local_default;
+SET @@optimizer_switch='semijoin=on,materialization=on';
+EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Rowid-ordered scan
+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;
+set optimizer_switch=@save_optimizer_switch;
+#
+# 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,in_to_exists=on';
+select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = 5);
+i
+4
+3
+2
+1
+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 MATERIALIZED 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;
+set optimizer_switch='firstmatch=on';
+#
+# MWL#90, review feedback: check what happens when the subquery
+# looks like candidate for MWL#90 checking at the first glance
+# but then subselect_hash_sj_engine::init_permanent() discovers
+# that it's not possible to perform duplicate removal for the
+# selected datatypes, and so materialization isn't applicable after
+# all.
+#
+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));
+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)));
+explain select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 Using where
+select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+drop table t1_1024, t2_1024;
+#
+# BUG##836491: Crash in Item_field::Item_field from add_ref_to_table_cond() with semijoin+materialization
+#
+CREATE TABLE t1 (c int, d varchar(1), KEY(d)) ;
+INSERT INTO t1 VALUES (2,'x'),(2,'x'),(2,'j'),(2,'c');
+CREATE TABLE t2 (a int, d varchar(1)) ;
+INSERT INTO t2 VALUES (1,'x');
+CREATE TABLE t3 (d varchar(1)) ;
+INSERT INTO t3 VALUES ('x'),('x'),('j'),('c');
+SELECT t2.a, t1.c
+FROM t1, t2
+WHERE t2.d IN ( SELECT d FROM t3 )
+AND t1.d = t2.d
+GROUP BY 1 , 2;
+a c
+1 2
+drop table t1,t2,t3;
+#
+# BUG#836523: Crash in JOIN::get_partial_cost_and_fanout with semijoin+materialization
+#
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('a'),('a');
+CREATE TABLE t2 (a varchar(1));
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (1),(2);
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('a'),('a');
+SELECT t1.a
+FROM t1
+WHERE t1.a IN (
+SELECT t2.a
+FROM t2, t3
+)
+HAVING a IN (
+SELECT a
+FROM t4
+);
+a
+DROP TABLE t1, t2, t3, t4;
+#
+# BUG#836507: Crash in setup_sj_materialization_part1() with semijoin+materialization
+#
+CREATE TABLE t1 (a int) ;
+INSERT IGNORE INTO t1 VALUES (1),(1);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1);
+CREATE TABLE t3 (a int);
+CREATE TABLE t4 (a int);
+INSERT INTO t4 VALUES (2),(2);
+CREATE TABLE t5 (a int);
+INSERT INTO t5 VALUES (1);
+SELECT * FROM t1
+WHERE (a) IN (
+SELECT t5.a
+FROM (
+t2
+LEFT JOIN ( t3 , t4 )
+ON 1 = 1
+)
+JOIN t5
+);
+a
+1
+1
+DROP TABLE t1,t2,t3,t4,t5;
+#
+# BUG#836532: Crash in Item_equal_fields_iterator::get_curr_field with semijoin+materialization
+#
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES ('a'),('a');
+Warnings:
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 1
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 2
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('m'),('o');
+CREATE TABLE t3 (a varchar(1) , b varchar(1) ) ;
+INSERT INTO t3 VALUES ('b','b');
+CREATE TABLE t5 (a varchar(1), KEY (a)) ;
+INSERT INTO t5 VALUES ('d'),('e');
+SELECT *
+FROM t2
+WHERE t2.a = ALL (
+SELECT t4.a
+FROM t4
+WHERE t4.a IN (
+SELECT t3.a
+FROM t3 , t5
+WHERE ( t5.a = t3.b )
+)
+);
+a
+0
+0
+DROP TABLE t2,t3,t4,t5;
+#
+# BUG#860300: Second crash with get_fanout_with_deps() with semijoin + materialization
+#
+set @tmp_860300=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f2 int);
+INSERT INTO t1 VALUES (9),(6);
+CREATE TABLE t3 (f4 int);
+CREATE TABLE t4 (f6 varchar(1));
+SELECT *
+FROM t3
+WHERE 'h' IN (SELECT f6
+FROM t4
+WHERE 5 IN (SELECT f2 FROM t1)
+GROUP BY t4.f6);
+f4
+DROP TABLE t1,t3,t4;
+set optimizer_switch=@tmp_860300;
+#
+# BUG#860535: Assertion `keypart_map' failed in mi_rkey with semijoin
+#
+set @tmp_860535=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f3 int) ;
+INSERT INTO t1 VALUES (1),(7);
+CREATE TABLE t2 (f3 int , f5 varchar(1), KEY (f3)) ;
+INSERT INTO t2 VALUES (7,'b');
+CREATE TABLE t3 (f3 int , f4 varchar(1) , KEY(f3), KEY (f4,f3)) ;
+INSERT INTO t3 VALUES (1,'t'),(7,'g');
+CREATE TABLE t4
+SELECT f3
+FROM t1 WHERE ( f3 ) NOT IN (
+SELECT f3
+FROM t2
+WHERE f5 IN (
+SELECT f4
+FROM t3
+WHERE t3.f3 < 3
+)
+);
+SELECT * FROM t4;
+f3
+1
+7
+DROP TABLE t1, t2, t3, t4;
+set optimizer_switch=@tmp_860535;
+#
+# BUG#860553: Crash in create_ref_for_key with semijoin + materialization
+#
+CREATE TABLE t1 (f1 int) ;
+CREATE TABLE t2 (f5 varchar(52) NOT NULL) ;
+CREATE TABLE t3 (f1 varchar(3), f4 varchar(52) , KEY (f4), PRIMARY KEY (f1));
+CREATE TABLE t4 (f3 int, KEY (f3));
+INSERT INTO t4 VALUES (17),(20);
+CREATE TABLE t5 (f2 int);
+INSERT INTO t5 VALUES (0),(0);
+SELECT *
+FROM t1
+JOIN t2
+ON ( t2.f5 ) IN (
+SELECT t3.f4
+FROM t3
+WHERE ( 1 ) IN (
+SELECT t4.f3
+FROM t4 , t5
+)
+);
+f1 f5
+DROP TABLE t1, t2, t3, t4, t5;
+#
+# BUG#868908: Crash in check_simple_equality() with semijoin + materialization + prepared statement
+#
+CREATE TABLE t1 ( a int );
+CREATE TABLE t3 ( b int, c int) ;
+CREATE TABLE t2 ( a int ) ;
+CREATE TABLE t4 ( a int , c int) ;
+PREPARE st1 FROM "
+SELECT STRAIGHT_JOIN *
+FROM t1
+WHERE ( 3 ) IN (
+ SELECT t3.b
+ FROM t3
+ LEFT JOIN (
+ t2 STRAIGHT_JOIN t4 ON ( t4.c = t2.a )
+ ) ON ( t4.a = t3.c )
+);
+";
+EXECUTE st1;
+a
+EXECUTE st1;
+a
+DROP TABLE t1,t2,t3,t4;
+#
+# BUG#901032: Wrong result for MIN/MAX on an indexed column with materialization and semijoin
+#
+CREATE TABLE t1 ( a INT, KEY(a) );
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 ( b INT );
+INSERT INTO t2 VALUES (2);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (2);
+SELECT MIN(a) FROM t1, t2 WHERE b IN (SELECT c FROM t3 GROUP BY c);
+MIN(a)
+1
+DROP TABLE t1,t2,t3;
+#
+#
+# BUG#902632: Crash or invalid read at st_join_table::cleanup, st_table::disable_keyread
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 ( b INT );
+INSERT INTO t2 VALUES (3), (4);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (5), (6);
+SELECT * FROM t1 WHERE EXISTS (
+SELECT DISTINCT b FROM t2
+WHERE b <= a
+AND b IN ( SELECT c FROM t3 GROUP BY c )
+);
+a
+DROP TABLE t1,t2,t3;
+#
+# BUG#901506: Crash in TABLE_LIST::print on EXPLAIN EXTENDED
+#
+CREATE TABLE t1 ( a INT, KEY(a) );
+INSERT INTO t1 VALUES (8);
+EXPLAIN EXTENDED
+SELECT * FROM t1
+WHERE a IN ( SELECT MIN(a) FROM t1 );
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system a NULL NULL NULL 1 100.00
+1 PRIMARY <subquery2> system NULL NULL NULL NULL 1 100.00
+2 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select 8 AS `a` from <materialize> (select min(`test`.`t1`.`a`) from `test`.`t1`) join `test`.`t1` where 1
+DROP TABLE t1;
+#
+# BUG#904432: Wrong result with LEFT JOIN, constant table, semijoin=ON,materialization=ON
+#
+CREATE TABLE t1 ( a INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4);
+CREATE TABLE t2 ( b INT NOT NULL, c INT );
+INSERT INTO t2 VALUES (4,2),(4,2),(4,4),(1,1);
+SELECT * FROM t1 LEFT JOIN t2 ON ( a = b )
+WHERE a IN ( SELECT c FROM t2 );
+a b c
+4 4 2
+4 4 2
+4 4 4
+DROP TABLE t1,t2;
+#
+# BUG#922254: Assertion `0' failed at item_cmpfunc.cc:5899: Item* Item_equal::get_first(JOIN_TAB*, Item*)
+#
+CREATE TABLE t1 ( a VARCHAR(3) );
+CREATE TABLE t2 ( b VARCHAR(3), c VARCHAR(8), KEY(c) );
+INSERT INTO t2 VALUES ('USA','Abilene'),('USA','Akron');
+EXPLAIN
+SELECT * FROM
+( SELECT * FROM t1 ) AS alias1,
+t2 AS alias2
+WHERE b = a AND a IN (
+SELECT alias3.c
+FROM t2 AS alias3, t2 AS alias4
+WHERE alias4.c = alias3.b
+);
+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#928048: Query containing IN subquery with OR in the where clause returns a wrong result
+#
+create table t1 (a int, b int);
+insert into t1 values (7,5), (3,3), (5,4), (9,3);
+create table t2 (a int, b int, index i_a(a));
+insert into t2 values
+(4,2), (7,9), (7,4), (3,1), (5,3), (3,1), (9,4), (8,1);
+explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t2 ALL i_a NULL NULL NULL 8 Using where
+select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1);
+a b
+7 5
+3 3
+drop table t1,t2;
+#
+# BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(8);
+SELECT STRAIGHT_JOIN MIN(a) FROM t1
+WHERE a IN (
+SELECT a FROM t1
+WHERE 'condition'='impossible'
+ );
+MIN(a)
+NULL
+DROP TABLE t1;
+#
+# BUG#938131: Subquery materialization is not used in CREATE TABLE SELECT
+#
+CREATE TABLE t1(a int);
+INSERT INTO t1 values(1),(2);
+CREATE TABLE t2(a int);
+INSERT INTO t2 values(1),(2);
+# Should use Materialization:
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 test.t1.a 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using temporary
+flush status;
+CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
+SHOW STATUS LIKE 'Created_tmp_tables';
+Variable_name Value
+Created_tmp_tables 2
+DROP TABLE t1,t2,t3;
+#
+# BUG#939009: Crash with aggregate function in IN subquery
+#
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='materialization=on,semijoin=on';
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (7,1), (4,2), (7,7);
+CREATE TABLE t2 ( c INT );
+INSERT INTO t2 VALUES (4), (7), (6);
+EXPLAIN EXTENDED
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where ((`test`.`t1`.`b` = 7) and (`test`.`t1`.`a` = `<subquery2>`.`MAX(c)`) and (isnull(`<subquery2>`.`MAX(c)`) or (`<subquery2>`.`MAX(c)` = 7)))
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
+a b
+7 7
+EXPLAIN
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
+a b
+SET optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2;
+#
+# BUG#946055: Crash with semijoin IN subquery when hash join is used
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (7);
+CREATE TABLE t2 (b int, c int, d varchar(1), e varchar(1), KEY (c), KEY (d, c));
+INSERT INTO t2 VALUES
+(4,2,'v','v'), (6,1,'v','v'), (0,5,'x','x'), (7,1,'x','x'),
+(7,3,'i','i'), (7,1,'e','e'), (1,4,'p','p'), (1,2,'j','j');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=2;
+EXPLAIN
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 index c c 5 NULL 8 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED s2 ref d d 4 const 1 Using where; Using index
+2 MATERIALIZED s1 ALL c NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+3 SUBQUERY t2 ALL NULL NULL NULL NULL 8
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+a c
+7 1
+7 1
+7 1
+SET optimizer_switch='join_cache_hashed=on';
+SET join_cache_level=4;
+EXPLAIN
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 index c c 5 NULL 8 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED s2 ref d d 4 const 1 Using where; Using index
+2 MATERIALIZED s1 hash_ALL c #hash#$hj 10 const,test.s2.d 8 Using where; Using join buffer (flat, BNLH join)
+3 SUBQUERY t2 ALL NULL NULL NULL NULL 8
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+a c
+7 1
+7 1
+7 1
+SET optimizer_switch=@save_optimizer_switch;
+SET join_cache_level=@save_join_cache_level;
+DROP TABLE t1,t2;
+#
+# BUG#952297: Server crashes on 2nd execution of PS in Field::is_null with semijoin+materialization
+#
+CREATE TABLE t1 ( a VARCHAR(1) );
+INSERT INTO t1 VALUES ('y'),('z');
+CREATE TABLE t2 ( b VARCHAR(1), c VARCHAR(1) );
+INSERT INTO t2 VALUES ('v','v'),('v','v');
+CREATE VIEW v2 AS SELECT * FROM t2;
+PREPARE ps FROM '
+SELECT a FROM t1, v2
+WHERE ( c, b ) IN ( SELECT b, b FROM t2 )
+GROUP BY a ';
+EXECUTE ps;
+a
+y
+z
+EXECUTE ps;
+a
+y
+z
+DROP VIEW v2;
+DROP TABLE t1, t2;
+#
+# BUG#1000269: Wrong result (extra rows) with semijoin+materialization, IN subqueries, join_cache_level>0
+#
+CREATE TABLE t1 (a1 VARCHAR(1), a2 VARCHAR(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('b','b'),('e','e');
+CREATE TABLE t2 (b1 VARCHAR(1), b2 VARCHAR(1), KEY(b1)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('v','v'),('s','s'),('l','l'), ('y','y'),('c','c'),('i','i');
+SELECT * FROM t1, t2 WHERE b1 IN ( SELECT b2 FROM t2 WHERE b1 > 'o' ) AND ( b1 < 'l' OR a1 IN ('b','c') );
+a1 a2 b1 b2
+b b v v
+b b s s
+b b y y
+DROP TABLE t1,t2;
+# This must be at the end:
+set optimizer_switch=@subselect_sj_mat_tmp;
+set join_cache_level=@save_join_cache_level;
diff --git a/mysql-test/r/subselect_sj_nonmerged.result b/mysql-test/r/subselect_sj_nonmerged.result
new file mode 100644
index 00000000000..c7e04225ffe
--- /dev/null
+++ b/mysql-test/r/subselect_sj_nonmerged.result
@@ -0,0 +1,122 @@
+drop table if exists t0, t1, t2, t3, t4;
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 as select * from t0;
+# The following should use full scan on <subquery2> and it must scan 1 row:
+explain select * from t0 where a in (select max(a) from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1
+1 PRIMARY t0 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10
+select * from t0 where a in (select max(a) from t1);
+a
+9
+insert into t1 values (11);
+select * from t0 where a in (select max(a) from t1);
+a
+delete from t1 where a=11;
+insert into t0 values (NULL);
+select * from t0 where a in (select max(a) from t1);
+a
+9
+delete from t0 where a is NULL;
+delete from t1;
+select * from t0 where a in (select max(a) from t1);
+a
+insert into t0 values (NULL);
+select * from t0 where a in (select max(a) from t1);
+a
+delete from t0 where a is NULL;
+drop table t1;
+create table t1 (a int, b int);
+insert into t1 select a,a from t0;
+create table t2 as select * from t1 where a<5;
+create table t3 as select (A.a + 10*B.a) as a from t0 A, t0 B;
+alter table t3 add primary key(a);
+# The following should have do a full scan on <subquery2> and scan 5 rows
+# (despite that subquery's join output estimate is 50 rows)
+explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+# Compare to this which really will have 50 record combinations:
+explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b, t1.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 50
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+# Outer joins also work:
+explain select * from t3
+where a in (select max(t2.a) from t1 left join t2 on t1.a=t2.a group by t2.b, t1.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 50
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using temporary
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using where
+SET optimizer_switch=@save_optimizer_switch;
+create table t4 (a int, b int, filler char(20), unique key(a,b));
+insert into t4 select A.a + 10*B.a, A.a + 10*B.a, 'filler' from t0 A, t0 B;
+explain select * from t0, t4 where
+t4.b=t0.a and t4.a in (select max(t2.a) from t1, t2 group by t2.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 10
+1 PRIMARY t4 ALL a NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 test.t4.a 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+insert into t4 select 100 + (B.a *100 + A.a), 100 + (B.a*100 + A.a), 'filler' from t4 A, t0 B;
+explain select * from t4 where
+t4.a in (select max(t2.a) from t1, t2 group by t2.b) and
+t4.b in (select max(t2.a) from t1, t2 group by t2.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery3> ALL distinct_key NULL NULL NULL 5
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5 Using join buffer (flat, BNL join)
+1 PRIMARY t4 ref a a 10 <subquery2>.max(t2.a),<subquery3>.max(t2.a) 12
+3 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary
+3 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+drop table t1,t2,t3,t4;
+drop table t0;
+#
+# BUG#780359: Crash with get_fanout_with_deps in maria-5.3-mwl90
+#
+CREATE TABLE t1 (f1 int);
+INSERT INTO t1 VALUES (2),(2);
+CREATE TABLE t2 (f3 int);
+INSERT INTO t2 VALUES (2),(2);
+SELECT *
+FROM t1
+WHERE ( f1 ) IN (
+SELECT t2.f3
+FROM t2
+WHERE t2.f3 = 97
+AND t2.f3 = 50
+GROUP BY 1
+);
+f1
+DROP TABLE t1, t2;
+#
+# BUG#727183: WL#90 does not trigger with non-comma 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, key(a));
+insert into t1 select A.a + 10*B.a + 100*C.a from t0 A, t0 B, t0 C;
+# The following must use non-merged SJ-Materialization:
+explain select * from t1 X join t0 Y on X.a < Y.a where X.a in (select max(a) from t0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1
+1 PRIMARY X ref a a 5 <subquery2>.max(a) 1 Using index
+1 PRIMARY Y ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t0 ALL NULL NULL NULL NULL 10
+drop table t0, t1;
+set optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/sysdate_is_now.result b/mysql-test/r/sysdate_is_now.result
index 1ebbb8c1588..82861436ff6 100644
--- a/mysql-test/r/sysdate_is_now.result
+++ b/mysql-test/r/sysdate_is_now.result
@@ -1,4 +1,4 @@
set timestamp=1;
SELECT sleep(1),NOW()-SYSDATE() as zero;
sleep(1) zero
-0 0.000000
+0 0
diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result
index aa407b25401..5079d72aaea 100644
--- a/mysql-test/r/system_mysql_db.result
+++ b/mysql-test/r/system_mysql_db.result
@@ -117,7 +117,7 @@ user CREATE TABLE `user` (
`max_questions` int(11) unsigned NOT NULL DEFAULT '0',
`max_updates` int(11) unsigned NOT NULL DEFAULT '0',
`max_connections` int(11) unsigned NOT NULL DEFAULT '0',
- `max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',
+ `max_user_connections` int(11) NOT NULL DEFAULT '0',
`plugin` char(60) CHARACTER SET latin1 NOT NULL DEFAULT '',
`auth_string` text COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`Host`,`User`)
@@ -240,7 +240,7 @@ event CREATE TABLE `event` (
show create table general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
- `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
@@ -250,10 +250,10 @@ general_log CREATE TABLE `general_log` (
show create table slow_log;
Table Create Table
slow_log CREATE TABLE `slow_log` (
- `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
- `query_time` time NOT NULL,
- `lock_time` time NOT NULL,
+ `query_time` time(6) NOT NULL,
+ `lock_time` time(6) NOT NULL,
`rows_sent` int(11) NOT NULL,
`rows_examined` int(11) NOT NULL,
`db` varchar(512) NOT NULL,
diff --git a/mysql-test/r/table_elim.result b/mysql-test/r/table_elim.result
index 32ce0cf6aad..35acd30d76d 100644
--- a/mysql-test/r/table_elim.result
+++ b/mysql-test/r/table_elim.result
@@ -1,5 +1,7 @@
drop table if exists t0, t1, t2, t3, t4, t5, t6;
drop view if exists v1, v2;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
create table t1 (a int);
insert into t1 values (0),(1),(2),(3);
create table t0 as select * from t1;
@@ -26,17 +28,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 +60,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 +77,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 (
@@ -117,58 +119,58 @@ t2 where id=f.id);
This should use one table:
explain select id from v1 where id=2;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY f const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE f const PRIMARY PRIMARY 4 const 1 Using index
This should use one table:
explain extended select id from v1 where id in (1,2,3,4);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY f range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index
+1 SIMPLE f range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index
Warnings:
-Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #2
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` where (`f`.`id` in (1,2,3,4))
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 f eq_ref PRIMARY PRIMARY 4 test.a1.id 1 100.00 Using index
+1 SIMPLE a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using index condition
+1 SIMPLE f eq_ref PRIMARY PRIMARY 4 test.a1.id 1 100.00 Using index
Warnings:
-Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #2
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t1` `a1` where ((`f`.`id` = `a1`.`id`) and (`a1`.`attr1` between 12 and 14))
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 f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using index
+1 SIMPLE a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using index condition; Using where
+1 SIMPLE f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using index
3 DEPENDENT SUBQUERY t2 ref PRIMARY PRIMARY 4 test.a2.id 2 100.00 Using index
Warnings:
-Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #2
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t2` `a2` where ((`f`.`id` = `a2`.`id`) and (`a2`.`attr2` between 12 and 14) and (`a2`.`fromdate` = (select max(`test`.`t2`.`fromdate`) from `test`.`t2` where (`test`.`t2`.`id` = `a2`.`id`))))
This should use one table:
explain select id from v2 where id=2;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY f const PRIMARY PRIMARY 4 const 1 Using index
+1 SIMPLE f const PRIMARY PRIMARY 4 const 1 Using index
This should use one table:
explain extended select id from v2 where id in (1,2,3,4);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY f range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index
+1 SIMPLE f range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index
Warnings:
-Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #2
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` where (`f`.`id` in (1,2,3,4))
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 f eq_ref PRIMARY PRIMARY 4 test.a1.id 1 100.00 Using index
+1 SIMPLE a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using index condition
+1 SIMPLE f eq_ref PRIMARY PRIMARY 4 test.a1.id 1 100.00 Using index
Warnings:
-Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #2
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t1` `a1` where ((`f`.`id` = `a1`.`id`) and (`a1`.`attr1` between 12 and 14))
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 f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using where; Using index
+1 SIMPLE a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using index condition
+1 SIMPLE f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using where; Using index
3 DEPENDENT SUBQUERY t2 ref PRIMARY PRIMARY 4 test.f.id 2 100.00 Using index
Warnings:
-Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #2
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t2` `a2` where ((`f`.`id` = `a2`.`id`) and (`a2`.`attr2` between 12 and 14) and (`a2`.`fromdate` = (select max(`test`.`t2`.`fromdate`) from `test`.`t2` where (`test`.`t2`.`id` = `f`.`id`))))
drop view v1, v2;
drop table t0, t1, t2;
@@ -194,7 +196,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 +214,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 +234,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 +249,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,21 +264,22 @@ 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');
create table t2 (a char(10), unique key(a(2)));
-insert into t2 values ('foo'),('bar');
+insert into t2 values
+('foo'),('bar'),('boo'),('car'),('coo'),('par'),('doo'),('tar');
explain select t1.* from t1 left join t2 on t2.a=t1.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 10 NULL 2 Using index
-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 +325,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 +350,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 +391,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 +408,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;
@@ -560,9 +563,9 @@ JOIN t5 ON t4.f3 ON t3.f1 = t5.f5 ON t2.f4 = t3.f4
WHERE t3.f2 ;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
-1 SIMPLE t5 ref f5 f5 5 test.t3.f1 2 Using index
-1 SIMPLE t4 ALL NULL NULL NULL NULL 3
-1 SIMPLE t2 ALL f4 NULL NULL NULL 11 Using where; Using join buffer
+1 SIMPLE t5 ref f5 f5 5 test.t3.f1 2 Using where; Using index
+1 SIMPLE t4 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t2 ALL f4 NULL NULL NULL 11 Using where; Using join buffer (flat, BNL join)
# ^^ The above must not produce a QEP of t3,t5,t2,t4
# as that violates the "no interleaving of outer join nests" rule.
DROP TABLE t1,t2,t3,t4,t5;
@@ -602,7 +605,8 @@ NULL NULL
EXPLAIN SELECT alias1.* FROM t3 LEFT JOIN v1 as alias1 ON ( t3.a = alias1.b );
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 system NULL NULL NULL NULL 1
-1 SIMPLE t1 ALL NULL NULL NULL NULL 1
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using index
drop view v1;
DROP TABLE t1,t2,t3;
+SET optimizer_switch=@save_optimizer_switch;
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/table_options.result b/mysql-test/r/table_options.result
index ddb7bd13c03..164fe4e30d0 100644
--- a/mysql-test/r/table_options.result
+++ b/mysql-test/r/table_options.result
@@ -3,9 +3,9 @@ SET @OLD_SQL_MODE=@@SQL_MODE;
SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1='1v1';
Warnings:
-Warning 1652 Unknown option 'fkey'
-Warning 1652 Unknown option 'dff'
-Warning 1652 Unknown option 'tkey1'
+Warning 1911 Unknown option 'fkey'
+Warning 1911 Unknown option 'dff'
+Warning 1911 Unknown option 'tkey1'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -16,10 +16,10 @@ drop table t1;
#reassiginig options in the same line
create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1 TKEY1=DEFAULT tkey1=1v2 tkey2=2v1;
Warnings:
-Warning 1652 Unknown option 'fkey'
-Warning 1652 Unknown option 'dff'
-Warning 1652 Unknown option 'tkey1'
-Warning 1652 Unknown option 'tkey2'
+Warning 1911 Unknown option 'fkey'
+Warning 1911 Unknown option 'dff'
+Warning 1911 Unknown option 'tkey1'
+Warning 1911 Unknown option 'tkey2'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -29,7 +29,7 @@ t1 CREATE TABLE `t1` (
#add option
alter table t1 tkey4=4v1;
Warnings:
-Warning 1652 Unknown option 'tkey4'
+Warning 1911 Unknown option 'tkey4'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -39,8 +39,8 @@ t1 CREATE TABLE `t1` (
#remove options
alter table t1 tkey3=DEFAULT tkey4=DEFAULT;
Warnings:
-Warning 1652 Unknown option 'tkey3'
-Warning 1652 Unknown option 'tkey4'
+Warning 1911 Unknown option 'tkey3'
+Warning 1911 Unknown option 'tkey4'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -50,11 +50,11 @@ t1 CREATE TABLE `t1` (
drop table t1;
create table t1 (a int fkey1=v1, key akey (a) kkey1=v1) tkey1=1v1 tkey1=1v2 TKEY1=DEFAULT tkey2=2v1 tkey3=3v1;
Warnings:
-Warning 1652 Unknown option 'fkey1'
-Warning 1652 Unknown option 'kkey1'
-Warning 1652 Unknown option 'TKEY1'
-Warning 1652 Unknown option 'tkey2'
-Warning 1652 Unknown option 'tkey3'
+Warning 1911 Unknown option 'fkey1'
+Warning 1911 Unknown option 'kkey1'
+Warning 1911 Unknown option 'TKEY1'
+Warning 1911 Unknown option 'tkey2'
+Warning 1911 Unknown option 'tkey3'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -64,7 +64,7 @@ t1 CREATE TABLE `t1` (
#change field with option with the same value
alter table t1 change a a int `FKEY1`='v1';
Warnings:
-Warning 1652 Unknown option 'FKEY1'
+Warning 1911 Unknown option 'FKEY1'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -74,7 +74,7 @@ t1 CREATE TABLE `t1` (
#change field with option with a different value
alter table t1 change a a int fkey1=v2;
Warnings:
-Warning 1652 Unknown option 'fkey1'
+Warning 1911 Unknown option 'fkey1'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -93,7 +93,7 @@ t1 CREATE TABLE `t1` (
#new key with options
alter table t1 add key bkey (b) kkey2=v1;
Warnings:
-Warning 1652 Unknown option 'kkey2'
+Warning 1911 Unknown option 'kkey2'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -105,8 +105,8 @@ t1 CREATE TABLE `t1` (
#new column with options
alter table t1 add column c int fkey1=v1 fkey2=v2;
Warnings:
-Warning 1652 Unknown option 'fkey1'
-Warning 1652 Unknown option 'fkey2'
+Warning 1911 Unknown option 'fkey1'
+Warning 1911 Unknown option 'fkey2'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -141,7 +141,7 @@ t1 CREATE TABLE `t1` (
#add column with options after delete
alter table t1 add column b int fkey2=v1;
Warnings:
-Warning 1652 Unknown option 'fkey2'
+Warning 1911 Unknown option 'fkey2'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -154,7 +154,7 @@ t1 CREATE TABLE `t1` (
#add key
alter table t1 add key bkey (b) kkey2=v2;
Warnings:
-Warning 1652 Unknown option 'kkey2'
+Warning 1911 Unknown option 'kkey2'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -168,7 +168,7 @@ t1 CREATE TABLE `t1` (
drop table t1;
create table t1 (a int) tkey1=100;
Warnings:
-Warning 1652 Unknown option 'tkey1'
+Warning 1911 Unknown option 'tkey1'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/mysql-test/r/timezone.result b/mysql-test/r/timezone.result
index 1223fff36c6..5ae7e6f8117 100644
--- a/mysql-test/r/timezone.result
+++ b/mysql-test/r/timezone.result
@@ -7,7 +7,7 @@ select @a:=FROM_UNIXTIME(1);
1970-01-01 01:00:01
select unix_timestamp(@a);
unix_timestamp(@a)
-1
+1.000000
CREATE TABLE t1 (ts int);
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 01:00'));
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00'));
@@ -44,4 +44,7 @@ unix_timestamp('1970-01-01 01:00:01'),
unix_timestamp('2038-01-19 04:14:07'),
unix_timestamp('2038-01-19 04:14:08');
unix_timestamp('1970-01-01 01:00:00') unix_timestamp('1970-01-01 01:00:01') unix_timestamp('2038-01-19 04:14:07') unix_timestamp('2038-01-19 04:14:08')
-0 1 2147483647 0
+0.000000 1.000000 2147483647.000000 NULL
+select unix_timestamp('1969-12-31 23:59:59'), unix_timestamp('1970-01-01 00:00:00'), unix_timestamp('1970-01-01 00:59:59');
+unix_timestamp('1969-12-31 23:59:59') unix_timestamp('1970-01-01 00:00:00') unix_timestamp('1970-01-01 00:59:59')
+NULL NULL NULL
diff --git a/mysql-test/r/timezone4.result b/mysql-test/r/timezone4.result
index 28028bea657..ad0672890a2 100644
--- a/mysql-test/r/timezone4.result
+++ b/mysql-test/r/timezone4.result
@@ -3,4 +3,4 @@ from_unixtime(0)
1969-12-31 14:00:00
select unix_timestamp('1969-12-31 14:00:01');
unix_timestamp('1969-12-31 14:00:01')
-1
+1.000000
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 479778deca3..9cf769983c6 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -2134,3 +2134,47 @@ i
2
drop table t1,t2;
End of 5.2 tests.
+#
+# BUG #910083: materialized subquery in a trigger
+#
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='materialization=on';
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (b int);
+CREATE TRIGGER tr AFTER UPDATE ON t1 FOR EACH ROW
+UPDATE t2 SET b = (SELECT COUNT(a) FROM t1);
+INSERT INTO t1
+VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9);
+INSERT INTO t2
+VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0);
+UPDATE t1 SET a = 3;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+9
+SELECT * FROM t2;
+b
+9
+9
+9
+9
+9
+9
+9
+9
+9
+UPDATE t1 SET a = 2;
+SELECT * FROM t2;
+b
+9
+9
+9
+9
+9
+9
+9
+9
+9
+SET optimizer_switch=@save_optimizer_switch;
+DROP TRIGGER tr;
+DROP TABLE t1, t2;
+End of 5.3 tests.
diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result
index 9f32a10a3fb..50042a428c7 100644
--- a/mysql-test/r/type_bit.result
+++ b/mysql-test/r/type_bit.result
@@ -36,7 +36,7 @@ select 0 + b'1000000000000001';
32769
drop table if exists t1,t2;
create table t1 (a bit(65));
-ERROR 42000: Display width out of range for column 'a' (max = 64)
+ERROR 42000: Display width out of range for 'a' (max = 64)
create table t1 (a bit(0));
show create table t1;
Table Create Table
diff --git a/mysql-test/r/type_bit_innodb.result b/mysql-test/r/type_bit_innodb.result
index 909db576b27..a6507ca8351 100644
--- a/mysql-test/r/type_bit_innodb.result
+++ b/mysql-test/r/type_bit_innodb.result
@@ -36,7 +36,7 @@ select 0 + b'1000000000000001';
32769
drop table if exists t1;
create table t1 (a bit(65)) engine=innodb;
-ERROR 42000: Display width out of range for column 'a' (max = 64)
+ERROR 42000: Display width out of range for 'a' (max = 64)
create table t1 (a bit(0)) engine=innodb;
show create table t1;
Table Create Table
diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result
index 8b4b6438842..f999506d77a 100644
--- a/mysql-test/r/type_blob.result
+++ b/mysql-test/r/type_blob.result
@@ -833,7 +833,7 @@ drop table b15776;
create table b15776 (data blob(4294967295));
drop table b15776;
create table b15776 (data blob(4294967296));
-ERROR 42000: Display width out of range for column 'data' (max = 4294967295)
+ERROR 42000: Display width out of range for 'data' (max = 4294967295)
CREATE TABLE b15776 (a blob(2147483647), b blob(2147483648), c blob(4294967295), a1 text(2147483647), b1 text(2147483648), c1 text(4294967295) );
show columns from b15776;
Field Type Null Key Default Extra
@@ -845,13 +845,13 @@ b1 longtext YES NULL
c1 longtext YES NULL
drop table b15776;
CREATE TABLE b15776 (a blob(4294967296));
-ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
+ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a text(4294967296));
-ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
+ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a blob(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
-ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
+ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a text(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
-ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
+ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a int(0));
INSERT INTO b15776 values (NULL), (1), (42), (654);
SELECT * from b15776 ORDER BY a;
@@ -866,7 +866,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
CREATE TABLE b15776 (a int(255));
DROP TABLE b15776;
CREATE TABLE b15776 (a int(256));
-ERROR 42000: Display width out of range for column 'a' (max = 255)
+ERROR 42000: Display width out of range for 'a' (max = 255)
CREATE TABLE b15776 (data blob(-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
CREATE TABLE b15776 (a char(2147483647));
@@ -876,7 +876,7 @@ ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT
CREATE TABLE b15776 (a char(4294967295));
ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead
CREATE TABLE b15776 (a char(4294967296));
-ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
+ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a year(4294967295));
Warnings:
Note 1287 'YEAR(4294967295)' is deprecated and will be removed in a future release. Please use YEAR(4) instead
@@ -886,7 +886,7 @@ a
2042
DROP TABLE b15776;
CREATE TABLE b15776 (a year(4294967296));
-ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
+ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a year(0));
Warnings:
Note 1287 'YEAR(0)' is deprecated and will be removed in a future release. Please use YEAR(4) instead
@@ -894,27 +894,23 @@ DROP TABLE b15776;
CREATE TABLE b15776 (a year(-2));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-2))' at line 1
CREATE TABLE b15776 (a timestamp(4294967294));
-Warnings:
-Warning 1287 'TIMESTAMP(4294967294)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-DROP TABLE b15776;
+ERROR 42000: Too big precision 4294967294 specified for 'a'. Maximum is 6.
CREATE TABLE b15776 (a timestamp(4294967295));
-Warnings:
-Warning 1287 'TIMESTAMP(4294967295)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-DROP TABLE b15776;
+ERROR 42000: Too big precision 4294967295 specified for 'a'. Maximum is 6.
CREATE TABLE b15776 (a timestamp(4294967296));
-ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
+ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a timestamp(-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
CREATE TABLE b15776 (a timestamp(-2));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-2))' at line 1
CREATE TABLE b15776 (a int(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
-ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
+ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
-ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
+ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a year(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
-ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
+ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 (a timestamp(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
-ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
+ERROR 42000: Display width out of range for 'a' (max = 4294967295)
CREATE TABLE b15776 select cast(null as char(4294967295));
show columns from b15776;
Field Type Null Key Default Extra
@@ -940,11 +936,11 @@ explain select cast(1 as binary(4294967295));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
explain select cast(1 as char(4294967296));
-ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
+ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select cast(1 as nchar(4294967296));
-ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
+ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select cast(1 as binary(4294967296));
-ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
+ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select cast(1 as decimal(-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
explain select cast(1 as decimal(64, 30));
@@ -960,23 +956,23 @@ explain select convert(1, char(4294967295));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
explain select convert(1, char(4294967296));
-ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
+ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select convert(1, char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
-ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
+ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select convert(1, nchar(4294967295));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
explain select convert(1, nchar(4294967296));
-ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
+ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select convert(1, nchar(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
-ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
+ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select convert(1, binary(4294967295));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
explain select convert(1, binary(4294967296));
-ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
+ERROR 42000: Display width out of range for '1' (max = 4294967295)
explain select convert(1, binary(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
-ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295)
+ERROR 42000: Display width out of range for '1' (max = 4294967295)
End of 5.0 tests
# Bug #52160: crash and inconsistent results when grouping
# by a function and column
@@ -989,3 +985,9 @@ COUNT(*)
DROP FUNCTION f1;
DROP TABLE t1;
End of 5.1 tests
+CREATE TABLE t1 ( f1 blob, f2 blob );
+INSERT INTO t1 VALUES ('','');
+SELECT f1,f2,"found row" FROM t1 WHERE f1 = f2 ;
+f1 f2 found row
+ found row
+DROP TABLE t1;
diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result
index e0a75174f71..23de0607838 100644
--- a/mysql-test/r/type_date.result
+++ b/mysql-test/r/type_date.result
@@ -145,8 +145,8 @@ Warning 1292 Incorrect datetime value: '1311'
create table t1 (d date , dt datetime , ts timestamp);
insert into t1 values (9912101,9912101,9912101);
Warnings:
-Warning 1264 Out of range value for column 'd' at row 1
-Warning 1264 Out of range value for column 'dt' at row 1
+Warning 1265 Data truncated for column 'd' at row 1
+Warning 1265 Data truncated for column 'dt' at row 1
Warning 1265 Data truncated for column 'ts' at row 1
insert into t1 values (11111,11111,11111);
select * from t1;
@@ -211,22 +211,17 @@ EXPLAIN SELECT * FROM t1 WHERE a = '0000-00-00';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref i i 4 const 1 Using where; Using index
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 1264 Out of range value for column 'a' at row 1
SELECT * FROM t1 WHERE a = '0000-00-00';
a
0000-00-00
0000-00-00
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 1264 Out of range value for column 'a' at row 1
SELECT * FROM t2 WHERE a = '0000-00-00';
a
0000-00-00
0000-00-00
-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
INSERT INTO t1 VALUES ('0000-00-00');
ERROR 22007: Incorrect date value: '0000-00-00' for column 'a' at row 1
SET SQL_MODE=DEFAULT;
@@ -249,22 +244,17 @@ EXPLAIN SELECT * FROM t1 WHERE a = '1000-00-00';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref i i 4 const 1 Using where; Using index
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
1000-00-00
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
1000-00-00
-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
INSERT INTO t1 VALUES ('1000-00-00');
ERROR 22007: Incorrect date value: '1000-00-00' for column 'a' at row 1
SET SQL_MODE=DEFAULT;
@@ -303,3 +293,8 @@ the_date the_time the_date the_time
DROP TABLE t1;
DROP VIEW v1;
End of 5.1 tests
+create table t1 (f1 date, key (f1));
+insert t1 values ('2010-10-10 15:foobar');
+Warnings:
+Warning 1265 Data truncated for column 'f1' at row 1
+drop table t1;
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 1f0965a105f..1a111fe591a 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -52,7 +52,7 @@ t
truncate table t1;
insert into t1 values("2003-0303 12:13:14");
Warnings:
-Warning 1264 Out of range value for column 't' at row 1
+Warning 1265 Data truncated for column 't' at row 1
select * from t1;
t
0000-00-00 00:00:00
@@ -115,12 +115,12 @@ create table t1 (t datetime);
insert into t1 values (20030102030460),(20030102036301),(20030102240401),
(20030132030401),(20031302030401),(100001202030401);
Warnings:
-Warning 1264 Out of range value for column 't' at row 1
-Warning 1264 Out of range value for column 't' at row 2
-Warning 1264 Out of range value for column 't' at row 3
-Warning 1264 Out of range value for column 't' at row 4
-Warning 1264 Out of range value for column 't' at row 5
-Warning 1264 Out of range value for column 't' at row 6
+Warning 1265 Data truncated for column 't' at row 1
+Warning 1265 Data truncated for column 't' at row 2
+Warning 1265 Data truncated for column 't' at row 3
+Warning 1265 Data truncated for column 't' at row 4
+Warning 1265 Data truncated for column 't' at row 5
+Warning 1265 Data truncated for column 't' at row 6
select * from t1;
t
0000-00-00 00:00:00
@@ -134,12 +134,12 @@ insert into t1 values
("2003-01-02 03:04:60"),("2003-01-02 03:63:01"),("2003-01-02 24:04:01"),
("2003-01-32 03:04:01"),("2003-13-02 03:04:01"), ("10000-12-02 03:04:00");
Warnings:
-Warning 1264 Out of range value for column 't' at row 1
-Warning 1264 Out of range value for column 't' at row 2
-Warning 1264 Out of range value for column 't' at row 3
-Warning 1264 Out of range value for column 't' at row 4
-Warning 1264 Out of range value for column 't' at row 5
-Warning 1264 Out of range value for column 't' at row 6
+Warning 1265 Data truncated for column 't' at row 1
+Warning 1265 Data truncated for column 't' at row 2
+Warning 1265 Data truncated for column 't' at row 3
+Warning 1265 Data truncated for column 't' at row 4
+Warning 1265 Data truncated for column 't' at row 5
+Warning 1265 Data truncated for column 't' at row 6
select * from t1;
t
0000-00-00 00:00:00
@@ -151,8 +151,8 @@ t
delete from t1;
insert into t1 values ("0000-00-00 00:00:00 some trailer"),("2003-01-01 00:00:00 some trailer");
Warnings:
-Warning 1264 Out of range value for column 't' at row 1
-Warning 1264 Out of range value for column 't' at row 2
+Warning 1265 Data truncated for column 't' at row 1
+Warning 1265 Data truncated for column 't' at row 2
select * from t1 order by t;
t
0000-00-00 00:00:00
@@ -170,7 +170,7 @@ dt
drop table t1;
select cast('2006-12-05 22:10:10' as datetime) + 0;
cast('2006-12-05 22:10:10' as datetime) + 0
-20061205221010.000000
+20061205221010
CREATE TABLE t1(a DATETIME NOT NULL);
INSERT INTO t1 VALUES ('20060606155555');
SELECT a FROM t1 WHERE a=(SELECT MAX(a) FROM t1) AND (a="20060606155555");
@@ -185,14 +185,14 @@ DROP TABLE t1;
SELECT CAST(CAST('2006-08-10' AS DATE) AS DECIMAL(20,6));
CAST(CAST('2006-08-10' AS DATE) AS DECIMAL(20,6))
20060810.000000
-SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME) AS DECIMAL(20,6));
-CAST(CAST('2006-08-10 10:11:12' AS DATETIME) AS DECIMAL(20,6))
+SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME(6)) AS DECIMAL(20,6));
+CAST(CAST('2006-08-10 10:11:12' AS DATETIME(6)) AS DECIMAL(20,6))
20060810101112.000000
-SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME) + INTERVAL 14 MICROSECOND AS DECIMAL(20,6));
-CAST(CAST('2006-08-10 10:11:12' AS DATETIME) + INTERVAL 14 MICROSECOND AS DECIMAL(20,6))
+SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME(6)) + INTERVAL 14 MICROSECOND AS DECIMAL(20,6));
+CAST(CAST('2006-08-10 10:11:12' AS DATETIME(6)) + INTERVAL 14 MICROSECOND AS DECIMAL(20,6))
20060810101112.000014
-SELECT CAST(CAST('10:11:12.098700' AS TIME) AS DECIMAL(20,6));
-CAST(CAST('10:11:12.098700' AS TIME) AS DECIMAL(20,6))
+SELECT CAST(CAST('10:11:12.098700' AS TIME(6)) AS DECIMAL(20,6));
+CAST(CAST('10:11:12.098700' AS TIME(6)) AS DECIMAL(20,6))
101112.098700
set @org_mode=@@sql_mode;
create table t1 (da date default '1962-03-03 23:33:34', dt datetime default '1962-03-03');
@@ -352,7 +352,7 @@ least(cast('01-01-01' as date), '01-01-02')
2001-01-01
select greatest(cast('01-01-01' as date), '01-01-02');
greatest(cast('01-01-01' as date), '01-01-02')
-01-01-02
+2001-01-02
select least(cast('01-01-01' as date), '01-01-02') + 0;
least(cast('01-01-01' as date), '01-01-02') + 0
20010101
@@ -361,7 +361,7 @@ greatest(cast('01-01-01' as date), '01-01-02') + 0
20010102
select least(cast('01-01-01' as datetime), '01-01-02') + 0;
least(cast('01-01-01' as datetime), '01-01-02') + 0
-20010101000000
+20010101000000.000000
select cast(least(cast('01-01-01' as datetime), '01-01-02') as signed);
cast(least(cast('01-01-01' as datetime), '01-01-02') as signed)
20010101000000
@@ -399,7 +399,7 @@ if(@bug28261 = f1, '', @bug28261:= f1)
2001-01-01
2002-02-02
Warnings:
-Warning 1292 Incorrect date value: '' for column 'f1' at row 1
+Warning 1292 Incorrect datetime value: ''
select if(@bug28261 = f1, '', @bug28261:= f1) from t1;
if(@bug28261 = f1, '', @bug28261:= f1)
2001-01-01
@@ -423,11 +423,11 @@ f1
2001-01-01 00:00:00
2002-02-02 00:00:00
Warnings:
-Warning 1292 Incorrect datetime value: '2002010' for column 'f1' at row 1
+Warning 1292 Incorrect datetime value: '2002010'
select * from t1 where f1 between 20020101 and 2007010100000;
f1
Warnings:
-Warning 1292 Incorrect datetime value: '2007010100000' for column 'f1' at row 1
+Warning 1292 Incorrect datetime value: '2007010100000'
drop table t1;
#
# Bug#27216: functions with parameters of different date types may
@@ -495,9 +495,10 @@ insert into t1 set f1 = '45:44:44';
insert into t1 set f1 = '15:44:44';
select * from t1 where (convert(f1,datetime)) != 1;
f1
+45:44:44
15:44:44
Warnings:
-Warning 1292 Incorrect datetime value: '0000-00-00 45:44:44'
+Warning 1292 Incorrect datetime value: '1'
drop table t1;
create table t1 (a tinyint);
insert into t1 values (), (), ();
@@ -509,15 +510,16 @@ create table t1 (id int(10) not null, cur_date datetime not null);
create table t2 (id int(10) not null, cur_date date not null);
insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22');
insert into t2 (id, cur_date) values (1, '2007-04-25');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
explain extended
select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-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 +528,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
@@ -540,10 +541,10 @@ 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 x1 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary; End temporary
Warnings:
Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`cur_date` AS `cur_date` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`id`,<exists>(select 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
@@ -552,13 +553,14 @@ 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 x1 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary; End temporary
Warnings:
Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`id` AS `id`,`test`.`t2`.`cur_date` AS `cur_date` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`id`,<exists>(select 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
+SET optimizer_switch=@save_optimizer_switch;
drop table t1,t2;
SELECT
CAST('NULL' AS DATE) <=> CAST('2008-01-01' AS DATE) n1,
@@ -619,21 +621,21 @@ ERROR 42000: Invalid default value for 'da'
create table t1 (t time default '916:00:00 a');
ERROR 42000: Invalid default value for 't'
set @@sql_mode= @org_mode;
-SELECT CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME) AS DECIMAL(30,7));
-CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME) AS DECIMAL(30,7))
+SELECT CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME(6)) AS DECIMAL(30,7));
+CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME(6)) AS DECIMAL(30,7))
20060810101112.0123450
Warnings:
Warning 1292 Truncated incorrect datetime value: '2006-08-10 10:11:12.0123450'
-SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME) AS DECIMAL(30,7));
-CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME) AS DECIMAL(30,7))
+SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME(6)) AS DECIMAL(30,7));
+CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME(6)) AS DECIMAL(30,7))
20060810101112.0123450
Warnings:
Warning 1292 Truncated incorrect datetime value: '00000002006-000008-0000010 000010:0000011:00000012.0123450'
-SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME) AS DECIMAL(30,7));
-CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME) AS DECIMAL(30,7))
+SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME(6)) AS DECIMAL(30,7));
+CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME(6)) AS DECIMAL(30,7))
20060810101112.0123450
-SELECT CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7));
-CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7))
+SELECT CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime(6)) AS DECIMAL(30,7));
+CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime(6)) AS DECIMAL(30,7))
20080729104251.1234560
Warnings:
Warning 1292 Truncated incorrect datetime value: '2008-07-29T10:42:51.1234567'
diff --git a/mysql-test/r/type_datetime_hires.result b/mysql-test/r/type_datetime_hires.result
new file mode 100644
index 00000000000..583030bf0da
--- /dev/null
+++ b/mysql-test/r/type_datetime_hires.result
@@ -0,0 +1,340 @@
+drop table if exists t1, t2, t3;
+create table t1 (a datetime(7));
+ERROR 42000: Too big precision 7 specified for 'a'. Maximum is 6.
+create table t1 (a datetime(3), key(a));
+insert t1 values ('2010-12-11 00:20:03.1234');
+insert t1 values ('2010-12-11 15:47:11.1234');
+insert t1 values (20101211010203.45678);
+insert t1 values (20101211030405.789e0);
+insert t1 values (99991231235959e1);
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+select * from t1;
+a
+0000-00-00 00:00:00.000
+2010-12-11 00:20:03.123
+2010-12-11 01:02:03.456
+2010-12-11 03:04:05.789
+2010-12-11 15:47:11.123
+select truncate(a, 6) from t1;
+truncate(a, 6)
+0.000000
+20101211002003.121094
+20101211010203.457031
+20101211030405.789062
+20101211154711.121094
+select a DIV 1 from t1;
+a DIV 1
+0
+20101211002003
+20101211010203
+20101211030405
+20101211154711
+select group_concat(distinct a) from t1;
+group_concat(distinct a)
+0000-00-00 00:00:00.000,2010-12-11 00:20:03.123,2010-12-11 01:02:03.456,2010-12-11 03:04:05.789,2010-12-11 15:47:11.123
+alter table t1 engine=innodb;
+select * from t1 order by a;
+a
+0000-00-00 00:00:00.000
+2010-12-11 00:20:03.123
+2010-12-11 01:02:03.456
+2010-12-11 03:04:05.789
+2010-12-11 15:47:11.123
+select * from t1 order by a+0;
+a
+0000-00-00 00:00:00.000
+2010-12-11 00:20:03.123
+2010-12-11 01:02:03.456
+2010-12-11 03:04:05.789
+2010-12-11 15:47:11.123
+drop table t1;
+create table t1 (a datetime(4)) engine=innodb;
+insert t1 values ('2010-12-11 01:02:03.456789');
+select * from t1;
+a
+2010-12-11 01:02:03.4567
+select extract(microsecond from a + interval 100 microsecond) from t1 where a>'2010-11-12 01:02:03.456';
+extract(microsecond from a + interval 100 microsecond)
+456800
+select a from t1 where a>'2010-11-12 01:02:03.456' group by a;
+a
+2010-12-11 01:02:03.4567
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` datetime(4) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+show columns from t1;
+Field Type Null Key Default Extra
+a datetime(4) YES NULL
+select table_name, column_name, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra from information_schema.columns where table_name='t1';
+table_name t1
+column_name a
+column_default NULL
+is_nullable YES
+data_type datetime
+character_maximum_length NULL
+character_octet_length NULL
+numeric_precision NULL
+numeric_scale NULL
+datetime_precision 4
+character_set_name NULL
+collation_name NULL
+column_type datetime(4)
+column_key
+extra
+select a, a+interval 9876543 microsecond from t1;
+a a+interval 9876543 microsecond
+2010-12-11 01:02:03.4567 2010-12-11 01:02:13.333243
+update t1 set a=a+interval 9876543 microsecond;
+select * from t1;
+a
+2010-12-11 01:02:13.3332
+select a, a + interval 2 year from t1;
+a a + interval 2 year
+2010-12-11 01:02:13.3332 2012-12-11 01:02:13.3332
+insert t1 select a + interval 2 year from t1;
+select * from t1;
+a
+2010-12-11 01:02:13.3332
+2012-12-11 01:02:13.3332
+delete from t1 where a < 20110101;
+select * from t1;
+a
+2012-12-11 01:02:13.3332
+create table t2 select * from t1;
+create table t3 like t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` datetime(4) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` datetime(4) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2, t3;
+insert t1 values ('2010-12-13 14:15:16.222222');
+select a, a+0, a-1, a*1, a/2 from t1;
+a a+0 a-1 a*1 a/2
+2012-12-11 01:02:13.3332 20121211010213.3332 20121211010212.3332 20121211010213.3332 10060605505106.66660000
+2010-12-13 14:15:16.2222 20101213141516.2222 20101213141515.2222 20101213141516.2222 10050606570758.11110000
+select max(a), min(a), sum(a), avg(a) from t1;
+max(a) min(a) sum(a) avg(a)
+2012-12-11 01:02:13.3332 2010-12-13 14:15:16.2222 40222424151729.5554 20111212075864.77770000
+create table t2 select a, a+0, a-1, a*1, a/2 from t1;
+create table t3 select max(a), min(a), sum(a), avg(a) from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` datetime(4) DEFAULT NULL,
+ `a+0` decimal(25,4) DEFAULT NULL,
+ `a-1` decimal(25,4) DEFAULT NULL,
+ `a*1` decimal(25,4) DEFAULT NULL,
+ `a/2` decimal(28,8) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `max(a)` datetime(4) DEFAULT NULL,
+ `min(a)` datetime(4) DEFAULT NULL,
+ `sum(a)` decimal(46,4) DEFAULT NULL,
+ `avg(a)` decimal(28,8) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1, t2, t3;
+create table t1 (f0_datetime datetime(0), f1_datetime datetime(1), f2_datetime datetime(2), f3_datetime datetime(3), f4_datetime datetime(4), f5_datetime datetime(5), f6_datetime datetime(6));
+insert t1 values ( '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432');
+select * from t1;
+f0_datetime 2010-11-12 11:14:17
+f1_datetime 2010-11-12 11:14:17.7
+f2_datetime 2010-11-12 11:14:17.76
+f3_datetime 2010-11-12 11:14:17.765
+f4_datetime 2010-11-12 11:14:17.7654
+f5_datetime 2010-11-12 11:14:17.76543
+f6_datetime 2010-11-12 11:14:17.765432
+select cast(f0_datetime as time(4)) time4_f0_datetime, cast(f1_datetime as datetime(3)) datetime3_f1_datetime, cast(f2_datetime as date) date_f2_datetime, cast(f4_datetime as double) double_f3_datetime, cast(f4_datetime as decimal(40,5)) decimal5_f4_datetime, cast(f5_datetime as signed) bigint_f5_datetime, cast(f6_datetime as char(255)) varchar_f6_datetime from t1;
+time4_f0_datetime 11:14:17.0000
+datetime3_f1_datetime 2010-11-12 11:14:17.700
+date_f2_datetime 2010-11-12
+double_f3_datetime 20101112111417.8
+decimal5_f4_datetime 20101112111417.76540
+bigint_f5_datetime 20101112111417
+varchar_f6_datetime 2010-11-12 11:14:17.765432
+create table t2 (time4_f0_datetime time(4), datetime3_f1_datetime datetime(3), date_f2_datetime date, double_f3_datetime double, decimal5_f4_datetime decimal(40,5), bigint_f5_datetime bigint, varchar_f6_datetime varchar(255));
+insert t2 select * from t1;
+Warnings:
+Level Note
+Code 1265
+Message Data truncated for column 'time4_f0_datetime' at row 1
+Level Note
+Code 1265
+Message Data truncated for column 'date_f2_datetime' at row 1
+select * from t2;
+time4_f0_datetime 11:14:17.0000
+datetime3_f1_datetime 2010-11-12 11:14:17.700
+date_f2_datetime 2010-11-12
+double_f3_datetime 20101112111417.8
+decimal5_f4_datetime 20101112111417.76540
+bigint_f5_datetime 20101112111417
+varchar_f6_datetime 2010-11-12 11:14:17.765432
+alter table t1 change f0_datetime time4_f0_datetime time(4), change f1_datetime datetime3_f1_datetime datetime(3), change f2_datetime date_f2_datetime date, change f3_datetime double_f3_datetime double, change f4_datetime decimal5_f4_datetime decimal(40,5), change f5_datetime bigint_f5_datetime bigint, change f6_datetime varchar_f6_datetime varchar(255);
+Warnings:
+Level Note
+Code 1265
+Message Data truncated for column 'time4_f0_datetime' at row 1
+Level Note
+Code 1265
+Message Data truncated for column 'date_f2_datetime' at row 1
+select * from t1;
+time4_f0_datetime 11:14:17.0000
+datetime3_f1_datetime 2010-11-12 11:14:17.700
+date_f2_datetime 2010-11-12
+double_f3_datetime 20101112111417.8
+decimal5_f4_datetime 20101112111417.76540
+bigint_f5_datetime 20101112111417
+varchar_f6_datetime 2010-11-12 11:14:17.765432
+alter table t1 modify time4_f0_datetime datetime(0), modify datetime3_f1_datetime datetime(1), modify date_f2_datetime datetime(2), modify double_f3_datetime datetime(3), modify decimal5_f4_datetime datetime(4), modify bigint_f5_datetime datetime(5), modify varchar_f6_datetime datetime(6);
+select * from t1;
+time4_f0_datetime 0000-00-00 11:14:17
+datetime3_f1_datetime 2010-11-12 11:14:17.7
+date_f2_datetime 2010-11-12 00:00:00.00
+double_f3_datetime 2010-11-12 11:14:17.800
+decimal5_f4_datetime 2010-11-12 11:14:17.7654
+bigint_f5_datetime 2010-11-12 11:14:17.00000
+varchar_f6_datetime 2010-11-12 11:14:17.765432
+delete from t1;
+insert t1 select * from t2;
+select * from t1;
+time4_f0_datetime 0000-00-00 11:14:17
+datetime3_f1_datetime 2010-11-12 11:14:17.7
+date_f2_datetime 2010-11-12 00:00:00.00
+double_f3_datetime 2010-11-12 11:14:17.765
+decimal5_f4_datetime 2010-11-12 11:14:17.7654
+bigint_f5_datetime 2010-11-12 11:14:17.00000
+varchar_f6_datetime 2010-11-12 11:14:17.765432
+drop table t1, t2;
+create table t1 (a datetime(6), b datetime(6));
+create procedure foo(x datetime, y datetime(4)) insert into t1 values (x, y);
+call foo('2010-02-03 4:5:6.789123', '2010-02-03 4:5:6.789123');
+select * from t1;
+a b
+2010-02-03 04:05:06.000000 2010-02-03 04:05:06.789100
+create procedure bar(a int, c datetime(5))
+begin
+declare b datetime(4);
+set b = c + interval a microsecond;
+insert t1 values (b, c + interval a microsecond);
+end|
+call bar(1111111, '2011-01-02 3:4:5.123456');
+select * from t1;
+a b
+2010-02-03 04:05:06.000000 2010-02-03 04:05:06.789100
+2011-01-02 03:04:06.234500 2011-01-02 03:04:06.234561
+drop procedure foo;
+drop procedure bar;
+create function xyz(s char(20)) returns datetime(4)
+return addtime('2010-10-10 10:10:10.101010', s);
+select xyz('1:1:1.010101');
+xyz('1:1:1.010101')
+2010-10-10 11:11:11.1111
+drop function xyz;
+create view v1 as select * from t1 group by a,b;
+select * from v1;
+a b
+2010-02-03 04:05:06.000000 2010-02-03 04:05:06.789100
+2011-01-02 03:04:06.234500 2011-01-02 03:04:06.234561
+show columns from v1;
+Field Type Null Key Default Extra
+a datetime(6) YES NULL
+b datetime(6) YES NULL
+create table t2 select * from v1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` datetime(6) DEFAULT NULL,
+ `b` datetime(6) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t2;
+a b
+2010-02-03 04:05:06.000000 2010-02-03 04:05:06.789100
+2011-01-02 03:04:06.234500 2011-01-02 03:04:06.234561
+drop view v1;
+drop table t1, t2;
+CREATE TABLE t1 (
+taken datetime(5) NOT NULL DEFAULT '0000-00-00 00:00:00',
+id int(11) NOT NULL DEFAULT '0',
+PRIMARY KEY (id,taken),
+KEY taken (taken)
+)
+PARTITION BY RANGE (to_days(taken))
+(
+PARTITION p01 VALUES LESS THAN (732920),
+PARTITION p02 VALUES LESS THAN (732950),
+PARTITION p03 VALUES LESS THAN MAXVALUE);
+INSERT INTO t1 VALUES
+('2006-09-27 21:50:01.123456',0),
+('2006-09-27 21:50:01.123456',1),
+('2006-09-27 21:50:01.123456',2),
+('2006-09-28 21:50:01.123456',3),
+('2006-09-29 21:50:01.123456',4),
+('2006-09-29 21:50:01.123456',5),
+('2006-09-30 21:50:01.123456',6),
+('2006-10-01 21:50:01.123456',7),
+('2006-10-02 21:50:01.123456',8),
+('2006-10-02 21:50:01.123456',9);
+SELECT id,to_days(taken) FROM t1 order by 2;
+id to_days(taken)
+0 732946
+1 732946
+2 732946
+3 732947
+5 732948
+4 732948
+6 732949
+7 732950
+8 732951
+9 732951
+CREATE TABLE t2 (
+taken datetime(5) NOT NULL DEFAULT '0000-00-00 00:00:00',
+id int(11) NOT NULL DEFAULT '0',
+PRIMARY KEY (id,taken),
+KEY taken (taken)
+)
+PARTITION BY RANGE (extract(microsecond from taken))
+(
+PARTITION p01 VALUES LESS THAN (123000),
+PARTITION p02 VALUES LESS THAN (500000),
+PARTITION p03 VALUES LESS THAN MAXVALUE);
+INSERT INTO t2 VALUES
+('2006-09-27 21:50:01',0),
+('2006-09-27 21:50:01.1',1),
+('2006-09-27 21:50:01.12',2),
+('2006-09-28 21:50:01.123',3),
+('2006-09-29 21:50:01.1234',4),
+('2006-09-29 21:50:01.12345',5),
+('2006-09-30 21:50:01.123456',6),
+('2006-10-01 21:50:01.56',7),
+('2006-10-02 21:50:01.567',8),
+('2006-10-02 21:50:01.5678',9);
+select table_name,partition_name,partition_method,partition_expression,partition_description,table_rows from information_schema.partitions where table_name in ('t1', 't2');
+table_name partition_name partition_method partition_expression partition_description table_rows
+t1 p01 RANGE to_days(taken) 732920 0
+t1 p02 RANGE to_days(taken) 732950 7
+t1 p03 RANGE to_days(taken) MAXVALUE 3
+t2 p01 RANGE extract(microsecond from taken) 123000 3
+t2 p02 RANGE extract(microsecond from taken) 500000 4
+t2 p03 RANGE extract(microsecond from taken) MAXVALUE 3
+drop table t1, t2;
+create table t1 (a datetime, b datetime(6));
+insert t1 values ('2010-01-02 03:04:05.678912', '2010-01-02 03:04:05.678912');
+update t1 set b=a;
+select * from t1;
+a b
+2010-01-02 03:04:05 2010-01-02 03:04:05.000000
+alter table t1 modify b datetime, modify a datetime(6);
+select * from t1;
+a b
+2010-01-02 03:04:05.000000 2010-01-02 03:04:05
+drop table t1;
diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index 76c5ea8f756..a0252676d65 100644
--- a/mysql-test/r/type_decimal.result
+++ b/mysql-test/r/type_decimal.result
@@ -721,7 +721,7 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (d decimal(66,0));
-ERROR 42000: Too big precision 66 specified for column 'd'. Maximum is 65.
+ERROR 42000: Too big precision 66 specified for 'd'. Maximum is 65.
CREATE TABLE t1 (i INT, d1 DECIMAL(9,2), d2 DECIMAL(9,2));
INSERT INTO t1 VALUES (1, 101.40, 21.40), (1, -80.00, 0.00),
(2, 0.00, 0.00), (2, -13.20, 0.00), (2, 59.60, 46.40),
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index 95ac2a23943..6c55dfd3869 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -133,7 +133,7 @@ min(a)
-0.010
drop table t1;
create table t1 (a float(200,100), b double(200,100));
-ERROR 42000: Too big scale 100 specified for column 'a'. Maximum is 30.
+ERROR 42000: Too big scale 100 specified for 'a'. Maximum is 30.
create table t1 (c20 char);
insert into t1 values (5000.0);
Warnings:
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index f80e7d4199b..cdffd202942 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -825,7 +825,7 @@ Error 1365 Division by 0
Error 1365 Division by 0
Error 1365 Division by 0
INSERT INTO Sow6_2f VALUES ('a59b');
-ERROR HY000: Incorrect decimal value: 'a59b' for column 'col1' at row 1
+ERROR 22007: Incorrect decimal value: 'a59b' for column 'col1' at row 1
drop table Sow6_2f;
select 10.3330000000000/12.34500000;
10.3330000000000/12.34500000
@@ -838,12 +838,12 @@ select 9999999999999999999999999999999999999999999999999999999999999999999999999
x
99999999999999999999999999999999999999999999999999999999999999999
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 1 as x;
x
100000000000000000000000000000000000000000000000000000000000000000
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
select 0.190287977636363637 + 0.040372670 * 0 - 0;
0.190287977636363637 + 0.040372670 * 0 - 0
0.190287977636363637
@@ -923,11 +923,11 @@ ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column
select cast(ln(14000) as decimal(2,3)) c1;
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '').
create table t1 (sl decimal(70,30));
-ERROR 42000: Too big precision 70 specified for column 'sl'. Maximum is 65.
+ERROR 42000: Too big precision 70 specified for 'sl'. Maximum is 65.
create table t1 (sl decimal(32,31));
-ERROR 42000: Too big scale 31 specified for column 'sl'. Maximum is 30.
+ERROR 42000: Too big scale 31 specified for 'sl'. Maximum is 30.
create table t1 (sl decimal(0,38));
-ERROR 42000: Too big scale 38 specified for column 'sl'. Maximum is 30.
+ERROR 42000: Too big scale 38 specified for 'sl'. Maximum is 30.
create table t1 (sl decimal(0,30));
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'sl').
create table t1 (sl decimal(5, 5));
@@ -1380,15 +1380,15 @@ create table t1 (c1 decimal(64));
insert into t1 values(
89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Warning 1264 Out of range value for column 'c1' at row 1
insert into t1 values(
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 *
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999);
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Warning 1264 Out of range value for column 'c1' at row 1
insert into t1 values(1e100);
Warnings:
@@ -1432,7 +1432,7 @@ select cast(19999999999999999999 as unsigned);
cast(19999999999999999999 as unsigned)
18446744073709551615
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '19999999999999999999' to UNSIGNED INT. Value truncated.
create table t1(a decimal(18));
insert into t1 values(123456789012345678);
alter table t1 modify column a decimal(19);
@@ -1485,12 +1485,12 @@ SELECT CAST(1 AS decimal(65,10));
CAST(1 AS decimal(65,10))
1.0000000000
SELECT CAST(1 AS decimal(66,10));
-ERROR 42000: Too big precision 66 specified for column '1'. Maximum is 65.
+ERROR 42000: Too big precision 66 specified for '1'. Maximum is 65.
SELECT CAST(1 AS decimal(65,30));
CAST(1 AS decimal(65,30))
1.000000000000000000000000000000
SELECT CAST(1 AS decimal(65,31));
-ERROR 42000: Too big scale 31 specified for column '1'. Maximum is 30.
+ERROR 42000: Too big scale 31 specified for '1'. Maximum is 30.
CREATE TABLE t1 (a int DEFAULT NULL, b int DEFAULT NULL);
INSERT INTO t1 VALUES (3,30), (1,10), (2,10);
SELECT a+CAST(1 AS decimal(65,30)) AS aa, SUM(b) FROM t1 GROUP BY aa;
@@ -1499,7 +1499,7 @@ aa SUM(b)
3.000000000000000000000000000000 10
4.000000000000000000000000000000 30
SELECT a+CAST(1 AS decimal(65,31)) AS aa, SUM(b) FROM t1 GROUP BY aa;
-ERROR 42000: Too big scale 31 specified for column '1'. Maximum is 30.
+ERROR 42000: Too big scale 31 specified for '1'. Maximum is 30.
DROP TABLE t1;
CREATE TABLE t1 (a int DEFAULT NULL, b int DEFAULT NULL);
INSERT INTO t1 VALUES (3,30), (1,10), (2,10);
@@ -1557,8 +1557,8 @@ SELECT substring(('M') FROM (999999999999999999999999999999999999999999999999999
foo
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '999999999999999999999999999999999999999999999999999999999999999999999999999999999' to INT. Value truncated.
+Error 1916 Got overflow when converting '999999999999999999999999999999999999999999999999999999999999999999999999999999999' to INT. Value truncated.
SELECT min(999999999999999999999999999999999999999999999999999999999999999999999999999999999) AS foo;
foo
999999999999999999999999999999999999999999999999999999999999999999999999999999999
@@ -1566,7 +1566,7 @@ SELECT multipolygonfromtext(('4294967294.1'),(9999999999999999999999999999999999
foo
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '999999999999999999999999999999999999999999999999999999999999999999999999999999999' to INT. Value truncated.
SELECT convert((999999999999999999999999999999999999999999999999999999999999999999999999999999999), decimal(30,30)) AS foo;
foo
0.999999999999999999999999999999
@@ -1576,7 +1576,7 @@ SELECT bit_xor(99999999999999999999999999999999999999999999999999999999999999999
foo
9223372036854775807
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '999999999999999999999999999999999999999999999999999999999999999999999999999999999' to INT. Value truncated.
SELECT -(999999999999999999999999999999999999999999999999999999999999999999999999999999999) AS foo;
foo
-999999999999999999999999999999999999999999999999999999999999999999999999999999999
@@ -1588,8 +1588,7 @@ AS foo;
foo
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Warning 1292 Incorrect datetime value: '9223372036854775807'
+Warning 1292 Incorrect datetime value: '999999999999999999999999999999999999999999999999999999999999999999999999999999999'
SELECT truncate(999999999999999999999999999999999999999999999999999999999999999999999999999999999, 28) AS foo;
foo
999999999999999999999999999999999999999999999999999999999999999999999999999999999
@@ -1718,7 +1717,7 @@ CREATE TABLE t1 SELECT
/* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
AS c1;
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
DESC t1;
Field Type Null Key Default Extra
c1 decimal(65,0) NO 0
diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result
index 86712bebfa1..f2464465d60 100644
--- a/mysql-test/r/type_time.result
+++ b/mysql-test/r/type_time.result
@@ -1,6 +1,8 @@
drop table if exists t1;
create table t1 (t time);
insert into t1 values("10:22:33"),("12:34:56.78"),(10),(1234),(123456.78),(1234559.99),("1"),("1:23"),("1:23:45"), ("10.22"), ("-10 1:22:33.45"),("20 10:22:33"),("1999-02-03 20:33:34");
+Warnings:
+Note 1265 Data truncated for column 't' at row 13
insert t1 values (30),(1230),("1230"),("12:30"),("12:30:35"),("1 12:30:31.32");
select * from t1;
t
@@ -26,9 +28,9 @@ t
insert into t1 values("10.22.22"),(1234567),(123456789),(123456789.10),("10 22:22"),("12.45a");
Warnings:
Warning 1265 Data truncated for column 't' at row 1
-Warning 1264 Out of range value for column 't' at row 2
-Warning 1264 Out of range value for column 't' at row 3
-Warning 1264 Out of range value for column 't' at row 4
+Warning 1265 Data truncated for column 't' at row 2
+Warning 1265 Data truncated for column 't' at row 3
+Warning 1265 Data truncated for column 't' at row 4
Warning 1265 Data truncated for column 't' at row 6
select * from t1;
t
@@ -53,8 +55,8 @@ t
36:30:31
00:00:10
00:00:00
-838:59:59
-838:59:59
+00:00:00
+00:00:00
262:22:00
00:00:12
drop table t1;
@@ -148,3 +150,26 @@ TIMESTAMP(f1,'1')
NULL
DROP TABLE t1;
End of 5.1 tests
+create table t1 (a time);
+insert t1 values (-131415);
+select * from t1;
+a
+-13:14:15
+drop table t1;
+create table t1 (f1 time , f2 varchar(5), key(f1));
+insert into t1 values ('00:20:01','a'),('00:20:03','b');
+select * from t1 force key (f1) where f1 < curdate();
+f1 f2
+00:20:01 a
+00:20:03 b
+select * from t1 ignore key (f1) where f1 < curdate();
+f1 f2
+00:20:01 a
+00:20:03 b
+drop table t1;
+create table t1(f1 time);
+insert into t1 values ('23:38:57');
+select f1, f1 = '2010-10-11 23:38:57' from t1;
+f1 f1 = '2010-10-11 23:38:57'
+23:38:57 0
+drop table t1;
diff --git a/mysql-test/r/type_time_hires.result b/mysql-test/r/type_time_hires.result
new file mode 100644
index 00000000000..bf54434a04c
--- /dev/null
+++ b/mysql-test/r/type_time_hires.result
@@ -0,0 +1,340 @@
+drop table if exists t1, t2, t3;
+create table t1 (a time(7));
+ERROR 42000: Too big precision 7 specified for 'a'. Maximum is 6.
+create table t1 (a time(3), key(a));
+insert t1 values ('2010-12-11 00:20:03.1234');
+Warnings:
+Note 1265 Data truncated for column 'a' at row 1
+insert t1 values ('2010-12-11 15:47:11.1234');
+Warnings:
+Note 1265 Data truncated for column 'a' at row 1
+insert t1 values (20101211010203.45678);
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+insert t1 values (20101211030405.789e0);
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+insert t1 values (99991231235959e1);
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+select * from t1;
+a
+00:00:00.000
+00:20:03.123
+01:02:03.456
+03:04:05.789
+15:47:11.123
+select truncate(a, 6) from t1;
+truncate(a, 6)
+0.000000
+2003.123000
+10203.456000
+30405.789062
+154711.123000
+select a DIV 1 from t1;
+a DIV 1
+0
+2003
+10203
+30405
+154711
+select group_concat(distinct a) from t1;
+group_concat(distinct a)
+00:00:00.000,00:20:03.123,01:02:03.456,03:04:05.789,15:47:11.123
+alter table t1 engine=innodb;
+select * from t1 order by a;
+a
+00:00:00.000
+00:20:03.123
+01:02:03.456
+03:04:05.789
+15:47:11.123
+select * from t1 order by a+0;
+a
+00:00:00.000
+00:20:03.123
+01:02:03.456
+03:04:05.789
+15:47:11.123
+drop table t1;
+create table t1 (a time(4)) engine=innodb;
+insert t1 values ('2010-12-11 01:02:03.456789');
+Warnings:
+Note 1265 Data truncated for column 'a' at row 1
+select * from t1;
+a
+01:02:03.4567
+select extract(microsecond from a + interval 100 microsecond) from t1 where a>'2010-11-12 01:02:03.456';
+extract(microsecond from a + interval 100 microsecond)
+select a from t1 where a>'2010-11-12 01:02:03.456' group by a;
+a
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` time(4) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+show columns from t1;
+Field Type Null Key Default Extra
+a time(4) YES NULL
+select table_name, column_name, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra from information_schema.columns where table_name='t1';
+table_name t1
+column_name a
+column_default NULL
+is_nullable YES
+data_type time
+character_maximum_length NULL
+character_octet_length NULL
+numeric_precision NULL
+numeric_scale NULL
+datetime_precision 4
+character_set_name NULL
+collation_name NULL
+column_type time(4)
+column_key
+extra
+select a, a+interval 9876543 microsecond from t1;
+a a+interval 9876543 microsecond
+01:02:03.4567 01:02:13.333243
+update t1 set a=a+interval 9876543 microsecond;
+select * from t1;
+a
+01:02:13.3332
+select a, a + interval 2 year from t1;
+a a + interval 2 year
+01:02:13.3332 NULL
+Warnings:
+Warning 1441 Datetime function: time field overflow
+insert t1 select a + interval 2 year from t1;
+Warnings:
+Warning 1441 Datetime function: time field overflow
+select * from t1;
+a
+01:02:13.3332
+NULL
+delete from t1 where a < 20110101;
+select * from t1;
+a
+01:02:13.3332
+NULL
+create table t2 select * from t1;
+create table t3 like t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` time(4) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` time(4) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2, t3;
+insert t1 values ('2010-12-13 14:15:16.222222');
+Warnings:
+Note 1265 Data truncated for column 'a' at row 1
+select a, a+0, a-1, a*1, a/2 from t1;
+a a+0 a-1 a*1 a/2
+01:02:13.3332 10213.3332 10212.3332 10213.3332 5106.66660000
+NULL NULL NULL NULL NULL
+14:15:16.2222 141516.2222 141515.2222 141516.2222 70758.11110000
+select max(a), min(a), sum(a), avg(a) from t1;
+max(a) min(a) sum(a) avg(a)
+14:15:16.2222 01:02:13.3332 151729.5554 75864.77770000
+create table t2 select a, a+0, a-1, a*1, a/2 from t1;
+create table t3 select max(a), min(a), sum(a), avg(a) from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` time(4) DEFAULT NULL,
+ `a+0` decimal(16,4) DEFAULT NULL,
+ `a-1` decimal(16,4) DEFAULT NULL,
+ `a*1` decimal(16,4) DEFAULT NULL,
+ `a/2` decimal(19,8) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `max(a)` time(4) DEFAULT NULL,
+ `min(a)` time(4) DEFAULT NULL,
+ `sum(a)` decimal(37,4) DEFAULT NULL,
+ `avg(a)` decimal(19,8) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1, t2, t3;
+create table t1 (f0_time time(0), f1_time time(1), f2_time time(2), f3_time time(3), f4_time time(4), f5_time time(5), f6_time time(6));
+insert t1 values ( '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432');
+Warnings:
+Level Note
+Code 1265
+Message Data truncated for column 'f0_time' at row 1
+Level Note
+Code 1265
+Message Data truncated for column 'f1_time' at row 1
+Level Note
+Code 1265
+Message Data truncated for column 'f2_time' at row 1
+Level Note
+Code 1265
+Message Data truncated for column 'f3_time' at row 1
+Level Note
+Code 1265
+Message Data truncated for column 'f4_time' at row 1
+Level Note
+Code 1265
+Message Data truncated for column 'f5_time' at row 1
+Level Note
+Code 1265
+Message Data truncated for column 'f6_time' at row 1
+select * from t1;
+f0_time 11:14:17
+f1_time 11:14:17.7
+f2_time 11:14:17.76
+f3_time 11:14:17.765
+f4_time 11:14:17.7654
+f5_time 11:14:17.76543
+f6_time 11:14:17.765432
+select cast(f0_time as time(4)) time4_f0_time, cast(f1_time as datetime(3)) datetime3_f1_time, cast(f2_time as date) date_f2_time, cast(f4_time as double) double_f3_time, cast(f4_time as decimal(40,5)) decimal5_f4_time, cast(f5_time as signed) bigint_f5_time, cast(f6_time as char(255)) varchar_f6_time from t1;
+time4_f0_time 11:14:17.0000
+datetime3_f1_time 0000-00-00 11:14:17.700
+date_f2_time 0000-00-00
+double_f3_time 111417.7654
+decimal5_f4_time 111417.76540
+bigint_f5_time 111417
+varchar_f6_time 11:14:17.765432
+create table t2 (time4_f0_time time(4), datetime3_f1_time datetime(3), date_f2_time date, double_f3_time double, decimal5_f4_time decimal(40,5), bigint_f5_time bigint, varchar_f6_time varchar(255));
+insert t2 select * from t1;
+Warnings:
+Level Note
+Code 1265
+Message Data truncated for column 'date_f2_time' at row 1
+select * from t2;
+time4_f0_time 11:14:17.0000
+datetime3_f1_time 0000-00-00 11:14:17.700
+date_f2_time 0000-00-00
+double_f3_time 111417.765
+decimal5_f4_time 111417.76540
+bigint_f5_time 111417
+varchar_f6_time 11:14:17.765432
+alter table t1 change f0_time time4_f0_time time(4), change f1_time datetime3_f1_time datetime(3), change f2_time date_f2_time date, change f3_time double_f3_time double, change f4_time decimal5_f4_time decimal(40,5), change f5_time bigint_f5_time bigint, change f6_time varchar_f6_time varchar(255);
+Warnings:
+Level Note
+Code 1265
+Message Data truncated for column 'date_f2_time' at row 1
+select * from t1;
+time4_f0_time 11:14:17.0000
+datetime3_f1_time 0000-00-00 11:14:17.700
+date_f2_time 0000-00-00
+double_f3_time 111417.765
+decimal5_f4_time 111417.76540
+bigint_f5_time 111417
+varchar_f6_time 11:14:17.765432
+alter table t1 modify time4_f0_time time(0), modify datetime3_f1_time time(1), modify date_f2_time time(2), modify double_f3_time time(3), modify decimal5_f4_time time(4), modify bigint_f5_time time(5), modify varchar_f6_time time(6);
+select * from t1;
+time4_f0_time 11:14:17
+datetime3_f1_time 11:14:17.7
+date_f2_time 00:00:00.00
+double_f3_time 11:14:17.765
+decimal5_f4_time 11:14:17.7654
+bigint_f5_time 11:14:17.00000
+varchar_f6_time 11:14:17.765432
+delete from t1;
+insert t1 select * from t2;
+select * from t1;
+time4_f0_time 11:14:17
+datetime3_f1_time 11:14:17.7
+date_f2_time 00:00:00.00
+double_f3_time 11:14:17.764
+decimal5_f4_time 11:14:17.7654
+bigint_f5_time 11:14:17.00000
+varchar_f6_time 11:14:17.765432
+drop table t1, t2;
+create table t1 (a time(6), b time(6));
+create procedure foo(x time, y time(4)) insert into t1 values (x, y);
+call foo('2010-02-03 4:5:6.789123', '2010-02-03 4:5:6.789123');
+Warnings:
+Note 1265 Data truncated for column 'x' at row 1
+Note 1265 Data truncated for column 'y' at row 1
+select * from t1;
+a b
+04:05:06.000000 04:05:06.789100
+create procedure bar(a int, c time(5))
+begin
+declare b time(4);
+set b = c + interval a microsecond;
+insert t1 values (b, c + interval a microsecond);
+end|
+call bar(1111111, '2011-01-02 3:4:5.123456');
+Warnings:
+Note 1265 Data truncated for column 'c' at row 1
+select * from t1;
+a b
+04:05:06.000000 04:05:06.789100
+03:04:06.234500 03:04:06.234561
+drop procedure foo;
+drop procedure bar;
+create function xyz(s char(20)) returns time(4)
+return addtime('2010-10-10 10:10:10.101010', s);
+select xyz('1:1:1.010101');
+xyz('1:1:1.010101')
+11:11:11.1111
+Warnings:
+Note 1265 Data truncated for column 'xyz('1:1:1.010101')' at row 1
+drop function xyz;
+create view v1 as select * from t1 group by a,b;
+select * from v1;
+a b
+03:04:06.234500 03:04:06.234561
+04:05:06.000000 04:05:06.789100
+show columns from v1;
+Field Type Null Key Default Extra
+a time(6) YES NULL
+b time(6) YES NULL
+create table t2 select * from v1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` time(6) DEFAULT NULL,
+ `b` time(6) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t2;
+a b
+03:04:06.234500 03:04:06.234561
+04:05:06.000000 04:05:06.789100
+drop view v1;
+drop table t1, t2;
+create table t1 (a time(4) not null, key(a));
+insert into t1 values ('1:2:3.001'),('1:2:3'), ('-00:00:00.6'),('-00:00:00.7'),('-00:00:00.8'),('-00:00:00.9'),('-00:00:01.0'),('-00:00:01.1'),('-00:00:01.000000'),('-00:00:01.100001'),('-00:00:01.000002'),('-00:00:01.090000');
+select * from t1 order by a;
+a
+-00:00:01.1000
+-00:00:01.1000
+-00:00:01.0900
+-00:00:01.0000
+-00:00:01.0000
+-00:00:01.0000
+-00:00:00.9000
+-00:00:00.8000
+-00:00:00.7000
+-00:00:00.6000
+01:02:03.0000
+01:02:03.0010
+select * from t1 order by a desc;
+a
+01:02:03.0010
+01:02:03.0000
+-00:00:00.6000
+-00:00:00.7000
+-00:00:00.8000
+-00:00:00.9000
+-00:00:01.0000
+-00:00:01.0000
+-00:00:01.0000
+-00:00:01.0900
+-00:00:01.1000
+-00:00:01.1000
+select min(a - interval 1 hour), max(a - interval 1 hour) from t1 where a < 0;
+min(a - interval 1 hour) max(a - interval 1 hour)
+-01:00:01.1000 -01:00:00.6000
+drop table t1;
+select cast(1e-6 as time(6));
+cast(1e-6 as time(6))
+00:00:00.000001
diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result
index 3176879343c..5c3c3226bf8 100644
--- a/mysql-test/r/type_timestamp.result
+++ b/mysql-test/r/type_timestamp.result
@@ -97,30 +97,6 @@ date date_time time_stamp
2005-01-01 2005-01-01 00:00:00 2005-01-01 00:00:00
2030-01-01 2030-01-01 00:00:00 2030-01-01 00:00:00
drop table t1;
-create table t1 (t2 timestamp(2), t4 timestamp(4), t6 timestamp(6),
-t8 timestamp(8), t10 timestamp(10), t12 timestamp(12),
-t14 timestamp(14));
-Warnings:
-Warning 1287 'TIMESTAMP(2)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-Warning 1287 'TIMESTAMP(4)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-Warning 1287 'TIMESTAMP(6)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-Warning 1287 'TIMESTAMP(8)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-Warning 1287 'TIMESTAMP(10)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-Warning 1287 'TIMESTAMP(12)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-Warning 1287 'TIMESTAMP(14)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-insert t1 values (0,0,0,0,0,0,0),
-("1997-12-31 23:47:59", "1997-12-31 23:47:59", "1997-12-31 23:47:59",
-"1997-12-31 23:47:59", "1997-12-31 23:47:59", "1997-12-31 23:47:59",
-"1997-12-31 23:47:59");
-select * from t1;
-t2 t4 t6 t8 t10 t12 t14
-0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00
-1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59
-select * from t1;
-t2 t4 t6 t8 t10 t12 t14
-0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00
-1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59
-drop table t1;
create table t1 (ix timestamp);
insert into t1 values (0),(20030101010160),(20030101016001),(20030101240101),(20030132010101),(20031301010101),(20031200000000),(20030000000000);
Warnings:
@@ -436,12 +412,12 @@ max(t)
2004-02-01 00:00:00
drop table t1;
set sql_mode='maxdb';
-create table t1 (a timestamp, b timestamp(19));
+create table t1 (a timestamp, b timestamp(5));
show create table t1;
Table Create Table
t1 CREATE TABLE "t1" (
"a" datetime DEFAULT NULL,
- "b" datetime DEFAULT NULL
+ "b" datetime(5) DEFAULT NULL
)
set sql_mode='';
drop table t1;
@@ -611,3 +587,16 @@ Variable_name Value
Handler_read_next 1
DROP TABLE t1, t2;
End of 5.1 tests
+#
+# lp:923429 Crash in decimal_cmp on using UNIX_TIMESTAMP with a wrongly formatted timestamp
+#
+SELECT UNIX_TIMESTAMP('abc') > 0;
+UNIX_TIMESTAMP('abc') > 0
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: 'abc'
+SELECT UNIX_TIMESTAMP('abc');
+UNIX_TIMESTAMP('abc')
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: 'abc'
diff --git a/mysql-test/r/type_timestamp_hires.result b/mysql-test/r/type_timestamp_hires.result
new file mode 100644
index 00000000000..b19542f90e7
--- /dev/null
+++ b/mysql-test/r/type_timestamp_hires.result
@@ -0,0 +1,280 @@
+drop table if exists t1, t2, t3;
+create table t1 (a timestamp(7));
+ERROR 42000: Too big precision 7 specified for 'a'. Maximum is 6.
+create table t1 (a timestamp(3), key(a));
+insert t1 values ('2010-12-11 00:20:03.1234');
+insert t1 values ('2010-12-11 15:47:11.1234');
+insert t1 values (20101211010203.45678);
+insert t1 values (20101211030405.789e0);
+insert t1 values (99991231235959e1);
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+select * from t1;
+a
+0000-00-00 00:00:00.000
+2010-12-11 00:20:03.123
+2010-12-11 01:02:03.456
+2010-12-11 03:04:05.789
+2010-12-11 15:47:11.123
+select truncate(a, 6) from t1;
+truncate(a, 6)
+0.000000
+20101211002003.121094
+20101211010203.457031
+20101211030405.789062
+20101211154711.121094
+select a DIV 1 from t1;
+a DIV 1
+0
+20101211002003
+20101211010203
+20101211030405
+20101211154711
+select group_concat(distinct a) from t1;
+group_concat(distinct a)
+0000-00-00 00:00:00.000,2010-12-11 00:20:03.123,2010-12-11 01:02:03.456,2010-12-11 03:04:05.789,2010-12-11 15:47:11.123
+alter table t1 engine=innodb;
+select * from t1 order by a;
+a
+0000-00-00 00:00:00.000
+2010-12-11 00:20:03.123
+2010-12-11 01:02:03.456
+2010-12-11 03:04:05.789
+2010-12-11 15:47:11.123
+select * from t1 order by a+0;
+a
+0000-00-00 00:00:00.000
+2010-12-11 00:20:03.123
+2010-12-11 01:02:03.456
+2010-12-11 03:04:05.789
+2010-12-11 15:47:11.123
+drop table t1;
+create table t1 (a timestamp(4)) engine=innodb;
+insert t1 values ('2010-12-11 01:02:03.456789');
+select * from t1;
+a
+2010-12-11 01:02:03.4567
+select extract(microsecond from a + interval 100 microsecond) from t1 where a>'2010-11-12 01:02:03.456';
+extract(microsecond from a + interval 100 microsecond)
+456800
+select a from t1 where a>'2010-11-12 01:02:03.456' group by a;
+a
+2010-12-11 01:02:03.4567
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` timestamp(4) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+show columns from t1;
+Field Type Null Key Default Extra
+a timestamp(4) NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
+select table_name, column_name, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra from information_schema.columns where table_name='t1';
+table_name t1
+column_name a
+column_default CURRENT_TIMESTAMP
+is_nullable NO
+data_type timestamp
+character_maximum_length NULL
+character_octet_length NULL
+numeric_precision NULL
+numeric_scale NULL
+datetime_precision 4
+character_set_name NULL
+collation_name NULL
+column_type timestamp(4)
+column_key
+extra on update CURRENT_TIMESTAMP
+select a, a+interval 9876543 microsecond from t1;
+a a+interval 9876543 microsecond
+2010-12-11 01:02:03.4567 2010-12-11 01:02:13.333243
+update t1 set a=a+interval 9876543 microsecond;
+select * from t1;
+a
+2010-12-11 01:02:13.3332
+select a, a + interval 2 year from t1;
+a a + interval 2 year
+2010-12-11 01:02:13.3332 2012-12-11 01:02:13.3332
+insert t1 select a + interval 2 year from t1;
+select * from t1;
+a
+2010-12-11 01:02:13.3332
+2012-12-11 01:02:13.3332
+delete from t1 where a < 20110101;
+select * from t1;
+a
+2012-12-11 01:02:13.3332
+create table t2 select * from t1;
+create table t3 like t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` timestamp(4) NOT NULL DEFAULT '0000-00-00 00:00:00.0000'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` timestamp(4) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2, t3;
+insert t1 values ('2010-12-13 14:15:16.222222');
+select a, a+0, a-1, a*1, a/2 from t1;
+a a+0 a-1 a*1 a/2
+2012-12-11 01:02:13.3332 20121211010213.3332 20121211010212.3332 20121211010213.3332 10060605505106.66660000
+2010-12-13 14:15:16.2222 20101213141516.2222 20101213141515.2222 20101213141516.2222 10050606570758.11110000
+select max(a), min(a), sum(a), avg(a) from t1;
+max(a) min(a) sum(a) avg(a)
+2012-12-11 01:02:13.3332 2010-12-13 14:15:16.2222 40222424151729.5554 20111212075864.77770000
+create table t2 select a, a+0, a-1, a*1, a/2 from t1;
+create table t3 select max(a), min(a), sum(a), avg(a) from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` timestamp(4) NOT NULL DEFAULT '0000-00-00 00:00:00.0000',
+ `a+0` decimal(25,4) NOT NULL DEFAULT '0.0000',
+ `a-1` decimal(25,4) NOT NULL DEFAULT '0.0000',
+ `a*1` decimal(25,4) NOT NULL DEFAULT '0.0000',
+ `a/2` decimal(28,8) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `max(a)` timestamp(4) NULL DEFAULT NULL,
+ `min(a)` timestamp(4) NULL DEFAULT NULL,
+ `sum(a)` decimal(46,4) DEFAULT NULL,
+ `avg(a)` decimal(28,8) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1, t2, t3;
+create table t1 (f0_timestamp timestamp(0), f1_timestamp timestamp(1), f2_timestamp timestamp(2), f3_timestamp timestamp(3), f4_timestamp timestamp(4), f5_timestamp timestamp(5), f6_timestamp timestamp(6));
+insert t1 values ( '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432', '2010-11-12 11:14:17.765432');
+select * from t1;
+f0_timestamp 2010-11-12 11:14:17
+f1_timestamp 2010-11-12 11:14:17.7
+f2_timestamp 2010-11-12 11:14:17.76
+f3_timestamp 2010-11-12 11:14:17.765
+f4_timestamp 2010-11-12 11:14:17.7654
+f5_timestamp 2010-11-12 11:14:17.76543
+f6_timestamp 2010-11-12 11:14:17.765432
+select cast(f0_timestamp as time(4)) time4_f0_timestamp, cast(f1_timestamp as datetime(3)) datetime3_f1_timestamp, cast(f2_timestamp as date) date_f2_timestamp, cast(f4_timestamp as double) double_f3_timestamp, cast(f4_timestamp as decimal(40,5)) decimal5_f4_timestamp, cast(f5_timestamp as signed) bigint_f5_timestamp, cast(f6_timestamp as char(255)) varchar_f6_timestamp from t1;
+time4_f0_timestamp 11:14:17.0000
+datetime3_f1_timestamp 2010-11-12 11:14:17.700
+date_f2_timestamp 2010-11-12
+double_f3_timestamp 20101112111417.8
+decimal5_f4_timestamp 20101112111417.76540
+bigint_f5_timestamp 20101112111417
+varchar_f6_timestamp 2010-11-12 11:14:17.765432
+create table t2 (time4_f0_timestamp time(4), datetime3_f1_timestamp datetime(3), date_f2_timestamp date, double_f3_timestamp double, decimal5_f4_timestamp decimal(40,5), bigint_f5_timestamp bigint, varchar_f6_timestamp varchar(255));
+insert t2 select * from t1;
+Warnings:
+Level Note
+Code 1265
+Message Data truncated for column 'time4_f0_timestamp' at row 1
+Level Note
+Code 1265
+Message Data truncated for column 'date_f2_timestamp' at row 1
+select * from t2;
+time4_f0_timestamp 11:14:17.0000
+datetime3_f1_timestamp 2010-11-12 11:14:17.700
+date_f2_timestamp 2010-11-12
+double_f3_timestamp 20101112111417.8
+decimal5_f4_timestamp 20101112111417.76540
+bigint_f5_timestamp 20101112111417
+varchar_f6_timestamp 2010-11-12 11:14:17.765432
+alter table t1 change f0_timestamp time4_f0_timestamp time(4), change f1_timestamp datetime3_f1_timestamp datetime(3), change f2_timestamp date_f2_timestamp date, change f3_timestamp double_f3_timestamp double, change f4_timestamp decimal5_f4_timestamp decimal(40,5), change f5_timestamp bigint_f5_timestamp bigint, change f6_timestamp varchar_f6_timestamp varchar(255);
+Warnings:
+Level Note
+Code 1265
+Message Data truncated for column 'time4_f0_timestamp' at row 1
+Level Note
+Code 1265
+Message Data truncated for column 'date_f2_timestamp' at row 1
+select * from t1;
+time4_f0_timestamp 11:14:17.0000
+datetime3_f1_timestamp 2010-11-12 11:14:17.700
+date_f2_timestamp 2010-11-12
+double_f3_timestamp 20101112111417.8
+decimal5_f4_timestamp 20101112111417.76540
+bigint_f5_timestamp 20101112111417
+varchar_f6_timestamp 2010-11-12 11:14:17.765432
+alter table t1 modify time4_f0_timestamp timestamp(0), modify datetime3_f1_timestamp timestamp(1), modify date_f2_timestamp timestamp(2), modify double_f3_timestamp timestamp(3), modify decimal5_f4_timestamp timestamp(4), modify bigint_f5_timestamp timestamp(5), modify varchar_f6_timestamp timestamp(6);
+Warnings:
+Level Warning
+Code 1265
+Message Data truncated for column 'time4_f0_timestamp' at row 1
+select * from t1;
+time4_f0_timestamp 0000-00-00 00:00:00
+datetime3_f1_timestamp 2010-11-12 11:14:17.7
+date_f2_timestamp 2010-11-12 00:00:00.00
+double_f3_timestamp 2010-11-12 11:14:17.800
+decimal5_f4_timestamp 2010-11-12 11:14:17.7654
+bigint_f5_timestamp 2010-11-12 11:14:17.00000
+varchar_f6_timestamp 2010-11-12 11:14:17.765432
+delete from t1;
+insert t1 select * from t2;
+Warnings:
+Level Warning
+Code 1265
+Message Data truncated for column 'time4_f0_timestamp' at row 1
+select * from t1;
+time4_f0_timestamp 0000-00-00 00:00:00
+datetime3_f1_timestamp 2010-11-12 11:14:17.7
+date_f2_timestamp 2010-11-12 00:00:00.00
+double_f3_timestamp 2010-11-12 11:14:17.765
+decimal5_f4_timestamp 2010-11-12 11:14:17.7654
+bigint_f5_timestamp 2010-11-12 11:14:17.00000
+varchar_f6_timestamp 2010-11-12 11:14:17.765432
+drop table t1, t2;
+create table t1 (a timestamp(6), b timestamp(6));
+create procedure foo(x timestamp, y timestamp(4)) insert into t1 values (x, y);
+call foo('2010-02-03 4:5:6.789123', '2010-02-03 4:5:6.789123');
+select * from t1;
+a b
+2010-02-03 04:05:06.000000 2010-02-03 04:05:06.789100
+create procedure bar(a int, c timestamp(5))
+begin
+declare b timestamp(4);
+set b = c + interval a microsecond;
+insert t1 values (b, c + interval a microsecond);
+end|
+call bar(1111111, '2011-01-02 3:4:5.123456');
+select * from t1;
+a b
+2010-02-03 04:05:06.000000 2010-02-03 04:05:06.789100
+2011-01-02 03:04:06.234500 2011-01-02 03:04:06.234561
+drop procedure foo;
+drop procedure bar;
+create function xyz(s char(20)) returns timestamp(4)
+return addtime('2010-10-10 10:10:10.101010', s);
+select xyz('1:1:1.010101');
+xyz('1:1:1.010101')
+2010-10-10 11:11:11.1111
+drop function xyz;
+create view v1 as select * from t1 group by a,b;
+select * from v1;
+a b
+2010-02-03 04:05:06.000000 2010-02-03 04:05:06.789100
+2011-01-02 03:04:06.234500 2011-01-02 03:04:06.234561
+show columns from v1;
+Field Type Null Key Default Extra
+a timestamp(6) NO 0000-00-00 00:00:00.000000
+b timestamp(6) NO 0000-00-00 00:00:00.000000
+create table t2 select * from v1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
+ `b` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t2;
+a b
+2010-02-03 04:05:06.000000 2010-02-03 04:05:06.789100
+2011-01-02 03:04:06.234500 2011-01-02 03:04:06.234561
+drop view v1;
+drop table t1, t2;
+set time_zone='+03:00';
+set timestamp=unix_timestamp('2011-01-01 01:01:01') + 0.123456;
+create table t1 (a timestamp(5));
+insert t1 values ();
+select * from t1;
+a
+2011-01-01 01:01:01.12345
+drop table t1;
diff --git a/mysql-test/r/type_year.result b/mysql-test/r/type_year.result
index e00569c93c1..e2c93962e0e 100644
--- a/mysql-test/r/type_year.result
+++ b/mysql-test/r/type_year.result
@@ -357,6 +357,9 @@ c1
SELECT COUNT(*) AS total_rows, MIN(c1) AS min_value, MAX(c1) FROM t1;
total_rows min_value MAX(c1)
3 0 2155
+SELECT COUNT(*) AS total_rows, MIN(c1+0) AS min_value, MAX(c1+0) FROM t1;
+total_rows min_value MAX(c1+0)
+3 0 2155
DROP TABLE t1;
#
# WL#6219: Deprecate and remove YEAR(2) type
@@ -371,3 +374,27 @@ Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Pleas
DROP TABLE t1;
#
End of 5.1 tests
+create function y2k() returns int deterministic return 2000;
+create table t1 (a year(2), b int);
+Warnings:
+Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead
+insert t1 values (0,2000);
+select a from t1 where a=2000;
+a
+00
+select a from t1 where a=1000+1000;
+a
+00
+select a from t1 where a=(select 2000);
+a
+00
+select a from t1 where a=(select 2000 from dual where 1);
+a
+00
+select a from t1 where a=y2k();
+a
+00
+select a from t1 where a=b;
+a
+drop table t1;
+drop function y2k;
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index b6678461c65..13941d3f84d 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -522,7 +522,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 UNION t2 const PRIMARY PRIMARY 4 const 1 100.00
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 (select '1' AS `a`,'1' AS `b` from `test`.`t1` where 1) union (select '1' AS `a`,'10' AS `b` from `test`.`t2` where 1)
+Note 1003 (select 1 AS `a`,1 AS `b` from `test`.`t1` where 1) union (select 1 AS `a`,10 AS `b` from `test`.`t2` where 1)
(select * from t1 where a=5) union (select * from t2 where a=1);
a b
1 10
@@ -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 );
@@ -918,6 +918,8 @@ Slow_queries 1
drop table t1;
create table t1 ( RID int(11) not null default '0', IID int(11) not null default '0', nada varchar(50) not null,NAME varchar(50) not null,PHONE varchar(50) not null) engine=MyISAM;
insert into t1 ( RID,IID,nada,NAME,PHONE) values (1, 1, 'main', 'a', '111'), (2, 1, 'main', 'b', '222'), (3, 1, 'main', 'c', '333'), (4, 1, 'main', 'd', '444'), (5, 1, 'main', 'e', '555'), (6, 2, 'main', 'c', '333'), (7, 2, 'main', 'd', '454'), (8, 2, 'main', 'e', '555'), (9, 2, 'main', 'f', '666'), (10, 2, 'main', 'g', '777');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select A.NAME, A.PHONE, B.NAME, B.PHONE from t1 A left join t1 B on A.NAME = B.NAME and B.IID = 2 where A.IID = 1 and (A.PHONE <> B.PHONE or B.NAME is null) union select A.NAME, A.PHONE, B.NAME, B.PHONE from t1 B left join t1 A on B.NAME = A.NAME and A.IID = 1 where B.IID = 2 and (A.PHONE <> B.PHONE or A.NAME is null);
NAME PHONE NAME PHONE
a 111 NULL NULL
@@ -925,6 +927,7 @@ b 222 NULL NULL
d 444 d 454
NULL NULL f 666
NULL NULL g 777
+SET optimizer_switch=@save_optimizer_switch;
drop table t1;
create table t1 (col1 tinyint unsigned, col2 tinyint unsigned);
insert into t1 values (1,2),(3,4),(5,6),(7,8),(9,10);
@@ -1635,11 +1638,11 @@ 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
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort
+3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #2
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` union select `test`.`t1`.`a` AS `a` from `test`.`t1` order by (select `test`.`t1`.`a` from `test`.`t2` where (`test`.`t2`.`b` = 12))
+Note 1276 Field or reference 'a' of SELECT #3 was resolved in SELECT #-1
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` union select `test`.`t1`.`a` AS `a` from `test`.`t1` order by (select `a` from `test`.`t2` where (`test`.`t2`.`b` = 12))
# Should not crash
SELECT * FROM t1 UNION SELECT * FROM t1
ORDER BY (SELECT a FROM t2 WHERE b = 12);
diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result
index 63baf639487..4062a92901d 100644
--- a/mysql-test/r/update.result
+++ b/mysql-test/r/update.result
@@ -276,6 +276,7 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
flush status;
update t1 set a=9999 order by a limit 1;
@@ -287,6 +288,7 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 2
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 9
flush status;
delete from t1 order by a limit 1;
@@ -297,6 +299,7 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
flush status;
delete from t1 order by a desc limit 1;
@@ -307,7 +310,8 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 1
-Handler_read_rnd_next 9
+Handler_read_rnd_deleted 1
+Handler_read_rnd_next 8
alter table t1 disable keys;
flush status;
delete from t1 order by a limit 1;
@@ -318,7 +322,8 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 1
-Handler_read_rnd_next 9
+Handler_read_rnd_deleted 2
+Handler_read_rnd_next 7
select * from t1;
a b
0 0
@@ -371,6 +376,7 @@ Handler_read_key 1
Handler_read_next 1
Handler_read_prev 0
Handler_read_rnd 1
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
drop table t1, t2;
create table t1(f1 int, `*f2` int);
@@ -408,6 +414,7 @@ Handler_read_key 1
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
SELECT user_id FROM t1 WHERE request_id=999999999999999999999999999999;
user_id
@@ -418,6 +425,7 @@ Handler_read_key 2
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
UPDATE t1 SET user_id=null WHERE request_id=9999999999999;
show status like '%Handler_read%';
@@ -427,6 +435,7 @@ Handler_read_key 3
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
UPDATE t1 SET user_id=null WHERE request_id=999999999999999999999999999999;
show status like '%Handler_read%';
@@ -436,6 +445,7 @@ Handler_read_key 3
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
DROP TABLE t1;
CREATE TABLE t1 (
diff --git a/mysql-test/r/update_ignore_216.result b/mysql-test/r/update_ignore_216.result
new file mode 100644
index 00000000000..4abc1eae06e
--- /dev/null
+++ b/mysql-test/r/update_ignore_216.result
@@ -0,0 +1,9 @@
+CREATE TABLE t1 ( a INT, b CHAR(3) );
+INSERT INTO t1 VALUES ( 1, 'foo' );
+CREATE TABLE t2 ( c CHAR(3), d INT );
+INSERT INTO t2 VALUES ( 'foo', 1 );
+UPDATE IGNORE t1, t2 SET b = 'bar', c = 'bar'
+ WHERE a != ( SELECT 1 UNION SELECT 2 );
+Warnings:
+Warning 1242 Subquery returns more than 1 row
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/user_limits-2.result b/mysql-test/r/user_limits-2.result
new file mode 100644
index 00000000000..d9daec5c089
--- /dev/null
+++ b/mysql-test/r/user_limits-2.result
@@ -0,0 +1,2 @@
+set global max_user_connections=100;
+ERROR HY000: The MySQL server is running with the --max-user-connections=0 option so it cannot execute this statement
diff --git a/mysql-test/r/user_limits.result b/mysql-test/r/user_limits.result
index a94eb4616d1..776a25d55e6 100644
--- a/mysql-test/r/user_limits.result
+++ b/mysql-test/r/user_limits.result
@@ -1,3 +1,4 @@
+set @my_max_user_connections= @@global.max_user_connections;
drop table if exists t1;
create table t1 (i int);
delete from mysql.user where user like 'mysqltest\_%';
@@ -12,9 +13,9 @@ i
select * from t1;
i
select * from t1;
-ERROR 42000: User 'mysqltest_1' has exceeded the 'max_questions' resource (current value: 2)
+ERROR 42000: User 'mysqltest_1' has exceeded the 'max_queries_per_hour' resource (current value: 2)
select * from t1;
-ERROR 42000: User 'mysqltest_1' has exceeded the 'max_questions' resource (current value: 2)
+ERROR 42000: User 'mysqltest_1' has exceeded the 'max_queries_per_hour' resource (current value: 2)
drop user mysqltest_1@localhost;
grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 2;
flush user_resources;
@@ -27,11 +28,11 @@ i
delete from t1;
delete from t1;
delete from t1;
-ERROR 42000: User 'mysqltest_1' has exceeded the 'max_updates' resource (current value: 2)
+ERROR 42000: User 'mysqltest_1' has exceeded the 'max_updates_per_hour' resource (current value: 2)
select * from t1;
i
delete from t1;
-ERROR 42000: User 'mysqltest_1' has exceeded the 'max_updates' resource (current value: 2)
+ERROR 42000: User 'mysqltest_1' has exceeded the 'max_updates_per_hour' resource (current value: 2)
select * from t1;
i
drop user mysqltest_1@localhost;
@@ -65,10 +66,20 @@ select * from t1;
i
connect(localhost,mysqltest_1,,test,MYSQL_PORT,MYSQL_SOCK);
ERROR 42000: User 'mysqltest_1' has exceeded the 'max_user_connections' resource (current value: 3)
+grant usage on *.* to mysqltest_1@localhost with max_user_connections -1;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_USER_CONNECTIONS -1
+flush user_resources;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_USER_CONNECTIONS -1
+connect(localhost,mysqltest_1,,test,MYSQL_PORT,MYSQL_SOCK);
+ERROR 42000: User 'mysqltest_1' has exceeded the 'max_user_connections' resource (current value: -1)
drop user mysqltest_1@localhost;
select @@session.max_user_connections, @@global.max_user_connections;
@@session.max_user_connections @@global.max_user_connections
-0 0
+1000 1000
set session max_user_connections= 2;
ERROR HY000: Variable 'max_user_connections' is a GLOBAL variable and should be set with SET GLOBAL
set global max_user_connections= 2;
@@ -92,5 +103,21 @@ select @@session.max_user_connections, @@global.max_user_connections;
connect(localhost,mysqltest_1,,test,MYSQL_PORT,MYSQL_SOCK);
ERROR 42000: User 'mysqltest_1' has exceeded the 'max_user_connections' resource (current value: 3)
set global max_user_connections= 0;
+grant usage on *.* to mysqltest_1@localhost with max_user_connections 0;
+set global max_user_connections=-1;
+show variables like "max_user_user_connections";
+Variable_name Value
+select @@max_user_connections;
+@@max_user_connections
+-1
+select @@global.max_user_connections;
+@@global.max_user_connections
+-1
+connect(localhost,mysqltest_1,,test,MYSQL_PORT,MYSQL_SOCK);
+ERROR 42000: User mysqltest_1 already has more than 'max_user_connections' active connections
+set global max_user_connections=1;
+connect(localhost,mysqltest_1,,test,MYSQL_PORT,MYSQL_SOCK);
+ERROR 42000: User mysqltest_1 already has more than 'max_user_connections' active connections
drop user mysqltest_1@localhost;
drop table t1;
+set global max_user_connections= @my_max_user_connections;
diff --git a/mysql-test/r/varbinary.result b/mysql-test/r/varbinary.result
index b623ea1d86e..545044fc520 100644
--- a/mysql-test/r/varbinary.result
+++ b/mysql-test/r/varbinary.result
@@ -15,7 +15,7 @@ explain extended select * from t1 where UNIQ=0x38afba1d73e6a18a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 const UNIQ UNIQ 8 const 1 100.00
Warnings:
-Note 1003 select '00000001' AS `ID`,'004084688022709641610' AS `UNIQ` from `test`.`t1` where 1
+Note 1003 select 00000001 AS `ID`,004084688022709641610 AS `UNIQ` from `test`.`t1` where 1
drop table t1;
select x'hello';
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 'x'hello'' at line 1
diff --git a/mysql-test/r/variables-big.result b/mysql-test/r/variables-big.result
index 71b32393d82..793363fc7c1 100644
--- a/mysql-test/r/variables-big.result
+++ b/mysql-test/r/variables-big.result
@@ -1,20 +1,20 @@
SET SESSION transaction_prealloc_size=1024*1024*1024*1;
SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
+Id User Host db Command Time State Info Progress
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST 0.000
SET SESSION transaction_prealloc_size=1024*1024*1024*2;
SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
+Id User Host db Command Time State Info Progress
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST 0.000
SET SESSION transaction_prealloc_size=1024*1024*1024*3;
SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
+Id User Host db Command Time State Info Progress
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST 0.000
SET SESSION transaction_prealloc_size=1024*1024*1024*4;
SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
+Id User Host db Command Time State Info Progress
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST 0.000
SET SESSION transaction_prealloc_size=1024*1024*1024*5;
SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
+Id User Host db Command Time State Info Progress
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST 0.000
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index 7ea198f5368..8b4b5c32f6f 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -14,6 +14,7 @@ set @my_max_delayed_threads =@@global.max_delayed_threads;
set @my_max_heap_table_size =@@global.max_heap_table_size;
set @my_max_insert_delayed_threads=@@global.max_insert_delayed_threads;
set @my_max_join_size =@@global.max_join_size;
+set @my_max_user_connections =@@global.max_user_connections;
set @my_myisam_data_pointer_size =@@global.myisam_data_pointer_size;
set @my_myisam_max_sort_file_size =@@global.myisam_max_sort_file_size;
set @my_net_buffer_length =@@global.net_buffer_length;
@@ -974,6 +975,7 @@ tmpdir #
select * from information_schema.session_variables where variable_name like 'tmpdir';
VARIABLE_NAME VARIABLE_VALUE
TMPDIR #
+set sort_buffer_size=1024*8;
select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key;
@@ssl_ca @@ssl_capath @@ssl_cert @@ssl_cipher @@ssl_key
# # # # #
@@ -1048,7 +1050,7 @@ set global max_delayed_threads =@my_max_delayed_threads;
set global max_heap_table_size =@my_max_heap_table_size;
set global max_insert_delayed_threads=@my_max_insert_delayed_threads;
set global max_join_size =@my_max_join_size;
-set global max_user_connections =default;
+set global max_user_connections =@my_max_user_connections;
set global max_write_lock_count =default;
set global myisam_data_pointer_size =@my_myisam_data_pointer_size;
set global myisam_max_sort_file_size =@my_myisam_max_sort_file_size;
@@ -1536,18 +1538,49 @@ ERROR HY000: Cannot drop default keycache
SET @@global.key_cache_block_size=0;
Warnings:
Warning 1292 Truncated incorrect key_cache_block_size value: '0'
+SET @@global.max_binlog_cache_size=DEFAULT;
+SET @@global.max_join_size=DEFAULT;
+SET @@global.key_buffer_size=@kbs;
+SET @@global.key_cache_block_size=@kcbs;
select @@max_long_data_size;
@@max_long_data_size
1048576
#
-# Bug#11766424 59527: DECIMAL_BIN_SIZE: ASSERTION `SCALE >= 0 && PRECISION > 0 && SCALE <= PRE
+# Bug#11766424 59527:
+# Assert in DECIMAL_BIN_SIZE:
+# `SCALE >= 0 && PRECISION > 0 && SCALE <= PRE
+# This test also exposed a bug with sql_buffer_result
#
CREATE TABLE t1(f1 DECIMAL(1,1) UNSIGNED);
INSERT INTO t1 VALUES (0.2),(0.1);
-SELECT 1 FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE @a=f1);
+set @a=NULL;
+set sql_buffer_result=0;
+SELECT 1 as 'one' FROM t1 GROUP BY @a:= ROUND(f1);
+one
+1
+explain SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0);
+one
+1
+SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE @a=f1);
+one
1
+set sql_buffer_result=1;
+explain SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using temporary
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0);
+one
+1
+SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE @a=f1);
+one
1
DROP TABLE t1;
+set sql_buffer_result=0;
CREATE TABLE t1 AS SELECT @a:= CAST(1 AS UNSIGNED) AS a;
SHOW CREATE TABLE t1;
Table Create Table
@@ -1555,8 +1588,4 @@ t1 CREATE TABLE `t1` (
`a` int(1) unsigned NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
-SET @@global.max_binlog_cache_size=DEFAULT;
-SET @@global.max_join_size=DEFAULT;
-SET @@global.key_buffer_size=@kbs;
-SET @@global.key_cache_block_size=@kcbs;
End of 5.1 tests
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 0ff06ac09d7..ee6c235d09e 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -2,6 +2,8 @@ drop table if exists t1,t2,t3,t4,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
drop view if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6;
drop database if exists mysqltest;
use test;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
create view v1 (c,d) as select a,b from t1;
ERROR 42S02: Table 'test.t1' doesn't exist
create temporary table t1 (a int, b int);
@@ -117,7 +119,7 @@ c
12
explain extended select c from v5;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY <derived3> ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE <derived3> ALL NULL NULL NULL NULL 5 100.00
3 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00
Warnings:
Note 1003 select (`v2`.`c` + 1) AS `c` from `test`.`v2`
@@ -237,7 +239,7 @@ a
3
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
select * from t1;
a
@@ -1417,10 +1419,10 @@ 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
+Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on((`test`.`t2`.`a` = `test`.`t3`.`a`))) on((`test`.`t1`.`a` = `test`.`t3`.`a`)) where 1
create view v1 (a) as select a from t1;
create view v2 (a) as select a from t2;
create view v4 (a,b) as select v1.a as a, v2.a as b from v1 left join v2 on (v1.a=v2.a);
@@ -1432,10 +1434,10 @@ 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
+Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join (`test`.`t2`) on((`test`.`t2`.`a` = `test`.`t3`.`a`))) on((`test`.`t1`.`a` = `test`.`t3`.`a`)) where 1
prepare stmt1 from "select * from t3 left join v4 on (t3.a = v4.a);";
execute stmt1;
a a b
@@ -2344,15 +2346,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);
@@ -3135,17 +3137,18 @@ Warnings:
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` order by `test`.`t1`.`f2`
select * from v1 order by f1;
f1 f2
-1 1
1 2
1 3
+1 1
+2 3
2 1
2 2
-2 3
explain extended select * from v1 order by f1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 100.00 Using filesort
Warnings:
-Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` order by `test`.`t1`.`f1`,`test`.`t1`.`f2`
+Note 1926 View 'test'.'v1' ORDER BY clause ignored because there is other ORDER BY clause already.
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` order by `test`.`t1`.`f1`
drop view v1;
drop table t1;
CREATE TABLE t1 (
@@ -3983,3 +3986,672 @@ DROP TABLE t1,t2;
# -----------------------------------------------------------------
# -- End of 5.2 tests.
# -----------------------------------------------------------------
+#
+# Bug #59696 Optimizer does not use equalities for conditions over view
+#
+CREATE TABLE t1 (a int NOT NULL);
+INSERT INTO t1 VALUES
+(9), (2), (8), (1), (3), (4), (2), (5),
+(9), (2), (8), (1), (3), (4), (2), (5);
+CREATE TABLE t2 (pk int PRIMARY KEY, c int NOT NULL);
+INSERT INTO t2 VALUES
+(9,90), (16, 160), (11,110), (1,10), (18,180), (2,20),
+(14,140), (15, 150), (12,120), (3,30), (17,170), (19,190);
+EXPLAIN EXTENDED
+SELECT t1.a,t2.c FROM t1,t2 WHERE t2.pk = t1.a AND t2.pk > 8;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Using where
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`pk` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 8))
+FLUSH STATUS;
+SELECT t1.a,t2.c FROM t1,t2 WHERE t2.pk = t1.a AND t2.pk > 8;
+a c
+9 90
+9 90
+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_deleted 0
+Handler_read_rnd_next 17
+CREATE VIEW v AS SELECT * FROM t2;
+EXPLAIN EXTENDED
+SELECT t1.a,v.c FROM t1,v WHERE v.pk = t1.a AND v.pk > 8;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Using where
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`pk` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 8))
+FLUSH STATUS;
+SELECT t1.a,v.c FROM t1,v WHERE v.pk = t1.a AND v.pk > 8;
+a c
+9 90
+9 90
+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_deleted 0
+Handler_read_rnd_next 17
+DROP VIEW v;
+DROP TABLE t1, t2;
+#
+# Bug#702403: crash with multiple equalities and a view
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (10);
+CREATE TABLE t2 (pk int PRIMARY KEY, b int, INDEX idx (b));
+INSERT INTO t2 VALUES (1,2), (3,4);
+CREATE TABLE t3 (pk int PRIMARY KEY, b int, INDEX idx (b));
+INSERT INTO t3 VALUES (1,2), (3,4);
+CREATE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN
+SELECT * FROM v1, t2, t3
+WHERE t3.pk = v1.a AND t2.b = 1 AND t2.b = t3.pk AND v1.a BETWEEN 2 AND 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+SELECT * FROM v1, t2, t3
+WHERE t3.pk = v1.a AND t2.b = 1 AND t2.b = t3.pk AND v1.a BETWEEN 2 AND 5;
+a pk b pk b
+DROP VIEW v1;
+DROP TABLE t1, t2, t3;
+#
+# Bug#717577: substitution for best field in a query over a view and
+# with OR in the WHERE condition
+#
+create table t1 (a int, b int);
+insert into t1 values (2,4), (1,3);
+create table t2 (c int);
+insert into t2 values (6), (4), (1), (3), (8), (3), (4), (2);
+select * from t1,t2 where t2.c=t1.a and t2.c < 3 or t2.c=t1.b and t2.c >=4;
+a b c
+2 4 4
+1 3 1
+2 4 4
+2 4 2
+explain extended
+select * from t1,t2 where t2.c=t1.a and t2.c < 3 or t2.c=t1.b and t2.c >=4;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where (((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`a` < 3)) or ((`test`.`t2`.`c` = `test`.`t1`.`b`) and (`test`.`t1`.`b` >= 4)))
+create view v1 as select * from t2;
+select * from t1,v1 where v1.c=t1.a and v1.c < 3 or v1.c=t1.b and v1.c >=4;
+a b c
+2 4 4
+1 3 1
+2 4 4
+2 4 2
+explain extended
+select * from t1,v1 where v1.c=t1.a and v1.c < 3 or v1.c=t1.b and v1.c >=4;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where (((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`a` < 3)) or ((`test`.`t2`.`c` = `test`.`t1`.`b`) and (`test`.`t1`.`b` >= 4)))
+create view v2 as select * from v1;
+select * from t1,v2 where v2.c=t1.a and v2.c < 3 or v2.c=t1.b and v2.c >=4;
+a b c
+2 4 4
+1 3 1
+2 4 4
+2 4 2
+explain extended
+select * from t1,v2 where v2.c=t1.a and v2.c < 3 or v2.c=t1.b and v2.c >=4;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where (((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`a` < 3)) or ((`test`.`t2`.`c` = `test`.`t1`.`b`) and (`test`.`t1`.`b` >= 4)))
+create view v3 as select * from t1;
+select * from v3,v2 where v2.c=v3.a and v2.c < 3 or v2.c=v3.b and v2.c >=4;
+a b c
+2 4 4
+1 3 1
+2 4 4
+2 4 2
+explain extended
+select * from v3,v2 where v2.c=v3.a and v2.c < 3 or v2.c=v3.b and v2.c >=4;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where (((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`a` < 3)) or ((`test`.`t2`.`c` = `test`.`t1`.`b`) and (`test`.`t1`.`b` >= 4)))
+drop view v1,v2,v3;
+drop table t1,t2;
+#
+# Bug#724942: substitution of the constant into a view field
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2), (9), (9), (6), (5), (4), (7);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM v1 WHERE a > -1 OR a > 6 AND a = 3;
+a
+2
+9
+9
+6
+5
+4
+7
+EXPLAIN EXTENDED
+SELECT * FROM v1 WHERE a > -1 OR a > 6 AND a = 3;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 7 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > -(1))
+SELECT * FROM v1 WHERE a > -1 OR a AND a = 0;
+a
+2
+9
+9
+6
+5
+4
+7
+EXPLAIN EXTENDED
+SELECT * FROM v1 WHERE a > -1 OR a AND a = 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 7 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > -(1))
+CREATE VIEW v2 AS SELECT * FROM v1;
+SELECT * FROM v2 WHERE a > -1 OR a AND a = 0;
+a
+2
+9
+9
+6
+5
+4
+7
+EXPLAIN EXTENDED
+SELECT * FROM v2 WHERE a > -1 OR a AND a = 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 7 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > -(1))
+DROP VIEW v1,v2;
+DROP TABLE t1;
+CREATE TABLE t1 (a varchar(10), KEY (a)) ;
+INSERT INTO t1 VALUES
+('DD'), ('ZZ'), ('ZZ'), ('KK'), ('FF'), ('HH'),('MM');
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM v1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV';
+a
+KK
+MM
+ZZ
+ZZ
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'VV'
+EXPLAIN EXTENDED
+SELECT * FROM v1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 range a a 13 NULL 4 100.00 Using where; Using index
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'VV'
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > 'JJ')
+SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV';
+a
+KK
+MM
+ZZ
+ZZ
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'VV'
+EXPLAIN EXTENDED
+SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 range a a 13 NULL 4 100.00 Using where; Using index
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'VV'
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > 'JJ')
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# Bug#777745: crash with equality propagation
+# over view fields
+#
+CREATE TABLE t1 (a int NOT NULL ) ;
+INSERT INTO t1 VALUES (2), (1);
+CREATE TABLE t2 (a int NOT NULL , b int NOT NULL) ;
+INSERT INTO t2 VALUES (2,20),(2,30);
+CREATE VIEW v2 AS SELECT * FROM t2;
+EXPLAIN
+SELECT * FROM t1,v2
+WHERE v2.a = t1.a AND v2.a = 2 AND v2.a IS NULL AND t1.a != 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+SELECT * FROM t1,v2
+WHERE v2.a = t1.a AND v2.a = 2 AND v2.a IS NULL AND t1.a != 0;
+a a b
+EXPLAIN
+SELECT * FROM t1,v2
+WHERE v2.a = t1.a AND v2.a = 2 AND v2.a+1 > 2 AND t1.a != 0;
+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 2 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t1,v2
+WHERE v2.a = t1.a AND v2.a = 2 AND v2.a+1 > 2 AND t1.a != 0;
+a a b
+2 2 20
+2 2 30
+DROP VIEW v2;
+DROP TABLE t1,t2;
+#
+# Bug#794038: crash with INSERT/UPDATE/DELETE
+# over a non-updatable view
+#
+CREATE TABLE t1 (a int);
+CREATE ALGORITHM = TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+CREATE ALGORITHM = MERGE VIEW v2 AS SELECT * FROM v1;
+CREATE ALGORITHM = TEMPTABLE VIEW v3 AS SELECT * FROM v2;
+INSERT INTO v3 VALUES (1);
+ERROR HY000: The target table v3 of the INSERT is not insertable-into
+UPDATE v3 SET a=0;
+ERROR HY000: The target table v3 of the UPDATE is not updatable
+DELETE FROM v3;
+ERROR HY000: The target table v3 of the DELETE is not updatable
+DROP VIEW v1,v2,v3;
+DROP TABLE t1;
+#
+# Bug#798621: crash with a view string field equal
+# to a constant
+#
+CREATE TABLE t1 (a varchar(32), b int) ;
+INSERT INTO t1 VALUES ('j', NULL), ('c', 8), ('c', 1);
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE TABLE t2 (a varchar(32)) ;
+INSERT INTO t2 VALUES ('j'), ('c');
+SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a
+WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b;
+a b a
+c 1 c
+EXPLAIN EXTENDED
+SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a
+WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`a` = `test`.`t1`.`a`)) where ((`test`.`t1`.`b` = 1) or ((`test`.`t1`.`a` = 'a') and (length(`test`.`t1`.`a`) >= `test`.`t1`.`b`)))
+DROP VIEW v1;
+DROP TABLE t1,t2;
+# Bug#798625: duplicate of the previous one, but without crash
+CREATE TABLE t1 (f1 int NOT NULL, f2 int, f3 int, f4 varchar(32), f5 int) ;
+INSERT INTO t1 VALUES (20,5,2,'r', 0);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT v1.f4 FROM v1
+WHERE f1<>0 OR f2<>0 AND f4='v' AND (f2<>0 OR f3<>0 AND f5<>0 OR f4 LIKE '%b%');
+f4
+r
+EXPLAIN EXTENDED
+SELECT v1.f4 FROM v1
+WHERE f1<>0 OR f2<>0 AND f4='v' AND (f2<>0 OR f3<>0 AND f5<>0 OR f4 LIKE '%b%');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select 'r' AS `f4` from `test`.`t1` where ((20 <> 0) or 0)
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# Bug#798576: abort on a GROUP BY query over a view with left join
+# that can be converted to inner join
+#
+CREATE TABLE t1 (a int NOT NULL , b int NOT NULL) ;
+INSERT INTO t1 VALUES (214,0), (6,6), (6,0), (7,0);
+CREATE TABLE t2 (b int) ;
+INSERT INTO t2 VALUES (88), (78), (6);
+CREATE ALGORITHM=MERGE VIEW v1 AS
+SELECT t1.a, t2.b FROM (t2 LEFT JOIN t1 ON t2.b > t1.a) WHERE t1.b <= 0;
+SELECT * FROM v1;
+a b
+6 88
+6 78
+7 88
+7 78
+SELECT a, MIN(b) FROM v1 GROUP BY a;
+a MIN(b)
+6 78
+7 78
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #793386: unexpected 'Duplicate column name ''' error
+# at the second execution of a PS using a view
+#
+CREATE TABLE t1 (f1 int, f2 int, f3 int, f4 int);
+CREATE VIEW v1 AS
+SELECT t.f1, t.f2, s.f3, s.f4 FROM t1 t, t1 s
+WHERE t.f4 >= s.f2 AND s.f3 < 0;
+PREPARE stmt1 FROM
+"SELECT s.f1 AS f1, s.f2 AS f2, s.f3 AS f3, t.f4 AS f4
+ FROM v1 AS t LEFT JOIN v1 AS s ON t.f4=s.f4 WHERE t.f2 <> 1225";
+EXECUTE stmt1;
+f1 f2 f3 f4
+EXECUTE stmt1;
+f1 f2 f3 f4
+DEALLOCATE PREPARE stmt1;
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# LP BUG#806071 (2 views with ORDER BY)
+#
+CREATE TABLE t1 (f1 int);
+INSERT INTO t1 VALUES (1),(1);
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT f1 FROM t1;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT f1 FROM v1 ORDER BY f1;
+SELECT * FROM v2 AS a1, v2 AS a2;
+f1 f1
+1 1
+1 1
+1 1
+1 1
+EXPLAIN EXTENDED SELECT * FROM v2 AS a1, v2 AS a2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE <derived3> ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 SIMPLE <derived5> ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
+5 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00
+3 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1926 View 'test'.'v2' ORDER BY clause ignored because there is other ORDER BY clause already.
+Note 1003 select `v1`.`f1` AS `f1`,`v1`.`f1` AS `f1` from `test`.`v1` join `test`.`v1` order by `v1`.`f1`
+DROP VIEW v1, v2;
+DROP TABLE t1;
+#
+# LP bug #823189: dependent subquery with RIGHT JOIN
+# referencing view in WHERE
+#
+CREATE TABLE t1 (a varchar(32));
+INSERT INTO t1 VALUES ('y'), ('w');
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (10);
+CREATE TABLE t3 (a varchar(32), b int);
+CREATE TABLE t4 (a varchar(32));
+INSERT INTO t4 VALUES ('y'), ('w');
+CREATE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN EXTENDED
+SELECT * FROM t1, t2
+WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+WHERE t4.a >= t1.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 0 0.00 const row not found
+2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`a` AS `a`,10 AS `a` from `test`.`t1` join `test`.`t2` where (not(<expr_cache><10,`test`.`t1`.`a`>(<in_optimizer>(10,<exists>(select NULL from `test`.`t4` left join `test`.`t3` on(multiple equal(NULL, `test`.`t4`.`a`)) where ((`test`.`t4`.`a` >= `test`.`t1`.`a`) and trigcond(((<cache>(10) = NULL) or isnull(NULL)))) having trigcond(<is_not_null_test>(NULL)))))))
+SELECT * FROM t1, t2
+WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+WHERE t4.a >= t1.a);
+a a
+EXPLAIN EXTENDED
+SELECT * FROM v1, t2
+WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+WHERE t4.a >= v1.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 0 0.00 const row not found
+2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'v1.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`a` AS `a`,10 AS `a` from `test`.`t1` join `test`.`t2` where (not(<expr_cache><10,`test`.`t1`.`a`>(<in_optimizer>(10,<exists>(select NULL from `test`.`t4` left join `test`.`t3` on(multiple equal(NULL, `test`.`t4`.`a`)) where ((`test`.`t4`.`a` >= `test`.`t1`.`a`) and trigcond(((<cache>(10) = NULL) or isnull(NULL)))) having trigcond(<is_not_null_test>(NULL)))))))
+SELECT * FROM v1, t2
+WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+WHERE t4.a >= v1.a);
+a a
+DROP VIEW v1;
+DROP TABLE t1,t2,t3,t4;
+#
+# LP bug #823237: dependent subquery with LEFT JOIN
+# referencing view in WHERE
+# (duplicate of LP bug #823189)
+#
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 ( b int, d int, e int);
+INSERT INTO t2 VALUES (7,8,0);
+CREATE TABLE t3 ( c int);
+INSERT INTO t3 VALUES (0);
+CREATE TABLE t4 (a int, b int, c int);
+INSERT INTO t4 VALUES (93,1,0), (95,NULL,0);
+CREATE VIEW v4 AS SELECT * FROM t4;
+EXPLAIN EXTENDED
+SELECT * FROM t3 , t4
+WHERE t4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d )
+WHERE t2.b > t4.b);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1276 Field or reference 'test.t4.b' of SELECT #2 was resolved in SELECT #1
+Note 1003 select 0 AS `c`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t3` join `test`.`t4` where (`test`.`t4`.`c` <= <expr_cache><`test`.`t4`.`b`>((select 0 from `test`.`t2` left join `test`.`t1` on(0) where (7 > `test`.`t4`.`b`))))
+SELECT * FROM t3 , t4
+WHERE t4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d )
+WHERE t2.b > t4.b);
+c a b c
+0 93 1 0
+EXPLAIN EXTENDED
+SELECT * FROM t3, v4
+WHERE v4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d )
+WHERE t2.b > v4.b);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1276 Field or reference 'v4.b' of SELECT #2 was resolved in SELECT #1
+Note 1003 select 0 AS `c`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t3` join `test`.`t4` where (`test`.`t4`.`c` <= <expr_cache><`test`.`t4`.`b`>((select 0 from `test`.`t2` left join `test`.`t1` on(0) where (7 > `test`.`t4`.`b`))))
+SELECT * FROM t3, v4
+WHERE v4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d )
+WHERE t2.b > v4.b);
+c a b c
+0 93 1 0
+DROP VIEW v4;
+DROP TABLE t1,t2,t3,t4;
+#
+# BUG#833600: Wrong result with view + outer join + uncorrelated subquery (non-semijoin)
+#
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (0,0),(0,0);
+CREATE TABLE t2 ( a int, b int );
+INSERT IGNORE INTO t2 VALUES (1,0),(1,0);
+CREATE TABLE t3 ( b int );
+INSERT IGNORE INTO t3 VALUES (0),(0);
+CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2;
+SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM t3 ) AND t1.b IS NULL ;
+a b a b
+NULL NULL 1 0
+NULL NULL 1 0
+SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM t3 ) AND t1.b IS NULL ;
+a b a b
+NULL NULL 1 0
+NULL NULL 1 0
+DROP VIEW v2;
+DROP TABLE t1, t2, t3;
+#
+# BUG#915222: Valgrind complains or crashes with INSERT SELECT
+# within a trigger that uses a view
+#
+CREATE TABLE t1 (a char(1));
+CREATE TABLE t2 (d int, e char(1));
+INSERT INTO t2 VALUES (13,'z');
+CREATE TRIGGER tr AFTER UPDATE ON t2
+FOR EACH ROW
+REPLACE INTO t3
+SELECT f, a AS alias FROM t3, v;
+CREATE TABLE t3 (f int, g char(8));
+CREATE VIEW v AS SELECT a, e FROM t2, t1;
+UPDATE t2 SET d=7;
+UPDATE t2 SET d=7;
+UPDATE t2 SET d=7;
+UPDATE t2 SET d=7;
+DROP TRIGGER tr;
+DROP VIEW v;
+DROP TABLE t1,t2,t3;
+#
+# BUG#972943: Assertion failure with INSERT SELECT within a trigger
+# that uses derived table and materialized view
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (1,0), (2,8);
+CREATE ALGORITHM=TEMPTABLE VIEW v1
+AS SELECT * FROM t1;
+CREATE TABLE t2 (c int);
+CREATE TABLE t3 (d int, e int);
+CREATE TRIGGER tr BEFORE INSERT ON t2 FOR EACH ROW
+INSERT INTO t3
+SELECT t1.*
+FROM (SELECT * FROM t1 WHERE b IN (SELECT b FROM v1)) AS alias1, t1
+WHERE t1.a = 3 OR t1.a > 5;
+INSERT INTO t2 VALUES (1);
+DROP TRIGGER tr;
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug#1007622 Server crashes in handler::increment_statistics on
+# inserting into a view over a view
+#
+CREATE TABLE t1 (a INT);
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT a1.* FROM t1 AS a1, t1 AS a2;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM v1;
+INSERT INTO v2 (a) VALUES (1) ;
+select * from t1;
+a
+1
+drop view v2,v1;
+drop table t1;
+#
+# MDEV-486 LP BUG#1010116 Incorrect query results in
+# view and derived tables
+#
+SELECT
+`Derived1`.`id`,
+`Derived2`.`Val1`
+FROM (select 30631 as `id`) AS `Derived1` LEFT OUTER JOIN (SELECT
+2 as `id`,
+1 AS `Val1`
+FROM (select 30631 as `id`) AS `Derived3`) AS `Derived2` ON `Derived1`.`id` = `Derived2`.`id`;
+id Val1
+30631 NULL
+create table t1 ( id int );
+insert into t1 values (30631);
+create table t2 ( id int );
+insert into t2 values (30631);
+create algorithm=MERGE view v2 as select 2 as id, 1 as val1 from t2;
+select t1.*, v2.* from t1 left join v2 on t1.id = v2.id;
+id id val1
+30631 NULL NULL
+drop view v2;
+drop table t1,t2;
+create table t1 ( id int );
+insert into t1 values (30631);
+create table t2 ( id int );
+insert into t2 values (30631);
+create algorithm=MERGE view v2 as select 2 as id, id is null as bbb, id as iddqd, 1 as val1 from t2;
+select t1.*, v2.* from t1 left join v2 on t1.id = v2.id;
+id id bbb iddqd val1
+30631 NULL NULL NULL NULL
+drop view v2;
+drop table t1,t2;
+#
+# MDEV-3914: Wrong result (NULLs instead of real values)
+# with INNER and RIGHT JOIN in a FROM subquery, derived_merge=on
+# (fix of above MDEV-486 fix)
+#
+SET @save_optimizer_switch_MDEV_3914=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on';
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (c INT) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (5),(6);
+SELECT * FROM ( SELECT c FROM ( t1 INNER JOIN t2 ) RIGHT JOIN t3 ON a = c ) AS alias;
+c
+5
+6
+SET optimizer_switch = 'derived_merge=off';
+SELECT * FROM ( SELECT c FROM ( t1 INNER JOIN t2 ) RIGHT JOIN t3 ON a = c ) AS alias;
+c
+5
+6
+SET optimizer_switch=@save_optimizer_switch_MDEV_3914;
+drop table t1,t2,t3;
+#
+# MDEV-589 (LP BUG#1007647) :
+# Assertion `vcol_table == 0 || vcol_table == table' failed in
+# fill_record(THD*, List<Item>&, List<Item>&, bool)
+#
+CREATE TABLE t1 (f1 INT, f2 INT);
+CREATE TABLE t2 (f1 INT, f2 INT);
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT a1.f1, a2.f2 FROM t1 AS a1, t1 AS a2;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM v1;
+CREATE ALGORITHM=MERGE VIEW v3 AS SELECT a1.f1, a2.f2 FROM t1 AS a1, t2 AS a2;
+CREATE ALGORITHM=MERGE VIEW v4 AS SELECT * FROM v3;
+INSERT INTO v3 (f1, f2) VALUES (1, 2);
+ERROR HY000: Can not modify more than one base table through a join view 'test.v3'
+INSERT INTO v1 (f1, f2) VALUES (1, 2);
+ERROR HY000: Can not modify more than one base table through a join view 'test.v1'
+INSERT INTO v4 (f1, f2) VALUES (1, 2);
+ERROR HY000: Can not modify more than one base table through a join view 'test.v4'
+INSERT INTO v2 (f1, f2) VALUES (1, 2);
+ERROR HY000: Can not modify more than one base table through a join view 'test.v2'
+drop view v4,v3,v2,v1;
+drop table t1,t2;
+#
+# MDEV-3799 fix of above bugfix (MDEV-589)
+# Wrong result (NULLs instead of real values) with RIGHT JOIN
+# in a FROM subquery and derived_merge=on
+#
+CREATE TABLE t1 (f1 INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4),(6);
+CREATE TABLE t2 (f2 INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (7),(8);
+SELECT * FROM (
+SELECT * FROM t1 RIGHT JOIN t2 ON f1 = f2
+) AS alias;
+f1 f2
+NULL 7
+NULL 8
+SELECT * FROM (
+SELECT * FROM t2 LEFT JOIN t1 ON f1 = f2
+) AS alias;
+f2 f1
+7 NULL
+8 NULL
+drop tables t1,t2;
+#
+# MDEV-3876 Wrong result (extra rows) with ALL subquery
+# from a MERGE view (duplicate of MDEV-3873)
+#
+CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1),(3);
+CREATE OR REPLACE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t2;
+SELECT a FROM t1 AS alias
+WHERE a >= ALL (
+SELECT b FROM t1 LEFT JOIN v1 ON (a = b)
+WHERE a = alias.a );
+a
+1
+drop view v1;
+drop table t1,t2;
+# -----------------------------------------------------------------
+# -- End of 5.3 tests.
+# -----------------------------------------------------------------
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result
index 95a969d3791..4195e90c128 100644
--- a/mysql-test/r/warnings.result
+++ b/mysql-test/r/warnings.result
@@ -324,7 +324,7 @@ select CAST(a AS DECIMAL(13,5)) FROM (SELECT '' as a) t;
CAST(a AS DECIMAL(13,5))
0.00000
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ''
create table t1 (a integer unsigned);
insert into t1 values (1),(-1),(0),(-2);
diff --git a/mysql-test/r/windows.result b/mysql-test/r/windows.result
index d0cdd858d4a..dc624a07f4f 100644
--- a/mysql-test/r/windows.result
+++ b/mysql-test/r/windows.result
@@ -16,7 +16,7 @@ CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (1,1);
EXPLAIN SELECT * FROM t1 WHERE b = (SELECT max(2));
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+1 PRIMARY t1 system NULL NULL NULL NULL 1
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
DROP TABLE t1;
CREATE DATABASE `TESTDB`;
diff --git a/mysql-test/r/xa_binlog.result b/mysql-test/r/xa_binlog.result
new file mode 100644
index 00000000000..3ce64953902
--- /dev/null
+++ b/mysql-test/r/xa_binlog.result
@@ -0,0 +1,32 @@
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+SET binlog_format= mixed;
+RESET MASTER;
+XA START 'xatest';
+INSERT INTO t1 VALUES (1);
+XA END 'xatest';
+XA PREPARE 'xatest';
+XA COMMIT 'xatest';
+XA START 'xatest';
+INSERT INTO t1 VALUES (2);
+XA END 'xatest';
+XA COMMIT 'xatest' ONE PHASE;
+BEGIN;
+INSERT INTO t1 VALUES (3);
+COMMIT;
+SELECT * FROM t1 ORDER BY a;
+a
+1
+2
+3
+SHOW BINLOG EVENTS LIMIT 1,9;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # BEGIN
+master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES (1)
+master-bin.000001 # Query 1 # COMMIT
+master-bin.000001 # Query 1 # BEGIN
+master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES (2)
+master-bin.000001 # Query 1 # COMMIT
+master-bin.000001 # Query 1 # BEGIN
+master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES (3)
+master-bin.000001 # Xid 1 # COMMIT /* xid=XX */
+DROP TABLE t1;
diff --git a/mysql-test/std_data/t917689.ARZ b/mysql-test/std_data/t917689.ARZ
new file mode 100644
index 00000000000..4770ca0c257
--- /dev/null
+++ b/mysql-test/std_data/t917689.ARZ
Binary files differ
diff --git a/mysql-test/std_data/words3.dat b/mysql-test/std_data/words3.dat
new file mode 100644
index 00000000000..dca0819721d
--- /dev/null
+++ b/mysql-test/std_data/words3.dat
@@ -0,0 +1,66 @@
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+abase
+abased
+abasement
+abasements
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+abatement
+abatements
+abater
+abates
+abating
+Abba
+abbe
+abbey
+abbeys
+abbot
+abbots
+Abbott
+abbreviate
+abbreviated
+abbreviates
+abbreviating
+abbreviation
+abbreviations
+Abby
+abdomen
+abdomens
+abdominal
+abduct
+abducted
+abduction
+abductions
+abductor
+abductors
+abducts
+Abe
+abed
+Abel
+Abelian
+Abelson
diff --git a/mysql-test/suite/binlog/r/binlog_checksum.result b/mysql-test/suite/binlog/r/binlog_checksum.result
new file mode 100644
index 00000000000..44024456720
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_checksum.result
@@ -0,0 +1,23 @@
+set @save_binlog_checksum = @@global.binlog_checksum;
+set @save_master_verify_checksum = @@global.master_verify_checksum;
+set @@global.binlog_checksum = CRC32;
+set @@global.master_verify_checksum = 1;
+reset master;
+must be master-bin.000001
+show binary logs;
+Log_name File_size
+master-bin.000001 #
+create table t1 (a int);
+flush logs;
+drop table t1;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; create table t1 (a int)
+master-bin.000001 # Rotate # # master-bin.000002;pos=4
+show tables;
+Tables_in_test
+t1
+drop table t1;
+set @@global.binlog_checksum = @save_binlog_checksum;
+set @@global.master_verify_checksum = @save_master_verify_checksum;
+End of the tests
diff --git a/mysql-test/suite/binlog/r/binlog_ioerr.result b/mysql-test/suite/binlog/r/binlog_ioerr.result
new file mode 100644
index 00000000000..04ac0340746
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_ioerr.result
@@ -0,0 +1,28 @@
+CALL mtr.add_suppression("Error writing file 'master-bin'");
+RESET MASTER;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+INSERT INTO t1 VALUES(0);
+SET SESSION debug='+d,fail_binlog_write_1';
+INSERT INTO t1 VALUES(1);
+ERROR HY000: Error writing file 'master-bin' (errno: 28)
+INSERT INTO t1 VALUES(2);
+ERROR HY000: Error writing file 'master-bin' (errno: 28)
+SET SESSION debug='';
+INSERT INTO t1 VALUES(3);
+SELECT * FROM t1;
+a
+0
+3
+SHOW BINLOG EVENTS;
+Log_name Pos Event_type Server_id End_log_pos Info
+BINLOG POS Format_desc 1 ENDPOS Server ver: #, Binlog ver: #
+BINLOG POS Query 1 ENDPOS use `test`; CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb
+BINLOG POS Query 1 ENDPOS BEGIN
+BINLOG POS Query 1 ENDPOS use `test`; INSERT INTO t1 VALUES(0)
+BINLOG POS Xid 1 ENDPOS COMMIT /* XID */
+BINLOG POS Query 1 ENDPOS BEGIN
+BINLOG POS Query 1 ENDPOS BEGIN
+BINLOG POS Query 1 ENDPOS BEGIN
+BINLOG POS Query 1 ENDPOS use `test`; INSERT INTO t1 VALUES(3)
+BINLOG POS Xid 1 ENDPOS COMMIT /* XID */
+DROP TABLE t1;
diff --git a/mysql-test/suite/binlog/r/binlog_killed.result b/mysql-test/suite/binlog/r/binlog_killed.result
index 72fda535b6f..8809bdca3dd 100644
--- a/mysql-test/suite/binlog/r/binlog_killed.result
+++ b/mysql-test/suite/binlog/r/binlog_killed.result
@@ -6,6 +6,11 @@ get_lock("a", 20)
1
reset master;
insert into t2 values (null, null), (null, get_lock("a", 10));
+kill query ID;
+select
+(@a:=load_file("MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog"))
+is not null;
+set @result= 2 - 1 - 1;
select @result /* must be zero either way */;
@result
0
@@ -55,7 +60,7 @@ drop table t4;
create table t4 (a int, b int) ENGINE=MyISAM /* for killing update and delete */;
create function bug27563(n int)
RETURNS int(11)
-DETERMINISTIC
+NOT DETERMINISTIC
begin
if @b > 0 then
select get_lock("a", 20) into @a;
@@ -84,18 +89,19 @@ a b
select @b /* must be 1 at the end of a stmt calling bug27563() */;
@b
1
-must have the update query event more to FD
+must have the update query event on the 3th line
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # User var # # @`b`=0
master-bin.000001 # Query # # use `test`; update t4 set b=b + bug27563(b)
+*** a proof the query is binlogged with an error ***
select
(@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
is not null;
(@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
is not null
1
-select 0 /* must return 0 to mean the killed query is in */;
+select 0 /* must return 0 to mean the killed update is in */;
0
0
select RELEASE_LOCK("a");
@@ -120,7 +126,7 @@ count(*)
select @b /* must be 1 at the end of a stmt calling bug27563() */;
@b
1
-must have the delete query event more to FD
+must have the delete query event on the 3th line
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # User var # # @`b`=0
@@ -131,7 +137,7 @@ is not null;
(@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
is not null
1
-select 0 /* must return 0 to mean the killed query is in */;
+select 0 /* must return 0 to mean the killed delete is in */;
0
0
select RELEASE_LOCK("a");
diff --git a/mysql-test/suite/binlog/r/binlog_row_annotate.result b/mysql-test/suite/binlog/r/binlog_row_annotate.result
new file mode 100644
index 00000000000..0c4a0dc552d
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_row_annotate.result
@@ -0,0 +1,1219 @@
+#####################################################################################
+# The following Annotate_rows events should appear below:
+# - INSERT INTO test2.t2 VALUES (1), (2), (3)
+# - INSERT INTO test3.t3 VALUES (1), (2), (3)
+# - DELETE test1.t1, test2.t2 FROM <...>
+# - INSERT INTO test2.t2 VALUES (1), (2), (3)
+# - DELETE xtest1.xt1, test2.t2 FROM <...>
+#####################################################################################
+show binlog events in 'master-bin.000001' from <start_pos>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # DROP DATABASE IF EXISTS test1
+master-bin.000001 # Query 1 # DROP DATABASE IF EXISTS test2
+master-bin.000001 # Query 1 # DROP DATABASE IF EXISTS test3
+master-bin.000001 # Query 1 # CREATE DATABASE test1
+master-bin.000001 # Query 1 # CREATE DATABASE test2
+master-bin.000001 # Query 1 # CREATE DATABASE test3
+master-bin.000001 # Query 1 # BEGIN
+master-bin.000001 # Table_map 1 # table_id: # (test1.t1)
+master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+master-bin.000001 # Query 1 # COMMIT
+master-bin.000001 # Query 1 # BEGIN
+master-bin.000001 # Annotate_rows 1 # INSERT INTO test2.t2 VALUES (1), (2), (3)
+master-bin.000001 # Table_map 1 # table_id: # (test2.t2)
+master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+master-bin.000001 # Query 1 # COMMIT
+master-bin.000001 # Query 1 # BEGIN
+master-bin.000001 # Annotate_rows 1 # INSERT INTO test3.t3 VALUES (1), (2), (3)
+master-bin.000001 # Table_map 1 # table_id: # (test3.t3)
+master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+master-bin.000001 # Query 1 # COMMIT
+master-bin.000001 # Query 1 # BEGIN
+master-bin.000001 # Annotate_rows 1 # DELETE test1.t1, test2.t2
+FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3
+WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3.a
+master-bin.000001 # Table_map 1 # table_id: # (test1.t1)
+master-bin.000001 # Table_map 1 # table_id: # (test2.t2)
+master-bin.000001 # Delete_rows 1 # table_id: #
+master-bin.000001 # Delete_rows 1 # table_id: # flags: STMT_END_F
+master-bin.000001 # Query 1 # COMMIT
+master-bin.000001 # Query 1 # BEGIN
+master-bin.000001 # Annotate_rows 1 # INSERT INTO test2.v2 VALUES (1), (2), (3)
+master-bin.000001 # Table_map 1 # table_id: # (test2.t2)
+master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+master-bin.000001 # Query 1 # COMMIT
+master-bin.000001 # Query 1 # BEGIN
+master-bin.000001 # Annotate_rows 1 # DELETE xtest1.xt1, test2.t2
+FROM xtest1.xt1 INNER JOIN test2.t2 INNER JOIN test3.t3
+WHERE xtest1.xt1.a=test2.t2.a AND test2.t2.a=test3.t3.a
+master-bin.000001 # Table_map 1 # table_id: # (test2.t2)
+master-bin.000001 # Delete_rows 1 # table_id: # flags: STMT_END_F
+master-bin.000001 # Query 1 # COMMIT
+master-bin.000001 # Rotate 1 # master-bin.000002;pos=4
+#
+#####################################################################################
+# mysqlbinlog
+# The following Annotates should appear in this output:
+# - INSERT INTO test2.t2 VALUES (1), (2), (3)
+# - INSERT INTO test3.t3 VALUES (1), (2), (3)
+# - DELETE test1.t1, test2.t2 FROM <...> (with two subsequent Table maps)
+# - INSERT INTO test2.t2 VALUES (1), (2), (3)
+# - DELETE xtest1.xt1, test2.t2 FROM <...> (with one subsequent Table map)
+#####################################################################################
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
+ROLLBACK/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=#/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+DROP DATABASE IF EXISTS test1
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+DROP DATABASE IF EXISTS test2
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+DROP DATABASE IF EXISTS test3
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test1
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test2
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test3
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Annotate_rows:
+#Q> INSERT INTO test2.t2 VALUES (1), (2), (3)
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Annotate_rows:
+#Q> INSERT INTO test3.t3 VALUES (1), (2), (3)
+#010909 4:46:40 server id # end_log_pos # Table_map: `test3`.`t3` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test3`.`t3`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test3`.`t3`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test3`.`t3`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Annotate_rows:
+#Q> DELETE test1.t1, test2.t2
+#Q> FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3
+#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3
+#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Annotate_rows:
+#Q> INSERT INTO test2.v2 VALUES (1), (2), (3)
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Annotate_rows:
+#Q> DELETE xtest1.xt1, test2.t2
+#Q> FROM xtest1.xt1 INNER JOIN test2.t2 INNER JOIN test3.t3
+#Q> WHERE xtest1.xt1.a=test2.t2.a AND test2.t2.a=test3.t3
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Rotate to master-bin.000002 pos: 4
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+#
+#####################################################################################
+# mysqlbinlog --database=test1
+# The following Annotate should appear in this output:
+# - DELETE test1.t1, test2.t2 FROM <...>
+#####################################################################################
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
+ROLLBACK/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=#/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+DROP DATABASE IF EXISTS test1
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test1
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Annotate_rows:
+#Q> DELETE test1.t1, test2.t2
+#Q> FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3
+#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3
+#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id #
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Rotate to master-bin.000002 pos: 4
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+#
+#####################################################################################
+# mysqlbinlog --skip-annotate-row-events
+# No Annotates should appear in this output
+#####################################################################################
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
+ROLLBACK/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=#/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+DROP DATABASE IF EXISTS test1
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+DROP DATABASE IF EXISTS test2
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+DROP DATABASE IF EXISTS test3
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test1
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test2
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test3
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test3`.`t3` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test3`.`t3`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test3`.`t3`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test3`.`t3`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Rotate to master-bin.000002 pos: 4
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+#
+#####################################################################################
+# mysqlbinlog --read-from-remote-server
+# The following Annotates should appear in this output:
+# - INSERT INTO test2.t2 VALUES (1), (2), (3)
+# - INSERT INTO test3.t3 VALUES (1), (2), (3)
+# - DELETE test1.t1, test2.t2 FROM <...> (with two subsequent Table maps)
+# - INSERT INTO test2.t2 VALUES (1), (2), (3)
+# - DELETE xtest1.xt1, test2.t2 FROM <...> (with one subsequent Table map)
+#####################################################################################
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
+ROLLBACK/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=#/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+DROP DATABASE IF EXISTS test1
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+DROP DATABASE IF EXISTS test2
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+DROP DATABASE IF EXISTS test3
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test1
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test2
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test3
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Annotate_rows:
+#Q> INSERT INTO test2.t2 VALUES (1), (2), (3)
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Annotate_rows:
+#Q> INSERT INTO test3.t3 VALUES (1), (2), (3)
+#010909 4:46:40 server id # end_log_pos # Table_map: `test3`.`t3` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test3`.`t3`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test3`.`t3`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test3`.`t3`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Annotate_rows:
+#Q> DELETE test1.t1, test2.t2
+#Q> FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3
+#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3
+#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Annotate_rows:
+#Q> INSERT INTO test2.v2 VALUES (1), (2), (3)
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Annotate_rows:
+#Q> DELETE xtest1.xt1, test2.t2
+#Q> FROM xtest1.xt1 INNER JOIN test2.t2 INNER JOIN test3.t3
+#Q> WHERE xtest1.xt1.a=test2.t2.a AND test2.t2.a=test3.t3
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Rotate to master-bin.000002 pos: 4
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+#
+#####################################################################################
+# mysqlbinlog --read-from-remote-server --database=test1
+# The following Annotate should appear in this output:
+# - DELETE test1.t1, test2.t2 FROM <...>
+#####################################################################################
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
+ROLLBACK/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=#/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+DROP DATABASE IF EXISTS test1
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test1
+/*!*/;
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Annotate_rows:
+#Q> DELETE test1.t1, test2.t2
+#Q> FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3
+#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3
+#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id #
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Rotate to master-bin.000002 pos: 4
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+#
+#####################################################################################
+# mysqlbinlog --read-from-remote-server --skip-annotate-row-events
+# No Annotates should appear in this output
+#####################################################################################
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
+ROLLBACK/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=#/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+DROP DATABASE IF EXISTS test1
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+DROP DATABASE IF EXISTS test2
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+DROP DATABASE IF EXISTS test3
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test1
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test2
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE DATABASE test3
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test1`.`t1`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test3`.`t3` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test3`.`t3`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test3`.`t3`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test3`.`t3`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test1`.`t1`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### INSERT INTO `test2`.`t2`
+### SET
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+BEGIN
+/*!*/;
+# at #
+# at #
+#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number #
+#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=3 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=2 /* INT meta=0 nullable=1 is_null=0 */
+### DELETE FROM `test2`.`t2`
+### WHERE
+### @1=1 /* INT meta=0 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id # end_log_pos # Rotate to master-bin.000002 pos: 4
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result
index e726d236323..a30dc69c7c0 100644
--- a/mysql-test/suite/binlog/r/binlog_row_binlog.result
+++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result
@@ -260,10 +260,18 @@ master-bin.000001 # Query # # use `test`; drop table t1
set @bcs = @@binlog_cache_size;
set global binlog_cache_size=4096;
reset master;
-create table t1 (a int) engine=innodb;
+create table t1 (a int, b char(255)) engine=innodb;
+flush status;
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 0
+*** the following must show the counter value = 1 ***
+Variable_name Value
+Binlog_cache_use 1
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # use `test`; create table t1 (a int) engine=innodb
+master-bin.000001 # Query # # use `test`; create table t1 (a int, b char(255)) engine=innodb
+master-bin.000001 # Query # # use `test`; flush status
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
@@ -465,606 +473,6 @@ master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Rotate # # master-bin.000002;pos=4
drop table t1;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result
index e7e263a3a20..5b324150d5a 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result
@@ -168,411 +168,119 @@ master-bin.000001 # Query # # use `test`; drop table t1
set @bcs = @@binlog_cache_size;
set global binlog_cache_size=4096;
reset master;
-create table t1 (a int) engine=innodb;
+create table t1 (a int, b char(255)) engine=innodb;
+flush status;
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 0
+*** the following must show the counter value = 1 ***
+Variable_name Value
+Binlog_cache_use 1
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # use `test`; create table t1 (a int) engine=innodb
+master-bin.000001 # Query # # use `test`; create table t1 (a int, b char(255)) engine=innodb
+master-bin.000001 # Query # # use `test`; flush status
master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Query # # use `test`; insert into t1 values( 400 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 399 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 398 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 397 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 396 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 395 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 394 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 393 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 392 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 391 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 390 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 389 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 388 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 387 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 386 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 385 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 384 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 383 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 382 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 381 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 380 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 379 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 378 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 377 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 376 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 375 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 374 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 373 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 372 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 371 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 370 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 369 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 368 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 367 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 366 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 365 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 364 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 363 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 362 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 361 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 360 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 359 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 358 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 357 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 356 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 355 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 354 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 353 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 352 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 351 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 350 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 349 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 348 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 347 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 346 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 345 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 344 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 343 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 342 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 341 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 340 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 339 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 338 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 337 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 336 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 335 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 334 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 333 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 332 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 331 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 330 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 329 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 328 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 327 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 326 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 325 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 324 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 323 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 322 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 321 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 320 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 319 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 318 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 317 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 316 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 315 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 314 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 313 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 312 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 311 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 310 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 309 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 308 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 307 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 306 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 305 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 304 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 303 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 302 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 301 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 300 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 299 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 298 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 297 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 296 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 295 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 294 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 293 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 292 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 291 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 290 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 289 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 288 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 287 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 286 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 285 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 284 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 283 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 282 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 281 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 280 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 279 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 278 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 277 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 276 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 275 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 274 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 273 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 272 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 271 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 270 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 269 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 268 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 267 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 266 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 265 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 264 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 263 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 262 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 261 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 260 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 259 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 258 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 257 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 256 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 255 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 254 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 253 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 252 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 251 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 250 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 249 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 248 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 247 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 246 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 245 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 244 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 243 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 242 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 241 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 240 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 239 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 238 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 237 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 236 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 235 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 234 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 233 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 232 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 231 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 230 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 229 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 228 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 227 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 226 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 225 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 224 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 223 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 222 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 221 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 220 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 219 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 218 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 217 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 216 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 215 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 214 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 213 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 212 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 211 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 210 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 209 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 208 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 207 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 206 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 205 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 204 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 203 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 202 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 201 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 200 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 199 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 198 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 197 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 196 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 195 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 194 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 193 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 192 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 191 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 190 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 189 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 188 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 187 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 186 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 185 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 184 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 183 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 182 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 181 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 180 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 179 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 178 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 177 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 176 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 175 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 174 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 173 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 172 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 171 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 170 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 169 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 168 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 167 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 166 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 165 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 164 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 163 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 162 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 161 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 160 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 159 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 158 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 157 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 156 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 155 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 154 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 153 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 152 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 151 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 150 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 149 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 148 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 147 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 146 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 145 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 144 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 143 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 142 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 141 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 140 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 139 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 138 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 137 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 136 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 135 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 134 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 133 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 132 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 131 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 130 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 129 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 128 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 127 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 126 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 125 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 124 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 123 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 122 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 121 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 120 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 119 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 118 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 117 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 116 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 115 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 114 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 113 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 112 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 111 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 110 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 109 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 108 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 107 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( <binlog_start> )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 105 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 104 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 103 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 102 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 101 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 100 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 99 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 98 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 97 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 96 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 95 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 94 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 93 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 92 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 91 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 90 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 89 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 88 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 87 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 86 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 85 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 84 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 83 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 82 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 81 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 80 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 79 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 78 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 77 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 76 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 75 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 74 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 73 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 72 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 71 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 70 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 69 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 68 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 67 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 66 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 65 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 64 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 63 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 62 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 61 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 60 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 59 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 58 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 57 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 56 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 55 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 54 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 53 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 52 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 51 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 50 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 49 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 48 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 47 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 46 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 45 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 44 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 43 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 42 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 41 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 40 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 39 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 38 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 37 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 36 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 35 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 34 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 33 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 32 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 31 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 30 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 29 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 28 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 27 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 26 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 25 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 24 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 23 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 22 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 21 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 20 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 19 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 18 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 17 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 16 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 15 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 14 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 13 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 12 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 11 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 10 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 9 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 8 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 7 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 6 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 5 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 4 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 3 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 2 )
-master-bin.000001 # Query # # use `test`; insert into t1 values( 1 )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 100, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 99, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 98, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 97, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 96, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 95, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 94, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 93, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 92, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 91, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 90, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 89, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 88, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 87, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 86, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 85, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 84, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 83, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 82, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 81, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 80, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 79, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 78, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 77, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 76, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 75, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 74, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 73, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 72, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 71, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 70, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 69, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 68, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 67, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 66, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 65, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 64, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 63, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 62, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 61, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 60, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 59, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 58, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 57, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 56, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 55, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 54, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 53, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 52, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 51, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 50, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 49, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 48, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 47, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 46, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 45, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 44, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 43, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 42, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 41, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 40, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 39, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 38, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 37, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 36, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 35, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 34, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 33, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 32, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 31, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 30, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 29, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 28, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 27, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 26, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 25, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 24, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 23, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 22, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 21, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 20, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 19, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 18, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 17, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 16, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 15, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 14, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 13, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 12, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 11, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 10, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 9, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 8, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 7, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 6, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 5, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 4, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 3, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 2, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
+master-bin.000001 # Query # # use `test`; insert into t1 values( 1, 'just to fill void to make transaction occupying at least two buffers of the trans cache' )
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Rotate # # master-bin.000002;pos=4
drop table t1;
diff --git a/mysql-test/suite/binlog/t/binlog_checksum.test b/mysql-test/suite/binlog/t/binlog_checksum.test
new file mode 100644
index 00000000000..7ecb9308f70
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_checksum.test
@@ -0,0 +1,37 @@
+source include/have_innodb.inc;
+source include/have_log_bin.inc;
+
+#
+# WL#2540 replication event checksum
+#
+# Objectives of the test are:
+# to demo binlog events with CRC32 checksum in them and
+# to prove show binlog events and mysqlbinlog are capable to handle
+# the checksum.
+#
+
+set @save_binlog_checksum = @@global.binlog_checksum;
+set @save_master_verify_checksum = @@global.master_verify_checksum;
+set @@global.binlog_checksum = CRC32;
+set @@global.master_verify_checksum = 1;
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+reset master;
+--echo must be master-bin.000001
+--source include/show_binary_logs.inc
+
+create table t1 (a int);
+flush logs;
+drop table t1;
+
+--source include/show_binlog_events.inc
+--exec $MYSQL_BINLOG -c $MYSQLD_DATADIR/master-bin.000001 | $MYSQL
+show tables;
+
+# clean-up
+
+drop table t1;
+set @@global.binlog_checksum = @save_binlog_checksum;
+set @@global.master_verify_checksum = @save_master_verify_checksum;
+
+--echo End of the tests
diff --git a/mysql-test/suite/binlog/t/binlog_incident.test b/mysql-test/suite/binlog/t/binlog_incident.test
index 901ac49ea24..1c526ca5980 100644
--- a/mysql-test/suite/binlog/t/binlog_incident.test
+++ b/mysql-test/suite/binlog/t/binlog_incident.test
@@ -4,6 +4,7 @@
source include/have_log_bin.inc;
source include/have_debug.inc;
+source include/binlog_start_pos.inc;
let $MYSQLD_DATADIR= `select @@datadir`;
RESET MASTER;
@@ -20,7 +21,7 @@ REPLACE INTO t1 VALUES (4);
DROP TABLE t1;
FLUSH LOGS;
-exec $MYSQL_BINLOG --start-position=106 $MYSQLD_DATADIR/master-bin.000001 >$MYSQLTEST_VARDIR/tmp/binlog_incident-bug44442.sql;
+exec $MYSQL_BINLOG --start-position=$binlog_start_pos $MYSQLD_DATADIR/master-bin.000001 >$MYSQLTEST_VARDIR/tmp/binlog_incident-bug44442.sql;
--disable_query_log
eval SELECT cont LIKE '%RELOAD DATABASE; # Shall generate syntax error%' AS `Contain RELOAD DATABASE` FROM (SELECT load_file('$MYSQLTEST_VARDIR/tmp/binlog_incident-bug44442.sql') AS cont) AS tbl;
--enable_query_log
diff --git a/mysql-test/suite/binlog/t/binlog_ioerr.test b/mysql-test/suite/binlog/t/binlog_ioerr.test
new file mode 100644
index 00000000000..e6f559c1a7b
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_ioerr.test
@@ -0,0 +1,30 @@
+source include/have_debug.inc;
+source include/have_innodb.inc;
+source include/have_log_bin.inc;
+source include/have_binlog_format_mixed_or_statement.inc;
+
+CALL mtr.add_suppression("Error writing file 'master-bin'");
+
+RESET MASTER;
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+INSERT INTO t1 VALUES(0);
+SET SESSION debug='+d,fail_binlog_write_1';
+--error ER_ERROR_ON_WRITE
+INSERT INTO t1 VALUES(1);
+--error ER_ERROR_ON_WRITE
+INSERT INTO t1 VALUES(2);
+SET SESSION debug='';
+INSERT INTO t1 VALUES(3);
+SELECT * FROM t1;
+
+# Actually the output from this currently shows a bug.
+# The injected IO error leaves partially written transactions in the binlog in
+# the form of stray "BEGIN" events.
+# These should disappear from the output if binlog error handling is improved
+# (see MySQL Bug#37148 and WL#1790).
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/
+--replace_column 1 BINLOG 2 POS 5 ENDPOS
+SHOW BINLOG EVENTS;
+
+DROP TABLE t1;
diff --git a/mysql-test/suite/binlog/t/binlog_killed.test b/mysql-test/suite/binlog/t/binlog_killed.test
index ce6d344af32..dd40f298083 100644
--- a/mysql-test/suite/binlog/t/binlog_killed.test
+++ b/mysql-test/suite/binlog/t/binlog_killed.test
@@ -1,5 +1,6 @@
-- source include/have_innodb.inc
-- source include/have_binlog_format_statement.inc
+-- source include/binlog_start_pos.inc
# You cannot use `KILL' with the Embedded MySQL Server library,
# because the embedded server merely runs inside the threads of the host
@@ -39,10 +40,15 @@ send insert into t2 values (null, null), (null, get_lock("a", 10));
connection con1;
-disable_abort_on_error;
-disable_query_log;
-disable_result_log;
+--disable_abort_on_error
+--disable_warnings
+
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where info like "%insert into t2 values%" and state like 'User lock';
+--source include/wait_condition.inc
+--replace_regex /[0-9]+/ID/
eval kill query $ID;
connection con2;
@@ -51,19 +57,23 @@ reap;
let $rows= `select count(*) from t2 /* must be 2 or 0 */`;
let $MYSQLD_DATADIR= `select @@datadir`;
---exec $MYSQL_BINLOG --force-if-open --start-position=134 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog
+
+--let $binlog_killed_pos=query_get_value(SHOW BINLOG EVENTS, Pos, 3)
+--let $binlog_killed_end_log_pos=query_get_value(SHOW BINLOG EVENTS, End_log_pos, 3)
+--exec $MYSQL_BINLOG --force-if-open --start-position=$binlog_killed_pos --stop-position=$binlog_killed_end_log_pos $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--disable_result_log
eval select
(@a:=load_file("$MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog"))
is not null;
+--enable_result_log
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
let $error_code= `select @a like "%#%error_code=0%" /* must return 1 or 0*/`;
let $insert_binlogged= `select @a like "%insert into%" /* must return 1 or 0 */`;
-eval set @result= $rows- $error_code - $insert_binlogged;
+eval set @result= $rows - $error_code - $insert_binlogged;
-enable_abort_on_error;
-enable_query_log;
-enable_result_log;
+--enable_warnings
+--enable_abort_on_error
select @result /* must be zero either way */;
@@ -218,7 +228,7 @@ create table t4 (a int, b int) ENGINE=MyISAM /* for killing update and delete */
delimiter |;
create function bug27563(n int)
RETURNS int(11)
-DETERMINISTIC
+NOT DETERMINISTIC
begin
if @b > 0 then
select get_lock("a", 20) into @a;
@@ -257,19 +267,21 @@ connection con2;
reap;
select * from t4 order by b /* must be (1,1), (1,2) */;
select @b /* must be 1 at the end of a stmt calling bug27563() */;
---echo must have the update query event more to FD
+--echo must have the update query event on the 3th line
source include/show_binlog_events.inc;
+--let $binlog_killed_pos= query_get_value(SHOW BINLOG EVENTS, Pos, 3)
+--let $binlog_killed_end_log_pos= query_get_value(SHOW BINLOG EVENTS, End_log_pos, 3)
-# a proof the query is binlogged with an error
+--echo *** a proof the query is binlogged with an error ***
---exec $MYSQL_BINLOG --force-if-open --start-position=106 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
+--exec $MYSQL_BINLOG --force-if-open --start-position=$binlog_killed_pos --stop-position=$binlog_killed_end_log_pos $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval select
(@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
is not null;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
let $error_code= `select @a like "%#%error_code=0%" /* must return 0*/`;
-eval select $error_code /* must return 0 to mean the killed query is in */;
+eval select $error_code /* must return 0 to mean the killed update is in */;
# cleanup for the sub-case
connection con1;
@@ -303,19 +315,21 @@ connection con2;
reap;
select count(*) from t4 /* must be 1 */;
select @b /* must be 1 at the end of a stmt calling bug27563() */;
---echo must have the delete query event more to FD
+--echo must have the delete query event on the 3th line
source include/show_binlog_events.inc;
+--let $binlog_killed_pos= query_get_value(SHOW BINLOG EVENTS, Pos, 3)
+--let $binlog_killed_end_log_pos= query_get_value(SHOW BINLOG EVENTS, End_log_pos, 3)
# a proof the query is binlogged with an error
---exec $MYSQL_BINLOG --force-if-open --start-position=106 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
+--exec $MYSQL_BINLOG --force-if-open --start-position=$binlog_killed_pos --stop-position=$binlog_killed_end_log_pos $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval select
(@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
is not null;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
let $error_code= `select @a like "%#%error_code=0%" /* must return 0*/`;
-eval select $error_code /* must return 0 to mean the killed query is in */;
+eval select $error_code /* must return 0 to mean the killed delete is in */;
# cleanup for the sub-case
connection con1;
diff --git a/mysql-test/suite/binlog/t/binlog_killed_simulate.test b/mysql-test/suite/binlog/t/binlog_killed_simulate.test
index b87d47559fe..c5c14137fbb 100644
--- a/mysql-test/suite/binlog/t/binlog_killed_simulate.test
+++ b/mysql-test/suite/binlog/t/binlog_killed_simulate.test
@@ -1,5 +1,6 @@
-- source include/have_debug.inc
-- source include/have_binlog_format_statement.inc
+-- source include/binlog_start_pos.inc
#
# bug#27571 asynchronous setting mysql_$query()'s local error and
# Query_log_event::error_code
@@ -24,7 +25,7 @@ update t1 set a=2 /* will be "killed" after work has been done */;
# for some constants like the offset of the first real event
# that is different between severs versions.
let $MYSQLD_DATADIR= `select @@datadir`;
---exec $MYSQL_BINLOG --force-if-open --start-position=106 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
+--exec $MYSQL_BINLOG --force-if-open --start-position=$binlog_start_pos $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval select
(@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog2.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog2.test
index d6be029ea56..57adde7b975 100644
--- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog2.test
+++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog2.test
@@ -3,7 +3,7 @@
# TODO: Need to look at making row based version once new binlog client is complete.
-- source include/have_binlog_format_mixed_or_statement.inc
-
+-- source include/binlog_start_pos.inc
--disable_warnings
drop table if exists t1;
@@ -50,15 +50,19 @@ select "--- offset --" as "";
--disable_query_log
select "--- start-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=608 $MYSQLD_DATADIR/master-bin.000001
+let $start_pos= `select @binlog_start_pos + 502`;
+--exec $MYSQL_BINLOG --short-form --start-position=$start_pos $MYSQLD_DATADIR/master-bin.000001
--disable_query_log
select "--- stop-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --stop-position=608 $MYSQLD_DATADIR/master-bin.000001
+let $stop_pos= `select @binlog_start_pos + 502`;
+--exec $MYSQL_BINLOG --short-form --stop-position=$stop_pos $MYSQLD_DATADIR/master-bin.000001
--disable_query_log
select "--- start and stop positions ---" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=608 --stop-position 725 $MYSQLD_DATADIR/master-bin.000001
+let $start_pos= `select @binlog_start_pos + 502`;
+let $stop_pos= `select @binlog_start_pos + 619`;
+--exec $MYSQL_BINLOG --short-form --start-position=$start_pos --stop-position $stop_pos $MYSQLD_DATADIR/master-bin.000001
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
@@ -84,11 +88,13 @@ select "--- offset --" as "";
--disable_query_log
select "--- start-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=608 $MYSQLD_DATADIR/master-bin.000001 $MYSQLD_DATADIR/master-bin.000002
+let $start_pos= `select @binlog_start_pos + 502`;
+--exec $MYSQL_BINLOG --short-form --start-position=$start_pos $MYSQLD_DATADIR/master-bin.000001 $MYSQLD_DATADIR/master-bin.000002
--disable_query_log
select "--- stop-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --stop-position=134 $MYSQLD_DATADIR/master-bin.000001 $MYSQLD_DATADIR/master-bin.000002
+let $stop_pos= `select @binlog_start_pos + 28`;
+--exec $MYSQL_BINLOG --short-form --stop-position=$stop_pos $MYSQLD_DATADIR/master-bin.000001 $MYSQLD_DATADIR/master-bin.000002
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
@@ -111,15 +117,19 @@ select "--- offset --" as "";
--disable_query_log
select "--- start-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=608 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
+let $start_pos= `select @binlog_start_pos + 502`;
+--exec $MYSQL_BINLOG --short-form --start-position=$start_pos --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
--disable_query_log
select "--- stop-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --stop-position=608 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
+let $stop_pos= `select @binlog_start_pos + 502`;
+--exec $MYSQL_BINLOG --short-form --stop-position=$stop_pos --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
--disable_query_log
select "--- start and stop positions ---" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=608 --stop-position 725 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
+let $start_pos= `select @binlog_start_pos + 502`;
+let $stop_pos= `select @binlog_start_pos + 619`;
+--exec $MYSQL_BINLOG --short-form --start-position=$start_pos --stop-position $stop_pos --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
@@ -142,11 +152,13 @@ select "--- offset --" as "";
--disable_query_log
select "--- start-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=608 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
+let $start_pos= `select @binlog_start_pos + 502`;
+--exec $MYSQL_BINLOG --short-form --start-position=$start_pos --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
--disable_query_log
select "--- stop-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --stop-position=134 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
+let $stop_pos= `select @binlog_start_pos + 28`;
+--exec $MYSQL_BINLOG --short-form --stop-position=$stop_pos --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
diff --git a/mysql-test/suite/binlog/t/binlog_row_annotate-master.opt b/mysql-test/suite/binlog/t/binlog_row_annotate-master.opt
new file mode 100644
index 00000000000..24d88646b3b
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_row_annotate-master.opt
@@ -0,0 +1 @@
+--timezone=GMT-3 --binlog-do-db=test1 --binlog-do-db=test2 --binlog-do-db=test3
diff --git a/mysql-test/suite/binlog/t/binlog_row_annotate.test b/mysql-test/suite/binlog/t/binlog_row_annotate.test
new file mode 100644
index 00000000000..a0f72c9222c
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_row_annotate.test
@@ -0,0 +1,189 @@
+###############################################################################
+# WL47: Store in binlog text of statements that caused RBR events
+# new event: ANNOTATE_ROWS_EVENT
+# new master option: --binlog-annotate-row-events
+# new mysqlbinlog option: --skip-annotate-row-events
+#
+# Intended to test that:
+# *** If the --binlog-annotate-row-events option is switched on on master
+# then Annotate_rows events:
+# - are generated;
+# - are genrated only once for "multi-table-maps" rbr queries;
+# - are not generated when the corresponding queries are filtered away;
+# - are generated when the corresponding queries are filtered away partialy
+# (e.g. in case of multi-delete).
+# *** Annotate_rows events are printed by mysqlbinlog started without
+# --skip-annotate-row-events options both in remote and local cases.
+# *** Annotate_rows events are not printed by mysqlbinlog started with
+# --skip-annotate-row-events options both in remote and local cases.
+###############################################################################
+
+--source include/have_log_bin.inc
+--source include/have_binlog_format_row.inc
+--source include/binlog_start_pos.inc
+
+--disable_query_log
+
+# Fix timestamp to avoid varying results
+SET timestamp=1000000000;
+
+# Delete all existing binary logs
+RESET MASTER;
+
+--disable_warnings
+DROP DATABASE IF EXISTS test1;
+DROP DATABASE IF EXISTS test2;
+DROP DATABASE IF EXISTS test3;
+DROP DATABASE IF EXISTS xtest1;
+DROP DATABASE IF EXISTS xtest2;
+--enable_warnings
+
+CREATE DATABASE test1;
+CREATE TABLE test1.t1(a int);
+
+CREATE DATABASE test2;
+CREATE TABLE test2.t2(a int);
+CREATE VIEW test2.v2 AS SELECT * FROM test2.t2;
+
+CREATE DATABASE test3;
+CREATE TABLE test3.t3(a int);
+
+CREATE DATABASE xtest1;
+CREATE TABLE xtest1.xt1(a int);
+
+CREATE DATABASE xtest2;
+CREATE TABLE xtest2.xt2(a int);
+
+# By default SESSION binlog_annotate_row_events = OFF
+
+INSERT INTO test1.t1 VALUES (1), (2), (3);
+
+SET SESSION binlog_annotate_row_events = ON;
+
+INSERT INTO test2.t2 VALUES (1), (2), (3);
+INSERT INTO test3.t3 VALUES (1), (2), (3);
+
+# This query generates two Table maps but the Annotate
+# event should appear only once before the first Table map
+DELETE test1.t1, test2.t2
+ FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3
+ WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3.a;
+
+# This event should be filtered out together with Annotate event
+INSERT INTO xtest1.xt1 VALUES (1), (2), (3);
+
+# This event should pass the filter
+INSERT INTO test2.v2 VALUES (1), (2), (3);
+
+# This event should pass the filter only for test2.t2 part
+DELETE xtest1.xt1, test2.t2
+ FROM xtest1.xt1 INNER JOIN test2.t2 INNER JOIN test3.t3
+ WHERE xtest1.xt1.a=test2.t2.a AND test2.t2.a=test3.t3.a;
+
+# These events should be filtered out together with Annotate events
+INSERT INTO xtest1.xt1 VALUES (1), (2), (3);
+INSERT INTO xtest2.xt2 VALUES (1), (2), (3);
+DELETE xtest1.xt1, xtest2.xt2
+ FROM xtest1.xt1 INNER JOIN xtest2.xt2 INNER JOIN test3.t3
+ WHERE xtest1.xt1.a=xtest2.xt2.a AND xtest2.xt2.a=test3.t3.a;
+
+FLUSH LOGS;
+--enable_query_log
+
+--echo #####################################################################################
+--echo # The following Annotate_rows events should appear below:
+--echo # - INSERT INTO test2.t2 VALUES (1), (2), (3)
+--echo # - INSERT INTO test3.t3 VALUES (1), (2), (3)
+--echo # - DELETE test1.t1, test2.t2 FROM <...>
+--echo # - INSERT INTO test2.t2 VALUES (1), (2), (3)
+--echo # - DELETE xtest1.xt1, test2.t2 FROM <...>
+--echo #####################################################################################
+
+let $start_pos= `select @binlog_start_pos`;
+--replace_column 2 # 5 #
+--replace_result $start_pos <start_pos>
+--replace_regex /table_id: [0-9]+/table_id: #/ /\/\* xid=.* \*\//\/* xid= *\//
+--eval show binlog events in 'master-bin.000001' from $start_pos
+
+--echo #
+--echo #####################################################################################
+--echo # mysqlbinlog
+--echo # The following Annotates should appear in this output:
+--echo # - INSERT INTO test2.t2 VALUES (1), (2), (3)
+--echo # - INSERT INTO test3.t3 VALUES (1), (2), (3)
+--echo # - DELETE test1.t1, test2.t2 FROM <...> (with two subsequent Table maps)
+--echo # - INSERT INTO test2.t2 VALUES (1), (2), (3)
+--echo # - DELETE xtest1.xt1, test2.t2 FROM <...> (with one subsequent Table map)
+--echo #####################################################################################
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/
+--exec $MYSQL_BINLOG --base64-output=decode-rows -v -v $MYSQLD_DATADIR/master-bin.000001
+
+--echo #
+--echo #####################################################################################
+--echo # mysqlbinlog --database=test1
+--echo # The following Annotate should appear in this output:
+--echo # - DELETE test1.t1, test2.t2 FROM <...>
+--echo #####################################################################################
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/
+--exec $MYSQL_BINLOG --base64-output=decode-rows --database=test1 -v -v $MYSQLD_DATADIR/master-bin.000001
+
+--echo #
+--echo #####################################################################################
+--echo # mysqlbinlog --skip-annotate-row-events
+--echo # No Annotates should appear in this output
+--echo #####################################################################################
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/
+--exec $MYSQL_BINLOG --base64-output=decode-rows --skip-annotate-row-events -v -v $MYSQLD_DATADIR/master-bin.000001
+
+--echo #
+--echo #####################################################################################
+--echo # mysqlbinlog --read-from-remote-server
+--echo # The following Annotates should appear in this output:
+--echo # - INSERT INTO test2.t2 VALUES (1), (2), (3)
+--echo # - INSERT INTO test3.t3 VALUES (1), (2), (3)
+--echo # - DELETE test1.t1, test2.t2 FROM <...> (with two subsequent Table maps)
+--echo # - INSERT INTO test2.t2 VALUES (1), (2), (3)
+--echo # - DELETE xtest1.xt1, test2.t2 FROM <...> (with one subsequent Table map)
+--echo #####################################################################################
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/
+--exec $MYSQL_BINLOG --base64-output=decode-rows -v -v --read-from-remote-server --user=root --host=localhost --port=$MASTER_MYPORT master-bin.000001
+
+--echo #
+--echo #####################################################################################
+--echo # mysqlbinlog --read-from-remote-server --database=test1
+--echo # The following Annotate should appear in this output:
+--echo # - DELETE test1.t1, test2.t2 FROM <...>
+--echo #####################################################################################
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/
+--exec $MYSQL_BINLOG --base64-output=decode-rows --database=test1 -v -v --read-from-remote-server --user=root --host=localhost --port=$MASTER_MYPORT master-bin.000001
+
+--echo #
+--echo #####################################################################################
+--echo # mysqlbinlog --read-from-remote-server --skip-annotate-row-events
+--echo # No Annotates should appear in this output
+--echo #####################################################################################
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/
+--exec $MYSQL_BINLOG --base64-output=decode-rows --skip-annotate-row-events -v -v --read-from-remote-server --user=root --host=localhost --port=$MASTER_MYPORT master-bin.000001
+
+# Clean-up
+
+--disable_query_log
+DROP DATABASE test1;
+DROP DATABASE test2;
+DROP DATABASE test3;
+DROP DATABASE xtest1;
+DROP DATABASE xtest2;
+--enable_query_log
+
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/engines/funcs/r/an_calendar.result b/mysql-test/suite/engines/funcs/r/an_calendar.result
index e974a67444e..f057c3b618f 100644
--- a/mysql-test/suite/engines/funcs/r/an_calendar.result
+++ b/mysql-test/suite/engines/funcs/r/an_calendar.result
@@ -16,7 +16,13 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NULL, c2 TIME NULL);
SET TIMESTAMP=1171346973;
INSERT INTO t1 VALUES(NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
INSERT INTO t1 VALUES(NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
diff --git a/mysql-test/suite/engines/funcs/r/datetime_function.result b/mysql-test/suite/engines/funcs/r/datetime_function.result
index 182f61f67f0..583552edc7d 100644
--- a/mysql-test/suite/engines/funcs/r/datetime_function.result
+++ b/mysql-test/suite/engines/funcs/r/datetime_function.result
@@ -25,7 +25,15 @@ INSERT INTO t3 VALUES('2008-02-29 13:13:13');
DROP TABLE t3;
CREATE TABLE t3(c1 TIME NOT NULL);
INSERT INTO t3 VALUES('1000-01-01 00:00:00');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t3 VALUES('1999-12-31 23:59:59');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t3 VALUES('2000-01-01 00:00:00');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t3 VALUES('2008-02-29 13:13:13');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
DROP TABLE t3;
diff --git a/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result b/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result
index 8f79469d8de..3a973c61ddb 100644
--- a/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result
+++ b/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result
@@ -76,6 +76,7 @@ utf8_roman_ci utf8 207 # #
utf8_persian_ci utf8 208 # #
utf8_esperanto_ci utf8 209 # #
utf8_hungarian_ci utf8 210 # #
+utf8_croatian_ci utf8 213 # #
utf8_general_mysql500_ci utf8 223 # #
ucs2_general_ci ucs2 35 Yes # #
ucs2_bin ucs2 90 # #
@@ -98,6 +99,7 @@ ucs2_roman_ci ucs2 143 # #
ucs2_persian_ci ucs2 144 # #
ucs2_esperanto_ci ucs2 145 # #
ucs2_hungarian_ci ucs2 146 # #
+ucs2_croatian_ci ucs2 149 # #
ucs2_general_mysql500_ci ucs2 159 # #
cp866_general_ci cp866 36 Yes # #
cp866_bin cp866 68 # #
diff --git a/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result b/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result
index 9fb36bd0927..eaf8a698421 100644
--- a/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result
+++ b/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result
@@ -76,6 +76,7 @@ utf8_roman_ci utf8 207 # #
utf8_persian_ci utf8 208 # #
utf8_esperanto_ci utf8 209 # #
utf8_hungarian_ci utf8 210 # #
+utf8_croatian_ci utf8 213 # #
utf8_general_mysql500_ci utf8 223 # #
ucs2_general_ci ucs2 35 Yes # #
ucs2_bin ucs2 90 # #
@@ -98,6 +99,7 @@ ucs2_roman_ci ucs2 143 # #
ucs2_persian_ci ucs2 144 # #
ucs2_esperanto_ci ucs2 145 # #
ucs2_hungarian_ci ucs2 146 # #
+ucs2_croatian_ci ucs2 149 # #
ucs2_general_mysql500_ci ucs2 159 # #
cp866_general_ci cp866 36 Yes # #
cp866_bin cp866 68 # #
diff --git a/mysql-test/suite/engines/funcs/r/de_calendar_range.result b/mysql-test/suite/engines/funcs/r/de_calendar_range.result
index 07543e0c8c4..ab39556e6ce 100644
--- a/mysql-test/suite/engines/funcs/r/de_calendar_range.result
+++ b/mysql-test/suite/engines/funcs/r/de_calendar_range.result
@@ -33,10 +33,20 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NOT NULL PRIMARY KEY);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'2 02:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'3 03:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'4 04:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
SELECT * FROM t1 ORDER BY c1;
c1
09:09:33
@@ -47,8 +57,6 @@ c1
DELETE FROM t1 WHERE c1 <= ADDTIME(NOW(),'2 02:01:01');
SELECT * FROM t1 ORDER BY c1;
c1
-12:10:34
-13:10:34
DROP TABLE t1;
CREATE TABLE t1(c1 DATETIME NOT NULL PRIMARY KEY);
SET TIMESTAMP=1171346973;
diff --git a/mysql-test/suite/engines/funcs/r/in_calendar_2_unique_constraints_duplicate_update.result b/mysql-test/suite/engines/funcs/r/in_calendar_2_unique_constraints_duplicate_update.result
index 9c56e23574d..c68baf685e2 100644
--- a/mysql-test/suite/engines/funcs/r/in_calendar_2_unique_constraints_duplicate_update.result
+++ b/mysql-test/suite/engines/funcs/r/in_calendar_2_unique_constraints_duplicate_update.result
@@ -66,12 +66,42 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NOT NULL, c2 TIME NULL, c3 TIME NULL, PRIMARY KEY(c1), UNIQUE(c2));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),ADDTIME(NOW(),'4 04:01:01'),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(ADDTIME(NOW(),'1 01:01:01'),ADDTIME(NOW(),'3 03:01:01'),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(ADDTIME(NOW(),'2 02:01:01'),ADDTIME(NOW(),'2 02:01:01'),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(ADDTIME(NOW(),'3 03:01:01'),ADDTIME(NOW(),'1 01:01:01'),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(ADDTIME(NOW(),'4 04:01:01'),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(ADDTIME(NOW(),'2 02:01:01'),ADDTIME(NOW(),'2 02:01:01'),NOW()) ON DUPLICATE KEY UPDATE c3=ADDTIME(NOW(),'6 06:01:01');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW()) ON DUPLICATE KEY UPDATE c3=ADDTIME(NOW(),'6 06:01:01');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
SELECT * FROM t1;
c1 c2 c3
09:09:33 13:10:34 15:10:34
diff --git a/mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_duplicate_update.result b/mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_duplicate_update.result
index 47355681eae..6e3f717e93d 100644
--- a/mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_duplicate_update.result
+++ b/mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_duplicate_update.result
@@ -29,8 +29,15 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NOT NULL PRIMARY KEY);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(NOW()) ON DUPLICATE KEY UPDATE c1=ADDTIME(NOW(),'2 02:01:01');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c1' at row 1
SELECT * FROM t1;
c1
10:10:34
diff --git a/mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_error.result b/mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_error.result
index f8bff355901..4644894beec 100644
--- a/mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_error.result
+++ b/mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_error.result
@@ -28,7 +28,11 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NOT NULL PRIMARY KEY);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(NOW());
ERROR 23000: Duplicate entry '09:09:33' for key 'PRIMARY'
SELECT * FROM t1;
diff --git a/mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_ignore.result b/mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_ignore.result
index f8bff355901..4644894beec 100644
--- a/mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_ignore.result
+++ b/mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_ignore.result
@@ -28,7 +28,11 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NOT NULL PRIMARY KEY);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(NOW());
ERROR 23000: Duplicate entry '09:09:33' for key 'PRIMARY'
SELECT * FROM t1;
diff --git a/mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_duplicate_update.result b/mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_duplicate_update.result
index 5c4307158fa..8af6ff6af13 100644
--- a/mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_duplicate_update.result
+++ b/mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_duplicate_update.result
@@ -29,8 +29,15 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NULL UNIQUE);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(NOW()) ON DUPLICATE KEY UPDATE c1=ADDTIME(NOW(),'2 02:01:01');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c1' at row 1
SELECT * FROM t1;
c1
10:10:34
diff --git a/mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_error.result b/mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_error.result
index 9f6a205530c..c96cd4ba8a8 100644
--- a/mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_error.result
+++ b/mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_error.result
@@ -28,7 +28,11 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NULL UNIQUE);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(NOW());
ERROR 23000: Duplicate entry '09:09:33' for key 'c1'
SELECT * FROM t1;
diff --git a/mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_ignore.result b/mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_ignore.result
index 5469527b762..210460d33f1 100644
--- a/mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_ignore.result
+++ b/mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_ignore.result
@@ -28,8 +28,14 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NULL UNIQUE);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT IGNORE INTO t1 (c1) VALUES(NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
SELECT * FROM t1;
c1
09:09:33
diff --git a/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_duplicate_update.result b/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_duplicate_update.result
index d7dfc9d794c..209f61440cd 100644
--- a/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_duplicate_update.result
+++ b/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_duplicate_update.result
@@ -61,11 +61,40 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NOT NULL, c2 TIME NOT NULL, c3 TIME NOT NULL, PRIMARY KEY(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),ADDTIME(NOW(),'1 01:01:01'),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(ADDTIME(NOW(),'1 01:01:01'),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW()) ON DUPLICATE KEY UPDATE c1=ADDTIME(NOW(),'2 02:01:01'),c2=ADDTIME(NOW(),'2 02:01:01'),c3=ADDTIME(NOW(),'2 02:01:01');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01')) ON DUPLICATE KEY UPDATE c1=ADDTIME(NOW(),'2 02:01:01'),c2=ADDTIME(NOW(),'2 02:01:01');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
SELECT * FROM t1;
c1 c2 c3
09:09:33 10:10:34 09:09:33
diff --git a/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_error.result b/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_error.result
index d71af8d6375..9c310d3d457 100644
--- a/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_error.result
+++ b/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_error.result
@@ -52,9 +52,25 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NOT NULL, c2 TIME NOT NULL, c3 TIME NOT NULL, PRIMARY KEY(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),ADDTIME(NOW(),'1 01:01:01'),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(ADDTIME(NOW(),'1 01:01:01'),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
ERROR 23000: Duplicate entry '09:09:33-09:09:33-09:09:33' for key 'PRIMARY'
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01'));
diff --git a/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_ignore.result b/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_ignore.result
index d71af8d6375..9c310d3d457 100644
--- a/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_ignore.result
+++ b/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_ignore.result
@@ -52,9 +52,25 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NOT NULL, c2 TIME NOT NULL, c3 TIME NOT NULL, PRIMARY KEY(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),ADDTIME(NOW(),'1 01:01:01'),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(ADDTIME(NOW(),'1 01:01:01'),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
ERROR 23000: Duplicate entry '09:09:33-09:09:33-09:09:33' for key 'PRIMARY'
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01'));
diff --git a/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_duplicate_update.result b/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_duplicate_update.result
index edad4bb218d..fe509a0615c 100644
--- a/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_duplicate_update.result
+++ b/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_duplicate_update.result
@@ -61,11 +61,40 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NULL, c2 TIME NULL, c3 TIME NULL, UNIQUE(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),ADDTIME(NOW(),'1 01:01:01'),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(ADDTIME(NOW(),'1 01:01:01'),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW()) ON DUPLICATE KEY UPDATE c1=ADDTIME(NOW(),'2 02:01:01'),c2=ADDTIME(NOW(),'2 02:01:01'),c3=ADDTIME(NOW(),'2 02:01:01');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01')) ON DUPLICATE KEY UPDATE c1=ADDTIME(NOW(),'2 02:01:01'),c2=ADDTIME(NOW(),'2 02:01:01');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
SELECT * FROM t1;
c1 c2 c3
09:09:33 10:10:34 09:09:33
diff --git a/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_error.result b/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_error.result
index 4d7cadac70c..78b0e81cd56 100644
--- a/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_error.result
+++ b/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_error.result
@@ -52,9 +52,25 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NULL, c2 TIME NULL, c3 TIME NULL, UNIQUE(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),ADDTIME(NOW(),'1 01:01:01'),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(ADDTIME(NOW(),'1 01:01:01'),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
ERROR 23000: Duplicate entry '09:09:33-09:09:33-09:09:33' for key 'c1'
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01'));
diff --git a/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_ignore.result b/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_ignore.result
index 31f7db1dc9a..a884345be84 100644
--- a/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_ignore.result
+++ b/mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_ignore.result
@@ -56,11 +56,35 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NULL, c2 TIME NULL, c3 TIME NULL, UNIQUE(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),ADDTIME(NOW(),'1 01:01:01'),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(ADDTIME(NOW(),'1 01:01:01'),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT IGNORE INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT IGNORE INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
SELECT * FROM t1;
c1 c2 c3
09:09:33 09:09:33 09:09:33
diff --git a/mysql-test/suite/engines/funcs/r/in_multicolumn_number_pk_constraint_duplicate_update.result b/mysql-test/suite/engines/funcs/r/in_multicolumn_number_pk_constraint_duplicate_update.result
index d7dfc9d794c..209f61440cd 100644
--- a/mysql-test/suite/engines/funcs/r/in_multicolumn_number_pk_constraint_duplicate_update.result
+++ b/mysql-test/suite/engines/funcs/r/in_multicolumn_number_pk_constraint_duplicate_update.result
@@ -61,11 +61,40 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NOT NULL, c2 TIME NOT NULL, c3 TIME NOT NULL, PRIMARY KEY(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),ADDTIME(NOW(),'1 01:01:01'),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(ADDTIME(NOW(),'1 01:01:01'),NOW(),NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW()) ON DUPLICATE KEY UPDATE c1=ADDTIME(NOW(),'2 02:01:01'),c2=ADDTIME(NOW(),'2 02:01:01'),c3=ADDTIME(NOW(),'2 02:01:01');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),ADDTIME(NOW(),'1 01:01:01')) ON DUPLICATE KEY UPDATE c1=ADDTIME(NOW(),'2 02:01:01'),c2=ADDTIME(NOW(),'2 02:01:01');
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c1' at row 1
+Note 1265 Data truncated for column 'c2' at row 1
SELECT * FROM t1;
c1 c2 c3
09:09:33 10:10:34 09:09:33
diff --git a/mysql-test/suite/engines/funcs/r/in_number_boundary_error.result b/mysql-test/suite/engines/funcs/r/in_number_boundary_error.result
index 556b5a05764..53964697506 100644
--- a/mysql-test/suite/engines/funcs/r/in_number_boundary_error.result
+++ b/mysql-test/suite/engines/funcs/r/in_number_boundary_error.result
@@ -7,7 +7,7 @@ INSERT INTO t4 (c1) VALUES(0);
INSERT INTO t4 (c1) VALUES(-1);
ERROR 22003: Out of range value for column 'c1' at row 1
INSERT INTO t4 (c1) VALUES('x');
-ERROR HY000: Incorrect integer value: 'x' for column 'c1' at row 1
+ERROR 22007: Incorrect integer value: 'x' for column 'c1' at row 1
INSERT INTO t4 (c1) VALUES('9');
SELECT COUNT(c1) AS total_rows FROM t4;
total_rows
@@ -26,7 +26,7 @@ INSERT INTO t4 (c1) VALUES(0);
INSERT INTO t4 (c1) VALUES(-1);
ERROR 22003: Out of range value for column 'c1' at row 1
INSERT INTO t4 (c1) VALUES('x');
-ERROR HY000: Incorrect integer value: 'x' for column 'c1' at row 1
+ERROR 22007: Incorrect integer value: 'x' for column 'c1' at row 1
INSERT INTO t4 (c1) VALUES('9');
SELECT COUNT(c1) AS total_rows FROM t4;
total_rows
@@ -45,7 +45,7 @@ INSERT INTO t4 (c1) VALUES(0);
INSERT INTO t4 (c1) VALUES(-1);
ERROR 22003: Out of range value for column 'c1' at row 1
INSERT INTO t4 (c1) VALUES('x');
-ERROR HY000: Incorrect integer value: 'x' for column 'c1' at row 1
+ERROR 22007: Incorrect integer value: 'x' for column 'c1' at row 1
INSERT INTO t4 (c1) VALUES('9');
SELECT COUNT(c1) AS total_rows FROM t4;
total_rows
@@ -64,7 +64,7 @@ INSERT INTO t4 (c1) VALUES(0);
INSERT INTO t4 (c1) VALUES(-1);
ERROR 22003: Out of range value for column 'c1' at row 1
INSERT INTO t4 (c1) VALUES('x');
-ERROR HY000: Incorrect integer value: 'x' for column 'c1' at row 1
+ERROR 22007: Incorrect integer value: 'x' for column 'c1' at row 1
INSERT INTO t4 (c1) VALUES('9');
SELECT COUNT(c1) AS total_rows FROM t4;
total_rows
@@ -83,7 +83,7 @@ INSERT INTO t4 (c1) VALUES(0);
INSERT INTO t4 (c1) VALUES(-1);
ERROR 22003: Out of range value for column 'c1' at row 1
INSERT INTO t4 (c1) VALUES('x');
-ERROR HY000: Incorrect integer value: 'x' for column 'c1' at row 1
+ERROR 22007: Incorrect integer value: 'x' for column 'c1' at row 1
INSERT INTO t4 (c1) VALUES('9');
SELECT COUNT(c1) AS total_rows FROM t4;
total_rows
@@ -102,7 +102,7 @@ INSERT INTO t4 (c1) VALUES(0);
INSERT INTO t4 (c1) VALUES(-1);
ERROR 22003: Out of range value for column 'c1' at row 1
INSERT INTO t4 (c1) VALUES('x');
-ERROR HY000: Incorrect integer value: 'x' for column 'c1' at row 1
+ERROR 22007: Incorrect integer value: 'x' for column 'c1' at row 1
INSERT INTO t4 (c1) VALUES('9');
SELECT COUNT(c1) AS total_rows FROM t4;
total_rows
diff --git a/mysql-test/suite/engines/funcs/r/in_number_decimal_boundary_error.result b/mysql-test/suite/engines/funcs/r/in_number_decimal_boundary_error.result
index fe7fc0e38d7..62ad9a568f9 100644
--- a/mysql-test/suite/engines/funcs/r/in_number_decimal_boundary_error.result
+++ b/mysql-test/suite/engines/funcs/r/in_number_decimal_boundary_error.result
@@ -7,7 +7,7 @@ INSERT INTO t5 (c1) VALUES(0);
INSERT INTO t5 (c1) VALUES(-1);
ERROR 22003: Out of range value for column 'c1' at row 1
INSERT INTO t5 (c1) VALUES('x');
-ERROR HY000: Incorrect decimal value: 'x' for column 'c1' at row 1
+ERROR 22007: Incorrect decimal value: 'x' for column 'c1' at row 1
INSERT INTO t5 (c1) VALUES(999999);
ERROR 22003: Out of range value for column 'c1' at row 1
SELECT COUNT(c1) AS total_rows FROM t5;
@@ -27,7 +27,7 @@ INSERT INTO t5 (c1) VALUES(0);
INSERT INTO t5 (c1) VALUES(-1);
ERROR 22003: Out of range value for column 'c1' at row 1
INSERT INTO t5 (c1) VALUES('x');
-ERROR HY000: Incorrect decimal value: 'x' for column 'c1' at row 1
+ERROR 22007: Incorrect decimal value: 'x' for column 'c1' at row 1
INSERT INTO t5 (c1) VALUES(999999);
ERROR 22003: Out of range value for column 'c1' at row 1
SELECT COUNT(c1) AS total_rows FROM t5;
@@ -47,7 +47,7 @@ INSERT INTO t5 (c1) VALUES(0);
INSERT INTO t5 (c1) VALUES(-1);
ERROR 22003: Out of range value for column 'c1' at row 1
INSERT INTO t5 (c1) VALUES('x');
-ERROR HY000: Incorrect decimal value: 'x' for column 'c1' at row 1
+ERROR 22007: Incorrect decimal value: 'x' for column 'c1' at row 1
INSERT INTO t5 (c1) VALUES(999999);
ERROR 22003: Out of range value for column 'c1' at row 1
SELECT COUNT(c1) AS total_rows FROM t5;
@@ -67,7 +67,7 @@ INSERT INTO t5 (c1) VALUES(0);
INSERT INTO t5 (c1) VALUES(-1);
ERROR 22003: Out of range value for column 'c1' at row 1
INSERT INTO t5 (c1) VALUES('x');
-ERROR HY000: Incorrect decimal value: 'x' for column 'c1' at row 1
+ERROR 22007: Incorrect decimal value: 'x' for column 'c1' at row 1
INSERT INTO t5 (c1) VALUES(999999);
ERROR 22003: Out of range value for column 'c1' at row 1
SELECT COUNT(c1) AS total_rows FROM t5;
diff --git a/mysql-test/suite/engines/funcs/r/ld_all_number_string_calendar_types.result b/mysql-test/suite/engines/funcs/r/ld_all_number_string_calendar_types.result
index 63d36edd3aa..4776a3ac748 100644
--- a/mysql-test/suite/engines/funcs/r/ld_all_number_string_calendar_types.result
+++ b/mysql-test/suite/engines/funcs/r/ld_all_number_string_calendar_types.result
@@ -61,6 +61,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -77,6 +81,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -93,6 +101,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -325,6 +337,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -341,6 +357,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -357,6 +377,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -589,6 +613,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -605,6 +633,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -621,6 +653,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -853,6 +889,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -869,6 +909,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -885,6 +929,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -1117,6 +1165,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -1133,6 +1185,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -1149,6 +1205,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -1381,6 +1441,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -1397,6 +1461,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -1413,6 +1481,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -1645,6 +1717,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -1661,6 +1737,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -1677,6 +1757,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -1909,6 +1993,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DEC NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -1925,6 +2013,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DEC NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -1941,6 +2033,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DEC NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -2173,6 +2269,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FIXED NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -2189,6 +2289,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FIXED NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -2205,6 +2309,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FIXED NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -2437,6 +2545,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 NUMERIC NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -2453,6 +2565,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 NUMERIC NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -2469,6 +2585,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 NUMERIC NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -2701,6 +2821,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -2717,6 +2841,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -2733,6 +2861,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -2965,6 +3097,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -2981,6 +3117,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -2997,6 +3137,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -3229,6 +3373,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE PRECISION NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -3245,6 +3393,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE PRECISION NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -3261,6 +3413,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE PRECISION NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -3493,6 +3649,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FLOAT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -3509,6 +3669,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FLOAT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -3525,6 +3689,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FLOAT NOT NULL PRIMARY KEY, c2 CHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -3757,6 +3925,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -3773,6 +3945,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -3789,6 +3965,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -4021,6 +4201,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -4037,6 +4221,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -4053,6 +4241,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -4285,6 +4477,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -4301,6 +4497,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -4317,6 +4517,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -4549,6 +4753,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -4565,6 +4773,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -4581,6 +4793,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -4813,6 +5029,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -4829,6 +5049,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -4845,6 +5069,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -5077,6 +5305,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -5093,6 +5325,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -5109,6 +5345,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -5341,6 +5581,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -5357,6 +5601,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -5373,6 +5621,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -5605,6 +5857,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DEC NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -5621,6 +5877,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DEC NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -5637,6 +5897,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DEC NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -5869,6 +6133,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FIXED NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -5885,6 +6153,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FIXED NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -5901,6 +6173,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FIXED NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -6133,6 +6409,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 NUMERIC NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -6149,6 +6429,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 NUMERIC NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -6165,6 +6449,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 NUMERIC NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -6397,6 +6685,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -6413,6 +6705,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -6429,6 +6725,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -6661,6 +6961,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -6677,6 +6981,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -6693,6 +7001,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -6925,6 +7237,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE PRECISION NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -6941,6 +7257,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE PRECISION NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -6957,6 +7277,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE PRECISION NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -7189,6 +7513,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FLOAT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -7205,6 +7533,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FLOAT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -7221,6 +7553,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FLOAT NOT NULL PRIMARY KEY, c2 VARCHAR(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -7453,6 +7789,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -7469,6 +7809,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -7485,6 +7829,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -7717,6 +8065,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -7733,6 +8085,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -7749,6 +8105,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -7981,6 +8341,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -7997,6 +8361,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -8013,6 +8381,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -8245,6 +8617,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -8261,6 +8637,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -8277,6 +8657,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -8509,6 +8893,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -8525,6 +8913,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -8541,6 +8933,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -8773,6 +9169,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -8789,6 +9189,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -8805,6 +9209,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -9037,6 +9445,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -9053,6 +9465,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -9069,6 +9485,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -9301,6 +9721,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DEC NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -9317,6 +9741,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DEC NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -9333,6 +9761,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DEC NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -9565,6 +9997,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FIXED NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -9581,6 +10017,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FIXED NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -9597,6 +10037,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FIXED NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -9829,6 +10273,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 NUMERIC NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -9845,6 +10293,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 NUMERIC NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -9861,6 +10313,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 NUMERIC NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -10093,6 +10549,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -10109,6 +10569,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -10125,6 +10589,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -10357,6 +10825,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -10373,6 +10845,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -10389,6 +10865,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -10621,6 +11101,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE PRECISION NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -10637,6 +11121,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE PRECISION NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -10653,6 +11141,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE PRECISION NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -10885,6 +11377,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FLOAT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -10901,6 +11397,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FLOAT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -10917,6 +11417,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FLOAT NOT NULL PRIMARY KEY, c2 BINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -11149,6 +11653,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -11165,6 +11673,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -11181,6 +11693,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 TINYINT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -11413,6 +11929,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -11429,6 +11949,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -11445,6 +11969,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 SMALLINT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -11677,6 +12205,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -11693,6 +12225,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -11709,6 +12245,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -11941,6 +12481,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -11957,6 +12501,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -11973,6 +12521,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -12205,6 +12757,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -12221,6 +12777,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -12237,6 +12797,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 INTEGER NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -12469,6 +13033,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -12485,6 +13053,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -12501,6 +13073,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 BIGINT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -12733,6 +13309,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -12749,6 +13329,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -12765,6 +13349,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -12997,6 +13585,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DEC NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -13013,6 +13605,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DEC NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -13029,6 +13625,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DEC NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -13261,6 +13861,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FIXED NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -13277,6 +13881,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FIXED NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -13293,6 +13901,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FIXED NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -13525,6 +14137,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 NUMERIC NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -13541,6 +14157,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 NUMERIC NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -13557,6 +14177,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 NUMERIC NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -13789,6 +14413,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -13805,6 +14433,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -13821,6 +14453,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -14053,6 +14689,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -14069,6 +14709,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -14085,6 +14729,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -14317,6 +14965,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE PRECISION NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -14333,6 +14985,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE PRECISION NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -14349,6 +15005,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 DOUBLE PRECISION NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -14581,6 +15241,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FLOAT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -14597,6 +15261,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FLOAT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
@@ -14613,6 +15281,10 @@ c1 c2 c3
DROP TABLE t1;
CREATE TABLE t1 (c1 FLOAT NOT NULL PRIMARY KEY, c2 VARBINARY(10), c3 TIME);
LOAD DATA LOCAL INFILE 'suite/engines/funcs/t/load_simple.inc' INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
+Warnings:
+Note 1265 Data truncated for column 'c3' at row 1
+Note 1265 Data truncated for column 'c3' at row 2
+Note 1265 Data truncated for column 'c3' at row 3
SELECT * INTO OUTFILE '../../tmp/t1.dat' FIELDS ENCLOSED BY '"' OPTIONALLY ENCLOSED BY ':' LINES TERMINATED BY '\r\n' FROM t1;
SELECT * FROM t1 ORDER BY c1;
c1 c2 c3
diff --git a/mysql-test/suite/engines/funcs/r/sq_all.result b/mysql-test/suite/engines/funcs/r/sq_all.result
index ac1908b7b1b..24e62a3f3ba 100644
--- a/mysql-test/suite/engines/funcs/r/sq_all.result
+++ b/mysql-test/suite/engines/funcs/r/sq_all.result
@@ -13,13 +13,10 @@ SELECT c1 FROM t1 WHERE c1 > ALL (SELECT c1 FROM t2);
c1
SELECT c1 FROM t1 WHERE c1 >= ALL (SELECT c1 FROM t2);
c1
-100
SELECT c1 FROM t1 WHERE c1 = ALL (SELECT c1 FROM t2);
c1
SELECT c1 FROM t1 WHERE c1 <= ALL (SELECT c1 FROM t2);
c1
-1
-2
SELECT c1 FROM t1 WHERE c1 <> ALL (SELECT c1 FROM t2);
c1
DROP TABLE t1;
@@ -37,13 +34,10 @@ SELECT c1 FROM t1 WHERE c1 > ALL (SELECT c1 FROM t2);
c1
SELECT c1 FROM t1 WHERE c1 >= ALL (SELECT c1 FROM t2);
c1
-100
SELECT c1 FROM t1 WHERE c1 = ALL (SELECT c1 FROM t2);
c1
SELECT c1 FROM t1 WHERE c1 <= ALL (SELECT c1 FROM t2);
c1
-1
-2
SELECT c1 FROM t1 WHERE c1 <> ALL (SELECT c1 FROM t2);
c1
DROP TABLE t1;
@@ -61,13 +55,10 @@ SELECT c1 FROM t1 WHERE c1 > ALL (SELECT c1 FROM t2);
c1
SELECT c1 FROM t1 WHERE c1 >= ALL (SELECT c1 FROM t2);
c1
-100
SELECT c1 FROM t1 WHERE c1 = ALL (SELECT c1 FROM t2);
c1
SELECT c1 FROM t1 WHERE c1 <= ALL (SELECT c1 FROM t2);
c1
-1
-2
SELECT c1 FROM t1 WHERE c1 <> ALL (SELECT c1 FROM t2);
c1
DROP TABLE t1;
@@ -85,13 +76,10 @@ SELECT c1 FROM t1 WHERE c1 > ALL (SELECT c1 FROM t2);
c1
SELECT c1 FROM t1 WHERE c1 >= ALL (SELECT c1 FROM t2);
c1
-100
SELECT c1 FROM t1 WHERE c1 = ALL (SELECT c1 FROM t2);
c1
SELECT c1 FROM t1 WHERE c1 <= ALL (SELECT c1 FROM t2);
c1
-1
-2
SELECT c1 FROM t1 WHERE c1 <> ALL (SELECT c1 FROM t2);
c1
DROP TABLE t1;
diff --git a/mysql-test/suite/engines/funcs/r/up_calendar_range.result b/mysql-test/suite/engines/funcs/r/up_calendar_range.result
index dbd6e2cf8a6..10bef827a88 100644
--- a/mysql-test/suite/engines/funcs/r/up_calendar_range.result
+++ b/mysql-test/suite/engines/funcs/r/up_calendar_range.result
@@ -39,10 +39,20 @@ DROP TABLE t1;
CREATE TABLE t1(c1 TIME NOT NULL);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'1 01:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'2 02:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'3 03:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
INSERT INTO t1 (c1) VALUES(ADDTIME(NOW(),'4 04:01:01'));
+Warnings:
+Note 1265 Data truncated for column 'c1' at row 1
SELECT * FROM t1 ORDER BY c1;
c1
09:09:33
@@ -54,10 +64,10 @@ UPDATE t1 SET c1 = NOW() WHERE c1 >= ADDTIME(NOW(),'2 02:01:01');
SELECT * FROM t1 ORDER BY c1;
c1
09:09:33
-09:09:33
-09:09:33
-09:09:33
10:10:34
+11:10:34
+12:10:34
+13:10:34
DROP TABLE t1;
CREATE TABLE t1(c1 DATETIME NOT NULL);
SET TIMESTAMP=1171346973;
diff --git a/mysql-test/suite/engines/funcs/t/se_join_left.test b/mysql-test/suite/engines/funcs/t/se_join_left.test
index 005936acb3b..792f2cdd699 100644
--- a/mysql-test/suite/engines/funcs/t/se_join_left.test
+++ b/mysql-test/suite/engines/funcs/t/se_join_left.test
@@ -12,8 +12,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -27,8 +30,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -42,8 +48,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -57,8 +66,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -72,8 +84,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -87,8 +102,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -102,8 +120,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -117,8 +138,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -132,8 +156,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -147,8 +174,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -162,8 +192,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -177,8 +210,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -192,8 +228,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -207,8 +246,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -222,8 +264,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -237,8 +282,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -252,8 +300,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -267,8 +318,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -282,8 +336,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -297,8 +354,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -312,8 +372,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -327,8 +390,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -342,8 +408,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -357,8 +426,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -372,8 +444,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -387,8 +462,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -402,8 +480,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -417,8 +498,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -432,8 +516,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -447,8 +534,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -462,8 +552,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -477,8 +570,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -492,8 +588,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -507,8 +606,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -522,8 +624,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -537,8 +642,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -552,8 +660,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -567,8 +678,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -582,8 +696,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -597,8 +714,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -612,8 +732,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -627,8 +750,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -642,8 +768,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -657,8 +786,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -672,8 +804,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -687,8 +822,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -702,8 +840,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -717,8 +858,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -732,8 +876,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -747,8 +894,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -762,8 +912,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -777,8 +930,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -792,8 +948,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -807,8 +966,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -822,8 +984,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -837,8 +1002,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -852,8 +1020,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -867,8 +1038,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -882,8 +1056,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -897,8 +1074,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -912,8 +1092,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -927,8 +1110,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -942,8 +1128,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -957,8 +1146,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -972,8 +1164,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -987,8 +1182,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1002,8 +1200,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1017,8 +1218,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1032,8 +1236,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1047,8 +1254,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1062,8 +1272,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1077,8 +1290,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1092,8 +1308,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1107,8 +1326,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1122,8 +1344,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1137,8 +1362,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1152,8 +1380,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1167,8 +1398,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1182,8 +1416,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1197,8 +1434,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1212,8 +1452,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1227,8 +1470,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1242,8 +1488,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1257,8 +1506,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1272,8 +1524,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1287,8 +1542,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1302,8 +1560,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1317,8 +1578,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1332,8 +1596,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1347,8 +1614,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1362,8 +1632,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1377,8 +1650,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1392,8 +1668,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1407,8 +1686,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1422,8 +1704,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1437,8 +1722,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1452,8 +1740,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1467,8 +1758,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1482,8 +1776,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1497,8 +1794,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1512,8 +1812,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1527,8 +1830,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1542,8 +1848,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1557,8 +1866,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1572,8 +1884,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1587,8 +1902,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1602,8 +1920,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1617,8 +1938,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1632,8 +1956,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1647,8 +1974,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1662,8 +1992,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1677,8 +2010,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1692,8 +2028,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1707,8 +2046,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1722,8 +2064,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1737,8 +2082,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1752,8 +2100,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1767,8 +2118,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1782,8 +2136,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1797,8 +2154,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1812,8 +2172,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1827,8 +2190,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1842,8 +2208,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1857,8 +2226,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1872,8 +2244,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1887,8 +2262,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1902,8 +2280,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1917,8 +2298,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1932,8 +2316,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1947,8 +2334,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1962,8 +2352,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1977,8 +2370,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1992,8 +2388,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2007,8 +2406,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2022,8 +2424,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2037,8 +2442,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2052,8 +2460,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2067,8 +2478,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2082,8 +2496,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2097,8 +2514,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2112,8 +2532,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2127,8 +2550,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2142,8 +2568,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2157,8 +2586,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2172,8 +2604,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2187,8 +2622,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2202,8 +2640,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2217,8 +2658,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2232,8 +2676,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2247,8 +2694,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2262,8 +2712,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2277,8 +2730,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2292,8 +2748,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2307,8 +2766,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2322,8 +2784,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2337,8 +2802,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2352,8 +2820,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2367,8 +2838,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2382,8 +2856,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2397,8 +2874,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2412,8 +2892,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2427,8 +2910,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2442,8 +2928,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2457,8 +2946,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2472,8 +2964,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2487,8 +2982,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2502,8 +3000,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2517,8 +3018,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2532,8 +3036,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2547,8 +3054,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2562,8 +3072,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2577,8 +3090,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2592,8 +3108,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2607,8 +3126,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2622,8 +3144,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2637,8 +3162,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2652,8 +3180,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2667,8 +3198,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2682,8 +3216,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2697,8 +3234,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2712,8 +3252,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2727,8 +3270,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2742,8 +3288,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2757,8 +3306,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2772,8 +3324,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2787,8 +3342,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 USING (c1);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2802,8 +3360,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2817,8 +3378,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2832,8 +3396,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2847,8 +3414,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2862,8 +3432,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2877,8 +3450,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 USING (c1);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2892,8 +3468,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2907,8 +3486,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2922,8 +3504,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2937,8 +3522,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2952,8 +3540,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2967,8 +3558,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 USING (c1);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2982,8 +3576,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2997,8 +3594,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -3012,8 +3612,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -3027,8 +3630,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -3042,8 +3648,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -3057,8 +3666,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 USING (c1);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -3072,8 +3684,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -3087,8 +3702,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -3102,8 +3720,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -3117,8 +3738,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -3132,8 +3756,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -3147,8 +3774,11 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 USING (c1);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
diff --git a/mysql-test/suite/engines/funcs/t/se_join_left_outer.test b/mysql-test/suite/engines/funcs/t/se_join_left_outer.test
index d986159078b..5e6b8af633b 100644
--- a/mysql-test/suite/engines/funcs/t/se_join_left_outer.test
+++ b/mysql-test/suite/engines/funcs/t/se_join_left_outer.test
@@ -12,7 +12,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -26,7 +28,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -40,7 +44,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -54,7 +60,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -68,7 +76,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -82,7 +92,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -96,7 +108,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -110,7 +124,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -124,7 +140,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -138,7 +156,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -152,7 +172,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -166,7 +188,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -180,7 +204,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -194,7 +220,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -208,7 +236,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -222,7 +252,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -236,7 +268,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -250,7 +284,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -264,7 +300,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -278,7 +316,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -292,7 +332,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -306,7 +348,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -320,7 +364,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -334,7 +380,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -348,7 +396,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -362,7 +412,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -376,7 +428,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -390,7 +444,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -404,7 +460,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -418,7 +476,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -432,7 +492,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -446,7 +508,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -460,7 +524,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -474,7 +540,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -488,7 +556,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -502,7 +572,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -516,7 +588,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -530,7 +604,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -544,7 +620,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -558,7 +636,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -572,7 +652,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -586,7 +668,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -600,7 +684,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -614,7 +700,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -628,7 +716,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -642,7 +732,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -656,7 +748,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -670,7 +764,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -684,7 +780,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -698,7 +796,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -712,7 +812,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -726,7 +828,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -740,7 +844,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -754,7 +860,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -768,7 +876,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -782,7 +892,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -796,7 +908,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -810,7 +924,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -824,7 +940,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -838,7 +956,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -852,7 +972,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -866,7 +988,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -880,7 +1004,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -894,7 +1020,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -908,7 +1036,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -922,7 +1052,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -936,7 +1068,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -950,7 +1084,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -964,7 +1100,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -978,7 +1116,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -992,7 +1132,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1006,7 +1148,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1020,7 +1164,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1034,7 +1180,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1048,7 +1196,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1062,7 +1212,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1076,7 +1228,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1090,7 +1244,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1104,7 +1260,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1118,7 +1276,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1132,7 +1292,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1146,7 +1308,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1160,7 +1324,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1174,7 +1340,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1188,7 +1356,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1202,7 +1372,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1216,7 +1388,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1230,7 +1404,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1244,7 +1420,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1258,7 +1436,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1272,7 +1452,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1286,7 +1468,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1300,7 +1484,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1314,7 +1500,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1328,7 +1516,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1342,7 +1532,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1356,7 +1548,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1370,7 +1564,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1384,7 +1580,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1398,7 +1596,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1412,7 +1612,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1426,7 +1628,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1440,7 +1644,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1454,7 +1660,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1468,7 +1676,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1482,7 +1692,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1496,7 +1708,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1510,7 +1724,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1524,7 +1740,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1538,7 +1756,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1552,7 +1772,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1566,7 +1788,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1580,7 +1804,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1594,7 +1820,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1608,7 +1836,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1622,7 +1852,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1636,7 +1868,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1650,7 +1884,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1664,7 +1900,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1678,7 +1916,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1692,7 +1932,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1706,7 +1948,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1720,7 +1964,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1734,7 +1980,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1748,7 +1996,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1762,7 +2012,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1776,7 +2028,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1790,7 +2044,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1804,7 +2060,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1818,7 +2076,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1832,7 +2092,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1846,7 +2108,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1860,7 +2124,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1874,7 +2140,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1888,7 +2156,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1902,7 +2172,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1916,7 +2188,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1930,7 +2204,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1944,7 +2220,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1958,7 +2236,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1972,7 +2252,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1986,7 +2268,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2000,7 +2284,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2014,7 +2300,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2028,7 +2316,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2042,7 +2332,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2056,7 +2348,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2070,7 +2364,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2084,7 +2380,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2098,7 +2396,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2112,7 +2412,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2126,7 +2428,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2140,7 +2444,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2154,7 +2460,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2168,7 +2476,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2182,7 +2492,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2196,7 +2508,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2210,7 +2524,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2224,7 +2540,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2238,7 +2556,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2252,7 +2572,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2266,7 +2588,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2280,7 +2604,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2294,7 +2620,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2308,7 +2636,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2322,7 +2652,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2336,7 +2668,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2350,7 +2684,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2364,7 +2700,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2378,7 +2716,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2392,7 +2732,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2406,7 +2748,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2420,7 +2764,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2434,7 +2780,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2448,7 +2796,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2462,7 +2812,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2476,7 +2828,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2490,7 +2844,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2504,7 +2860,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2518,7 +2876,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2532,7 +2892,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2546,7 +2908,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2560,7 +2924,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2574,7 +2940,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2588,7 +2956,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2602,7 +2972,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2616,7 +2988,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2630,7 +3004,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2644,7 +3020,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2658,7 +3036,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2672,7 +3052,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2686,7 +3068,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 LEFT OUTER JOIN t3 ON t1.c1 = t3.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2700,7 +3084,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2714,7 +3100,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2728,7 +3116,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2742,7 +3132,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2756,7 +3148,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2770,7 +3164,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 LEFT OUTER JOIN t4 ON t1.c1 = t4.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2784,7 +3180,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2798,7 +3196,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2812,7 +3212,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2826,7 +3228,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2840,7 +3244,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2854,7 +3260,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 LEFT OUTER JOIN t5 ON t1.c1 = t5.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2868,7 +3276,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2882,7 +3292,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2896,7 +3308,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2910,7 +3324,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2924,7 +3340,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2938,7 +3356,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 LEFT OUTER JOIN t6 ON t1.c1 = t6.c1 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
diff --git a/mysql-test/suite/engines/funcs/t/se_join_natural_left.test b/mysql-test/suite/engines/funcs/t/se_join_natural_left.test
index 2ff6276cfa5..7b9deea3cb6 100644
--- a/mysql-test/suite/engines/funcs/t/se_join_natural_left.test
+++ b/mysql-test/suite/engines/funcs/t/se_join_natural_left.test
@@ -12,7 +12,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -26,7 +28,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -40,7 +44,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -54,7 +60,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -68,7 +76,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -82,7 +92,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -96,7 +108,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -110,7 +124,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -124,7 +140,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -138,7 +156,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -152,7 +172,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -166,7 +188,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -180,7 +204,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -194,7 +220,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -208,7 +236,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -222,7 +252,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -236,7 +268,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -250,7 +284,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -264,7 +300,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -278,7 +316,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -292,7 +332,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -306,7 +348,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -320,7 +364,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -334,7 +380,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -348,7 +396,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -362,7 +412,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -376,7 +428,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -390,7 +444,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -404,7 +460,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -418,7 +476,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -432,7 +492,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -446,7 +508,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -460,7 +524,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -474,7 +540,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -488,7 +556,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -502,7 +572,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -516,7 +588,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -530,7 +604,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -544,7 +620,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -558,7 +636,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -572,7 +652,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -586,7 +668,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -600,7 +684,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -614,7 +700,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -628,7 +716,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -642,7 +732,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -656,7 +748,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -670,7 +764,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -684,7 +780,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -698,7 +796,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -712,7 +812,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -726,7 +828,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -740,7 +844,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -754,7 +860,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -768,7 +876,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -782,7 +892,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -796,7 +908,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -810,7 +924,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -824,7 +940,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -838,7 +956,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -852,7 +972,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -866,7 +988,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -880,7 +1004,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -894,7 +1020,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -908,7 +1036,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -922,7 +1052,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -936,7 +1068,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -950,7 +1084,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -964,7 +1100,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -978,7 +1116,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -992,7 +1132,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1006,7 +1148,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1020,7 +1164,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1034,7 +1180,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1048,7 +1196,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1062,7 +1212,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1076,7 +1228,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1090,7 +1244,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1104,7 +1260,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1118,7 +1276,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1132,7 +1292,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1146,7 +1308,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1160,7 +1324,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1174,7 +1340,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1188,7 +1356,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1202,7 +1372,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1216,7 +1388,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1230,7 +1404,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1244,7 +1420,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1258,7 +1436,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1272,7 +1452,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1286,7 +1468,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1300,7 +1484,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1314,7 +1500,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1328,7 +1516,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1342,7 +1532,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1356,7 +1548,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1370,7 +1564,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1384,7 +1580,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1398,7 +1596,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1412,7 +1612,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1426,7 +1628,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1440,7 +1644,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1454,7 +1660,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1468,7 +1676,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1482,7 +1692,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1496,7 +1708,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1510,7 +1724,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1524,7 +1740,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1538,7 +1756,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1552,7 +1772,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1566,7 +1788,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1580,7 +1804,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1594,7 +1820,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1608,7 +1836,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1622,7 +1852,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1636,7 +1868,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1650,7 +1884,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1664,7 +1900,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1678,7 +1916,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1692,7 +1932,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1706,7 +1948,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1720,7 +1964,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1734,7 +1980,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1748,7 +1996,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1762,7 +2012,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1776,7 +2028,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1790,7 +2044,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1804,7 +2060,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1818,7 +2076,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1832,7 +2092,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1846,7 +2108,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1860,7 +2124,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1874,7 +2140,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1888,7 +2156,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1902,7 +2172,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1916,7 +2188,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1930,7 +2204,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1944,7 +2220,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1958,7 +2236,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1972,7 +2252,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1986,7 +2268,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2000,7 +2284,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2014,7 +2300,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2028,7 +2316,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2042,7 +2332,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2056,7 +2348,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2070,7 +2364,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2084,7 +2380,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2098,7 +2396,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2112,7 +2412,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2126,7 +2428,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2140,7 +2444,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2154,7 +2460,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2168,7 +2476,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2182,7 +2492,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2196,7 +2508,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2210,7 +2524,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2224,7 +2540,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2238,7 +2556,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2252,7 +2572,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2266,7 +2588,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2280,7 +2604,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2294,7 +2620,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2308,7 +2636,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2322,7 +2652,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2336,7 +2668,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2350,7 +2684,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2364,7 +2700,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2378,7 +2716,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2392,7 +2732,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2406,7 +2748,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2420,7 +2764,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2434,7 +2780,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2448,7 +2796,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2462,7 +2812,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2476,7 +2828,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2490,7 +2844,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2504,7 +2860,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2518,7 +2876,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2532,7 +2892,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2546,7 +2908,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2560,7 +2924,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2574,7 +2940,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2588,7 +2956,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2602,7 +2972,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT JOIN t2 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2616,7 +2988,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2630,7 +3004,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2644,7 +3020,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2658,7 +3036,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2672,7 +3052,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2686,7 +3068,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT JOIN t3 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2700,7 +3084,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2714,7 +3100,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2728,7 +3116,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2742,7 +3132,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2756,7 +3148,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2770,7 +3164,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT JOIN t4 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2784,7 +3180,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2798,7 +3196,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2812,7 +3212,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2826,7 +3228,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2840,7 +3244,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2854,7 +3260,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT JOIN t5 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2868,7 +3276,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2882,7 +3292,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2896,7 +3308,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2910,7 +3324,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2924,7 +3340,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2938,7 +3356,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT JOIN t6 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
diff --git a/mysql-test/suite/engines/funcs/t/se_join_natural_left_outer.test b/mysql-test/suite/engines/funcs/t/se_join_natural_left_outer.test
index 93384418d80..d484cbe5216 100644
--- a/mysql-test/suite/engines/funcs/t/se_join_natural_left_outer.test
+++ b/mysql-test/suite/engines/funcs/t/se_join_natural_left_outer.test
@@ -12,7 +12,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -26,7 +28,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -40,7 +44,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -54,7 +60,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -68,7 +76,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -82,7 +92,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -96,7 +108,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -110,7 +124,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -124,7 +140,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -138,7 +156,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -152,7 +172,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -166,7 +188,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -180,7 +204,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -194,7 +220,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -208,7 +236,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -222,7 +252,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -236,7 +268,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -250,7 +284,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -264,7 +300,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -278,7 +316,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -292,7 +332,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -306,7 +348,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -320,7 +364,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -334,7 +380,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -348,7 +396,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -362,7 +412,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -376,7 +428,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -390,7 +444,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -404,7 +460,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -418,7 +476,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 < 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -432,7 +492,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -446,7 +508,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -460,7 +524,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -474,7 +540,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -488,7 +556,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -502,7 +572,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -516,7 +588,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -530,7 +604,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -544,7 +620,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -558,7 +636,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -572,7 +652,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -586,7 +668,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -600,7 +684,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -614,7 +700,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -628,7 +716,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -642,7 +732,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -656,7 +748,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -670,7 +764,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -684,7 +780,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -698,7 +796,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -712,7 +812,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -726,7 +828,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -740,7 +844,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -754,7 +860,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -768,7 +876,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -782,7 +892,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -796,7 +908,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -810,7 +924,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -824,7 +940,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -838,7 +956,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -852,7 +972,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -866,7 +988,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -880,7 +1004,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -894,7 +1020,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -908,7 +1036,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -922,7 +1052,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -936,7 +1068,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -950,7 +1084,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -964,7 +1100,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -978,7 +1116,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -992,7 +1132,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1006,7 +1148,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1020,7 +1164,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1034,7 +1180,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1048,7 +1196,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1062,7 +1212,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1076,7 +1228,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1090,7 +1244,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1104,7 +1260,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1118,7 +1276,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1132,7 +1292,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1146,7 +1308,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1160,7 +1324,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1174,7 +1340,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1188,7 +1356,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1202,7 +1372,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1216,7 +1388,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1230,7 +1404,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1244,7 +1420,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1258,7 +1436,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 = 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1272,7 +1452,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1286,7 +1468,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1300,7 +1484,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1314,7 +1500,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1328,7 +1516,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1342,7 +1532,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1356,7 +1548,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1370,7 +1564,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1384,7 +1580,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1398,7 +1596,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1412,7 +1612,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1426,7 +1628,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1440,7 +1644,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1454,7 +1660,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1468,7 +1676,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1482,7 +1692,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1496,7 +1708,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1510,7 +1724,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1524,7 +1740,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1538,7 +1756,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1552,7 +1772,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1566,7 +1788,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1580,7 +1804,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1594,7 +1820,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1608,7 +1836,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1622,7 +1852,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1636,7 +1868,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1650,7 +1884,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1664,7 +1900,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1678,7 +1916,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 >= 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1692,7 +1932,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1706,7 +1948,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1720,7 +1964,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1734,7 +1980,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1748,7 +1996,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1762,7 +2012,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1776,7 +2028,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1790,7 +2044,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1804,7 +2060,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1818,7 +2076,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1832,7 +2092,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1846,7 +2108,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1860,7 +2124,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1874,7 +2140,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1888,7 +2156,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1902,7 +2172,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -1916,7 +2188,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -1930,7 +2204,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -1944,7 +2220,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -1958,7 +2236,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -1972,7 +2252,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -1986,7 +2268,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2000,7 +2284,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2014,7 +2300,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2028,7 +2316,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2042,7 +2332,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2056,7 +2348,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2070,7 +2364,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2084,7 +2380,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2098,7 +2396,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 != 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2112,7 +2412,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2126,7 +2428,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2140,7 +2444,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2154,7 +2460,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2168,7 +2476,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2182,7 +2492,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2196,7 +2508,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2210,7 +2524,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2224,7 +2540,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2238,7 +2556,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2252,7 +2572,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2266,7 +2588,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2280,7 +2604,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2294,7 +2620,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2308,7 +2636,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2322,7 +2652,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2336,7 +2668,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2350,7 +2684,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2364,7 +2700,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2378,7 +2716,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2392,7 +2732,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2406,7 +2748,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2420,7 +2764,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2434,7 +2780,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2448,7 +2796,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2462,7 +2812,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2476,7 +2828,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2490,7 +2844,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2504,7 +2860,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2518,7 +2876,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2532,7 +2892,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2546,7 +2908,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2560,7 +2924,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2574,7 +2940,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2588,7 +2956,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2602,7 +2972,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2;
+--sorted_result
SELECT t1.c1,t2.c1 FROM t1 NATURAL LEFT OUTER JOIN t2 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2616,7 +2988,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2630,7 +3004,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2644,7 +3020,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2658,7 +3036,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2672,7 +3052,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2686,7 +3068,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3;
+--sorted_result
SELECT t1.c1,t3.c1 FROM t1 NATURAL LEFT OUTER JOIN t3 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2700,7 +3084,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2714,7 +3100,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2728,7 +3116,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2742,7 +3132,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2756,7 +3148,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2770,7 +3164,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4;
+--sorted_result
SELECT t1.c1,t4.c1 FROM t1 NATURAL LEFT OUTER JOIN t4 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2784,7 +3180,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2798,7 +3196,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2812,7 +3212,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2826,7 +3228,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2840,7 +3244,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2854,7 +3260,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5;
+--sorted_result
SELECT t1.c1,t5.c1 FROM t1 NATURAL LEFT OUTER JOIN t5 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 TINYINT NOT NULL);
@@ -2868,7 +3276,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 SMALLINT NOT NULL);
@@ -2882,7 +3292,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 MEDIUMINT NOT NULL);
@@ -2896,7 +3308,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INT NOT NULL);
@@ -2910,7 +3324,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 INTEGER NOT NULL);
@@ -2924,7 +3340,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
CREATE TABLE t1 (c1 BIGINT NOT NULL);
@@ -2938,7 +3356,9 @@ INSERT INTO t2 (c1) VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t3 (c1) VALUES(1),(3),(5),(7),(9);
INSERT INTO t4 (c1) VALUES(10);
INSERT INTO t5 (c1) VALUES(10),(11),(12),(13),(14);
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6;
+--sorted_result
SELECT t1.c1,t6.c1 FROM t1 NATURAL LEFT OUTER JOIN t6 WHERE t1.c1 <=> 5;
DROP TABLE t1,t2,t3,t4,t5,t6;
diff --git a/mysql-test/suite/engines/iuds/r/delete_time.result b/mysql-test/suite/engines/iuds/r/delete_time.result
index 619b31bf4ce..00b2262e07b 100644
--- a/mysql-test/suite/engines/iuds/r/delete_time.result
+++ b/mysql-test/suite/engines/iuds/r/delete_time.result
@@ -497,10 +497,10 @@ c2
00:13:13
00:51:51
01:01:01
-02:02:02
03:03:00
08:08:08
100:04:04
+11:11:11
11:11:27
125:00:00
125:05:00
@@ -644,7 +644,7 @@ c1 c2
-838:59:59 -838:59:59
00:04:00 00:04:00
00:54:54 00:54:54
-11:11:11 11:11:11
+02:02:02 02:02:02
12:34:56 NULL
SELECT * FROM t2;
c1 c2
diff --git a/mysql-test/suite/engines/iuds/r/insert_decimal.result b/mysql-test/suite/engines/iuds/r/insert_decimal.result
index c97d827f438..0af5a3bcca0 100644
--- a/mysql-test/suite/engines/iuds/r/insert_decimal.result
+++ b/mysql-test/suite/engines/iuds/r/insert_decimal.result
@@ -1013,7 +1013,7 @@ ROUND(c1,c2) TRUNCATE(c1,c2)
1.133000 1.132000
DROP TABLE t5;
CREATE TABLE t7(c1 DECIMAL(66,0));
-ERROR 42000: Too big precision 66 specified for column 'c1'. Maximum is 65.
+ERROR 42000: Too big precision 66 specified for 'c1'. Maximum is 65.
CREATE TABLE t7(c1 DECIMAL(5,10));
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'c1').
DROP TABLE t1,t2;
diff --git a/mysql-test/suite/engines/iuds/r/insert_number.result b/mysql-test/suite/engines/iuds/r/insert_number.result
index 66295047ffe..bad05c4bfcb 100644
--- a/mysql-test/suite/engines/iuds/r/insert_number.result
+++ b/mysql-test/suite/engines/iuds/r/insert_number.result
@@ -4957,12 +4957,20 @@ c1 c2 c3 c4 c5 c6 c7
0 -128 26 27 28 29 30
SELECT * FROM t3 WHERE c2 = -129 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -129 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -129 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -129 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 <> -129 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -128 1 2 3 4 5
@@ -5324,12 +5332,20 @@ c1 c2 c3 c4 c5 c6 c7
0 -128 26 27 28 29 30
SELECT * FROM t3 WHERE c2 = 128 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 128 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 128 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 128 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 <> 128 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -128 1 2 3 4 5
@@ -10646,12 +10662,20 @@ c1 c2 c3 c4 c5 c6 c7
0 -32768 26 27 28 29 30
SELECT * FROM t3 WHERE c2 = -32769 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -32769 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -32769 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -32769 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 <> -32769 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -32768 1 2 3 4 5
@@ -11026,12 +11050,20 @@ c1 c2 c3 c4 c5 c6 c7
0 -32768 26 27 28 29 30
SELECT * FROM t3 WHERE c2 = 32768 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 32768 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 32768 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 32768 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 <> 32768 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -32768 1 2 3 4 5
@@ -16440,12 +16472,20 @@ c1 c2 c3 c4 c5 c6 c7
0 -8388608 26 27 28 29 30
SELECT * FROM t3 WHERE c2 = -8388609 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -8388609 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -8388609 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -8388609 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 <> -8388609 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -8388608 1 2 3 4 5
@@ -16833,12 +16873,20 @@ c1 c2 c3 c4 c5 c6 c7
0 -8388608 26 27 28 29 30
SELECT * FROM t3 WHERE c2 = 8388608 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 8388608 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 8388608 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 8388608 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 <> 8388608 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -8388608 1 2 3 4 5
@@ -22339,12 +22387,20 @@ c1 c2 c3 c4 c5 c6 c7
0 -2147483648 26 27 28 29 30
SELECT * FROM t3 WHERE c2 = -2147483649 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -2147483649 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -2147483649 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -2147483649 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 <> -2147483649 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -2147483648 1 2 3 4 5
@@ -22745,12 +22801,20 @@ c1 c2 c3 c4 c5 c6 c7
0 -2147483648 26 27 28 29 30
SELECT * FROM t3 WHERE c2 = 2147483648 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 2147483648 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 2147483648 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 2147483648 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 <> 2147483648 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -2147483648 1 2 3 4 5
@@ -28261,12 +28325,20 @@ c1 c2 c3 c4 c5 c6 c7
0 -2147483648 26 27 28 29 30
SELECT * FROM t3 WHERE c2 = -2147483649 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -2147483649 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -2147483649 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = -2147483649 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 <> -2147483649 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -2147483648 1 2 3 4 5
@@ -28667,12 +28739,20 @@ c1 c2 c3 c4 c5 c6 c7
0 -2147483648 26 27 28 29 30
SELECT * FROM t3 WHERE c2 = 2147483648 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 2147483648 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 2147483648 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 2147483648 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 <> 2147483648 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -2147483648 1 2 3 4 5
@@ -32315,7 +32395,7 @@ total_rows min_value max(c1)
23 0 18446744073709551615
SELECT * FROM t2 WHERE c2 = -9223372036854775809;
c1 c2 c3 c4 c5 c6 c7
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
Warnings:
SELECT c1,c6 FROM t2;
c1 c6
@@ -34161,19 +34241,19 @@ c1 c2 c3 c4 c5 c6 c7
SELECT * FROM t3 WHERE c2 = -9223372036854775809 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 = -9223372036854775809 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 = -9223372036854775809 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 = -9223372036854775809 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 <> -9223372036854775809 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 1 2 3 4 5
@@ -34198,13 +34278,13 @@ c1 c2 c3 c4 c5 c6 c7
18446744073709551615 9223372036854775807 26 27 28 29 30
18446744073709551615 9223372036854775807 36 37 38 39 40
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 <> -9223372036854775809 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 1 2 3 4 5
0 -9223372036854775808 31 32 33 34 35
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 > -9223372036854775809 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 1 2 3 4 5
@@ -34229,13 +34309,13 @@ c1 c2 c3 c4 c5 c6 c7
18446744073709551615 9223372036854775807 26 27 28 29 30
18446744073709551615 9223372036854775807 36 37 38 39 40
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 > -9223372036854775809 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 1 2 3 4 5
0 -9223372036854775808 31 32 33 34 35
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 >= -9223372036854775809 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 1 2 3 4 5
@@ -34260,37 +34340,37 @@ c1 c2 c3 c4 c5 c6 c7
18446744073709551615 9223372036854775807 26 27 28 29 30
18446744073709551615 9223372036854775807 36 37 38 39 40
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 >= -9223372036854775809 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 1 2 3 4 5
0 -9223372036854775808 31 32 33 34 35
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 < -9223372036854775809 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 < -9223372036854775809 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 <= -9223372036854775809 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 <= -9223372036854775809 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 <=> -9223372036854775809 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 <=> -9223372036854775809 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 BETWEEN -9223372036854775809 AND 9223372036854775808 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 1 2 3 4 5
@@ -34315,13 +34395,13 @@ c1 c2 c3 c4 c5 c6 c7
18446744073709551615 9223372036854775807 26 27 28 29 30
18446744073709551615 9223372036854775807 36 37 38 39 40
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 BETWEEN -9223372036854775809 AND 9223372036854775808 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 1 2 3 4 5
0 -9223372036854775808 31 32 33 34 35
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 IN (-9223372036854775809,9223372036854775808) ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 1 2 3 4 5
@@ -34334,12 +34414,12 @@ SELECT * FROM t3 WHERE c2 >= -9223372036854775809 AND c2 < 9223372036854775808 A
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 >= -9223372036854775809 AND c2 < 9223372036854775808 AND c7 = 35 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 IS NULL ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
105 NULL 102 103 104 105 106
@@ -34397,13 +34477,13 @@ c1 c2 c3 c4 c5 c6 c7
18446744073709551615 9223372036854775807 36 37 38 39 40
18446744073709551615 9223372036854775807 26 27 28 29 30
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 <> -9223372036854775809 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
0 -9223372036854775808 1 2 3 4 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 > -9223372036854775809 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
@@ -34428,13 +34508,13 @@ c1 c2 c3 c4 c5 c6 c7
18446744073709551615 9223372036854775807 36 37 38 39 40
18446744073709551615 9223372036854775807 26 27 28 29 30
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 > -9223372036854775809 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
0 -9223372036854775808 1 2 3 4 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 >= -9223372036854775809 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
@@ -34459,37 +34539,37 @@ c1 c2 c3 c4 c5 c6 c7
18446744073709551615 9223372036854775807 36 37 38 39 40
18446744073709551615 9223372036854775807 26 27 28 29 30
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 >= -9223372036854775809 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
0 -9223372036854775808 1 2 3 4 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 < -9223372036854775809 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 < -9223372036854775809 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 <= -9223372036854775809 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 <= -9223372036854775809 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 <=> -9223372036854775809 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 <=> -9223372036854775809 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 BETWEEN -9223372036854775809 AND 9223372036854775808 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
@@ -34514,13 +34594,13 @@ c1 c2 c3 c4 c5 c6 c7
18446744073709551615 9223372036854775807 36 37 38 39 40
18446744073709551615 9223372036854775807 26 27 28 29 30
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 BETWEEN -9223372036854775809 AND 9223372036854775808 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
0 -9223372036854775808 1 2 3 4 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 IN (-9223372036854775809,9223372036854775808) ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
@@ -34533,12 +34613,12 @@ SELECT * FROM t3 WHERE c2 >= -9223372036854775809 AND c2 < 9223372036854775808 A
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 >= -9223372036854775809 AND c2 < 9223372036854775808 AND c7 = 35 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 IS NULL ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
105 NULL 102 103 104 105 106
@@ -34659,12 +34739,20 @@ c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
SELECT * FROM t3 WHERE c2 = 9223372036854775808 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 9223372036854775808 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 9223372036854775808 ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 = 9223372036854775808 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t3 WHERE c2 <> 9223372036854775808 ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 1 2 3 4 5
@@ -34782,13 +34870,13 @@ c1 c2 c3 c4 c5 c6 c7
18446744073709551615 9223372036854775807 26 27 28 29 30
18446744073709551615 9223372036854775807 36 37 38 39 40
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 BETWEEN -9223372036854775809 AND 9223372036854775808 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 1 2 3 4 5
0 -9223372036854775808 31 32 33 34 35
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 IN (-9223372036854775809,9223372036854775808) ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 1 2 3 4 5
@@ -34801,12 +34889,12 @@ SELECT * FROM t3 WHERE c2 >= -9223372036854775809 AND c2 < 9223372036854775808 A
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 >= -9223372036854775809 AND c2 < 9223372036854775808 AND c7 = 35 ORDER BY c2,c7 LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 IS NULL ORDER BY c2,c7;
c1 c2 c3 c4 c5 c6 c7
105 NULL 102 103 104 105 106
@@ -34957,13 +35045,13 @@ c1 c2 c3 c4 c5 c6 c7
18446744073709551615 9223372036854775807 36 37 38 39 40
18446744073709551615 9223372036854775807 26 27 28 29 30
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 BETWEEN -9223372036854775809 AND 9223372036854775808 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
0 -9223372036854775808 1 2 3 4 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 IN (-9223372036854775809,9223372036854775808) ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
@@ -34976,12 +35064,12 @@ SELECT * FROM t3 WHERE c2 >= -9223372036854775809 AND c2 < 9223372036854775808 A
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 >= -9223372036854775809 AND c2 < 9223372036854775808 AND c7 = 35 ORDER BY c2,c7 DESC LIMIT 2;
c1 c2 c3 c4 c5 c6 c7
0 -9223372036854775808 31 32 33 34 35
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated.
SELECT * FROM t3 WHERE c2 IS NULL ORDER BY c2,c7 DESC;
c1 c2 c3 c4 c5 c6 c7
105 NULL 102 103 104 105 106
diff --git a/mysql-test/suite/engines/iuds/r/insert_time.result b/mysql-test/suite/engines/iuds/r/insert_time.result
index a6366a1255b..154127fc80c 100644
--- a/mysql-test/suite/engines/iuds/r/insert_time.result
+++ b/mysql-test/suite/engines/iuds/r/insert_time.result
@@ -40,12 +40,12 @@ INSERT INTO t4 VALUES('10.22.22','10.22.22','2009-01-26'),(1234567,1234567,'2009
Warnings:
Warning 1265 Data truncated for column 'c1' at row 1
Warning 1265 Data truncated for column 'c2' at row 1
-Warning 1264 Out of range value for column 'c1' at row 2
-Warning 1264 Out of range value for column 'c2' at row 2
-Warning 1264 Out of range value for column 'c1' at row 3
-Warning 1264 Out of range value for column 'c2' at row 3
-Warning 1264 Out of range value for column 'c1' at row 4
-Warning 1264 Out of range value for column 'c2' at row 4
+Warning 1265 Data truncated for column 'c1' at row 2
+Warning 1265 Data truncated for column 'c2' at row 2
+Warning 1265 Data truncated for column 'c1' at row 3
+Warning 1265 Data truncated for column 'c2' at row 3
+Warning 1265 Data truncated for column 'c1' at row 4
+Warning 1265 Data truncated for column 'c2' at row 4
Warning 1265 Data truncated for column 'c1' at row 6
Warning 1265 Data truncated for column 'c2' at row 6
INSERT INTO t1 VALUES('8:29:45',NULL,'2009-02-01');
@@ -135,6 +135,8 @@ c1 c2 c3
-838:59:59 -838:59:59 2009-01-08
00:00:00 00:00:00 2009-01-09
00:00:00 00:00:00 2009-01-27
+00:00:00 00:00:00 2009-01-28
+00:00:00 00:00:00 2009-01-29
00:00:10 00:00:10 2009-01-26
00:00:11 00:00:11 2009-01-20
00:00:12 00:00:12 2009-01-13
@@ -160,8 +162,6 @@ c1 c2 c3
491:22:33 491:22:33 2009-01-04
825:23:00 825:23:00 2009-01-05
838:59:59 838:59:59 2009-01-10
-838:59:59 838:59:59 2009-01-28
-838:59:59 838:59:59 2009-01-29
SELECT * FROM t1;
c1 c2 c3
-838:59:59 -838:59:59 2009-01-21
@@ -1650,8 +1650,10 @@ SELECT * FROM t1 WHERE c2 BETWEEN NULL AND '10:22:33' ORDER BY c2 LIMIT 2;
c1 c2 c3
SELECT * FROM t1 WHERE c2 IN (NULL,'10:22:33') ORDER BY c2;
c1 c2 c3
+10:22:33 10:22:33 2009-01-02
SELECT * FROM t1 WHERE c2 IN (NULL,'10:22:33') ORDER BY c2 LIMIT 2;
c1 c2 c3
+10:22:33 10:22:33 2009-01-02
SELECT * FROM t1 WHERE c2 >= NULL AND c2 < '10:22:33' AND c1 = '491:22:33' ORDER BY c2;
c1 c2 c3
SELECT * FROM t1 WHERE c2 >= NULL AND c2 < '10:22:33' AND c1 = '491:22:33' ORDER BY c2 LIMIT 2;
@@ -1723,8 +1725,10 @@ SELECT * FROM t1 WHERE c2 BETWEEN NULL AND '10:22:33' ORDER BY c2 DESC LIMIT 2;
c1 c2 c3
SELECT * FROM t1 WHERE c2 IN (NULL,'10:22:33') ORDER BY c2 DESC;
c1 c2 c3
+10:22:33 10:22:33 2009-01-02
SELECT * FROM t1 WHERE c2 IN (NULL,'10:22:33') ORDER BY c2 DESC LIMIT 2;
c1 c2 c3
+10:22:33 10:22:33 2009-01-02
SELECT * FROM t1 WHERE c2 >= NULL AND c2 < '10:22:33' AND c1 = '491:22:33' ORDER BY c2 DESC;
c1 c2 c3
SELECT * FROM t1 WHERE c2 >= NULL AND c2 < '10:22:33' AND c1 = '491:22:33' ORDER BY c2 DESC LIMIT 2;
@@ -3218,8 +3222,10 @@ SELECT * FROM t2 WHERE c2 BETWEEN NULL AND '10:22:33' ORDER BY c1,c2 LIMIT 2;
c1 c2 c3
SELECT * FROM t2 WHERE c2 IN (NULL,'10:22:33') ORDER BY c1,c2;
c1 c2 c3
+10:22:33 10:22:33 2009-01-02
SELECT * FROM t2 WHERE c2 IN (NULL,'10:22:33') ORDER BY c1,c2 LIMIT 2;
c1 c2 c3
+10:22:33 10:22:33 2009-01-02
SELECT * FROM t2 WHERE c2 >= NULL AND c2 < '10:22:33' AND c1 = '491:22:33' ORDER BY c1,c2;
c1 c2 c3
SELECT * FROM t2 WHERE c2 >= NULL AND c2 < '10:22:33' AND c1 = '491:22:33' ORDER BY c1,c2 LIMIT 2;
@@ -3287,8 +3293,10 @@ SELECT * FROM t2 WHERE c2 BETWEEN NULL AND '10:22:33' ORDER BY c1,c2 DESC LIMIT
c1 c2 c3
SELECT * FROM t2 WHERE c2 IN (NULL,'10:22:33') ORDER BY c1,c2 DESC;
c1 c2 c3
+10:22:33 10:22:33 2009-01-02
SELECT * FROM t2 WHERE c2 IN (NULL,'10:22:33') ORDER BY c1,c2 DESC LIMIT 2;
c1 c2 c3
+10:22:33 10:22:33 2009-01-02
SELECT * FROM t2 WHERE c2 >= NULL AND c2 < '10:22:33' AND c1 = '491:22:33' ORDER BY c1,c2 DESC;
c1 c2 c3
SELECT * FROM t2 WHERE c2 >= NULL AND c2 < '10:22:33' AND c1 = '491:22:33' ORDER BY c1,c2 DESC LIMIT 2;
@@ -4814,8 +4822,10 @@ SELECT * FROM t3 WHERE c2 BETWEEN NULL AND '10:22:33' ORDER BY c1,c2 LIMIT 2;
c1 c2 c3
SELECT * FROM t3 WHERE c2 IN (NULL,'10:22:33') ORDER BY c1,c2;
c1 c2 c3
+10:22:33 10:22:33 2009-01-02
SELECT * FROM t3 WHERE c2 IN (NULL,'10:22:33') ORDER BY c1,c2 LIMIT 2;
c1 c2 c3
+10:22:33 10:22:33 2009-01-02
SELECT * FROM t3 WHERE c2 >= NULL AND c2 < '10:22:33' AND c1 = '491:22:33' ORDER BY c1,c2;
c1 c2 c3
SELECT * FROM t3 WHERE c2 >= NULL AND c2 < '10:22:33' AND c1 = '491:22:33' ORDER BY c1,c2 LIMIT 2;
@@ -4887,8 +4897,10 @@ SELECT * FROM t3 WHERE c2 BETWEEN NULL AND '10:22:33' ORDER BY c1,c2 DESC LIMIT
c1 c2 c3
SELECT * FROM t3 WHERE c2 IN (NULL,'10:22:33') ORDER BY c1,c2 DESC;
c1 c2 c3
+10:22:33 10:22:33 2009-01-02
SELECT * FROM t3 WHERE c2 IN (NULL,'10:22:33') ORDER BY c1,c2 DESC LIMIT 2;
c1 c2 c3
+10:22:33 10:22:33 2009-01-02
SELECT * FROM t3 WHERE c2 >= NULL AND c2 < '10:22:33' AND c1 = '491:22:33' ORDER BY c1,c2 DESC;
c1 c2 c3
SELECT * FROM t3 WHERE c2 >= NULL AND c2 < '10:22:33' AND c1 = '491:22:33' ORDER BY c1,c2 DESC LIMIT 2;
@@ -5008,28 +5020,24 @@ c1 MIN(c2)
838:59:59 838:59:59
SELECT CAST(235959.123456 AS TIME);
CAST(235959.123456 AS TIME)
-23:59:59.123456
+23:59:59
SELECT CAST(0.235959123456e+6 AS TIME);
CAST(0.235959123456e+6 AS TIME)
-23:59:59.123456
+23:59:59
SELECT CAST(235959123456e-6 AS TIME);
CAST(235959123456e-6 AS TIME)
-23:59:59.123456
+23:59:59
SELECT CAST(235959.1234567 AS TIME);
CAST(235959.1234567 AS TIME)
-23:59:59.123456
-Warnings:
-Warning 1292 Truncated incorrect time value: '235959.1234567'
+23:59:59
SELECT CAST(0.2359591234567e6 AS TIME);
CAST(0.2359591234567e6 AS TIME)
-23:59:59.123456
-Warnings:
-Warning 1292 Truncated incorrect time value: '235959.1234567'
+23:59:59
SELECT CAST(0.2359591234567e+30 AS TIME);
CAST(0.2359591234567e+30 AS TIME)
NULL
Warnings:
-Warning 1292 Truncated incorrect time value: '2.359591234567e+29'
+Warning 1292 Incorrect datetime value: '2.359591234567e+29'
select cast('100:55:50' as time) < cast('24:00:00' as time);
cast('100:55:50' as time) < cast('24:00:00' as time)
0
@@ -5077,7 +5085,6 @@ c1 c2 c3
INSERT INTO t2(c1,c2) VALUES('12:34:56.78','12:34:56.78') ON DUPLICATE KEY UPDATE c1='12:34:56.79',c2='12:34:57.78';
SELECT * FROM t2 WHERE c1='12:34:56.79' AND c2='12:34:57.78' /* 1 row */;
c1 c2 c3
-12:34:56 12:34:57 2009-01-01
SELECT * FROM t1 WHERE c1='10:22:35' AND c2='33 9:23' /* no rows */;
c1 c2 c3
INSERT INTO t1(c1,c2) VALUES('10:22:34','34 9:23') ON DUPLICATE KEY UPDATE c1='10:22:35',c2='33 9:23';
@@ -5137,8 +5144,8 @@ c1 c2 c3
09:36:00 09:36:00 2009-01-25
00:00:10 00:00:10 2009-01-26
00:00:00 00:00:00 2009-01-27
-838:59:59 838:59:59 2009-01-28
-838:59:59 838:59:59 2009-01-29
+00:00:00 00:00:00 2009-01-28
+00:00:00 00:00:00 2009-01-29
262:22:00 262:22:00 2009-01-30
00:00:12 00:00:12 2009-01-31
08:29:45 NULL 2009-02-01
@@ -5146,15 +5153,39 @@ c1 c2 c3
TRUNCATE TABLE t5;
INSERT INTO t5 SELECT * FROM t4 WHERE c1 >='12colon34colon56';
Warnings:
-Warning 1292 Incorrect time value: '12colon34colon56' for column 'c1' at row 1
+Warning 1292 Truncated incorrect time value: '12colon34colon56'
SELECT * FROM t5;
c1 c2 c3
+12:34:56 12:34:56 2009-01-01
+10:22:33 10:22:33 2009-01-02
+01:23:00 01:23:00 2009-01-03
491:22:33 491:22:33 2009-01-04
825:23:00 825:23:00 2009-01-05
+10:00:00 10:00:00 2009-01-06
+00:00:45 00:00:45 2009-01-07
+00:00:00 00:00:00 2009-01-09
838:59:59 838:59:59 2009-01-10
-838:59:59 838:59:59 2009-01-28
-838:59:59 838:59:59 2009-01-29
+10:11:12 10:11:12 2009-01-11
+11:11:12 11:11:12 2009-01-12
+00:00:12 00:00:12 2009-01-13
+00:12:34 00:12:34 2009-01-14
+12:34:58 12:34:58 2009-01-15
+12:35:56 12:35:56 2009-01-16
+11:11:27 11:11:27 2009-01-17
+08:03:02 08:03:02 2009-01-18
+00:11:12 00:11:12 2009-01-19
+00:00:11 00:00:11 2009-01-20
+00:12:30 00:12:30 2009-01-23
+09:00:45 09:00:45 2009-01-24
+09:36:00 09:36:00 2009-01-25
+00:00:10 00:00:10 2009-01-26
+00:00:00 00:00:00 2009-01-27
+00:00:00 00:00:00 2009-01-28
+00:00:00 00:00:00 2009-01-29
262:22:00 262:22:00 2009-01-30
+00:00:12 00:00:12 2009-01-31
+08:29:45 NULL 2009-02-01
+00:00:00 07:23:55 NULL
TRUNCATE TABLE t5;
DROP TABLE t5;
DROP TABLE t1,t2,t3,t4;
diff --git a/mysql-test/suite/engines/iuds/r/type_bit_iuds.result b/mysql-test/suite/engines/iuds/r/type_bit_iuds.result
index eb41c3acfa2..ef03c09e61c 100644
--- a/mysql-test/suite/engines/iuds/r/type_bit_iuds.result
+++ b/mysql-test/suite/engines/iuds/r/type_bit_iuds.result
@@ -49,7 +49,7 @@ SELECT CONCAT(BIN(c1),BIN(c2),BIN(c3)) FROM t2;
CONCAT(BIN(c1),BIN(c2),BIN(c3))
000
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(0) NOT NULL PRIMARY KEY, c2 BIT(0));
@@ -854,7 +854,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
000
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(1) NOT NULL PRIMARY KEY, c2 BIT(1));
@@ -1704,7 +1704,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111
111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(2) NOT NULL PRIMARY KEY, c2 BIT(2));
@@ -2619,7 +2619,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111
111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(4) NOT NULL PRIMARY KEY, c2 BIT(4));
@@ -3692,7 +3692,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111
111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(8) NOT NULL PRIMARY KEY, c2 BIT(8));
@@ -5211,7 +5211,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(16) NOT NULL PRIMARY KEY, c2 BIT(16));
@@ -7252,7 +7252,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(32) NOT NULL PRIMARY KEY, c2 BIT(32));
@@ -10587,7 +10587,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(64) NOT NULL PRIMARY KEY, c2 BIT(64));
@@ -11419,7 +11419,7 @@ SELECT CONCAT(BIN(c1),BIN(c2),BIN(c3)) FROM t2;
CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(0) NOT NULL PRIMARY KEY, c2 BIT(0));
@@ -12224,7 +12224,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(1) NOT NULL PRIMARY KEY, c2 BIT(1));
@@ -13074,7 +13074,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111
111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(2) NOT NULL PRIMARY KEY, c2 BIT(2));
@@ -13989,7 +13989,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111
111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(4) NOT NULL PRIMARY KEY, c2 BIT(4));
@@ -15062,7 +15062,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111
111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(8) NOT NULL PRIMARY KEY, c2 BIT(8));
@@ -16581,7 +16581,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(16) NOT NULL PRIMARY KEY, c2 BIT(16));
@@ -18622,7 +18622,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(32) NOT NULL PRIMARY KEY, c2 BIT(32));
@@ -21957,7 +21957,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(64) NOT NULL PRIMARY KEY, c2 BIT(64));
@@ -22795,7 +22795,7 @@ SELECT CONCAT(BIN(c1),BIN(c2),BIN(c3)) FROM t2;
CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(0) NOT NULL PRIMARY KEY, c2 BIT(0));
@@ -23606,7 +23606,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(1) NOT NULL PRIMARY KEY, c2 BIT(1));
@@ -24456,7 +24456,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111
111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(2) NOT NULL PRIMARY KEY, c2 BIT(2));
@@ -25371,7 +25371,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111
111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(4) NOT NULL PRIMARY KEY, c2 BIT(4));
@@ -26444,7 +26444,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111
111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(8) NOT NULL PRIMARY KEY, c2 BIT(8));
@@ -27963,7 +27963,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(16) NOT NULL PRIMARY KEY, c2 BIT(16));
@@ -30004,7 +30004,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(32) NOT NULL PRIMARY KEY, c2 BIT(32));
@@ -33339,7 +33339,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(64) NOT NULL PRIMARY KEY, c2 BIT(64));
@@ -34177,7 +34177,7 @@ SELECT CONCAT(BIN(c1),BIN(c2),BIN(c3)) FROM t2;
CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(0) NOT NULL PRIMARY KEY, c2 BIT(0));
@@ -34988,7 +34988,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(1) NOT NULL PRIMARY KEY, c2 BIT(1));
@@ -35844,7 +35844,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111
111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(2) NOT NULL PRIMARY KEY, c2 BIT(2));
@@ -36759,7 +36759,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111
111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(4) NOT NULL PRIMARY KEY, c2 BIT(4));
@@ -37832,7 +37832,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111
111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(8) NOT NULL PRIMARY KEY, c2 BIT(8));
@@ -39351,7 +39351,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(16) NOT NULL PRIMARY KEY, c2 BIT(16));
@@ -41392,7 +41392,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(32) NOT NULL PRIMARY KEY, c2 BIT(32));
@@ -44727,7 +44727,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(64) NOT NULL PRIMARY KEY, c2 BIT(64));
@@ -45565,7 +45565,7 @@ SELECT CONCAT(BIN(c1),BIN(c2),BIN(c3)) FROM t2;
CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(0) NOT NULL PRIMARY KEY, c2 BIT(0));
@@ -46376,7 +46376,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(1) NOT NULL PRIMARY KEY, c2 BIT(1));
@@ -47232,7 +47232,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111
111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(2) NOT NULL PRIMARY KEY, c2 BIT(2));
@@ -48153,7 +48153,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111
111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(4) NOT NULL PRIMARY KEY, c2 BIT(4));
@@ -49232,7 +49232,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111
111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(8) NOT NULL PRIMARY KEY, c2 BIT(8));
@@ -50751,7 +50751,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(16) NOT NULL PRIMARY KEY, c2 BIT(16));
@@ -52792,7 +52792,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(32) NOT NULL PRIMARY KEY, c2 BIT(32));
@@ -56127,7 +56127,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(64) NOT NULL PRIMARY KEY, c2 BIT(64));
@@ -56916,7 +56916,7 @@ SELECT 0 + (101010101010101010101010101010<<0);
0 + (101010101010101010101010101010<<0)
9223372036854775807
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(0));
CREATE TABLE t2(c1 BIT(0), c2 BIT(0), c3 BIT(0));
INSERT INTO t1 VALUES (b'101010101010101010101010101010');
@@ -56967,7 +56967,7 @@ SELECT CONCAT(BIN(c1),BIN(c2),BIN(c3)) FROM t2;
CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(0) NOT NULL PRIMARY KEY, c2 BIT(0));
@@ -57687,7 +57687,7 @@ SELECT 0 + (101010101010101010101010101010<<1);
0 + (101010101010101010101010101010<<1)
18446744073709551614
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(1));
CREATE TABLE t2(c1 BIT(1), c2 BIT(1), c3 BIT(1));
set @v1=1;
@@ -57780,7 +57780,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(1) NOT NULL PRIMARY KEY, c2 BIT(1));
@@ -58507,7 +58507,7 @@ SELECT 0 + (101010101010101010101010101010<<2);
0 + (101010101010101010101010101010<<2)
18446744073709551612
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(2));
CREATE TABLE t2(c1 BIT(2), c2 BIT(2), c3 BIT(2));
set @v1=2;
@@ -58638,7 +58638,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111
111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(2) NOT NULL PRIMARY KEY, c2 BIT(2));
@@ -59350,7 +59350,7 @@ SELECT 0 + (101010101010101010101010101010<<4);
0 + (101010101010101010101010101010<<4)
18446744073709551600
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(4));
CREATE TABLE t2(c1 BIT(4), c2 BIT(4), c3 BIT(4));
set @v1=4;
@@ -59561,7 +59561,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111
111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(4) NOT NULL PRIMARY KEY, c2 BIT(4));
@@ -60271,7 +60271,7 @@ SELECT 0 + (101010101010101010101010101010<<8);
0 + (101010101010101010101010101010<<8)
18446744073709551360
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(8));
CREATE TABLE t2(c1 BIT(8), c2 BIT(8), c3 BIT(8));
set @v1=8;
@@ -60642,7 +60642,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111
111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(8) NOT NULL PRIMARY KEY, c2 BIT(8));
@@ -61478,7 +61478,7 @@ SELECT 0 + (101010101010101010101010101010<<16);
0 + (101010101010101010101010101010<<16)
18446744073709486080
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(16));
CREATE TABLE t2(c1 BIT(16), c2 BIT(16), c3 BIT(16));
set @v1=16;
@@ -62169,7 +62169,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(16) NOT NULL PRIMARY KEY, c2 BIT(16));
@@ -62890,7 +62890,7 @@ SELECT 0 + (101010101010101010101010101010<<32);
0 + (101010101010101010101010101010<<32)
18446744069414584320
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(32));
CREATE TABLE t2(c1 BIT(32), c2 BIT(32), c3 BIT(32));
set @v1=32;
@@ -64212,7 +64212,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(32) NOT NULL PRIMARY KEY, c2 BIT(32));
@@ -64963,7 +64963,7 @@ SELECT 0 + (101010101010101010101010101010<<64);
0 + (101010101010101010101010101010<<64)
0
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(64));
CREATE TABLE t2(c1 BIT(64), c2 BIT(64), c3 BIT(64));
set @v1=64;
@@ -67549,7 +67549,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(64) NOT NULL PRIMARY KEY, c2 BIT(64));
@@ -68335,7 +68335,7 @@ SELECT 0 + (1010101010101010101010101010101010101010101010101010101010101010<<0)
0 + (1010101010101010101010101010101010101010101010101010101010101010<<0)
9223372036854775807
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '1010101010101010101010101010101010101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(0));
CREATE TABLE t2(c1 BIT(0), c2 BIT(0), c3 BIT(0));
INSERT INTO t1 VALUES (b'1010101010101010101010101010101010101010101010101010101010101010');
@@ -68386,7 +68386,7 @@ SELECT CONCAT(BIN(c1),BIN(c2),BIN(c3)) FROM t2;
CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(0) NOT NULL PRIMARY KEY, c2 BIT(0));
@@ -69103,7 +69103,7 @@ SELECT 0 + (1010101010101010101010101010101010101010101010101010101010101010<<1)
0 + (1010101010101010101010101010101010101010101010101010101010101010<<1)
18446744073709551614
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '1010101010101010101010101010101010101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(1));
CREATE TABLE t2(c1 BIT(1), c2 BIT(1), c3 BIT(1));
set @v1=1;
@@ -69196,7 +69196,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(1) NOT NULL PRIMARY KEY, c2 BIT(1));
@@ -69920,7 +69920,7 @@ SELECT 0 + (1010101010101010101010101010101010101010101010101010101010101010<<2)
0 + (1010101010101010101010101010101010101010101010101010101010101010<<2)
18446744073709551612
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '1010101010101010101010101010101010101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(2));
CREATE TABLE t2(c1 BIT(2), c2 BIT(2), c3 BIT(2));
set @v1=2;
@@ -70051,7 +70051,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111
111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(2) NOT NULL PRIMARY KEY, c2 BIT(2));
@@ -70760,7 +70760,7 @@ SELECT 0 + (1010101010101010101010101010101010101010101010101010101010101010<<4)
0 + (1010101010101010101010101010101010101010101010101010101010101010<<4)
18446744073709551600
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '1010101010101010101010101010101010101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(4));
CREATE TABLE t2(c1 BIT(4), c2 BIT(4), c3 BIT(4));
set @v1=4;
@@ -70971,7 +70971,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111
111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(4) NOT NULL PRIMARY KEY, c2 BIT(4));
@@ -71678,7 +71678,7 @@ SELECT 0 + (1010101010101010101010101010101010101010101010101010101010101010<<8)
0 + (1010101010101010101010101010101010101010101010101010101010101010<<8)
18446744073709551360
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '1010101010101010101010101010101010101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(8));
CREATE TABLE t2(c1 BIT(8), c2 BIT(8), c3 BIT(8));
set @v1=8;
@@ -72049,7 +72049,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111
111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(8) NOT NULL PRIMARY KEY, c2 BIT(8));
@@ -72882,7 +72882,7 @@ SELECT 0 + (1010101010101010101010101010101010101010101010101010101010101010<<16
0 + (1010101010101010101010101010101010101010101010101010101010101010<<16)
18446744073709486080
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '1010101010101010101010101010101010101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(16));
CREATE TABLE t2(c1 BIT(16), c2 BIT(16), c3 BIT(16));
set @v1=16;
@@ -73573,7 +73573,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(16) NOT NULL PRIMARY KEY, c2 BIT(16));
@@ -74291,7 +74291,7 @@ SELECT 0 + (1010101010101010101010101010101010101010101010101010101010101010<<32
0 + (1010101010101010101010101010101010101010101010101010101010101010<<32)
18446744069414584320
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '1010101010101010101010101010101010101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(32));
CREATE TABLE t2(c1 BIT(32), c2 BIT(32), c3 BIT(32));
set @v1=32;
@@ -75619,7 +75619,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(32) NOT NULL PRIMARY KEY, c2 BIT(32));
@@ -76367,7 +76367,7 @@ SELECT 0 + (1010101010101010101010101010101010101010101010101010101010101010<<64
0 + (1010101010101010101010101010101010101010101010101010101010101010<<64)
0
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '1010101010101010101010101010101010101010101010101010101010101010' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(64));
CREATE TABLE t2(c1 BIT(64), c2 BIT(64), c3 BIT(64));
set @v1=64;
@@ -78953,7 +78953,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(64) NOT NULL PRIMARY KEY, c2 BIT(64));
@@ -79739,7 +79739,7 @@ SELECT 0 + (10101010101010101010101010101010101010101010101010101010101010101<<0
0 + (10101010101010101010101010101010101010101010101010101010101010101<<0)
9223372036854775807
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '10101010101010101010101010101010101010101010101010101010101010101' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(0));
CREATE TABLE t2(c1 BIT(0), c2 BIT(0), c3 BIT(0));
INSERT INTO t1 VALUES (b'10101010101010101010101010101010101010101010101010101010101010101');
@@ -79790,7 +79790,7 @@ SELECT CONCAT(BIN(c1),BIN(c2),BIN(c3)) FROM t2;
CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(0) NOT NULL PRIMARY KEY, c2 BIT(0));
@@ -80507,7 +80507,7 @@ SELECT 0 + (10101010101010101010101010101010101010101010101010101010101010101<<1
0 + (10101010101010101010101010101010101010101010101010101010101010101<<1)
18446744073709551614
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '10101010101010101010101010101010101010101010101010101010101010101' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(1));
CREATE TABLE t2(c1 BIT(1), c2 BIT(1), c3 BIT(1));
set @v1=1;
@@ -80600,7 +80600,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111
111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(1) NOT NULL PRIMARY KEY, c2 BIT(1));
@@ -81324,7 +81324,7 @@ SELECT 0 + (10101010101010101010101010101010101010101010101010101010101010101<<2
0 + (10101010101010101010101010101010101010101010101010101010101010101<<2)
18446744073709551612
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '10101010101010101010101010101010101010101010101010101010101010101' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(2));
CREATE TABLE t2(c1 BIT(2), c2 BIT(2), c3 BIT(2));
set @v1=2;
@@ -81455,7 +81455,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111
111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(2) NOT NULL PRIMARY KEY, c2 BIT(2));
@@ -82164,7 +82164,7 @@ SELECT 0 + (10101010101010101010101010101010101010101010101010101010101010101<<4
0 + (10101010101010101010101010101010101010101010101010101010101010101<<4)
18446744073709551600
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '10101010101010101010101010101010101010101010101010101010101010101' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(4));
CREATE TABLE t2(c1 BIT(4), c2 BIT(4), c3 BIT(4));
set @v1=4;
@@ -82375,7 +82375,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111
111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(4) NOT NULL PRIMARY KEY, c2 BIT(4));
@@ -83082,7 +83082,7 @@ SELECT 0 + (10101010101010101010101010101010101010101010101010101010101010101<<8
0 + (10101010101010101010101010101010101010101010101010101010101010101<<8)
18446744073709551360
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '10101010101010101010101010101010101010101010101010101010101010101' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(8));
CREATE TABLE t2(c1 BIT(8), c2 BIT(8), c3 BIT(8));
set @v1=8;
@@ -83453,7 +83453,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111
111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(8) NOT NULL PRIMARY KEY, c2 BIT(8));
@@ -84286,7 +84286,7 @@ SELECT 0 + (10101010101010101010101010101010101010101010101010101010101010101<<1
0 + (10101010101010101010101010101010101010101010101010101010101010101<<16)
18446744073709486080
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '10101010101010101010101010101010101010101010101010101010101010101' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(16));
CREATE TABLE t2(c1 BIT(16), c2 BIT(16), c3 BIT(16));
set @v1=16;
@@ -84977,7 +84977,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(16) NOT NULL PRIMARY KEY, c2 BIT(16));
@@ -85695,7 +85695,7 @@ SELECT 0 + (10101010101010101010101010101010101010101010101010101010101010101<<3
0 + (10101010101010101010101010101010101010101010101010101010101010101<<32)
18446744069414584320
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '10101010101010101010101010101010101010101010101010101010101010101' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(32));
CREATE TABLE t2(c1 BIT(32), c2 BIT(32), c3 BIT(32));
set @v1=32;
@@ -87023,7 +87023,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(32) NOT NULL PRIMARY KEY, c2 BIT(32));
@@ -87771,7 +87771,7 @@ SELECT 0 + (10101010101010101010101010101010101010101010101010101010101010101<<6
0 + (10101010101010101010101010101010101010101010101010101010101010101<<64)
0
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '10101010101010101010101010101010101010101010101010101010101010101' to INT. Value truncated.
CREATE TABLE t1(c1 BIT(64));
CREATE TABLE t2(c1 BIT(64), c2 BIT(64), c3 BIT(64));
set @v1=64;
@@ -90363,7 +90363,7 @@ CONCAT(BIN(c1),BIN(c2),BIN(c3))
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
CREATE TABLE t3 (c1 BIT(65));
-ERROR 42000: Display width out of range for column 'c1' (max = 64)
+ERROR 42000: Display width out of range for 'c1' (max = 64)
CREATE TABLE t4(i INT, b BIT NOT NULL);
ALTER TABLE t4 ADD PRIMARY KEY (i);
CREATE TABLE t5(c1 BIT(64) NOT NULL PRIMARY KEY, c2 BIT(64));
diff --git a/mysql-test/suite/engines/iuds/r/update_delete_calendar.result b/mysql-test/suite/engines/iuds/r/update_delete_calendar.result
index e2dd83e03b4..e637885dbf6 100644
--- a/mysql-test/suite/engines/iuds/r/update_delete_calendar.result
+++ b/mysql-test/suite/engines/iuds/r/update_delete_calendar.result
@@ -71,13 +71,6 @@ Warning 1265 Data truncated for column 'c2' at row 1
SELECT count(*) FROM t1 WHERE c2='10:45:15' OR c2='2009-01-32' OR c2='2009-02-30' OR c2='2009-04-31' OR c2='2009-06-31' OR c2='2009-09-31' /* returns 0 */;
count(*)
0
-Warnings:
-Warning 1292 Incorrect date value: '10:45:15' for column 'c2' at row 1
-Warning 1292 Incorrect date value: '2009-01-32' for column 'c2' at row 1
-Warning 1292 Incorrect date value: '10:45:15' for column 'c2' at row 1
-Warning 1292 Incorrect date value: '2009-01-32' for column 'c2' at row 1
-Warning 1292 Incorrect date value: '10:45:15' for column 'c2' at row 1
-Warning 1292 Incorrect date value: '2009-01-32' for column 'c2' at row 1
UPDATE t1 SET c2='2009-11-31' WHERE c2='2001-01-16';
Warnings:
Warning 1265 Data truncated for column 'c2' at row 1
@@ -108,8 +101,7 @@ c1 c2 c3
2001-01-16 0000-00-00 12
2001-01-17 0000-00-00 13
Warnings:
-Warning 1292 Incorrect date value: '0000-00-00' for column 'c2' at row 1
-Warning 1292 Incorrect date value: '0000-00-00' for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
UPDATE t1 SET c2='0000-00-00' WHERE c2='2001-01-18';
ERROR 22007: Incorrect date value: '0000-00-00' for column 'c2' at row 1
SET SQL_MODE=DEFAULT;
@@ -774,20 +766,17 @@ c1 c2 c3
INSERT INTO t1 VALUES('2001-01-09','2001-01-10',6),('2001-01-11','2001-01-12',7);
UPDATE t1 SET c1='2001-01-09 24:59:59',c2='2009-01-10 23:60:59' WHERE c1='2001-01-09';
Warnings:
-Warning 1264 Out of range value for column 'c1' at row 1
-Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1265 Data truncated for column 'c1' at row 1
+Warning 1265 Data truncated for column 'c2' at row 1
UPDATE t1 SET c2='2001-01-11 23:59:60' WHERE c1='2001-01-11';
Warnings:
-Warning 1264 Out of range value for column 'c2' at row 1
+Warning 1265 Data truncated for column 'c2' at row 1
SELECT count(*) FROM t1 WHERE c1='2001-01-09 24:59:59' AND c2='2009-01-10 23:60:59';
count(*)
1
Warnings:
-Warning 1292 Incorrect datetime value: '2001-01-09 24:59:59' for column 'c1' at row 1
-Warning 1292 Incorrect datetime value: '2009-01-10 23:60:59' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '2001-01-09 24:59:59' for column 'c1' at row 1
-Warning 1292 Truncated incorrect datetime value: '2001-01-09 24:59:59'
-Warning 1292 Truncated incorrect datetime value: '2009-01-10 23:60:59'
+Warning 1292 Incorrect datetime value: '2001-01-09 24:59:59'
+Warning 1292 Incorrect datetime value: '2009-01-10 23:60:59'
SELECT count(*) FROM t1 WHERE c2='2001-01-11 23:59:60' /* returns 0 */;
count(*)
0
@@ -803,8 +792,7 @@ c1 c2 c3
2001-01-11 00:00:00 0000-00-00 00:00:00 7
2001-01-17 00:00:00 0000-00-00 00:00:00 8
Warnings:
-Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' for column 'c2' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
UPDATE t1 SET c2='0000-00-00 00:00:00' WHERE c2='2001-01-18 07:35';
ERROR 22007: Incorrect datetime value: '0000-00-00 00:00:00' for column 'c2' at row 1
SET SQL_MODE=DEFAULT;
@@ -946,15 +934,13 @@ c1 c2 c3
2003-01-01 01:02:03 2002-01-09 01:30:30 10
UPDATE t1 SET c1='2003-01-01 1:2:3' WHERE c2 BETWEEN '20020109 01:30:40' AND '20020109 01:30:50' ORDER BY c2 LIMIT 2;
Warnings:
-Warning 1292 Incorrect datetime value: '20020109 01:30:40' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '20020109 01:30:40' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '20020109 01:30:50' for column 'c2' at row 1
+Warning 1292 Incorrect datetime value: '20020109 01:30:40'
+Warning 1292 Incorrect datetime value: '20020109 01:30:50'
SELECT * FROM t1 WHERE c2 BETWEEN '20020109 01:30:40' AND '20020109 01:30:50' ORDER BY c2;
c1 c2 c3
Warnings:
-Warning 1292 Incorrect datetime value: '20020109 01:30:40' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '20020109 01:30:40' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '20020109 01:30:50' for column 'c2' at row 1
+Warning 1292 Incorrect datetime value: '20020109 01:30:40'
+Warning 1292 Incorrect datetime value: '20020109 01:30:50'
UPDATE t1 SET c1='2003-01-01 1:2:3' WHERE c2 IN('2002-01-09 1:30:55','2002-01-09 2:00') ORDER BY c2 DESC LIMIT 2;
SELECT * FROM t1 WHERE c2 IN('2002-01-09 1:30:55','2002-01-09 2:00') ORDER BY c2 DESC;
c1 c2 c3
@@ -1386,17 +1372,13 @@ SELECT count(*) FROM t1 WHERE c1='2001-01-09 24:59:59' AND c2='2009-01-10 23:60:
count(*)
1
Warnings:
-Warning 1292 Incorrect datetime value: '2001-01-09 24:59:59' for column 'c1' at row 1
-Warning 1292 Incorrect datetime value: '2009-01-10 23:60:59' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '2001-01-09 24:59:59' for column 'c1' at row 1
-Warning 1292 Truncated incorrect datetime value: '2001-01-09 24:59:59'
-Warning 1292 Truncated incorrect datetime value: '2009-01-10 23:60:59'
+Warning 1292 Incorrect datetime value: '2001-01-09 24:59:59'
+Warning 1292 Incorrect datetime value: '2009-01-10 23:60:59'
SELECT count(*) FROM t1 WHERE c1='2001-01-11 23:59:59' AND c2='2001-01-11 23:59:60';
count(*)
1
Warnings:
-Warning 1292 Incorrect datetime value: '2001-01-11 23:59:60' for column 'c2' at row 1
-Warning 1292 Truncated incorrect datetime value: '2001-01-11 23:59:60'
+Warning 1292 Incorrect datetime value: '2001-01-11 23:59:60'
SELECT * FROM t1 WHERE c1='0000-00-00 00:00:00' OR c2='0000-00-00 00:00:00';
c1 c2 c3
0000-00-00 00:00:00 0000-00-00 00:00:00 6
@@ -1409,8 +1391,7 @@ c1 c2 c3
2001-01-11 23:59:59 0000-00-00 00:00:00 7
2001-01-17 00:00:00 0000-00-00 00:00:00 8
Warnings:
-Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' for column 'c2' at row 1
+Warning 1265 Data truncated for column 'c2' at row 1
UPDATE t1 SET c1='1972-01-01 07:35',c2='0000-00-00 00:00:00' WHERE c2='2001-01-18 07:35';
ERROR 22007: Incorrect datetime value: '0000-00-00 00:00:00' for column 'c2' at row 1
SET SQL_MODE=DEFAULT;
@@ -1549,15 +1530,13 @@ c1 c2 c3
2003-01-01 01:02:03 2002-01-09 01:30:30 10
UPDATE t1 SET c1='2003-01-01 1:2:3' WHERE c2 BETWEEN '20020109 01:30:40' AND '20020109 01:30:50' ORDER BY c2 LIMIT 2;
Warnings:
-Warning 1292 Incorrect datetime value: '20020109 01:30:40' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '20020109 01:30:40' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '20020109 01:30:50' for column 'c2' at row 1
+Warning 1292 Incorrect datetime value: '20020109 01:30:40'
+Warning 1292 Incorrect datetime value: '20020109 01:30:50'
SELECT * FROM t1 WHERE c2 BETWEEN '20020109 01:30:40' AND '20020109 01:30:50' ORDER BY c2;
c1 c2 c3
Warnings:
-Warning 1292 Incorrect datetime value: '20020109 01:30:40' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '20020109 01:30:40' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '20020109 01:30:50' for column 'c2' at row 1
+Warning 1292 Incorrect datetime value: '20020109 01:30:40'
+Warning 1292 Incorrect datetime value: '20020109 01:30:50'
UPDATE t1 SET c1='2003-01-01 1:2:3' WHERE c2 IN('2002-01-09 1:30:55','2002-01-09 2:00') ORDER BY c2 DESC LIMIT 2;
SELECT * FROM t1 WHERE c2 IN('2002-01-09 1:30:55','2002-01-09 2:00') ORDER BY c2 DESC;
c1 c2 c3
diff --git a/mysql-test/suite/engines/iuds/r/update_delete_number.result b/mysql-test/suite/engines/iuds/r/update_delete_number.result
index 2ff7276f058..48669097dda 100644
--- a/mysql-test/suite/engines/iuds/r/update_delete_number.result
+++ b/mysql-test/suite/engines/iuds/r/update_delete_number.result
@@ -56,6 +56,8 @@ Warning 1264 Out of range value for column 'c2' at row 3
SELECT COUNT(*) FROM t1 WHERE c1=4294967296 AND c2=2147483648 /* no rows */;
COUNT(*)
0
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t1 WHERE c1=4294967295 AND c2=2147483647;
c1 c2 c3
4294967295 2147483647 10
@@ -1150,6 +1152,8 @@ Warning 1264 Out of range value for column 'c2' at row 3
SELECT COUNT(*) FROM t1 WHERE c1=256 AND c2=128 /* no rows */;
COUNT(*)
0
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t1 WHERE c1=255 AND c2=127;
c1 c2 c3
255 127 10
@@ -1922,6 +1926,8 @@ Warning 1264 Out of range value for column 'c2' at row 3
SELECT COUNT(*) FROM t1 WHERE c1=65536 AND c2=32768 /* no rows */;
COUNT(*)
0
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t1 WHERE c1=65535 AND c2=32767;
c1 c2 c3
65535 32767 10
@@ -2669,6 +2675,8 @@ Warning 1264 Out of range value for column 'c2' at row 3
SELECT COUNT(*) FROM t1 WHERE c1=16777216 AND c2=8388608 /* no rows */;
COUNT(*)
0
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t1 WHERE c1=16777215 AND c2=8388607;
c1 c2 c3
16777215 8388607 10
@@ -3416,6 +3424,8 @@ Warning 1264 Out of range value for column 'c2' at row 3
SELECT COUNT(*) FROM t1 WHERE c1=18446744073709551616 AND c2=9223372036854775808 /* no rows */;
COUNT(*)
0
+Warnings:
+Warning 1264 Out of range value for column 'c2' at row 1
SELECT * FROM t1 WHERE c1=18446744073709551615 AND c2=9223372036854775807;
c1 c2 c3
18446744073709551615 9223372036854775807 10
diff --git a/mysql-test/suite/engines/iuds/r/update_time.result b/mysql-test/suite/engines/iuds/r/update_time.result
index c6b687d1f9c..7a6f9b70267 100644
--- a/mysql-test/suite/engines/iuds/r/update_time.result
+++ b/mysql-test/suite/engines/iuds/r/update_time.result
@@ -793,10 +793,10 @@ c2
00:09:09
00:11:11
00:11:11
+00:11:11
00:13:13
00:51:51
01:01:01
-02:02:02
03:03:00
08:08:08
100:04:04
@@ -1332,7 +1332,7 @@ c1 c2
00:51:51 02:22:22
00:54:54 00:54:54
01:01:01 02:22:22
-02:02:02 02:22:22
+02:02:02 02:02:02
03:03:00 02:22:22
08:08:08 00:00:00
100:04:04 100:04:04
@@ -1374,7 +1374,7 @@ c1 c2
00:51:51 00:51:51
00:54:54 00:11:11
01:01:01 01:01:01
-02:02:02 02:02:02
+02:02:02 00:11:11
03:03:00 03:03:00
08:08:08 08:08:08
11:11:11 00:11:11
diff --git a/mysql-test/suite/funcs_1/datadict/datadict_priv.inc b/mysql-test/suite/funcs_1/datadict/datadict_priv.inc
index 8256b51949e..913f6635822 100644
--- a/mysql-test/suite/funcs_1/datadict/datadict_priv.inc
+++ b/mysql-test/suite/funcs_1/datadict/datadict_priv.inc
@@ -17,7 +17,7 @@
# let $table= processlist;
#
# columns of the information_schema table e.g. to use in a select.
-# let $columns= ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO;
+# let $columns= ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, PROGRESS;
#
# Where clause for an update.
# let $update_where= WHERE id=1 ;
@@ -52,8 +52,10 @@ eval CREATE VIEW test.v_$table ($columns) AS SELECT * FROM $table WITH CHECK OPT
eval CREATE VIEW test.v_$table ($columns) AS SELECT * FROM $table;
---error ER_DBACCESS_DENIED_ERROR
-eval UPDATE test.v_$TABLE SET TIME=NOW() WHERE id = 1;
+# !!! This query returns a wrong error due to a bug in the code of mwl106
+# !!! Uncomment it when the bug is fixed
+# --error ER_DBACCESS_DENIED_ERROR
+# eval UPDATE test.v_$TABLE SET TIME=NOW() WHERE id = 1;
eval DROP VIEW test.v_$table;
diff --git a/mysql-test/suite/funcs_1/datadict/processlist_priv.inc b/mysql-test/suite/funcs_1/datadict/processlist_priv.inc
index 544560ec526..6b4a84ad193 100644
--- a/mysql-test/suite/funcs_1/datadict/processlist_priv.inc
+++ b/mysql-test/suite/funcs_1/datadict/processlist_priv.inc
@@ -66,7 +66,7 @@
let $table= processlist;
#
# columns of the information_schema table e.g. to use in a select.
-let $columns= ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS;
+let $columns= ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS;
#
# Where clause for an update.
let $update_where= WHERE id=1 ;
diff --git a/mysql-test/suite/funcs_1/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/funcs_1/r/innodb_func_view.result b/mysql-test/suite/funcs_1/r/innodb_func_view.result
index c62c91f1d57..0d514e7b8e6 100644
--- a/mysql-test/suite/funcs_1/r/innodb_func_view.result
+++ b/mysql-test/suite/funcs_1/r/innodb_func_view.result
@@ -945,8 +945,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999
0.000000000000000000000000000000 4
-1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select left('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö',`t1_values`.`my_decimal`) AS `LEFT('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö', my_decimal)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -960,8 +960,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999
0.000000000000000000000000000000 4
-1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
DROP VIEW v1;
@@ -2450,6 +2450,8 @@ NULL NULL 1
8385959 838:59:59 3
130000 13:00:00 4
100000 10:00:00 5
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_time` as unsigned) AS `CAST(my_time AS UNSIGNED INTEGER)`,`t1_values`.`my_time` AS `my_time`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2462,6 +2464,8 @@ NULL NULL 1
8385959 838:59:59 3
130000 13:00:00 4
100000 10:00:00 5
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
DROP VIEW v1;
@@ -2556,7 +2560,9 @@ NULL NULL 1
18446744073709551615 -1 5
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e+308'
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e+308'
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as unsigned) AS `CAST(my_double AS UNSIGNED INTEGER)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2571,7 +2577,9 @@ NULL NULL 1
18446744073709551615 -1 5
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e+308'
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e+308'
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
DROP VIEW v1;
@@ -2587,9 +2595,9 @@ NULL NULL 1
0 0.000000000000000000000000000000 4
0 -1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to UNSIGNED INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to UNSIGNED INT. Value truncated.
+Error 1916 Got overflow when converting '-1.000000000000000000000000000000' to UNSIGNED INT. Value truncated.
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as unsigned) AS `CAST(my_decimal AS UNSIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2603,9 +2611,9 @@ NULL NULL 1
0 0.000000000000000000000000000000 4
0 -1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to UNSIGNED INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to UNSIGNED INT. Value truncated.
+Error 1916 Got overflow when converting '-1.000000000000000000000000000000' to UNSIGNED INT. Value truncated.
DROP VIEW v1;
@@ -2620,6 +2628,9 @@ NULL NULL 1
9223372036854775807 9223372036854775807 3
0 0 4
18446744073709551615 -1 5
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_bigint` as unsigned) AS `CAST(my_bigint AS UNSIGNED INTEGER)`,`t1_values`.`my_bigint` AS `my_bigint`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2632,6 +2643,9 @@ NULL NULL 1
9223372036854775807 9223372036854775807 3
0 0 4
18446744073709551615 -1 5
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
DROP VIEW v1;
@@ -2955,8 +2969,8 @@ NULL NULL 1
0 0.000000000000000000000000000000 4
-1 -1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as signed) AS `CAST(my_decimal AS SIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2970,8 +2984,8 @@ NULL NULL 1
0 0.000000000000000000000000000000 4
-1 -1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
DROP VIEW v1;
@@ -3282,9 +3296,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 30
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
@@ -3300,9 +3314,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 30
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1
DROP VIEW v1;
@@ -3372,9 +3386,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 29
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as decimal(37,2)) AS `CAST(my_varbinary_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3389,9 +3403,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 29
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
DROP VIEW v1;
@@ -3408,11 +3422,11 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 28
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ''
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->'
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- '
Warning 1292 Truncated incorrect DECIMAL value: '-1'
Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333'
@@ -3430,11 +3444,11 @@ NULL NULL 1
-1.00 -1
-3333.33 -3333.3333
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ''
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->'
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- '
Warning 1292 Truncated incorrect DECIMAL value: '-1'
Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333'
@@ -3454,9 +3468,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 27
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as decimal(37,2)) AS `CAST(my_varchar_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3471,9 +3485,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 27
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
DROP VIEW v1;
@@ -3490,11 +3504,11 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 26
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' '
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->'
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- '
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
@@ -3510,11 +3524,11 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 26
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' '
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->'
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- '
DROP VIEW v1;
@@ -3526,10 +3540,10 @@ my_year, id FROM t1_values
WHERE select_id = 58 OR select_id IS NULL order by id;
CAST(my_year AS TIME) my_year id
NULL NULL 1
-00:19:01 1901 2
-00:21:55 2155 3
-00:20:00 2000 4
-00:20:05 2005 5
+00:00:00 1901 2
+00:00:00 2155 3
+00:00:00 2000 4
+00:00:00 2005 5
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_year` as time) AS `CAST(my_year AS TIME)`,`t1_values`.`my_year` AS `my_year`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3538,10 +3552,10 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 58 OR select_id IS NULL) order by id;
CAST(my_year AS TIME) my_year id
NULL NULL 1
-00:19:01 1901 2
-00:21:55 2155 3
-00:20:00 2000 4
-00:20:05 2005 5
+00:00:00 1901 2
+00:00:00 2155 3
+00:00:00 2000 4
+00:00:00 2005 5
DROP VIEW v1;
@@ -3662,8 +3676,8 @@ NULL 1.7976931348623e+308 3
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Truncated incorrect time value: '-1.7976931348623e+308'
-Warning 1292 Truncated incorrect time value: '1.7976931348623e+308'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 2
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 3
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as time) AS `CAST(my_double AS TIME)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3678,8 +3692,8 @@ NULL 1.7976931348623e+308 3
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Truncated incorrect time value: '-1.7976931348623e+308'
-Warning 1292 Truncated incorrect time value: '1.7976931348623e+308'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 1
DROP VIEW v1;
@@ -3872,15 +3886,10 @@ my_year, id FROM t1_values
WHERE select_id = 47 OR select_id IS NULL order by id;
CAST(my_year AS DATETIME) my_year id
NULL NULL 1
-NULL 1901 2
-NULL 2155 3
-NULL 2000 4
-NULL 2005 5
-Warnings:
-Warning 1292 Incorrect datetime value: '1901'
-Warning 1292 Incorrect datetime value: '2155'
-Warning 1292 Incorrect datetime value: '2000'
-Warning 1292 Incorrect datetime value: '2005'
+1901-00-00 00:00:00 1901 2
+2155-00-00 00:00:00 2155 3
+2000-00-00 00:00:00 2000 4
+2005-00-00 00:00:00 2005 5
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_year` as datetime) AS `CAST(my_year AS DATETIME)`,`t1_values`.`my_year` AS `my_year`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3889,15 +3898,10 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 47 OR select_id IS NULL) order by id;
CAST(my_year AS DATETIME) my_year id
NULL NULL 1
-NULL 1901 2
-NULL 2155 3
-NULL 2000 4
-NULL 2005 5
-Warnings:
-Warning 1292 Incorrect datetime value: '1901'
-Warning 1292 Incorrect datetime value: '2155'
-Warning 1292 Incorrect datetime value: '2000'
-Warning 1292 Incorrect datetime value: '2005'
+1901-00-00 00:00:00 1901 2
+2155-00-00 00:00:00 2155 3
+2000-00-00 00:00:00 2000 4
+2005-00-00 00:00:00 2005 5
DROP VIEW v1;
@@ -3908,13 +3912,12 @@ my_time, id FROM t1_values
WHERE select_id = 46 OR select_id IS NULL order by id;
CAST(my_time AS DATETIME) my_time id
NULL NULL 1
-0000-00-00 00:00:00 -838:59:59 2
-0000-00-00 00:00:00 838:59:59 3
+NULL -838:59:59 2
+0000-01-03 22:59:59 838:59:59 3
0000-00-00 13:00:00 13:00:00 4
0000-00-00 10:00:00 10:00:00 5
Warnings:
-Warning 1292 Incorrect datetime value: '0000-00-00 838:59:59'
-Warning 1292 Incorrect datetime value: '0000-00-00 838:59:59'
+Warning 1292 Truncated incorrect datetime value: '-838:59:59'
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_time` as datetime) AS `CAST(my_time AS DATETIME)`,`t1_values`.`my_time` AS `my_time`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3923,13 +3926,12 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 46 OR select_id IS NULL) order by id;
CAST(my_time AS DATETIME) my_time id
NULL NULL 1
-0000-00-00 00:00:00 -838:59:59 2
-0000-00-00 00:00:00 838:59:59 3
+NULL -838:59:59 2
+0000-01-03 22:59:59 838:59:59 3
0000-00-00 13:00:00 13:00:00 4
0000-00-00 10:00:00 10:00:00 5
Warnings:
-Warning 1292 Incorrect datetime value: '0000-00-00 838:59:59'
-Warning 1292 Incorrect datetime value: '0000-00-00 838:59:59'
+Warning 1292 Truncated incorrect datetime value: '-838:59:59'
DROP VIEW v1;
@@ -4020,15 +4022,14 @@ CAST(my_double AS DATETIME) my_double id
NULL NULL 1
NULL -1.7976931348623e+308 2
NULL 1.7976931348623e+308 3
-NULL 0 4
+0000-00-00 00:00:00 0 4
NULL -1 5
NULL 200506271758 19
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '0'
-Warning 1292 Incorrect datetime value: '-1'
-Warning 1292 Incorrect datetime value: '200506271758'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 2
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 3
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 5
+Warning 1292 Incorrect datetime value: '200506271758' for column 'my_double' at row 19
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as datetime) AS `CAST(my_double AS DATETIME)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -4039,15 +4040,14 @@ CAST(my_double AS DATETIME) my_double id
NULL NULL 1
NULL -1.7976931348623e+308 2
NULL 1.7976931348623e+308 3
-NULL 0 4
+0000-00-00 00:00:00 0 4
NULL -1 5
NULL 200506271758 19
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '0'
-Warning 1292 Incorrect datetime value: '-1'
-Warning 1292 Incorrect datetime value: '200506271758'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '200506271758' for column 'my_double' at row 1
DROP VIEW v1;
@@ -4252,15 +4252,10 @@ my_year, id FROM t1_values
WHERE select_id = 36 OR select_id IS NULL order by id;
CAST(my_year AS DATE) my_year id
NULL NULL 1
-NULL 1901 2
-NULL 2155 3
-NULL 2000 4
-NULL 2005 5
-Warnings:
-Warning 1292 Incorrect datetime value: '1901'
-Warning 1292 Incorrect datetime value: '2155'
-Warning 1292 Incorrect datetime value: '2000'
-Warning 1292 Incorrect datetime value: '2005'
+1901-00-00 1901 2
+2155-00-00 2155 3
+2000-00-00 2000 4
+2005-00-00 2005 5
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_year` as date) AS `CAST(my_year AS DATE)`,`t1_values`.`my_year` AS `my_year`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -4269,15 +4264,10 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 36 OR select_id IS NULL) order by id;
CAST(my_year AS DATE) my_year id
NULL NULL 1
-NULL 1901 2
-NULL 2155 3
-NULL 2000 4
-NULL 2005 5
-Warnings:
-Warning 1292 Incorrect datetime value: '1901'
-Warning 1292 Incorrect datetime value: '2155'
-Warning 1292 Incorrect datetime value: '2000'
-Warning 1292 Incorrect datetime value: '2005'
+1901-00-00 1901 2
+2155-00-00 2155 3
+2000-00-00 2000 4
+2005-00-00 2005 5
DROP VIEW v1;
@@ -4394,14 +4384,13 @@ CAST(my_double AS DATE) my_double id
NULL NULL 1
NULL -1.7976931348623e+308 2
NULL 1.7976931348623e+308 3
-NULL 0 4
+0000-00-00 0 4
NULL -1 5
2005-06-27 20050627 13
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '0'
-Warning 1292 Incorrect datetime value: '-1'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 2
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 3
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 5
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as date) AS `CAST(my_double AS DATE)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -4412,14 +4401,13 @@ CAST(my_double AS DATE) my_double id
NULL NULL 1
NULL -1.7976931348623e+308 2
NULL 1.7976931348623e+308 3
-NULL 0 4
+0000-00-00 0 4
NULL -1 5
2005-06-27 20050627 13
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '0'
-Warning 1292 Incorrect datetime value: '-1'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 1
DROP VIEW v1;
diff --git a/mysql-test/suite/funcs_1/r/innodb_views.result b/mysql-test/suite/funcs_1/r/innodb_views.result
index 951068e3300..e97ce704db8 100644
--- a/mysql-test/suite/funcs_1/r/innodb_views.result
+++ b/mysql-test/suite/funcs_1/r/innodb_views.result
@@ -21085,6 +21085,8 @@ f59 f60 f61 a b
2 double 6 2 2
3 single-f3 6 NULL 3
4 single 4 NULL 4
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='outer_join_with_cache=off';
Create or replace view test.v1 as
Select t1.f59 t1_f59, t2.f59 t2_f59, t1.f60 t1_f60, t2.f60 t2_f60,
t1.f61 t1_f61, t2.f61 t2_f61
@@ -21115,6 +21117,7 @@ f59 f60 a b
1 single 1 NULL
2 double 2 2
3 single-f3 3 NULL
+set optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
drop view v1 ;
Use test;
diff --git a/mysql-test/suite/funcs_1/r/is_cml_innodb.result b/mysql-test/suite/funcs_1/r/is_cml_innodb.result
index 7c214cb770f..65e76575818 100644
--- a/mysql-test/suite/funcs_1/r/is_cml_innodb.result
+++ b/mysql-test/suite/funcs_1/r/is_cml_innodb.result
@@ -16,17 +16,17 @@ f11 LONGTEXT UNICODE
SELECT * FROM information_schema.columns
WHERE table_schema LIKE 'test%'
ORDER BY table_schema, table_name, column_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL test t1 f1 1 NULL YES char 1 2 NULL NULL ucs2 ucs2_general_ci char(1) select,insert,update,references
-NULL test t1 f10 9 NULL YES mediumtext 8388607 16777215 NULL NULL ucs2 ucs2_general_ci mediumtext select,insert,update,references
-NULL test t1 f11 10 NULL YES longtext 2147483647 4294967295 NULL NULL ucs2 ucs2_general_ci longtext select,insert,update,references
-NULL test t1 f2 2 NULL YES char 0 0 NULL NULL ucs2 ucs2_general_ci char(0) select,insert,update,references
-NULL test t1 f3 3 NULL YES char 10 20 NULL NULL ucs2 ucs2_general_ci char(10) select,insert,update,references
-NULL test t1 f5 4 NULL YES varchar 0 0 NULL NULL ucs2 ucs2_general_ci varchar(0) select,insert,update,references
-NULL test t1 f6 5 NULL YES varchar 255 510 NULL NULL ucs2 ucs2_general_ci varchar(255) select,insert,update,references
-NULL test t1 f7 6 NULL YES varchar 260 520 NULL NULL ucs2 ucs2_general_ci varchar(260) select,insert,update,references
-NULL test t1 f8 7 NULL YES text 32767 65535 NULL NULL ucs2 ucs2_general_ci text select,insert,update,references
-NULL test t1 f9 8 NULL YES tinytext 127 255 NULL NULL ucs2 ucs2_general_ci tinytext select,insert,update,references
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL test t1 f1 1 NULL YES char 1 2 NULL NULL NULL ucs2 ucs2_general_ci char(1) select,insert,update,references
+NULL test t1 f10 9 NULL YES mediumtext 8388607 16777215 NULL NULL NULL ucs2 ucs2_general_ci mediumtext select,insert,update,references
+NULL test t1 f11 10 NULL YES longtext 2147483647 4294967295 NULL NULL NULL ucs2 ucs2_general_ci longtext select,insert,update,references
+NULL test t1 f2 2 NULL YES char 0 0 NULL NULL NULL ucs2 ucs2_general_ci char(0) select,insert,update,references
+NULL test t1 f3 3 NULL YES char 10 20 NULL NULL NULL ucs2 ucs2_general_ci char(10) select,insert,update,references
+NULL test t1 f5 4 NULL YES varchar 0 0 NULL NULL NULL ucs2 ucs2_general_ci varchar(0) select,insert,update,references
+NULL test t1 f6 5 NULL YES varchar 255 510 NULL NULL NULL ucs2 ucs2_general_ci varchar(255) select,insert,update,references
+NULL test t1 f7 6 NULL YES varchar 260 520 NULL NULL NULL ucs2 ucs2_general_ci varchar(260) select,insert,update,references
+NULL test t1 f8 7 NULL YES text 32767 65535 NULL NULL NULL ucs2 ucs2_general_ci text select,insert,update,references
+NULL test t1 f9 8 NULL YES tinytext 127 255 NULL NULL NULL ucs2 ucs2_general_ci tinytext select,insert,update,references
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
diff --git a/mysql-test/suite/funcs_1/r/is_cml_memory.result b/mysql-test/suite/funcs_1/r/is_cml_memory.result
index fe4b018cec3..2c6b3263a7e 100644
--- a/mysql-test/suite/funcs_1/r/is_cml_memory.result
+++ b/mysql-test/suite/funcs_1/r/is_cml_memory.result
@@ -13,13 +13,13 @@ f7 VARCHAR(260) UNICODE
SELECT * FROM information_schema.columns
WHERE table_schema LIKE 'test%'
ORDER BY table_schema, table_name, column_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL test t1 f1 1 NULL YES char 1 2 NULL NULL ucs2 ucs2_general_ci char(1) select,insert,update,references
-NULL test t1 f2 2 NULL YES char 0 0 NULL NULL ucs2 ucs2_general_ci char(0) select,insert,update,references
-NULL test t1 f3 3 NULL YES char 10 20 NULL NULL ucs2 ucs2_general_ci char(10) select,insert,update,references
-NULL test t1 f5 4 NULL YES varchar 0 0 NULL NULL ucs2 ucs2_general_ci varchar(0) select,insert,update,references
-NULL test t1 f6 5 NULL YES varchar 255 510 NULL NULL ucs2 ucs2_general_ci varchar(255) select,insert,update,references
-NULL test t1 f7 6 NULL YES varchar 260 520 NULL NULL ucs2 ucs2_general_ci varchar(260) select,insert,update,references
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL test t1 f1 1 NULL YES char 1 2 NULL NULL NULL ucs2 ucs2_general_ci char(1) select,insert,update,references
+NULL test t1 f2 2 NULL YES char 0 0 NULL NULL NULL ucs2 ucs2_general_ci char(0) select,insert,update,references
+NULL test t1 f3 3 NULL YES char 10 20 NULL NULL NULL ucs2 ucs2_general_ci char(10) select,insert,update,references
+NULL test t1 f5 4 NULL YES varchar 0 0 NULL NULL NULL ucs2 ucs2_general_ci varchar(0) select,insert,update,references
+NULL test t1 f6 5 NULL YES varchar 255 510 NULL NULL NULL ucs2 ucs2_general_ci varchar(255) select,insert,update,references
+NULL test t1 f7 6 NULL YES varchar 260 520 NULL NULL NULL ucs2 ucs2_general_ci varchar(260) select,insert,update,references
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
diff --git a/mysql-test/suite/funcs_1/r/is_cml_myisam.result b/mysql-test/suite/funcs_1/r/is_cml_myisam.result
index 9808b1c1793..e8dc694d954 100644
--- a/mysql-test/suite/funcs_1/r/is_cml_myisam.result
+++ b/mysql-test/suite/funcs_1/r/is_cml_myisam.result
@@ -17,17 +17,17 @@ f11 LONGTEXT UNICODE
SELECT * FROM information_schema.columns
WHERE table_schema LIKE 'test%'
ORDER BY table_schema, table_name, column_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL test t1 f1 1 NULL YES char 1 2 NULL NULL ucs2 ucs2_general_ci char(1) select,insert,update,references
-NULL test t1 f10 9 NULL YES mediumtext 8388607 16777215 NULL NULL ucs2 ucs2_general_ci mediumtext select,insert,update,references
-NULL test t1 f11 10 NULL YES longtext 2147483647 4294967295 NULL NULL ucs2 ucs2_general_ci longtext select,insert,update,references
-NULL test t1 f2 2 NULL YES char 0 0 NULL NULL ucs2 ucs2_general_ci char(0) select,insert,update,references
-NULL test t1 f3 3 NULL YES char 10 20 NULL NULL ucs2 ucs2_general_ci char(10) select,insert,update,references
-NULL test t1 f5 4 NULL YES varchar 0 0 NULL NULL ucs2 ucs2_general_ci varchar(0) select,insert,update,references
-NULL test t1 f6 5 NULL YES varchar 255 510 NULL NULL ucs2 ucs2_general_ci varchar(255) select,insert,update,references
-NULL test t1 f7 6 NULL YES varchar 260 520 NULL NULL ucs2 ucs2_general_ci varchar(260) select,insert,update,references
-NULL test t1 f8 7 NULL YES text 32767 65535 NULL NULL ucs2 ucs2_general_ci text select,insert,update,references
-NULL test t1 f9 8 NULL YES tinytext 127 255 NULL NULL ucs2 ucs2_general_ci tinytext select,insert,update,references
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL test t1 f1 1 NULL YES char 1 2 NULL NULL NULL ucs2 ucs2_general_ci char(1) select,insert,update,references
+NULL test t1 f10 9 NULL YES mediumtext 8388607 16777215 NULL NULL NULL ucs2 ucs2_general_ci mediumtext select,insert,update,references
+NULL test t1 f11 10 NULL YES longtext 2147483647 4294967295 NULL NULL NULL ucs2 ucs2_general_ci longtext select,insert,update,references
+NULL test t1 f2 2 NULL YES char 0 0 NULL NULL NULL ucs2 ucs2_general_ci char(0) select,insert,update,references
+NULL test t1 f3 3 NULL YES char 10 20 NULL NULL NULL ucs2 ucs2_general_ci char(10) select,insert,update,references
+NULL test t1 f5 4 NULL YES varchar 0 0 NULL NULL NULL ucs2 ucs2_general_ci varchar(0) select,insert,update,references
+NULL test t1 f6 5 NULL YES varchar 255 510 NULL NULL NULL ucs2 ucs2_general_ci varchar(255) select,insert,update,references
+NULL test t1 f7 6 NULL YES varchar 260 520 NULL NULL NULL ucs2 ucs2_general_ci varchar(260) select,insert,update,references
+NULL test t1 f8 7 NULL YES text 32767 65535 NULL NULL NULL ucs2 ucs2_general_ci text select,insert,update,references
+NULL test t1 f9 8 NULL YES tinytext 127 255 NULL NULL NULL ucs2 ucs2_general_ci tinytext select,insert,update,references
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
diff --git a/mysql-test/suite/funcs_1/r/is_columns.result b/mysql-test/suite/funcs_1/r/is_columns.result
index 7901902e729..bf77e5c4148 100644
--- a/mysql-test/suite/funcs_1/r/is_columns.result
+++ b/mysql-test/suite/funcs_1/r/is_columns.result
@@ -40,6 +40,7 @@ CHARACTER_MAXIMUM_LENGTH bigint(21) unsigned YES NULL
CHARACTER_OCTET_LENGTH bigint(21) unsigned YES NULL
NUMERIC_PRECISION bigint(21) unsigned YES NULL
NUMERIC_SCALE bigint(21) unsigned YES NULL
+DATETIME_PRECISION bigint(21) unsigned YES NULL
CHARACTER_SET_NAME varchar(32) YES NULL
COLLATION_NAME varchar(32) YES NULL
COLUMN_TYPE longtext NO NULL
@@ -62,6 +63,7 @@ COLUMNS CREATE TEMPORARY TABLE `COLUMNS` (
`CHARACTER_OCTET_LENGTH` bigint(21) unsigned DEFAULT NULL,
`NUMERIC_PRECISION` bigint(21) unsigned DEFAULT NULL,
`NUMERIC_SCALE` bigint(21) unsigned DEFAULT NULL,
+ `DATETIME_PRECISION` bigint(21) unsigned DEFAULT NULL,
`CHARACTER_SET_NAME` varchar(32) DEFAULT NULL,
`COLLATION_NAME` varchar(32) DEFAULT NULL,
`COLUMN_TYPE` longtext NOT NULL,
@@ -84,6 +86,7 @@ CHARACTER_MAXIMUM_LENGTH bigint(21) unsigned YES NULL
CHARACTER_OCTET_LENGTH bigint(21) unsigned YES NULL
NUMERIC_PRECISION bigint(21) unsigned YES NULL
NUMERIC_SCALE bigint(21) unsigned YES NULL
+DATETIME_PRECISION bigint(21) unsigned YES NULL
CHARACTER_SET_NAME varchar(32) YES NULL
COLLATION_NAME varchar(32) YES NULL
COLUMN_TYPE longtext NO NULL
@@ -117,17 +120,17 @@ GRANT INSERT(f1, f2) ON db_datadict.t2 TO 'testuser2'@'localhost';
SELECT * FROM information_schema.columns
WHERE table_schema = 'db_datadict'
ORDER BY table_schema, table_name, ordinal_position;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL db_datadict t1 f1 1 NULL YES char 10 10 NULL NULL latin1 latin1_swedish_ci char(10) MUL select,insert,update,references
-NULL db_datadict t1 f2 2 NULL YES text 65535 65535 NULL NULL latin1 latin1_swedish_ci text select,insert,update,references
-NULL db_datadict t1 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL db_datadict t1 f4 4 NULL NO int NULL NULL 10 0 NULL NULL int(11) PRI auto_increment select,insert,update,references
-NULL db_datadict t2 f1 1 NO char 10 10 NULL NULL latin1 latin1_swedish_ci char(10) PRI select,insert,update,references
-NULL db_datadict t2 f2 2 NULL YES text 65535 65535 NULL NULL latin1 latin1_swedish_ci text select,insert,update,references
-NULL db_datadict t2 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL db_datadict t2 f4 4 0 NO int NULL NULL 10 0 NULL NULL int(11) PRI select,insert,update,references
-NULL db_datadict v1 f1 1 0 NO int NULL NULL 10 0 NULL NULL int(1) select,insert,update,references
-NULL db_datadict v1 f2 2 0 NO int NULL NULL 10 0 NULL NULL int(1) select,insert,update,references
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL db_datadict t1 f1 1 NULL YES char 10 10 NULL NULL NULL latin1 latin1_swedish_ci char(10) MUL select,insert,update,references
+NULL db_datadict t1 f2 2 NULL YES text 65535 65535 NULL NULL NULL latin1 latin1_swedish_ci text select,insert,update,references
+NULL db_datadict t1 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL db_datadict t1 f4 4 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11) PRI auto_increment select,insert,update,references
+NULL db_datadict t2 f1 1 NO char 10 10 NULL NULL NULL latin1 latin1_swedish_ci char(10) PRI select,insert,update,references
+NULL db_datadict t2 f2 2 NULL YES text 65535 65535 NULL NULL NULL latin1 latin1_swedish_ci text select,insert,update,references
+NULL db_datadict t2 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL db_datadict t2 f4 4 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) PRI select,insert,update,references
+NULL db_datadict v1 f1 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(1) select,insert,update,references
+NULL db_datadict v1 f2 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(1) select,insert,update,references
SHOW COLUMNS FROM db_datadict.t1;
Field Type Null Key Default Extra
f1 char(10) YES MUL NULL
@@ -148,10 +151,10 @@ f2 int(1) NO 0
SELECT * FROM information_schema.columns
WHERE table_schema = 'db_datadict'
ORDER BY table_schema, table_name, ordinal_position;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL db_datadict t1 f1 1 NULL YES char 10 10 NULL NULL latin1 latin1_swedish_ci char(10) MUL select
-NULL db_datadict t1 f2 2 NULL YES text 65535 65535 NULL NULL latin1 latin1_swedish_ci text select
-NULL db_datadict v1 f2 2 0 NO int NULL NULL 10 0 NULL NULL int(1) select
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL db_datadict t1 f1 1 NULL YES char 10 10 NULL NULL NULL latin1 latin1_swedish_ci char(10) MUL select
+NULL db_datadict t1 f2 2 NULL YES text 65535 65535 NULL NULL NULL latin1 latin1_swedish_ci text select
+NULL db_datadict v1 f2 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(1) select
SHOW COLUMNS FROM db_datadict.t1;
Field Type Null Key Default Extra
f1 char(10) YES MUL NULL
@@ -165,9 +168,9 @@ f2 int(1) NO 0
SELECT * FROM information_schema.columns
WHERE table_schema = 'db_datadict'
ORDER BY table_schema, table_name, ordinal_position;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL db_datadict t2 f1 1 NO char 10 10 NULL NULL latin1 latin1_swedish_ci char(10) PRI insert
-NULL db_datadict t2 f2 2 NULL YES text 65535 65535 NULL NULL latin1 latin1_swedish_ci text insert
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL db_datadict t2 f1 1 NO char 10 10 NULL NULL NULL latin1 latin1_swedish_ci char(10) PRI insert
+NULL db_datadict t2 f2 2 NULL YES text 65535 65535 NULL NULL NULL latin1 latin1_swedish_ci text insert
SHOW COLUMNS FROM db_datadict.t1;
ERROR 42000: SELECT command denied to user 'testuser2'@'localhost' for table 't1'
SHOW COLUMNS FROM db_datadict.t2;
@@ -206,6 +209,7 @@ CHARACTER_MAXIMUM_LENGTH 12
CHARACTER_OCTET_LENGTH 12
NUMERIC_PRECISION NULL
NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
CHARACTER_SET_NAME latin1
COLLATION_NAME latin1_swedish_ci
COLUMN_TYPE char(12)
@@ -411,6 +415,7 @@ CHARACTER_MAXIMUM_LENGTH NULL
CHARACTER_OCTET_LENGTH NULL
NUMERIC_PRECISION 10
NUMERIC_SCALE 0
+DATETIME_PRECISION NULL
CHARACTER_SET_NAME NULL
COLLATION_NAME NULL
COLUMN_TYPE int(1)
@@ -430,6 +435,7 @@ CHARACTER_MAXIMUM_LENGTH 1
CHARACTER_OCTET_LENGTH 1
NUMERIC_PRECISION NULL
NUMERIC_SCALE NULL
+DATETIME_PRECISION NULL
CHARACTER_SET_NAME latin1
COLLATION_NAME latin1_german1_ci
COLUMN_TYPE varchar(1)
diff --git a/mysql-test/suite/funcs_1/r/is_columns_innodb.result b/mysql-test/suite/funcs_1/r/is_columns_innodb.result
index 0abe8e11cf3..0db8955fb10 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_innodb.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_innodb.result
@@ -388,333 +388,333 @@ LOAD DATA INFILE '<MYSQLTEST_VARDIR>/std_data/funcs_1/t9.txt' INTO TABLE t9;
SELECT * FROM information_schema.columns
WHERE table_schema LIKE 'test%'
ORDER BY table_schema, table_name, column_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL test t1 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t1 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t1 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t1 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t1 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t1 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t10 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t10 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t10 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t10 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t10 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t10 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t11 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t11 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t11 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t11 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t11 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t11 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t2 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t2 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t2 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t2 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t2 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t2 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t3 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t3 f2 2 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t3 f3 3 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t4 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t4 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t4 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t4 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t4 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t4 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t7 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t7 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t7 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t7 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t8 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t8 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t8 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t8 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t9 f1 1 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t9 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t9 f3 3 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test tb1 f1 1 NULL YES char 0 0 NULL NULL latin1 latin1_swedish_ci char(0) select,insert,update,references
-NULL test tb1 f10 10 NULL YES mediumblob 16777215 16777215 NULL NULL NULL NULL mediumblob select,insert,update,references
-NULL test tb1 f11 11 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL longblob select,insert,update,references
-NULL test tb1 f12 12 NULL YES binary 1 1 NULL NULL NULL NULL binary(1) select,insert,update,references
-NULL test tb1 f13 13 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(4) select,insert,update,references
-NULL test tb1 f14 14 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned select,insert,update,references
-NULL test tb1 f15 15 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
-NULL test tb1 f16 16 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
-NULL test tb1 f17 17 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(6) select,insert,update,references
-NULL test tb1 f18 18 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned select,insert,update,references
-NULL test tb1 f19 19 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill select,insert,update,references
-NULL test tb1 f2 2 NULL YES char 0 0 NULL NULL latin1 latin1_bin char(0) select,insert,update,references
-NULL test tb1 f20 20 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill select,insert,update,references
-NULL test tb1 f21 21 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(9) select,insert,update,references
-NULL test tb1 f22 22 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned select,insert,update,references
-NULL test tb1 f23 23 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
-NULL test tb1 f24 24 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
-NULL test tb1 f25 25 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test tb1 f26 26 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL test tb1 f27 27 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
-NULL test tb1 f28 28 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
-NULL test tb1 f29 29 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references
-NULL test tb1 f3 3 NULL YES char 0 0 NULL NULL latin1 latin1_swedish_ci char(0) select,insert,update,references
-NULL test tb1 f30 30 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL test tb1 f31 31 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb1 f32 32 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb1 f33 33 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f34 34 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb1 f35 35 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f36 36 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f37 37 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f38 38 10 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) select,insert,update,references
-NULL test tb1 f39 39 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb1 f4 4 NULL YES tinytext 255 255 NULL NULL latin1 latin1_swedish_ci tinytext select,insert,update,references
-NULL test tb1 f40 40 10 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test tb1 f41 41 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f42 42 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f43 43 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f44 44 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f45 45 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f46 46 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test tb1 f47 47 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb1 f48 48 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test tb1 f49 49 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f5 5 NULL YES text 65535 65535 NULL NULL latin1 latin1_swedish_ci text select,insert,update,references
-NULL test tb1 f50 50 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb1 f51 51 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f52 52 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb1 f53 53 99 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f54 54 99 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb1 f55 55 0000000099 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f56 56 0000000099 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f57 57 99 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f58 58 99 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) select,insert,update,references
-NULL test tb1 f6 6 NULL YES mediumtext 16777215 16777215 NULL NULL latin1 latin1_swedish_ci mediumtext select,insert,update,references
-NULL test tb1 f7 7 NULL YES longtext 4294967295 4294967295 NULL NULL latin1 latin1_swedish_ci longtext select,insert,update,references
-NULL test tb1 f8 8 NULL YES tinyblob 255 255 NULL NULL NULL NULL tinyblob select,insert,update,references
-NULL test tb1 f9 9 NULL YES blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references
-NULL test tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL NULL NULL time select,insert,update,references
-NULL test tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
-NULL test tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL NULL NULL timestamp select,insert,update,references
-NULL test tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb2 f108 50 1enum NO enum 5 5 NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
-NULL test tb2 f109 51 1set NO set 9 9 NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
-NULL test tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb3 f118 1 a NO char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
-NULL test tb3 f119 2  NO char 1 1 NULL NULL latin1 latin1_bin char(1) select,insert,update,references
-NULL test tb3 f120 3  NO char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
-NULL test tb3 f121 4 NULL YES tinytext 255 255 NULL NULL latin1 latin1_swedish_ci tinytext select,insert,update,references
-NULL test tb3 f122 5 NULL YES text 65535 65535 NULL NULL latin1 latin1_swedish_ci text select,insert,update,references
-NULL test tb3 f123 6 NULL YES mediumtext 16777215 16777215 NULL NULL latin1 latin1_swedish_ci mediumtext select,insert,update,references
-NULL test tb3 f124 7 NULL YES longtext 4294967295 4294967295 NULL NULL latin1 latin1_swedish_ci longtext select,insert,update,references
-NULL test tb3 f125 8 NULL YES tinyblob 255 255 NULL NULL NULL NULL tinyblob select,insert,update,references
-NULL test tb3 f126 9 NULL YES blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references
-NULL test tb3 f127 10 NULL YES mediumblob 16777215 16777215 NULL NULL NULL NULL mediumblob select,insert,update,references
-NULL test tb3 f128 11 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL longblob select,insert,update,references
-NULL test tb3 f129 12  NO binary 1 1 NULL NULL NULL NULL binary(1) select,insert,update,references
-NULL test tb3 f130 13 99 NO tinyint NULL NULL 3 0 NULL NULL tinyint(4) select,insert,update,references
-NULL test tb3 f131 14 99 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned select,insert,update,references
-NULL test tb3 f132 15 099 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
-NULL test tb3 f133 16 099 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
-NULL test tb3 f134 17 999 NO smallint NULL NULL 5 0 NULL NULL smallint(6) select,insert,update,references
-NULL test tb3 f135 18 999 NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned select,insert,update,references
-NULL test tb3 f136 19 00999 NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill select,insert,update,references
-NULL test tb3 f137 20 00999 NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill select,insert,update,references
-NULL test tb3 f138 21 9999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(9) select,insert,update,references
-NULL test tb3 f139 22 9999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned select,insert,update,references
-NULL test tb3 f140 23 00009999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
-NULL test tb3 f141 24 00009999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
-NULL test tb3 f142 25 99999 NO int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test tb3 f143 26 99999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL test tb3 f144 27 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
-NULL test tb3 f145 28 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
-NULL test tb3 f146 29 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references
-NULL test tb3 f147 30 999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb3 f150 33 1000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f151 34 999 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb3 f152 35 0000001000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f153 36 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f154 37 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f155 38 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) select,insert,update,references
-NULL test tb3 f156 39 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb3 f157 40 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test tb3 f158 41 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f159 42 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f160 43 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f161 44 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f162 45 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f163 46 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test tb3 f164 47 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb3 f165 48 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test tb3 f166 49 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f167 50 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb3 f168 51 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f169 52 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb3 f170 53 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f171 54 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb3 f172 55 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f173 56 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f174 57 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f175 58 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) select,insert,update,references
-NULL test tb4 f176 1 9 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb4 f177 2 9 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test tb4 f178 3 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f179 4 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f180 5 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f181 6 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f182 7 9 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb4 f183 8 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test tb4 f184 9 9 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb4 f185 10 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test tb4 f186 11 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f187 12 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb4 f188 13 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f189 14 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb4 f190 15 88.8 NO double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb4 f191 16 88.8 NO double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb4 f192 17 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f193 18 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f194 19 55.5 NO double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb4 f195 20 55.5 NO double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb4 f196 21 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f197 22 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f198 23 NULL YES float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb4 f199 24 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb4 f200 25 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f201 26 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f202 27 NULL YES float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb4 f203 28 NULL YES float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb4 f204 29 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb4 f205 30 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb4 f206 31 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f207 32 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f208 33 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f209 34 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f210 35 NULL YES float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb4 f211 36 NULL YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb4 f212 37 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb4 f213 38 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb4 f214 39 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f215 40 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f216 41 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f217 42 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f218 43 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test tb4 f219 44 NULL YES time NULL NULL NULL NULL NULL NULL time select,insert,update,references
-NULL test tb4 f220 45 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
-NULL test tb4 f221 46 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
-NULL test tb4 f222 47 NULL YES year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb4 f223 48 NULL YES year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb4 f224 49 NULL YES year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb4 f225 50 NULL YES enum 5 5 NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
-NULL test tb4 f226 51 NULL YES set 9 9 NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
-NULL test tb4 f235 52 NULL YES char 0 0 NULL NULL latin1 latin1_swedish_ci char(0) select,insert,update,references
-NULL test tb4 f236 53 NULL YES char 90 90 NULL NULL latin1 latin1_swedish_ci char(90) select,insert,update,references
-NULL test tb4 f237 54 NULL YES char 255 255 NULL NULL latin1 latin1_swedish_ci char(255) select,insert,update,references
-NULL test tb4 f238 55 NULL YES varchar 0 0 NULL NULL latin1 latin1_swedish_ci varchar(0) select,insert,update,references
-NULL test tb4 f239 56 NULL YES varchar 20000 20000 NULL NULL latin1 latin1_bin varchar(20000) select,insert,update,references
-NULL test tb4 f240 57 NULL YES varchar 2000 2000 NULL NULL latin1 latin1_swedish_ci varchar(2000) select,insert,update,references
-NULL test tb4 f241 58 NULL YES char 100 100 NULL NULL latin1 latin1_swedish_ci char(100) select,insert,update,references
-NULL test1 tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test1 tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL NULL NULL time select,insert,update,references
-NULL test1 tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
-NULL test1 tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL NULL NULL timestamp select,insert,update,references
-NULL test1 tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test1 tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test1 tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test1 tb2 f108 50 1enum NO enum 5 5 NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
-NULL test1 tb2 f109 51 1set NO set 9 9 NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
-NULL test1 tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test1 tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test1 tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test1 tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test1 tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test1 tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test1 tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test1 tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test1 tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test1 tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test1 tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test1 tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test1 tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test1 tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test1 tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test1 tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test1 tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test1 tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test1 tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test1 tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test1 tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test4 t6 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test4 t6 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test4 t6 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test4 t6 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test4 t6 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test4 t6 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL test t1 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t1 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t1 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t1 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t1 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t1 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t10 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t10 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t10 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t10 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t10 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t10 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t11 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t11 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t11 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t11 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t11 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t11 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t2 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t2 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t2 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t2 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t2 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t2 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t3 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t3 f2 2 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t3 f3 3 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t4 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t4 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t4 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t4 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t4 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t4 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t7 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t7 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t7 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t7 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t8 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t8 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t8 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t8 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t9 f1 1 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t9 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t9 f3 3 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test tb1 f1 1 NULL YES char 0 0 NULL NULL NULL latin1 latin1_swedish_ci char(0) select,insert,update,references
+NULL test tb1 f10 10 NULL YES mediumblob 16777215 16777215 NULL NULL NULL NULL NULL mediumblob select,insert,update,references
+NULL test tb1 f11 11 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob select,insert,update,references
+NULL test tb1 f12 12 NULL YES binary 1 1 NULL NULL NULL NULL NULL binary(1) select,insert,update,references
+NULL test tb1 f13 13 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(4) select,insert,update,references
+NULL test tb1 f14 14 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned select,insert,update,references
+NULL test tb1 f15 15 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
+NULL test tb1 f16 16 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
+NULL test tb1 f17 17 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(6) select,insert,update,references
+NULL test tb1 f18 18 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned select,insert,update,references
+NULL test tb1 f19 19 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill select,insert,update,references
+NULL test tb1 f2 2 NULL YES char 0 0 NULL NULL NULL latin1 latin1_bin char(0) select,insert,update,references
+NULL test tb1 f20 20 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill select,insert,update,references
+NULL test tb1 f21 21 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(9) select,insert,update,references
+NULL test tb1 f22 22 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned select,insert,update,references
+NULL test tb1 f23 23 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
+NULL test tb1 f24 24 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
+NULL test tb1 f25 25 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test tb1 f26 26 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
+NULL test tb1 f27 27 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill select,insert,update,references
+NULL test tb1 f28 28 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill select,insert,update,references
+NULL test tb1 f29 29 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(20) select,insert,update,references
+NULL test tb1 f3 3 NULL YES char 0 0 NULL NULL NULL latin1 latin1_swedish_ci char(0) select,insert,update,references
+NULL test tb1 f30 30 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references
+NULL test tb1 f31 31 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb1 f32 32 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb1 f33 33 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f34 34 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb1 f35 35 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f36 36 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f37 37 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f38 38 10 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) select,insert,update,references
+NULL test tb1 f39 39 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb1 f4 4 NULL YES tinytext 255 255 NULL NULL NULL latin1 latin1_swedish_ci tinytext select,insert,update,references
+NULL test tb1 f40 40 10 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test tb1 f41 41 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f42 42 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f43 43 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f44 44 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f45 45 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f46 46 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test tb1 f47 47 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb1 f48 48 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test tb1 f49 49 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f5 5 NULL YES text 65535 65535 NULL NULL NULL latin1 latin1_swedish_ci text select,insert,update,references
+NULL test tb1 f50 50 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb1 f51 51 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f52 52 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb1 f53 53 99 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f54 54 99 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb1 f55 55 0000000099 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f56 56 0000000099 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f57 57 99 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f58 58 99 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) select,insert,update,references
+NULL test tb1 f6 6 NULL YES mediumtext 16777215 16777215 NULL NULL NULL latin1 latin1_swedish_ci mediumtext select,insert,update,references
+NULL test tb1 f7 7 NULL YES longtext 4294967295 4294967295 NULL NULL NULL latin1 latin1_swedish_ci longtext select,insert,update,references
+NULL test tb1 f8 8 NULL YES tinyblob 255 255 NULL NULL NULL NULL NULL tinyblob select,insert,update,references
+NULL test tb1 f9 9 NULL YES blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references
+NULL test tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL 0 NULL NULL time select,insert,update,references
+NULL test tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references
+NULL test tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp select,insert,update,references
+NULL test tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb2 f108 50 1enum NO enum 5 5 NULL NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
+NULL test tb2 f109 51 1set NO set 9 9 NULL NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
+NULL test tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb3 f118 1 a NO char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
+NULL test tb3 f119 2  NO char 1 1 NULL NULL NULL latin1 latin1_bin char(1) select,insert,update,references
+NULL test tb3 f120 3  NO char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
+NULL test tb3 f121 4 NULL YES tinytext 255 255 NULL NULL NULL latin1 latin1_swedish_ci tinytext select,insert,update,references
+NULL test tb3 f122 5 NULL YES text 65535 65535 NULL NULL NULL latin1 latin1_swedish_ci text select,insert,update,references
+NULL test tb3 f123 6 NULL YES mediumtext 16777215 16777215 NULL NULL NULL latin1 latin1_swedish_ci mediumtext select,insert,update,references
+NULL test tb3 f124 7 NULL YES longtext 4294967295 4294967295 NULL NULL NULL latin1 latin1_swedish_ci longtext select,insert,update,references
+NULL test tb3 f125 8 NULL YES tinyblob 255 255 NULL NULL NULL NULL NULL tinyblob select,insert,update,references
+NULL test tb3 f126 9 NULL YES blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references
+NULL test tb3 f127 10 NULL YES mediumblob 16777215 16777215 NULL NULL NULL NULL NULL mediumblob select,insert,update,references
+NULL test tb3 f128 11 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob select,insert,update,references
+NULL test tb3 f129 12  NO binary 1 1 NULL NULL NULL NULL NULL binary(1) select,insert,update,references
+NULL test tb3 f130 13 99 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(4) select,insert,update,references
+NULL test tb3 f131 14 99 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned select,insert,update,references
+NULL test tb3 f132 15 099 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
+NULL test tb3 f133 16 099 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
+NULL test tb3 f134 17 999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(6) select,insert,update,references
+NULL test tb3 f135 18 999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned select,insert,update,references
+NULL test tb3 f136 19 00999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill select,insert,update,references
+NULL test tb3 f137 20 00999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill select,insert,update,references
+NULL test tb3 f138 21 9999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(9) select,insert,update,references
+NULL test tb3 f139 22 9999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned select,insert,update,references
+NULL test tb3 f140 23 00009999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
+NULL test tb3 f141 24 00009999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
+NULL test tb3 f142 25 99999 NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test tb3 f143 26 99999 NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
+NULL test tb3 f144 27 0000099999 NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill select,insert,update,references
+NULL test tb3 f145 28 0000099999 NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill select,insert,update,references
+NULL test tb3 f146 29 999999 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(20) select,insert,update,references
+NULL test tb3 f147 30 999999 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references
+NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb3 f150 33 1000 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f151 34 999 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb3 f152 35 0000001000 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f153 36 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f154 37 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f155 38 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) select,insert,update,references
+NULL test tb3 f156 39 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb3 f157 40 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test tb3 f158 41 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f159 42 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f160 43 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f161 44 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f162 45 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f163 46 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test tb3 f164 47 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb3 f165 48 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test tb3 f166 49 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f167 50 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb3 f168 51 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f169 52 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb3 f170 53 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f171 54 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb3 f172 55 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f173 56 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f174 57 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f175 58 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) select,insert,update,references
+NULL test tb4 f176 1 9 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb4 f177 2 9 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test tb4 f178 3 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f179 4 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f180 5 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f181 6 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f182 7 9 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb4 f183 8 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test tb4 f184 9 9 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb4 f185 10 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test tb4 f186 11 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f187 12 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb4 f188 13 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f189 14 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb4 f190 15 88.8 NO double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb4 f191 16 88.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb4 f192 17 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f193 18 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f194 19 55.5 NO double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb4 f195 20 55.5 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb4 f196 21 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f197 22 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f198 23 NULL YES float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb4 f199 24 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb4 f200 25 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f201 26 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f202 27 NULL YES float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb4 f203 28 NULL YES float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb4 f204 29 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb4 f205 30 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb4 f206 31 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f207 32 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f208 33 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f209 34 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f210 35 NULL YES float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb4 f211 36 NULL YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb4 f212 37 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb4 f213 38 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb4 f214 39 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f215 40 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f216 41 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f217 42 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f218 43 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test tb4 f219 44 NULL YES time NULL NULL NULL NULL 0 NULL NULL time select,insert,update,references
+NULL test tb4 f220 45 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references
+NULL test tb4 f221 46 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
+NULL test tb4 f222 47 NULL YES year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb4 f223 48 NULL YES year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb4 f224 49 NULL YES year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb4 f225 50 NULL YES enum 5 5 NULL NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
+NULL test tb4 f226 51 NULL YES set 9 9 NULL NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
+NULL test tb4 f235 52 NULL YES char 0 0 NULL NULL NULL latin1 latin1_swedish_ci char(0) select,insert,update,references
+NULL test tb4 f236 53 NULL YES char 90 90 NULL NULL NULL latin1 latin1_swedish_ci char(90) select,insert,update,references
+NULL test tb4 f237 54 NULL YES char 255 255 NULL NULL NULL latin1 latin1_swedish_ci char(255) select,insert,update,references
+NULL test tb4 f238 55 NULL YES varchar 0 0 NULL NULL NULL latin1 latin1_swedish_ci varchar(0) select,insert,update,references
+NULL test tb4 f239 56 NULL YES varchar 20000 20000 NULL NULL NULL latin1 latin1_bin varchar(20000) select,insert,update,references
+NULL test tb4 f240 57 NULL YES varchar 2000 2000 NULL NULL NULL latin1 latin1_swedish_ci varchar(2000) select,insert,update,references
+NULL test tb4 f241 58 NULL YES char 100 100 NULL NULL NULL latin1 latin1_swedish_ci char(100) select,insert,update,references
+NULL test1 tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test1 tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL 0 NULL NULL time select,insert,update,references
+NULL test1 tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references
+NULL test1 tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp select,insert,update,references
+NULL test1 tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test1 tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test1 tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test1 tb2 f108 50 1enum NO enum 5 5 NULL NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
+NULL test1 tb2 f109 51 1set NO set 9 9 NULL NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
+NULL test1 tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test1 tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test1 tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test1 tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test1 tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test1 tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test1 tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test1 tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test1 tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test1 tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test1 tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test1 tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test1 tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test1 tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test1 tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test1 tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test1 tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test1 tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test1 tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test1 tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test1 tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test4 t6 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test4 t6 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test4 t6 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test4 t6 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test4 t6 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test4 t6 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result
index 2fa72d4bc1b..d210b049eff 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_is.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_is.result
@@ -2,558 +2,562 @@ SELECT * FROM information_schema.columns
WHERE table_schema = 'information_schema'
AND table_name <> 'profiling'
ORDER BY table_schema, table_name, column_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema CHARACTER_SETS DESCRIPTION 3 NO varchar 60 180 NULL NULL utf8 utf8_general_ci varchar(60) select
-NULL information_schema CHARACTER_SETS MAXLEN 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(3) select
-NULL information_schema CLIENT_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL double select
-NULL information_schema CLIENT_STATISTICS BYTES_RECEIVED 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS BYTES_SENT 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS CLIENT 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema CLIENT_STATISTICS COMMIT_TRANSACTIONS 18 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS CONNECTED_TIME 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL double select
-NULL information_schema CLIENT_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS ROWS_INSERTED 13 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS ROWS_READ 10 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS ROWS_SENT 11 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS ROWS_UPDATED 14 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS SELECT_COMMANDS 15 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS 2 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema CLIENT_STATISTICS UPDATE_COMMANDS 16 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema COLLATIONS CHARACTER_SET_NAME 2 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema COLLATIONS COLLATION_NAME 1 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema COLLATIONS ID 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(11) select
-NULL information_schema COLLATIONS IS_COMPILED 5 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema COLLATIONS IS_DEFAULT 4 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema COLLATIONS SORTLEN 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(3) select
-NULL information_schema COLLATION_CHARACTER_SET_APPLICABILITY CHARACTER_SET_NAME 2 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME 1 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema COLUMNS CHARACTER_MAXIMUM_LENGTH 9 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema COLUMNS CHARACTER_OCTET_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema COLUMNS CHARACTER_SET_NAME 13 NULL YES varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema COLUMNS COLLATION_NAME 14 NULL YES varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema COLUMNS COLUMN_COMMENT 19 NO varchar 255 765 NULL NULL utf8 utf8_general_ci varchar(255) select
-NULL information_schema COLUMNS COLUMN_DEFAULT 6 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
-NULL information_schema COLUMNS COLUMN_KEY 16 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema COLUMNS COLUMN_NAME 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema COLUMNS COLUMN_TYPE 15 NULL NO longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
-NULL information_schema COLUMNS DATA_TYPE 8 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema COLUMNS EXTRA 17 NO varchar 27 81 NULL NULL utf8 utf8_general_ci varchar(27) select
-NULL information_schema COLUMNS IS_NULLABLE 7 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema COLUMNS NUMERIC_PRECISION 11 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema COLUMNS NUMERIC_SCALE 12 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema COLUMNS ORDINAL_POSITION 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema COLUMNS PRIVILEGES 18 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
-NULL information_schema COLUMNS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema COLUMNS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema COLUMNS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema COLUMN_PRIVILEGES COLUMN_NAME 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema COLUMN_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81) select
-NULL information_schema COLUMN_PRIVILEGES IS_GRANTABLE 7 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema COLUMN_PRIVILEGES PRIVILEGE_TYPE 6 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema COLUMN_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema COLUMN_PRIVILEGES TABLE_NAME 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema COLUMN_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema ENGINES COMMENT 3 NO varchar 160 480 NULL NULL utf8 utf8_general_ci varchar(160) select
-NULL information_schema ENGINES ENGINE 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema ENGINES SAVEPOINTS 6 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema ENGINES SUPPORT 2 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8) select
-NULL information_schema ENGINES TRANSACTIONS 4 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema ENGINES XA 5 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema EVENTS CHARACTER_SET_CLIENT 22 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema EVENTS COLLATION_CONNECTION 23 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema EVENTS CREATED 17 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema EVENTS DATABASE_COLLATION 24 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema EVENTS DEFINER 4 NO varchar 77 231 NULL NULL utf8 utf8_general_ci varchar(77) select
-NULL information_schema EVENTS ENDS 14 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema EVENTS EVENT_BODY 6 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8) select
-NULL information_schema EVENTS EVENT_CATALOG 1 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema EVENTS EVENT_COMMENT 20 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema EVENTS EVENT_DEFINITION 7 NULL NO longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
-NULL information_schema EVENTS EVENT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema EVENTS EVENT_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema EVENTS EVENT_TYPE 8 NO varchar 9 27 NULL NULL utf8 utf8_general_ci varchar(9) select
-NULL information_schema EVENTS EXECUTE_AT 9 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema EVENTS INTERVAL_FIELD 11 NULL YES varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18) select
-NULL information_schema EVENTS INTERVAL_VALUE 10 NULL YES varchar 256 768 NULL NULL utf8 utf8_general_ci varchar(256) select
-NULL information_schema EVENTS LAST_ALTERED 18 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema EVENTS LAST_EXECUTED 19 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema EVENTS ON_COMPLETION 16 NO varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select
-NULL information_schema EVENTS ORIGINATOR 21 0 NO bigint NULL NULL 19 0 NULL NULL bigint(10) select
-NULL information_schema EVENTS SQL_MODE 12 NO varchar 8192 24576 NULL NULL utf8 utf8_general_ci varchar(8192) select
-NULL information_schema EVENTS STARTS 13 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema EVENTS STATUS 15 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18) select
-NULL information_schema EVENTS TIME_ZONE 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema FILES AUTOEXTEND_SIZE 19 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES AVG_ROW_LENGTH 28 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES CHECKSUM 36 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES CHECK_TIME 35 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema FILES CREATE_TIME 33 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema FILES CREATION_TIME 20 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema FILES DATA_FREE 32 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES DATA_LENGTH 29 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES DELETED_ROWS 12 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
-NULL information_schema FILES ENGINE 10 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema FILES EXTENT_SIZE 16 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4) select
-NULL information_schema FILES EXTRA 38 NULL YES varchar 255 765 NULL NULL utf8 utf8_general_ci varchar(255) select
-NULL information_schema FILES FILE_ID 1 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4) select
-NULL information_schema FILES FILE_NAME 2 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema FILES FILE_TYPE 3 NO varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20) select
-NULL information_schema FILES FREE_EXTENTS 14 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
-NULL information_schema FILES FULLTEXT_KEYS 11 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema FILES INDEX_LENGTH 31 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES INITIAL_SIZE 17 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES LAST_ACCESS_TIME 22 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema FILES LAST_UPDATE_TIME 21 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema FILES LOGFILE_GROUP_NAME 8 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema FILES LOGFILE_GROUP_NUMBER 9 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
-NULL information_schema FILES MAXIMUM_SIZE 18 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES MAX_DATA_LENGTH 30 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES RECOVER_TIME 23 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
-NULL information_schema FILES ROW_FORMAT 26 NULL YES varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10) select
-NULL information_schema FILES STATUS 37 NO varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20) select
-NULL information_schema FILES TABLESPACE_NAME 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema FILES TABLE_CATALOG 5 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema FILES TABLE_NAME 7 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema FILES TABLE_ROWS 27 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES TABLE_SCHEMA 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema FILES TOTAL_EXTENTS 15 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
-NULL information_schema FILES TRANSACTION_COUNTER 24 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
-NULL information_schema FILES UPDATE_COUNT 13 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
-NULL information_schema FILES UPDATE_TIME 34 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema FILES VERSION 25 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema GLOBAL_STATUS VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema GLOBAL_STATUS VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
-NULL information_schema GLOBAL_VARIABLES VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema GLOBAL_VARIABLES VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
-NULL information_schema INDEX_STATISTICS INDEX_NAME 3 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INDEX_STATISTICS ROWS_READ 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema INDEX_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INDEX_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_BUFFER_PAGE ACCESS_TIME 10 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE BLOCK_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE COMPRESSED_SIZE 15 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE DATA_SIZE 14 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE FIX_COUNT 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE FLUSH_TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE FREE_PAGE_CLOCK 19 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE INDEX_NAME 12 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
-NULL information_schema INNODB_BUFFER_PAGE IO_FIX 17 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema INNODB_BUFFER_PAGE IS_HASHED 7 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema INNODB_BUFFER_PAGE IS_OLD 18 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema INNODB_BUFFER_PAGE NEWEST_MODIFICATION 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE NUMBER_RECORDS 13 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE OLDEST_MODIFICATION 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE PAGE_NUMBER 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE PAGE_STATE 16 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema INNODB_BUFFER_PAGE PAGE_TYPE 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema INNODB_BUFFER_PAGE SPACE 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE TABLE_NAME 11 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
-NULL information_schema INNODB_BUFFER_PAGE_LRU ACCESS_TIME 10 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE_LRU COMPRESSED 16 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema INNODB_BUFFER_PAGE_LRU COMPRESSED_SIZE 15 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE_LRU DATA_SIZE 14 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE_LRU FIX_COUNT 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE_LRU FLUSH_TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE_LRU FREE_PAGE_CLOCK 19 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE_LRU INDEX_NAME 12 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
-NULL information_schema INNODB_BUFFER_PAGE_LRU IO_FIX 17 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema INNODB_BUFFER_PAGE_LRU IS_HASHED 7 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema INNODB_BUFFER_PAGE_LRU IS_OLD 18 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema INNODB_BUFFER_PAGE_LRU LRU_POSITION 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE_LRU NEWEST_MODIFICATION 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE_LRU NUMBER_RECORDS 13 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE_LRU OLDEST_MODIFICATION 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE_LRU PAGE_NUMBER 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE_LRU PAGE_TYPE 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema INNODB_BUFFER_PAGE_LRU SPACE 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_PAGE_LRU TABLE_NAME 11 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
-NULL information_schema INNODB_BUFFER_POOL_PAGES fix_count 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES flush_type 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES lru_position 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES page_no 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES page_type 1 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema INNODB_BUFFER_POOL_PAGES space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB compressed 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB fix_count 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB flush_type 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB lru_position 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB next_page_no 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB page_no 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB part_len 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB space_id 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX access_time 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX data_size 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX dirty 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX fix_count 12 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX flush_type 13 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX hashed 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX index_id 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX lru_position 11 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX modified 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX n_recs 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX old 10 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX page_no 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS DATABASE_PAGES 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS FREE_BUFFERS 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS HIT_RATE 21 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS LRU_IO_CURRENT 29 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS LRU_IO_TOTAL 28 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS MODIFIED_DATABASE_PAGES 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS NOT_YOUNG_MAKE_PER_THOUSAND_GETS 23 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_CREATED 15 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_GET 20 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_READ 14 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_READ_AHEAD 24 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_WRITTEN 16 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_READ_AHEAD_EVICTED 25 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS OLD_DATABASE_PAGES 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_CREATE_RATE 18 0 NO double NULL NULL 12 NULL NULL NULL double select
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_MADE_NOT_YOUNG_RATE 13 0 NO double NULL NULL 12 NULL NULL NULL double select
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_MADE_YOUNG 10 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_MADE_YOUNG_RATE 12 0 NO double NULL NULL 12 NULL NULL NULL double select
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_NOT_MADE_YOUNG 11 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_READ_RATE 17 0 NO double NULL NULL 12 NULL NULL NULL double select
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_WRITTEN_RATE 19 0 NO double NULL NULL 12 NULL NULL NULL double select
-NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_DECOMPRESS 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_FLUSH_LIST 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_FLUSH_LRU 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_READS 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS POOL_SIZE 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS READ_AHEAD_EVICTED_RATE 27 0 NO double NULL NULL 12 NULL NULL NULL double select
-NULL information_schema INNODB_BUFFER_POOL_STATS READ_AHEAD_RATE 26 0 NO double NULL NULL 12 NULL NULL NULL double select
-NULL information_schema INNODB_BUFFER_POOL_STATS UNCOMPRESS_CURRENT 31 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS UNCOMPRESS_TOTAL 30 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_STATS YOUNG_MAKE_PER_THOUSAND_GETS 22 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_CHANGED_PAGES end_lsn 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_CHANGED_PAGES page_id 2 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select
-NULL information_schema INNODB_CHANGED_PAGES space_id 1 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select
-NULL information_schema INNODB_CHANGED_PAGES start_lsn 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_CMP compress_ops 2 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMP compress_ops_ok 3 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMP compress_time 4 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMP page_size 1 0 NO int NULL NULL 10 0 NULL NULL int(5) select
-NULL information_schema INNODB_CMP uncompress_ops 5 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMP uncompress_time 6 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMPMEM pages_free 3 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMPMEM pages_used 2 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMPMEM page_size 1 0 NO int NULL NULL 10 0 NULL NULL int(5) select
-NULL information_schema INNODB_CMPMEM relocation_ops 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema INNODB_CMPMEM relocation_time 5 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMPMEM_RESET pages_free 3 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMPMEM_RESET pages_used 2 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMPMEM_RESET page_size 1 0 NO int NULL NULL 10 0 NULL NULL int(5) select
-NULL information_schema INNODB_CMPMEM_RESET relocation_ops 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema INNODB_CMPMEM_RESET relocation_time 5 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMP_RESET compress_ops 2 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMP_RESET compress_ops_ok 3 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMP_RESET compress_time 4 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMP_RESET page_size 1 0 NO int NULL NULL 10 0 NULL NULL int(5) select
-NULL information_schema INNODB_CMP_RESET uncompress_ops 5 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_CMP_RESET uncompress_time 6 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_INDEX_STATS fields 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_INDEX_STATS index_name 3 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_INDEX_STATS index_size 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_INDEX_STATS leaf_pages 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_INDEX_STATS row_per_keys 5 NO varchar 256 768 NULL NULL utf8 utf8_general_ci varchar(256) select
-NULL information_schema INNODB_INDEX_STATS table_name 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_INDEX_STATS table_schema 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_LOCKS lock_data 10 NULL YES varchar 8192 24576 NULL NULL utf8 utf8_general_ci varchar(8192) select
-NULL information_schema INNODB_LOCKS lock_id 1 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81) select
-NULL information_schema INNODB_LOCKS lock_index 6 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
-NULL information_schema INNODB_LOCKS lock_mode 3 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema INNODB_LOCKS lock_page 8 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_LOCKS lock_rec 9 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_LOCKS lock_space 7 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_LOCKS lock_table 5 NO varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
-NULL information_schema INNODB_LOCKS lock_trx_id 2 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18) select
-NULL information_schema INNODB_LOCKS lock_type 4 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema INNODB_LOCK_WAITS blocking_lock_id 4 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81) select
-NULL information_schema INNODB_LOCK_WAITS blocking_trx_id 3 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18) select
-NULL information_schema INNODB_LOCK_WAITS requested_lock_id 2 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81) select
-NULL information_schema INNODB_LOCK_WAITS requesting_trx_id 1 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18) select
-NULL information_schema INNODB_RSEG curr_size 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_RSEG max_size 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_RSEG page_no 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_RSEG rseg_id 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_RSEG space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_RSEG zip_size 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_INDEXES ID 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_INDEXES NAME 3 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_SYS_INDEXES N_FIELDS 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_INDEXES PAGE_NO 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_INDEXES SPACE 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_INDEXES TABLE_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_INDEXES TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_STATS DIFF_VALS 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_STATS INDEX_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_STATS KEY_COLS 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_STATS NON_NULL_VALS 4 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_TABLES CLUSTER_NAME 8 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_SYS_TABLES ID 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_TABLES MIX_ID 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_TABLES MIX_LEN 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_TABLES NAME 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_SYS_TABLES N_COLS 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_TABLES SCHEMA 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_SYS_TABLES SPACE 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_TABLES TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_TABLE_STATS clust_size 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_TABLE_STATS modified 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_TABLE_STATS other_size 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_TABLE_STATS rows 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_TABLE_STATS table_name 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_TABLE_STATS table_schema 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_TRX trx_id 1 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18) select
-NULL information_schema INNODB_TRX trx_mysql_thread_id 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_TRX trx_query 8 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
-NULL information_schema INNODB_TRX trx_requested_lock_id 4 NULL YES varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81) select
-NULL information_schema INNODB_TRX trx_started 3 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema INNODB_TRX trx_state 2 NO varchar 13 39 NULL NULL utf8 utf8_general_ci varchar(13) select
-NULL information_schema INNODB_TRX trx_wait_started 5 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema INNODB_TRX trx_weight 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema KEY_CACHES BLOCK_SIZE 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema KEY_CACHES DIRTY_BLOCKS 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema KEY_CACHES FULL_SIZE 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema KEY_CACHES KEY_CACHE_NAME 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema KEY_CACHES READS 10 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema KEY_CACHES READ_REQUESTS 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema KEY_CACHES SEGMENTS 2 NULL YES int NULL NULL 10 0 NULL NULL int(3) unsigned select
-NULL information_schema KEY_CACHES SEGMENT_NUMBER 3 NULL YES int NULL NULL 10 0 NULL NULL int(3) unsigned select
-NULL information_schema KEY_CACHES UNUSED_BLOCKS 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema KEY_CACHES USED_BLOCKS 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema KEY_CACHES WRITES 12 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema KEY_CACHES WRITE_REQUESTS 11 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema KEY_COLUMN_USAGE COLUMN_NAME 7 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema KEY_COLUMN_USAGE ORDINAL_POSITION 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(10) select
-NULL information_schema KEY_COLUMN_USAGE POSITION_IN_UNIQUE_CONSTRAINT 9 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(10) select
-NULL information_schema KEY_COLUMN_USAGE REFERENCED_COLUMN_NAME 12 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_NAME 11 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_SCHEMA 10 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema KEY_COLUMN_USAGE TABLE_CATALOG 4 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema KEY_COLUMN_USAGE TABLE_NAME 6 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema KEY_COLUMN_USAGE TABLE_SCHEMA 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PARTITIONS AVG_ROW_LENGTH 14 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema PARTITIONS CHECKSUM 22 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema PARTITIONS CHECK_TIME 21 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema PARTITIONS CREATE_TIME 19 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema PARTITIONS DATA_FREE 18 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema PARTITIONS DATA_LENGTH 15 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema PARTITIONS INDEX_LENGTH 17 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema PARTITIONS MAX_DATA_LENGTH 16 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema PARTITIONS NODEGROUP 24 NO varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select
-NULL information_schema PARTITIONS PARTITION_COMMENT 23 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
-NULL information_schema PARTITIONS PARTITION_DESCRIPTION 12 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
-NULL information_schema PARTITIONS PARTITION_EXPRESSION 10 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
-NULL information_schema PARTITIONS PARTITION_METHOD 8 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select
-NULL information_schema PARTITIONS PARTITION_NAME 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PARTITIONS PARTITION_ORDINAL_POSITION 6 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema PARTITIONS SUBPARTITION_EXPRESSION 11 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
-NULL information_schema PARTITIONS SUBPARTITION_METHOD 9 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select
-NULL information_schema PARTITIONS SUBPARTITION_NAME 5 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PARTITIONS SUBPARTITION_ORDINAL_POSITION 7 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema PARTITIONS TABLESPACE_NAME 25 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PARTITIONS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema PARTITIONS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PARTITIONS TABLE_ROWS 13 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema PARTITIONS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PARTITIONS UPDATE_TIME 20 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PLUGINS PLUGIN_AUTH_VERSION 12 NULL YES varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
-NULL information_schema PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
-NULL information_schema PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20) select
-NULL information_schema PLUGINS PLUGIN_LICENSE 10 NULL YES varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
-NULL information_schema PLUGINS PLUGIN_MATURITY 11 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select
-NULL information_schema PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10) select
-NULL information_schema PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
-NULL information_schema PLUGINS PLUGIN_TYPE_VERSION 5 NO varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20) select
-NULL information_schema PLUGINS PLUGIN_VERSION 2 NO varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20) select
-NULL information_schema PROCESSLIST COMMAND 5 NO varchar 16 48 NULL NULL utf8 utf8_general_ci varchar(16) select
-NULL information_schema PROCESSLIST DB 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PROCESSLIST HOST 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PROCESSLIST ID 1 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4) select
-NULL information_schema PROCESSLIST INFO 8 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
-NULL information_schema PROCESSLIST STATE 7 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PROCESSLIST TIME 6 0 NO int NULL NULL 10 0 NULL NULL int(7) select
-NULL information_schema PROCESSLIST TIME_MS 9 0.000 NO decimal NULL NULL 22 3 NULL NULL decimal(22,3) select
-NULL information_schema PROCESSLIST USER 2 NO varchar 16 48 NULL NULL utf8 utf8_general_ci varchar(16) select
-NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema REFERENTIAL_CONSTRAINTS DELETE_RULE 9 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema REFERENTIAL_CONSTRAINTS MATCH_OPTION 7 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema REFERENTIAL_CONSTRAINTS REFERENCED_TABLE_NAME 11 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema REFERENTIAL_CONSTRAINTS TABLE_NAME 10 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_CATALOG 4 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_NAME 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_SCHEMA 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema REFERENTIAL_CONSTRAINTS UPDATE_RULE 8 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema ROUTINES CHARACTER_SET_CLIENT 21 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema ROUTINES COLLATION_CONNECTION 22 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema ROUTINES CREATED 16 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema ROUTINES DATABASE_COLLATION 23 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema ROUTINES DEFINER 20 NO varchar 77 231 NULL NULL utf8 utf8_general_ci varchar(77) select
-NULL information_schema ROUTINES DTD_IDENTIFIER 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema ROUTINES EXTERNAL_LANGUAGE 10 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema ROUTINES EXTERNAL_NAME 9 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema ROUTINES IS_DETERMINISTIC 12 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema ROUTINES LAST_ALTERED 17 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema ROUTINES PARAMETER_STYLE 11 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8) select
-NULL information_schema ROUTINES ROUTINE_BODY 7 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8) select
-NULL information_schema ROUTINES ROUTINE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema ROUTINES ROUTINE_COMMENT 19 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema ROUTINES ROUTINE_DEFINITION 8 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
-NULL information_schema ROUTINES ROUTINE_NAME 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema ROUTINES ROUTINE_SCHEMA 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema ROUTINES ROUTINE_TYPE 5 NO varchar 9 27 NULL NULL utf8 utf8_general_ci varchar(9) select
-NULL information_schema ROUTINES SECURITY_TYPE 15 NO varchar 7 21 NULL NULL utf8 utf8_general_ci varchar(7) select
-NULL information_schema ROUTINES SPECIFIC_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema ROUTINES SQL_DATA_ACCESS 13 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema ROUTINES SQL_MODE 18 NO varchar 8192 24576 NULL NULL utf8 utf8_general_ci varchar(8192) select
-NULL information_schema ROUTINES SQL_PATH 14 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema SCHEMATA CATALOG_NAME 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema SCHEMATA DEFAULT_CHARACTER_SET_NAME 3 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema SCHEMATA DEFAULT_COLLATION_NAME 4 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema SCHEMATA SCHEMA_NAME 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema SCHEMATA SQL_PATH 5 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema SCHEMA_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81) select
-NULL information_schema SCHEMA_PRIVILEGES IS_GRANTABLE 5 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema SCHEMA_PRIVILEGES PRIVILEGE_TYPE 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema SCHEMA_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema SCHEMA_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema SESSION_STATUS VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema SESSION_STATUS VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
-NULL information_schema SESSION_VARIABLES VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema SESSION_VARIABLES VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
-NULL information_schema STATISTICS CARDINALITY 10 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema STATISTICS COLLATION 9 NULL YES varchar 1 3 NULL NULL utf8 utf8_general_ci varchar(1) select
-NULL information_schema STATISTICS COLUMN_NAME 8 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema STATISTICS COMMENT 15 NULL YES varchar 16 48 NULL NULL utf8 utf8_general_ci varchar(16) select
-NULL information_schema STATISTICS INDEX_NAME 6 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema STATISTICS INDEX_SCHEMA 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema STATISTICS INDEX_TYPE 14 NO varchar 16 48 NULL NULL utf8 utf8_general_ci varchar(16) select
-NULL information_schema STATISTICS NON_UNIQUE 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(1) select
-NULL information_schema STATISTICS NULLABLE 13 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema STATISTICS PACKED 12 NULL YES varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10) select
-NULL information_schema STATISTICS SEQ_IN_INDEX 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(2) select
-NULL information_schema STATISTICS SUB_PART 11 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(3) select
-NULL information_schema STATISTICS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema STATISTICS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema STATISTICS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLES AUTO_INCREMENT 14 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema TABLES AVG_ROW_LENGTH 9 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema TABLES CHECKSUM 19 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema TABLES CHECK_TIME 17 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema TABLES CREATE_OPTIONS 20 NULL YES varchar 255 765 NULL NULL utf8 utf8_general_ci varchar(255) select
-NULL information_schema TABLES CREATE_TIME 15 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema TABLES DATA_FREE 13 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema TABLES DATA_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema TABLES ENGINE 5 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLES INDEX_LENGTH 12 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema TABLES MAX_DATA_LENGTH 11 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema TABLES ROW_FORMAT 7 NULL YES varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10) select
-NULL information_schema TABLES TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema TABLES TABLE_COLLATION 18 NULL YES varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema TABLES TABLE_COMMENT 21 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
-NULL information_schema TABLES TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLES TABLE_ROWS 8 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema TABLES TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLES TABLE_TYPE 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLES UPDATE_TIME 16 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema TABLES VERSION 6 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
-NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_TYPE 6 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLE_CONSTRAINTS TABLE_NAME 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLE_CONSTRAINTS TABLE_SCHEMA 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLE_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81) select
-NULL information_schema TABLE_PRIVILEGES IS_GRANTABLE 6 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema TABLE_PRIVILEGES PRIVILEGE_TYPE 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLE_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema TABLE_PRIVILEGES TABLE_NAME 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLE_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLE_STATISTICS ROWS_CHANGED 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema TABLE_STATISTICS ROWS_CHANGED_X_INDEXES 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema TABLE_STATISTICS ROWS_READ 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema TABLE_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema TABLE_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema TRIGGERS ACTION_CONDITION 9 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
-NULL information_schema TRIGGERS ACTION_ORDER 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4) select
-NULL information_schema TRIGGERS ACTION_ORIENTATION 11 NO varchar 9 27 NULL NULL utf8 utf8_general_ci varchar(9) select
-NULL information_schema TRIGGERS ACTION_REFERENCE_NEW_ROW 16 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema TRIGGERS ACTION_REFERENCE_NEW_TABLE 14 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TRIGGERS ACTION_REFERENCE_OLD_ROW 15 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema TRIGGERS ACTION_REFERENCE_OLD_TABLE 13 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TRIGGERS ACTION_STATEMENT 10 NULL NO longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
-NULL information_schema TRIGGERS ACTION_TIMING 12 NO varchar 6 18 NULL NULL utf8 utf8_general_ci varchar(6) select
-NULL information_schema TRIGGERS CHARACTER_SET_CLIENT 20 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema TRIGGERS COLLATION_CONNECTION 21 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema TRIGGERS CREATED 17 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema TRIGGERS DATABASE_COLLATION 22 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema TRIGGERS DEFINER 19 NO varchar 77 231 NULL NULL utf8 utf8_general_ci varchar(77) select
-NULL information_schema TRIGGERS EVENT_MANIPULATION 4 NO varchar 6 18 NULL NULL utf8 utf8_general_ci varchar(6) select
-NULL information_schema TRIGGERS EVENT_OBJECT_CATALOG 5 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema TRIGGERS EVENT_OBJECT_SCHEMA 6 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TRIGGERS EVENT_OBJECT_TABLE 7 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TRIGGERS SQL_MODE 18 NO varchar 8192 24576 NULL NULL utf8 utf8_general_ci varchar(8192) select
-NULL information_schema TRIGGERS TRIGGER_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema TRIGGERS TRIGGER_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TRIGGERS TRIGGER_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema USER_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81) select
-NULL information_schema USER_PRIVILEGES IS_GRANTABLE 4 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema USER_PRIVILEGES PRIVILEGE_TYPE 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema USER_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema USER_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL double select
-NULL information_schema USER_STATISTICS BYTES_RECEIVED 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS BYTES_SENT 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS COMMIT_TRANSACTIONS 18 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema USER_STATISTICS CONNECTED_TIME 4 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema USER_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL double select
-NULL information_schema USER_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS ROWS_INSERTED 13 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS ROWS_READ 10 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS ROWS_SENT 11 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS ROWS_UPDATED 14 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS SELECT_COMMANDS 15 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS TOTAL_CONNECTIONS 2 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema USER_STATISTICS UPDATE_COMMANDS 16 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
-NULL information_schema USER_STATISTICS USER 1 NO varchar 48 144 NULL NULL utf8 utf8_general_ci varchar(48) select
-NULL information_schema VIEWS CHARACTER_SET_CLIENT 9 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema VIEWS CHECK_OPTION 5 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8) select
-NULL information_schema VIEWS COLLATION_CONNECTION 10 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema VIEWS DEFINER 7 NO varchar 77 231 NULL NULL utf8 utf8_general_ci varchar(77) select
-NULL information_schema VIEWS IS_UPDATABLE 6 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema VIEWS SECURITY_TYPE 8 NO varchar 7 21 NULL NULL utf8 utf8_general_ci varchar(7) select
-NULL information_schema VIEWS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
-NULL information_schema VIEWS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema VIEWS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema VIEWS VIEW_DEFINITION 4 NULL NO longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
-NULL information_schema XTRADB_ADMIN_COMMAND result_message 1 NO varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema CHARACTER_SETS DESCRIPTION 3 NO varchar 60 180 NULL NULL NULL utf8 utf8_general_ci varchar(60) select
+NULL information_schema CHARACTER_SETS MAXLEN 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(3) select
+NULL information_schema CLIENT_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL NULL double select
+NULL information_schema CLIENT_STATISTICS BYTES_RECEIVED 7 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS BYTES_SENT 8 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS CLIENT 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema CLIENT_STATISTICS COMMIT_TRANSACTIONS 18 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS CONNECTED_TIME 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL NULL double select
+NULL information_schema CLIENT_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS ROWS_INSERTED 13 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS ROWS_READ 10 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS ROWS_SENT 11 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS ROWS_UPDATED 14 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS SELECT_COMMANDS 15 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS 2 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema CLIENT_STATISTICS UPDATE_COMMANDS 16 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema COLLATIONS CHARACTER_SET_NAME 2 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema COLLATIONS COLLATION_NAME 1 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema COLLATIONS ID 3 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(11) select
+NULL information_schema COLLATIONS IS_COMPILED 5 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema COLLATIONS IS_DEFAULT 4 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema COLLATIONS SORTLEN 6 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(3) select
+NULL information_schema COLLATION_CHARACTER_SET_APPLICABILITY CHARACTER_SET_NAME 2 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME 1 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema COLUMNS CHARACTER_MAXIMUM_LENGTH 9 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema COLUMNS CHARACTER_OCTET_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema COLUMNS CHARACTER_SET_NAME 14 NULL YES varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema COLUMNS COLLATION_NAME 15 NULL YES varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema COLUMNS COLUMN_COMMENT 20 NO varchar 255 765 NULL NULL NULL utf8 utf8_general_ci varchar(255) select
+NULL information_schema COLUMNS COLUMN_DEFAULT 6 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema COLUMNS COLUMN_KEY 17 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema COLUMNS COLUMN_NAME 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema COLUMNS COLUMN_TYPE 16 NULL NO longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema COLUMNS DATA_TYPE 8 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema COLUMNS DATETIME_PRECISION 13 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema COLUMNS EXTRA 18 NO varchar 27 81 NULL NULL NULL utf8 utf8_general_ci varchar(27) select
+NULL information_schema COLUMNS IS_NULLABLE 7 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema COLUMNS NUMERIC_PRECISION 11 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema COLUMNS NUMERIC_SCALE 12 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema COLUMNS ORDINAL_POSITION 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema COLUMNS PRIVILEGES 19 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select
+NULL information_schema COLUMNS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema COLUMNS TABLE_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema COLUMNS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema COLUMN_PRIVILEGES COLUMN_NAME 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema COLUMN_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81) select
+NULL information_schema COLUMN_PRIVILEGES IS_GRANTABLE 7 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema COLUMN_PRIVILEGES PRIVILEGE_TYPE 6 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema COLUMN_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema COLUMN_PRIVILEGES TABLE_NAME 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema COLUMN_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema ENGINES COMMENT 3 NO varchar 160 480 NULL NULL NULL utf8 utf8_general_ci varchar(160) select
+NULL information_schema ENGINES ENGINE 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema ENGINES SAVEPOINTS 6 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema ENGINES SUPPORT 2 NO varchar 8 24 NULL NULL NULL utf8 utf8_general_ci varchar(8) select
+NULL information_schema ENGINES TRANSACTIONS 4 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema ENGINES XA 5 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema EVENTS CHARACTER_SET_CLIENT 22 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema EVENTS COLLATION_CONNECTION 23 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema EVENTS CREATED 17 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema EVENTS DATABASE_COLLATION 24 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema EVENTS DEFINER 4 NO varchar 77 231 NULL NULL NULL utf8 utf8_general_ci varchar(77) select
+NULL information_schema EVENTS ENDS 14 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema EVENTS EVENT_BODY 6 NO varchar 8 24 NULL NULL NULL utf8 utf8_general_ci varchar(8) select
+NULL information_schema EVENTS EVENT_CATALOG 1 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema EVENTS EVENT_COMMENT 20 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema EVENTS EVENT_DEFINITION 7 NULL NO longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema EVENTS EVENT_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema EVENTS EVENT_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema EVENTS EVENT_TYPE 8 NO varchar 9 27 NULL NULL NULL utf8 utf8_general_ci varchar(9) select
+NULL information_schema EVENTS EXECUTE_AT 9 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema EVENTS INTERVAL_FIELD 11 NULL YES varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18) select
+NULL information_schema EVENTS INTERVAL_VALUE 10 NULL YES varchar 256 768 NULL NULL NULL utf8 utf8_general_ci varchar(256) select
+NULL information_schema EVENTS LAST_ALTERED 18 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema EVENTS LAST_EXECUTED 19 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema EVENTS ON_COMPLETION 16 NO varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12) select
+NULL information_schema EVENTS ORIGINATOR 21 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(10) select
+NULL information_schema EVENTS SQL_MODE 12 NO varchar 8192 24576 NULL NULL NULL utf8 utf8_general_ci varchar(8192) select
+NULL information_schema EVENTS STARTS 13 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema EVENTS STATUS 15 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18) select
+NULL information_schema EVENTS TIME_ZONE 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema FILES AUTOEXTEND_SIZE 19 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema FILES AVG_ROW_LENGTH 28 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema FILES CHECKSUM 36 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema FILES CHECK_TIME 35 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema FILES CREATE_TIME 33 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema FILES CREATION_TIME 20 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema FILES DATA_FREE 32 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema FILES DATA_LENGTH 29 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema FILES DELETED_ROWS 12 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select
+NULL information_schema FILES ENGINE 10 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema FILES EXTENT_SIZE 16 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select
+NULL information_schema FILES EXTRA 38 NULL YES varchar 255 765 NULL NULL NULL utf8 utf8_general_ci varchar(255) select
+NULL information_schema FILES FILE_ID 1 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select
+NULL information_schema FILES FILE_NAME 2 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema FILES FILE_TYPE 3 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select
+NULL information_schema FILES FREE_EXTENTS 14 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select
+NULL information_schema FILES FULLTEXT_KEYS 11 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema FILES INDEX_LENGTH 31 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema FILES INITIAL_SIZE 17 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema FILES LAST_ACCESS_TIME 22 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema FILES LAST_UPDATE_TIME 21 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema FILES LOGFILE_GROUP_NAME 8 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema FILES LOGFILE_GROUP_NUMBER 9 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select
+NULL information_schema FILES MAXIMUM_SIZE 18 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema FILES MAX_DATA_LENGTH 30 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema FILES RECOVER_TIME 23 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select
+NULL information_schema FILES ROW_FORMAT 26 NULL YES varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10) select
+NULL information_schema FILES STATUS 37 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select
+NULL information_schema FILES TABLESPACE_NAME 4 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema FILES TABLE_CATALOG 5 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema FILES TABLE_NAME 7 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema FILES TABLE_ROWS 27 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema FILES TABLE_SCHEMA 6 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema FILES TOTAL_EXTENTS 15 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select
+NULL information_schema FILES TRANSACTION_COUNTER 24 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select
+NULL information_schema FILES UPDATE_COUNT 13 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select
+NULL information_schema FILES UPDATE_TIME 34 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema FILES VERSION 25 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema GLOBAL_STATUS VARIABLE_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema GLOBAL_STATUS VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024) select
+NULL information_schema GLOBAL_VARIABLES VARIABLE_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema GLOBAL_VARIABLES VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024) select
+NULL information_schema INDEX_STATISTICS INDEX_NAME 3 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema INDEX_STATISTICS ROWS_READ 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema INDEX_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema INDEX_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema INNODB_BUFFER_PAGE ACCESS_TIME 10 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE BLOCK_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE COMPRESSED_SIZE 15 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE DATA_SIZE 14 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE FIX_COUNT 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE FLUSH_TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE FREE_PAGE_CLOCK 19 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE INDEX_NAME 12 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024) select
+NULL information_schema INNODB_BUFFER_PAGE IO_FIX 17 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema INNODB_BUFFER_PAGE IS_HASHED 7 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema INNODB_BUFFER_PAGE IS_OLD 18 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema INNODB_BUFFER_PAGE NEWEST_MODIFICATION 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE NUMBER_RECORDS 13 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE OLDEST_MODIFICATION 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE PAGE_NUMBER 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE PAGE_STATE 16 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema INNODB_BUFFER_PAGE PAGE_TYPE 4 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema INNODB_BUFFER_PAGE SPACE 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE TABLE_NAME 11 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024) select
+NULL information_schema INNODB_BUFFER_PAGE_LRU ACCESS_TIME 10 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE_LRU COMPRESSED 16 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema INNODB_BUFFER_PAGE_LRU COMPRESSED_SIZE 15 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE_LRU DATA_SIZE 14 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE_LRU FIX_COUNT 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE_LRU FLUSH_TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE_LRU FREE_PAGE_CLOCK 19 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE_LRU INDEX_NAME 12 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024) select
+NULL information_schema INNODB_BUFFER_PAGE_LRU IO_FIX 17 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema INNODB_BUFFER_PAGE_LRU IS_HASHED 7 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema INNODB_BUFFER_PAGE_LRU IS_OLD 18 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema INNODB_BUFFER_PAGE_LRU LRU_POSITION 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE_LRU NEWEST_MODIFICATION 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE_LRU NUMBER_RECORDS 13 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE_LRU OLDEST_MODIFICATION 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE_LRU PAGE_NUMBER 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE_LRU PAGE_TYPE 4 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema INNODB_BUFFER_PAGE_LRU SPACE 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_PAGE_LRU TABLE_NAME 11 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024) select
+NULL information_schema INNODB_BUFFER_POOL_PAGES fix_count 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES flush_type 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES lru_position 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES page_no 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES page_type 1 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema INNODB_BUFFER_POOL_PAGES space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB compressed 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB fix_count 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB flush_type 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB lru_position 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB next_page_no 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB page_no 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB part_len 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB space_id 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX access_time 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX data_size 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX dirty 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX fix_count 12 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX flush_type 13 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX hashed 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX index_id 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX lru_position 11 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX modified 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX n_recs 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX old 10 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX page_no 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS DATABASE_PAGES 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS FREE_BUFFERS 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS HIT_RATE 21 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS LRU_IO_CURRENT 29 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS LRU_IO_TOTAL 28 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS MODIFIED_DATABASE_PAGES 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS NOT_YOUNG_MAKE_PER_THOUSAND_GETS 23 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_CREATED 15 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_GET 20 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_READ 14 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_READ_AHEAD 24 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_WRITTEN 16 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_READ_AHEAD_EVICTED 25 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS OLD_DATABASE_PAGES 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_CREATE_RATE 18 0 NO double NULL NULL 12 NULL NULL NULL NULL double select
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_MADE_NOT_YOUNG_RATE 13 0 NO double NULL NULL 12 NULL NULL NULL NULL double select
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_MADE_YOUNG 10 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_MADE_YOUNG_RATE 12 0 NO double NULL NULL 12 NULL NULL NULL NULL double select
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_NOT_MADE_YOUNG 11 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_READ_RATE 17 0 NO double NULL NULL 12 NULL NULL NULL NULL double select
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_WRITTEN_RATE 19 0 NO double NULL NULL 12 NULL NULL NULL NULL double select
+NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_DECOMPRESS 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_FLUSH_LIST 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_FLUSH_LRU 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_READS 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS POOL_SIZE 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS READ_AHEAD_EVICTED_RATE 27 0 NO double NULL NULL 12 NULL NULL NULL NULL double select
+NULL information_schema INNODB_BUFFER_POOL_STATS READ_AHEAD_RATE 26 0 NO double NULL NULL 12 NULL NULL NULL NULL double select
+NULL information_schema INNODB_BUFFER_POOL_STATS UNCOMPRESS_CURRENT 31 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS UNCOMPRESS_TOTAL 30 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_STATS YOUNG_MAKE_PER_THOUSAND_GETS 22 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_CHANGED_PAGES end_lsn 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_CHANGED_PAGES page_id 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select
+NULL information_schema INNODB_CHANGED_PAGES space_id 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select
+NULL information_schema INNODB_CHANGED_PAGES start_lsn 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_CMP compress_ops 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMP compress_ops_ok 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMP compress_time 4 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMP page_size 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(5) select
+NULL information_schema INNODB_CMP uncompress_ops 5 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMP uncompress_time 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMPMEM pages_free 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMPMEM pages_used 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMPMEM page_size 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(5) select
+NULL information_schema INNODB_CMPMEM relocation_ops 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema INNODB_CMPMEM relocation_time 5 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMPMEM_RESET pages_free 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMPMEM_RESET pages_used 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMPMEM_RESET page_size 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(5) select
+NULL information_schema INNODB_CMPMEM_RESET relocation_ops 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema INNODB_CMPMEM_RESET relocation_time 5 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMP_RESET compress_ops 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMP_RESET compress_ops_ok 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMP_RESET compress_time 4 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMP_RESET page_size 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(5) select
+NULL information_schema INNODB_CMP_RESET uncompress_ops 5 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_CMP_RESET uncompress_time 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema INNODB_INDEX_STATS fields 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_INDEX_STATS index_name 3 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema INNODB_INDEX_STATS index_size 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_INDEX_STATS leaf_pages 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_INDEX_STATS row_per_keys 5 NO varchar 256 768 NULL NULL NULL utf8 utf8_general_ci varchar(256) select
+NULL information_schema INNODB_INDEX_STATS table_name 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema INNODB_INDEX_STATS table_schema 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema INNODB_LOCKS lock_data 10 NULL YES varchar 8192 24576 NULL NULL NULL utf8 utf8_general_ci varchar(8192) select
+NULL information_schema INNODB_LOCKS lock_id 1 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81) select
+NULL information_schema INNODB_LOCKS lock_index 6 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024) select
+NULL information_schema INNODB_LOCKS lock_mode 3 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema INNODB_LOCKS lock_page 8 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_LOCKS lock_rec 9 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_LOCKS lock_space 7 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_LOCKS lock_table 5 NO varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024) select
+NULL information_schema INNODB_LOCKS lock_trx_id 2 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18) select
+NULL information_schema INNODB_LOCKS lock_type 4 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema INNODB_LOCK_WAITS blocking_lock_id 4 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81) select
+NULL information_schema INNODB_LOCK_WAITS blocking_trx_id 3 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18) select
+NULL information_schema INNODB_LOCK_WAITS requested_lock_id 2 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81) select
+NULL information_schema INNODB_LOCK_WAITS requesting_trx_id 1 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18) select
+NULL information_schema INNODB_RSEG curr_size 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_RSEG max_size 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_RSEG page_no 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_RSEG rseg_id 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_RSEG space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_RSEG zip_size 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_INDEXES ID 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_INDEXES NAME 3 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema INNODB_SYS_INDEXES N_FIELDS 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_INDEXES PAGE_NO 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_INDEXES SPACE 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_INDEXES TABLE_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_INDEXES TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_STATS DIFF_VALS 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_STATS INDEX_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_STATS KEY_COLS 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_STATS NON_NULL_VALS 4 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_TABLES CLUSTER_NAME 8 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema INNODB_SYS_TABLES ID 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_TABLES MIX_ID 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_TABLES MIX_LEN 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_TABLES NAME 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema INNODB_SYS_TABLES N_COLS 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_TABLES SCHEMA 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema INNODB_SYS_TABLES SPACE 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_TABLES TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_TABLE_STATS clust_size 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_TABLE_STATS modified 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_TABLE_STATS other_size 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_TABLE_STATS rows 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_TABLE_STATS table_name 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema INNODB_TABLE_STATS table_schema 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema INNODB_TRX trx_id 1 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18) select
+NULL information_schema INNODB_TRX trx_mysql_thread_id 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_TRX trx_query 8 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024) select
+NULL information_schema INNODB_TRX trx_requested_lock_id 4 NULL YES varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81) select
+NULL information_schema INNODB_TRX trx_started 3 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema INNODB_TRX trx_state 2 NO varchar 13 39 NULL NULL NULL utf8 utf8_general_ci varchar(13) select
+NULL information_schema INNODB_TRX trx_wait_started 5 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema INNODB_TRX trx_weight 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES BLOCK_SIZE 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES DIRTY_BLOCKS 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES FULL_SIZE 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES KEY_CACHE_NAME 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema KEY_CACHES READS 10 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES READ_REQUESTS 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES SEGMENTS 2 NULL YES int NULL NULL 10 0 NULL NULL NULL int(3) unsigned select
+NULL information_schema KEY_CACHES SEGMENT_NUMBER 3 NULL YES int NULL NULL 10 0 NULL NULL NULL int(3) unsigned select
+NULL information_schema KEY_CACHES UNUSED_BLOCKS 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES USED_BLOCKS 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES WRITES 12 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_CACHES WRITE_REQUESTS 11 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema KEY_COLUMN_USAGE COLUMN_NAME 7 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema KEY_COLUMN_USAGE ORDINAL_POSITION 8 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(10) select
+NULL information_schema KEY_COLUMN_USAGE POSITION_IN_UNIQUE_CONSTRAINT 9 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(10) select
+NULL information_schema KEY_COLUMN_USAGE REFERENCED_COLUMN_NAME 12 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_NAME 11 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_SCHEMA 10 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema KEY_COLUMN_USAGE TABLE_CATALOG 4 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema KEY_COLUMN_USAGE TABLE_NAME 6 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema KEY_COLUMN_USAGE TABLE_SCHEMA 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PARTITIONS AVG_ROW_LENGTH 14 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS CHECKSUM 22 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS CHECK_TIME 21 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema PARTITIONS CREATE_TIME 19 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema PARTITIONS DATA_FREE 18 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS DATA_LENGTH 15 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS INDEX_LENGTH 17 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS MAX_DATA_LENGTH 16 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS NODEGROUP 24 NO varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12) select
+NULL information_schema PARTITIONS PARTITION_COMMENT 23 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select
+NULL information_schema PARTITIONS PARTITION_DESCRIPTION 12 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema PARTITIONS PARTITION_EXPRESSION 10 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema PARTITIONS PARTITION_METHOD 8 NULL YES varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12) select
+NULL information_schema PARTITIONS PARTITION_NAME 4 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PARTITIONS PARTITION_ORDINAL_POSITION 6 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS SUBPARTITION_EXPRESSION 11 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema PARTITIONS SUBPARTITION_METHOD 9 NULL YES varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12) select
+NULL information_schema PARTITIONS SUBPARTITION_NAME 5 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PARTITIONS SUBPARTITION_ORDINAL_POSITION 7 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS TABLESPACE_NAME 25 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PARTITIONS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema PARTITIONS TABLE_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PARTITIONS TABLE_ROWS 13 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PARTITIONS UPDATE_TIME 20 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PLUGINS PLUGIN_AUTH_VERSION 12 NULL YES varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select
+NULL information_schema PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select
+NULL information_schema PLUGINS PLUGIN_LICENSE 10 NULL YES varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select
+NULL information_schema PLUGINS PLUGIN_MATURITY 11 NULL YES varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12) select
+NULL information_schema PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10) select
+NULL information_schema PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select
+NULL information_schema PLUGINS PLUGIN_TYPE_VERSION 5 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select
+NULL information_schema PLUGINS PLUGIN_VERSION 2 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select
+NULL information_schema PROCESSLIST COMMAND 5 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) select
+NULL information_schema PROCESSLIST DB 4 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PROCESSLIST HOST 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PROCESSLIST ID 1 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select
+NULL information_schema PROCESSLIST INFO 8 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema PROCESSLIST MAX_STAGE 11 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2) select
+NULL information_schema PROCESSLIST PROGRESS 12 0.000 NO decimal NULL NULL 7 3 NULL NULL NULL decimal(7,3) select
+NULL information_schema PROCESSLIST STAGE 10 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2) select
+NULL information_schema PROCESSLIST STATE 7 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema PROCESSLIST TIME 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(7) select
+NULL information_schema PROCESSLIST TIME_MS 9 0.000 NO decimal NULL NULL 22 3 NULL NULL NULL decimal(22,3) select
+NULL information_schema PROCESSLIST USER 2 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) select
+NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema REFERENTIAL_CONSTRAINTS DELETE_RULE 9 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema REFERENTIAL_CONSTRAINTS MATCH_OPTION 7 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema REFERENTIAL_CONSTRAINTS REFERENCED_TABLE_NAME 11 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema REFERENTIAL_CONSTRAINTS TABLE_NAME 10 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_CATALOG 4 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_NAME 6 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_SCHEMA 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema REFERENTIAL_CONSTRAINTS UPDATE_RULE 8 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema ROUTINES CHARACTER_SET_CLIENT 21 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema ROUTINES COLLATION_CONNECTION 22 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema ROUTINES CREATED 16 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema ROUTINES DATABASE_COLLATION 23 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema ROUTINES DEFINER 20 NO varchar 77 231 NULL NULL NULL utf8 utf8_general_ci varchar(77) select
+NULL information_schema ROUTINES DTD_IDENTIFIER 6 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema ROUTINES EXTERNAL_LANGUAGE 10 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema ROUTINES EXTERNAL_NAME 9 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema ROUTINES IS_DETERMINISTIC 12 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema ROUTINES LAST_ALTERED 17 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema ROUTINES PARAMETER_STYLE 11 NO varchar 8 24 NULL NULL NULL utf8 utf8_general_ci varchar(8) select
+NULL information_schema ROUTINES ROUTINE_BODY 7 NO varchar 8 24 NULL NULL NULL utf8 utf8_general_ci varchar(8) select
+NULL information_schema ROUTINES ROUTINE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema ROUTINES ROUTINE_COMMENT 19 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema ROUTINES ROUTINE_DEFINITION 8 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema ROUTINES ROUTINE_NAME 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema ROUTINES ROUTINE_SCHEMA 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema ROUTINES ROUTINE_TYPE 5 NO varchar 9 27 NULL NULL NULL utf8 utf8_general_ci varchar(9) select
+NULL information_schema ROUTINES SECURITY_TYPE 15 NO varchar 7 21 NULL NULL NULL utf8 utf8_general_ci varchar(7) select
+NULL information_schema ROUTINES SPECIFIC_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema ROUTINES SQL_DATA_ACCESS 13 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema ROUTINES SQL_MODE 18 NO varchar 8192 24576 NULL NULL NULL utf8 utf8_general_ci varchar(8192) select
+NULL information_schema ROUTINES SQL_PATH 14 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema SCHEMATA CATALOG_NAME 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema SCHEMATA DEFAULT_CHARACTER_SET_NAME 3 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema SCHEMATA DEFAULT_COLLATION_NAME 4 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema SCHEMATA SCHEMA_NAME 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema SCHEMATA SQL_PATH 5 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema SCHEMA_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81) select
+NULL information_schema SCHEMA_PRIVILEGES IS_GRANTABLE 5 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema SCHEMA_PRIVILEGES PRIVILEGE_TYPE 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema SCHEMA_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema SCHEMA_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema SESSION_STATUS VARIABLE_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema SESSION_STATUS VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024) select
+NULL information_schema SESSION_VARIABLES VARIABLE_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema SESSION_VARIABLES VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024) select
+NULL information_schema STATISTICS CARDINALITY 10 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema STATISTICS COLLATION 9 NULL YES varchar 1 3 NULL NULL NULL utf8 utf8_general_ci varchar(1) select
+NULL information_schema STATISTICS COLUMN_NAME 8 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema STATISTICS COMMENT 15 NULL YES varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) select
+NULL information_schema STATISTICS INDEX_NAME 6 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema STATISTICS INDEX_SCHEMA 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema STATISTICS INDEX_TYPE 14 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) select
+NULL information_schema STATISTICS NON_UNIQUE 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(1) select
+NULL information_schema STATISTICS NULLABLE 13 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema STATISTICS PACKED 12 NULL YES varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10) select
+NULL information_schema STATISTICS SEQ_IN_INDEX 7 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(2) select
+NULL information_schema STATISTICS SUB_PART 11 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(3) select
+NULL information_schema STATISTICS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema STATISTICS TABLE_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema STATISTICS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TABLES AUTO_INCREMENT 14 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES AVG_ROW_LENGTH 9 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES CHECKSUM 19 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES CHECK_TIME 17 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema TABLES CREATE_OPTIONS 20 NULL YES varchar 255 765 NULL NULL NULL utf8 utf8_general_ci varchar(255) select
+NULL information_schema TABLES CREATE_TIME 15 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema TABLES DATA_FREE 13 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES DATA_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES ENGINE 5 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TABLES INDEX_LENGTH 12 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES MAX_DATA_LENGTH 11 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES ROW_FORMAT 7 NULL YES varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10) select
+NULL information_schema TABLES TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema TABLES TABLE_COLLATION 18 NULL YES varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema TABLES TABLE_COMMENT 21 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select
+NULL information_schema TABLES TABLE_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TABLES TABLE_ROWS 8 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TABLES TABLE_TYPE 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TABLES UPDATE_TIME 16 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema TABLES VERSION 6 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned select
+NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_TYPE 6 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TABLE_CONSTRAINTS TABLE_NAME 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TABLE_CONSTRAINTS TABLE_SCHEMA 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TABLE_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81) select
+NULL information_schema TABLE_PRIVILEGES IS_GRANTABLE 6 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema TABLE_PRIVILEGES PRIVILEGE_TYPE 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TABLE_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema TABLE_PRIVILEGES TABLE_NAME 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TABLE_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TABLE_STATISTICS ROWS_CHANGED 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema TABLE_STATISTICS ROWS_CHANGED_X_INDEXES 5 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema TABLE_STATISTICS ROWS_READ 3 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema TABLE_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema TABLE_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192) select
+NULL information_schema TRIGGERS ACTION_CONDITION 9 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema TRIGGERS ACTION_ORDER 8 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select
+NULL information_schema TRIGGERS ACTION_ORIENTATION 11 NO varchar 9 27 NULL NULL NULL utf8 utf8_general_ci varchar(9) select
+NULL information_schema TRIGGERS ACTION_REFERENCE_NEW_ROW 16 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema TRIGGERS ACTION_REFERENCE_NEW_TABLE 14 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TRIGGERS ACTION_REFERENCE_OLD_ROW 15 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema TRIGGERS ACTION_REFERENCE_OLD_TABLE 13 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TRIGGERS ACTION_STATEMENT 10 NULL NO longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema TRIGGERS ACTION_TIMING 12 NO varchar 6 18 NULL NULL NULL utf8 utf8_general_ci varchar(6) select
+NULL information_schema TRIGGERS CHARACTER_SET_CLIENT 20 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema TRIGGERS COLLATION_CONNECTION 21 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema TRIGGERS CREATED 17 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select
+NULL information_schema TRIGGERS DATABASE_COLLATION 22 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema TRIGGERS DEFINER 19 NO varchar 77 231 NULL NULL NULL utf8 utf8_general_ci varchar(77) select
+NULL information_schema TRIGGERS EVENT_MANIPULATION 4 NO varchar 6 18 NULL NULL NULL utf8 utf8_general_ci varchar(6) select
+NULL information_schema TRIGGERS EVENT_OBJECT_CATALOG 5 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema TRIGGERS EVENT_OBJECT_SCHEMA 6 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TRIGGERS EVENT_OBJECT_TABLE 7 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TRIGGERS SQL_MODE 18 NO varchar 8192 24576 NULL NULL NULL utf8 utf8_general_ci varchar(8192) select
+NULL information_schema TRIGGERS TRIGGER_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema TRIGGERS TRIGGER_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema TRIGGERS TRIGGER_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema USER_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81) select
+NULL information_schema USER_PRIVILEGES IS_GRANTABLE 4 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema USER_PRIVILEGES PRIVILEGE_TYPE 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema USER_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema USER_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL NULL double select
+NULL information_schema USER_STATISTICS BYTES_RECEIVED 7 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS BYTES_SENT 8 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS COMMIT_TRANSACTIONS 18 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema USER_STATISTICS CONNECTED_TIME 4 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema USER_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL NULL double select
+NULL information_schema USER_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS ROWS_INSERTED 13 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS ROWS_READ 10 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS ROWS_SENT 11 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS ROWS_UPDATED 14 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS SELECT_COMMANDS 15 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS TOTAL_CONNECTIONS 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select
+NULL information_schema USER_STATISTICS UPDATE_COMMANDS 16 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select
+NULL information_schema USER_STATISTICS USER 1 NO varchar 48 144 NULL NULL NULL utf8 utf8_general_ci varchar(48) select
+NULL information_schema VIEWS CHARACTER_SET_CLIENT 9 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema VIEWS CHECK_OPTION 5 NO varchar 8 24 NULL NULL NULL utf8 utf8_general_ci varchar(8) select
+NULL information_schema VIEWS COLLATION_CONNECTION 10 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select
+NULL information_schema VIEWS DEFINER 7 NO varchar 77 231 NULL NULL NULL utf8 utf8_general_ci varchar(77) select
+NULL information_schema VIEWS IS_UPDATABLE 6 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3) select
+NULL information_schema VIEWS SECURITY_TYPE 8 NO varchar 7 21 NULL NULL NULL utf8 utf8_general_ci varchar(7) select
+NULL information_schema VIEWS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select
+NULL information_schema VIEWS TABLE_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema VIEWS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema VIEWS VIEW_DEFINITION 4 NULL NO longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema XTRADB_ADMIN_COMMAND result_message 1 NO varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024) select
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
@@ -597,6 +601,7 @@ NULL datetime NULL NULL
NULL decimal NULL NULL
NULL double NULL NULL
NULL int NULL NULL
+NULL tinyint NULL NULL
--> CHAR(0) is allowed (see manual), and here both CHARACHTER_* values
--> are 0, which is intended behavior, and the result of 0 / 0 IS NULL
SELECT CHARACTER_OCTET_LENGTH / CHARACTER_MAXIMUM_LENGTH AS COL_CML,
@@ -661,6 +666,7 @@ NULL information_schema COLUMNS CHARACTER_MAXIMUM_LENGTH bigint NULL NULL NULL N
NULL information_schema COLUMNS CHARACTER_OCTET_LENGTH bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema COLUMNS NUMERIC_PRECISION bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema COLUMNS NUMERIC_SCALE bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema COLUMNS DATETIME_PRECISION bigint NULL NULL NULL NULL bigint(21) unsigned
3.0000 information_schema COLUMNS CHARACTER_SET_NAME varchar 32 96 utf8 utf8_general_ci varchar(32)
3.0000 information_schema COLUMNS COLLATION_NAME varchar 32 96 utf8 utf8_general_ci varchar(32)
1.0000 information_schema COLUMNS COLUMN_TYPE longtext 4294967295 4294967295 utf8 utf8_general_ci longtext
@@ -1004,6 +1010,9 @@ NULL information_schema PROCESSLIST TIME int NULL NULL NULL NULL int(7)
3.0000 information_schema PROCESSLIST STATE varchar 64 192 utf8 utf8_general_ci varchar(64)
1.0000 information_schema PROCESSLIST INFO longtext 4294967295 4294967295 utf8 utf8_general_ci longtext
NULL information_schema PROCESSLIST TIME_MS decimal NULL NULL NULL NULL decimal(22,3)
+NULL information_schema PROCESSLIST STAGE tinyint NULL NULL NULL NULL tinyint(2)
+NULL information_schema PROCESSLIST MAX_STAGE tinyint NULL NULL NULL NULL tinyint(2)
+NULL information_schema PROCESSLIST PROGRESS decimal NULL NULL NULL NULL decimal(7,3)
3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512)
3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result
index 721579750a2..e61328705d9 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result
@@ -2,558 +2,562 @@ SELECT * FROM information_schema.columns
WHERE table_schema = 'information_schema'
AND table_name <> 'profiling'
ORDER BY table_schema, table_name, column_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema CHARACTER_SETS DESCRIPTION 3 NO varchar 60 180 NULL NULL utf8 utf8_general_ci varchar(60)
-NULL information_schema CHARACTER_SETS MAXLEN 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(3)
-NULL information_schema CLIENT_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL double
-NULL information_schema CLIENT_STATISTICS BYTES_RECEIVED 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS BYTES_SENT 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS CLIENT 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema CLIENT_STATISTICS COMMIT_TRANSACTIONS 18 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS CONNECTED_TIME 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL double
-NULL information_schema CLIENT_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS ROWS_INSERTED 13 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS ROWS_READ 10 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS ROWS_SENT 11 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS ROWS_UPDATED 14 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS SELECT_COMMANDS 15 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS 2 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema CLIENT_STATISTICS UPDATE_COMMANDS 16 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema COLLATIONS CHARACTER_SET_NAME 2 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema COLLATIONS COLLATION_NAME 1 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema COLLATIONS ID 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(11)
-NULL information_schema COLLATIONS IS_COMPILED 5 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema COLLATIONS IS_DEFAULT 4 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema COLLATIONS SORTLEN 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(3)
-NULL information_schema COLLATION_CHARACTER_SET_APPLICABILITY CHARACTER_SET_NAME 2 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME 1 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema COLUMNS CHARACTER_MAXIMUM_LENGTH 9 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema COLUMNS CHARACTER_OCTET_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema COLUMNS CHARACTER_SET_NAME 13 NULL YES varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema COLUMNS COLLATION_NAME 14 NULL YES varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema COLUMNS COLUMN_COMMENT 19 NO varchar 255 765 NULL NULL utf8 utf8_general_ci varchar(255)
-NULL information_schema COLUMNS COLUMN_DEFAULT 6 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext
-NULL information_schema COLUMNS COLUMN_KEY 16 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema COLUMNS COLUMN_NAME 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema COLUMNS COLUMN_TYPE 15 NULL NO longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext
-NULL information_schema COLUMNS DATA_TYPE 8 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema COLUMNS EXTRA 17 NO varchar 27 81 NULL NULL utf8 utf8_general_ci varchar(27)
-NULL information_schema COLUMNS IS_NULLABLE 7 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema COLUMNS NUMERIC_PRECISION 11 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema COLUMNS NUMERIC_SCALE 12 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema COLUMNS ORDINAL_POSITION 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema COLUMNS PRIVILEGES 18 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80)
-NULL information_schema COLUMNS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema COLUMNS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema COLUMNS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema COLUMN_PRIVILEGES COLUMN_NAME 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema COLUMN_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81)
-NULL information_schema COLUMN_PRIVILEGES IS_GRANTABLE 7 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema COLUMN_PRIVILEGES PRIVILEGE_TYPE 6 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema COLUMN_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema COLUMN_PRIVILEGES TABLE_NAME 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema COLUMN_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema ENGINES COMMENT 3 NO varchar 160 480 NULL NULL utf8 utf8_general_ci varchar(160)
-NULL information_schema ENGINES ENGINE 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema ENGINES SAVEPOINTS 6 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema ENGINES SUPPORT 2 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8)
-NULL information_schema ENGINES TRANSACTIONS 4 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema ENGINES XA 5 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema EVENTS CHARACTER_SET_CLIENT 22 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema EVENTS COLLATION_CONNECTION 23 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema EVENTS CREATED 17 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema EVENTS DATABASE_COLLATION 24 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema EVENTS DEFINER 4 NO varchar 77 231 NULL NULL utf8 utf8_general_ci varchar(77)
-NULL information_schema EVENTS ENDS 14 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema EVENTS EVENT_BODY 6 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8)
-NULL information_schema EVENTS EVENT_CATALOG 1 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema EVENTS EVENT_COMMENT 20 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema EVENTS EVENT_DEFINITION 7 NULL NO longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext
-NULL information_schema EVENTS EVENT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema EVENTS EVENT_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema EVENTS EVENT_TYPE 8 NO varchar 9 27 NULL NULL utf8 utf8_general_ci varchar(9)
-NULL information_schema EVENTS EXECUTE_AT 9 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema EVENTS INTERVAL_FIELD 11 NULL YES varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18)
-NULL information_schema EVENTS INTERVAL_VALUE 10 NULL YES varchar 256 768 NULL NULL utf8 utf8_general_ci varchar(256)
-NULL information_schema EVENTS LAST_ALTERED 18 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema EVENTS LAST_EXECUTED 19 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema EVENTS ON_COMPLETION 16 NO varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12)
-NULL information_schema EVENTS ORIGINATOR 21 0 NO bigint NULL NULL 19 0 NULL NULL bigint(10)
-NULL information_schema EVENTS SQL_MODE 12 NO varchar 8192 24576 NULL NULL utf8 utf8_general_ci varchar(8192)
-NULL information_schema EVENTS STARTS 13 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema EVENTS STATUS 15 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18)
-NULL information_schema EVENTS TIME_ZONE 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema FILES AUTOEXTEND_SIZE 19 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema FILES AVG_ROW_LENGTH 28 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema FILES CHECKSUM 36 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema FILES CHECK_TIME 35 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema FILES CREATE_TIME 33 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema FILES CREATION_TIME 20 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema FILES DATA_FREE 32 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema FILES DATA_LENGTH 29 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema FILES DELETED_ROWS 12 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4)
-NULL information_schema FILES ENGINE 10 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema FILES EXTENT_SIZE 16 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4)
-NULL information_schema FILES EXTRA 38 NULL YES varchar 255 765 NULL NULL utf8 utf8_general_ci varchar(255)
-NULL information_schema FILES FILE_ID 1 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4)
-NULL information_schema FILES FILE_NAME 2 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema FILES FILE_TYPE 3 NO varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20)
-NULL information_schema FILES FREE_EXTENTS 14 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4)
-NULL information_schema FILES FULLTEXT_KEYS 11 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema FILES INDEX_LENGTH 31 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema FILES INITIAL_SIZE 17 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema FILES LAST_ACCESS_TIME 22 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema FILES LAST_UPDATE_TIME 21 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema FILES LOGFILE_GROUP_NAME 8 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema FILES LOGFILE_GROUP_NUMBER 9 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4)
-NULL information_schema FILES MAXIMUM_SIZE 18 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema FILES MAX_DATA_LENGTH 30 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema FILES RECOVER_TIME 23 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4)
-NULL information_schema FILES ROW_FORMAT 26 NULL YES varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10)
-NULL information_schema FILES STATUS 37 NO varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20)
-NULL information_schema FILES TABLESPACE_NAME 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema FILES TABLE_CATALOG 5 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema FILES TABLE_NAME 7 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema FILES TABLE_ROWS 27 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema FILES TABLE_SCHEMA 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema FILES TOTAL_EXTENTS 15 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4)
-NULL information_schema FILES TRANSACTION_COUNTER 24 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4)
-NULL information_schema FILES UPDATE_COUNT 13 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4)
-NULL information_schema FILES UPDATE_TIME 34 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema FILES VERSION 25 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema GLOBAL_STATUS VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema GLOBAL_STATUS VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024)
-NULL information_schema GLOBAL_VARIABLES VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema GLOBAL_VARIABLES VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024)
-NULL information_schema INDEX_STATISTICS INDEX_NAME 3 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema INDEX_STATISTICS ROWS_READ 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema INDEX_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema INDEX_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema INNODB_BUFFER_PAGE ACCESS_TIME 10 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE BLOCK_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE COMPRESSED_SIZE 15 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE DATA_SIZE 14 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE FIX_COUNT 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE FLUSH_TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE FREE_PAGE_CLOCK 19 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE INDEX_NAME 12 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024)
-NULL information_schema INNODB_BUFFER_PAGE IO_FIX 17 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema INNODB_BUFFER_PAGE IS_HASHED 7 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema INNODB_BUFFER_PAGE IS_OLD 18 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema INNODB_BUFFER_PAGE NEWEST_MODIFICATION 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE NUMBER_RECORDS 13 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE OLDEST_MODIFICATION 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE PAGE_NUMBER 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE PAGE_STATE 16 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema INNODB_BUFFER_PAGE PAGE_TYPE 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema INNODB_BUFFER_PAGE SPACE 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE TABLE_NAME 11 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024)
-NULL information_schema INNODB_BUFFER_PAGE_LRU ACCESS_TIME 10 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE_LRU COMPRESSED 16 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema INNODB_BUFFER_PAGE_LRU COMPRESSED_SIZE 15 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE_LRU DATA_SIZE 14 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE_LRU FIX_COUNT 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE_LRU FLUSH_TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE_LRU FREE_PAGE_CLOCK 19 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE_LRU INDEX_NAME 12 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024)
-NULL information_schema INNODB_BUFFER_PAGE_LRU IO_FIX 17 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema INNODB_BUFFER_PAGE_LRU IS_HASHED 7 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema INNODB_BUFFER_PAGE_LRU IS_OLD 18 NULL YES varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema INNODB_BUFFER_PAGE_LRU LRU_POSITION 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE_LRU NEWEST_MODIFICATION 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE_LRU NUMBER_RECORDS 13 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE_LRU OLDEST_MODIFICATION 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE_LRU PAGE_NUMBER 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE_LRU PAGE_TYPE 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema INNODB_BUFFER_PAGE_LRU SPACE 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_PAGE_LRU TABLE_NAME 11 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024)
-NULL information_schema INNODB_BUFFER_POOL_PAGES fix_count 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES flush_type 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES lru_position 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES page_no 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES page_type 1 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema INNODB_BUFFER_POOL_PAGES space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB compressed 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB fix_count 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB flush_type 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB lru_position 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB next_page_no 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB page_no 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB part_len 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB space_id 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX access_time 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX data_size 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX dirty 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX fix_count 12 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX flush_type 13 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX hashed 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX index_id 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX lru_position 11 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX modified 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX n_recs 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX old 10 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX page_no 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS DATABASE_PAGES 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS FREE_BUFFERS 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS HIT_RATE 21 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS LRU_IO_CURRENT 29 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS LRU_IO_TOTAL 28 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS MODIFIED_DATABASE_PAGES 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS NOT_YOUNG_MAKE_PER_THOUSAND_GETS 23 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_CREATED 15 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_GET 20 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_READ 14 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_READ_AHEAD 24 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_WRITTEN 16 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_READ_AHEAD_EVICTED 25 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS OLD_DATABASE_PAGES 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_CREATE_RATE 18 0 NO double NULL NULL 12 NULL NULL NULL double
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_MADE_NOT_YOUNG_RATE 13 0 NO double NULL NULL 12 NULL NULL NULL double
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_MADE_YOUNG 10 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_MADE_YOUNG_RATE 12 0 NO double NULL NULL 12 NULL NULL NULL double
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_NOT_MADE_YOUNG 11 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_READ_RATE 17 0 NO double NULL NULL 12 NULL NULL NULL double
-NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_WRITTEN_RATE 19 0 NO double NULL NULL 12 NULL NULL NULL double
-NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_DECOMPRESS 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_FLUSH_LIST 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_FLUSH_LRU 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_READS 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS POOL_SIZE 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS READ_AHEAD_EVICTED_RATE 27 0 NO double NULL NULL 12 NULL NULL NULL double
-NULL information_schema INNODB_BUFFER_POOL_STATS READ_AHEAD_RATE 26 0 NO double NULL NULL 12 NULL NULL NULL double
-NULL information_schema INNODB_BUFFER_POOL_STATS UNCOMPRESS_CURRENT 31 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS UNCOMPRESS_TOTAL 30 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_STATS YOUNG_MAKE_PER_THOUSAND_GETS 22 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_CHANGED_PAGES end_lsn 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_CHANGED_PAGES page_id 2 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned
-NULL information_schema INNODB_CHANGED_PAGES space_id 1 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned
-NULL information_schema INNODB_CHANGED_PAGES start_lsn 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_CMP compress_ops 2 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMP compress_ops_ok 3 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMP compress_time 4 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMP page_size 1 0 NO int NULL NULL 10 0 NULL NULL int(5)
-NULL information_schema INNODB_CMP uncompress_ops 5 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMP uncompress_time 6 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMPMEM pages_free 3 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMPMEM pages_used 2 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMPMEM page_size 1 0 NO int NULL NULL 10 0 NULL NULL int(5)
-NULL information_schema INNODB_CMPMEM relocation_ops 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema INNODB_CMPMEM relocation_time 5 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMPMEM_RESET pages_free 3 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMPMEM_RESET pages_used 2 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMPMEM_RESET page_size 1 0 NO int NULL NULL 10 0 NULL NULL int(5)
-NULL information_schema INNODB_CMPMEM_RESET relocation_ops 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema INNODB_CMPMEM_RESET relocation_time 5 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMP_RESET compress_ops 2 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMP_RESET compress_ops_ok 3 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMP_RESET compress_time 4 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMP_RESET page_size 1 0 NO int NULL NULL 10 0 NULL NULL int(5)
-NULL information_schema INNODB_CMP_RESET uncompress_ops 5 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_CMP_RESET uncompress_time 6 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema INNODB_INDEX_STATS fields 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_INDEX_STATS index_name 3 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema INNODB_INDEX_STATS index_size 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_INDEX_STATS leaf_pages 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_INDEX_STATS row_per_keys 5 NO varchar 256 768 NULL NULL utf8 utf8_general_ci varchar(256)
-NULL information_schema INNODB_INDEX_STATS table_name 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema INNODB_INDEX_STATS table_schema 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema INNODB_LOCKS lock_data 10 NULL YES varchar 8192 24576 NULL NULL utf8 utf8_general_ci varchar(8192)
-NULL information_schema INNODB_LOCKS lock_id 1 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81)
-NULL information_schema INNODB_LOCKS lock_index 6 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024)
-NULL information_schema INNODB_LOCKS lock_mode 3 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema INNODB_LOCKS lock_page 8 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_LOCKS lock_rec 9 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_LOCKS lock_space 7 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_LOCKS lock_table 5 NO varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024)
-NULL information_schema INNODB_LOCKS lock_trx_id 2 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18)
-NULL information_schema INNODB_LOCKS lock_type 4 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema INNODB_LOCK_WAITS blocking_lock_id 4 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81)
-NULL information_schema INNODB_LOCK_WAITS blocking_trx_id 3 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18)
-NULL information_schema INNODB_LOCK_WAITS requested_lock_id 2 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81)
-NULL information_schema INNODB_LOCK_WAITS requesting_trx_id 1 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18)
-NULL information_schema INNODB_RSEG curr_size 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_RSEG max_size 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_RSEG page_no 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_RSEG rseg_id 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_RSEG space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_RSEG zip_size 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_INDEXES ID 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_INDEXES NAME 3 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema INNODB_SYS_INDEXES N_FIELDS 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_INDEXES PAGE_NO 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_INDEXES SPACE 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_INDEXES TABLE_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_INDEXES TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_STATS DIFF_VALS 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_STATS INDEX_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_STATS KEY_COLS 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_STATS NON_NULL_VALS 4 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_TABLES CLUSTER_NAME 8 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema INNODB_SYS_TABLES ID 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_TABLES MIX_ID 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_TABLES MIX_LEN 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_TABLES NAME 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema INNODB_SYS_TABLES N_COLS 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_TABLES SCHEMA 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema INNODB_SYS_TABLES SPACE 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_SYS_TABLES TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_TABLE_STATS clust_size 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_TABLE_STATS modified 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_TABLE_STATS other_size 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_TABLE_STATS rows 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_TABLE_STATS table_name 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema INNODB_TABLE_STATS table_schema 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema INNODB_TRX trx_id 1 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18)
-NULL information_schema INNODB_TRX trx_mysql_thread_id 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_TRX trx_query 8 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024)
-NULL information_schema INNODB_TRX trx_requested_lock_id 4 NULL YES varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81)
-NULL information_schema INNODB_TRX trx_started 3 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema INNODB_TRX trx_state 2 NO varchar 13 39 NULL NULL utf8 utf8_general_ci varchar(13)
-NULL information_schema INNODB_TRX trx_wait_started 5 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema INNODB_TRX trx_weight 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema KEY_CACHES BLOCK_SIZE 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema KEY_CACHES DIRTY_BLOCKS 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema KEY_CACHES FULL_SIZE 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema KEY_CACHES KEY_CACHE_NAME 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema KEY_CACHES READS 10 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema KEY_CACHES READ_REQUESTS 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema KEY_CACHES SEGMENTS 2 NULL YES int NULL NULL 10 0 NULL NULL int(3) unsigned
-NULL information_schema KEY_CACHES SEGMENT_NUMBER 3 NULL YES int NULL NULL 10 0 NULL NULL int(3) unsigned
-NULL information_schema KEY_CACHES UNUSED_BLOCKS 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema KEY_CACHES USED_BLOCKS 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema KEY_CACHES WRITES 12 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema KEY_CACHES WRITE_REQUESTS 11 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema KEY_COLUMN_USAGE COLUMN_NAME 7 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema KEY_COLUMN_USAGE ORDINAL_POSITION 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(10)
-NULL information_schema KEY_COLUMN_USAGE POSITION_IN_UNIQUE_CONSTRAINT 9 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(10)
-NULL information_schema KEY_COLUMN_USAGE REFERENCED_COLUMN_NAME 12 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_NAME 11 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_SCHEMA 10 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema KEY_COLUMN_USAGE TABLE_CATALOG 4 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema KEY_COLUMN_USAGE TABLE_NAME 6 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema KEY_COLUMN_USAGE TABLE_SCHEMA 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema PARTITIONS AVG_ROW_LENGTH 14 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema PARTITIONS CHECKSUM 22 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema PARTITIONS CHECK_TIME 21 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema PARTITIONS CREATE_TIME 19 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema PARTITIONS DATA_FREE 18 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema PARTITIONS DATA_LENGTH 15 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema PARTITIONS INDEX_LENGTH 17 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema PARTITIONS MAX_DATA_LENGTH 16 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema PARTITIONS NODEGROUP 24 NO varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12)
-NULL information_schema PARTITIONS PARTITION_COMMENT 23 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80)
-NULL information_schema PARTITIONS PARTITION_DESCRIPTION 12 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext
-NULL information_schema PARTITIONS PARTITION_EXPRESSION 10 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext
-NULL information_schema PARTITIONS PARTITION_METHOD 8 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12)
-NULL information_schema PARTITIONS PARTITION_NAME 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema PARTITIONS PARTITION_ORDINAL_POSITION 6 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema PARTITIONS SUBPARTITION_EXPRESSION 11 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext
-NULL information_schema PARTITIONS SUBPARTITION_METHOD 9 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12)
-NULL information_schema PARTITIONS SUBPARTITION_NAME 5 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema PARTITIONS SUBPARTITION_ORDINAL_POSITION 7 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema PARTITIONS TABLESPACE_NAME 25 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema PARTITIONS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema PARTITIONS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema PARTITIONS TABLE_ROWS 13 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema PARTITIONS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema PARTITIONS UPDATE_TIME 20 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema PLUGINS PLUGIN_AUTH_VERSION 12 NULL YES varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80)
-NULL information_schema PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext
-NULL information_schema PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20)
-NULL information_schema PLUGINS PLUGIN_LICENSE 10 NULL YES varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80)
-NULL information_schema PLUGINS PLUGIN_MATURITY 11 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12)
-NULL information_schema PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10)
-NULL information_schema PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80)
-NULL information_schema PLUGINS PLUGIN_TYPE_VERSION 5 NO varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20)
-NULL information_schema PLUGINS PLUGIN_VERSION 2 NO varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20)
-NULL information_schema PROCESSLIST COMMAND 5 NO varchar 16 48 NULL NULL utf8 utf8_general_ci varchar(16)
-NULL information_schema PROCESSLIST DB 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema PROCESSLIST HOST 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema PROCESSLIST ID 1 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4)
-NULL information_schema PROCESSLIST INFO 8 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext
-NULL information_schema PROCESSLIST STATE 7 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema PROCESSLIST TIME 6 0 NO int NULL NULL 10 0 NULL NULL int(7)
-NULL information_schema PROCESSLIST TIME_MS 9 0.000 NO decimal NULL NULL 22 3 NULL NULL decimal(22,3)
-NULL information_schema PROCESSLIST USER 2 NO varchar 16 48 NULL NULL utf8 utf8_general_ci varchar(16)
-NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema REFERENTIAL_CONSTRAINTS DELETE_RULE 9 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema REFERENTIAL_CONSTRAINTS MATCH_OPTION 7 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema REFERENTIAL_CONSTRAINTS REFERENCED_TABLE_NAME 11 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema REFERENTIAL_CONSTRAINTS TABLE_NAME 10 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_CATALOG 4 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_NAME 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_SCHEMA 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema REFERENTIAL_CONSTRAINTS UPDATE_RULE 8 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema ROUTINES CHARACTER_SET_CLIENT 21 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema ROUTINES COLLATION_CONNECTION 22 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema ROUTINES CREATED 16 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema ROUTINES DATABASE_COLLATION 23 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema ROUTINES DEFINER 20 NO varchar 77 231 NULL NULL utf8 utf8_general_ci varchar(77)
-NULL information_schema ROUTINES DTD_IDENTIFIER 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema ROUTINES EXTERNAL_LANGUAGE 10 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema ROUTINES EXTERNAL_NAME 9 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema ROUTINES IS_DETERMINISTIC 12 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema ROUTINES LAST_ALTERED 17 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema ROUTINES PARAMETER_STYLE 11 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8)
-NULL information_schema ROUTINES ROUTINE_BODY 7 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8)
-NULL information_schema ROUTINES ROUTINE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema ROUTINES ROUTINE_COMMENT 19 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema ROUTINES ROUTINE_DEFINITION 8 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext
-NULL information_schema ROUTINES ROUTINE_NAME 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema ROUTINES ROUTINE_SCHEMA 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema ROUTINES ROUTINE_TYPE 5 NO varchar 9 27 NULL NULL utf8 utf8_general_ci varchar(9)
-NULL information_schema ROUTINES SECURITY_TYPE 15 NO varchar 7 21 NULL NULL utf8 utf8_general_ci varchar(7)
-NULL information_schema ROUTINES SPECIFIC_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema ROUTINES SQL_DATA_ACCESS 13 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema ROUTINES SQL_MODE 18 NO varchar 8192 24576 NULL NULL utf8 utf8_general_ci varchar(8192)
-NULL information_schema ROUTINES SQL_PATH 14 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema SCHEMATA CATALOG_NAME 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema SCHEMATA DEFAULT_CHARACTER_SET_NAME 3 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema SCHEMATA DEFAULT_COLLATION_NAME 4 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema SCHEMATA SCHEMA_NAME 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema SCHEMATA SQL_PATH 5 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema SCHEMA_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81)
-NULL information_schema SCHEMA_PRIVILEGES IS_GRANTABLE 5 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema SCHEMA_PRIVILEGES PRIVILEGE_TYPE 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema SCHEMA_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema SCHEMA_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema SESSION_STATUS VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema SESSION_STATUS VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024)
-NULL information_schema SESSION_VARIABLES VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema SESSION_VARIABLES VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024)
-NULL information_schema STATISTICS CARDINALITY 10 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema STATISTICS COLLATION 9 NULL YES varchar 1 3 NULL NULL utf8 utf8_general_ci varchar(1)
-NULL information_schema STATISTICS COLUMN_NAME 8 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema STATISTICS COMMENT 15 NULL YES varchar 16 48 NULL NULL utf8 utf8_general_ci varchar(16)
-NULL information_schema STATISTICS INDEX_NAME 6 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema STATISTICS INDEX_SCHEMA 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema STATISTICS INDEX_TYPE 14 NO varchar 16 48 NULL NULL utf8 utf8_general_ci varchar(16)
-NULL information_schema STATISTICS NON_UNIQUE 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(1)
-NULL information_schema STATISTICS NULLABLE 13 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema STATISTICS PACKED 12 NULL YES varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10)
-NULL information_schema STATISTICS SEQ_IN_INDEX 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(2)
-NULL information_schema STATISTICS SUB_PART 11 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(3)
-NULL information_schema STATISTICS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema STATISTICS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema STATISTICS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TABLES AUTO_INCREMENT 14 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema TABLES AVG_ROW_LENGTH 9 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema TABLES CHECKSUM 19 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema TABLES CHECK_TIME 17 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema TABLES CREATE_OPTIONS 20 NULL YES varchar 255 765 NULL NULL utf8 utf8_general_ci varchar(255)
-NULL information_schema TABLES CREATE_TIME 15 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema TABLES DATA_FREE 13 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema TABLES DATA_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema TABLES ENGINE 5 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TABLES INDEX_LENGTH 12 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema TABLES MAX_DATA_LENGTH 11 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema TABLES ROW_FORMAT 7 NULL YES varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10)
-NULL information_schema TABLES TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema TABLES TABLE_COLLATION 18 NULL YES varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema TABLES TABLE_COMMENT 21 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80)
-NULL information_schema TABLES TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TABLES TABLE_ROWS 8 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema TABLES TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TABLES TABLE_TYPE 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TABLES UPDATE_TIME 16 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema TABLES VERSION 6 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned
-NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_TYPE 6 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TABLE_CONSTRAINTS TABLE_NAME 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TABLE_CONSTRAINTS TABLE_SCHEMA 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TABLE_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81)
-NULL information_schema TABLE_PRIVILEGES IS_GRANTABLE 6 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema TABLE_PRIVILEGES PRIVILEGE_TYPE 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TABLE_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema TABLE_PRIVILEGES TABLE_NAME 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TABLE_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TABLE_STATISTICS ROWS_CHANGED 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema TABLE_STATISTICS ROWS_CHANGED_X_INDEXES 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema TABLE_STATISTICS ROWS_READ 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema TABLE_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema TABLE_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192)
-NULL information_schema TRIGGERS ACTION_CONDITION 9 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext
-NULL information_schema TRIGGERS ACTION_ORDER 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4)
-NULL information_schema TRIGGERS ACTION_ORIENTATION 11 NO varchar 9 27 NULL NULL utf8 utf8_general_ci varchar(9)
-NULL information_schema TRIGGERS ACTION_REFERENCE_NEW_ROW 16 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema TRIGGERS ACTION_REFERENCE_NEW_TABLE 14 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TRIGGERS ACTION_REFERENCE_OLD_ROW 15 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema TRIGGERS ACTION_REFERENCE_OLD_TABLE 13 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TRIGGERS ACTION_STATEMENT 10 NULL NO longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext
-NULL information_schema TRIGGERS ACTION_TIMING 12 NO varchar 6 18 NULL NULL utf8 utf8_general_ci varchar(6)
-NULL information_schema TRIGGERS CHARACTER_SET_CLIENT 20 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema TRIGGERS COLLATION_CONNECTION 21 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema TRIGGERS CREATED 17 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL information_schema TRIGGERS DATABASE_COLLATION 22 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema TRIGGERS DEFINER 19 NO varchar 77 231 NULL NULL utf8 utf8_general_ci varchar(77)
-NULL information_schema TRIGGERS EVENT_MANIPULATION 4 NO varchar 6 18 NULL NULL utf8 utf8_general_ci varchar(6)
-NULL information_schema TRIGGERS EVENT_OBJECT_CATALOG 5 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema TRIGGERS EVENT_OBJECT_SCHEMA 6 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TRIGGERS EVENT_OBJECT_TABLE 7 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TRIGGERS SQL_MODE 18 NO varchar 8192 24576 NULL NULL utf8 utf8_general_ci varchar(8192)
-NULL information_schema TRIGGERS TRIGGER_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema TRIGGERS TRIGGER_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema TRIGGERS TRIGGER_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema USER_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81)
-NULL information_schema USER_PRIVILEGES IS_GRANTABLE 4 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema USER_PRIVILEGES PRIVILEGE_TYPE 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema USER_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema USER_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL double
-NULL information_schema USER_STATISTICS BYTES_RECEIVED 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS BYTES_SENT 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS COMMIT_TRANSACTIONS 18 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema USER_STATISTICS CONNECTED_TIME 4 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema USER_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL double
-NULL information_schema USER_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS ROWS_INSERTED 13 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS ROWS_READ 10 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS ROWS_SENT 11 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS ROWS_UPDATED 14 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS SELECT_COMMANDS 15 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS TOTAL_CONNECTIONS 2 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL information_schema USER_STATISTICS UPDATE_COMMANDS 16 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21)
-NULL information_schema USER_STATISTICS USER 1 NO varchar 48 144 NULL NULL utf8 utf8_general_ci varchar(48)
-NULL information_schema VIEWS CHARACTER_SET_CLIENT 9 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema VIEWS CHECK_OPTION 5 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8)
-NULL information_schema VIEWS COLLATION_CONNECTION 10 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32)
-NULL information_schema VIEWS DEFINER 7 NO varchar 77 231 NULL NULL utf8 utf8_general_ci varchar(77)
-NULL information_schema VIEWS IS_UPDATABLE 6 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3)
-NULL information_schema VIEWS SECURITY_TYPE 8 NO varchar 7 21 NULL NULL utf8 utf8_general_ci varchar(7)
-NULL information_schema VIEWS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL information_schema VIEWS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema VIEWS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema VIEWS VIEW_DEFINITION 4 NULL NO longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext
-NULL information_schema XTRADB_ADMIN_COMMAND result_message 1 NO varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024)
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema CHARACTER_SETS DESCRIPTION 3 NO varchar 60 180 NULL NULL NULL utf8 utf8_general_ci varchar(60)
+NULL information_schema CHARACTER_SETS MAXLEN 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(3)
+NULL information_schema CLIENT_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL NULL double
+NULL information_schema CLIENT_STATISTICS BYTES_RECEIVED 7 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS BYTES_SENT 8 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS CLIENT 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema CLIENT_STATISTICS COMMIT_TRANSACTIONS 18 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS CONNECTED_TIME 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL NULL double
+NULL information_schema CLIENT_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_INSERTED 13 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_READ 10 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_SENT 11 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_UPDATED 14 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS SELECT_COMMANDS 15 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS 2 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS UPDATE_COMMANDS 16 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema COLLATIONS CHARACTER_SET_NAME 2 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema COLLATIONS COLLATION_NAME 1 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema COLLATIONS ID 3 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(11)
+NULL information_schema COLLATIONS IS_COMPILED 5 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema COLLATIONS IS_DEFAULT 4 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema COLLATIONS SORTLEN 6 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(3)
+NULL information_schema COLLATION_CHARACTER_SET_APPLICABILITY CHARACTER_SET_NAME 2 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME 1 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema COLUMNS CHARACTER_MAXIMUM_LENGTH 9 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema COLUMNS CHARACTER_OCTET_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema COLUMNS CHARACTER_SET_NAME 14 NULL YES varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema COLUMNS COLLATION_NAME 15 NULL YES varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema COLUMNS COLUMN_COMMENT 20 NO varchar 255 765 NULL NULL NULL utf8 utf8_general_ci varchar(255)
+NULL information_schema COLUMNS COLUMN_DEFAULT 6 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema COLUMNS COLUMN_KEY 17 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema COLUMNS COLUMN_NAME 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema COLUMNS COLUMN_TYPE 16 NULL NO longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema COLUMNS DATA_TYPE 8 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema COLUMNS DATETIME_PRECISION 13 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema COLUMNS EXTRA 18 NO varchar 27 81 NULL NULL NULL utf8 utf8_general_ci varchar(27)
+NULL information_schema COLUMNS IS_NULLABLE 7 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema COLUMNS NUMERIC_PRECISION 11 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema COLUMNS NUMERIC_SCALE 12 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema COLUMNS ORDINAL_POSITION 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema COLUMNS PRIVILEGES 19 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80)
+NULL information_schema COLUMNS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema COLUMNS TABLE_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema COLUMNS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema COLUMN_PRIVILEGES COLUMN_NAME 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema COLUMN_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81)
+NULL information_schema COLUMN_PRIVILEGES IS_GRANTABLE 7 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema COLUMN_PRIVILEGES PRIVILEGE_TYPE 6 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema COLUMN_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema COLUMN_PRIVILEGES TABLE_NAME 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema COLUMN_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema ENGINES COMMENT 3 NO varchar 160 480 NULL NULL NULL utf8 utf8_general_ci varchar(160)
+NULL information_schema ENGINES ENGINE 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema ENGINES SAVEPOINTS 6 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema ENGINES SUPPORT 2 NO varchar 8 24 NULL NULL NULL utf8 utf8_general_ci varchar(8)
+NULL information_schema ENGINES TRANSACTIONS 4 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema ENGINES XA 5 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema EVENTS CHARACTER_SET_CLIENT 22 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema EVENTS COLLATION_CONNECTION 23 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema EVENTS CREATED 17 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema EVENTS DATABASE_COLLATION 24 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema EVENTS DEFINER 4 NO varchar 77 231 NULL NULL NULL utf8 utf8_general_ci varchar(77)
+NULL information_schema EVENTS ENDS 14 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema EVENTS EVENT_BODY 6 NO varchar 8 24 NULL NULL NULL utf8 utf8_general_ci varchar(8)
+NULL information_schema EVENTS EVENT_CATALOG 1 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema EVENTS EVENT_COMMENT 20 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema EVENTS EVENT_DEFINITION 7 NULL NO longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema EVENTS EVENT_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema EVENTS EVENT_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema EVENTS EVENT_TYPE 8 NO varchar 9 27 NULL NULL NULL utf8 utf8_general_ci varchar(9)
+NULL information_schema EVENTS EXECUTE_AT 9 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema EVENTS INTERVAL_FIELD 11 NULL YES varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18)
+NULL information_schema EVENTS INTERVAL_VALUE 10 NULL YES varchar 256 768 NULL NULL NULL utf8 utf8_general_ci varchar(256)
+NULL information_schema EVENTS LAST_ALTERED 18 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema EVENTS LAST_EXECUTED 19 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema EVENTS ON_COMPLETION 16 NO varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12)
+NULL information_schema EVENTS ORIGINATOR 21 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(10)
+NULL information_schema EVENTS SQL_MODE 12 NO varchar 8192 24576 NULL NULL NULL utf8 utf8_general_ci varchar(8192)
+NULL information_schema EVENTS STARTS 13 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema EVENTS STATUS 15 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18)
+NULL information_schema EVENTS TIME_ZONE 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema FILES AUTOEXTEND_SIZE 19 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema FILES AVG_ROW_LENGTH 28 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema FILES CHECKSUM 36 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema FILES CHECK_TIME 35 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema FILES CREATE_TIME 33 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema FILES CREATION_TIME 20 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema FILES DATA_FREE 32 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema FILES DATA_LENGTH 29 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema FILES DELETED_ROWS 12 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4)
+NULL information_schema FILES ENGINE 10 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema FILES EXTENT_SIZE 16 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4)
+NULL information_schema FILES EXTRA 38 NULL YES varchar 255 765 NULL NULL NULL utf8 utf8_general_ci varchar(255)
+NULL information_schema FILES FILE_ID 1 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4)
+NULL information_schema FILES FILE_NAME 2 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema FILES FILE_TYPE 3 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20)
+NULL information_schema FILES FREE_EXTENTS 14 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4)
+NULL information_schema FILES FULLTEXT_KEYS 11 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema FILES INDEX_LENGTH 31 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema FILES INITIAL_SIZE 17 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema FILES LAST_ACCESS_TIME 22 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema FILES LAST_UPDATE_TIME 21 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema FILES LOGFILE_GROUP_NAME 8 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema FILES LOGFILE_GROUP_NUMBER 9 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4)
+NULL information_schema FILES MAXIMUM_SIZE 18 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema FILES MAX_DATA_LENGTH 30 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema FILES RECOVER_TIME 23 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4)
+NULL information_schema FILES ROW_FORMAT 26 NULL YES varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10)
+NULL information_schema FILES STATUS 37 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20)
+NULL information_schema FILES TABLESPACE_NAME 4 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema FILES TABLE_CATALOG 5 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema FILES TABLE_NAME 7 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema FILES TABLE_ROWS 27 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema FILES TABLE_SCHEMA 6 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema FILES TOTAL_EXTENTS 15 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4)
+NULL information_schema FILES TRANSACTION_COUNTER 24 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4)
+NULL information_schema FILES UPDATE_COUNT 13 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(4)
+NULL information_schema FILES UPDATE_TIME 34 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema FILES VERSION 25 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema GLOBAL_STATUS VARIABLE_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema GLOBAL_STATUS VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema GLOBAL_VARIABLES VARIABLE_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema GLOBAL_VARIABLES VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema INDEX_STATISTICS INDEX_NAME 3 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INDEX_STATISTICS ROWS_READ 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema INDEX_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INDEX_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_BUFFER_PAGE ACCESS_TIME 10 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE BLOCK_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE COMPRESSED_SIZE 15 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE DATA_SIZE 14 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE FIX_COUNT 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE FLUSH_TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE FREE_PAGE_CLOCK 19 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE INDEX_NAME 12 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema INNODB_BUFFER_PAGE IO_FIX 17 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema INNODB_BUFFER_PAGE IS_HASHED 7 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema INNODB_BUFFER_PAGE IS_OLD 18 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema INNODB_BUFFER_PAGE NEWEST_MODIFICATION 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE NUMBER_RECORDS 13 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE OLDEST_MODIFICATION 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE PAGE_NUMBER 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE PAGE_STATE 16 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema INNODB_BUFFER_PAGE PAGE_TYPE 4 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema INNODB_BUFFER_PAGE SPACE 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE TABLE_NAME 11 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema INNODB_BUFFER_PAGE_LRU ACCESS_TIME 10 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE_LRU COMPRESSED 16 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema INNODB_BUFFER_PAGE_LRU COMPRESSED_SIZE 15 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE_LRU DATA_SIZE 14 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE_LRU FIX_COUNT 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE_LRU FLUSH_TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE_LRU FREE_PAGE_CLOCK 19 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE_LRU INDEX_NAME 12 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema INNODB_BUFFER_PAGE_LRU IO_FIX 17 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema INNODB_BUFFER_PAGE_LRU IS_HASHED 7 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema INNODB_BUFFER_PAGE_LRU IS_OLD 18 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema INNODB_BUFFER_PAGE_LRU LRU_POSITION 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE_LRU NEWEST_MODIFICATION 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE_LRU NUMBER_RECORDS 13 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE_LRU OLDEST_MODIFICATION 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE_LRU PAGE_NUMBER 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE_LRU PAGE_TYPE 4 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema INNODB_BUFFER_PAGE_LRU SPACE 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_PAGE_LRU TABLE_NAME 11 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema INNODB_BUFFER_POOL_PAGES fix_count 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES flush_type 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES lru_position 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES page_no 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES page_type 1 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema INNODB_BUFFER_POOL_PAGES space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB compressed 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB fix_count 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB flush_type 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB lru_position 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB next_page_no 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB page_no 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB part_len 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB space_id 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX access_time 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX data_size 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX dirty 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX fix_count 12 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX flush_type 13 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX hashed 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX index_id 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX lru_position 11 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX modified 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX n_recs 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX old 10 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX page_no 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS DATABASE_PAGES 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS FREE_BUFFERS 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS HIT_RATE 21 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS LRU_IO_CURRENT 29 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS LRU_IO_TOTAL 28 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS MODIFIED_DATABASE_PAGES 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS NOT_YOUNG_MAKE_PER_THOUSAND_GETS 23 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_CREATED 15 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_GET 20 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_READ 14 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_READ_AHEAD 24 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_PAGES_WRITTEN 16 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS NUMBER_READ_AHEAD_EVICTED 25 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS OLD_DATABASE_PAGES 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_CREATE_RATE 18 0 NO double NULL NULL 12 NULL NULL NULL NULL double
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_MADE_NOT_YOUNG_RATE 13 0 NO double NULL NULL 12 NULL NULL NULL NULL double
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_MADE_YOUNG 10 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_MADE_YOUNG_RATE 12 0 NO double NULL NULL 12 NULL NULL NULL NULL double
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_NOT_MADE_YOUNG 11 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_READ_RATE 17 0 NO double NULL NULL 12 NULL NULL NULL NULL double
+NULL information_schema INNODB_BUFFER_POOL_STATS PAGES_WRITTEN_RATE 19 0 NO double NULL NULL 12 NULL NULL NULL NULL double
+NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_DECOMPRESS 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_FLUSH_LIST 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_FLUSH_LRU 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS PENDING_READS 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS POOL_SIZE 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS READ_AHEAD_EVICTED_RATE 27 0 NO double NULL NULL 12 NULL NULL NULL NULL double
+NULL information_schema INNODB_BUFFER_POOL_STATS READ_AHEAD_RATE 26 0 NO double NULL NULL 12 NULL NULL NULL NULL double
+NULL information_schema INNODB_BUFFER_POOL_STATS UNCOMPRESS_CURRENT 31 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS UNCOMPRESS_TOTAL 30 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_STATS YOUNG_MAKE_PER_THOUSAND_GETS 22 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_CHANGED_PAGES end_lsn 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_CHANGED_PAGES page_id 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned
+NULL information_schema INNODB_CHANGED_PAGES space_id 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned
+NULL information_schema INNODB_CHANGED_PAGES start_lsn 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_CMP compress_ops 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP compress_ops_ok 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP compress_time 4 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP page_size 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(5)
+NULL information_schema INNODB_CMP uncompress_ops 5 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP uncompress_time 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMPMEM pages_free 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMPMEM pages_used 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMPMEM page_size 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(5)
+NULL information_schema INNODB_CMPMEM relocation_ops 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema INNODB_CMPMEM relocation_time 5 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMPMEM_RESET pages_free 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMPMEM_RESET pages_used 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMPMEM_RESET page_size 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(5)
+NULL information_schema INNODB_CMPMEM_RESET relocation_ops 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema INNODB_CMPMEM_RESET relocation_time 5 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP_RESET compress_ops 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP_RESET compress_ops_ok 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP_RESET compress_time 4 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP_RESET page_size 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(5)
+NULL information_schema INNODB_CMP_RESET uncompress_ops 5 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP_RESET uncompress_time 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_INDEX_STATS fields 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_INDEX_STATS index_name 3 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_INDEX_STATS index_size 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_INDEX_STATS leaf_pages 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_INDEX_STATS row_per_keys 5 NO varchar 256 768 NULL NULL NULL utf8 utf8_general_ci varchar(256)
+NULL information_schema INNODB_INDEX_STATS table_name 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_INDEX_STATS table_schema 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_LOCKS lock_data 10 NULL YES varchar 8192 24576 NULL NULL NULL utf8 utf8_general_ci varchar(8192)
+NULL information_schema INNODB_LOCKS lock_id 1 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81)
+NULL information_schema INNODB_LOCKS lock_index 6 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema INNODB_LOCKS lock_mode 3 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema INNODB_LOCKS lock_page 8 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_LOCKS lock_rec 9 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_LOCKS lock_space 7 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_LOCKS lock_table 5 NO varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema INNODB_LOCKS lock_trx_id 2 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18)
+NULL information_schema INNODB_LOCKS lock_type 4 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema INNODB_LOCK_WAITS blocking_lock_id 4 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81)
+NULL information_schema INNODB_LOCK_WAITS blocking_trx_id 3 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18)
+NULL information_schema INNODB_LOCK_WAITS requested_lock_id 2 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81)
+NULL information_schema INNODB_LOCK_WAITS requesting_trx_id 1 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18)
+NULL information_schema INNODB_RSEG curr_size 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_RSEG max_size 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_RSEG page_no 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_RSEG rseg_id 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_RSEG space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_RSEG zip_size 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES ID 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES NAME 3 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_SYS_INDEXES N_FIELDS 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES PAGE_NO 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES SPACE 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES TABLE_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS DIFF_VALS 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS INDEX_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS KEY_COLS 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS NON_NULL_VALS 4 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES CLUSTER_NAME 8 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_SYS_TABLES ID 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES MIX_ID 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES MIX_LEN 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES NAME 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_SYS_TABLES N_COLS 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES SCHEMA 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_SYS_TABLES SPACE 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_TABLE_STATS clust_size 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_TABLE_STATS modified 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_TABLE_STATS other_size 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_TABLE_STATS rows 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_TABLE_STATS table_name 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_TABLE_STATS table_schema 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_TRX trx_id 1 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18)
+NULL information_schema INNODB_TRX trx_mysql_thread_id 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_TRX trx_query 8 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema INNODB_TRX trx_requested_lock_id 4 NULL YES varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81)
+NULL information_schema INNODB_TRX trx_started 3 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema INNODB_TRX trx_state 2 NO varchar 13 39 NULL NULL NULL utf8 utf8_general_ci varchar(13)
+NULL information_schema INNODB_TRX trx_wait_started 5 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema INNODB_TRX trx_weight 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES BLOCK_SIZE 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES DIRTY_BLOCKS 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES FULL_SIZE 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES KEY_CACHE_NAME 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema KEY_CACHES READS 10 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES READ_REQUESTS 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES SEGMENTS 2 NULL YES int NULL NULL 10 0 NULL NULL NULL int(3) unsigned
+NULL information_schema KEY_CACHES SEGMENT_NUMBER 3 NULL YES int NULL NULL 10 0 NULL NULL NULL int(3) unsigned
+NULL information_schema KEY_CACHES UNUSED_BLOCKS 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES USED_BLOCKS 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES WRITES 12 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES WRITE_REQUESTS 11 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_COLUMN_USAGE COLUMN_NAME 7 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema KEY_COLUMN_USAGE ORDINAL_POSITION 8 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(10)
+NULL information_schema KEY_COLUMN_USAGE POSITION_IN_UNIQUE_CONSTRAINT 9 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(10)
+NULL information_schema KEY_COLUMN_USAGE REFERENCED_COLUMN_NAME 12 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_NAME 11 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_SCHEMA 10 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema KEY_COLUMN_USAGE TABLE_CATALOG 4 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema KEY_COLUMN_USAGE TABLE_NAME 6 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema KEY_COLUMN_USAGE TABLE_SCHEMA 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema PARTITIONS AVG_ROW_LENGTH 14 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema PARTITIONS CHECKSUM 22 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema PARTITIONS CHECK_TIME 21 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema PARTITIONS CREATE_TIME 19 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema PARTITIONS DATA_FREE 18 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema PARTITIONS DATA_LENGTH 15 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema PARTITIONS INDEX_LENGTH 17 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema PARTITIONS MAX_DATA_LENGTH 16 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema PARTITIONS NODEGROUP 24 NO varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12)
+NULL information_schema PARTITIONS PARTITION_COMMENT 23 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80)
+NULL information_schema PARTITIONS PARTITION_DESCRIPTION 12 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema PARTITIONS PARTITION_EXPRESSION 10 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema PARTITIONS PARTITION_METHOD 8 NULL YES varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12)
+NULL information_schema PARTITIONS PARTITION_NAME 4 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema PARTITIONS PARTITION_ORDINAL_POSITION 6 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema PARTITIONS SUBPARTITION_EXPRESSION 11 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema PARTITIONS SUBPARTITION_METHOD 9 NULL YES varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12)
+NULL information_schema PARTITIONS SUBPARTITION_NAME 5 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema PARTITIONS SUBPARTITION_ORDINAL_POSITION 7 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema PARTITIONS TABLESPACE_NAME 25 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema PARTITIONS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema PARTITIONS TABLE_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema PARTITIONS TABLE_ROWS 13 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema PARTITIONS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema PARTITIONS UPDATE_TIME 20 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema PLUGINS PLUGIN_AUTH_VERSION 12 NULL YES varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80)
+NULL information_schema PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20)
+NULL information_schema PLUGINS PLUGIN_LICENSE 10 NULL YES varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80)
+NULL information_schema PLUGINS PLUGIN_MATURITY 11 NULL YES varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12)
+NULL information_schema PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10)
+NULL information_schema PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80)
+NULL information_schema PLUGINS PLUGIN_TYPE_VERSION 5 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20)
+NULL information_schema PLUGINS PLUGIN_VERSION 2 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20)
+NULL information_schema PROCESSLIST COMMAND 5 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16)
+NULL information_schema PROCESSLIST DB 4 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema PROCESSLIST HOST 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema PROCESSLIST ID 1 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4)
+NULL information_schema PROCESSLIST INFO 8 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema PROCESSLIST MAX_STAGE 11 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2)
+NULL information_schema PROCESSLIST PROGRESS 12 0.000 NO decimal NULL NULL 7 3 NULL NULL NULL decimal(7,3)
+NULL information_schema PROCESSLIST STAGE 10 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2)
+NULL information_schema PROCESSLIST STATE 7 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema PROCESSLIST TIME 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(7)
+NULL information_schema PROCESSLIST TIME_MS 9 0.000 NO decimal NULL NULL 22 3 NULL NULL NULL decimal(22,3)
+NULL information_schema PROCESSLIST USER 2 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16)
+NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema REFERENTIAL_CONSTRAINTS DELETE_RULE 9 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema REFERENTIAL_CONSTRAINTS MATCH_OPTION 7 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema REFERENTIAL_CONSTRAINTS REFERENCED_TABLE_NAME 11 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema REFERENTIAL_CONSTRAINTS TABLE_NAME 10 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_CATALOG 4 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_NAME 6 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema REFERENTIAL_CONSTRAINTS UNIQUE_CONSTRAINT_SCHEMA 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema REFERENTIAL_CONSTRAINTS UPDATE_RULE 8 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema ROUTINES CHARACTER_SET_CLIENT 21 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema ROUTINES COLLATION_CONNECTION 22 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema ROUTINES CREATED 16 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema ROUTINES DATABASE_COLLATION 23 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema ROUTINES DEFINER 20 NO varchar 77 231 NULL NULL NULL utf8 utf8_general_ci varchar(77)
+NULL information_schema ROUTINES DTD_IDENTIFIER 6 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema ROUTINES EXTERNAL_LANGUAGE 10 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema ROUTINES EXTERNAL_NAME 9 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema ROUTINES IS_DETERMINISTIC 12 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema ROUTINES LAST_ALTERED 17 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema ROUTINES PARAMETER_STYLE 11 NO varchar 8 24 NULL NULL NULL utf8 utf8_general_ci varchar(8)
+NULL information_schema ROUTINES ROUTINE_BODY 7 NO varchar 8 24 NULL NULL NULL utf8 utf8_general_ci varchar(8)
+NULL information_schema ROUTINES ROUTINE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema ROUTINES ROUTINE_COMMENT 19 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema ROUTINES ROUTINE_DEFINITION 8 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema ROUTINES ROUTINE_NAME 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema ROUTINES ROUTINE_SCHEMA 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema ROUTINES ROUTINE_TYPE 5 NO varchar 9 27 NULL NULL NULL utf8 utf8_general_ci varchar(9)
+NULL information_schema ROUTINES SECURITY_TYPE 15 NO varchar 7 21 NULL NULL NULL utf8 utf8_general_ci varchar(7)
+NULL information_schema ROUTINES SPECIFIC_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema ROUTINES SQL_DATA_ACCESS 13 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema ROUTINES SQL_MODE 18 NO varchar 8192 24576 NULL NULL NULL utf8 utf8_general_ci varchar(8192)
+NULL information_schema ROUTINES SQL_PATH 14 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema SCHEMATA CATALOG_NAME 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema SCHEMATA DEFAULT_CHARACTER_SET_NAME 3 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema SCHEMATA DEFAULT_COLLATION_NAME 4 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema SCHEMATA SCHEMA_NAME 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema SCHEMATA SQL_PATH 5 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema SCHEMA_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81)
+NULL information_schema SCHEMA_PRIVILEGES IS_GRANTABLE 5 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema SCHEMA_PRIVILEGES PRIVILEGE_TYPE 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema SCHEMA_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema SCHEMA_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema SESSION_STATUS VARIABLE_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema SESSION_STATUS VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema SESSION_VARIABLES VARIABLE_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema SESSION_VARIABLES VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema STATISTICS CARDINALITY 10 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema STATISTICS COLLATION 9 NULL YES varchar 1 3 NULL NULL NULL utf8 utf8_general_ci varchar(1)
+NULL information_schema STATISTICS COLUMN_NAME 8 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema STATISTICS COMMENT 15 NULL YES varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16)
+NULL information_schema STATISTICS INDEX_NAME 6 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema STATISTICS INDEX_SCHEMA 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema STATISTICS INDEX_TYPE 14 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16)
+NULL information_schema STATISTICS NON_UNIQUE 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(1)
+NULL information_schema STATISTICS NULLABLE 13 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema STATISTICS PACKED 12 NULL YES varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10)
+NULL information_schema STATISTICS SEQ_IN_INDEX 7 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(2)
+NULL information_schema STATISTICS SUB_PART 11 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(3)
+NULL information_schema STATISTICS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema STATISTICS TABLE_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema STATISTICS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLES AUTO_INCREMENT 14 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema TABLES AVG_ROW_LENGTH 9 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema TABLES CHECKSUM 19 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema TABLES CHECK_TIME 17 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema TABLES CREATE_OPTIONS 20 NULL YES varchar 255 765 NULL NULL NULL utf8 utf8_general_ci varchar(255)
+NULL information_schema TABLES CREATE_TIME 15 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema TABLES DATA_FREE 13 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema TABLES DATA_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema TABLES ENGINE 5 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLES INDEX_LENGTH 12 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema TABLES MAX_DATA_LENGTH 11 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema TABLES ROW_FORMAT 7 NULL YES varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10)
+NULL information_schema TABLES TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema TABLES TABLE_COLLATION 18 NULL YES varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema TABLES TABLE_COMMENT 21 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80)
+NULL information_schema TABLES TABLE_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLES TABLE_ROWS 8 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema TABLES TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLES TABLE_TYPE 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLES UPDATE_TIME 16 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema TABLES VERSION 6 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_TYPE 6 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLE_CONSTRAINTS TABLE_NAME 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLE_CONSTRAINTS TABLE_SCHEMA 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLE_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81)
+NULL information_schema TABLE_PRIVILEGES IS_GRANTABLE 6 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema TABLE_PRIVILEGES PRIVILEGE_TYPE 5 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLE_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema TABLE_PRIVILEGES TABLE_NAME 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLE_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLE_STATISTICS ROWS_CHANGED 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema TABLE_STATISTICS ROWS_CHANGED_X_INDEXES 5 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema TABLE_STATISTICS ROWS_READ 3 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema TABLE_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema TABLE_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema TRIGGERS ACTION_CONDITION 9 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema TRIGGERS ACTION_ORDER 8 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4)
+NULL information_schema TRIGGERS ACTION_ORIENTATION 11 NO varchar 9 27 NULL NULL NULL utf8 utf8_general_ci varchar(9)
+NULL information_schema TRIGGERS ACTION_REFERENCE_NEW_ROW 16 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema TRIGGERS ACTION_REFERENCE_NEW_TABLE 14 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TRIGGERS ACTION_REFERENCE_OLD_ROW 15 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema TRIGGERS ACTION_REFERENCE_OLD_TABLE 13 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TRIGGERS ACTION_STATEMENT 10 NULL NO longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema TRIGGERS ACTION_TIMING 12 NO varchar 6 18 NULL NULL NULL utf8 utf8_general_ci varchar(6)
+NULL information_schema TRIGGERS CHARACTER_SET_CLIENT 20 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema TRIGGERS COLLATION_CONNECTION 21 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema TRIGGERS CREATED 17 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema TRIGGERS DATABASE_COLLATION 22 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema TRIGGERS DEFINER 19 NO varchar 77 231 NULL NULL NULL utf8 utf8_general_ci varchar(77)
+NULL information_schema TRIGGERS EVENT_MANIPULATION 4 NO varchar 6 18 NULL NULL NULL utf8 utf8_general_ci varchar(6)
+NULL information_schema TRIGGERS EVENT_OBJECT_CATALOG 5 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema TRIGGERS EVENT_OBJECT_SCHEMA 6 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TRIGGERS EVENT_OBJECT_TABLE 7 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TRIGGERS SQL_MODE 18 NO varchar 8192 24576 NULL NULL NULL utf8 utf8_general_ci varchar(8192)
+NULL information_schema TRIGGERS TRIGGER_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema TRIGGERS TRIGGER_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TRIGGERS TRIGGER_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema USER_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81)
+NULL information_schema USER_PRIVILEGES IS_GRANTABLE 4 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema USER_PRIVILEGES PRIVILEGE_TYPE 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema USER_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema USER_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL NULL double
+NULL information_schema USER_STATISTICS BYTES_RECEIVED 7 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS BYTES_SENT 8 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS COMMIT_TRANSACTIONS 18 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema USER_STATISTICS CONNECTED_TIME 4 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema USER_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL NULL double
+NULL information_schema USER_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_INSERTED 13 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_READ 10 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_SENT 11 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_UPDATED 14 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS SELECT_COMMANDS 15 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS TOTAL_CONNECTIONS 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema USER_STATISTICS UPDATE_COMMANDS 16 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS USER 1 NO varchar 48 144 NULL NULL NULL utf8 utf8_general_ci varchar(48)
+NULL information_schema VIEWS CHARACTER_SET_CLIENT 9 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema VIEWS CHECK_OPTION 5 NO varchar 8 24 NULL NULL NULL utf8 utf8_general_ci varchar(8)
+NULL information_schema VIEWS COLLATION_CONNECTION 10 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema VIEWS DEFINER 7 NO varchar 77 231 NULL NULL NULL utf8 utf8_general_ci varchar(77)
+NULL information_schema VIEWS IS_UPDATABLE 6 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
+NULL information_schema VIEWS SECURITY_TYPE 8 NO varchar 7 21 NULL NULL NULL utf8 utf8_general_ci varchar(7)
+NULL information_schema VIEWS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema VIEWS TABLE_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema VIEWS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema VIEWS VIEW_DEFINITION 4 NULL NO longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema XTRADB_ADMIN_COMMAND result_message 1 NO varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
@@ -597,6 +601,7 @@ NULL datetime NULL NULL
NULL decimal NULL NULL
NULL double NULL NULL
NULL int NULL NULL
+NULL tinyint NULL NULL
--> CHAR(0) is allowed (see manual), and here both CHARACHTER_* values
--> are 0, which is intended behavior, and the result of 0 / 0 IS NULL
SELECT CHARACTER_OCTET_LENGTH / CHARACTER_MAXIMUM_LENGTH AS COL_CML,
@@ -661,6 +666,7 @@ NULL information_schema COLUMNS CHARACTER_MAXIMUM_LENGTH bigint NULL NULL NULL N
NULL information_schema COLUMNS CHARACTER_OCTET_LENGTH bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema COLUMNS NUMERIC_PRECISION bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema COLUMNS NUMERIC_SCALE bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema COLUMNS DATETIME_PRECISION bigint NULL NULL NULL NULL bigint(21) unsigned
3.0000 information_schema COLUMNS CHARACTER_SET_NAME varchar 32 96 utf8 utf8_general_ci varchar(32)
3.0000 information_schema COLUMNS COLLATION_NAME varchar 32 96 utf8 utf8_general_ci varchar(32)
1.0000 information_schema COLUMNS COLUMN_TYPE longtext 4294967295 4294967295 utf8 utf8_general_ci longtext
@@ -1004,6 +1010,9 @@ NULL information_schema PROCESSLIST TIME int NULL NULL NULL NULL int(7)
3.0000 information_schema PROCESSLIST STATE varchar 64 192 utf8 utf8_general_ci varchar(64)
1.0000 information_schema PROCESSLIST INFO longtext 4294967295 4294967295 utf8 utf8_general_ci longtext
NULL information_schema PROCESSLIST TIME_MS decimal NULL NULL NULL NULL decimal(22,3)
+NULL information_schema PROCESSLIST STAGE tinyint NULL NULL NULL NULL tinyint(2)
+NULL information_schema PROCESSLIST MAX_STAGE tinyint NULL NULL NULL NULL tinyint(2)
+NULL information_schema PROCESSLIST PROGRESS decimal NULL NULL NULL NULL decimal(7,3)
3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512)
3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
diff --git a/mysql-test/suite/funcs_1/r/is_columns_memory.result b/mysql-test/suite/funcs_1/r/is_columns_memory.result
index c476b930f60..fb6c8fd728a 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_memory.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_memory.result
@@ -377,318 +377,318 @@ LOAD DATA INFILE '<MYSQLTEST_VARDIR>/std_data/funcs_1/t9.txt' INTO TABLE t9;
SELECT * FROM information_schema.columns
WHERE table_schema LIKE 'test%'
ORDER BY table_schema, table_name, column_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL test t1 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t1 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t1 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t1 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t1 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t1 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t10 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t10 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t10 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t10 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t10 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t10 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t11 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t11 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t11 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t11 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t11 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t11 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t2 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t2 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t2 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t2 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t2 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t2 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t3 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t3 f2 2 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t3 f3 3 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t4 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t4 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t4 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t4 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t4 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t4 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t7 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t7 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t7 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t7 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t8 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t8 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t8 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t8 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t9 f1 1 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t9 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t9 f3 3 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test tb1 f1 1 NULL YES char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
-NULL test tb1 f12 4 NULL YES binary 1 1 NULL NULL NULL NULL binary(1) select,insert,update,references
-NULL test tb1 f13 5 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(4) select,insert,update,references
-NULL test tb1 f14 6 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned select,insert,update,references
-NULL test tb1 f15 7 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
-NULL test tb1 f16 8 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
-NULL test tb1 f17 9 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(6) select,insert,update,references
-NULL test tb1 f18 10 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned select,insert,update,references
-NULL test tb1 f19 11 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill select,insert,update,references
-NULL test tb1 f2 2 NULL YES char 1 1 NULL NULL latin1 latin1_bin char(1) select,insert,update,references
-NULL test tb1 f20 12 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill select,insert,update,references
-NULL test tb1 f21 13 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(9) select,insert,update,references
-NULL test tb1 f22 14 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned select,insert,update,references
-NULL test tb1 f23 15 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
-NULL test tb1 f24 16 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
-NULL test tb1 f25 17 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test tb1 f26 18 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL test tb1 f27 19 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
-NULL test tb1 f28 20 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
-NULL test tb1 f29 21 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references
-NULL test tb1 f3 3 NULL YES char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
-NULL test tb1 f30 22 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL test tb1 f31 23 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb1 f32 24 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb1 f33 25 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f34 26 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb1 f35 27 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f36 28 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f37 29 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f38 30 10 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) select,insert,update,references
-NULL test tb1 f39 31 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb1 f40 32 10 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test tb1 f41 33 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f42 34 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f43 35 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f44 36 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f45 37 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f46 38 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test tb1 f47 39 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb1 f48 40 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test tb1 f49 41 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f50 42 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb1 f51 43 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f52 44 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb1 f53 45 99 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f54 46 99 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb1 f55 47 0000000099 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f56 48 0000000099 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f57 49 99 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f58 50 99 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) select,insert,update,references
-NULL test tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL NULL NULL time select,insert,update,references
-NULL test tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
-NULL test tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL NULL NULL timestamp select,insert,update,references
-NULL test tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb2 f108 50 1enum NO enum 5 5 NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
-NULL test tb2 f109 51 1set NO set 9 9 NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
-NULL test tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb3 f118 1 a NO char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
-NULL test tb3 f119 2  NO char 1 1 NULL NULL latin1 latin1_bin char(1) select,insert,update,references
-NULL test tb3 f120 3  NO char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
-NULL test tb3 f121 4 NULL YES char 50 50 NULL NULL latin1 latin1_swedish_ci char(50) select,insert,update,references
-NULL test tb3 f122 5 NULL YES char 50 50 NULL NULL latin1 latin1_swedish_ci char(50) select,insert,update,references
-NULL test tb3 f129 6  NO binary 1 1 NULL NULL NULL NULL binary(1) select,insert,update,references
-NULL test tb3 f130 7 99 NO tinyint NULL NULL 3 0 NULL NULL tinyint(4) select,insert,update,references
-NULL test tb3 f131 8 99 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned select,insert,update,references
-NULL test tb3 f132 9 099 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
-NULL test tb3 f133 10 099 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
-NULL test tb3 f134 11 999 NO smallint NULL NULL 5 0 NULL NULL smallint(6) select,insert,update,references
-NULL test tb3 f135 12 999 NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned select,insert,update,references
-NULL test tb3 f136 13 00999 NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill select,insert,update,references
-NULL test tb3 f137 14 00999 NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill select,insert,update,references
-NULL test tb3 f138 15 9999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(9) select,insert,update,references
-NULL test tb3 f139 16 9999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned select,insert,update,references
-NULL test tb3 f140 17 00009999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
-NULL test tb3 f141 18 00009999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
-NULL test tb3 f142 19 99999 NO int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test tb3 f143 20 99999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL test tb3 f144 21 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
-NULL test tb3 f145 22 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
-NULL test tb3 f146 23 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references
-NULL test tb3 f147 24 999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL test tb3 f148 25 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb3 f149 26 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb3 f150 27 1000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f151 28 999 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb3 f152 29 0000001000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f153 30 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f154 31 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f155 32 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) select,insert,update,references
-NULL test tb3 f156 33 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb3 f157 34 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test tb3 f158 35 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f159 36 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f160 37 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f161 38 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f162 39 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f163 40 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test tb3 f164 41 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb3 f165 42 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test tb3 f166 43 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f167 44 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb3 f168 45 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f169 46 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb3 f170 47 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f171 48 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb3 f172 49 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f173 50 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f174 51 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f175 52 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) select,insert,update,references
-NULL test tb4 f176 1 9 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb4 f177 2 9 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test tb4 f178 3 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f179 4 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f180 5 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f181 6 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f182 7 9 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb4 f183 8 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test tb4 f184 9 9 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb4 f185 10 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test tb4 f186 11 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f187 12 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb4 f188 13 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f189 14 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb4 f190 15 88.8 NO double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb4 f191 16 88.8 NO double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb4 f192 17 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f193 18 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f194 19 55.5 NO double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb4 f195 20 55.5 NO double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb4 f196 21 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f197 22 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f198 23 NULL YES float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb4 f199 24 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb4 f200 25 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f201 26 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f202 27 NULL YES float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb4 f203 28 NULL YES float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb4 f204 29 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb4 f205 30 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb4 f206 31 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f207 32 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f208 33 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f209 34 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f210 35 NULL YES float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb4 f211 36 NULL YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb4 f212 37 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb4 f213 38 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb4 f214 39 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f215 40 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f216 41 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f217 42 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f218 43 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test tb4 f219 44 NULL YES time NULL NULL NULL NULL NULL NULL time select,insert,update,references
-NULL test tb4 f220 45 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
-NULL test tb4 f221 46 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
-NULL test tb4 f222 47 NULL YES year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb4 f223 48 NULL YES year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb4 f224 49 NULL YES year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb4 f225 50 NULL YES enum 5 5 NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
-NULL test tb4 f226 51 NULL YES set 9 9 NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
-NULL test tb4 f236 52 NULL YES char 95 95 NULL NULL latin1 latin1_swedish_ci char(95) select,insert,update,references
-NULL test tb4 f237 54 NULL YES char 130 130 NULL NULL latin1 latin1_bin char(130) select,insert,update,references
-NULL test tb4 f238 55 NULL YES varchar 25000 25000 NULL NULL latin1 latin1_bin varchar(25000) select,insert,update,references
-NULL test tb4 f239 56 NULL YES varbinary 0 0 NULL NULL NULL NULL varbinary(0) select,insert,update,references
-NULL test tb4 f240 57 NULL YES varchar 1200 1200 NULL NULL latin1 latin1_swedish_ci varchar(1200) select,insert,update,references
-NULL test tb4 f241 53 NULL YES char 255 255 NULL NULL latin1 latin1_swedish_ci char(255) select,insert,update,references
-NULL test1 tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test1 tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL NULL NULL time select,insert,update,references
-NULL test1 tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
-NULL test1 tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL NULL NULL timestamp select,insert,update,references
-NULL test1 tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test1 tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test1 tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test1 tb2 f108 50 1enum NO enum 5 5 NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
-NULL test1 tb2 f109 51 1set NO set 9 9 NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
-NULL test1 tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test1 tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test1 tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test1 tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test1 tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test1 tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test1 tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test1 tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test1 tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test1 tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test1 tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test1 tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test1 tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test1 tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test1 tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test1 tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test1 tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test1 tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test1 tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test1 tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test1 tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test4 t6 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test4 t6 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test4 t6 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test4 t6 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test4 t6 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test4 t6 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL test t1 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t1 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t1 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t1 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t1 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t1 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t10 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t10 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t10 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t10 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t10 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t10 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t11 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t11 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t11 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t11 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t11 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t11 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t2 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t2 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t2 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t2 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t2 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t2 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t3 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t3 f2 2 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t3 f3 3 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t4 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t4 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t4 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t4 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t4 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t4 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t7 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t7 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t7 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t7 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t8 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t8 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t8 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t8 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t9 f1 1 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t9 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t9 f3 3 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test tb1 f1 1 NULL YES char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
+NULL test tb1 f12 4 NULL YES binary 1 1 NULL NULL NULL NULL NULL binary(1) select,insert,update,references
+NULL test tb1 f13 5 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(4) select,insert,update,references
+NULL test tb1 f14 6 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned select,insert,update,references
+NULL test tb1 f15 7 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
+NULL test tb1 f16 8 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
+NULL test tb1 f17 9 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(6) select,insert,update,references
+NULL test tb1 f18 10 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned select,insert,update,references
+NULL test tb1 f19 11 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill select,insert,update,references
+NULL test tb1 f2 2 NULL YES char 1 1 NULL NULL NULL latin1 latin1_bin char(1) select,insert,update,references
+NULL test tb1 f20 12 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill select,insert,update,references
+NULL test tb1 f21 13 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(9) select,insert,update,references
+NULL test tb1 f22 14 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned select,insert,update,references
+NULL test tb1 f23 15 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
+NULL test tb1 f24 16 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
+NULL test tb1 f25 17 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test tb1 f26 18 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
+NULL test tb1 f27 19 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill select,insert,update,references
+NULL test tb1 f28 20 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill select,insert,update,references
+NULL test tb1 f29 21 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(20) select,insert,update,references
+NULL test tb1 f3 3 NULL YES char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
+NULL test tb1 f30 22 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references
+NULL test tb1 f31 23 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb1 f32 24 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb1 f33 25 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f34 26 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb1 f35 27 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f36 28 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f37 29 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f38 30 10 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) select,insert,update,references
+NULL test tb1 f39 31 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb1 f40 32 10 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test tb1 f41 33 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f42 34 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f43 35 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f44 36 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f45 37 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f46 38 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test tb1 f47 39 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb1 f48 40 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test tb1 f49 41 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f50 42 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb1 f51 43 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f52 44 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb1 f53 45 99 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f54 46 99 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb1 f55 47 0000000099 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f56 48 0000000099 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f57 49 99 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f58 50 99 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) select,insert,update,references
+NULL test tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL 0 NULL NULL time select,insert,update,references
+NULL test tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references
+NULL test tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp select,insert,update,references
+NULL test tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb2 f108 50 1enum NO enum 5 5 NULL NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
+NULL test tb2 f109 51 1set NO set 9 9 NULL NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
+NULL test tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb3 f118 1 a NO char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
+NULL test tb3 f119 2  NO char 1 1 NULL NULL NULL latin1 latin1_bin char(1) select,insert,update,references
+NULL test tb3 f120 3  NO char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
+NULL test tb3 f121 4 NULL YES char 50 50 NULL NULL NULL latin1 latin1_swedish_ci char(50) select,insert,update,references
+NULL test tb3 f122 5 NULL YES char 50 50 NULL NULL NULL latin1 latin1_swedish_ci char(50) select,insert,update,references
+NULL test tb3 f129 6  NO binary 1 1 NULL NULL NULL NULL NULL binary(1) select,insert,update,references
+NULL test tb3 f130 7 99 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(4) select,insert,update,references
+NULL test tb3 f131 8 99 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned select,insert,update,references
+NULL test tb3 f132 9 099 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
+NULL test tb3 f133 10 099 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
+NULL test tb3 f134 11 999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(6) select,insert,update,references
+NULL test tb3 f135 12 999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned select,insert,update,references
+NULL test tb3 f136 13 00999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill select,insert,update,references
+NULL test tb3 f137 14 00999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill select,insert,update,references
+NULL test tb3 f138 15 9999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(9) select,insert,update,references
+NULL test tb3 f139 16 9999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned select,insert,update,references
+NULL test tb3 f140 17 00009999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
+NULL test tb3 f141 18 00009999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
+NULL test tb3 f142 19 99999 NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test tb3 f143 20 99999 NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
+NULL test tb3 f144 21 0000099999 NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill select,insert,update,references
+NULL test tb3 f145 22 0000099999 NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill select,insert,update,references
+NULL test tb3 f146 23 999999 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(20) select,insert,update,references
+NULL test tb3 f147 24 999999 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references
+NULL test tb3 f148 25 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb3 f149 26 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb3 f150 27 1000 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f151 28 999 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb3 f152 29 0000001000 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f153 30 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f154 31 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f155 32 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) select,insert,update,references
+NULL test tb3 f156 33 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb3 f157 34 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test tb3 f158 35 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f159 36 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f160 37 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f161 38 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f162 39 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f163 40 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test tb3 f164 41 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb3 f165 42 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test tb3 f166 43 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f167 44 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb3 f168 45 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f169 46 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb3 f170 47 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f171 48 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb3 f172 49 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f173 50 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f174 51 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f175 52 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) select,insert,update,references
+NULL test tb4 f176 1 9 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb4 f177 2 9 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test tb4 f178 3 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f179 4 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f180 5 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f181 6 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f182 7 9 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb4 f183 8 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test tb4 f184 9 9 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb4 f185 10 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test tb4 f186 11 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f187 12 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb4 f188 13 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f189 14 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb4 f190 15 88.8 NO double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb4 f191 16 88.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb4 f192 17 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f193 18 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f194 19 55.5 NO double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb4 f195 20 55.5 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb4 f196 21 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f197 22 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f198 23 NULL YES float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb4 f199 24 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb4 f200 25 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f201 26 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f202 27 NULL YES float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb4 f203 28 NULL YES float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb4 f204 29 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb4 f205 30 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb4 f206 31 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f207 32 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f208 33 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f209 34 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f210 35 NULL YES float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb4 f211 36 NULL YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb4 f212 37 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb4 f213 38 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb4 f214 39 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f215 40 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f216 41 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f217 42 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f218 43 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test tb4 f219 44 NULL YES time NULL NULL NULL NULL 0 NULL NULL time select,insert,update,references
+NULL test tb4 f220 45 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references
+NULL test tb4 f221 46 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
+NULL test tb4 f222 47 NULL YES year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb4 f223 48 NULL YES year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb4 f224 49 NULL YES year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb4 f225 50 NULL YES enum 5 5 NULL NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
+NULL test tb4 f226 51 NULL YES set 9 9 NULL NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
+NULL test tb4 f236 52 NULL YES char 95 95 NULL NULL NULL latin1 latin1_swedish_ci char(95) select,insert,update,references
+NULL test tb4 f237 54 NULL YES char 130 130 NULL NULL NULL latin1 latin1_bin char(130) select,insert,update,references
+NULL test tb4 f238 55 NULL YES varchar 25000 25000 NULL NULL NULL latin1 latin1_bin varchar(25000) select,insert,update,references
+NULL test tb4 f239 56 NULL YES varbinary 0 0 NULL NULL NULL NULL NULL varbinary(0) select,insert,update,references
+NULL test tb4 f240 57 NULL YES varchar 1200 1200 NULL NULL NULL latin1 latin1_swedish_ci varchar(1200) select,insert,update,references
+NULL test tb4 f241 53 NULL YES char 255 255 NULL NULL NULL latin1 latin1_swedish_ci char(255) select,insert,update,references
+NULL test1 tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test1 tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL 0 NULL NULL time select,insert,update,references
+NULL test1 tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references
+NULL test1 tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp select,insert,update,references
+NULL test1 tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test1 tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test1 tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test1 tb2 f108 50 1enum NO enum 5 5 NULL NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
+NULL test1 tb2 f109 51 1set NO set 9 9 NULL NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
+NULL test1 tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test1 tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test1 tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test1 tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test1 tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test1 tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test1 tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test1 tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test1 tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test1 tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test1 tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test1 tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test1 tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test1 tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test1 tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test1 tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test1 tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test1 tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test1 tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test1 tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test1 tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test4 t6 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test4 t6 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test4 t6 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test4 t6 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test4 t6 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test4 t6 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
diff --git a/mysql-test/suite/funcs_1/r/is_columns_myisam.result b/mysql-test/suite/funcs_1/r/is_columns_myisam.result
index 0e464d0fbc1..d0c409798dc 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_myisam.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_myisam.result
@@ -417,358 +417,358 @@ LOAD DATA INFILE '<MYSQLTEST_VARDIR>/std_data/funcs_1/t9.txt' INTO TABLE t9;
SELECT * FROM information_schema.columns
WHERE table_schema LIKE 'test%'
ORDER BY table_schema, table_name, column_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL test t1 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t1 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t1 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t1 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t1 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t1 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t10 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t10 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t10 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t10 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t10 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t10 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t11 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t11 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t11 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t11 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t11 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t11 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t2 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t2 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t2 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t2 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t2 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t2 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t3 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t3 f2 2 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t3 f3 3 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t4 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t4 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t4 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t4 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t4 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t4 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t7 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t7 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t7 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t7 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t8 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test t8 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t8 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test t8 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t9 f1 1 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test t9 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test t9 f3 3 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test tb1 f1 1 NULL YES char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
-NULL test tb1 f10 10 NULL YES mediumblob 16777215 16777215 NULL NULL NULL NULL mediumblob select,insert,update,references
-NULL test tb1 f11 11 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL longblob select,insert,update,references
-NULL test tb1 f12 12 NULL YES binary 1 1 NULL NULL NULL NULL binary(1) select,insert,update,references
-NULL test tb1 f13 13 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(4) select,insert,update,references
-NULL test tb1 f14 14 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned select,insert,update,references
-NULL test tb1 f15 15 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
-NULL test tb1 f16 16 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
-NULL test tb1 f17 17 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(6) select,insert,update,references
-NULL test tb1 f18 18 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned select,insert,update,references
-NULL test tb1 f19 19 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill select,insert,update,references
-NULL test tb1 f2 2 NULL YES char 1 1 NULL NULL latin1 latin1_bin char(1) select,insert,update,references
-NULL test tb1 f20 20 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill select,insert,update,references
-NULL test tb1 f21 21 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(9) select,insert,update,references
-NULL test tb1 f22 22 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned select,insert,update,references
-NULL test tb1 f23 23 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
-NULL test tb1 f24 24 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
-NULL test tb1 f25 25 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test tb1 f26 26 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL test tb1 f27 27 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
-NULL test tb1 f28 28 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
-NULL test tb1 f29 29 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references
-NULL test tb1 f3 3 NULL YES char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
-NULL test tb1 f30 30 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL test tb1 f31 31 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb1 f32 32 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb1 f33 33 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f34 34 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb1 f35 35 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f36 36 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f37 37 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f38 38 10 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) select,insert,update,references
-NULL test tb1 f39 39 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb1 f4 4 NULL YES tinytext 255 255 NULL NULL latin1 latin1_swedish_ci tinytext select,insert,update,references
-NULL test tb1 f40 40 10 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test tb1 f41 41 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f42 42 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f43 43 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f44 44 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f45 45 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f46 46 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test tb1 f47 47 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb1 f48 48 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test tb1 f49 49 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f5 5 NULL YES text 65535 65535 NULL NULL latin1 latin1_swedish_ci text select,insert,update,references
-NULL test tb1 f50 50 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb1 f51 51 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f52 52 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb1 f53 53 99 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f54 54 99 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb1 f55 55 0000000099 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f56 56 0000000099 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb1 f57 57 99 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb1 f58 58 99 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) select,insert,update,references
-NULL test tb1 f6 6 NULL YES mediumtext 16777215 16777215 NULL NULL latin1 latin1_swedish_ci mediumtext select,insert,update,references
-NULL test tb1 f7 7 NULL YES longtext 4294967295 4294967295 NULL NULL latin1 latin1_swedish_ci longtext select,insert,update,references
-NULL test tb1 f8 8 NULL YES tinyblob 255 255 NULL NULL NULL NULL tinyblob select,insert,update,references
-NULL test tb1 f9 9 NULL YES blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references
-NULL test tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL NULL NULL time select,insert,update,references
-NULL test tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
-NULL test tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL NULL NULL timestamp select,insert,update,references
-NULL test tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb2 f108 50 1enum NO enum 5 5 NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
-NULL test tb2 f109 51 1set NO set 9 9 NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
-NULL test tb2 f110 52 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64) select,insert,update,references
-NULL test tb2 f111 53 NULL YES varbinary 27 27 NULL NULL NULL NULL varbinary(27) select,insert,update,references
-NULL test tb2 f112 54 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64) select,insert,update,references
-NULL test tb2 f113 55 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192) select,insert,update,references
-NULL test tb2 f114 56 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192) select,insert,update,references
-NULL test tb2 f115 57 NULL YES varbinary 27 27 NULL NULL NULL NULL varbinary(27) select,insert,update,references
-NULL test tb2 f116 58 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64) select,insert,update,references
-NULL test tb2 f117 59 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192) select,insert,update,references
-NULL test tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb3 f118 1 a NO char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
-NULL test tb3 f119 2  NO char 1 1 NULL NULL latin1 latin1_bin char(1) select,insert,update,references
-NULL test tb3 f120 3  NO char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
-NULL test tb3 f121 4 NULL YES tinytext 255 255 NULL NULL latin1 latin1_swedish_ci tinytext select,insert,update,references
-NULL test tb3 f122 5 NULL YES text 65535 65535 NULL NULL latin1 latin1_swedish_ci text select,insert,update,references
-NULL test tb3 f123 6 NULL YES mediumtext 16777215 16777215 NULL NULL latin1 latin1_swedish_ci mediumtext select,insert,update,references
-NULL test tb3 f124 7 NULL YES longtext 4294967295 4294967295 NULL NULL latin1 latin1_swedish_ci longtext select,insert,update,references
-NULL test tb3 f125 8 NULL YES tinyblob 255 255 NULL NULL NULL NULL tinyblob select,insert,update,references
-NULL test tb3 f126 9 NULL YES blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references
-NULL test tb3 f127 10 NULL YES mediumblob 16777215 16777215 NULL NULL NULL NULL mediumblob select,insert,update,references
-NULL test tb3 f128 11 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL longblob select,insert,update,references
-NULL test tb3 f129 12  NO binary 1 1 NULL NULL NULL NULL binary(1) select,insert,update,references
-NULL test tb3 f130 13 99 NO tinyint NULL NULL 3 0 NULL NULL tinyint(4) select,insert,update,references
-NULL test tb3 f131 14 99 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned select,insert,update,references
-NULL test tb3 f132 15 099 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
-NULL test tb3 f133 16 099 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
-NULL test tb3 f134 17 999 NO smallint NULL NULL 5 0 NULL NULL smallint(6) select,insert,update,references
-NULL test tb3 f135 18 999 NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned select,insert,update,references
-NULL test tb3 f136 19 00999 NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill select,insert,update,references
-NULL test tb3 f137 20 00999 NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill select,insert,update,references
-NULL test tb3 f138 21 9999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(9) select,insert,update,references
-NULL test tb3 f139 22 9999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned select,insert,update,references
-NULL test tb3 f140 23 00009999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
-NULL test tb3 f141 24 00009999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
-NULL test tb3 f142 25 99999 NO int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test tb3 f143 26 99999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL test tb3 f144 27 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
-NULL test tb3 f145 28 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
-NULL test tb3 f146 29 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references
-NULL test tb3 f147 30 999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb3 f150 33 1000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f151 34 999 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb3 f152 35 0000001000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f153 36 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f154 37 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f155 38 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) select,insert,update,references
-NULL test tb3 f156 39 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb3 f157 40 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test tb3 f158 41 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f159 42 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f160 43 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f161 44 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f162 45 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f163 46 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test tb3 f164 47 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb3 f165 48 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test tb3 f166 49 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f167 50 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb3 f168 51 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f169 52 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb3 f170 53 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f171 54 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb3 f172 55 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f173 56 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb3 f174 57 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb3 f175 58 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) select,insert,update,references
-NULL test tb4 f176 1 9 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb4 f177 2 9 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test tb4 f178 3 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f179 4 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f180 5 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f181 6 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f182 7 9 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test tb4 f183 8 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test tb4 f184 9 9 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test tb4 f185 10 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test tb4 f186 11 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f187 12 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb4 f188 13 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test tb4 f189 14 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test tb4 f190 15 88.8 NO double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb4 f191 16 88.8 NO double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb4 f192 17 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f193 18 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f194 19 55.5 NO double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb4 f195 20 55.5 NO double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb4 f196 21 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f197 22 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f198 23 NULL YES float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb4 f199 24 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb4 f200 25 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f201 26 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f202 27 NULL YES float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb4 f203 28 NULL YES float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb4 f204 29 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb4 f205 30 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb4 f206 31 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f207 32 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f208 33 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f209 34 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f210 35 NULL YES float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test tb4 f211 36 NULL YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test tb4 f212 37 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test tb4 f213 38 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test tb4 f214 39 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f215 40 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f216 41 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test tb4 f217 42 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test tb4 f218 43 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test tb4 f219 44 NULL YES time NULL NULL NULL NULL NULL NULL time select,insert,update,references
-NULL test tb4 f220 45 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
-NULL test tb4 f221 46 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
-NULL test tb4 f222 47 NULL YES year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb4 f223 48 NULL YES year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb4 f224 49 NULL YES year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test tb4 f225 50 NULL YES enum 5 5 NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
-NULL test tb4 f226 51 NULL YES set 9 9 NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
-NULL test tb4 f227 52 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64) select,insert,update,references
-NULL test tb4 f228 53 NULL YES varbinary 27 27 NULL NULL NULL NULL varbinary(27) select,insert,update,references
-NULL test tb4 f229 54 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64) select,insert,update,references
-NULL test tb4 f230 55 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192) select,insert,update,references
-NULL test tb4 f231 56 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192) select,insert,update,references
-NULL test tb4 f232 57 NULL YES varbinary 27 27 NULL NULL NULL NULL varbinary(27) select,insert,update,references
-NULL test tb4 f233 58 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64) select,insert,update,references
-NULL test tb4 f234 59 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192) select,insert,update,references
-NULL test tb4 f235 60 NULL YES char 255 255 NULL NULL latin1 latin1_swedish_ci char(255) select,insert,update,references
-NULL test tb4 f236 61 NULL YES char 60 60 NULL NULL latin1 latin1_swedish_ci char(60) select,insert,update,references
-NULL test tb4 f237 62 NULL YES char 255 255 NULL NULL latin1 latin1_bin char(255) select,insert,update,references
-NULL test tb4 f238 63 NULL YES varchar 0 0 NULL NULL latin1 latin1_bin varchar(0) select,insert,update,references
-NULL test tb4 f239 64 NULL YES varbinary 1000 1000 NULL NULL NULL NULL varbinary(1000) select,insert,update,references
-NULL test tb4 f240 65 NULL YES varchar 120 120 NULL NULL latin1 latin1_swedish_ci varchar(120) select,insert,update,references
-NULL test tb4 f241 66 NULL YES char 100 100 NULL NULL latin1 latin1_swedish_ci char(100) select,insert,update,references
-NULL test tb4 f242 67 NULL YES bit NULL NULL 30 NULL NULL NULL bit(30) select,insert,update,references
-NULL test1 tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test1 tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL NULL NULL time select,insert,update,references
-NULL test1 tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
-NULL test1 tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL NULL NULL timestamp select,insert,update,references
-NULL test1 tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test1 tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test1 tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
-NULL test1 tb2 f108 50 1enum NO enum 5 5 NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
-NULL test1 tb2 f109 51 1set NO set 9 9 NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
-NULL test1 tb2 f110 52 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64) select,insert,update,references
-NULL test1 tb2 f111 53 NULL YES varbinary 27 27 NULL NULL NULL NULL varbinary(27) select,insert,update,references
-NULL test1 tb2 f112 54 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64) select,insert,update,references
-NULL test1 tb2 f113 55 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192) select,insert,update,references
-NULL test1 tb2 f114 56 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192) select,insert,update,references
-NULL test1 tb2 f115 57 NULL YES varbinary 27 27 NULL NULL NULL NULL varbinary(27) select,insert,update,references
-NULL test1 tb2 f116 58 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64) select,insert,update,references
-NULL test1 tb2 f117 59 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192) select,insert,update,references
-NULL test1 tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test1 tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned select,insert,update,references
-NULL test1 tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
-NULL test1 tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) select,insert,update,references
-NULL test1 tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
-NULL test1 tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned select,insert,update,references
-NULL test1 tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
-NULL test1 tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test1 tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test1 tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test1 tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test1 tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test1 tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test1 tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test1 tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test1 tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test1 tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test1 tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL float select,insert,update,references
-NULL test1 tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL double select,insert,update,references
-NULL test1 tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned select,insert,update,references
-NULL test1 tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL double unsigned select,insert,update,references
-NULL test1 tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test1 tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill select,insert,update,references
-NULL test1 tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill select,insert,update,references
-NULL test4 t6 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
-NULL test4 t6 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test4 t6 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references
-NULL test4 t6 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL test4 t6 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
-NULL test4 t6 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL test t1 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t1 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t1 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t1 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t1 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t1 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t10 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t10 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t10 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t10 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t10 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t10 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t11 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t11 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t11 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t11 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t11 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t11 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t2 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t2 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t2 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t2 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t2 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t2 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t3 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t3 f2 2 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t3 f3 3 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t4 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t4 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t4 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t4 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t4 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t4 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t7 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t7 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t7 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t7 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t8 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test t8 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t8 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test t8 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t9 f1 1 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test t9 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test t9 f3 3 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test tb1 f1 1 NULL YES char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
+NULL test tb1 f10 10 NULL YES mediumblob 16777215 16777215 NULL NULL NULL NULL NULL mediumblob select,insert,update,references
+NULL test tb1 f11 11 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob select,insert,update,references
+NULL test tb1 f12 12 NULL YES binary 1 1 NULL NULL NULL NULL NULL binary(1) select,insert,update,references
+NULL test tb1 f13 13 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(4) select,insert,update,references
+NULL test tb1 f14 14 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned select,insert,update,references
+NULL test tb1 f15 15 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
+NULL test tb1 f16 16 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
+NULL test tb1 f17 17 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(6) select,insert,update,references
+NULL test tb1 f18 18 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned select,insert,update,references
+NULL test tb1 f19 19 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill select,insert,update,references
+NULL test tb1 f2 2 NULL YES char 1 1 NULL NULL NULL latin1 latin1_bin char(1) select,insert,update,references
+NULL test tb1 f20 20 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill select,insert,update,references
+NULL test tb1 f21 21 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(9) select,insert,update,references
+NULL test tb1 f22 22 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned select,insert,update,references
+NULL test tb1 f23 23 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
+NULL test tb1 f24 24 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
+NULL test tb1 f25 25 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test tb1 f26 26 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
+NULL test tb1 f27 27 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill select,insert,update,references
+NULL test tb1 f28 28 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill select,insert,update,references
+NULL test tb1 f29 29 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(20) select,insert,update,references
+NULL test tb1 f3 3 NULL YES char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
+NULL test tb1 f30 30 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references
+NULL test tb1 f31 31 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb1 f32 32 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb1 f33 33 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f34 34 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb1 f35 35 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f36 36 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f37 37 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f38 38 10 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) select,insert,update,references
+NULL test tb1 f39 39 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb1 f4 4 NULL YES tinytext 255 255 NULL NULL NULL latin1 latin1_swedish_ci tinytext select,insert,update,references
+NULL test tb1 f40 40 10 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test tb1 f41 41 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f42 42 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f43 43 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f44 44 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f45 45 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f46 46 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test tb1 f47 47 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb1 f48 48 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test tb1 f49 49 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f5 5 NULL YES text 65535 65535 NULL NULL NULL latin1 latin1_swedish_ci text select,insert,update,references
+NULL test tb1 f50 50 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb1 f51 51 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f52 52 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb1 f53 53 99 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f54 54 99 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb1 f55 55 0000000099 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f56 56 0000000099 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb1 f57 57 99 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb1 f58 58 99 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) select,insert,update,references
+NULL test tb1 f6 6 NULL YES mediumtext 16777215 16777215 NULL NULL NULL latin1 latin1_swedish_ci mediumtext select,insert,update,references
+NULL test tb1 f7 7 NULL YES longtext 4294967295 4294967295 NULL NULL NULL latin1 latin1_swedish_ci longtext select,insert,update,references
+NULL test tb1 f8 8 NULL YES tinyblob 255 255 NULL NULL NULL NULL NULL tinyblob select,insert,update,references
+NULL test tb1 f9 9 NULL YES blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references
+NULL test tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL 0 NULL NULL time select,insert,update,references
+NULL test tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references
+NULL test tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp select,insert,update,references
+NULL test tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb2 f108 50 1enum NO enum 5 5 NULL NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
+NULL test tb2 f109 51 1set NO set 9 9 NULL NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
+NULL test tb2 f110 52 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64) select,insert,update,references
+NULL test tb2 f111 53 NULL YES varbinary 27 27 NULL NULL NULL NULL NULL varbinary(27) select,insert,update,references
+NULL test tb2 f112 54 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64) select,insert,update,references
+NULL test tb2 f113 55 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192) select,insert,update,references
+NULL test tb2 f114 56 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192) select,insert,update,references
+NULL test tb2 f115 57 NULL YES varbinary 27 27 NULL NULL NULL NULL NULL varbinary(27) select,insert,update,references
+NULL test tb2 f116 58 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64) select,insert,update,references
+NULL test tb2 f117 59 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192) select,insert,update,references
+NULL test tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb3 f118 1 a NO char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
+NULL test tb3 f119 2  NO char 1 1 NULL NULL NULL latin1 latin1_bin char(1) select,insert,update,references
+NULL test tb3 f120 3  NO char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
+NULL test tb3 f121 4 NULL YES tinytext 255 255 NULL NULL NULL latin1 latin1_swedish_ci tinytext select,insert,update,references
+NULL test tb3 f122 5 NULL YES text 65535 65535 NULL NULL NULL latin1 latin1_swedish_ci text select,insert,update,references
+NULL test tb3 f123 6 NULL YES mediumtext 16777215 16777215 NULL NULL NULL latin1 latin1_swedish_ci mediumtext select,insert,update,references
+NULL test tb3 f124 7 NULL YES longtext 4294967295 4294967295 NULL NULL NULL latin1 latin1_swedish_ci longtext select,insert,update,references
+NULL test tb3 f125 8 NULL YES tinyblob 255 255 NULL NULL NULL NULL NULL tinyblob select,insert,update,references
+NULL test tb3 f126 9 NULL YES blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references
+NULL test tb3 f127 10 NULL YES mediumblob 16777215 16777215 NULL NULL NULL NULL NULL mediumblob select,insert,update,references
+NULL test tb3 f128 11 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob select,insert,update,references
+NULL test tb3 f129 12  NO binary 1 1 NULL NULL NULL NULL NULL binary(1) select,insert,update,references
+NULL test tb3 f130 13 99 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(4) select,insert,update,references
+NULL test tb3 f131 14 99 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned select,insert,update,references
+NULL test tb3 f132 15 099 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
+NULL test tb3 f133 16 099 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill select,insert,update,references
+NULL test tb3 f134 17 999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(6) select,insert,update,references
+NULL test tb3 f135 18 999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned select,insert,update,references
+NULL test tb3 f136 19 00999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill select,insert,update,references
+NULL test tb3 f137 20 00999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill select,insert,update,references
+NULL test tb3 f138 21 9999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(9) select,insert,update,references
+NULL test tb3 f139 22 9999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned select,insert,update,references
+NULL test tb3 f140 23 00009999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
+NULL test tb3 f141 24 00009999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill select,insert,update,references
+NULL test tb3 f142 25 99999 NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test tb3 f143 26 99999 NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
+NULL test tb3 f144 27 0000099999 NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill select,insert,update,references
+NULL test tb3 f145 28 0000099999 NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill select,insert,update,references
+NULL test tb3 f146 29 999999 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(20) select,insert,update,references
+NULL test tb3 f147 30 999999 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references
+NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb3 f150 33 1000 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f151 34 999 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb3 f152 35 0000001000 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f153 36 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f154 37 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f155 38 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) select,insert,update,references
+NULL test tb3 f156 39 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb3 f157 40 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test tb3 f158 41 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f159 42 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f160 43 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f161 44 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f162 45 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f163 46 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test tb3 f164 47 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb3 f165 48 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test tb3 f166 49 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f167 50 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb3 f168 51 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f169 52 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb3 f170 53 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f171 54 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb3 f172 55 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f173 56 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb3 f174 57 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb3 f175 58 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) select,insert,update,references
+NULL test tb4 f176 1 9 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb4 f177 2 9 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test tb4 f178 3 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f179 4 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f180 5 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f181 6 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f182 7 9 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test tb4 f183 8 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test tb4 f184 9 9 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test tb4 f185 10 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test tb4 f186 11 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f187 12 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb4 f188 13 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test tb4 f189 14 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test tb4 f190 15 88.8 NO double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb4 f191 16 88.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb4 f192 17 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f193 18 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f194 19 55.5 NO double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb4 f195 20 55.5 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb4 f196 21 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f197 22 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f198 23 NULL YES float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb4 f199 24 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb4 f200 25 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f201 26 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f202 27 NULL YES float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb4 f203 28 NULL YES float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb4 f204 29 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb4 f205 30 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb4 f206 31 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f207 32 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f208 33 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f209 34 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f210 35 NULL YES float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test tb4 f211 36 NULL YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test tb4 f212 37 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test tb4 f213 38 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test tb4 f214 39 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f215 40 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f216 41 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test tb4 f217 42 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test tb4 f218 43 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test tb4 f219 44 NULL YES time NULL NULL NULL NULL 0 NULL NULL time select,insert,update,references
+NULL test tb4 f220 45 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references
+NULL test tb4 f221 46 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
+NULL test tb4 f222 47 NULL YES year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb4 f223 48 NULL YES year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb4 f224 49 NULL YES year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test tb4 f225 50 NULL YES enum 5 5 NULL NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
+NULL test tb4 f226 51 NULL YES set 9 9 NULL NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
+NULL test tb4 f227 52 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64) select,insert,update,references
+NULL test tb4 f228 53 NULL YES varbinary 27 27 NULL NULL NULL NULL NULL varbinary(27) select,insert,update,references
+NULL test tb4 f229 54 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64) select,insert,update,references
+NULL test tb4 f230 55 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192) select,insert,update,references
+NULL test tb4 f231 56 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192) select,insert,update,references
+NULL test tb4 f232 57 NULL YES varbinary 27 27 NULL NULL NULL NULL NULL varbinary(27) select,insert,update,references
+NULL test tb4 f233 58 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64) select,insert,update,references
+NULL test tb4 f234 59 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192) select,insert,update,references
+NULL test tb4 f235 60 NULL YES char 255 255 NULL NULL NULL latin1 latin1_swedish_ci char(255) select,insert,update,references
+NULL test tb4 f236 61 NULL YES char 60 60 NULL NULL NULL latin1 latin1_swedish_ci char(60) select,insert,update,references
+NULL test tb4 f237 62 NULL YES char 255 255 NULL NULL NULL latin1 latin1_bin char(255) select,insert,update,references
+NULL test tb4 f238 63 NULL YES varchar 0 0 NULL NULL NULL latin1 latin1_bin varchar(0) select,insert,update,references
+NULL test tb4 f239 64 NULL YES varbinary 1000 1000 NULL NULL NULL NULL NULL varbinary(1000) select,insert,update,references
+NULL test tb4 f240 65 NULL YES varchar 120 120 NULL NULL NULL latin1 latin1_swedish_ci varchar(120) select,insert,update,references
+NULL test tb4 f241 66 NULL YES char 100 100 NULL NULL NULL latin1 latin1_swedish_ci char(100) select,insert,update,references
+NULL test tb4 f242 67 NULL YES bit NULL NULL 30 NULL NULL NULL NULL bit(30) select,insert,update,references
+NULL test1 tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test1 tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL 0 NULL NULL time select,insert,update,references
+NULL test1 tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references
+NULL test1 tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp select,insert,update,references
+NULL test1 tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test1 tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test1 tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4) select,insert,update,references
+NULL test1 tb2 f108 50 1enum NO enum 5 5 NULL NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum') select,insert,update,references
+NULL test1 tb2 f109 51 1set NO set 9 9 NULL NULL NULL latin1 latin1_swedish_ci set('1set','2set') select,insert,update,references
+NULL test1 tb2 f110 52 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64) select,insert,update,references
+NULL test1 tb2 f111 53 NULL YES varbinary 27 27 NULL NULL NULL NULL NULL varbinary(27) select,insert,update,references
+NULL test1 tb2 f112 54 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64) select,insert,update,references
+NULL test1 tb2 f113 55 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192) select,insert,update,references
+NULL test1 tb2 f114 56 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192) select,insert,update,references
+NULL test1 tb2 f115 57 NULL YES varbinary 27 27 NULL NULL NULL NULL NULL varbinary(27) select,insert,update,references
+NULL test1 tb2 f116 58 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64) select,insert,update,references
+NULL test1 tb2 f117 59 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192) select,insert,update,references
+NULL test1 tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test1 tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned select,insert,update,references
+NULL test1 tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) select,insert,update,references
+NULL test1 tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) select,insert,update,references
+NULL test1 tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned select,insert,update,references
+NULL test1 tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned select,insert,update,references
+NULL test1 tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill select,insert,update,references
+NULL test1 tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test1 tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test1 tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test1 tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test1 tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test1 tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test1 tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test1 tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test1 tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test1 tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test1 tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float select,insert,update,references
+NULL test1 tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double select,insert,update,references
+NULL test1 tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned select,insert,update,references
+NULL test1 tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned select,insert,update,references
+NULL test1 tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test1 tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill select,insert,update,references
+NULL test1 tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill select,insert,update,references
+NULL test4 t6 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20) select,insert,update,references
+NULL test4 t6 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test4 t6 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date select,insert,update,references
+NULL test4 t6 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL test4 t6 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25) select,insert,update,references
+NULL test4 t6 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
diff --git a/mysql-test/suite/funcs_1/r/is_columns_myisam_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_myisam_embedded.result
index 7424ba8573d..9242ce1cb53 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_myisam_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_myisam_embedded.result
@@ -417,358 +417,358 @@ LOAD DATA INFILE '<MYSQLTEST_VARDIR>/std_data/funcs_1/t9.txt' INTO TABLE t9;
SELECT * FROM information_schema.columns
WHERE table_schema LIKE 'test%'
ORDER BY table_schema, table_name, column_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL test t1 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20)
-NULL test t1 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test t1 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date
-NULL test t1 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t1 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test t1 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t10 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20)
-NULL test t10 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test t10 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date
-NULL test t10 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t10 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test t10 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t11 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20)
-NULL test t11 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test t11 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date
-NULL test t11 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t11 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test t11 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t2 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20)
-NULL test t2 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test t2 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date
-NULL test t2 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t2 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test t2 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t3 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20)
-NULL test t3 f2 2 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20)
-NULL test t3 f3 3 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t4 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20)
-NULL test t4 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test t4 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date
-NULL test t4 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t4 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test t4 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t7 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20)
-NULL test t7 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test t7 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date
-NULL test t7 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t8 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20)
-NULL test t8 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test t8 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date
-NULL test t8 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t9 f1 1 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test t9 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test t9 f3 3 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test tb1 f1 1 NULL YES char 1 1 NULL NULL latin1 latin1_swedish_ci char(1)
-NULL test tb1 f10 10 NULL YES mediumblob 16777215 16777215 NULL NULL NULL NULL mediumblob
-NULL test tb1 f11 11 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL longblob
-NULL test tb1 f12 12 NULL YES binary 1 1 NULL NULL NULL NULL binary(1)
-NULL test tb1 f13 13 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(4)
-NULL test tb1 f14 14 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned
-NULL test tb1 f15 15 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill
-NULL test tb1 f16 16 NULL YES tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill
-NULL test tb1 f17 17 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(6)
-NULL test tb1 f18 18 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned
-NULL test tb1 f19 19 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill
-NULL test tb1 f2 2 NULL YES char 1 1 NULL NULL latin1 latin1_bin char(1)
-NULL test tb1 f20 20 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill
-NULL test tb1 f21 21 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(9)
-NULL test tb1 f22 22 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned
-NULL test tb1 f23 23 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill
-NULL test tb1 f24 24 NULL YES mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill
-NULL test tb1 f25 25 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test tb1 f26 26 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned
-NULL test tb1 f27 27 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill
-NULL test tb1 f28 28 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill
-NULL test tb1 f29 29 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20)
-NULL test tb1 f3 3 NULL YES char 1 1 NULL NULL latin1 latin1_swedish_ci char(1)
-NULL test tb1 f30 30 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned
-NULL test tb1 f31 31 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill
-NULL test tb1 f32 32 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill
-NULL test tb1 f33 33 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0)
-NULL test tb1 f34 34 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test tb1 f35 35 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb1 f36 36 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb1 f37 37 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0)
-NULL test tb1 f38 38 10 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0)
-NULL test tb1 f39 39 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test tb1 f4 4 NULL YES tinytext 255 255 NULL NULL latin1 latin1_swedish_ci tinytext
-NULL test tb1 f40 40 10 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned
-NULL test tb1 f41 41 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb1 f42 42 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill
-NULL test tb1 f43 43 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb1 f44 44 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill
-NULL test tb1 f45 45 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0)
-NULL test tb1 f46 46 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30)
-NULL test tb1 f47 47 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test tb1 f48 48 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned
-NULL test tb1 f49 49 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb1 f5 5 NULL YES text 65535 65535 NULL NULL latin1 latin1_swedish_ci text
-NULL test tb1 f50 50 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill
-NULL test tb1 f51 51 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb1 f52 52 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill
-NULL test tb1 f53 53 99 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0)
-NULL test tb1 f54 54 99 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test tb1 f55 55 0000000099 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb1 f56 56 0000000099 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb1 f57 57 99 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0)
-NULL test tb1 f58 58 99 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0)
-NULL test tb1 f6 6 NULL YES mediumtext 16777215 16777215 NULL NULL latin1 latin1_swedish_ci mediumtext
-NULL test tb1 f7 7 NULL YES longtext 4294967295 4294967295 NULL NULL latin1 latin1_swedish_ci longtext
-NULL test tb1 f8 8 NULL YES tinyblob 255 255 NULL NULL NULL NULL tinyblob
-NULL test tb1 f9 9 NULL YES blob 65535 65535 NULL NULL NULL NULL blob
-NULL test tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL date
-NULL test tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL NULL NULL time
-NULL test tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime
-NULL test tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL NULL NULL timestamp
-NULL test tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL year(4)
-NULL test tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL year(4)
-NULL test tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL year(4)
-NULL test tb2 f108 50 1enum NO enum 5 5 NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum')
-NULL test tb2 f109 51 1set NO set 9 9 NULL NULL latin1 latin1_swedish_ci set('1set','2set')
-NULL test tb2 f110 52 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64)
-NULL test tb2 f111 53 NULL YES varbinary 27 27 NULL NULL NULL NULL varbinary(27)
-NULL test tb2 f112 54 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64)
-NULL test tb2 f113 55 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192)
-NULL test tb2 f114 56 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192)
-NULL test tb2 f115 57 NULL YES varbinary 27 27 NULL NULL NULL NULL varbinary(27)
-NULL test tb2 f116 58 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64)
-NULL test tb2 f117 59 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192)
-NULL test tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned
-NULL test tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill
-NULL test tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill
-NULL test tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0)
-NULL test tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30)
-NULL test tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned
-NULL test tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill
-NULL test tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill
-NULL test tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL double
-NULL test tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned
-NULL test tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL double
-NULL test tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL double unsigned
-NULL test tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL float
-NULL test tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned
-NULL test tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL float
-NULL test tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL float
-NULL test tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned
-NULL test tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned
-NULL test tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL float
-NULL test tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL double
-NULL test tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned
-NULL test tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL double unsigned
-NULL test tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb3 f118 1 a NO char 1 1 NULL NULL latin1 latin1_swedish_ci char(1)
-NULL test tb3 f119 2  NO char 1 1 NULL NULL latin1 latin1_bin char(1)
-NULL test tb3 f120 3  NO char 1 1 NULL NULL latin1 latin1_swedish_ci char(1)
-NULL test tb3 f121 4 NULL YES tinytext 255 255 NULL NULL latin1 latin1_swedish_ci tinytext
-NULL test tb3 f122 5 NULL YES text 65535 65535 NULL NULL latin1 latin1_swedish_ci text
-NULL test tb3 f123 6 NULL YES mediumtext 16777215 16777215 NULL NULL latin1 latin1_swedish_ci mediumtext
-NULL test tb3 f124 7 NULL YES longtext 4294967295 4294967295 NULL NULL latin1 latin1_swedish_ci longtext
-NULL test tb3 f125 8 NULL YES tinyblob 255 255 NULL NULL NULL NULL tinyblob
-NULL test tb3 f126 9 NULL YES blob 65535 65535 NULL NULL NULL NULL blob
-NULL test tb3 f127 10 NULL YES mediumblob 16777215 16777215 NULL NULL NULL NULL mediumblob
-NULL test tb3 f128 11 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL longblob
-NULL test tb3 f129 12  NO binary 1 1 NULL NULL NULL NULL binary(1)
-NULL test tb3 f130 13 99 NO tinyint NULL NULL 3 0 NULL NULL tinyint(4)
-NULL test tb3 f131 14 99 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned
-NULL test tb3 f132 15 099 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill
-NULL test tb3 f133 16 099 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned zerofill
-NULL test tb3 f134 17 999 NO smallint NULL NULL 5 0 NULL NULL smallint(6)
-NULL test tb3 f135 18 999 NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned
-NULL test tb3 f136 19 00999 NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill
-NULL test tb3 f137 20 00999 NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned zerofill
-NULL test tb3 f138 21 9999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(9)
-NULL test tb3 f139 22 9999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned
-NULL test tb3 f140 23 00009999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill
-NULL test tb3 f141 24 00009999 NO mediumint NULL NULL 7 0 NULL NULL mediumint(8) unsigned zerofill
-NULL test tb3 f142 25 99999 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL test tb3 f143 26 99999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned
-NULL test tb3 f144 27 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill
-NULL test tb3 f145 28 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill
-NULL test tb3 f146 29 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20)
-NULL test tb3 f147 30 999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned
-NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill
-NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill
-NULL test tb3 f150 33 1000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0)
-NULL test tb3 f151 34 999 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test tb3 f152 35 0000001000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb3 f153 36 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb3 f154 37 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0)
-NULL test tb3 f155 38 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0)
-NULL test tb3 f156 39 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test tb3 f157 40 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned
-NULL test tb3 f158 41 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb3 f159 42 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill
-NULL test tb3 f160 43 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb3 f161 44 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill
-NULL test tb3 f162 45 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0)
-NULL test tb3 f163 46 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30)
-NULL test tb3 f164 47 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test tb3 f165 48 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned
-NULL test tb3 f166 49 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb3 f167 50 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill
-NULL test tb3 f168 51 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb3 f169 52 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill
-NULL test tb3 f170 53 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0)
-NULL test tb3 f171 54 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test tb3 f172 55 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb3 f173 56 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb3 f174 57 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0)
-NULL test tb3 f175 58 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0)
-NULL test tb4 f176 1 9 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test tb4 f177 2 9 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned
-NULL test tb4 f178 3 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb4 f179 4 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill
-NULL test tb4 f180 5 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb4 f181 6 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill
-NULL test tb4 f182 7 9 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0)
-NULL test tb4 f183 8 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30)
-NULL test tb4 f184 9 9 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test tb4 f185 10 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned
-NULL test tb4 f186 11 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb4 f187 12 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill
-NULL test tb4 f188 13 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test tb4 f189 14 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill
-NULL test tb4 f190 15 88.8 NO double NULL NULL 22 NULL NULL NULL double
-NULL test tb4 f191 16 88.8 NO double NULL NULL 22 NULL NULL NULL double unsigned
-NULL test tb4 f192 17 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test tb4 f193 18 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test tb4 f194 19 55.5 NO double NULL NULL 22 NULL NULL NULL double
-NULL test tb4 f195 20 55.5 NO double NULL NULL 22 NULL NULL NULL double unsigned
-NULL test tb4 f196 21 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test tb4 f197 22 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test tb4 f198 23 NULL YES float NULL NULL 12 NULL NULL NULL float
-NULL test tb4 f199 24 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned
-NULL test tb4 f200 25 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb4 f201 26 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb4 f202 27 NULL YES float NULL NULL 12 NULL NULL NULL float
-NULL test tb4 f203 28 NULL YES float NULL NULL 12 NULL NULL NULL float
-NULL test tb4 f204 29 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned
-NULL test tb4 f205 30 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned
-NULL test tb4 f206 31 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb4 f207 32 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb4 f208 33 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb4 f209 34 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb4 f210 35 NULL YES float NULL NULL 12 NULL NULL NULL float
-NULL test tb4 f211 36 NULL YES double NULL NULL 22 NULL NULL NULL double
-NULL test tb4 f212 37 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned
-NULL test tb4 f213 38 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned
-NULL test tb4 f214 39 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb4 f215 40 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test tb4 f216 41 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test tb4 f217 42 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test tb4 f218 43 NULL YES date NULL NULL NULL NULL NULL NULL date
-NULL test tb4 f219 44 NULL YES time NULL NULL NULL NULL NULL NULL time
-NULL test tb4 f220 45 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL test tb4 f221 46 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP
-NULL test tb4 f222 47 NULL YES year NULL NULL NULL NULL NULL NULL year(4)
-NULL test tb4 f223 48 NULL YES year NULL NULL NULL NULL NULL NULL year(4)
-NULL test tb4 f224 49 NULL YES year NULL NULL NULL NULL NULL NULL year(4)
-NULL test tb4 f225 50 NULL YES enum 5 5 NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum')
-NULL test tb4 f226 51 NULL YES set 9 9 NULL NULL latin1 latin1_swedish_ci set('1set','2set')
-NULL test tb4 f227 52 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64)
-NULL test tb4 f228 53 NULL YES varbinary 27 27 NULL NULL NULL NULL varbinary(27)
-NULL test tb4 f229 54 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64)
-NULL test tb4 f230 55 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192)
-NULL test tb4 f231 56 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192)
-NULL test tb4 f232 57 NULL YES varbinary 27 27 NULL NULL NULL NULL varbinary(27)
-NULL test tb4 f233 58 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64)
-NULL test tb4 f234 59 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192)
-NULL test tb4 f235 60 NULL YES char 255 255 NULL NULL latin1 latin1_swedish_ci char(255)
-NULL test tb4 f236 61 NULL YES char 60 60 NULL NULL latin1 latin1_swedish_ci char(60)
-NULL test tb4 f237 62 NULL YES char 255 255 NULL NULL latin1 latin1_bin char(255)
-NULL test tb4 f238 63 NULL YES varchar 0 0 NULL NULL latin1 latin1_bin varchar(0)
-NULL test tb4 f239 64 NULL YES varbinary 1000 1000 NULL NULL NULL NULL varbinary(1000)
-NULL test tb4 f240 65 NULL YES varchar 120 120 NULL NULL latin1 latin1_swedish_ci varchar(120)
-NULL test tb4 f241 66 NULL YES char 100 100 NULL NULL latin1 latin1_swedish_ci char(100)
-NULL test tb4 f242 67 NULL YES bit NULL NULL 30 NULL NULL NULL bit(30)
-NULL test1 tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test1 tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL date
-NULL test1 tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL NULL NULL time
-NULL test1 tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime
-NULL test1 tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL NULL NULL timestamp
-NULL test1 tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL year(4)
-NULL test1 tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL year(4)
-NULL test1 tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL year(4)
-NULL test1 tb2 f108 50 1enum NO enum 5 5 NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum')
-NULL test1 tb2 f109 51 1set NO set 9 9 NULL NULL latin1 latin1_swedish_ci set('1set','2set')
-NULL test1 tb2 f110 52 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64)
-NULL test1 tb2 f111 53 NULL YES varbinary 27 27 NULL NULL NULL NULL varbinary(27)
-NULL test1 tb2 f112 54 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64)
-NULL test1 tb2 f113 55 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192)
-NULL test1 tb2 f114 56 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192)
-NULL test1 tb2 f115 57 NULL YES varbinary 27 27 NULL NULL NULL NULL varbinary(27)
-NULL test1 tb2 f116 58 NULL YES varbinary 64 64 NULL NULL NULL NULL varbinary(64)
-NULL test1 tb2 f117 59 NULL YES varbinary 192 192 NULL NULL NULL NULL varbinary(192)
-NULL test1 tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test1 tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned
-NULL test1 tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test1 tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill
-NULL test1 tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test1 tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL decimal(64,0) unsigned zerofill
-NULL test1 tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0)
-NULL test1 tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30)
-NULL test1 tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned
-NULL test1 tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned
-NULL test1 tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test1 tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill
-NULL test1 tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill
-NULL test1 tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill
-NULL test1 tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL double
-NULL test1 tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned
-NULL test1 tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test1 tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test1 tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL double
-NULL test1 tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL double unsigned
-NULL test1 tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test1 tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test1 tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL float
-NULL test1 tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned
-NULL test1 tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test1 tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test1 tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL float
-NULL test1 tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL float
-NULL test1 tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned
-NULL test1 tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned
-NULL test1 tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test1 tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test1 tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test1 tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test1 tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL float
-NULL test1 tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL double
-NULL test1 tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned
-NULL test1 tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL double unsigned
-NULL test1 tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test1 tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill
-NULL test1 tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill
-NULL test4 t6 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20)
-NULL test4 t6 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test4 t6 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date
-NULL test4 t6 f4 4 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL test4 t6 f5 5 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25)
-NULL test4 t6 f6 6 NULL YES int NULL NULL 10 0 NULL NULL int(11)
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL test t1 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20)
+NULL test t1 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test t1 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date
+NULL test t1 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t1 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test t1 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t10 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20)
+NULL test t10 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test t10 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date
+NULL test t10 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t10 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test t10 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t11 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20)
+NULL test t11 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test t11 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date
+NULL test t11 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t11 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test t11 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t2 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20)
+NULL test t2 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test t2 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date
+NULL test t2 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t2 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test t2 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t3 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20)
+NULL test t3 f2 2 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20)
+NULL test t3 f3 3 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t4 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20)
+NULL test t4 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test t4 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date
+NULL test t4 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t4 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test t4 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t7 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20)
+NULL test t7 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test t7 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date
+NULL test t7 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t8 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20)
+NULL test t8 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test t8 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date
+NULL test t8 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t9 f1 1 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test t9 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test t9 f3 3 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test tb1 f1 1 NULL YES char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1)
+NULL test tb1 f10 10 NULL YES mediumblob 16777215 16777215 NULL NULL NULL NULL NULL mediumblob
+NULL test tb1 f11 11 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob
+NULL test tb1 f12 12 NULL YES binary 1 1 NULL NULL NULL NULL NULL binary(1)
+NULL test tb1 f13 13 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(4)
+NULL test tb1 f14 14 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned
+NULL test tb1 f15 15 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill
+NULL test tb1 f16 16 NULL YES tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill
+NULL test tb1 f17 17 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(6)
+NULL test tb1 f18 18 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned
+NULL test tb1 f19 19 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill
+NULL test tb1 f2 2 NULL YES char 1 1 NULL NULL NULL latin1 latin1_bin char(1)
+NULL test tb1 f20 20 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill
+NULL test tb1 f21 21 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(9)
+NULL test tb1 f22 22 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned
+NULL test tb1 f23 23 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill
+NULL test tb1 f24 24 NULL YES mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill
+NULL test tb1 f25 25 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test tb1 f26 26 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned
+NULL test tb1 f27 27 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill
+NULL test tb1 f28 28 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill
+NULL test tb1 f29 29 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(20)
+NULL test tb1 f3 3 NULL YES char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1)
+NULL test tb1 f30 30 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned
+NULL test tb1 f31 31 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill
+NULL test tb1 f32 32 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill
+NULL test tb1 f33 33 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0)
+NULL test tb1 f34 34 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test tb1 f35 35 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb1 f36 36 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb1 f37 37 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0)
+NULL test tb1 f38 38 10 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0)
+NULL test tb1 f39 39 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test tb1 f4 4 NULL YES tinytext 255 255 NULL NULL NULL latin1 latin1_swedish_ci tinytext
+NULL test tb1 f40 40 10 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned
+NULL test tb1 f41 41 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb1 f42 42 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill
+NULL test tb1 f43 43 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb1 f44 44 0000000000000000000000000000000000000000000000000000000000000010 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill
+NULL test tb1 f45 45 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0)
+NULL test tb1 f46 46 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30)
+NULL test tb1 f47 47 10 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test tb1 f48 48 9.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned
+NULL test tb1 f49 49 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb1 f5 5 NULL YES text 65535 65535 NULL NULL NULL latin1 latin1_swedish_ci text
+NULL test tb1 f50 50 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill
+NULL test tb1 f51 51 0000000010 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb1 f52 52 000000000000000000000000000000009.900000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill
+NULL test tb1 f53 53 99 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0)
+NULL test tb1 f54 54 99 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test tb1 f55 55 0000000099 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb1 f56 56 0000000099 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb1 f57 57 99 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0)
+NULL test tb1 f58 58 99 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0)
+NULL test tb1 f6 6 NULL YES mediumtext 16777215 16777215 NULL NULL NULL latin1 latin1_swedish_ci mediumtext
+NULL test tb1 f7 7 NULL YES longtext 4294967295 4294967295 NULL NULL NULL latin1 latin1_swedish_ci longtext
+NULL test tb1 f8 8 NULL YES tinyblob 255 255 NULL NULL NULL NULL NULL tinyblob
+NULL test tb1 f9 9 NULL YES blob 65535 65535 NULL NULL NULL NULL NULL blob
+NULL test tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL NULL date
+NULL test tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL 0 NULL NULL time
+NULL test tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL test tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp
+NULL test tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4)
+NULL test tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4)
+NULL test tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4)
+NULL test tb2 f108 50 1enum NO enum 5 5 NULL NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum')
+NULL test tb2 f109 51 1set NO set 9 9 NULL NULL NULL latin1 latin1_swedish_ci set('1set','2set')
+NULL test tb2 f110 52 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64)
+NULL test tb2 f111 53 NULL YES varbinary 27 27 NULL NULL NULL NULL NULL varbinary(27)
+NULL test tb2 f112 54 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64)
+NULL test tb2 f113 55 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192)
+NULL test tb2 f114 56 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192)
+NULL test tb2 f115 57 NULL YES varbinary 27 27 NULL NULL NULL NULL NULL varbinary(27)
+NULL test tb2 f116 58 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64)
+NULL test tb2 f117 59 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192)
+NULL test tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned
+NULL test tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill
+NULL test tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill
+NULL test tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0)
+NULL test tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30)
+NULL test tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned
+NULL test tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill
+NULL test tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill
+NULL test tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL NULL double
+NULL test tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned
+NULL test tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double
+NULL test tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned
+NULL test tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float
+NULL test tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned
+NULL test tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float
+NULL test tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float
+NULL test tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned
+NULL test tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned
+NULL test tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float
+NULL test tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double
+NULL test tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned
+NULL test tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned
+NULL test tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb3 f118 1 a NO char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1)
+NULL test tb3 f119 2  NO char 1 1 NULL NULL NULL latin1 latin1_bin char(1)
+NULL test tb3 f120 3  NO char 1 1 NULL NULL NULL latin1 latin1_swedish_ci char(1)
+NULL test tb3 f121 4 NULL YES tinytext 255 255 NULL NULL NULL latin1 latin1_swedish_ci tinytext
+NULL test tb3 f122 5 NULL YES text 65535 65535 NULL NULL NULL latin1 latin1_swedish_ci text
+NULL test tb3 f123 6 NULL YES mediumtext 16777215 16777215 NULL NULL NULL latin1 latin1_swedish_ci mediumtext
+NULL test tb3 f124 7 NULL YES longtext 4294967295 4294967295 NULL NULL NULL latin1 latin1_swedish_ci longtext
+NULL test tb3 f125 8 NULL YES tinyblob 255 255 NULL NULL NULL NULL NULL tinyblob
+NULL test tb3 f126 9 NULL YES blob 65535 65535 NULL NULL NULL NULL NULL blob
+NULL test tb3 f127 10 NULL YES mediumblob 16777215 16777215 NULL NULL NULL NULL NULL mediumblob
+NULL test tb3 f128 11 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob
+NULL test tb3 f129 12  NO binary 1 1 NULL NULL NULL NULL NULL binary(1)
+NULL test tb3 f130 13 99 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(4)
+NULL test tb3 f131 14 99 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned
+NULL test tb3 f132 15 099 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill
+NULL test tb3 f133 16 099 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned zerofill
+NULL test tb3 f134 17 999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(6)
+NULL test tb3 f135 18 999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned
+NULL test tb3 f136 19 00999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill
+NULL test tb3 f137 20 00999 NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned zerofill
+NULL test tb3 f138 21 9999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(9)
+NULL test tb3 f139 22 9999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned
+NULL test tb3 f140 23 00009999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill
+NULL test tb3 f141 24 00009999 NO mediumint NULL NULL 7 0 NULL NULL NULL mediumint(8) unsigned zerofill
+NULL test tb3 f142 25 99999 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test tb3 f143 26 99999 NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned
+NULL test tb3 f144 27 0000099999 NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill
+NULL test tb3 f145 28 0000099999 NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned zerofill
+NULL test tb3 f146 29 999999 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(20)
+NULL test tb3 f147 30 999999 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned
+NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill
+NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned zerofill
+NULL test tb3 f150 33 1000 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0)
+NULL test tb3 f151 34 999 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test tb3 f152 35 0000001000 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb3 f153 36 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb3 f154 37 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0)
+NULL test tb3 f155 38 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0)
+NULL test tb3 f156 39 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test tb3 f157 40 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned
+NULL test tb3 f158 41 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb3 f159 42 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill
+NULL test tb3 f160 43 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb3 f161 44 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill
+NULL test tb3 f162 45 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0)
+NULL test tb3 f163 46 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30)
+NULL test tb3 f164 47 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test tb3 f165 48 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned
+NULL test tb3 f166 49 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb3 f167 50 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill
+NULL test tb3 f168 51 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb3 f169 52 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill
+NULL test tb3 f170 53 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0)
+NULL test tb3 f171 54 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test tb3 f172 55 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb3 f173 56 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb3 f174 57 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0)
+NULL test tb3 f175 58 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0)
+NULL test tb4 f176 1 9 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test tb4 f177 2 9 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned
+NULL test tb4 f178 3 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb4 f179 4 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill
+NULL test tb4 f180 5 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb4 f181 6 0000000000000000000000000000000000000000000000000000000000000009 NO decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill
+NULL test tb4 f182 7 9 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0)
+NULL test tb4 f183 8 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30)
+NULL test tb4 f184 9 9 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test tb4 f185 10 9.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned
+NULL test tb4 f186 11 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb4 f187 12 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill
+NULL test tb4 f188 13 0000000009 NO decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test tb4 f189 14 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill
+NULL test tb4 f190 15 88.8 NO double NULL NULL 22 NULL NULL NULL NULL double
+NULL test tb4 f191 16 88.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned
+NULL test tb4 f192 17 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test tb4 f193 18 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test tb4 f194 19 55.5 NO double NULL NULL 22 NULL NULL NULL NULL double
+NULL test tb4 f195 20 55.5 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned
+NULL test tb4 f196 21 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test tb4 f197 22 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test tb4 f198 23 NULL YES float NULL NULL 12 NULL NULL NULL NULL float
+NULL test tb4 f199 24 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned
+NULL test tb4 f200 25 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb4 f201 26 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb4 f202 27 NULL YES float NULL NULL 12 NULL NULL NULL NULL float
+NULL test tb4 f203 28 NULL YES float NULL NULL 12 NULL NULL NULL NULL float
+NULL test tb4 f204 29 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned
+NULL test tb4 f205 30 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned
+NULL test tb4 f206 31 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb4 f207 32 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb4 f208 33 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb4 f209 34 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb4 f210 35 NULL YES float NULL NULL 12 NULL NULL NULL NULL float
+NULL test tb4 f211 36 NULL YES double NULL NULL 22 NULL NULL NULL NULL double
+NULL test tb4 f212 37 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned
+NULL test tb4 f213 38 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned
+NULL test tb4 f214 39 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb4 f215 40 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test tb4 f216 41 NULL YES float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test tb4 f217 42 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test tb4 f218 43 NULL YES date NULL NULL NULL NULL NULL NULL NULL date
+NULL test tb4 f219 44 NULL YES time NULL NULL NULL NULL 0 NULL NULL time
+NULL test tb4 f220 45 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL test tb4 f221 46 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP
+NULL test tb4 f222 47 NULL YES year NULL NULL NULL NULL NULL NULL NULL year(4)
+NULL test tb4 f223 48 NULL YES year NULL NULL NULL NULL NULL NULL NULL year(4)
+NULL test tb4 f224 49 NULL YES year NULL NULL NULL NULL NULL NULL NULL year(4)
+NULL test tb4 f225 50 NULL YES enum 5 5 NULL NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum')
+NULL test tb4 f226 51 NULL YES set 9 9 NULL NULL NULL latin1 latin1_swedish_ci set('1set','2set')
+NULL test tb4 f227 52 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64)
+NULL test tb4 f228 53 NULL YES varbinary 27 27 NULL NULL NULL NULL NULL varbinary(27)
+NULL test tb4 f229 54 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64)
+NULL test tb4 f230 55 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192)
+NULL test tb4 f231 56 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192)
+NULL test tb4 f232 57 NULL YES varbinary 27 27 NULL NULL NULL NULL NULL varbinary(27)
+NULL test tb4 f233 58 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64)
+NULL test tb4 f234 59 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192)
+NULL test tb4 f235 60 NULL YES char 255 255 NULL NULL NULL latin1 latin1_swedish_ci char(255)
+NULL test tb4 f236 61 NULL YES char 60 60 NULL NULL NULL latin1 latin1_swedish_ci char(60)
+NULL test tb4 f237 62 NULL YES char 255 255 NULL NULL NULL latin1 latin1_bin char(255)
+NULL test tb4 f238 63 NULL YES varchar 0 0 NULL NULL NULL latin1 latin1_bin varchar(0)
+NULL test tb4 f239 64 NULL YES varbinary 1000 1000 NULL NULL NULL NULL NULL varbinary(1000)
+NULL test tb4 f240 65 NULL YES varchar 120 120 NULL NULL NULL latin1 latin1_swedish_ci varchar(120)
+NULL test tb4 f241 66 NULL YES char 100 100 NULL NULL NULL latin1 latin1_swedish_ci char(100)
+NULL test tb4 f242 67 NULL YES bit NULL NULL 30 NULL NULL NULL NULL bit(30)
+NULL test1 tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test1 tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL NULL date
+NULL test1 tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL 0 NULL NULL time
+NULL test1 tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL test1 tb2 f104 46 2000-12-31 23:59:59 NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp
+NULL test1 tb2 f105 47 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4)
+NULL test1 tb2 f106 48 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4)
+NULL test1 tb2 f107 49 2000 NO year NULL NULL NULL NULL NULL NULL NULL year(4)
+NULL test1 tb2 f108 50 1enum NO enum 5 5 NULL NULL NULL latin1 latin1_swedish_ci enum('1enum','2enum')
+NULL test1 tb2 f109 51 1set NO set 9 9 NULL NULL NULL latin1 latin1_swedish_ci set('1set','2set')
+NULL test1 tb2 f110 52 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64)
+NULL test1 tb2 f111 53 NULL YES varbinary 27 27 NULL NULL NULL NULL NULL varbinary(27)
+NULL test1 tb2 f112 54 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64)
+NULL test1 tb2 f113 55 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192)
+NULL test1 tb2 f114 56 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192)
+NULL test1 tb2 f115 57 NULL YES varbinary 27 27 NULL NULL NULL NULL NULL varbinary(27)
+NULL test1 tb2 f116 58 NULL YES varbinary 64 64 NULL NULL NULL NULL NULL varbinary(64)
+NULL test1 tb2 f117 59 NULL YES varbinary 192 192 NULL NULL NULL NULL NULL varbinary(192)
+NULL test1 tb2 f59 1 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test1 tb2 f60 2 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned
+NULL test1 tb2 f61 3 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test1 tb2 f62 4 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill
+NULL test1 tb2 f63 5 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test1 tb2 f64 6 NULL YES decimal NULL NULL 64 0 NULL NULL NULL decimal(64,0) unsigned zerofill
+NULL test1 tb2 f65 7 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0)
+NULL test1 tb2 f66 8 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30)
+NULL test1 tb2 f67 9 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned
+NULL test1 tb2 f68 10 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned
+NULL test1 tb2 f69 11 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test1 tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill
+NULL test1 tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL NULL decimal(10,0) unsigned zerofill
+NULL test1 tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL NULL decimal(63,30) unsigned zerofill
+NULL test1 tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL NULL double
+NULL test1 tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned
+NULL test1 tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test1 tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test1 tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double
+NULL test1 tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned
+NULL test1 tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test1 tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test1 tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float
+NULL test1 tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned
+NULL test1 tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test1 tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test1 tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float
+NULL test1 tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float
+NULL test1 tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned
+NULL test1 tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned
+NULL test1 tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test1 tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test1 tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test1 tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test1 tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float
+NULL test1 tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double
+NULL test1 tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned
+NULL test1 tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned
+NULL test1 tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test1 tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL NULL double unsigned zerofill
+NULL test1 tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL NULL float unsigned zerofill
+NULL test4 t6 f1 1 NULL YES char 20 20 NULL NULL NULL latin1 latin1_swedish_ci char(20)
+NULL test4 t6 f2 2 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test4 t6 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL NULL date
+NULL test4 t6 f4 4 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL test4 t6 f5 5 NULL YES char 25 25 NULL NULL NULL latin1 latin1_swedish_ci char(25)
+NULL test4 t6 f6 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
index 30a3d047bde..8d486bae3a3 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
@@ -1,222 +1,222 @@
SELECT * FROM information_schema.columns
WHERE table_schema = 'mysql'
ORDER BY table_schema, table_name, column_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL mysql columns_priv Column_name 5 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
-NULL mysql columns_priv Column_priv 7 NO set 31 93 NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','References') select,insert,update,references
-NULL mysql columns_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
-NULL mysql columns_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
-NULL mysql columns_priv Table_name 4 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
-NULL mysql columns_priv Timestamp 6 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
-NULL mysql columns_priv User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
-NULL mysql db Alter_priv 13 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Alter_routine_priv 19 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Create_priv 8 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Create_routine_priv 18 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Create_tmp_table_priv 14 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Create_view_priv 16 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
-NULL mysql db Delete_priv 7 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Drop_priv 9 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Event_priv 21 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Execute_priv 20 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Grant_priv 10 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
-NULL mysql db Index_priv 12 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Insert_priv 5 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Lock_tables_priv 15 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db References_priv 11 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Select_priv 4 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Show_view_priv 17 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Trigger_priv 22 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db Update_priv 6 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql db User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
-NULL mysql event body 3 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL longblob select,insert,update,references
-NULL mysql event body_utf8 22 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL longblob select,insert,update,references
-NULL mysql event character_set_client 19 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32) select,insert,update,references
-NULL mysql event collation_connection 20 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32) select,insert,update,references
-NULL mysql event comment 16 NO char 64 192 NULL NULL utf8 utf8_bin char(64) select,insert,update,references
-NULL mysql event created 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
-NULL mysql event db 1 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
-NULL mysql event db_collation 21 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32) select,insert,update,references
-NULL mysql event definer 4 NO char 77 231 NULL NULL utf8 utf8_bin char(77) select,insert,update,references
-NULL mysql event ends 12 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
-NULL mysql event execute_at 5 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
-NULL mysql event interval_field 7 NULL YES enum 18 54 NULL NULL utf8 utf8_general_ci enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') select,insert,update,references
-NULL mysql event interval_value 6 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL mysql event last_executed 10 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
-NULL mysql event modified 9 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL NULL NULL timestamp select,insert,update,references
-NULL mysql event name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
-NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE') select,insert,update,references
-NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL mysql event sql_mode 15 NO set 494 1482 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
-NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
-NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') select,insert,update,references
-NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL latin1 latin1_swedish_ci char(64) select,insert,update,references
-NULL mysql func dl 3 NO char 128 384 NULL NULL utf8 utf8_bin char(128) select,insert,update,references
-NULL mysql func name 1 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
-NULL mysql func ret 2 0 NO tinyint NULL NULL 3 0 NULL NULL tinyint(1) select,insert,update,references
-NULL mysql func type 4 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('function','aggregate') select,insert,update,references
-NULL mysql general_log argument 6 NULL NO mediumtext 16777215 16777215 NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
-NULL mysql general_log command_type 5 NULL NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select,insert,update,references
-NULL mysql general_log event_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
-NULL mysql general_log server_id 4 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL mysql general_log thread_id 3 NULL NO int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL mysql general_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
-NULL mysql help_category help_category_id 1 NULL NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned PRI select,insert,update,references
-NULL mysql help_category name 2 NULL NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) UNI select,insert,update,references
-NULL mysql help_category parent_category_id 3 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned select,insert,update,references
-NULL mysql help_category url 4 NULL NO char 128 384 NULL NULL utf8 utf8_general_ci char(128) select,insert,update,references
-NULL mysql help_keyword help_keyword_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI select,insert,update,references
-NULL mysql help_keyword name 2 NULL NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) UNI select,insert,update,references
-NULL mysql help_relation help_keyword_id 2 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI select,insert,update,references
-NULL mysql help_relation help_topic_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI select,insert,update,references
-NULL mysql help_topic description 4 NULL NO text 65535 65535 NULL NULL utf8 utf8_general_ci text select,insert,update,references
-NULL mysql help_topic example 5 NULL NO text 65535 65535 NULL NULL utf8 utf8_general_ci text select,insert,update,references
-NULL mysql help_topic help_category_id 3 NULL NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned select,insert,update,references
-NULL mysql help_topic help_topic_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI select,insert,update,references
-NULL mysql help_topic name 2 NULL NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) UNI select,insert,update,references
-NULL mysql help_topic url 6 NULL NO char 128 384 NULL NULL utf8 utf8_general_ci char(128) select,insert,update,references
-NULL mysql host Alter_priv 12 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Alter_routine_priv 18 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Create_priv 7 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Create_routine_priv 17 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Create_tmp_table_priv 13 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Create_view_priv 15 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
-NULL mysql host Delete_priv 6 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Drop_priv 8 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Execute_priv 19 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Grant_priv 9 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
-NULL mysql host Index_priv 11 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Insert_priv 4 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Lock_tables_priv 14 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host References_priv 10 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Select_priv 3 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Show_view_priv 16 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Trigger_priv 20 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql host Update_priv 5 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql ndb_binlog_index deletes 6 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL mysql ndb_binlog_index epoch 3 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned PRI select,insert,update,references
-NULL mysql ndb_binlog_index File 2 NULL NO varchar 255 255 NULL NULL latin1 latin1_swedish_ci varchar(255) select,insert,update,references
-NULL mysql ndb_binlog_index inserts 4 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL mysql ndb_binlog_index Position 1 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL mysql ndb_binlog_index schemaops 7 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL mysql ndb_binlog_index updates 5 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL mysql plugin dl 2 NO char 128 384 NULL NULL utf8 utf8_bin char(128) select,insert,update,references
-NULL mysql plugin name 1 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
-NULL mysql proc body 11 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL longblob select,insert,update,references
-NULL mysql proc body_utf8 20 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL longblob select,insert,update,references
-NULL mysql proc character_set_client 17 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32) select,insert,update,references
-NULL mysql proc collation_connection 18 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32) select,insert,update,references
-NULL mysql proc comment 16 NO char 64 192 NULL NULL utf8 utf8_bin char(64) select,insert,update,references
-NULL mysql proc created 13 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
-NULL mysql proc db 1 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
-NULL mysql proc db_collation 19 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32) select,insert,update,references
-NULL mysql proc definer 12 NO char 77 231 NULL NULL utf8 utf8_bin char(77) select,insert,update,references
-NULL mysql proc is_deterministic 7 NO NO enum 3 9 NULL NULL utf8 utf8_general_ci enum('YES','NO') select,insert,update,references
-NULL mysql proc language 5 SQL NO enum 3 9 NULL NULL utf8 utf8_general_ci enum('SQL') select,insert,update,references
-NULL mysql proc modified 14 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL NULL NULL timestamp select,insert,update,references
-NULL mysql proc name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
-NULL mysql proc param_list 9 NULL NO blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references
-NULL mysql proc returns 10 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL longblob select,insert,update,references
-NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER') select,insert,update,references
-NULL mysql proc specific_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
-NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') select,insert,update,references
-NULL mysql proc sql_mode 15 NO set 494 1482 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
-NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI select,insert,update,references
-NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
-NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references
-NULL mysql procs_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
-NULL mysql procs_priv Proc_priv 7 NO set 27 81 NULL NULL utf8 utf8_general_ci set('Execute','Alter Routine','Grant') select,insert,update,references
-NULL mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
-NULL mysql procs_priv Routine_type 5 NULL NO enum 9 27 NULL NULL utf8 utf8_bin enum('FUNCTION','PROCEDURE') PRI select,insert,update,references
-NULL mysql procs_priv Timestamp 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
-NULL mysql procs_priv User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
-NULL mysql servers Db 3 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
-NULL mysql servers Host 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
-NULL mysql servers Owner 9 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
-NULL mysql servers Password 5 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
-NULL mysql servers Port 6 0 NO int NULL NULL 10 0 NULL NULL int(4) select,insert,update,references
-NULL mysql servers Server_name 1 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
-NULL mysql servers Socket 7 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
-NULL mysql servers Username 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
-NULL mysql servers Wrapper 8 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
-NULL mysql slow_log db 7 NULL NO varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select,insert,update,references
-NULL mysql slow_log insert_id 9 NULL NO int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL mysql slow_log last_insert_id 8 NULL NO int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL mysql slow_log lock_time 4 NULL NO time NULL NULL NULL NULL NULL NULL time select,insert,update,references
-NULL mysql slow_log query_time 3 NULL NO time NULL NULL NULL NULL NULL NULL time select,insert,update,references
-NULL mysql slow_log rows_examined 6 NULL NO int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL mysql slow_log rows_sent 5 NULL NO int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL mysql slow_log server_id 10 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL mysql slow_log sql_text 11 NULL NO mediumtext 16777215 16777215 NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
-NULL mysql slow_log start_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
-NULL mysql slow_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
-NULL mysql tables_priv Column_priv 8 NO set 31 93 NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','References') select,insert,update,references
-NULL mysql tables_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
-NULL mysql tables_priv Grantor 5 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references
-NULL mysql tables_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
-NULL mysql tables_priv Table_name 4 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
-NULL mysql tables_priv Table_priv 7 NO set 98 294 NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') select,insert,update,references
-NULL mysql tables_priv Timestamp 6 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
-NULL mysql tables_priv User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
-NULL mysql time_zone Time_zone_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI auto_increment select,insert,update,references
-NULL mysql time_zone Use_leap_seconds 2 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('Y','N') select,insert,update,references
-NULL mysql time_zone_leap_second Correction 2 NULL NO int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL mysql time_zone_leap_second Transition_time 1 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) PRI select,insert,update,references
-NULL mysql time_zone_name Name 1 NULL NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
-NULL mysql time_zone_name Time_zone_id 2 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL mysql time_zone_transition Time_zone_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI select,insert,update,references
-NULL mysql time_zone_transition Transition_time 2 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) PRI select,insert,update,references
-NULL mysql time_zone_transition Transition_type_id 3 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
-NULL mysql time_zone_transition_type Abbreviation 5 NO char 8 24 NULL NULL utf8 utf8_general_ci char(8) select,insert,update,references
-NULL mysql time_zone_transition_type Is_DST 4 0 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned select,insert,update,references
-NULL mysql time_zone_transition_type Offset 3 0 NO int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
-NULL mysql time_zone_transition_type Time_zone_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI select,insert,update,references
-NULL mysql time_zone_transition_type Transition_type_id 2 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI select,insert,update,references
-NULL mysql user Alter_priv 17 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Alter_routine_priv 28 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user auth_string 41 NULL NO text 65535 65535 NULL NULL utf8 utf8_bin text select,insert,update,references
-NULL mysql user Create_priv 8 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Create_routine_priv 27 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Create_tmp_table_priv 20 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Create_user_priv 29 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Create_view_priv 25 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Delete_priv 7 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Drop_priv 9 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Event_priv 30 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Execute_priv 22 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user File_priv 13 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Grant_priv 14 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
-NULL mysql user Index_priv 16 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Insert_priv 5 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Lock_tables_priv 21 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user max_connections 38 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references
-NULL mysql user max_questions 36 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references
-NULL mysql user max_updates 37 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references
-NULL mysql user max_user_connections 39 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references
-NULL mysql user Password 3 NO char 41 41 NULL NULL latin1 latin1_bin char(41) select,insert,update,references
-NULL mysql user plugin 40 NO char 60 60 NULL NULL latin1 latin1_swedish_ci char(60) select,insert,update,references
-NULL mysql user Process_priv 12 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user References_priv 15 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Reload_priv 10 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Repl_client_priv 24 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Repl_slave_priv 23 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Select_priv 4 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Show_db_priv 18 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Show_view_priv 26 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Shutdown_priv 11 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user ssl_cipher 33 NULL NO blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references
-NULL mysql user ssl_type 32 NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('','ANY','X509','SPECIFIED') select,insert,update,references
-NULL mysql user Super_priv 19 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Trigger_priv 31 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user Update_priv 6 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql user User 2 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
-NULL mysql user x509_issuer 34 NULL NO blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references
-NULL mysql user x509_subject 35 NULL NO blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL mysql columns_priv Column_name 5 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql columns_priv Column_priv 7 NO set 31 93 NULL NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','References') select,insert,update,references
+NULL mysql columns_priv Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql columns_priv Host 1 NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
+NULL mysql columns_priv Table_name 4 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql columns_priv Timestamp 6 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
+NULL mysql columns_priv User 3 NO char 16 48 NULL NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
+NULL mysql db Alter_priv 13 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Alter_routine_priv 19 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Create_priv 8 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Create_routine_priv 18 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Create_tmp_table_priv 14 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Create_view_priv 16 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql db Delete_priv 7 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Drop_priv 9 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Event_priv 21 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Execute_priv 20 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Grant_priv 10 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Host 1 NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
+NULL mysql db Index_priv 12 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Insert_priv 5 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Lock_tables_priv 15 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db References_priv 11 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Select_priv 4 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Show_view_priv 17 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Trigger_priv 22 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db Update_priv 6 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql db User 3 NO char 16 48 NULL NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
+NULL mysql event body 3 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob select,insert,update,references
+NULL mysql event body_utf8 22 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob select,insert,update,references
+NULL mysql event character_set_client 19 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32) select,insert,update,references
+NULL mysql event collation_connection 20 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32) select,insert,update,references
+NULL mysql event comment 16 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) select,insert,update,references
+NULL mysql event created 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
+NULL mysql event db 1 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql event db_collation 21 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32) select,insert,update,references
+NULL mysql event definer 4 NO char 77 231 NULL NULL NULL utf8 utf8_bin char(77) select,insert,update,references
+NULL mysql event ends 12 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references
+NULL mysql event execute_at 5 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references
+NULL mysql event interval_field 7 NULL YES enum 18 54 NULL NULL NULL utf8 utf8_general_ci enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') select,insert,update,references
+NULL mysql event interval_value 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL mysql event last_executed 10 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references
+NULL mysql event modified 9 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp select,insert,update,references
+NULL mysql event name 2 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
+NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE') select,insert,update,references
+NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
+NULL mysql event sql_mode 15 NO set 494 1482 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
+NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references
+NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') select,insert,update,references
+NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL NULL latin1 latin1_swedish_ci char(64) select,insert,update,references
+NULL mysql func dl 3 NO char 128 384 NULL NULL NULL utf8 utf8_bin char(128) select,insert,update,references
+NULL mysql func name 1 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql func ret 2 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(1) select,insert,update,references
+NULL mysql func type 4 NULL NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('function','aggregate') select,insert,update,references
+NULL mysql general_log argument 6 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
+NULL mysql general_log command_type 5 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select,insert,update,references
+NULL mysql general_log event_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP select,insert,update,references
+NULL mysql general_log server_id 4 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
+NULL mysql general_log thread_id 3 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL mysql general_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
+NULL mysql help_category help_category_id 1 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned PRI select,insert,update,references
+NULL mysql help_category name 2 NULL NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) UNI select,insert,update,references
+NULL mysql help_category parent_category_id 3 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned select,insert,update,references
+NULL mysql help_category url 4 NULL NO char 128 384 NULL NULL NULL utf8 utf8_general_ci char(128) select,insert,update,references
+NULL mysql help_keyword help_keyword_id 1 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI select,insert,update,references
+NULL mysql help_keyword name 2 NULL NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) UNI select,insert,update,references
+NULL mysql help_relation help_keyword_id 2 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI select,insert,update,references
+NULL mysql help_relation help_topic_id 1 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI select,insert,update,references
+NULL mysql help_topic description 4 NULL NO text 65535 65535 NULL NULL NULL utf8 utf8_general_ci text select,insert,update,references
+NULL mysql help_topic example 5 NULL NO text 65535 65535 NULL NULL NULL utf8 utf8_general_ci text select,insert,update,references
+NULL mysql help_topic help_category_id 3 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned select,insert,update,references
+NULL mysql help_topic help_topic_id 1 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI select,insert,update,references
+NULL mysql help_topic name 2 NULL NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) UNI select,insert,update,references
+NULL mysql help_topic url 6 NULL NO char 128 384 NULL NULL NULL utf8 utf8_general_ci char(128) select,insert,update,references
+NULL mysql host Alter_priv 12 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Alter_routine_priv 18 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Create_priv 7 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Create_routine_priv 17 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Create_tmp_table_priv 13 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Create_view_priv 15 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql host Delete_priv 6 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Drop_priv 8 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Execute_priv 19 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Grant_priv 9 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Host 1 NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
+NULL mysql host Index_priv 11 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Insert_priv 4 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Lock_tables_priv 14 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host References_priv 10 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Select_priv 3 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Show_view_priv 16 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Trigger_priv 20 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql host Update_priv 5 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql ndb_binlog_index deletes 6 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references
+NULL mysql ndb_binlog_index epoch 3 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned PRI select,insert,update,references
+NULL mysql ndb_binlog_index File 2 NULL NO varchar 255 255 NULL NULL NULL latin1 latin1_swedish_ci varchar(255) select,insert,update,references
+NULL mysql ndb_binlog_index inserts 4 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references
+NULL mysql ndb_binlog_index Position 1 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references
+NULL mysql ndb_binlog_index schemaops 7 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references
+NULL mysql ndb_binlog_index updates 5 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references
+NULL mysql plugin dl 2 NO char 128 384 NULL NULL NULL utf8 utf8_bin char(128) select,insert,update,references
+NULL mysql plugin name 1 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql proc body 11 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob select,insert,update,references
+NULL mysql proc body_utf8 20 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob select,insert,update,references
+NULL mysql proc character_set_client 17 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32) select,insert,update,references
+NULL mysql proc collation_connection 18 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32) select,insert,update,references
+NULL mysql proc comment 16 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) select,insert,update,references
+NULL mysql proc created 13 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
+NULL mysql proc db 1 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql proc db_collation 19 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32) select,insert,update,references
+NULL mysql proc definer 12 NO char 77 231 NULL NULL NULL utf8 utf8_bin char(77) select,insert,update,references
+NULL mysql proc is_deterministic 7 NO NO enum 3 9 NULL NULL NULL utf8 utf8_general_ci enum('YES','NO') select,insert,update,references
+NULL mysql proc language 5 SQL NO enum 3 9 NULL NULL NULL utf8 utf8_general_ci enum('SQL') select,insert,update,references
+NULL mysql proc modified 14 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp select,insert,update,references
+NULL mysql proc name 2 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
+NULL mysql proc param_list 9 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references
+NULL mysql proc returns 10 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob select,insert,update,references
+NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER') select,insert,update,references
+NULL mysql proc specific_name 4 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
+NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') select,insert,update,references
+NULL mysql proc sql_mode 15 NO set 494 1482 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
+NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI select,insert,update,references
+NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references
+NULL mysql procs_priv Host 1 NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
+NULL mysql procs_priv Proc_priv 7 NO set 27 81 NULL NULL NULL utf8 utf8_general_ci set('Execute','Alter Routine','Grant') select,insert,update,references
+NULL mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
+NULL mysql procs_priv Routine_type 5 NULL NO enum 9 27 NULL NULL NULL utf8 utf8_bin enum('FUNCTION','PROCEDURE') PRI select,insert,update,references
+NULL mysql procs_priv Timestamp 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
+NULL mysql procs_priv User 3 NO char 16 48 NULL NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
+NULL mysql servers Db 3 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
+NULL mysql servers Host 2 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
+NULL mysql servers Owner 9 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
+NULL mysql servers Password 5 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
+NULL mysql servers Port 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(4) select,insert,update,references
+NULL mysql servers Server_name 1 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
+NULL mysql servers Socket 7 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
+NULL mysql servers Username 4 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
+NULL mysql servers Wrapper 8 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
+NULL mysql slow_log db 7 NULL NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select,insert,update,references
+NULL mysql slow_log insert_id 9 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL mysql slow_log last_insert_id 8 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL mysql slow_log lock_time 4 NULL NO time NULL NULL NULL NULL 6 NULL NULL time(6) select,insert,update,references
+NULL mysql slow_log query_time 3 NULL NO time NULL NULL NULL NULL 6 NULL NULL time(6) select,insert,update,references
+NULL mysql slow_log rows_examined 6 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL mysql slow_log rows_sent 5 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL mysql slow_log server_id 10 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
+NULL mysql slow_log sql_text 11 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
+NULL mysql slow_log start_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP select,insert,update,references
+NULL mysql slow_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
+NULL mysql tables_priv Column_priv 8 NO set 31 93 NULL NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','References') select,insert,update,references
+NULL mysql tables_priv Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql tables_priv Grantor 5 NO char 77 231 NULL NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references
+NULL mysql tables_priv Host 1 NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
+NULL mysql tables_priv Table_name 4 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql tables_priv Table_priv 7 NO set 98 294 NULL NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') select,insert,update,references
+NULL mysql tables_priv Timestamp 6 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
+NULL mysql tables_priv User 3 NO char 16 48 NULL NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
+NULL mysql time_zone Time_zone_id 1 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI auto_increment select,insert,update,references
+NULL mysql time_zone Use_leap_seconds 2 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('Y','N') select,insert,update,references
+NULL mysql time_zone_leap_second Correction 2 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL mysql time_zone_leap_second Transition_time 1 NULL NO bigint NULL NULL 19 0 NULL NULL NULL bigint(20) PRI select,insert,update,references
+NULL mysql time_zone_name Name 1 NULL NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
+NULL mysql time_zone_name Time_zone_id 2 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
+NULL mysql time_zone_transition Time_zone_id 1 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI select,insert,update,references
+NULL mysql time_zone_transition Transition_time 2 NULL NO bigint NULL NULL 19 0 NULL NULL NULL bigint(20) PRI select,insert,update,references
+NULL mysql time_zone_transition Transition_type_id 3 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
+NULL mysql time_zone_transition_type Abbreviation 5 NO char 8 24 NULL NULL NULL utf8 utf8_general_ci char(8) select,insert,update,references
+NULL mysql time_zone_transition_type Is_DST 4 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned select,insert,update,references
+NULL mysql time_zone_transition_type Offset 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL mysql time_zone_transition_type Time_zone_id 1 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI select,insert,update,references
+NULL mysql time_zone_transition_type Transition_type_id 2 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI select,insert,update,references
+NULL mysql user Alter_priv 17 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Alter_routine_priv 28 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user auth_string 41 NULL NO text 65535 65535 NULL NULL NULL utf8 utf8_bin text select,insert,update,references
+NULL mysql user Create_priv 8 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Create_routine_priv 27 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Create_tmp_table_priv 20 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Create_user_priv 29 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Create_view_priv 25 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Delete_priv 7 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Drop_priv 9 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Event_priv 30 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Execute_priv 22 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user File_priv 13 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Grant_priv 14 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Host 1 NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
+NULL mysql user Index_priv 16 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Insert_priv 5 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Lock_tables_priv 21 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user max_connections 38 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references
+NULL mysql user max_questions 36 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references
+NULL mysql user max_updates 37 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references
+NULL mysql user max_user_connections 39 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
+NULL mysql user Password 3 NO char 41 41 NULL NULL NULL latin1 latin1_bin char(41) select,insert,update,references
+NULL mysql user plugin 40 NO char 60 60 NULL NULL NULL latin1 latin1_swedish_ci char(60) select,insert,update,references
+NULL mysql user Process_priv 12 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user References_priv 15 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Reload_priv 10 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Repl_client_priv 24 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Repl_slave_priv 23 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Select_priv 4 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Show_db_priv 18 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Show_view_priv 26 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Shutdown_priv 11 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user ssl_cipher 33 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references
+NULL mysql user ssl_type 32 NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('','ANY','X509','SPECIFIED') select,insert,update,references
+NULL mysql user Super_priv 19 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Trigger_priv 31 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user Update_priv 6 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
+NULL mysql user User 2 NO char 16 48 NULL NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
+NULL mysql user x509_issuer 34 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references
+NULL mysql user x509_subject 35 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob select,insert,update,references
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
@@ -342,7 +342,7 @@ NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
NULL mysql func ret tinyint NULL NULL NULL NULL tinyint(1)
3.0000 mysql func dl char 128 384 utf8 utf8_bin char(128)
3.0000 mysql func type enum 9 27 utf8 utf8_general_ci enum('function','aggregate')
-NULL mysql general_log event_time timestamp NULL NULL NULL NULL timestamp
+NULL mysql general_log event_time timestamp NULL NULL NULL NULL timestamp(6)
1.0000 mysql general_log user_host mediumtext 16777215 16777215 utf8 utf8_general_ci mediumtext
NULL mysql general_log thread_id int NULL NULL NULL NULL int(11)
NULL mysql general_log server_id int NULL NULL NULL NULL int(10) unsigned
@@ -428,10 +428,10 @@ NULL mysql servers Port int NULL NULL NULL NULL int(4)
3.0000 mysql servers Socket char 64 192 utf8 utf8_general_ci char(64)
3.0000 mysql servers Wrapper char 64 192 utf8 utf8_general_ci char(64)
3.0000 mysql servers Owner char 64 192 utf8 utf8_general_ci char(64)
-NULL mysql slow_log start_time timestamp NULL NULL NULL NULL timestamp
+NULL mysql slow_log start_time timestamp NULL NULL NULL NULL timestamp(6)
1.0000 mysql slow_log user_host mediumtext 16777215 16777215 utf8 utf8_general_ci mediumtext
-NULL mysql slow_log query_time time NULL NULL NULL NULL time
-NULL mysql slow_log lock_time time NULL NULL NULL NULL time
+NULL mysql slow_log query_time time NULL NULL NULL NULL time(6)
+NULL mysql slow_log lock_time time NULL NULL NULL NULL time(6)
NULL mysql slow_log rows_sent int NULL NULL NULL NULL int(11)
NULL mysql slow_log rows_examined int NULL NULL NULL NULL int(11)
3.0000 mysql slow_log db varchar 512 1536 utf8 utf8_general_ci varchar(512)
@@ -499,6 +499,6 @@ NULL mysql time_zone_transition_type Is_DST tinyint NULL NULL NULL NULL tinyint(
NULL mysql user max_questions int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_updates int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_connections int NULL NULL NULL NULL int(11) unsigned
-NULL mysql user max_user_connections int NULL NULL NULL NULL int(11) unsigned
+NULL mysql user max_user_connections int NULL NULL NULL NULL int(11)
1.0000 mysql user plugin char 60 60 latin1 latin1_swedish_ci char(60)
1.0000 mysql user auth_string text 65535 65535 utf8 utf8_bin text
diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result
index 926c2219bb0..8617628532c 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result
@@ -1,220 +1,222 @@
SELECT * FROM information_schema.columns
WHERE table_schema = 'mysql'
ORDER BY table_schema, table_name, column_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-NULL mysql columns_priv Column_name 5 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
-NULL mysql columns_priv Column_priv 7 NO set 31 93 NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','References')
-NULL mysql columns_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
-NULL mysql columns_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI
-NULL mysql columns_priv Table_name 4 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
-NULL mysql columns_priv Timestamp 6 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP
-NULL mysql columns_priv User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI
-NULL mysql db Alter_priv 13 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Alter_routine_priv 19 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Create_priv 8 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Create_routine_priv 18 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Create_tmp_table_priv 14 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Create_view_priv 16 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
-NULL mysql db Delete_priv 7 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Drop_priv 9 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Event_priv 21 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Execute_priv 20 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Grant_priv 10 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI
-NULL mysql db Index_priv 12 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Insert_priv 5 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Lock_tables_priv 15 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db References_priv 11 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Select_priv 4 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Show_view_priv 17 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Trigger_priv 22 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db Update_priv 6 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql db User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI
-NULL mysql event body 3 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL longblob
-NULL mysql event body_utf8 22 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL longblob
-NULL mysql event character_set_client 19 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32)
-NULL mysql event collation_connection 20 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32)
-NULL mysql event comment 16 NO char 64 192 NULL NULL utf8 utf8_bin char(64)
-NULL mysql event created 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP
-NULL mysql event db 1 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
-NULL mysql event db_collation 21 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32)
-NULL mysql event definer 4 NO char 77 231 NULL NULL utf8 utf8_bin char(77)
-NULL mysql event ends 12 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL mysql event execute_at 5 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL mysql event interval_field 7 NULL YES enum 18 54 NULL NULL utf8 utf8_general_ci enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND')
-NULL mysql event interval_value 6 NULL YES int NULL NULL 10 0 NULL NULL int(11)
-NULL mysql event last_executed 10 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL mysql event modified 9 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL NULL NULL timestamp
-NULL mysql event name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI
-NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE')
-NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
-NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
-NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
-NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
-NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL latin1 latin1_swedish_ci char(64)
-NULL mysql func dl 3 NO char 128 384 NULL NULL utf8 utf8_bin char(128)
-NULL mysql func name 1 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
-NULL mysql func ret 2 0 NO tinyint NULL NULL 3 0 NULL NULL tinyint(1)
-NULL mysql func type 4 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('function','aggregate')
-NULL mysql general_log argument 6 NULL NO mediumtext 16777215 16777215 NULL NULL utf8 utf8_general_ci mediumtext
-NULL mysql general_log command_type 5 NULL NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64)
-NULL mysql general_log event_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP
-NULL mysql general_log server_id 4 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
-NULL mysql general_log thread_id 3 NULL NO int NULL NULL 10 0 NULL NULL int(11)
-NULL mysql general_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL utf8 utf8_general_ci mediumtext
-NULL mysql help_category help_category_id 1 NULL NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned PRI
-NULL mysql help_category name 2 NULL NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) UNI
-NULL mysql help_category parent_category_id 3 NULL YES smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned
-NULL mysql help_category url 4 NULL NO char 128 384 NULL NULL utf8 utf8_general_ci char(128)
-NULL mysql help_keyword help_keyword_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI
-NULL mysql help_keyword name 2 NULL NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) UNI
-NULL mysql help_relation help_keyword_id 2 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI
-NULL mysql help_relation help_topic_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI
-NULL mysql help_topic description 4 NULL NO text 65535 65535 NULL NULL utf8 utf8_general_ci text
-NULL mysql help_topic example 5 NULL NO text 65535 65535 NULL NULL utf8 utf8_general_ci text
-NULL mysql help_topic help_category_id 3 NULL NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned
-NULL mysql help_topic help_topic_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI
-NULL mysql help_topic name 2 NULL NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) UNI
-NULL mysql help_topic url 6 NULL NO char 128 384 NULL NULL utf8 utf8_general_ci char(128)
-NULL mysql host Alter_priv 12 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Alter_routine_priv 18 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Create_priv 7 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Create_routine_priv 17 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Create_tmp_table_priv 13 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Create_view_priv 15 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
-NULL mysql host Delete_priv 6 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Drop_priv 8 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Execute_priv 19 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Grant_priv 9 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI
-NULL mysql host Index_priv 11 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Insert_priv 4 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Lock_tables_priv 14 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host References_priv 10 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Select_priv 3 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Show_view_priv 16 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Trigger_priv 20 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql host Update_priv 5 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql ndb_binlog_index deletes 6 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned
-NULL mysql ndb_binlog_index epoch 3 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned PRI
-NULL mysql ndb_binlog_index File 2 NULL NO varchar 255 255 NULL NULL latin1 latin1_swedish_ci varchar(255)
-NULL mysql ndb_binlog_index inserts 4 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned
-NULL mysql ndb_binlog_index Position 1 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned
-NULL mysql ndb_binlog_index schemaops 7 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned
-NULL mysql ndb_binlog_index updates 5 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned
-NULL mysql plugin dl 2 NO char 128 384 NULL NULL utf8 utf8_bin char(128)
-NULL mysql plugin name 1 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
-NULL mysql proc body 11 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL longblob
-NULL mysql proc body_utf8 20 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL longblob
-NULL mysql proc character_set_client 17 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32)
-NULL mysql proc collation_connection 18 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32)
-NULL mysql proc comment 16 NO char 64 192 NULL NULL utf8 utf8_bin char(64)
-NULL mysql proc created 13 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP
-NULL mysql proc db 1 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
-NULL mysql proc db_collation 19 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32)
-NULL mysql proc definer 12 NO char 77 231 NULL NULL utf8 utf8_bin char(77)
-NULL mysql proc is_deterministic 7 NO NO enum 3 9 NULL NULL utf8 utf8_general_ci enum('YES','NO')
-NULL mysql proc language 5 SQL NO enum 3 9 NULL NULL utf8 utf8_general_ci enum('SQL')
-NULL mysql proc modified 14 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL NULL NULL timestamp
-NULL mysql proc name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI
-NULL mysql proc param_list 9 NULL NO blob 65535 65535 NULL NULL NULL NULL blob
-NULL mysql proc returns 10 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL longblob
-NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER')
-NULL mysql proc specific_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
-NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')
-NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
-NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI
-NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
-NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL
-NULL mysql procs_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI
-NULL mysql procs_priv Proc_priv 7 NO set 27 81 NULL NULL utf8 utf8_general_ci set('Execute','Alter Routine','Grant')
-NULL mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI
-NULL mysql procs_priv Routine_type 5 NULL NO enum 9 27 NULL NULL utf8 utf8_bin enum('FUNCTION','PROCEDURE') PRI
-NULL mysql procs_priv Timestamp 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP
-NULL mysql procs_priv User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI
-NULL mysql servers Db 3 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
-NULL mysql servers Host 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
-NULL mysql servers Owner 9 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
-NULL mysql servers Password 5 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
-NULL mysql servers Port 6 0 NO int NULL NULL 10 0 NULL NULL int(4)
-NULL mysql servers Server_name 1 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI
-NULL mysql servers Socket 7 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
-NULL mysql servers Username 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
-NULL mysql servers Wrapper 8 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
-NULL mysql slow_log db 7 NULL NO varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
-NULL mysql slow_log insert_id 9 NULL NO int NULL NULL 10 0 NULL NULL int(11)
-NULL mysql slow_log last_insert_id 8 NULL NO int NULL NULL 10 0 NULL NULL int(11)
-NULL mysql slow_log lock_time 4 NULL NO time NULL NULL NULL NULL NULL NULL time
-NULL mysql slow_log query_time 3 NULL NO time NULL NULL NULL NULL NULL NULL time
-NULL mysql slow_log rows_examined 6 NULL NO int NULL NULL 10 0 NULL NULL int(11)
-NULL mysql slow_log rows_sent 5 NULL NO int NULL NULL 10 0 NULL NULL int(11)
-NULL mysql slow_log server_id 10 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
-NULL mysql slow_log sql_text 11 NULL NO mediumtext 16777215 16777215 NULL NULL utf8 utf8_general_ci mediumtext
-NULL mysql slow_log start_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP
-NULL mysql slow_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL utf8 utf8_general_ci mediumtext
-NULL mysql tables_priv Column_priv 8 NO set 31 93 NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','References')
-NULL mysql tables_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
-NULL mysql tables_priv Grantor 5 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL
-NULL mysql tables_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI
-NULL mysql tables_priv Table_name 4 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
-NULL mysql tables_priv Table_priv 7 NO set 98 294 NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger')
-NULL mysql tables_priv Timestamp 6 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP
-NULL mysql tables_priv User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI
-NULL mysql time_zone Time_zone_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI auto_increment
-NULL mysql time_zone Use_leap_seconds 2 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('Y','N')
-NULL mysql time_zone_leap_second Correction 2 NULL NO int NULL NULL 10 0 NULL NULL int(11)
-NULL mysql time_zone_leap_second Transition_time 1 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) PRI
-NULL mysql time_zone_name Name 1 NULL NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI
-NULL mysql time_zone_name Time_zone_id 2 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
-NULL mysql time_zone_transition Time_zone_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI
-NULL mysql time_zone_transition Transition_time 2 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) PRI
-NULL mysql time_zone_transition Transition_type_id 3 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
-NULL mysql time_zone_transition_type Abbreviation 5 NO char 8 24 NULL NULL utf8 utf8_general_ci char(8)
-NULL mysql time_zone_transition_type Is_DST 4 0 NO tinyint NULL NULL 3 0 NULL NULL tinyint(3) unsigned
-NULL mysql time_zone_transition_type Offset 3 0 NO int NULL NULL 10 0 NULL NULL int(11)
-NULL mysql time_zone_transition_type Time_zone_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI
-NULL mysql time_zone_transition_type Transition_type_id 2 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI
-NULL mysql user Alter_priv 17 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Alter_routine_priv 28 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Create_priv 8 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Create_routine_priv 27 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Create_tmp_table_priv 20 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Create_user_priv 29 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Create_view_priv 25 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Delete_priv 7 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Drop_priv 9 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Event_priv 30 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Execute_priv 22 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user File_priv 13 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Grant_priv 14 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI
-NULL mysql user Index_priv 16 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Insert_priv 5 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Lock_tables_priv 21 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user max_connections 38 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned
-NULL mysql user max_questions 36 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned
-NULL mysql user max_updates 37 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned
-NULL mysql user max_user_connections 39 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned
-NULL mysql user Password 3 NO char 41 41 NULL NULL latin1 latin1_bin char(41)
-NULL mysql user Process_priv 12 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user References_priv 15 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Reload_priv 10 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Repl_client_priv 24 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Repl_slave_priv 23 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Select_priv 4 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Show_db_priv 18 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Show_view_priv 26 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Shutdown_priv 11 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user ssl_cipher 33 NULL NO blob 65535 65535 NULL NULL NULL NULL blob
-NULL mysql user ssl_type 32 NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('','ANY','X509','SPECIFIED')
-NULL mysql user Super_priv 19 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Trigger_priv 31 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user Update_priv 6 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y')
-NULL mysql user User 2 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI
-NULL mysql user x509_issuer 34 NULL NO blob 65535 65535 NULL NULL NULL NULL blob
-NULL mysql user x509_subject 35 NULL NO blob 65535 65535 NULL NULL NULL NULL blob
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+NULL mysql columns_priv Column_name 5 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
+NULL mysql columns_priv Column_priv 7 NO set 31 93 NULL NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','References')
+NULL mysql columns_priv Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
+NULL mysql columns_priv Host 1 NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI
+NULL mysql columns_priv Table_name 4 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
+NULL mysql columns_priv Timestamp 6 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP
+NULL mysql columns_priv User 3 NO char 16 48 NULL NULL NULL utf8 utf8_bin char(16) PRI
+NULL mysql db Alter_priv 13 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Alter_routine_priv 19 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Create_priv 8 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Create_routine_priv 18 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Create_tmp_table_priv 14 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Create_view_priv 16 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
+NULL mysql db Delete_priv 7 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Drop_priv 9 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Event_priv 21 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Execute_priv 20 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Grant_priv 10 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Host 1 NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI
+NULL mysql db Index_priv 12 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Insert_priv 5 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Lock_tables_priv 15 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db References_priv 11 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Select_priv 4 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Show_view_priv 17 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Trigger_priv 22 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db Update_priv 6 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql db User 3 NO char 16 48 NULL NULL NULL utf8 utf8_bin char(16) PRI
+NULL mysql event body 3 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob
+NULL mysql event body_utf8 22 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob
+NULL mysql event character_set_client 19 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32)
+NULL mysql event collation_connection 20 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32)
+NULL mysql event comment 16 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64)
+NULL mysql event created 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP
+NULL mysql event db 1 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
+NULL mysql event db_collation 21 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32)
+NULL mysql event definer 4 NO char 77 231 NULL NULL NULL utf8 utf8_bin char(77)
+NULL mysql event ends 12 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL mysql event execute_at 5 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL mysql event interval_field 7 NULL YES enum 18 54 NULL NULL NULL utf8 utf8_general_ci enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND')
+NULL mysql event interval_value 6 NULL YES int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL mysql event last_executed 10 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL mysql event modified 9 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp
+NULL mysql event name 2 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI
+NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE')
+NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned
+NULL mysql event sql_mode 15 NO set 494 1482 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
+NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL NULL latin1 latin1_swedish_ci char(64)
+NULL mysql func dl 3 NO char 128 384 NULL NULL NULL utf8 utf8_bin char(128)
+NULL mysql func name 1 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
+NULL mysql func ret 2 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(1)
+NULL mysql func type 4 NULL NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('function','aggregate')
+NULL mysql general_log argument 6 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext
+NULL mysql general_log command_type 5 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL mysql general_log event_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP
+NULL mysql general_log server_id 4 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned
+NULL mysql general_log thread_id 3 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL mysql general_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext
+NULL mysql help_category help_category_id 1 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned PRI
+NULL mysql help_category name 2 NULL NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) UNI
+NULL mysql help_category parent_category_id 3 NULL YES smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned
+NULL mysql help_category url 4 NULL NO char 128 384 NULL NULL NULL utf8 utf8_general_ci char(128)
+NULL mysql help_keyword help_keyword_id 1 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI
+NULL mysql help_keyword name 2 NULL NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) UNI
+NULL mysql help_relation help_keyword_id 2 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI
+NULL mysql help_relation help_topic_id 1 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI
+NULL mysql help_topic description 4 NULL NO text 65535 65535 NULL NULL NULL utf8 utf8_general_ci text
+NULL mysql help_topic example 5 NULL NO text 65535 65535 NULL NULL NULL utf8 utf8_general_ci text
+NULL mysql help_topic help_category_id 3 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) unsigned
+NULL mysql help_topic help_topic_id 1 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI
+NULL mysql help_topic name 2 NULL NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) UNI
+NULL mysql help_topic url 6 NULL NO char 128 384 NULL NULL NULL utf8 utf8_general_ci char(128)
+NULL mysql host Alter_priv 12 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Alter_routine_priv 18 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Create_priv 7 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Create_routine_priv 17 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Create_tmp_table_priv 13 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Create_view_priv 15 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
+NULL mysql host Delete_priv 6 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Drop_priv 8 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Execute_priv 19 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Grant_priv 9 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Host 1 NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI
+NULL mysql host Index_priv 11 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Insert_priv 4 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Lock_tables_priv 14 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host References_priv 10 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Select_priv 3 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Show_view_priv 16 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Trigger_priv 20 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql host Update_priv 5 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql ndb_binlog_index deletes 6 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned
+NULL mysql ndb_binlog_index epoch 3 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned PRI
+NULL mysql ndb_binlog_index File 2 NULL NO varchar 255 255 NULL NULL NULL latin1 latin1_swedish_ci varchar(255)
+NULL mysql ndb_binlog_index inserts 4 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned
+NULL mysql ndb_binlog_index Position 1 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned
+NULL mysql ndb_binlog_index schemaops 7 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned
+NULL mysql ndb_binlog_index updates 5 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned
+NULL mysql plugin dl 2 NO char 128 384 NULL NULL NULL utf8 utf8_bin char(128)
+NULL mysql plugin name 1 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
+NULL mysql proc body 11 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob
+NULL mysql proc body_utf8 20 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob
+NULL mysql proc character_set_client 17 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32)
+NULL mysql proc collation_connection 18 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32)
+NULL mysql proc comment 16 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64)
+NULL mysql proc created 13 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP
+NULL mysql proc db 1 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
+NULL mysql proc db_collation 19 NULL YES char 32 96 NULL NULL NULL utf8 utf8_bin char(32)
+NULL mysql proc definer 12 NO char 77 231 NULL NULL NULL utf8 utf8_bin char(77)
+NULL mysql proc is_deterministic 7 NO NO enum 3 9 NULL NULL NULL utf8 utf8_general_ci enum('YES','NO')
+NULL mysql proc language 5 SQL NO enum 3 9 NULL NULL NULL utf8 utf8_general_ci enum('SQL')
+NULL mysql proc modified 14 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp
+NULL mysql proc name 2 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI
+NULL mysql proc param_list 9 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob
+NULL mysql proc returns 10 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL NULL longblob
+NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER')
+NULL mysql proc specific_name 4 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64)
+NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')
+NULL mysql proc sql_mode 15 NO set 494 1482 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI
+NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
+NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL NULL utf8 utf8_bin char(77) MUL
+NULL mysql procs_priv Host 1 NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI
+NULL mysql procs_priv Proc_priv 7 NO set 27 81 NULL NULL NULL utf8 utf8_general_ci set('Execute','Alter Routine','Grant')
+NULL mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI
+NULL mysql procs_priv Routine_type 5 NULL NO enum 9 27 NULL NULL NULL utf8 utf8_bin enum('FUNCTION','PROCEDURE') PRI
+NULL mysql procs_priv Timestamp 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP
+NULL mysql procs_priv User 3 NO char 16 48 NULL NULL NULL utf8 utf8_bin char(16) PRI
+NULL mysql servers Db 3 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64)
+NULL mysql servers Host 2 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64)
+NULL mysql servers Owner 9 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64)
+NULL mysql servers Password 5 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64)
+NULL mysql servers Port 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(4)
+NULL mysql servers Server_name 1 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI
+NULL mysql servers Socket 7 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64)
+NULL mysql servers Username 4 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64)
+NULL mysql servers Wrapper 8 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64)
+NULL mysql slow_log db 7 NULL NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL mysql slow_log insert_id 9 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL mysql slow_log last_insert_id 8 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL mysql slow_log lock_time 4 NULL NO time NULL NULL NULL NULL 6 NULL NULL time(6)
+NULL mysql slow_log query_time 3 NULL NO time NULL NULL NULL NULL 6 NULL NULL time(6)
+NULL mysql slow_log rows_examined 6 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL mysql slow_log rows_sent 5 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL mysql slow_log server_id 10 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned
+NULL mysql slow_log sql_text 11 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext
+NULL mysql slow_log start_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP
+NULL mysql slow_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext
+NULL mysql tables_priv Column_priv 8 NO set 31 93 NULL NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','References')
+NULL mysql tables_priv Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
+NULL mysql tables_priv Grantor 5 NO char 77 231 NULL NULL NULL utf8 utf8_bin char(77) MUL
+NULL mysql tables_priv Host 1 NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI
+NULL mysql tables_priv Table_name 4 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
+NULL mysql tables_priv Table_priv 7 NO set 98 294 NULL NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger')
+NULL mysql tables_priv Timestamp 6 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP
+NULL mysql tables_priv User 3 NO char 16 48 NULL NULL NULL utf8 utf8_bin char(16) PRI
+NULL mysql time_zone Time_zone_id 1 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI auto_increment
+NULL mysql time_zone Use_leap_seconds 2 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('Y','N')
+NULL mysql time_zone_leap_second Correction 2 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL mysql time_zone_leap_second Transition_time 1 NULL NO bigint NULL NULL 19 0 NULL NULL NULL bigint(20) PRI
+NULL mysql time_zone_name Name 1 NULL NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI
+NULL mysql time_zone_name Time_zone_id 2 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned
+NULL mysql time_zone_transition Time_zone_id 1 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI
+NULL mysql time_zone_transition Transition_time 2 NULL NO bigint NULL NULL 19 0 NULL NULL NULL bigint(20) PRI
+NULL mysql time_zone_transition Transition_type_id 3 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned
+NULL mysql time_zone_transition_type Abbreviation 5 NO char 8 24 NULL NULL NULL utf8 utf8_general_ci char(8)
+NULL mysql time_zone_transition_type Is_DST 4 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(3) unsigned
+NULL mysql time_zone_transition_type Offset 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL mysql time_zone_transition_type Time_zone_id 1 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI
+NULL mysql time_zone_transition_type Transition_type_id 2 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI
+NULL mysql user Alter_priv 17 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Alter_routine_priv 28 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user auth_string 41 NULL NO text 65535 65535 NULL NULL NULL utf8 utf8_bin text
+NULL mysql user Create_priv 8 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Create_routine_priv 27 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Create_tmp_table_priv 20 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Create_user_priv 29 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Create_view_priv 25 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Delete_priv 7 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Drop_priv 9 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Event_priv 30 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Execute_priv 22 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user File_priv 13 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Grant_priv 14 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Host 1 NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI
+NULL mysql user Index_priv 16 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Insert_priv 5 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Lock_tables_priv 21 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user max_connections 38 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned
+NULL mysql user max_questions 36 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned
+NULL mysql user max_updates 37 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned
+NULL mysql user max_user_connections 39 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned
+NULL mysql user Password 3 NO char 41 41 NULL NULL NULL latin1 latin1_bin char(41)
+NULL mysql user plugin 40 NO char 60 60 NULL NULL NULL latin1 latin1_swedish_ci char(60)
+NULL mysql user Process_priv 12 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user References_priv 15 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Reload_priv 10 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Repl_client_priv 24 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Repl_slave_priv 23 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Select_priv 4 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Show_db_priv 18 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Show_view_priv 26 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Shutdown_priv 11 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user ssl_cipher 33 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob
+NULL mysql user ssl_type 32 NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('','ANY','X509','SPECIFIED')
+NULL mysql user Super_priv 19 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Trigger_priv 31 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user Update_priv 6 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user User 2 NO char 16 48 NULL NULL NULL utf8 utf8_bin char(16) PRI
+NULL mysql user x509_issuer 34 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob
+NULL mysql user x509_subject 35 NULL NO blob 65535 65535 NULL NULL NULL NULL NULL blob
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
@@ -233,6 +235,7 @@ COL_CML DATA_TYPE CHARACTER_SET_NAME COLLATION_NAME
1.0000 char latin1 latin1_bin
1.0000 char latin1 latin1_swedish_ci
1.0000 varchar latin1 latin1_swedish_ci
+1.0000 text utf8 utf8_bin
1.0000 mediumtext utf8 utf8_general_ci
1.0000 text utf8 utf8_general_ci
SELECT DISTINCT
@@ -327,7 +330,7 @@ NULL mysql event starts datetime NULL NULL NULL NULL datetime
NULL mysql event ends datetime NULL NULL NULL NULL datetime
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
-3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql event sql_mode set 494 1482 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
@@ -339,7 +342,7 @@ NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
NULL mysql func ret tinyint NULL NULL NULL NULL tinyint(1)
3.0000 mysql func dl char 128 384 utf8 utf8_bin char(128)
3.0000 mysql func type enum 9 27 utf8 utf8_general_ci enum('function','aggregate')
-NULL mysql general_log event_time timestamp NULL NULL NULL NULL timestamp
+NULL mysql general_log event_time timestamp NULL NULL NULL NULL timestamp(6)
1.0000 mysql general_log user_host mediumtext 16777215 16777215 utf8 utf8_general_ci mediumtext
NULL mysql general_log thread_id int NULL NULL NULL NULL int(11)
NULL mysql general_log server_id int NULL NULL NULL NULL int(10) unsigned
@@ -402,7 +405,7 @@ NULL mysql ndb_binlog_index schemaops bigint NULL NULL NULL NULL bigint(20) unsi
3.0000 mysql proc definer char 77 231 utf8 utf8_bin char(77)
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
-3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql proc sql_mode set 494 1482 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql proc comment char 64 192 utf8 utf8_bin char(64)
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)
@@ -425,10 +428,10 @@ NULL mysql servers Port int NULL NULL NULL NULL int(4)
3.0000 mysql servers Socket char 64 192 utf8 utf8_general_ci char(64)
3.0000 mysql servers Wrapper char 64 192 utf8 utf8_general_ci char(64)
3.0000 mysql servers Owner char 64 192 utf8 utf8_general_ci char(64)
-NULL mysql slow_log start_time timestamp NULL NULL NULL NULL timestamp
+NULL mysql slow_log start_time timestamp NULL NULL NULL NULL timestamp(6)
1.0000 mysql slow_log user_host mediumtext 16777215 16777215 utf8 utf8_general_ci mediumtext
-NULL mysql slow_log query_time time NULL NULL NULL NULL time
-NULL mysql slow_log lock_time time NULL NULL NULL NULL time
+NULL mysql slow_log query_time time NULL NULL NULL NULL time(6)
+NULL mysql slow_log lock_time time NULL NULL NULL NULL time(6)
NULL mysql slow_log rows_sent int NULL NULL NULL NULL int(11)
NULL mysql slow_log rows_examined int NULL NULL NULL NULL int(11)
3.0000 mysql slow_log db varchar 512 1536 utf8 utf8_general_ci varchar(512)
@@ -497,3 +500,5 @@ NULL mysql user max_questions int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_updates int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_connections int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_user_connections int NULL NULL NULL NULL int(11) unsigned
+1.0000 mysql user plugin char 60 60 latin1 latin1_swedish_ci char(60)
+1.0000 mysql user auth_string text 65535 65535 utf8 utf8_bin text
diff --git a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result
index 187724a035c..f4fe0a880e7 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result
@@ -38,6 +38,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME CLIENT_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME COLLATIONS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -245,6 +268,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME INDEX_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME INNODB_BUFFER_POOL_PAGES
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -498,6 +544,75 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_INDEXES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_STATS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_TABLES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME INNODB_TABLE_STATS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -544,6 +659,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME KEY_CACHES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME KEY_COLUMN_USAGE
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -590,6 +728,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME PBXT_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME PLUGINS
TABLE_TYPE SYSTEM VIEW
ENGINE MYISAM_OR_MARIA
@@ -866,6 +1027,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME TABLE_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME TRIGGERS
TABLE_TYPE SYSTEM VIEW
ENGINE MYISAM_OR_MARIA
@@ -912,6 +1096,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME USER_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME VIEWS
TABLE_TYPE SYSTEM VIEW
ENGINE MYISAM_OR_MARIA
@@ -935,6 +1142,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME XTRADB_ADMIN_COMMAND
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME XTRADB_ENHANCEMENTS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -998,6 +1228,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME CLIENT_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME COLLATIONS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1205,6 +1458,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME INDEX_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME INNODB_BUFFER_POOL_PAGES
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1458,6 +1734,75 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_INDEXES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_STATS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_TABLES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME INNODB_TABLE_STATS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1504,6 +1849,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME KEY_CACHES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME KEY_COLUMN_USAGE
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1550,6 +1918,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME PBXT_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME PLUGINS
TABLE_TYPE SYSTEM VIEW
ENGINE MYISAM_OR_MARIA
@@ -1826,6 +2217,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME TABLE_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME TRIGGERS
TABLE_TYPE SYSTEM VIEW
ENGINE MYISAM_OR_MARIA
@@ -1872,6 +2286,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME USER_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME VIEWS
TABLE_TYPE SYSTEM VIEW
ENGINE MYISAM_OR_MARIA
@@ -1895,6 +2332,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME XTRADB_ADMIN_COMMAND
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME XTRADB_ENHANCEMENTS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
diff --git a/mysql-test/suite/funcs_1/r/memory_func_view.result b/mysql-test/suite/funcs_1/r/memory_func_view.result
index f83a931af5c..61b375fbc1e 100644
--- a/mysql-test/suite/funcs_1/r/memory_func_view.result
+++ b/mysql-test/suite/funcs_1/r/memory_func_view.result
@@ -946,8 +946,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999
0.000000000000000000000000000000 4
-1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select left('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö',`t1_values`.`my_decimal`) AS `LEFT('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö', my_decimal)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -961,8 +961,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999
0.000000000000000000000000000000 4
-1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
DROP VIEW v1;
@@ -2451,6 +2451,8 @@ NULL NULL 1
8385959 838:59:59 3
130000 13:00:00 4
100000 10:00:00 5
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_time` as unsigned) AS `CAST(my_time AS UNSIGNED INTEGER)`,`t1_values`.`my_time` AS `my_time`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2463,6 +2465,8 @@ NULL NULL 1
8385959 838:59:59 3
130000 13:00:00 4
100000 10:00:00 5
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
DROP VIEW v1;
@@ -2557,7 +2561,9 @@ NULL NULL 1
18446744073709551615 -1 5
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e+308'
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e+308'
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as unsigned) AS `CAST(my_double AS UNSIGNED INTEGER)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2572,7 +2578,9 @@ NULL NULL 1
18446744073709551615 -1 5
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e+308'
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e+308'
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
DROP VIEW v1;
@@ -2588,9 +2596,9 @@ NULL NULL 1
0 0.000000000000000000000000000000 4
0 -1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to UNSIGNED INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to UNSIGNED INT. Value truncated.
+Error 1916 Got overflow when converting '-1.000000000000000000000000000000' to UNSIGNED INT. Value truncated.
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as unsigned) AS `CAST(my_decimal AS UNSIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2604,9 +2612,9 @@ NULL NULL 1
0 0.000000000000000000000000000000 4
0 -1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to UNSIGNED INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to UNSIGNED INT. Value truncated.
+Error 1916 Got overflow when converting '-1.000000000000000000000000000000' to UNSIGNED INT. Value truncated.
DROP VIEW v1;
@@ -2621,6 +2629,9 @@ NULL NULL 1
9223372036854775807 9223372036854775807 3
0 0 4
18446744073709551615 -1 5
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_bigint` as unsigned) AS `CAST(my_bigint AS UNSIGNED INTEGER)`,`t1_values`.`my_bigint` AS `my_bigint`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2633,6 +2644,9 @@ NULL NULL 1
9223372036854775807 9223372036854775807 3
0 0 4
18446744073709551615 -1 5
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
DROP VIEW v1;
@@ -2956,8 +2970,8 @@ NULL NULL 1
0 0.000000000000000000000000000000 4
-1 -1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as signed) AS `CAST(my_decimal AS SIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2971,8 +2985,8 @@ NULL NULL 1
0 0.000000000000000000000000000000 4
-1 -1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
DROP VIEW v1;
@@ -3283,9 +3297,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 30
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
@@ -3301,9 +3315,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 30
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1
DROP VIEW v1;
@@ -3373,9 +3387,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 29
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as decimal(37,2)) AS `CAST(my_varbinary_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3390,9 +3404,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 29
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
DROP VIEW v1;
@@ -3409,11 +3423,11 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 28
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ''
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->'
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- '
Warning 1292 Truncated incorrect DECIMAL value: '-1'
Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333'
@@ -3431,11 +3445,11 @@ NULL NULL 1
-1.00 -1
-3333.33 -3333.3333
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ''
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->'
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- '
Warning 1292 Truncated incorrect DECIMAL value: '-1'
Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333'
@@ -3455,9 +3469,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 27
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as decimal(37,2)) AS `CAST(my_varchar_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3472,9 +3486,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 27
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
DROP VIEW v1;
@@ -3491,11 +3505,11 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 26
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' '
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->'
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- '
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
@@ -3511,11 +3525,11 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 26
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' '
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->'
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- '
DROP VIEW v1;
@@ -3527,10 +3541,10 @@ my_year, id FROM t1_values
WHERE select_id = 58 OR select_id IS NULL order by id;
CAST(my_year AS TIME) my_year id
NULL NULL 1
-00:19:01 1901 2
-00:21:55 2155 3
-00:20:00 2000 4
-00:20:05 2005 5
+00:00:00 1901 2
+00:00:00 2155 3
+00:00:00 2000 4
+00:00:00 2005 5
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_year` as time) AS `CAST(my_year AS TIME)`,`t1_values`.`my_year` AS `my_year`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3539,10 +3553,10 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 58 OR select_id IS NULL) order by id;
CAST(my_year AS TIME) my_year id
NULL NULL 1
-00:19:01 1901 2
-00:21:55 2155 3
-00:20:00 2000 4
-00:20:05 2005 5
+00:00:00 1901 2
+00:00:00 2155 3
+00:00:00 2000 4
+00:00:00 2005 5
DROP VIEW v1;
@@ -3663,8 +3677,8 @@ NULL 1.7976931348623e+308 3
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Truncated incorrect time value: '-1.7976931348623e+308'
-Warning 1292 Truncated incorrect time value: '1.7976931348623e+308'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 2
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 3
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as time) AS `CAST(my_double AS TIME)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3679,8 +3693,8 @@ NULL 1.7976931348623e+308 3
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Truncated incorrect time value: '-1.7976931348623e+308'
-Warning 1292 Truncated incorrect time value: '1.7976931348623e+308'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 1
DROP VIEW v1;
@@ -3873,15 +3887,10 @@ my_year, id FROM t1_values
WHERE select_id = 47 OR select_id IS NULL order by id;
CAST(my_year AS DATETIME) my_year id
NULL NULL 1
-NULL 1901 2
-NULL 2155 3
-NULL 2000 4
-NULL 2005 5
-Warnings:
-Warning 1292 Incorrect datetime value: '1901'
-Warning 1292 Incorrect datetime value: '2155'
-Warning 1292 Incorrect datetime value: '2000'
-Warning 1292 Incorrect datetime value: '2005'
+1901-00-00 00:00:00 1901 2
+2155-00-00 00:00:00 2155 3
+2000-00-00 00:00:00 2000 4
+2005-00-00 00:00:00 2005 5
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_year` as datetime) AS `CAST(my_year AS DATETIME)`,`t1_values`.`my_year` AS `my_year`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3890,15 +3899,10 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 47 OR select_id IS NULL) order by id;
CAST(my_year AS DATETIME) my_year id
NULL NULL 1
-NULL 1901 2
-NULL 2155 3
-NULL 2000 4
-NULL 2005 5
-Warnings:
-Warning 1292 Incorrect datetime value: '1901'
-Warning 1292 Incorrect datetime value: '2155'
-Warning 1292 Incorrect datetime value: '2000'
-Warning 1292 Incorrect datetime value: '2005'
+1901-00-00 00:00:00 1901 2
+2155-00-00 00:00:00 2155 3
+2000-00-00 00:00:00 2000 4
+2005-00-00 00:00:00 2005 5
DROP VIEW v1;
@@ -3909,13 +3913,12 @@ my_time, id FROM t1_values
WHERE select_id = 46 OR select_id IS NULL order by id;
CAST(my_time AS DATETIME) my_time id
NULL NULL 1
-0000-00-00 00:00:00 -838:59:59 2
-0000-00-00 00:00:00 838:59:59 3
+NULL -838:59:59 2
+0000-01-03 22:59:59 838:59:59 3
0000-00-00 13:00:00 13:00:00 4
0000-00-00 10:00:00 10:00:00 5
Warnings:
-Warning 1292 Incorrect datetime value: '0000-00-00 838:59:59'
-Warning 1292 Incorrect datetime value: '0000-00-00 838:59:59'
+Warning 1292 Truncated incorrect datetime value: '-838:59:59'
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_time` as datetime) AS `CAST(my_time AS DATETIME)`,`t1_values`.`my_time` AS `my_time`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3924,13 +3927,12 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 46 OR select_id IS NULL) order by id;
CAST(my_time AS DATETIME) my_time id
NULL NULL 1
-0000-00-00 00:00:00 -838:59:59 2
-0000-00-00 00:00:00 838:59:59 3
+NULL -838:59:59 2
+0000-01-03 22:59:59 838:59:59 3
0000-00-00 13:00:00 13:00:00 4
0000-00-00 10:00:00 10:00:00 5
Warnings:
-Warning 1292 Incorrect datetime value: '0000-00-00 838:59:59'
-Warning 1292 Incorrect datetime value: '0000-00-00 838:59:59'
+Warning 1292 Truncated incorrect datetime value: '-838:59:59'
DROP VIEW v1;
@@ -4021,15 +4023,14 @@ CAST(my_double AS DATETIME) my_double id
NULL NULL 1
NULL -1.7976931348623e+308 2
NULL 1.7976931348623e+308 3
-NULL 0 4
+0000-00-00 00:00:00 0 4
NULL -1 5
NULL 200506271758 19
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '0'
-Warning 1292 Incorrect datetime value: '-1'
-Warning 1292 Incorrect datetime value: '200506271758'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 2
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 3
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 5
+Warning 1292 Incorrect datetime value: '200506271758' for column 'my_double' at row 6
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as datetime) AS `CAST(my_double AS DATETIME)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -4040,15 +4041,14 @@ CAST(my_double AS DATETIME) my_double id
NULL NULL 1
NULL -1.7976931348623e+308 2
NULL 1.7976931348623e+308 3
-NULL 0 4
+0000-00-00 00:00:00 0 4
NULL -1 5
NULL 200506271758 19
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '0'
-Warning 1292 Incorrect datetime value: '-1'
-Warning 1292 Incorrect datetime value: '200506271758'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '200506271758' for column 'my_double' at row 1
DROP VIEW v1;
@@ -4253,15 +4253,10 @@ my_year, id FROM t1_values
WHERE select_id = 36 OR select_id IS NULL order by id;
CAST(my_year AS DATE) my_year id
NULL NULL 1
-NULL 1901 2
-NULL 2155 3
-NULL 2000 4
-NULL 2005 5
-Warnings:
-Warning 1292 Incorrect datetime value: '1901'
-Warning 1292 Incorrect datetime value: '2155'
-Warning 1292 Incorrect datetime value: '2000'
-Warning 1292 Incorrect datetime value: '2005'
+1901-00-00 1901 2
+2155-00-00 2155 3
+2000-00-00 2000 4
+2005-00-00 2005 5
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_year` as date) AS `CAST(my_year AS DATE)`,`t1_values`.`my_year` AS `my_year`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -4270,15 +4265,10 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 36 OR select_id IS NULL) order by id;
CAST(my_year AS DATE) my_year id
NULL NULL 1
-NULL 1901 2
-NULL 2155 3
-NULL 2000 4
-NULL 2005 5
-Warnings:
-Warning 1292 Incorrect datetime value: '1901'
-Warning 1292 Incorrect datetime value: '2155'
-Warning 1292 Incorrect datetime value: '2000'
-Warning 1292 Incorrect datetime value: '2005'
+1901-00-00 1901 2
+2155-00-00 2155 3
+2000-00-00 2000 4
+2005-00-00 2005 5
DROP VIEW v1;
@@ -4395,14 +4385,13 @@ CAST(my_double AS DATE) my_double id
NULL NULL 1
NULL -1.7976931348623e+308 2
NULL 1.7976931348623e+308 3
-NULL 0 4
+0000-00-00 0 4
NULL -1 5
2005-06-27 20050627 13
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '0'
-Warning 1292 Incorrect datetime value: '-1'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 2
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 3
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 5
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as date) AS `CAST(my_double AS DATE)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -4413,14 +4402,13 @@ CAST(my_double AS DATE) my_double id
NULL NULL 1
NULL -1.7976931348623e+308 2
NULL 1.7976931348623e+308 3
-NULL 0 4
+0000-00-00 0 4
NULL -1 5
2005-06-27 20050627 13
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '0'
-Warning 1292 Incorrect datetime value: '-1'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 1
DROP VIEW v1;
diff --git a/mysql-test/suite/funcs_1/r/memory_views.result b/mysql-test/suite/funcs_1/r/memory_views.result
index 0bb03e62192..5af10d822a6 100644
--- a/mysql-test/suite/funcs_1/r/memory_views.result
+++ b/mysql-test/suite/funcs_1/r/memory_views.result
@@ -21087,6 +21087,8 @@ f59 f60 f61 a b
2 double 6 2 2
3 single-f3 6 NULL 3
4 single 4 NULL 4
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='outer_join_with_cache=off';
Create or replace view test.v1 as
Select t1.f59 t1_f59, t2.f59 t2_f59, t1.f60 t1_f60, t2.f60 t2_f60,
t1.f61 t1_f61, t2.f61 t2_f61
@@ -21117,6 +21119,7 @@ f59 f60 a b
1 single 1 NULL
2 double 2 2
3 single-f3 3 NULL
+set optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
drop view v1 ;
Use test;
diff --git a/mysql-test/suite/funcs_1/r/myisam_func_view.result b/mysql-test/suite/funcs_1/r/myisam_func_view.result
index f83a931af5c..61b375fbc1e 100644
--- a/mysql-test/suite/funcs_1/r/myisam_func_view.result
+++ b/mysql-test/suite/funcs_1/r/myisam_func_view.result
@@ -946,8 +946,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999
0.000000000000000000000000000000 4
-1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select left('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö',`t1_values`.`my_decimal`) AS `LEFT('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö', my_decimal)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -961,8 +961,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999
0.000000000000000000000000000000 4
-1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
DROP VIEW v1;
@@ -2451,6 +2451,8 @@ NULL NULL 1
8385959 838:59:59 3
130000 13:00:00 4
100000 10:00:00 5
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_time` as unsigned) AS `CAST(my_time AS UNSIGNED INTEGER)`,`t1_values`.`my_time` AS `my_time`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2463,6 +2465,8 @@ NULL NULL 1
8385959 838:59:59 3
130000 13:00:00 4
100000 10:00:00 5
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
DROP VIEW v1;
@@ -2557,7 +2561,9 @@ NULL NULL 1
18446744073709551615 -1 5
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e+308'
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e+308'
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as unsigned) AS `CAST(my_double AS UNSIGNED INTEGER)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2572,7 +2578,9 @@ NULL NULL 1
18446744073709551615 -1 5
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '-1.7976931348623e+308'
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
Warning 1292 Truncated incorrect INTEGER value: '1.7976931348623e+308'
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
DROP VIEW v1;
@@ -2588,9 +2596,9 @@ NULL NULL 1
0 0.000000000000000000000000000000 4
0 -1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to UNSIGNED INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to UNSIGNED INT. Value truncated.
+Error 1916 Got overflow when converting '-1.000000000000000000000000000000' to UNSIGNED INT. Value truncated.
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as unsigned) AS `CAST(my_decimal AS UNSIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2604,9 +2612,9 @@ NULL NULL 1
0 0.000000000000000000000000000000 4
0 -1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to UNSIGNED INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to UNSIGNED INT. Value truncated.
+Error 1916 Got overflow when converting '-1.000000000000000000000000000000' to UNSIGNED INT. Value truncated.
DROP VIEW v1;
@@ -2621,6 +2629,9 @@ NULL NULL 1
9223372036854775807 9223372036854775807 3
0 0 4
18446744073709551615 -1 5
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_bigint` as unsigned) AS `CAST(my_bigint AS UNSIGNED INTEGER)`,`t1_values`.`my_bigint` AS `my_bigint`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2633,6 +2644,9 @@ NULL NULL 1
9223372036854775807 9223372036854775807 3
0 0 4
18446744073709551615 -1 5
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
DROP VIEW v1;
@@ -2956,8 +2970,8 @@ NULL NULL 1
0 0.000000000000000000000000000000 4
-1 -1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as signed) AS `CAST(my_decimal AS SIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -2971,8 +2985,8 @@ NULL NULL 1
0 0.000000000000000000000000000000 4
-1 -1.000000000000000000000000000000 5
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
+Error 1916 Got overflow when converting '9999999999999999999999999999999999.999999999999999999999999999999' to INT. Value truncated.
DROP VIEW v1;
@@ -3283,9 +3297,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 30
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
@@ -3301,9 +3315,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 30
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1
DROP VIEW v1;
@@ -3373,9 +3387,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 29
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as decimal(37,2)) AS `CAST(my_varbinary_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3390,9 +3404,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 29
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
DROP VIEW v1;
@@ -3409,11 +3423,11 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 28
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ''
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->'
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- '
Warning 1292 Truncated incorrect DECIMAL value: '-1'
Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333'
@@ -3431,11 +3445,11 @@ NULL NULL 1
-1.00 -1
-3333.33 -3333.3333
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ''
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->'
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- '
Warning 1292 Truncated incorrect DECIMAL value: '-1'
Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333'
@@ -3455,9 +3469,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 27
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as decimal(37,2)) AS `CAST(my_varchar_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3472,9 +3486,9 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 27
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
+Error 1918 Encountered illegal value '' when converting to DECIMAL
DROP VIEW v1;
@@ -3491,11 +3505,11 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 26
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' '
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->'
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- '
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
@@ -3511,11 +3525,11 @@ NULL NULL 1
-1.00 -1 5
-3333.33 -3333.3333 26
Warnings:
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' '
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->'
-Error 1366 Incorrect decimal value: '' for column '' at row 0
+Error 1918 Encountered illegal value '' when converting to DECIMAL
Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- '
DROP VIEW v1;
@@ -3527,10 +3541,10 @@ my_year, id FROM t1_values
WHERE select_id = 58 OR select_id IS NULL order by id;
CAST(my_year AS TIME) my_year id
NULL NULL 1
-00:19:01 1901 2
-00:21:55 2155 3
-00:20:00 2000 4
-00:20:05 2005 5
+00:00:00 1901 2
+00:00:00 2155 3
+00:00:00 2000 4
+00:00:00 2005 5
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_year` as time) AS `CAST(my_year AS TIME)`,`t1_values`.`my_year` AS `my_year`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3539,10 +3553,10 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 58 OR select_id IS NULL) order by id;
CAST(my_year AS TIME) my_year id
NULL NULL 1
-00:19:01 1901 2
-00:21:55 2155 3
-00:20:00 2000 4
-00:20:05 2005 5
+00:00:00 1901 2
+00:00:00 2155 3
+00:00:00 2000 4
+00:00:00 2005 5
DROP VIEW v1;
@@ -3663,8 +3677,8 @@ NULL 1.7976931348623e+308 3
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Truncated incorrect time value: '-1.7976931348623e+308'
-Warning 1292 Truncated incorrect time value: '1.7976931348623e+308'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 2
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 3
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as time) AS `CAST(my_double AS TIME)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3679,8 +3693,8 @@ NULL 1.7976931348623e+308 3
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Truncated incorrect time value: '-1.7976931348623e+308'
-Warning 1292 Truncated incorrect time value: '1.7976931348623e+308'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 1
DROP VIEW v1;
@@ -3873,15 +3887,10 @@ my_year, id FROM t1_values
WHERE select_id = 47 OR select_id IS NULL order by id;
CAST(my_year AS DATETIME) my_year id
NULL NULL 1
-NULL 1901 2
-NULL 2155 3
-NULL 2000 4
-NULL 2005 5
-Warnings:
-Warning 1292 Incorrect datetime value: '1901'
-Warning 1292 Incorrect datetime value: '2155'
-Warning 1292 Incorrect datetime value: '2000'
-Warning 1292 Incorrect datetime value: '2005'
+1901-00-00 00:00:00 1901 2
+2155-00-00 00:00:00 2155 3
+2000-00-00 00:00:00 2000 4
+2005-00-00 00:00:00 2005 5
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_year` as datetime) AS `CAST(my_year AS DATETIME)`,`t1_values`.`my_year` AS `my_year`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3890,15 +3899,10 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 47 OR select_id IS NULL) order by id;
CAST(my_year AS DATETIME) my_year id
NULL NULL 1
-NULL 1901 2
-NULL 2155 3
-NULL 2000 4
-NULL 2005 5
-Warnings:
-Warning 1292 Incorrect datetime value: '1901'
-Warning 1292 Incorrect datetime value: '2155'
-Warning 1292 Incorrect datetime value: '2000'
-Warning 1292 Incorrect datetime value: '2005'
+1901-00-00 00:00:00 1901 2
+2155-00-00 00:00:00 2155 3
+2000-00-00 00:00:00 2000 4
+2005-00-00 00:00:00 2005 5
DROP VIEW v1;
@@ -3909,13 +3913,12 @@ my_time, id FROM t1_values
WHERE select_id = 46 OR select_id IS NULL order by id;
CAST(my_time AS DATETIME) my_time id
NULL NULL 1
-0000-00-00 00:00:00 -838:59:59 2
-0000-00-00 00:00:00 838:59:59 3
+NULL -838:59:59 2
+0000-01-03 22:59:59 838:59:59 3
0000-00-00 13:00:00 13:00:00 4
0000-00-00 10:00:00 10:00:00 5
Warnings:
-Warning 1292 Incorrect datetime value: '0000-00-00 838:59:59'
-Warning 1292 Incorrect datetime value: '0000-00-00 838:59:59'
+Warning 1292 Truncated incorrect datetime value: '-838:59:59'
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_time` as datetime) AS `CAST(my_time AS DATETIME)`,`t1_values`.`my_time` AS `my_time`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3924,13 +3927,12 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 46 OR select_id IS NULL) order by id;
CAST(my_time AS DATETIME) my_time id
NULL NULL 1
-0000-00-00 00:00:00 -838:59:59 2
-0000-00-00 00:00:00 838:59:59 3
+NULL -838:59:59 2
+0000-01-03 22:59:59 838:59:59 3
0000-00-00 13:00:00 13:00:00 4
0000-00-00 10:00:00 10:00:00 5
Warnings:
-Warning 1292 Incorrect datetime value: '0000-00-00 838:59:59'
-Warning 1292 Incorrect datetime value: '0000-00-00 838:59:59'
+Warning 1292 Truncated incorrect datetime value: '-838:59:59'
DROP VIEW v1;
@@ -4021,15 +4023,14 @@ CAST(my_double AS DATETIME) my_double id
NULL NULL 1
NULL -1.7976931348623e+308 2
NULL 1.7976931348623e+308 3
-NULL 0 4
+0000-00-00 00:00:00 0 4
NULL -1 5
NULL 200506271758 19
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '0'
-Warning 1292 Incorrect datetime value: '-1'
-Warning 1292 Incorrect datetime value: '200506271758'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 2
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 3
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 5
+Warning 1292 Incorrect datetime value: '200506271758' for column 'my_double' at row 6
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as datetime) AS `CAST(my_double AS DATETIME)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -4040,15 +4041,14 @@ CAST(my_double AS DATETIME) my_double id
NULL NULL 1
NULL -1.7976931348623e+308 2
NULL 1.7976931348623e+308 3
-NULL 0 4
+0000-00-00 00:00:00 0 4
NULL -1 5
NULL 200506271758 19
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '0'
-Warning 1292 Incorrect datetime value: '-1'
-Warning 1292 Incorrect datetime value: '200506271758'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '200506271758' for column 'my_double' at row 1
DROP VIEW v1;
@@ -4253,15 +4253,10 @@ my_year, id FROM t1_values
WHERE select_id = 36 OR select_id IS NULL order by id;
CAST(my_year AS DATE) my_year id
NULL NULL 1
-NULL 1901 2
-NULL 2155 3
-NULL 2000 4
-NULL 2005 5
-Warnings:
-Warning 1292 Incorrect datetime value: '1901'
-Warning 1292 Incorrect datetime value: '2155'
-Warning 1292 Incorrect datetime value: '2000'
-Warning 1292 Incorrect datetime value: '2005'
+1901-00-00 1901 2
+2155-00-00 2155 3
+2000-00-00 2000 4
+2005-00-00 2005 5
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_year` as date) AS `CAST(my_year AS DATE)`,`t1_values`.`my_year` AS `my_year`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -4270,15 +4265,10 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 36 OR select_id IS NULL) order by id;
CAST(my_year AS DATE) my_year id
NULL NULL 1
-NULL 1901 2
-NULL 2155 3
-NULL 2000 4
-NULL 2005 5
-Warnings:
-Warning 1292 Incorrect datetime value: '1901'
-Warning 1292 Incorrect datetime value: '2155'
-Warning 1292 Incorrect datetime value: '2000'
-Warning 1292 Incorrect datetime value: '2005'
+1901-00-00 1901 2
+2155-00-00 2155 3
+2000-00-00 2000 4
+2005-00-00 2005 5
DROP VIEW v1;
@@ -4395,14 +4385,13 @@ CAST(my_double AS DATE) my_double id
NULL NULL 1
NULL -1.7976931348623e+308 2
NULL 1.7976931348623e+308 3
-NULL 0 4
+0000-00-00 0 4
NULL -1 5
2005-06-27 20050627 13
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '0'
-Warning 1292 Incorrect datetime value: '-1'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 2
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 3
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 5
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as date) AS `CAST(my_double AS DATE)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -4413,14 +4402,13 @@ CAST(my_double AS DATE) my_double id
NULL NULL 1
NULL -1.7976931348623e+308 2
NULL 1.7976931348623e+308 3
-NULL 0 4
+0000-00-00 0 4
NULL -1 5
2005-06-27 20050627 13
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '1.7976931348623e+308'
-Warning 1292 Incorrect datetime value: '0'
-Warning 1292 Incorrect datetime value: '-1'
+Warning 1292 Incorrect datetime value: '-1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e+308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 1
DROP VIEW v1;
diff --git a/mysql-test/suite/funcs_1/r/myisam_views-big.result b/mysql-test/suite/funcs_1/r/myisam_views-big.result
index 0afb1d7d6c8..cfd15293b7b 100644
--- a/mysql-test/suite/funcs_1/r/myisam_views-big.result
+++ b/mysql-test/suite/funcs_1/r/myisam_views-big.result
@@ -22754,6 +22754,8 @@ f59 f60 f61 a b
2 double 6 2 2
3 single-f3 6 NULL 3
4 single 4 NULL 4
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='outer_join_with_cache=off';
Create or replace view test.v1 as
Select t1.f59 t1_f59, t2.f59 t2_f59, t1.f60 t1_f60, t2.f60 t2_f60,
t1.f61 t1_f61, t2.f61 t2_f61
@@ -22784,6 +22786,7 @@ f59 f60 a b
1 single 1 NULL
2 double 2 2
3 single-f3 3 NULL
+set optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
drop view v1 ;
Use test;
diff --git a/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result b/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result
index d5b6cc17801..b5d330dffb5 100644
--- a/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result
+++ b/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result
@@ -30,30 +30,31 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext,
- `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Query TIME NULL SHOW processlist
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-SELECT * FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID root HOST_NAME information_schema Query TIME executing SELECT * FROM processlist ORDER BY id TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
-SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID root HOST_NAME information_schema Query TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id TIME_MS
+Id User Host db Command Time State Info Progress
+ID root HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+SELECT * FROM processlist ORDER BY id;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID root HOST_NAME information_schema Query TIME executing SELECT * FROM processlist ORDER BY id TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID root HOST_NAME information_schema Query TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist;
UPDATE test.t_processlist SET user='horst' WHERE id=1 ;
INSERT INTO processlist SELECT * FROM test.t_processlist;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
DROP TABLE test.t_processlist;
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist WITH CHECK OPTION;
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist WITH CHECK OPTION;
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist;
-UPDATE test.v_processlist SET TIME=NOW() WHERE id = 1;
-ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist;
DROP VIEW test.v_processlist;
UPDATE processlist SET user='any_user' WHERE id=1 ;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
@@ -101,27 +102,28 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext,
- `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM processlist ORDER BY id TIME_MS
-SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id TIME_MS
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM processlist ORDER BY id TIME_MS 0 0 0.000
+SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id TIME_MS 0 0 0.000
CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist;
UPDATE test.t_processlist SET user='horst' WHERE id=1 ;
INSERT INTO processlist SELECT * FROM test.t_processlist;
ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
DROP TABLE test.t_processlist;
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist WITH CHECK OPTION;
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist WITH CHECK OPTION;
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist;
-UPDATE test.v_processlist SET TIME=NOW() WHERE id = 1;
-ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist;
DROP VIEW test.v_processlist;
UPDATE processlist SET user='any_user' WHERE id=1 ;
ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
@@ -169,11 +171,11 @@ SHOW GRANTS;
Grants for ddicttestuser1@localhost
GRANT PROCESS ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
####################################################################################
4.2 New connection con101 (ddicttestuser1 with PROCESS privilege)
SHOW/SELECT shows all processes/threads.
@@ -182,15 +184,15 @@ SHOW GRANTS;
Grants for ddicttestuser1@localhost
GRANT PROCESS ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+Id User Host db Command Time State Info Progress
ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
5 Grant PROCESS privilege to anonymous user.
connection default (user=root)
@@ -205,17 +207,17 @@ SHOW GRANTS;
Grants for @localhost
GRANT PROCESS ON *.* TO ''@'localhost'
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
-ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
6 Revoke PROCESS privilege from ddicttestuser1
connection default (user=root)
@@ -230,15 +232,15 @@ SHOW GRANTS;
Grants for ddicttestuser1@localhost
GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
7 Revoke PROCESS privilege from anonymous user
connection default (user=root)
@@ -253,9 +255,9 @@ SHOW GRANTS FOR ''@'localhost';
Grants for @localhost
GRANT USAGE ON *.* TO ''@'localhost'
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
-ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
8 Grant SUPER (does not imply PROCESS) privilege to ddicttestuser1
connection default (user=root)
@@ -269,17 +271,17 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
Grants for ddicttestuser1@localhost
GRANT SUPER ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
9 Revoke SUPER privilege from user ddicttestuser1
connection default (user=root)
@@ -294,19 +296,19 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
Grants for ddicttestuser1@localhost
GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
10 Grant SUPER privilege with grant option to user ddicttestuser1.
connection default (user=root)
@@ -342,23 +344,8 @@ SHOW GRANTS FOR 'ddicttestuser2'@'localhost';
Grants for ddicttestuser2@localhost
GRANT PROCESS ON *.* TO 'ddicttestuser2'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser2 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+Id User Host db Command Time State Info Progress
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
@@ -366,7 +353,22 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
-ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser2 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
11 User ddicttestuser1 revokes PROCESS privilege from user ddicttestuser2
connection ddicttestuser1;
@@ -380,13 +382,13 @@ SHOW GRANTS;
Grants for ddicttestuser2@localhost
GRANT USAGE ON *.* TO 'ddicttestuser2'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser2 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser2 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
11.2 Revoke SUPER,PROCESS,GRANT OPTION privilege from user ddicttestuser1
connection default (user=root)
@@ -403,18 +405,7 @@ GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA
GRANT PROCESS ON *.* TO 'ddicttestuser2'@'localhost';
ERROR 28000: Access denied for user 'ddicttestuser1'@'localhost' (using password: YES)
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
@@ -422,6 +413,17 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
12 Revoke the SELECT privilege from user ddicttestuser1
connection default (user=root)
@@ -438,19 +440,7 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
Grants for ddicttestuser1@localhost
GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
@@ -459,6 +449,18 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
12.2 Revoke only the SELECT privilege on the information_schema from ddicttestuser1.
connection default (user=root)
diff --git a/mysql-test/suite/funcs_1/r/processlist_priv_ps.result b/mysql-test/suite/funcs_1/r/processlist_priv_ps.result
index c05c9549334..bc4c197a4bb 100644
--- a/mysql-test/suite/funcs_1/r/processlist_priv_ps.result
+++ b/mysql-test/suite/funcs_1/r/processlist_priv_ps.result
@@ -30,30 +30,31 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext,
- `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Query TIME NULL SHOW processlist
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-SELECT * FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID root HOST_NAME information_schema Execute TIME executing SELECT * FROM processlist ORDER BY id TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
-SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID root HOST_NAME information_schema Execute TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id TIME_MS
+Id User Host db Command Time State Info Progress
+ID root HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+SELECT * FROM processlist ORDER BY id;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID root HOST_NAME information_schema Execute TIME executing SELECT * FROM processlist ORDER BY id TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID root HOST_NAME information_schema Execute TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist;
UPDATE test.t_processlist SET user='horst' WHERE id=1 ;
INSERT INTO processlist SELECT * FROM test.t_processlist;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
DROP TABLE test.t_processlist;
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist WITH CHECK OPTION;
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist WITH CHECK OPTION;
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist;
-UPDATE test.v_processlist SET TIME=NOW() WHERE id = 1;
-ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist;
DROP VIEW test.v_processlist;
UPDATE processlist SET user='any_user' WHERE id=1 ;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
@@ -101,27 +102,28 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext,
- `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM processlist ORDER BY id TIME_MS
-SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id TIME_MS
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM processlist ORDER BY id TIME_MS 0 0 0.000
+SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id TIME_MS 0 0 0.000
CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist;
UPDATE test.t_processlist SET user='horst' WHERE id=1 ;
INSERT INTO processlist SELECT * FROM test.t_processlist;
ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
DROP TABLE test.t_processlist;
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist WITH CHECK OPTION;
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist WITH CHECK OPTION;
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist;
-UPDATE test.v_processlist SET TIME=NOW() WHERE id = 1;
-ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist;
DROP VIEW test.v_processlist;
UPDATE processlist SET user='any_user' WHERE id=1 ;
ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
@@ -169,11 +171,11 @@ SHOW GRANTS;
Grants for ddicttestuser1@localhost
GRANT PROCESS ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
####################################################################################
4.2 New connection con101 (ddicttestuser1 with PROCESS privilege)
SHOW/SELECT shows all processes/threads.
@@ -182,15 +184,15 @@ SHOW GRANTS;
Grants for ddicttestuser1@localhost
GRANT PROCESS ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+Id User Host db Command Time State Info Progress
ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
5 Grant PROCESS privilege to anonymous user.
connection default (user=root)
@@ -205,17 +207,17 @@ SHOW GRANTS;
Grants for @localhost
GRANT PROCESS ON *.* TO ''@'localhost'
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
-ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
6 Revoke PROCESS privilege from ddicttestuser1
connection default (user=root)
@@ -230,15 +232,15 @@ SHOW GRANTS;
Grants for ddicttestuser1@localhost
GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
7 Revoke PROCESS privilege from anonymous user
connection default (user=root)
@@ -253,9 +255,9 @@ SHOW GRANTS FOR ''@'localhost';
Grants for @localhost
GRANT USAGE ON *.* TO ''@'localhost'
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
-ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
8 Grant SUPER (does not imply PROCESS) privilege to ddicttestuser1
connection default (user=root)
@@ -269,17 +271,17 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
Grants for ddicttestuser1@localhost
GRANT SUPER ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
9 Revoke SUPER privilege from user ddicttestuser1
connection default (user=root)
@@ -294,19 +296,19 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
Grants for ddicttestuser1@localhost
GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
10 Grant SUPER privilege with grant option to user ddicttestuser1.
connection default (user=root)
@@ -342,23 +344,8 @@ SHOW GRANTS FOR 'ddicttestuser2'@'localhost';
Grants for ddicttestuser2@localhost
GRANT PROCESS ON *.* TO 'ddicttestuser2'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser2 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+Id User Host db Command Time State Info Progress
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
@@ -366,7 +353,22 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
-ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser2 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
11 User ddicttestuser1 revokes PROCESS privilege from user ddicttestuser2
connection ddicttestuser1;
@@ -380,13 +382,13 @@ SHOW GRANTS;
Grants for ddicttestuser2@localhost
GRANT USAGE ON *.* TO 'ddicttestuser2'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser2 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser2 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
11.2 Revoke SUPER,PROCESS,GRANT OPTION privilege from user ddicttestuser1
connection default (user=root)
@@ -403,18 +405,7 @@ GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA
GRANT PROCESS ON *.* TO 'ddicttestuser2'@'localhost';
ERROR 28000: Access denied for user 'ddicttestuser1'@'localhost' (using password: YES)
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
@@ -422,6 +413,17 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
12 Revoke the SELECT privilege from user ddicttestuser1
connection default (user=root)
@@ -438,19 +440,7 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
Grants for ddicttestuser1@localhost
GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
@@ -459,6 +449,18 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
12.2 Revoke only the SELECT privilege on the information_schema from ddicttestuser1.
connection default (user=root)
diff --git a/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result b/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result
index 431133cd2c8..c5533166acc 100644
--- a/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result
+++ b/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result
@@ -20,17 +20,20 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext,
- `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
# Ensure that the information about the own connection is correct.
#--------------------------------------------------------------------------
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> root <HOST_NAME> test Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> root <HOST_NAME> test Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> test Query <TIME> NULL SHOW FULL PROCESSLIST
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> test Query <TIME> NULL SHOW FULL PROCESSLIST <TIME_MS>
SET @default_id = CONNECTION_ID();
SELECT COUNT(*) = 1 AS "Expect exact one connection with this id"
FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = @default_id;
@@ -73,13 +76,13 @@ Has TIME a reasonable value?
# Poll till the connection con1 is in state COMMAND = 'Sleep'.
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS>
-<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL 0.000
SELECT ID,TIME INTO @test_user_con1_id,@time FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE COMMAND = 'Sleep' AND USER = 'test_user';
SELECT @test_user_con1_id = @default_id + 1
@@ -107,11 +110,11 @@ Expect 1
# ----- switch to connection con1 (user = test_user) -----
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
+Id User Host db Command Time State Info Progress
+<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
# Ensure that the user test_user sees all connections with his username.
#----------------------------------------------------------------------------
@@ -124,13 +127,13 @@ Id User Host db Command Time State Info
# ----- switch to connection con2 (user = test_user) -----
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL
-<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
+Id User Host db Command Time State Info Progress
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
# ----- switch to connection default (user = root) -----
SELECT ID INTO @test_user_con2_id FROM INFORMATION_SCHEMA.PROCESSLIST
@@ -150,15 +153,15 @@ SELECT sleep(10), 17;
# Poll till connection con2 is in state 'User sleep'.
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17 <TIME_MS>
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS>
-<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17 <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL
-<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17 0.000
SELECT STATE, TIME, INFO INTO @state, @time, @info
FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID = @test_user_con2_id;
@@ -194,13 +197,13 @@ LOCK TABLE test.t1 WRITE;
SELECT COUNT(*) FROM test.t1;
# ----- switch to connection default (user = root) -----
-# Poll till INFO is no more NULL and State = 'Locked'.
+# Poll till INFO is no more NULL and State = "Table Lock".
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Query <TIME> Locked SELECT COUNT(*) FROM test.t1 <TIME_MS>
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS>
-<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Query <TIME> Table lock SELECT COUNT(*) FROM test.t1 <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
UNLOCK TABLES;
# ----- switch to connection con2 (user = test_user) -----
@@ -222,7 +225,7 @@ LOCK TABLE test.t1 WRITE;
SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1;
# ----- switch to connection default (user = root) -----
-# Poll till INFO is no more NULL and State = 'Locked'.
+# Poll till INFO is no more NULL and State = "Table Lock".
# Expect result:
# Statement Content of INFO
@@ -231,20 +234,20 @@ SELECT count(*),'BEGIN-This is the representative of a very long statement.This
# SHOW PROCESSLIST statement truncated after 100 char
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1 <TIME_MS>
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL <TIME_MS>
-<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1 <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW FULL PROCESSLIST
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW FULL PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1 0.000
SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW PROCESSLIST
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representativ
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representativ 0.000
UNLOCK TABLES;
# ----- switch to connection con2 (user = test_user) -----
diff --git a/mysql-test/suite/funcs_1/r/processlist_val_ps.result b/mysql-test/suite/funcs_1/r/processlist_val_ps.result
index 86f290daea7..546f2a19b61 100644
--- a/mysql-test/suite/funcs_1/r/processlist_val_ps.result
+++ b/mysql-test/suite/funcs_1/r/processlist_val_ps.result
@@ -20,17 +20,20 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext,
- `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
# Ensure that the information about the own connection is correct.
#--------------------------------------------------------------------------
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> root <HOST_NAME> test Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> root <HOST_NAME> test Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> test Query <TIME> NULL SHOW FULL PROCESSLIST
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> test Query <TIME> NULL SHOW FULL PROCESSLIST <TIME_MS>
SET @default_id = CONNECTION_ID();
SELECT COUNT(*) = 1 AS "Expect exact one connection with this id"
FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = @default_id;
@@ -73,13 +76,13 @@ Has TIME a reasonable value?
# Poll till the connection con1 is in state COMMAND = 'Sleep'.
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS>
-<ID> root <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL 0.000
SELECT ID,TIME INTO @test_user_con1_id,@time FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE COMMAND = 'Sleep' AND USER = 'test_user';
SELECT @test_user_con1_id = @default_id + 1
@@ -107,11 +110,11 @@ Expect 1
# ----- switch to connection con1 (user = test_user) -----
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
+Id User Host db Command Time State Info Progress
+<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
# Ensure that the user test_user sees all connections with his username.
#----------------------------------------------------------------------------
@@ -124,13 +127,13 @@ Id User Host db Command Time State Info
# ----- switch to connection con2 (user = test_user) -----
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL
-<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
+Id User Host db Command Time State Info Progress
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
# ----- switch to connection default (user = root) -----
SELECT ID INTO @test_user_con2_id FROM INFORMATION_SCHEMA.PROCESSLIST
@@ -150,15 +153,15 @@ SELECT sleep(10), 17;
# Poll till connection con2 is in state 'User sleep'.
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17 <TIME_MS>
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS>
-<ID> root <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17 <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL
-<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17 0.000
SELECT STATE, TIME, INFO INTO @state, @time, @info
FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID = @test_user_con2_id;
@@ -194,13 +197,13 @@ LOCK TABLE test.t1 WRITE;
SELECT COUNT(*) FROM test.t1;
# ----- switch to connection default (user = root) -----
-# Poll till INFO is no more NULL and State = 'Locked'.
+# Poll till INFO is no more NULL and State = "Table Lock".
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Query <TIME> Locked SELECT COUNT(*) FROM test.t1 <TIME_MS>
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS>
-<ID> root <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Query <TIME> Table lock SELECT COUNT(*) FROM test.t1 <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
UNLOCK TABLES;
# ----- switch to connection con2 (user = test_user) -----
@@ -222,7 +225,7 @@ LOCK TABLE test.t1 WRITE;
SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1;
# ----- switch to connection default (user = root) -----
-# Poll till INFO is no more NULL and State = 'Locked'.
+# Poll till INFO is no more NULL and State = "Table Lock".
# Expect result:
# Statement Content of INFO
@@ -231,20 +234,20 @@ SELECT count(*),'BEGIN-This is the representative of a very long statement.This
# SHOW PROCESSLIST statement truncated after 100 char
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1 <TIME_MS>
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL <TIME_MS>
-<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1 <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW FULL PROCESSLIST
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW FULL PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1 0.000
SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW PROCESSLIST
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representativ
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representativ 0.000
UNLOCK TABLES;
# ----- switch to connection con2 (user = test_user) -----
diff --git a/mysql-test/suite/funcs_1/r/storedproc.result b/mysql-test/suite/funcs_1/r/storedproc.result
index 7647579820a..57cb2cfb5ae 100644
--- a/mysql-test/suite/funcs_1/r/storedproc.result
+++ b/mysql-test/suite/funcs_1/r/storedproc.result
@@ -142,7 +142,7 @@ BEGIN
SET @v1 = f1;
SELECT @v1;
END//
-ERROR 42000: Too big precision 256 specified for column ''. Maximum is 65.
+ERROR 42000: Too big precision 256 specified for ''. Maximum is 65.
DROP PROCEDURE IF EXISTS sp1//
Warnings:
Note 1305 PROCEDURE sp1 does not exist
@@ -152,7 +152,7 @@ BEGIN
SET @v1 = f1;
SELECT @v1;
END//
-ERROR 42000: Too big precision 66 specified for column ''. Maximum is 65.
+ERROR 42000: Too big precision 66 specified for ''. Maximum is 65.
DROP PROCEDURE IF EXISTS sp1//
Warnings:
Note 1305 PROCEDURE sp1 does not exist
@@ -1551,7 +1551,7 @@ BEGIN
SET f1 = 1000000 + f1;
RETURN f1;
END//
-ERROR 42000: Too big scale 31 specified for column ''. Maximum is 30.
+ERROR 42000: Too big scale 31 specified for ''. Maximum is 30.
SELECT fn1( 1.3326e+8 );
ERROR 42000: FUNCTION db_storedproc.fn1 does not exist
CREATE FUNCTION fn1( f1 DECIMAL(63, 30) ) RETURNS DECIMAL(63, 30)
@@ -3942,7 +3942,9 @@ CREATE PROCEDURE sp1()
alter:BEGIN
SELECT @x;
END//
-ERROR 0A000: ALTER VIEW is not allowed in stored procedures
+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 ':BEGIN
+SELECT @x;
+END' at line 2
DROP PROCEDURE IF EXISTS sp1;
CREATE PROCEDURE sp1()
analyze:BEGIN
@@ -5838,7 +5840,7 @@ fetch cur1 into e;
SELECT x, y, z, a, b, c, d, e;
close cur1;
END//
-ERROR 42000: Too big scale 255 specified for column ''. Maximum is 30.
+ERROR 42000: Too big scale 255 specified for ''. Maximum is 30.
CALL sp6();
ERROR 42000: PROCEDURE db_storedproc.sp6 does not exist
DROP PROCEDURE IF EXISTS sp6;
@@ -13936,7 +13938,7 @@ CALL sp1();
xx
0000-00-00 00:00:00
Warnings:
-Warning 1264 Out of range value for column 'xx' at row 1
+Warning 1265 Data truncated for column 'xx' at row 1
DROP PROCEDURE IF EXISTS sp1;
CREATE PROCEDURE sp1()
BEGIN
diff --git a/mysql-test/suite/funcs_1/t/storedproc.test b/mysql-test/suite/funcs_1/t/storedproc.test
index 16c4d61bf58..3bd3199da4e 100644
--- a/mysql-test/suite/funcs_1/t/storedproc.test
+++ b/mysql-test/suite/funcs_1/t/storedproc.test
@@ -3082,7 +3082,7 @@ DROP PROCEDURE IF EXISTS sp1;
--enable_warnings
delimiter //;
---error ER_SP_BADSTATEMENT
+--error ER_PARSE_ERROR
CREATE PROCEDURE sp1()
alter:BEGIN
SELECT @x;
diff --git a/mysql-test/suite/funcs_1/views/views_master.inc b/mysql-test/suite/funcs_1/views/views_master.inc
index 4f8439efc3a..1069ba3eaa7 100644
--- a/mysql-test/suite/funcs_1/views/views_master.inc
+++ b/mysql-test/suite/funcs_1/views/views_master.inc
@@ -2541,6 +2541,10 @@ Select f59, f60, f61, t1.a, t2.b
FROM t2 natural left outer join t1;
# Testcase 3.3.1.61 ;
+
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='outer_join_with_cache=off';
+
Create or replace view test.v1 as
Select t1.f59 t1_f59, t2.f59 t2_f59, t1.f60 t1_f60, t2.f60 t2_f60,
t1.f61 t1_f61, t2.f61 t2_f61
@@ -2558,6 +2562,8 @@ Select * from v1 order by f59 desc;
Select f59, f60, a, b
FROM t2 natural right outer join t1;
+set optimizer_switch=@save_optimizer_switch;
+
drop table t1, t2;
drop view v1 ;
@@ -3830,6 +3836,7 @@ while ($num)
--error ER_NON_INSERTABLE_TABLE
INSERT INTO v1 VALUES (1002);
# --error ER_NON_UPDATABLE_TABLE, ER_UPDATE_TABLE_USED
+
--error ER_NON_UPDATABLE_TABLE
UPDATE v1 SET f61=1007;
--error ER_NON_UPDATABLE_TABLE
diff --git a/mysql-test/suite/handler/aria.result b/mysql-test/suite/handler/aria.result
index a912a2559e3..efddd7784fd 100644
--- a/mysql-test/suite/handler/aria.result
+++ b/mysql-test/suite/handler/aria.result
@@ -4,50 +4,50 @@ create table t1 (a int, b char(10), key a (a), key b (a,b));
insert into t1 values
(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
(14,"aaa"),(16,"ccc"),(16,"xxx"),
-(20,"ggg"),(21,"hhh"),(22,"iii");
+(20,"ggg"),(21,"hhh"),(22,"iii"),(23,"xxx"),(24,"xxx"),(25,"xxx");
handler t1 open as t2;
-handler t2 read a first;
+handler t2 read b first;
a b
14 aaa
-handler t2 read a next;
+handler t2 read b next;
a b
16 ccc
-handler t2 read a next;
+handler t2 read b next;
a b
16 xxx
-handler t2 read a prev;
+handler t2 read b prev;
a b
16 ccc
-handler t2 read a last;
+handler t2 read b last;
a b
-22 iii
-handler t2 read a prev;
+25 xxx
+handler t2 read b prev;
a b
-21 hhh
-handler t2 read a prev;
+24 xxx
+handler t2 read b prev;
a b
-20 ggg
-handler t2 read a first;
+23 xxx
+handler t2 read b first;
a b
14 aaa
-handler t2 read a prev;
+handler t2 read b prev;
a b
-handler t2 read a last;
+handler t2 read b last;
a b
-22 iii
-handler t2 read a prev;
+25 xxx
+handler t2 read b prev;
a b
-21 hhh
-handler t2 read a next;
+24 xxx
+handler t2 read b next;
a b
-22 iii
-handler t2 read a next;
+25 xxx
+handler t2 read b next;
a b
handler t2 read a=(15);
a b
-handler t2 read a=(16);
+handler t2 read a=(21);
a b
-16 ccc
+21 hhh
handler t2 read a=(19,"fff");
ERROR 42000: Too many key parts specified; max 1 parts allowed
handler t2 read b=(19,"fff");
@@ -66,29 +66,31 @@ a b
handler t2 read a>=(11);
a b
14 aaa
-handler t2 read a=(18);
+handler t2 read b=(18);
a b
18 eee
-handler t2 read a>=(18);
+handler t2 read b>=(18);
a b
18 eee
-handler t2 read a>(18);
+handler t2 read b>(18);
a b
19 fff
-handler t2 read a<=(18);
+handler t2 read b<=(18);
a b
18 eee
-handler t2 read a<(18);
+handler t2 read b<(18);
a b
17 ddd
handler t2 read a=(15);
a b
-handler t2 read a>=(15);
+handler t2 read a>=(15) limit 2;
a b
16 ccc
-handler t2 read a>(15);
+16 xxx
+handler t2 read a>(15) limit 2;
a b
16 ccc
+16 xxx
handler t2 read a<=(15);
a b
14 aaa
@@ -103,10 +105,10 @@ handler t2 read a>(54);
a b
handler t2 read a<=(54);
a b
-22 iii
+25 xxx
handler t2 read a<(54);
a b
-22 iii
+25 xxx
handler t2 read a=(1);
a b
handler t2 read a>=(1);
@@ -119,19 +121,19 @@ handler t2 read a<=(1);
a b
handler t2 read a<(1);
a b
-handler t2 read a first limit 5;
+handler t2 read b first limit 5;
a b
14 aaa
16 ccc
16 xxx
17 ddd
18 eee
-handler t2 read a next limit 3;
+handler t2 read b next limit 3;
a b
19 fff
19 yyy
20 ggg
-handler t2 read a prev limit 10;
+handler t2 read b prev limit 10;
a b
19 yyy
19 fff
@@ -140,25 +142,32 @@ a b
16 xxx
16 ccc
14 aaa
-handler t2 read a>=(16) limit 4;
+handler t2 read b>=(16) limit 4;
a b
16 ccc
16 xxx
17 ddd
18 eee
-handler t2 read a>=(16) limit 2,2;
+handler t2 read b>=(16) limit 2,2;
+a b
+17 ddd
+18 eee
+select * from t1 where a>=16 order by a,b 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=(19);
+25 xxx
+24 xxx
+23 xxx
+handler t2 read b=(16) limit 1,3;
+a b
+16 xxx
+handler t2 read b=(19);
a b
19 fff
-handler t2 read a=(19) where b="yyy";
+handler t2 read b=(19) where b="yyy";
a b
19 yyy
handler t2 read first;
@@ -172,20 +181,20 @@ a b
19 fff
handler t2 close;
handler t1 open;
-handler t1 read a next;
+handler t1 read b next;
a b
14 aaa
-handler t1 read a next;
+handler t1 read b next;
a b
16 ccc
handler t1 close;
handler t1 open;
handler t1 read a prev;
a b
-22 iii
+25 xxx
handler t1 read a prev;
a b
-21 hhh
+24 xxx
handler t1 close;
handler t1 open as t2;
handler t2 read first;
@@ -194,6 +203,168 @@ 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=(20) limit 1,3;
+a b
+flush tables;
+handler t1 read a=(20) limit 1,3;
+a b
+handler t1 close;
+handler t1 open;
+handler t1 read a=(25);
+a b
+25 xxx
+handler t1 read a next;
+a b
+handler t1 read a next;
+a b
+handler t1 read a next;
+a b
+handler t1 read a prev;
+a b
+25 xxx
+handler t1 read a=(1000);
+a b
+handler t1 read a next;
+a b
+handler t1 read a prev;
+a b
+25 xxx
+handler t1 read a=(1000);
+a b
+handler t1 read a prev;
+a b
+25 xxx
+handler t1 read a=(14);
+a b
+14 aaa
+handler t1 read a prev;
+a b
+handler t1 read a prev;
+a b
+handler t1 read a next;
+a b
+14 aaa
+handler t1 read a=(1);
+a b
+handler t1 read a prev;
+a b
+handler t1 read a next;
+a b
+14 aaa
+handler t1 read a=(1);
+a b
+handler t1 read a next;
+a b
+14 aaa
+handler t1 close;
+handler t1 open;
+prepare stmt from 'handler t1 read a=(?) limit ?,?';
+set @a=20,@b=1,@c=100;
+execute stmt using @a,@b,@c;
+a b
+set @a=20,@b=2,@c=1;
+execute stmt using @a,@b,@c;
+a b
+set @a=20,@b=0,@c=2;
+execute stmt using @a,@b,@c;
+a b
+20 ggg
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a next limit ?';
+handler t1 read a>=(21);
+a b
+21 hhh
+set @a=3;
+execute stmt using @a;
+a b
+22 iii
+23 xxx
+24 xxx
+execute stmt using @a;
+a b
+25 xxx
+execute stmt using @a;
+a b
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read b prev limit ?';
+execute stmt using @a;
+a b
+25 xxx
+24 xxx
+23 xxx
+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
+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 b>=(?) where a < ? limit 5';
+set @a=17, @b=24;
+execute stmt using @a,@b;
+a b
+17 ddd
+18 eee
+19 fff
+19 yyy
+20 ggg
+execute stmt using @a,@b;
+a b
+17 ddd
+18 eee
+19 fff
+19 yyy
+20 ggg
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a=(?)';
+set @a=17;
+execute stmt using @a;
+a b
+17 ddd
+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=17;
+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);
@@ -429,7 +600,7 @@ handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias close;
drop table t1;
-create temporary table t1 (a int, b char(1), key a (a), key b(a,b));
+create temporary table t1 (a int, b char(1), key a (a), key b (a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"),(9,'k');
select a,b from t1;
@@ -481,20 +652,20 @@ a b
9 j
9 k
handler t1 open as a2;
-handler a2 read a=(9);
+handler a2 read b=(9);
a b
9 j
-handler a2 read a next;
+handler a2 read b next;
a b
9 k
-handler a2 read a prev limit 2;
+handler a2 read b prev limit 2;
a b
9 j
8 i
-handler a2 read a last;
+handler a2 read b last;
a b
9 k
-handler a2 read a prev;
+handler a2 read b prev;
a b
9 j
handler a2 close;
diff --git a/mysql-test/suite/handler/handler.inc b/mysql-test/suite/handler/handler.inc
index 48ed2ce0b8a..5c87652f2b5 100644
--- a/mysql-test/suite/handler/handler.inc
+++ b/mysql-test/suite/handler/handler.inc
@@ -23,24 +23,24 @@
# Start testing the table created in init.inc
#
handler t1 open as t2;
-handler t2 read a first;
-handler t2 read a next;
-handler t2 read a next;
-handler t2 read a prev;
-handler t2 read a last;
-handler t2 read a prev;
-handler t2 read a prev;
-
-handler t2 read a first;
-handler t2 read a prev;
-
-handler t2 read a last;
-handler t2 read a prev;
-handler t2 read a next;
-handler t2 read a next;
+handler t2 read b first;
+handler t2 read b next;
+handler t2 read b next;
+handler t2 read b prev;
+handler t2 read b last;
+handler t2 read b prev;
+handler t2 read b prev;
+
+handler t2 read b first;
+handler t2 read b prev;
+
+handler t2 read b last;
+handler t2 read b prev;
+handler t2 read b next;
+handler t2 read b next;
handler t2 read a=(15);
-handler t2 read a=(16);
+handler t2 read a=(21);
--error 1070
handler t2 read a=(19,"fff");
@@ -55,17 +55,20 @@ handler t1 read a last;
handler t2 read a=(11);
handler t2 read a>=(11);
-# Search on something we ca nfind
-handler t2 read a=(18);
-handler t2 read a>=(18);
-handler t2 read a>(18);
-handler t2 read a<=(18);
-handler t2 read a<(18);
+# Search on something we can find
+handler t2 read b=(18);
+handler t2 read b>=(18);
+handler t2 read b>(18);
+handler t2 read b<=(18);
+handler t2 read b<(18);
# Search on something we can't find
+--sorted_result
handler t2 read a=(15);
-handler t2 read a>=(15);
-handler t2 read a>(15);
+--sorted_result
+handler t2 read a>=(15) limit 2;
+--sorted_result
+handler t2 read a>(15) limit 2;
handler t2 read a<=(15);
handler t2 read a<(15);
@@ -83,16 +86,17 @@ handler t2 read a>(1);
handler t2 read a<=(1);
handler t2 read a<(1);
-handler t2 read a first limit 5;
-handler t2 read a next limit 3;
-handler t2 read a prev limit 10;
+handler t2 read b first limit 5;
+handler t2 read b next limit 3;
+handler t2 read b prev limit 10;
-handler t2 read a>=(16) limit 4;
-handler t2 read a>=(16) limit 2,2;
+handler t2 read b>=(16) limit 4;
+handler t2 read b>=(16) limit 2,2;
+select * from t1 where a>=16 order by a,b limit 2,2;
handler t2 read a last limit 3;
-
-handler t2 read a=(19);
-handler t2 read a=(19) where b="yyy";
+handler t2 read b=(16) limit 1,3;
+handler t2 read b=(19);
+handler t2 read b=(19) where b="yyy";
handler t2 read first;
handler t2 read next;
@@ -100,8 +104,8 @@ handler t2 read next;
handler t2 close;
handler t1 open;
-handler t1 read a next; # this used to crash as a bug#5373
-handler t1 read a next;
+handler t1 read b next; # this used to crash as a bug#5373
+handler t1 read b next;
handler t1 close;
handler t1 open;
@@ -115,6 +119,107 @@ eval alter table t1 engine = $engine_type;
--error 1109
handler t2 read first;
+handler t1 open;
+handler t1 read a=(20) limit 1,3;
+flush tables;
+handler t1 read a=(20) limit 1,3;
+handler t1 close;
+
+#
+# Search after end and before start of index
+#
+
+handler t1 open;
+handler t1 read a=(25);
+handler t1 read a next;
+handler t1 read a next;
+handler t1 read a next;
+handler t1 read a prev;
+handler t1 read a=(1000);
+handler t1 read a next;
+handler t1 read a prev;
+handler t1 read a=(1000);
+handler t1 read a prev;
+
+handler t1 read a=(14);
+handler t1 read a prev;
+handler t1 read a prev;
+handler t1 read a next;
+handler t1 read a=(1);
+handler t1 read a prev;
+handler t1 read a next;
+handler t1 read a=(1);
+handler t1 read a next;
+
+handler t1 close;
+
+#
+# Test with prepared statements
+#
+
+handler t1 open;
+prepare stmt from 'handler t1 read a=(?) limit ?,?';
+set @a=20,@b=1,@c=100;
+execute stmt using @a,@b,@c;
+set @a=20,@b=2,@c=1;
+execute stmt using @a,@b,@c;
+set @a=20,@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>=(21);
+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 b>=(?) where a < ? limit 5';
+set @a=17, @b=24;
+execute stmt using @a,@b;
+execute stmt using @a,@b;
+deallocate prepare stmt;
+
+prepare stmt from 'handler t1 read a=(?)';
+set @a=17;
+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=17;
+--error ER_NEED_REPREPARE
+execute stmt using @a;
+deallocate prepare stmt;
+handler t1 close;
+
#
# DROP TABLE / ALTER TABLE
#
@@ -376,7 +481,7 @@ drop table t1;
# is open by a HANDLER, no other statement can access it.
#
-eval create temporary table t1 (a int, b char(1), key a $key_type (a), key b(a,b));
+eval create temporary table t1 (a int, b char(1), key a $key_type (a), key b $key_type (a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"),(9,'k');
select a,b from t1;
@@ -392,12 +497,12 @@ handler a1 read a=(6) where b="g";
handler a1 close;
select a,b from t1;
handler t1 open as a2;
-handler a2 read a=(9);
-handler a2 read a next;
-handler a2 read a prev limit 2;
+handler a2 read b=(9);
+handler a2 read b next;
+handler a2 read b prev limit 2;
--error 0,1031
-handler a2 read a last;
-handler a2 read a prev;
+handler a2 read b last;
+handler a2 read b prev;
handler a2 close;
drop table t1;
diff --git a/mysql-test/suite/handler/heap.result b/mysql-test/suite/handler/heap.result
new file mode 100644
index 00000000000..04bc9c73159
--- /dev/null
+++ b/mysql-test/suite/handler/heap.result
@@ -0,0 +1,827 @@
+SET SESSION STORAGE_ENGINE = MEMORY;
+drop table if exists t1,t3,t4,t5;
+create table t1 (a int, b char(10), key a using btree (a), key b using btree (a,b));
+insert into t1 values
+(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
+(14,"aaa"),(16,"ccc"),(16,"xxx"),
+(20,"ggg"),(21,"hhh"),(22,"iii"),(23,"xxx"),(24,"xxx"),(25,"xxx");
+handler t1 open as t2;
+handler t2 read b first;
+a b
+14 aaa
+handler t2 read b next;
+a b
+16 ccc
+handler t2 read b next;
+a b
+16 xxx
+handler t2 read b prev;
+a b
+16 ccc
+handler t2 read b last;
+a b
+25 xxx
+handler t2 read b prev;
+a b
+24 xxx
+handler t2 read b prev;
+a b
+23 xxx
+handler t2 read b first;
+a b
+14 aaa
+handler t2 read b prev;
+a b
+handler t2 read b last;
+a b
+25 xxx
+handler t2 read b prev;
+a b
+24 xxx
+handler t2 read b next;
+a b
+25 xxx
+handler t2 read b next;
+a b
+handler t2 read a=(15);
+a b
+handler t2 read a=(21);
+a b
+21 hhh
+handler t2 read a=(19,"fff");
+ERROR 42000: Too many key parts specified; max 1 parts allowed
+handler t2 read b=(19,"fff");
+a b
+19 fff
+handler t2 read b=(19,"yyy");
+a b
+19 yyy
+handler t2 read b=(19);
+a b
+19 fff
+handler t1 read a last;
+ERROR 42S02: Unknown table 't1' in HANDLER
+handler t2 read a=(11);
+a b
+handler t2 read a>=(11);
+a b
+14 aaa
+handler t2 read b=(18);
+a b
+18 eee
+handler t2 read b>=(18);
+a b
+18 eee
+handler t2 read b>(18);
+a b
+19 fff
+handler t2 read b<=(18);
+a b
+18 eee
+handler t2 read b<(18);
+a b
+17 ddd
+handler t2 read a=(15);
+a b
+handler t2 read a>=(15) limit 2;
+a b
+16 ccc
+16 xxx
+handler t2 read a>(15) limit 2;
+a b
+16 ccc
+16 xxx
+handler t2 read a<=(15);
+a b
+14 aaa
+handler t2 read a<(15);
+a b
+14 aaa
+handler t2 read a=(54);
+a b
+handler t2 read a>=(54);
+a b
+handler t2 read a>(54);
+a b
+handler t2 read a<=(54);
+a b
+25 xxx
+handler t2 read a<(54);
+a b
+25 xxx
+handler t2 read a=(1);
+a b
+handler t2 read a>=(1);
+a b
+14 aaa
+handler t2 read a>(1);
+a b
+14 aaa
+handler t2 read a<=(1);
+a b
+handler t2 read a<(1);
+a b
+handler t2 read b first limit 5;
+a b
+14 aaa
+16 ccc
+16 xxx
+17 ddd
+18 eee
+handler t2 read b next limit 3;
+a b
+19 fff
+19 yyy
+20 ggg
+handler t2 read b prev limit 10;
+a b
+19 yyy
+19 fff
+18 eee
+17 ddd
+16 xxx
+16 ccc
+14 aaa
+handler t2 read b>=(16) limit 4;
+a b
+16 ccc
+16 xxx
+17 ddd
+18 eee
+handler t2 read b>=(16) limit 2,2;
+a b
+17 ddd
+18 eee
+select * from t1 where a>=16 order by a,b limit 2,2;
+a b
+17 ddd
+18 eee
+handler t2 read a last limit 3;
+a b
+25 xxx
+24 xxx
+23 xxx
+handler t2 read b=(16) limit 1,3;
+a b
+16 xxx
+handler t2 read b=(19);
+a b
+19 fff
+handler t2 read b=(19) where b="yyy";
+a b
+19 yyy
+handler t2 read first;
+a b
+17 ddd
+handler t2 read next;
+a b
+18 eee
+handler t2 read next;
+a b
+19 fff
+handler t2 close;
+handler t1 open;
+handler t1 read b next;
+a b
+14 aaa
+handler t1 read b next;
+a b
+16 ccc
+handler t1 close;
+handler t1 open;
+handler t1 read a prev;
+a b
+25 xxx
+handler t1 read a prev;
+a b
+24 xxx
+handler t1 close;
+handler t1 open as t2;
+handler t2 read first;
+a b
+17 ddd
+alter table t1 engine = MEMORY;
+handler t2 read first;
+ERROR 42S02: Unknown table 't2' in HANDLER
+handler t1 open;
+handler t1 read a=(20) limit 1,3;
+a b
+flush tables;
+handler t1 read a=(20) limit 1,3;
+a b
+handler t1 close;
+handler t1 open;
+handler t1 read a=(25);
+a b
+25 xxx
+handler t1 read a next;
+a b
+handler t1 read a next;
+a b
+handler t1 read a next;
+a b
+handler t1 read a prev;
+a b
+25 xxx
+handler t1 read a=(1000);
+a b
+handler t1 read a next;
+a b
+handler t1 read a prev;
+a b
+25 xxx
+handler t1 read a=(1000);
+a b
+handler t1 read a prev;
+a b
+25 xxx
+handler t1 read a=(14);
+a b
+14 aaa
+handler t1 read a prev;
+a b
+handler t1 read a prev;
+a b
+handler t1 read a next;
+a b
+14 aaa
+handler t1 read a=(1);
+a b
+handler t1 read a prev;
+a b
+handler t1 read a next;
+a b
+14 aaa
+handler t1 read a=(1);
+a b
+handler t1 read a next;
+a b
+14 aaa
+handler t1 close;
+handler t1 open;
+prepare stmt from 'handler t1 read a=(?) limit ?,?';
+set @a=20,@b=1,@c=100;
+execute stmt using @a,@b,@c;
+a b
+set @a=20,@b=2,@c=1;
+execute stmt using @a,@b,@c;
+a b
+set @a=20,@b=0,@c=2;
+execute stmt using @a,@b,@c;
+a b
+20 ggg
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a next limit ?';
+handler t1 read a>=(21);
+a b
+21 hhh
+set @a=3;
+execute stmt using @a;
+a b
+22 iii
+23 xxx
+24 xxx
+execute stmt using @a;
+a b
+25 xxx
+execute stmt using @a;
+a b
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read b prev limit ?';
+execute stmt using @a;
+a b
+25 xxx
+24 xxx
+23 xxx
+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
+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 b>=(?) where a < ? limit 5';
+set @a=17, @b=24;
+execute stmt using @a,@b;
+a b
+17 ddd
+18 eee
+19 fff
+19 yyy
+20 ggg
+execute stmt using @a,@b;
+a b
+17 ddd
+18 eee
+19 fff
+19 yyy
+20 ggg
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a=(?)';
+set @a=17;
+execute stmt using @a;
+a b
+17 ddd
+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=17;
+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);
+insert into t1 values (17);
+handler t2 read first;
+ERROR 42S02: Unknown table 't2' in HANDLER
+handler t1 open as t2;
+alter table t1 engine=CSV;
+handler t2 read first;
+ERROR 42S02: Unknown table 't2' in HANDLER
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3),(4),(5),(6);
+delete from t1 limit 2;
+handler t1 open;
+handler t1 read first;
+a
+3
+handler t1 read first limit 1,1;
+a
+4
+handler t1 read first limit 2,2;
+a
+5
+6
+delete from t1 limit 3;
+handler t1 read first;
+a
+6
+drop table t1;
+create table t1(a int, index using btree (a));
+insert into t1 values (1), (2), (3);
+handler t1 open;
+handler t1 read a=(W);
+ERROR 42S22: Unknown column 'W' in 'field list'
+handler t1 read a=(a);
+ERROR HY000: Incorrect arguments to HANDLER ... READ
+drop table t1;
+create table t1 (a char(5));
+insert into t1 values ("Ok");
+handler t1 open as t;
+handler t read first;
+a
+Ok
+use mysql;
+handler t read first;
+a
+Ok
+handler t close;
+handler test.t1 open as t;
+handler t read first;
+a
+Ok
+handler t close;
+use test;
+drop table t1;
+create table t1 ( a int, b int, INDEX a using btree (a) );
+insert into t1 values (1,2), (2,1);
+handler t1 open;
+handler t1 read a=(1) where b=2;
+a b
+1 2
+handler t1 read a=(1) where b=3;
+a b
+handler t1 read a=(1) where b=1;
+a b
+handler t1 close;
+drop table t1;
+create table t1 (c1 char(20));
+insert into t1 values ("t1");
+handler t1 open as h1;
+handler h1 read first limit 9;
+c1
+t1
+create table t2 (c1 char(20));
+insert into t2 values ("t2");
+handler t2 open as h2;
+handler h2 read first limit 9;
+c1
+t2
+create table t3 (c1 char(20));
+insert into t3 values ("t3");
+handler t3 open as h3;
+handler h3 read first limit 9;
+c1
+t3
+create table t4 (c1 char(20));
+insert into t4 values ("t4");
+handler t4 open as h4;
+handler h4 read first limit 9;
+c1
+t4
+create table t5 (c1 char(20));
+insert into t5 values ("t5");
+handler t5 open as h5;
+handler h5 read first limit 9;
+c1
+t5
+alter table t1 engine=MyISAM;
+handler h1 read first limit 9;
+ERROR 42S02: Unknown table 'h1' in HANDLER
+handler h2 read first limit 9;
+c1
+t2
+handler h3 read first limit 9;
+c1
+t3
+handler h4 read first limit 9;
+c1
+t4
+handler h5 read first limit 9;
+c1
+t5
+alter table t5 engine=MyISAM;
+handler h1 read first limit 9;
+ERROR 42S02: Unknown table 'h1' in HANDLER
+handler h2 read first limit 9;
+c1
+t2
+handler h3 read first limit 9;
+c1
+t3
+handler h4 read first limit 9;
+c1
+t4
+handler h5 read first limit 9;
+ERROR 42S02: Unknown table 'h5' in HANDLER
+alter table t3 engine=MyISAM;
+handler h1 read first limit 9;
+ERROR 42S02: Unknown table 'h1' in HANDLER
+handler h2 read first limit 9;
+c1
+t2
+handler h3 read first limit 9;
+ERROR 42S02: Unknown table 'h3' in HANDLER
+handler h4 read first limit 9;
+c1
+t4
+handler h5 read first limit 9;
+ERROR 42S02: Unknown table 'h5' in HANDLER
+handler h2 close;
+handler h4 close;
+handler t1 open as h1_1;
+handler t1 open as h1_2;
+handler t1 open as h1_3;
+handler h1_1 read first limit 9;
+c1
+t1
+handler h1_2 read first limit 9;
+c1
+t1
+handler h1_3 read first limit 9;
+c1
+t1
+alter table t1 engine=MEMORY;
+handler h1_1 read first limit 9;
+ERROR 42S02: Unknown table 'h1_1' in HANDLER
+handler h1_2 read first limit 9;
+ERROR 42S02: Unknown table 'h1_2' in HANDLER
+handler h1_3 read first limit 9;
+ERROR 42S02: Unknown table 'h1_3' in HANDLER
+drop table t1;
+drop table t2;
+drop table t3;
+drop table t4;
+drop table t5;
+create table t1 (c1 int);
+insert into t1 values (1);
+handler t1 open;
+handler t1 read first;
+c1
+1
+send the below to another connection, do not wait for the result
+optimize table t1;
+proceed with the normal connection
+handler t1 read next;
+c1
+1
+handler t1 close;
+read the result from the other connection
+Table Op Msg_type Msg_text
+test.t1 optimize note The storage engine for the table doesn't support optimize
+proceed with the normal connection
+drop table t1;
+CREATE TABLE t1 ( no1 smallint(5) NOT NULL default '0', no2 int(10) NOT NULL default '0', PRIMARY KEY using btree (no1,no2));
+INSERT INTO t1 VALUES (1,274),(1,275),(2,6),(2,8),(4,1),(4,2);
+HANDLER t1 OPEN;
+HANDLER t1 READ `primary` = (1, 1000);
+no1 no2
+HANDLER t1 READ `primary` PREV;
+no1 no2
+1 275
+HANDLER t1 READ `primary` = (1, 1000);
+no1 no2
+HANDLER t1 READ `primary` NEXT;
+no1 no2
+2 6
+DROP TABLE t1;
+create table t1 (c1 int);
+insert into t1 values (14397);
+flush tables with read lock;
+drop table t1;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+send the below to another connection, do not wait for the result
+drop table t1;
+proceed with the normal connection
+select * from t1;
+c1
+14397
+unlock tables;
+read the result from the other connection
+proceed with the normal connection
+select * from t1;
+ERROR 42S02: Table 'test.t1' doesn't exist
+drop table if exists t1;
+Warnings:
+Note 1051 Unknown table 't1'
+create table t1 (a int not null) ENGINE=CSV;
+--> client 2
+handler t1 open;
+ERROR HY000: Table storage engine for 't1' doesn't have this option
+--> client 1
+drop table t1;
+create table t1 (a int);
+handler t1 open as t1_alias;
+handler t1_alias read a next;
+ERROR 42000: Key 'a' doesn't exist in table 't1_alias'
+handler t1_alias READ a next where inexistent > 0;
+ERROR 42S22: Unknown column 'inexistent' in 'field list'
+handler t1_alias read a next;
+ERROR 42000: Key 'a' doesn't exist in table 't1_alias'
+handler t1_alias READ a next where inexistent > 0;
+ERROR 42S22: Unknown column 'inexistent' in 'field list'
+handler t1_alias close;
+drop table t1;
+create temporary table t1 (a int, b char(1), key a using btree (a), key b using btree (a,b));
+insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
+(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"),(9,'k');
+select a,b from t1;
+a b
+0 a
+1 b
+2 c
+3 d
+4 e
+5 f
+6 g
+7 h
+8 i
+9 j
+9 k
+handler t1 open as a1;
+handler a1 read a=(1);
+a b
+1 b
+handler a1 read a next;
+a b
+2 c
+handler a1 read a next;
+a b
+3 d
+select a,b from t1;
+ERROR HY000: Can't reopen table: 'a1'
+handler a1 read a prev;
+a b
+2 c
+handler a1 read a prev;
+a b
+1 b
+handler a1 read a=(6) where b="g";
+a b
+6 g
+handler a1 close;
+select a,b from t1;
+a b
+0 a
+1 b
+2 c
+3 d
+4 e
+5 f
+6 g
+7 h
+8 i
+9 j
+9 k
+handler t1 open as a2;
+handler a2 read b=(9);
+a b
+9 j
+handler a2 read b next;
+a b
+9 k
+handler a2 read b prev limit 2;
+a b
+9 j
+8 i
+handler a2 read b last;
+a b
+9 k
+handler a2 read b prev;
+a b
+9 j
+handler a2 close;
+drop table t1;
+create table t1 (a int);
+create temporary table t2 (a int, key using btree (a));
+handler t1 open as a1;
+handler t2 open as a2;
+handler a2 read a first;
+a
+drop table t1, t2;
+handler a2 read a next;
+ERROR 42S02: Unknown table 'a2' in HANDLER
+handler a1 close;
+ERROR 42S02: Unknown table 'a1' in HANDLER
+create table t1 (a int, key using btree (a));
+create table t2 like t1;
+handler t1 open as a1;
+handler t2 open as a2;
+handler a1 read a first;
+a
+handler a2 read a first;
+a
+alter table t1 add b int;
+handler a1 close;
+ERROR 42S02: Unknown table 'a1' in HANDLER
+handler a2 close;
+drop table t1, t2;
+create table t1 (a int, key using btree (a));
+handler t1 open as a1;
+handler a1 read a first;
+a
+rename table t1 to t2;
+handler a1 read a first;
+ERROR 42S02: Unknown table 'a1' in HANDLER
+drop table t2;
+create table t1 (a int, key using btree (a));
+create table t2 like t1;
+handler t1 open as a1;
+handler t2 open as a2;
+handler a1 read a first;
+a
+handler a2 read a first;
+a
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note The storage engine for the table doesn't support optimize
+handler a1 close;
+ERROR 42S02: Unknown table 'a1' in HANDLER
+handler a2 close;
+drop table t1, t2;
+#
+# BUG#51877 - HANDLER interface causes invalid memory read
+#
+CREATE TABLE t1(a INT, KEY using btree (a));
+HANDLER t1 OPEN;
+HANDLER t1 READ a FIRST;
+a
+INSERT INTO t1 VALUES(1);
+HANDLER t1 READ a NEXT;
+HANDLER t1 CLOSE;
+DROP TABLE t1;
+CREATE TABLE t1(a INT, b INT, KEY(a), KEY b using btree (b), KEY ab using btree(a, b)) engine=memory;
+INSERT INTO t1 VALUES (2, 20), (2,20), (1, 10), (4, 40), (3, 30), (5,50), (6,50);
+HANDLER t1 OPEN;
+HANDLER t1 READ a>=(2) limit 3;
+a b
+2 20
+2 20
+HANDLER t1 READ a PREV;
+a b
+2 20
+HANDLER t1 READ a PREV;
+a b
+2 20
+HANDLER t1 READ a PREV;
+a b
+HANDLER t1 READ b>=(20) limit 3;
+a b
+2 20
+2 20
+3 30
+HANDLER t1 READ b PREV;
+a b
+2 20
+HANDLER t1 READ b PREV LIMIT 2;
+a b
+2 20
+1 10
+HANDLER t1 READ ab=(3,30) limit 3;
+a b
+3 30
+HANDLER t1 READ ab>=(3,30) limit 3;
+a b
+3 30
+4 40
+5 50
+HANDLER t1 READ a FIRST;
+ERROR HY000: Table storage engine for 't1' doesn't have this option
+HANDLER t1 READ a LAST;
+ERROR HY000: Table storage engine for 't1' doesn't have this option
+HANDLER t1 READ b FIRST LIMIT 2;
+a b
+1 10
+2 20
+HANDLER t1 READ ab LAST LIMIT 2;
+a b
+6 50
+5 50
+HANDLER t1 READ FIRST LIMIT 10;
+a b
+2 20
+2 20
+1 10
+4 40
+3 30
+5 50
+6 50
+HANDLER t1 READ b FIRST;
+a b
+1 10
+insert into t1 values (7,50);
+HANDLER t1 READ b NEXT;
+ERROR HY000: Record has changed since last read in table 't1'
+HANDLER t1 READ b FIRST;
+a b
+1 10
+insert into t1 values (7,50);
+HANDLER t1 READ b NEXT;
+ERROR HY000: Record has changed since last read in table 't1'
+HANDLER t1 READ FIRST;
+a b
+2 20
+insert into t1 values (8,50);
+HANDLER t1 READ NEXT;
+a b
+2 20
+delete from t1 where a=3;
+HANDLER t1 READ NEXT LIMIT 2;
+a b
+1 10
+4 40
+delete from t1;
+HANDLER t1 READ NEXT LIMIT 2;
+ERROR HY000: Record has changed since last read in table 't1'
+HANDLER t1 CLOSE;
+DROP TABLE t1;
+create table t1 (f1 integer not null, key (f1)) engine=Memory;
+insert into t1 values (1);
+HANDLER t1 OPEN;
+HANDLER t1 READ f1 NEXT;
+ERROR HY000: Table storage engine for 't1' doesn't have this option
+HANDLER t1 READ f1 NEXT;
+ERROR HY000: Table storage engine for 't1' doesn't have this option
+HANDLER t1 READ f1 NEXT;
+ERROR HY000: Table storage engine for 't1' doesn't have this option
+HANDLER t1 CLOSE;
+DROP TABLE t1;
+End of 5.3 tests
diff --git a/mysql-test/suite/handler/heap.test b/mysql-test/suite/handler/heap.test
new file mode 100644
index 00000000000..d6715144caa
--- /dev/null
+++ b/mysql-test/suite/handler/heap.test
@@ -0,0 +1,88 @@
+# test of HANDLER with HEAP tables
+#
+
+let $engine_type= MEMORY;
+let $key_type=using btree;
+
+--source init.inc
+--source handler.inc
+
+#
+# Test what happens if table is changed (Unique test for HEAP)
+#
+
+connect (con1,localhost,root,,);
+connection default;
+
+CREATE TABLE t1(a INT, b INT, KEY(a), KEY b using btree (b), KEY ab using btree(a, b)) engine=memory;
+
+INSERT INTO t1 VALUES (2, 20), (2,20), (1, 10), (4, 40), (3, 30), (5,50), (6,50);
+
+HANDLER t1 OPEN;
+HANDLER t1 READ a>=(2) limit 3;
+HANDLER t1 READ a PREV;
+HANDLER t1 READ a PREV;
+HANDLER t1 READ a PREV;
+HANDLER t1 READ b>=(20) limit 3;
+HANDLER t1 READ b PREV;
+HANDLER t1 READ b PREV LIMIT 2;
+HANDLER t1 READ ab=(3,30) limit 3;
+HANDLER t1 READ ab>=(3,30) limit 3;
+
+# Test FIRST/LAST on hash and btree keys
+--error ER_ILLEGAL_HA
+HANDLER t1 READ a FIRST;
+--error ER_ILLEGAL_HA
+HANDLER t1 READ a LAST;
+HANDLER t1 READ b FIRST LIMIT 2;
+HANDLER t1 READ ab LAST LIMIT 2;
+
+# Table scan
+HANDLER t1 READ FIRST LIMIT 10;
+# Index scan
+HANDLER t1 READ b FIRST;
+insert into t1 values (7,50);
+--error ER_CHECKREAD
+HANDLER t1 READ b NEXT;
+
+HANDLER t1 READ b FIRST;
+connection con1;
+insert into t1 values (7,50);
+connection default;
+--error ER_CHECKREAD
+HANDLER t1 READ b NEXT;
+
+HANDLER t1 READ FIRST;
+connection con1;
+insert into t1 values (8,50);
+connection default;
+HANDLER t1 READ NEXT;
+connection con1;
+delete from t1 where a=3;
+connection default;
+HANDLER t1 READ NEXT LIMIT 2;
+connection con1;
+delete from t1;
+connection default;
+--error ER_CHECKREAD
+HANDLER t1 READ NEXT LIMIT 2;
+HANDLER t1 CLOSE;
+DROP TABLE t1;
+disconnect con1;
+
+#
+# LP#702786 Two handler read f1 next gives different errors
+#
+create table t1 (f1 integer not null, key (f1)) engine=Memory;
+insert into t1 values (1);
+HANDLER t1 OPEN;
+--error 1031
+HANDLER t1 READ f1 NEXT;
+--error 1031
+HANDLER t1 READ f1 NEXT;
+--error 1031
+HANDLER t1 READ f1 NEXT;
+HANDLER t1 CLOSE;
+DROP TABLE t1;
+
+--echo End of 5.3 tests
diff --git a/mysql-test/suite/handler/init.inc b/mysql-test/suite/handler/init.inc
index 32c6010f95b..3e63f14a103 100644
--- a/mysql-test/suite/handler/init.inc
+++ b/mysql-test/suite/handler/init.inc
@@ -30,4 +30,4 @@ eval create table t1 (a int, b char(10), key a $key_type (a), key b $key_type (a
insert into t1 values
(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
(14,"aaa"),(16,"ccc"),(16,"xxx"),
-(20,"ggg"),(21,"hhh"),(22,"iii");
+(20,"ggg"),(21,"hhh"),(22,"iii"),(23,"xxx"),(24,"xxx"),(25,"xxx");
diff --git a/mysql-test/suite/handler/innodb.result b/mysql-test/suite/handler/innodb.result
index 2cdaa0c4664..3bf3a1f2c70 100644
--- a/mysql-test/suite/handler/innodb.result
+++ b/mysql-test/suite/handler/innodb.result
@@ -4,50 +4,50 @@ create table t1 (a int, b char(10), key a (a), key b (a,b));
insert into t1 values
(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
(14,"aaa"),(16,"ccc"),(16,"xxx"),
-(20,"ggg"),(21,"hhh"),(22,"iii");
+(20,"ggg"),(21,"hhh"),(22,"iii"),(23,"xxx"),(24,"xxx"),(25,"xxx");
handler t1 open as t2;
-handler t2 read a first;
+handler t2 read b first;
a b
14 aaa
-handler t2 read a next;
+handler t2 read b next;
a b
16 ccc
-handler t2 read a next;
+handler t2 read b next;
a b
16 xxx
-handler t2 read a prev;
+handler t2 read b prev;
a b
16 ccc
-handler t2 read a last;
+handler t2 read b last;
a b
-22 iii
-handler t2 read a prev;
+25 xxx
+handler t2 read b prev;
a b
-21 hhh
-handler t2 read a prev;
+24 xxx
+handler t2 read b prev;
a b
-20 ggg
-handler t2 read a first;
+23 xxx
+handler t2 read b first;
a b
14 aaa
-handler t2 read a prev;
+handler t2 read b prev;
a b
-handler t2 read a last;
+handler t2 read b last;
a b
-22 iii
-handler t2 read a prev;
+25 xxx
+handler t2 read b prev;
a b
-21 hhh
-handler t2 read a next;
+24 xxx
+handler t2 read b next;
a b
-22 iii
-handler t2 read a next;
+25 xxx
+handler t2 read b next;
a b
handler t2 read a=(15);
a b
-handler t2 read a=(16);
+handler t2 read a=(21);
a b
-16 ccc
+21 hhh
handler t2 read a=(19,"fff");
ERROR 42000: Too many key parts specified; max 1 parts allowed
handler t2 read b=(19,"fff");
@@ -66,29 +66,31 @@ a b
handler t2 read a>=(11);
a b
14 aaa
-handler t2 read a=(18);
+handler t2 read b=(18);
a b
18 eee
-handler t2 read a>=(18);
+handler t2 read b>=(18);
a b
18 eee
-handler t2 read a>(18);
+handler t2 read b>(18);
a b
19 fff
-handler t2 read a<=(18);
+handler t2 read b<=(18);
a b
18 eee
-handler t2 read a<(18);
+handler t2 read b<(18);
a b
17 ddd
handler t2 read a=(15);
a b
-handler t2 read a>=(15);
+handler t2 read a>=(15) limit 2;
a b
16 ccc
-handler t2 read a>(15);
+16 xxx
+handler t2 read a>(15) limit 2;
a b
16 ccc
+16 xxx
handler t2 read a<=(15);
a b
14 aaa
@@ -103,10 +105,10 @@ handler t2 read a>(54);
a b
handler t2 read a<=(54);
a b
-22 iii
+25 xxx
handler t2 read a<(54);
a b
-22 iii
+25 xxx
handler t2 read a=(1);
a b
handler t2 read a>=(1);
@@ -119,19 +121,19 @@ handler t2 read a<=(1);
a b
handler t2 read a<(1);
a b
-handler t2 read a first limit 5;
+handler t2 read b first limit 5;
a b
14 aaa
16 ccc
16 xxx
17 ddd
18 eee
-handler t2 read a next limit 3;
+handler t2 read b next limit 3;
a b
19 fff
19 yyy
20 ggg
-handler t2 read a prev limit 10;
+handler t2 read b prev limit 10;
a b
19 yyy
19 fff
@@ -140,25 +142,32 @@ a b
16 xxx
16 ccc
14 aaa
-handler t2 read a>=(16) limit 4;
+handler t2 read b>=(16) limit 4;
a b
16 ccc
16 xxx
17 ddd
18 eee
-handler t2 read a>=(16) limit 2,2;
+handler t2 read b>=(16) limit 2,2;
+a b
+17 ddd
+18 eee
+select * from t1 where a>=16 order by a,b 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=(19);
+25 xxx
+24 xxx
+23 xxx
+handler t2 read b=(16) limit 1,3;
+a b
+16 xxx
+handler t2 read b=(19);
a b
19 fff
-handler t2 read a=(19) where b="yyy";
+handler t2 read b=(19) where b="yyy";
a b
19 yyy
handler t2 read first;
@@ -172,20 +181,20 @@ a b
19 fff
handler t2 close;
handler t1 open;
-handler t1 read a next;
+handler t1 read b next;
a b
14 aaa
-handler t1 read a next;
+handler t1 read b next;
a b
16 ccc
handler t1 close;
handler t1 open;
handler t1 read a prev;
a b
-22 iii
+25 xxx
handler t1 read a prev;
a b
-21 hhh
+24 xxx
handler t1 close;
handler t1 open as t2;
handler t2 read first;
@@ -194,6 +203,168 @@ 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=(20) limit 1,3;
+a b
+flush tables;
+handler t1 read a=(20) limit 1,3;
+a b
+handler t1 close;
+handler t1 open;
+handler t1 read a=(25);
+a b
+25 xxx
+handler t1 read a next;
+a b
+handler t1 read a next;
+a b
+handler t1 read a next;
+a b
+handler t1 read a prev;
+a b
+25 xxx
+handler t1 read a=(1000);
+a b
+handler t1 read a next;
+a b
+handler t1 read a prev;
+a b
+25 xxx
+handler t1 read a=(1000);
+a b
+handler t1 read a prev;
+a b
+25 xxx
+handler t1 read a=(14);
+a b
+14 aaa
+handler t1 read a prev;
+a b
+handler t1 read a prev;
+a b
+handler t1 read a next;
+a b
+14 aaa
+handler t1 read a=(1);
+a b
+handler t1 read a prev;
+a b
+handler t1 read a next;
+a b
+14 aaa
+handler t1 read a=(1);
+a b
+handler t1 read a next;
+a b
+16 ccc
+handler t1 close;
+handler t1 open;
+prepare stmt from 'handler t1 read a=(?) limit ?,?';
+set @a=20,@b=1,@c=100;
+execute stmt using @a,@b,@c;
+a b
+set @a=20,@b=2,@c=1;
+execute stmt using @a,@b,@c;
+a b
+set @a=20,@b=0,@c=2;
+execute stmt using @a,@b,@c;
+a b
+20 ggg
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a next limit ?';
+handler t1 read a>=(21);
+a b
+21 hhh
+set @a=3;
+execute stmt using @a;
+a b
+22 iii
+23 xxx
+24 xxx
+execute stmt using @a;
+a b
+25 xxx
+execute stmt using @a;
+a b
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read b prev limit ?';
+execute stmt using @a;
+a b
+25 xxx
+24 xxx
+23 xxx
+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
+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 b>=(?) where a < ? limit 5';
+set @a=17, @b=24;
+execute stmt using @a,@b;
+a b
+17 ddd
+18 eee
+19 fff
+19 yyy
+20 ggg
+execute stmt using @a,@b;
+a b
+17 ddd
+18 eee
+19 fff
+19 yyy
+20 ggg
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a=(?)';
+set @a=17;
+execute stmt using @a;
+a b
+17 ddd
+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=17;
+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);
@@ -430,7 +601,7 @@ handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias close;
drop table t1;
-create temporary table t1 (a int, b char(1), key a (a), key b(a,b));
+create temporary table t1 (a int, b char(1), key a (a), key b (a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"),(9,'k');
select a,b from t1;
@@ -482,20 +653,20 @@ a b
9 j
9 k
handler t1 open as a2;
-handler a2 read a=(9);
+handler a2 read b=(9);
a b
9 j
-handler a2 read a next;
+handler a2 read b next;
a b
9 k
-handler a2 read a prev limit 2;
+handler a2 read b prev limit 2;
a b
9 j
8 i
-handler a2 read a last;
+handler a2 read b last;
a b
9 k
-handler a2 read a prev;
+handler a2 read b prev;
a b
9 j
handler a2 close;
diff --git a/mysql-test/suite/handler/interface.result b/mysql-test/suite/handler/interface.result
index 0b5a4447739..04fcb1b9002 100644
--- a/mysql-test/suite/handler/interface.result
+++ b/mysql-test/suite/handler/interface.result
@@ -6,7 +6,7 @@ create table t1 (a int, b char(10), key a (a), key b (a,b));
insert into t1 values
(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
(14,"aaa"),(16,"ccc"),(16,"xxx"),
-(20,"ggg"),(21,"hhh"),(22,"iii");
+(20,"ggg"),(21,"hhh"),(22,"iii"),(23,"xxx"),(24,"xxx"),(25,"xxx");
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
@@ -257,3 +257,5 @@ drop table t1;
USE information_schema;
HANDLER COLUMNS OPEN;
ERROR HY000: Incorrect usage of HANDLER OPEN and information_schema
+PREPARE h_r FROM 'HANDLER t1 READ `PRIMARY` LAST';
+ERROR 42S02: Unknown table 't1' in HANDLER
diff --git a/mysql-test/suite/handler/interface.test b/mysql-test/suite/handler/interface.test
index 809f0228f98..e03f2ed777c 100644
--- a/mysql-test/suite/handler/interface.test
+++ b/mysql-test/suite/handler/interface.test
@@ -305,3 +305,9 @@ connection default;
USE information_schema;
--error ER_WRONG_USAGE
HANDLER COLUMNS OPEN;
+
+#
+# LP#697622 Assertion `! is_set()' failed when preparing a HANDLER statement
+#
+--error ER_UNKNOWN_TABLE
+PREPARE h_r FROM 'HANDLER t1 READ `PRIMARY` LAST';
diff --git a/mysql-test/suite/handler/myisam.result b/mysql-test/suite/handler/myisam.result
index bd356d6e81d..321811d7339 100644
--- a/mysql-test/suite/handler/myisam.result
+++ b/mysql-test/suite/handler/myisam.result
@@ -4,50 +4,50 @@ create table t1 (a int, b char(10), key a (a), key b (a,b));
insert into t1 values
(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
(14,"aaa"),(16,"ccc"),(16,"xxx"),
-(20,"ggg"),(21,"hhh"),(22,"iii");
+(20,"ggg"),(21,"hhh"),(22,"iii"),(23,"xxx"),(24,"xxx"),(25,"xxx");
handler t1 open as t2;
-handler t2 read a first;
+handler t2 read b first;
a b
14 aaa
-handler t2 read a next;
+handler t2 read b next;
a b
16 ccc
-handler t2 read a next;
+handler t2 read b next;
a b
16 xxx
-handler t2 read a prev;
+handler t2 read b prev;
a b
16 ccc
-handler t2 read a last;
+handler t2 read b last;
a b
-22 iii
-handler t2 read a prev;
+25 xxx
+handler t2 read b prev;
a b
-21 hhh
-handler t2 read a prev;
+24 xxx
+handler t2 read b prev;
a b
-20 ggg
-handler t2 read a first;
+23 xxx
+handler t2 read b first;
a b
14 aaa
-handler t2 read a prev;
+handler t2 read b prev;
a b
-handler t2 read a last;
+handler t2 read b last;
a b
-22 iii
-handler t2 read a prev;
+25 xxx
+handler t2 read b prev;
a b
-21 hhh
-handler t2 read a next;
+24 xxx
+handler t2 read b next;
a b
-22 iii
-handler t2 read a next;
+25 xxx
+handler t2 read b next;
a b
handler t2 read a=(15);
a b
-handler t2 read a=(16);
+handler t2 read a=(21);
a b
-16 ccc
+21 hhh
handler t2 read a=(19,"fff");
ERROR 42000: Too many key parts specified; max 1 parts allowed
handler t2 read b=(19,"fff");
@@ -66,29 +66,31 @@ a b
handler t2 read a>=(11);
a b
14 aaa
-handler t2 read a=(18);
+handler t2 read b=(18);
a b
18 eee
-handler t2 read a>=(18);
+handler t2 read b>=(18);
a b
18 eee
-handler t2 read a>(18);
+handler t2 read b>(18);
a b
19 fff
-handler t2 read a<=(18);
+handler t2 read b<=(18);
a b
18 eee
-handler t2 read a<(18);
+handler t2 read b<(18);
a b
17 ddd
handler t2 read a=(15);
a b
-handler t2 read a>=(15);
+handler t2 read a>=(15) limit 2;
a b
16 ccc
-handler t2 read a>(15);
+16 xxx
+handler t2 read a>(15) limit 2;
a b
16 ccc
+16 xxx
handler t2 read a<=(15);
a b
14 aaa
@@ -103,10 +105,10 @@ handler t2 read a>(54);
a b
handler t2 read a<=(54);
a b
-22 iii
+25 xxx
handler t2 read a<(54);
a b
-22 iii
+25 xxx
handler t2 read a=(1);
a b
handler t2 read a>=(1);
@@ -119,19 +121,19 @@ handler t2 read a<=(1);
a b
handler t2 read a<(1);
a b
-handler t2 read a first limit 5;
+handler t2 read b first limit 5;
a b
14 aaa
16 ccc
16 xxx
17 ddd
18 eee
-handler t2 read a next limit 3;
+handler t2 read b next limit 3;
a b
19 fff
19 yyy
20 ggg
-handler t2 read a prev limit 10;
+handler t2 read b prev limit 10;
a b
19 yyy
19 fff
@@ -140,25 +142,32 @@ a b
16 xxx
16 ccc
14 aaa
-handler t2 read a>=(16) limit 4;
+handler t2 read b>=(16) limit 4;
a b
16 ccc
16 xxx
17 ddd
18 eee
-handler t2 read a>=(16) limit 2,2;
+handler t2 read b>=(16) limit 2,2;
+a b
+17 ddd
+18 eee
+select * from t1 where a>=16 order by a,b 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=(19);
+25 xxx
+24 xxx
+23 xxx
+handler t2 read b=(16) limit 1,3;
+a b
+16 xxx
+handler t2 read b=(19);
a b
19 fff
-handler t2 read a=(19) where b="yyy";
+handler t2 read b=(19) where b="yyy";
a b
19 yyy
handler t2 read first;
@@ -172,20 +181,20 @@ a b
19 fff
handler t2 close;
handler t1 open;
-handler t1 read a next;
+handler t1 read b next;
a b
14 aaa
-handler t1 read a next;
+handler t1 read b next;
a b
16 ccc
handler t1 close;
handler t1 open;
handler t1 read a prev;
a b
-22 iii
+25 xxx
handler t1 read a prev;
a b
-21 hhh
+24 xxx
handler t1 close;
handler t1 open as t2;
handler t2 read first;
@@ -194,6 +203,168 @@ 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=(20) limit 1,3;
+a b
+flush tables;
+handler t1 read a=(20) limit 1,3;
+a b
+handler t1 close;
+handler t1 open;
+handler t1 read a=(25);
+a b
+25 xxx
+handler t1 read a next;
+a b
+handler t1 read a next;
+a b
+handler t1 read a next;
+a b
+handler t1 read a prev;
+a b
+25 xxx
+handler t1 read a=(1000);
+a b
+handler t1 read a next;
+a b
+handler t1 read a prev;
+a b
+25 xxx
+handler t1 read a=(1000);
+a b
+handler t1 read a prev;
+a b
+25 xxx
+handler t1 read a=(14);
+a b
+14 aaa
+handler t1 read a prev;
+a b
+handler t1 read a prev;
+a b
+handler t1 read a next;
+a b
+14 aaa
+handler t1 read a=(1);
+a b
+handler t1 read a prev;
+a b
+handler t1 read a next;
+a b
+14 aaa
+handler t1 read a=(1);
+a b
+handler t1 read a next;
+a b
+14 aaa
+handler t1 close;
+handler t1 open;
+prepare stmt from 'handler t1 read a=(?) limit ?,?';
+set @a=20,@b=1,@c=100;
+execute stmt using @a,@b,@c;
+a b
+set @a=20,@b=2,@c=1;
+execute stmt using @a,@b,@c;
+a b
+set @a=20,@b=0,@c=2;
+execute stmt using @a,@b,@c;
+a b
+20 ggg
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a next limit ?';
+handler t1 read a>=(21);
+a b
+21 hhh
+set @a=3;
+execute stmt using @a;
+a b
+22 iii
+23 xxx
+24 xxx
+execute stmt using @a;
+a b
+25 xxx
+execute stmt using @a;
+a b
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read b prev limit ?';
+execute stmt using @a;
+a b
+25 xxx
+24 xxx
+23 xxx
+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
+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 b>=(?) where a < ? limit 5';
+set @a=17, @b=24;
+execute stmt using @a,@b;
+a b
+17 ddd
+18 eee
+19 fff
+19 yyy
+20 ggg
+execute stmt using @a,@b;
+a b
+17 ddd
+18 eee
+19 fff
+19 yyy
+20 ggg
+deallocate prepare stmt;
+prepare stmt from 'handler t1 read a=(?)';
+set @a=17;
+execute stmt using @a;
+a b
+17 ddd
+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=17;
+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);
@@ -429,7 +600,7 @@ handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias close;
drop table t1;
-create temporary table t1 (a int, b char(1), key a (a), key b(a,b));
+create temporary table t1 (a int, b char(1), key a (a), key b (a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"),(9,'k');
select a,b from t1;
@@ -481,20 +652,20 @@ a b
9 j
9 k
handler t1 open as a2;
-handler a2 read a=(9);
+handler a2 read b=(9);
a b
9 j
-handler a2 read a next;
+handler a2 read b next;
a b
9 k
-handler a2 read a prev limit 2;
+handler a2 read b prev limit 2;
a b
9 j
8 i
-handler a2 read a last;
+handler a2 read b last;
a b
9 k
-handler a2 read a prev;
+handler a2 read b prev;
a b
9 j
handler a2 close;
diff --git a/mysql-test/suite/innodb/r/innodb-autoinc-61209.result b/mysql-test/suite/innodb/r/innodb-autoinc-61209.result
new file mode 100644
index 00000000000..1ae672fcf98
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-autoinc-61209.result
@@ -0,0 +1,30 @@
+DROP TABLE IF EXISTS bug_61209;
+CREATE TABLE bug_61209 (a INT auto_increment, PRIMARY KEY(a)) ENGINE=InnoDB;
+INSERT INTO bug_61209 VALUES (), ();
+
+# Connect con1
+
+# Connect con2
+
+# Connection con1
+SET SESSION auto_increment_increment=3;
+SET SESSION auto_increment_offset=2;
+SELECT GET_LOCK('a', 9);
+GET_LOCK('a', 9)
+1
+
+# Connection con2
+SET SESSION auto_increment_increment=3;
+SET SESSION auto_increment_offset=2;
+INSERT INTO bug_61209 (a) VALUES (NULL), (NULL), (NULL + GET_LOCK('a', 10));
+
+# Connection con1 reap
+INSERT INTO bug_61209 (a) VALUES (NULL), (NULL), (NULL);
+SELECT RELEASE_LOCK('a');
+RELEASE_LOCK('a')
+1
+
+# Connection con2 reap
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 3
+DROP TABLE bug_61209;
diff --git a/mysql-test/suite/innodb/r/innodb-autoinc.result b/mysql-test/suite/innodb/r/innodb-autoinc.result
index 0c8d16f27fb..fa821372337 100644
--- a/mysql-test/suite/innodb/r/innodb-autoinc.result
+++ b/mysql-test/suite/innodb/r/innodb-autoinc.result
@@ -366,7 +366,7 @@ c1
310
400
1000
-1010
+1110
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
@@ -648,7 +648,7 @@ t2 CREATE TABLE `t2` (
`n` int(10) unsigned NOT NULL,
`o` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`m`)
-) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 ;
SHOW CREATE TABLE t1;
Table Create Table
@@ -657,7 +657,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 ;
SELECT * FROM t1;
a b c
@@ -671,16 +671,16 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
-13 1 TRUE
-14 1 FALSE
-15 2 TRUE
-16 2 FALSE
-17 3 TRUE
-18 3 FALSE
-19 4 TRUE
-20 4 FALSE
-21 5 TRUE
-22 5 FALSE
+16 1 TRUE
+17 1 FALSE
+18 2 TRUE
+19 2 FALSE
+20 3 TRUE
+21 3 FALSE
+22 4 TRUE
+23 4 FALSE
+24 5 TRUE
+25 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -688,7 +688,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SELECT * FROM t1;
a b c
@@ -702,21 +702,21 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
-13 1 TRUE
-14 1 FALSE
-15 2 TRUE
-16 2 FALSE
-17 3 TRUE
-18 3 FALSE
-19 4 TRUE
-20 4 FALSE
-21 5 TRUE
-22 5 FALSE
-23 1 FALSE
-24 2 FALSE
-25 3 FALSE
-26 4 FALSE
-27 5 FALSE
+16 1 TRUE
+17 1 FALSE
+18 2 TRUE
+19 2 FALSE
+20 3 TRUE
+21 3 FALSE
+22 4 TRUE
+23 4 FALSE
+24 5 TRUE
+25 5 FALSE
+31 1 FALSE
+32 2 FALSE
+33 3 FALSE
+34 4 FALSE
+35 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -724,7 +724,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SELECT * FROM t1;
a b c
@@ -738,26 +738,26 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
-13 1 TRUE
-14 1 FALSE
-15 2 TRUE
-16 2 FALSE
-17 3 TRUE
-18 3 FALSE
-19 4 TRUE
-20 4 FALSE
-21 5 TRUE
-22 5 FALSE
-23 1 FALSE
-24 2 FALSE
-25 3 FALSE
-26 4 FALSE
-27 5 FALSE
-30 1 FALSE
-31 2 FALSE
-32 3 FALSE
-33 4 FALSE
-34 5 FALSE
+16 1 TRUE
+17 1 FALSE
+18 2 TRUE
+19 2 FALSE
+20 3 TRUE
+21 3 FALSE
+22 4 TRUE
+23 4 FALSE
+24 5 TRUE
+25 5 FALSE
+31 1 FALSE
+32 2 FALSE
+33 3 FALSE
+34 4 FALSE
+35 5 FALSE
+38 1 FALSE
+39 2 FALSE
+40 3 FALSE
+41 4 FALSE
+42 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -765,7 +765,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SHOW CREATE TABLE t1;
Table Create Table
@@ -774,7 +774,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=52 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SHOW CREATE TABLE t1;
Table Create Table
@@ -783,7 +783,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SELECT * FROM t1;
a b c
@@ -797,41 +797,41 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
-13 1 TRUE
-14 1 FALSE
-15 2 TRUE
-16 2 FALSE
-17 3 TRUE
-18 3 FALSE
-19 4 TRUE
-20 4 FALSE
-21 5 TRUE
-22 5 FALSE
-23 1 FALSE
-24 2 FALSE
-25 3 FALSE
-26 4 FALSE
-27 5 FALSE
-30 1 FALSE
-31 2 FALSE
-32 3 FALSE
-33 4 FALSE
-34 5 FALSE
-37 1 FALSE
-38 2 FALSE
-39 3 FALSE
-40 4 FALSE
-41 5 FALSE
-44 1 FALSE
-45 2 FALSE
-46 3 FALSE
-47 4 FALSE
-48 5 FALSE
-51 1 FALSE
-52 2 FALSE
-53 3 FALSE
-54 4 FALSE
-55 5 FALSE
+16 1 TRUE
+17 1 FALSE
+18 2 TRUE
+19 2 FALSE
+20 3 TRUE
+21 3 FALSE
+22 4 TRUE
+23 4 FALSE
+24 5 TRUE
+25 5 FALSE
+31 1 FALSE
+32 2 FALSE
+33 3 FALSE
+34 4 FALSE
+35 5 FALSE
+38 1 FALSE
+39 2 FALSE
+40 3 FALSE
+41 4 FALSE
+42 5 FALSE
+45 1 FALSE
+46 2 FALSE
+47 3 FALSE
+48 4 FALSE
+49 5 FALSE
+52 1 FALSE
+53 2 FALSE
+54 3 FALSE
+55 4 FALSE
+56 5 FALSE
+59 1 FALSE
+60 2 FALSE
+61 3 FALSE
+62 4 FALSE
+63 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -839,7 +839,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=58 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=latin1
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE IF EXISTS t1;
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index 244ad5f4435..94644ddffbe 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
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
@@ -1928,7 +1928,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
@@ -2104,7 +2104,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_bug54044.result b/mysql-test/suite/innodb/r/innodb_bug54044.result
index 90ab812f2ae..3f607e20ddf 100644
--- a/mysql-test/suite/innodb/r/innodb_bug54044.result
+++ b/mysql-test/suite/innodb/r/innodb_bug54044.result
@@ -1,3 +1,2 @@
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
-ERROR HY000: Can't create table 'test.table_54044' (errno: -1)
diff --git a/mysql-test/suite/innodb/r/innodb_gis.result b/mysql-test/suite/innodb/r/innodb_gis.result
index d1237942a6a..3f957dcd606 100644
--- a/mysql-test/suite/innodb/r/innodb_gis.result
+++ b/mysql-test/suite/innodb/r/innodb_gis.result
@@ -236,7 +236,7 @@ explain extended select Dimension(g), GeometryType(g), IsEmpty(g), AsText(Envelo
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_geometry ALL NULL NULL NULL NULL 21 100.00
Warnings:
-Note 1003 select dimension(`test`.`gis_geometry`.`g`) AS `Dimension(g)`,geometrytype(`test`.`gis_geometry`.`g`) AS `GeometryType(g)`,isempty(`test`.`gis_geometry`.`g`) AS `IsEmpty(g)`,astext(envelope(`test`.`gis_geometry`.`g`)) AS `AsText(Envelope(g))` from `test`.`gis_geometry`
+Note 1003 select st_dimension(`test`.`gis_geometry`.`g`) AS `Dimension(g)`,st_geometrytype(`test`.`gis_geometry`.`g`) AS `GeometryType(g)`,st_isempty(`test`.`gis_geometry`.`g`) AS `IsEmpty(g)`,st_astext(st_envelope(`test`.`gis_geometry`.`g`)) AS `AsText(Envelope(g))` from `test`.`gis_geometry`
SELECT fid, X(g) FROM gis_point ORDER by fid;
fid X(g)
101 10
@@ -253,7 +253,7 @@ explain extended select X(g),Y(g) FROM gis_point;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_point ALL NULL NULL NULL NULL 4 100.00
Warnings:
-Note 1003 select x(`test`.`gis_point`.`g`) AS `X(g)`,y(`test`.`gis_point`.`g`) AS `Y(g)` from `test`.`gis_point`
+Note 1003 select st_x(`test`.`gis_point`.`g`) AS `X(g)`,st_y(`test`.`gis_point`.`g`) AS `Y(g)` from `test`.`gis_point`
SELECT fid, AsText(StartPoint(g)) FROM gis_line ORDER by fid;
fid AsText(StartPoint(g))
105 POINT(0 0)
@@ -288,7 +288,7 @@ explain extended select AsText(StartPoint(g)),AsText(EndPoint(g)),GLength(g),Num
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_line ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select astext(startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint(g))`,astext(endpoint(`test`.`gis_line`.`g`)) AS `AsText(EndPoint(g))`,glength(`test`.`gis_line`.`g`) AS `GLength(g)`,numpoints(`test`.`gis_line`.`g`) AS `NumPoints(g)`,astext(pointn(`test`.`gis_line`.`g`,2)) AS `AsText(PointN(g, 2))`,isclosed(`test`.`gis_line`.`g`) AS `IsClosed(g)` from `test`.`gis_line`
+Note 1003 select st_astext(st_startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint(g))`,st_astext(st_endpoint(`test`.`gis_line`.`g`)) AS `AsText(EndPoint(g))`,st_length(`test`.`gis_line`.`g`) AS `GLength(g)`,st_numpoints(`test`.`gis_line`.`g`) AS `NumPoints(g)`,st_astext(st_pointn(`test`.`gis_line`.`g`,2)) AS `AsText(PointN(g, 2))`,st_isclosed(`test`.`gis_line`.`g`) AS `IsClosed(g)` from `test`.`gis_line`
SELECT fid, AsText(Centroid(g)) FROM gis_polygon ORDER by fid;
fid AsText(Centroid(g))
108 POINT(15 15)
@@ -318,7 +318,7 @@ explain extended select AsText(Centroid(g)),Area(g),AsText(ExteriorRing(g)),NumI
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_polygon ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select astext(centroid(`test`.`gis_polygon`.`g`)) AS `AsText(Centroid(g))`,area(`test`.`gis_polygon`.`g`) AS `Area(g)`,astext(exteriorring(`test`.`gis_polygon`.`g`)) AS `AsText(ExteriorRing(g))`,numinteriorrings(`test`.`gis_polygon`.`g`) AS `NumInteriorRings(g)`,astext(interiorringn(`test`.`gis_polygon`.`g`,1)) AS `AsText(InteriorRingN(g, 1))` from `test`.`gis_polygon`
+Note 1003 select st_astext(st_centroid(`test`.`gis_polygon`.`g`)) AS `AsText(Centroid(g))`,st_area(`test`.`gis_polygon`.`g`) AS `Area(g)`,st_astext(st_exteriorring(`test`.`gis_polygon`.`g`)) AS `AsText(ExteriorRing(g))`,st_numinteriorrings(`test`.`gis_polygon`.`g`) AS `NumInteriorRings(g)`,st_astext(st_interiorringn(`test`.`gis_polygon`.`g`,1)) AS `AsText(InteriorRingN(g, 1))` from `test`.`gis_polygon`
SELECT fid, IsClosed(g) FROM gis_multi_line ORDER by fid;
fid IsClosed(g)
114 0
@@ -357,7 +357,7 @@ explain extended SELECT fid, NumGeometries(g) from gis_multi_point;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,numgeometries(`test`.`gis_multi_point`.`g`) AS `NumGeometries(g)` from `test`.`gis_multi_point`
+Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_numgeometries(`test`.`gis_multi_point`.`g`) AS `NumGeometries(g)` from `test`.`gis_multi_point`
SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point ORDER by fid;
fid AsText(GeometryN(g, 2))
111 POINT(10 10)
@@ -385,17 +385,17 @@ explain extended SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,astext(geometryn(`test`.`gis_multi_point`.`g`,2)) AS `AsText(GeometryN(g, 2))` from `test`.`gis_multi_point`
+Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_astext(st_geometryn(`test`.`gis_multi_point`.`g`,2)) AS `AsText(GeometryN(g, 2))` from `test`.`gis_multi_point`
SELECT g1.fid as first, g2.fid as second,
Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o,
Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
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;
first second w c o e d t i r
-120 120 1 1 0 1 0 0 1 0
+120 120 1 1 0 1 0 1 1 0
120 121 0 0 1 0 0 0 1 0
121 120 0 0 1 0 0 0 1 0
-121 121 1 1 0 1 0 0 1 0
+121 121 1 1 0 1 0 1 1 0
explain extended SELECT g1.fid as first, g2.fid as second,
Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o,
Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
@@ -403,9 +403,9 @@ 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`
+Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,st_within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,st_contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,mbroverlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,st_equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,mbrdisjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,st_touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,mbrintersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,st_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;
CREATE TABLE t1 (
a INTEGER PRIMARY KEY AUTO_INCREMENT,
@@ -494,7 +494,7 @@ mbroverlaps
down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrtouches
-down2,left2,right2,up2
+big,center,down,down2,left,left2,right,right2,small,up,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrwithin
big,center
@@ -515,7 +515,7 @@ overlaps
down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
touches
-down2,left2,right2,up2
+big,center,down,down2,left,left2,right,right2,small,up,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
within
big,center
diff --git a/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result b/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result
index bd8760b8f79..2cb761c6ea1 100644
--- a/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result
+++ b/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result
@@ -97,6 +97,8 @@ insert into t1 values (1,1), (2,null), (3,1), (4,1),
# Demonstrate that for the SELECT statement
# used later in the test JT_EQ_REF access method is used.
#
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
explain
select 1 from t1 natural join (select 2 as a, 1 as b union all
select 2 as a, 2 as b) as t2 for update;
@@ -150,6 +152,7 @@ key_len NULL
ref NULL
rows NULL
Extra
+set optimizer_switch=@tmp_optimizer_switch;
#
# Demonstrate that the reported SELECT statement
# no longer produces warnings.
@@ -301,6 +304,8 @@ begin;
# is retreived and processed first.
#
# Verify that JT_EQ_REF is used.
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
explain
select 1 from t1 natural join (select 3 as a, 2 as b union all
select 3 as a, 1 as b) as t2 for update;
@@ -354,6 +359,7 @@ key_len NULL
ref NULL
rows NULL
Extra
+set optimizer_switch=@tmp_optimizer_switch;
# Lock the record.
select 1 from t1 natural join (select 3 as a, 2 as b union all
select 3 as a, 1 as b) as t2 for update;
diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result
index e022bd961d6..5d0cacca509 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
@@ -316,7 +316,7 @@ INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (1);
DELETE IGNORE FROM t1 WHERE i = 1;
Warnings:
-Error 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`) ON DELETE NO ACTION)
+Warning 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`) ON DELETE NO ACTION)
SELECT * FROM t1, t2;
i i
1 1
@@ -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;
@@ -679,8 +679,6 @@ INSERT INTO t1(b,c) SELECT b,c FROM t2;
UPDATE t2 SET c='2007-01-03';
INSERT INTO t1(b,c) SELECT b,c FROM t2;
set @@sort_buffer_size=8192;
-Warnings:
-Warning 1292 Truncated incorrect sort_buffer_size value: '8192'
SELECT COUNT(*) FROM t1;
COUNT(*)
3072
@@ -1426,12 +1424,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='in_to_exists=on,materialization=off';
explain
-select b from t1 where a not in (select b from t1,t2 group by a) group by a;
+select b from t1 where a not in (select max(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` (
@@ -1738,8 +1739,8 @@ EXPLAIN
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
-2 DERIVED t1 ALL c3,c2 c3 5 const 5 Using where; Using filesort
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ref c3,c2 c3 5 const 2 Using where; Using filesort
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3))
ENGINE=InnoDB;
@@ -1752,8 +1753,8 @@ EXPLAIN
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
-2 DERIVED t1 ALL c3,c2 c3 9 const 5 Using where; Using filesort
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ref c3,c2 c3 9 const 2 Using where; Using filesort
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2),
KEY (c3), KEY (c2, c3))
@@ -1767,8 +1768,8 @@ EXPLAIN
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
-2 DERIVED t1 ALL c3,c2 c3 7 const 5 Using where; Using filesort
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ref c3,c2 c3 7 const 2 Using where; Using filesort
DROP TABLE t1;
End of 5.1 tests
drop table if exists t1, t2, t3;
@@ -2556,7 +2557,7 @@ INSERT INTO t1 VALUES (0);
SET SQL_MODE='STRICT_ALL_TABLES';
CREATE TABLE t2
SELECT LEAST((SELECT '' FROM t1),NOW()) FROM `t1`;
-ERROR 22007: Incorrect datetime value: '' for column 'NOW()' at row 1
+ERROR 22007: Incorrect datetime value: ''
DROP TABLE t1;
SET SQL_MODE=DEFAULT;
#
@@ -2670,8 +2671,7 @@ SELECT COUNT(*) FROM
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
-2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 1536 Using sort_union(idx,PRIMARY); Using where
+1 SIMPLE t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 1536 Using sort_union(idx,PRIMARY); Using where
SELECT COUNT(*) FROM
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
@@ -2689,6 +2689,7 @@ select * from t1;
a b
1 1
drop table t1;
+End of 5.1 tests
#
# Test for bug #39932 "create table fails if column for FK is in different
# case than in corr index".
@@ -2710,6 +2711,97 @@ t2 CREATE TABLE `t2` (
) 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 hash_index PRIMARY #hash#PRIMARY:PRIMARY 4:4 test.t1.pk 13 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 index PRIMARY idx 5 NULL 6 Using where; Using index
+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;
+#
# Test for bug #56619 - Assertion failed during
# ALTER TABLE RENAME, DISABLE KEYS
#
@@ -2734,3 +2826,26 @@ UPDATE t1 SET c = 5;
UNLOCK TABLES;
DROP TEMPORARY TABLE t1;
End of 5.1 tests
+#
+# Bug#702322: HAVING with two ANDed predicates + ORDER BY
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, a int, KEY (a)) ENGINE=InnoDB;
+CREATE TABLE t2 (a int, KEY (a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(18,0),(9,10),(8,11),(2,15),(7,19),(1,20);
+SET SESSION join_cache_level = 0;
+EXPLAIN
+SELECT t1.a FROM t1 LEFT JOIN t2 ON t1.pk = t2.a
+WHERE t1.pk >= 6 HAVING t1.a<> 0 AND t1.a <> 11
+ORDER BY t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using filesort
+1 SIMPLE t2 ref a a 5 test.t1.pk 1 Using index
+SELECT t1.a FROM t1 LEFT JOIN t2 ON t1.pk = t2.a
+WHERE t1.pk >= 6 HAVING t1.a<> 0 AND t1.a <> 11
+ORDER BY t1.a;
+a
+10
+19
+DROP TABLE t1,t2;
+End of 5.3 tests
diff --git a/mysql-test/suite/innodb/t/innodb-autoinc-61209.test b/mysql-test/suite/innodb/t/innodb-autoinc-61209.test
new file mode 100644
index 00000000000..cf0b7cf2415
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-autoinc-61209.test
@@ -0,0 +1,55 @@
+# This is the test case for bug #61209 - duplicate key errors
+# when using auto_increment_increment > 1 and auto_increment_offset > 1
+#
+--source include/have_innodb.inc
+
+#
+# Precautionary clean up.
+#
+--disable_warnings
+DROP TABLE IF EXISTS bug_61209;
+--enable_warnings
+
+#
+# Create test data.
+#
+CREATE TABLE bug_61209 (a INT auto_increment, PRIMARY KEY(a)) ENGINE=InnoDB;
+
+INSERT INTO bug_61209 VALUES (), ();
+
+--echo
+--echo # Connect con1
+--connect (con1,localhost,root,,)
+--echo
+--echo # Connect con2
+--connect (con2,localhost,root,,)
+
+--echo
+--echo # Connection con1
+--connection con1
+SET SESSION auto_increment_increment=3;
+SET SESSION auto_increment_offset=2;
+SELECT GET_LOCK('a', 9);
+
+--echo
+--echo # Connection con2
+--connection con2
+SET SESSION auto_increment_increment=3;
+SET SESSION auto_increment_offset=2;
+send INSERT INTO bug_61209 (a) VALUES (NULL), (NULL), (NULL + GET_LOCK('a', 10));
+
+--echo
+--echo # Connection con1 reap
+--connection con1
+INSERT INTO bug_61209 (a) VALUES (NULL), (NULL), (NULL);
+SELECT RELEASE_LOCK('a');
+
+--echo
+--echo # Connection con2 reap
+--connection con2
+reap;
+
+#
+# Clean up
+#
+DROP TABLE bug_61209;
diff --git a/mysql-test/suite/innodb/t/innodb_bug51920.test b/mysql-test/suite/innodb/t/innodb_bug51920.test
index bc3bb006c1c..3c386980ed4 100644
--- a/mysql-test/suite/innodb/t/innodb_bug51920.test
+++ b/mysql-test/suite/innodb/t/innodb_bug51920.test
@@ -36,7 +36,7 @@ let $wait_condition =
# depending on platform.
#
connection con1;
--- error 1317, 2006, 2013
+-- error 1317, 2006, 2013, 1927
reap;
connection default;
DROP TABLE bug51920;
diff --git a/mysql-test/suite/innodb/t/innodb_bug54044.test b/mysql-test/suite/innodb/t/innodb_bug54044.test
index a6722ed6399..32a4ca0e116 100644
--- a/mysql-test/suite/innodb/t/innodb_bug54044.test
+++ b/mysql-test/suite/innodb/t/innodb_bug54044.test
@@ -1,11 +1,4 @@
-# This is the test for bug #54044. Special handle MYSQL_TYPE_NULL type
-# during create table, so it will not trigger assertion failure.
-
--source include/have_innodb.inc
-# This 'create table' operation should fail because of
-# using NULL datatype
---error ER_CANT_CREATE_TABLE
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
-
diff --git a/mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1.test b/mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1.test
index fcbf2b1cfc7..2707b97bfa2 100644
--- a/mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1.test
+++ b/mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1.test
@@ -140,9 +140,12 @@ insert into t1 values (1,1), (2,null), (3,1), (4,1),
--echo # used later in the test JT_EQ_REF access method is used.
--echo #
--vertical_results
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
explain
select 1 from t1 natural join (select 2 as a, 1 as b union all
select 2 as a, 2 as b) as t2 for update;
+set optimizer_switch=@tmp_optimizer_switch;
--horizontal_results
--echo #
--echo # Demonstrate that the reported SELECT statement
@@ -236,9 +239,12 @@ begin;
--echo #
--echo # Verify that JT_EQ_REF is used.
--vertical_results
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
explain
select 1 from t1 natural join (select 3 as a, 2 as b union all
select 3 as a, 1 as b) as t2 for update;
+set optimizer_switch=@tmp_optimizer_switch;
--horizontal_results
--echo # Lock the record.
select 1 from t1 natural join (select 3 as a, 2 as b union all
diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test
index 0b34245dda0..a860f52c187 100644
--- a/mysql-test/suite/innodb/t/innodb_mysql.test
+++ b/mysql-test/suite/innodb/t/innodb_mysql.test
@@ -911,6 +911,8 @@ alter ignore table t1 add unique `main` (b);
select * from t1;
drop table t1;
+--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".
@@ -929,9 +931,78 @@ 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 #
--echo # Test for bug #56619 - Assertion failed during
--echo # ALTER TABLE RENAME, DISABLE KEYS
--echo #
+
--disable_warnings
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
@@ -941,7 +1012,6 @@ ALTER TABLE t1 RENAME TO t2, DISABLE KEYS;
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
-
--echo #
--echo # Test for bug #11762012 - "54553: INNODB ASSERTS IN HA_INNOBASE::
--echo # UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK".
@@ -962,3 +1032,27 @@ UNLOCK TABLES;
DROP TEMPORARY TABLE t1;
--echo End of 5.1 tests
+
+--echo #
+--echo # Bug#702322: HAVING with two ANDed predicates + ORDER BY
+--echo #
+
+CREATE TABLE t1 (pk int PRIMARY KEY, a int, KEY (a)) ENGINE=InnoDB;
+CREATE TABLE t2 (a int, KEY (a)) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES
+ (18,0),(9,10),(8,11),(2,15),(7,19),(1,20);
+
+SET SESSION join_cache_level = 0;
+
+EXPLAIN
+SELECT t1.a FROM t1 LEFT JOIN t2 ON t1.pk = t2.a
+ WHERE t1.pk >= 6 HAVING t1.a<> 0 AND t1.a <> 11
+ ORDER BY t1.a;
+SELECT t1.a FROM t1 LEFT JOIN t2 ON t1.pk = t2.a
+ WHERE t1.pk >= 6 HAVING t1.a<> 0 AND t1.a <> 11
+ ORDER BY t1.a;
+
+DROP TABLE t1,t2;
+
+--echo End of 5.3 tests
diff --git a/mysql-test/suite/innodb_plugin/r/binlog_consistent.result b/mysql-test/suite/innodb_plugin/r/binlog_consistent.result
new file mode 100644
index 00000000000..09cbbd98fac
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/r/binlog_consistent.result
@@ -0,0 +1,99 @@
+RESET MASTER;
+# Connection default
+CREATE TABLE t1 (a INT, b VARCHAR(100), PRIMARY KEY (a,b)) ENGINE=innodb;
+SHOW MASTER STATUS;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 380
+SHOW STATUS LIKE 'binlog_snapshot_%';
+Variable_name Value
+binlog_snapshot_file master-bin.000001
+binlog_snapshot_position 380
+BEGIN;
+INSERT INTO t1 VALUES (0, "");
+# Connection con1
+BEGIN;
+INSERT INTO t1 VALUES (1, "");
+# Connection con2
+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=myisam;
+BEGIN;
+INSERT INTO t1 VALUES (2, "first");
+INSERT INTO t2 VALUES (2);
+INSERT INTO t1 VALUES (2, "second");
+# Connection default
+COMMIT;
+SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+# Connection con3
+BEGIN;
+INSERT INTO t1 VALUES (3, "");
+INSERT INTO t2 VALUES (3);
+# Connection con4
+BEGIN;
+INSERT INTO t1 VALUES (4, "");
+COMMIT;
+# Connection default
+SELECT * FROM t1 ORDER BY a,b;
+a b
+0
+SHOW STATUS LIKE 'binlog_snapshot_%';
+Variable_name Value
+binlog_snapshot_file master-bin.000001
+binlog_snapshot_position 679
+SHOW MASTER STATUS;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 866
+SELECT * FROM t2 ORDER BY a;
+a
+2
+3
+# Connection con1
+COMMIT;
+# Connection con2
+COMMIT;
+# Connection con3
+COMMIT;
+FLUSH LOGS;
+# Connection default
+SELECT * FROM t1 ORDER BY a,b;
+a b
+0
+SHOW STATUS LIKE 'binlog_snapshot_%';
+Variable_name Value
+binlog_snapshot_file master-bin.000001
+binlog_snapshot_position 679
+SHOW MASTER STATUS;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000002 245
+COMMIT;
+SHOW STATUS LIKE 'binlog_snapshot_%';
+Variable_name Value
+binlog_snapshot_file master-bin.000002
+binlog_snapshot_position 245
+SHOW MASTER STATUS;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000002 245
+SHOW BINLOG EVENTS;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 4 Format_desc 1 245 Server ver: #, Binlog ver: #
+master-bin.000001 245 Query 1 380 use `test`; CREATE TABLE t1 (a INT, b VARCHAR(100), PRIMARY KEY (a,b)) ENGINE=innodb
+master-bin.000001 380 Query 1 492 use `test`; CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=myisam
+master-bin.000001 492 Query 1 560 BEGIN
+master-bin.000001 560 Query 1 652 use `test`; INSERT INTO t1 VALUES (0, "")
+master-bin.000001 652 Xid 1 679 COMMIT /* XID */
+master-bin.000001 679 Query 1 747 BEGIN
+master-bin.000001 747 Query 1 839 use `test`; INSERT INTO t1 VALUES (4, "")
+master-bin.000001 839 Xid 1 866 COMMIT /* XID */
+master-bin.000001 866 Query 1 934 BEGIN
+master-bin.000001 934 Query 1 1026 use `test`; INSERT INTO t1 VALUES (1, "")
+master-bin.000001 1026 Xid 1 1053 COMMIT /* XID */
+master-bin.000001 1053 Query 1 1121 BEGIN
+master-bin.000001 1121 Query 1 1218 use `test`; INSERT INTO t1 VALUES (2, "first")
+master-bin.000001 1218 Query 1 1306 use `test`; INSERT INTO t2 VALUES (2)
+master-bin.000001 1306 Query 1 1404 use `test`; INSERT INTO t1 VALUES (2, "second")
+master-bin.000001 1404 Xid 1 1431 COMMIT /* XID */
+master-bin.000001 1431 Query 1 1499 BEGIN
+master-bin.000001 1499 Query 1 1591 use `test`; INSERT INTO t1 VALUES (3, "")
+master-bin.000001 1591 Query 1 1679 use `test`; INSERT INTO t2 VALUES (3)
+master-bin.000001 1679 Xid 1 1706 COMMIT /* XID */
+master-bin.000001 1706 Rotate 1 1750 master-bin.000002;pos=4
+DROP TABLE t1,t2;
diff --git a/mysql-test/suite/innodb_plugin/r/group_commit.result b/mysql-test/suite/innodb_plugin/r/group_commit.result
new file mode 100644
index 00000000000..1009a83637f
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/r/group_commit.result
@@ -0,0 +1,65 @@
+CREATE TABLE t1 (a VARCHAR(10) PRIMARY KEY) ENGINE=innodb;
+SELECT variable_value INTO @commits FROM information_schema.global_status
+WHERE variable_name = 'binlog_commits';
+SELECT variable_value INTO @group_commits FROM information_schema.global_status
+WHERE variable_name = 'binlog_group_commits';
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group1_running WAIT_FOR group2_queued";
+INSERT INTO t1 VALUES ("con1");
+set DEBUG_SYNC= "now WAIT_FOR group1_running";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con2";
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group2_running";
+SET DEBUG_SYNC= "commit_after_release_LOCK_log WAIT_FOR group3_committed";
+SET DEBUG_SYNC= "commit_after_group_run_commit_ordered SIGNAL group2_visible WAIT_FOR group2_checked";
+INSERT INTO t1 VALUES ("con2");
+SET DEBUG_SYNC= "now WAIT_FOR group2_con2";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con3";
+INSERT INTO t1 VALUES ("con3");
+SET DEBUG_SYNC= "now WAIT_FOR group2_con3";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con4";
+INSERT INTO t1 VALUES ("con4");
+SET DEBUG_SYNC= "now WAIT_FOR group2_con4";
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+SELECT * FROM t1 ORDER BY a;
+a
+SET DEBUG_SYNC= "now SIGNAL group2_queued";
+SELECT * FROM t1 ORDER BY a;
+a
+con1
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group3_con5";
+SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con5_leader WAIT_FOR con6_queued";
+set DEBUG_SYNC= "now WAIT_FOR group2_running";
+INSERT INTO t1 VALUES ("con5");
+SET DEBUG_SYNC= "now WAIT_FOR con5_leader";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con6_queued";
+INSERT INTO t1 VALUES ("con6");
+SET DEBUG_SYNC= "now WAIT_FOR group3_con5";
+SELECT * FROM t1 ORDER BY a;
+a
+con1
+SET DEBUG_SYNC= "now SIGNAL group3_committed";
+SET DEBUG_SYNC= "now WAIT_FOR group2_visible";
+SELECT * FROM t1 ORDER BY a;
+a
+con1
+con2
+con3
+con4
+SET DEBUG_SYNC= "now SIGNAL group2_checked";
+SELECT * FROM t1 ORDER BY a;
+a
+con1
+con2
+con3
+con4
+con5
+con6
+SELECT variable_value - @commits FROM information_schema.global_status
+WHERE variable_name = 'binlog_commits';
+variable_value - @commits
+6
+SELECT variable_value - @group_commits FROM information_schema.global_status
+WHERE variable_name = 'binlog_group_commits';
+variable_value - @group_commits
+3
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_plugin/r/group_commit_binlog_pos.result b/mysql-test/suite/innodb_plugin/r/group_commit_binlog_pos.result
new file mode 100644
index 00000000000..79ade2acec7
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/r/group_commit_binlog_pos.result
@@ -0,0 +1,35 @@
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+INSERT INTO t1 VALUES (0);
+SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con1_waiting WAIT_FOR con3_queued";
+SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont EXECUTE 3";
+INSERT INTO t1 VALUES (1);
+SET DEBUG_SYNC= "now WAIT_FOR con1_waiting";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con2_queued";
+INSERT INTO t1 VALUES (2);
+SET DEBUG_SYNC= "now WAIT_FOR con2_queued";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con3_queued";
+INSERT INTO t1 VALUES (3);
+SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
+SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
+SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
+SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
+SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
+SELECT * FROM t1 ORDER BY a;
+a
+0
+1
+2
+SET SESSION debug="+d,crash_dispatch_command_before";
+SELECT 1;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+SELECT * FROM t1 ORDER BY a;
+a
+0
+1
+2
+3
+InnoDB: Last MySQL binlog file position 0 906, file name ./master-bin.000001
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_plugin/r/group_commit_binlog_pos_no_optimize_thread.result b/mysql-test/suite/innodb_plugin/r/group_commit_binlog_pos_no_optimize_thread.result
new file mode 100644
index 00000000000..e6ea24a67bd
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/r/group_commit_binlog_pos_no_optimize_thread.result
@@ -0,0 +1,36 @@
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+INSERT INTO t1 VALUES (0);
+SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con1_waiting WAIT_FOR con3_queued";
+SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont";
+INSERT INTO t1 VALUES (1);
+SET DEBUG_SYNC= "now WAIT_FOR con1_waiting";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con2_queued";
+SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont";
+INSERT INTO t1 VALUES (2);
+SET DEBUG_SYNC= "now WAIT_FOR con2_queued";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con3_queued";
+SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont";
+INSERT INTO t1 VALUES (3);
+SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
+SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
+SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
+SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
+SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
+SELECT * FROM t1 ORDER BY a;
+a
+0
+1
+2
+SET SESSION debug="+d,crash_dispatch_command_before";
+SELECT 1;
+Got one of the listed errors
+Got one of the listed errors
+SELECT * FROM t1 ORDER BY a;
+a
+0
+1
+2
+3
+InnoDB: Last MySQL binlog file position 0 906, file name ./master-bin.000001
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_plugin/r/group_commit_crash.result b/mysql-test/suite/innodb_plugin/r/group_commit_crash.result
new file mode 100644
index 00000000000..a55d8f29dda
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/r/group_commit_crash.result
@@ -0,0 +1,125 @@
+CREATE TABLE t1(a CHAR(255),
+b CHAR(255),
+c CHAR(255),
+d CHAR(255),
+id INT AUTO_INCREMENT,
+PRIMARY KEY(id)) ENGINE=InnoDB;
+create table t2 like t1;
+create procedure setcrash(IN i INT)
+begin
+CASE i
+WHEN 1 THEN SET SESSION debug="d,crash_commit_after_prepare";
+WHEN 2 THEN SET SESSION debug="d,crash_commit_after_log";
+WHEN 3 THEN SET SESSION debug="d,crash_commit_before_unlog";
+WHEN 4 THEN SET SESSION debug="d,crash_commit_after";
+WHEN 5 THEN SET SESSION debug="d,crash_commit_before";
+ELSE BEGIN END;
+END CASE;
+end //
+FLUSH TABLES;
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+SET binlog_format= mixed;
+RESET MASTER;
+START TRANSACTION;
+insert into t1 select * from t2;
+call setcrash(5);
+COMMIT;
+Got one of the listed errors
+SELECT * FROM t1 ORDER BY id;
+a b c d id
+SHOW BINLOG EVENTS LIMIT 2,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+delete from t1;
+SET binlog_format= mixed;
+RESET MASTER;
+START TRANSACTION;
+insert into t1 select * from t2;
+call setcrash(4);
+COMMIT;
+Got one of the listed errors
+SELECT * FROM t1 ORDER BY id;
+a b c d id
+a b c d 1
+a b c d 2
+a b c d 3
+a b c d 4
+a b c d 5
+a b c d 6
+a b c d 7
+a b c d 8
+a b c d 9
+a b c d 10
+SHOW BINLOG EVENTS LIMIT 2,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; insert into t1 select * from t2
+delete from t1;
+SET binlog_format= mixed;
+RESET MASTER;
+START TRANSACTION;
+insert into t1 select * from t2;
+call setcrash(3);
+COMMIT;
+Got one of the listed errors
+SELECT * FROM t1 ORDER BY id;
+a b c d id
+a b c d 1
+a b c d 2
+a b c d 3
+a b c d 4
+a b c d 5
+a b c d 6
+a b c d 7
+a b c d 8
+a b c d 9
+a b c d 10
+SHOW BINLOG EVENTS LIMIT 2,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; insert into t1 select * from t2
+delete from t1;
+SET binlog_format= mixed;
+RESET MASTER;
+START TRANSACTION;
+insert into t1 select * from t2;
+call setcrash(2);
+COMMIT;
+Got one of the listed errors
+SELECT * FROM t1 ORDER BY id;
+a b c d id
+a b c d 1
+a b c d 2
+a b c d 3
+a b c d 4
+a b c d 5
+a b c d 6
+a b c d 7
+a b c d 8
+a b c d 9
+a b c d 10
+SHOW BINLOG EVENTS LIMIT 2,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; insert into t1 select * from t2
+delete from t1;
+SET binlog_format= mixed;
+RESET MASTER;
+START TRANSACTION;
+insert into t1 select * from t2;
+call setcrash(1);
+COMMIT;
+Got one of the listed errors
+SELECT * FROM t1 ORDER BY id;
+a b c d id
+SHOW BINLOG EVENTS LIMIT 2,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+delete from t1;
+DROP TABLE t1;
+DROP TABLE t2;
+DROP PROCEDURE setcrash;
diff --git a/mysql-test/suite/innodb_plugin/r/group_commit_crash_no_optimize_thread.result b/mysql-test/suite/innodb_plugin/r/group_commit_crash_no_optimize_thread.result
new file mode 100644
index 00000000000..a55d8f29dda
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/r/group_commit_crash_no_optimize_thread.result
@@ -0,0 +1,125 @@
+CREATE TABLE t1(a CHAR(255),
+b CHAR(255),
+c CHAR(255),
+d CHAR(255),
+id INT AUTO_INCREMENT,
+PRIMARY KEY(id)) ENGINE=InnoDB;
+create table t2 like t1;
+create procedure setcrash(IN i INT)
+begin
+CASE i
+WHEN 1 THEN SET SESSION debug="d,crash_commit_after_prepare";
+WHEN 2 THEN SET SESSION debug="d,crash_commit_after_log";
+WHEN 3 THEN SET SESSION debug="d,crash_commit_before_unlog";
+WHEN 4 THEN SET SESSION debug="d,crash_commit_after";
+WHEN 5 THEN SET SESSION debug="d,crash_commit_before";
+ELSE BEGIN END;
+END CASE;
+end //
+FLUSH TABLES;
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+SET binlog_format= mixed;
+RESET MASTER;
+START TRANSACTION;
+insert into t1 select * from t2;
+call setcrash(5);
+COMMIT;
+Got one of the listed errors
+SELECT * FROM t1 ORDER BY id;
+a b c d id
+SHOW BINLOG EVENTS LIMIT 2,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+delete from t1;
+SET binlog_format= mixed;
+RESET MASTER;
+START TRANSACTION;
+insert into t1 select * from t2;
+call setcrash(4);
+COMMIT;
+Got one of the listed errors
+SELECT * FROM t1 ORDER BY id;
+a b c d id
+a b c d 1
+a b c d 2
+a b c d 3
+a b c d 4
+a b c d 5
+a b c d 6
+a b c d 7
+a b c d 8
+a b c d 9
+a b c d 10
+SHOW BINLOG EVENTS LIMIT 2,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; insert into t1 select * from t2
+delete from t1;
+SET binlog_format= mixed;
+RESET MASTER;
+START TRANSACTION;
+insert into t1 select * from t2;
+call setcrash(3);
+COMMIT;
+Got one of the listed errors
+SELECT * FROM t1 ORDER BY id;
+a b c d id
+a b c d 1
+a b c d 2
+a b c d 3
+a b c d 4
+a b c d 5
+a b c d 6
+a b c d 7
+a b c d 8
+a b c d 9
+a b c d 10
+SHOW BINLOG EVENTS LIMIT 2,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; insert into t1 select * from t2
+delete from t1;
+SET binlog_format= mixed;
+RESET MASTER;
+START TRANSACTION;
+insert into t1 select * from t2;
+call setcrash(2);
+COMMIT;
+Got one of the listed errors
+SELECT * FROM t1 ORDER BY id;
+a b c d id
+a b c d 1
+a b c d 2
+a b c d 3
+a b c d 4
+a b c d 5
+a b c d 6
+a b c d 7
+a b c d 8
+a b c d 9
+a b c d 10
+SHOW BINLOG EVENTS LIMIT 2,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; insert into t1 select * from t2
+delete from t1;
+SET binlog_format= mixed;
+RESET MASTER;
+START TRANSACTION;
+insert into t1 select * from t2;
+call setcrash(1);
+COMMIT;
+Got one of the listed errors
+SELECT * FROM t1 ORDER BY id;
+a b c d id
+SHOW BINLOG EVENTS LIMIT 2,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+delete from t1;
+DROP TABLE t1;
+DROP TABLE t2;
+DROP PROCEDURE setcrash;
diff --git a/mysql-test/suite/innodb_plugin/r/group_commit_no_optimize_thread.result b/mysql-test/suite/innodb_plugin/r/group_commit_no_optimize_thread.result
new file mode 100644
index 00000000000..34a638da2d5
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/r/group_commit_no_optimize_thread.result
@@ -0,0 +1,65 @@
+CREATE TABLE t1 (a VARCHAR(10) PRIMARY KEY) ENGINE=innodb;
+SELECT variable_value INTO @commits FROM information_schema.global_status
+WHERE variable_name = 'binlog_commits';
+SELECT variable_value INTO @group_commits FROM information_schema.global_status
+WHERE variable_name = 'binlog_group_commits';
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group1_running WAIT_FOR group2_queued";
+INSERT INTO t1 VALUES ("con1");
+set DEBUG_SYNC= "now WAIT_FOR group1_running";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con2";
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group2_running";
+SET DEBUG_SYNC= "commit_after_release_LOCK_log WAIT_FOR group3_committed";
+INSERT INTO t1 VALUES ("con2");
+SET DEBUG_SYNC= "now WAIT_FOR group2_con2";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con3";
+INSERT INTO t1 VALUES ("con3");
+SET DEBUG_SYNC= "now WAIT_FOR group2_con3";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con4";
+SET DEBUG_SYNC= "commit_after_group_run_commit_ordered SIGNAL group2_visible WAIT_FOR group2_checked";
+INSERT INTO t1 VALUES ("con4");
+SET DEBUG_SYNC= "now WAIT_FOR group2_con4";
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+SELECT * FROM t1 ORDER BY a;
+a
+SET DEBUG_SYNC= "now SIGNAL group2_queued";
+SELECT * FROM t1 ORDER BY a;
+a
+con1
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group3_con5";
+SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con5_leader WAIT_FOR con6_queued";
+set DEBUG_SYNC= "now WAIT_FOR group2_running";
+INSERT INTO t1 VALUES ("con5");
+SET DEBUG_SYNC= "now WAIT_FOR con5_leader";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con6_queued";
+INSERT INTO t1 VALUES ("con6");
+SET DEBUG_SYNC= "now WAIT_FOR group3_con5";
+SELECT * FROM t1 ORDER BY a;
+a
+con1
+SET DEBUG_SYNC= "now SIGNAL group3_committed";
+SET DEBUG_SYNC= "now WAIT_FOR group2_visible";
+SELECT * FROM t1 ORDER BY a;
+a
+con1
+con2
+con3
+con4
+SET DEBUG_SYNC= "now SIGNAL group2_checked";
+SELECT * FROM t1 ORDER BY a;
+a
+con1
+con2
+con3
+con4
+con5
+con6
+SELECT variable_value - @commits FROM information_schema.global_status
+WHERE variable_name = 'binlog_commits';
+variable_value - @commits
+6
+SELECT variable_value - @group_commits FROM information_schema.global_status
+WHERE variable_name = 'binlog_group_commits';
+variable_value - @group_commits
+3
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result b/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result
index 0c8d16f27fb..fa821372337 100644
--- a/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result
+++ b/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result
@@ -366,7 +366,7 @@ c1
310
400
1000
-1010
+1110
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
@@ -648,7 +648,7 @@ t2 CREATE TABLE `t2` (
`n` int(10) unsigned NOT NULL,
`o` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`m`)
-) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 ;
SHOW CREATE TABLE t1;
Table Create Table
@@ -657,7 +657,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 ;
SELECT * FROM t1;
a b c
@@ -671,16 +671,16 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
-13 1 TRUE
-14 1 FALSE
-15 2 TRUE
-16 2 FALSE
-17 3 TRUE
-18 3 FALSE
-19 4 TRUE
-20 4 FALSE
-21 5 TRUE
-22 5 FALSE
+16 1 TRUE
+17 1 FALSE
+18 2 TRUE
+19 2 FALSE
+20 3 TRUE
+21 3 FALSE
+22 4 TRUE
+23 4 FALSE
+24 5 TRUE
+25 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -688,7 +688,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SELECT * FROM t1;
a b c
@@ -702,21 +702,21 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
-13 1 TRUE
-14 1 FALSE
-15 2 TRUE
-16 2 FALSE
-17 3 TRUE
-18 3 FALSE
-19 4 TRUE
-20 4 FALSE
-21 5 TRUE
-22 5 FALSE
-23 1 FALSE
-24 2 FALSE
-25 3 FALSE
-26 4 FALSE
-27 5 FALSE
+16 1 TRUE
+17 1 FALSE
+18 2 TRUE
+19 2 FALSE
+20 3 TRUE
+21 3 FALSE
+22 4 TRUE
+23 4 FALSE
+24 5 TRUE
+25 5 FALSE
+31 1 FALSE
+32 2 FALSE
+33 3 FALSE
+34 4 FALSE
+35 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -724,7 +724,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SELECT * FROM t1;
a b c
@@ -738,26 +738,26 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
-13 1 TRUE
-14 1 FALSE
-15 2 TRUE
-16 2 FALSE
-17 3 TRUE
-18 3 FALSE
-19 4 TRUE
-20 4 FALSE
-21 5 TRUE
-22 5 FALSE
-23 1 FALSE
-24 2 FALSE
-25 3 FALSE
-26 4 FALSE
-27 5 FALSE
-30 1 FALSE
-31 2 FALSE
-32 3 FALSE
-33 4 FALSE
-34 5 FALSE
+16 1 TRUE
+17 1 FALSE
+18 2 TRUE
+19 2 FALSE
+20 3 TRUE
+21 3 FALSE
+22 4 TRUE
+23 4 FALSE
+24 5 TRUE
+25 5 FALSE
+31 1 FALSE
+32 2 FALSE
+33 3 FALSE
+34 4 FALSE
+35 5 FALSE
+38 1 FALSE
+39 2 FALSE
+40 3 FALSE
+41 4 FALSE
+42 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -765,7 +765,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SHOW CREATE TABLE t1;
Table Create Table
@@ -774,7 +774,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=52 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SHOW CREATE TABLE t1;
Table Create Table
@@ -783,7 +783,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SELECT * FROM t1;
a b c
@@ -797,41 +797,41 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
-13 1 TRUE
-14 1 FALSE
-15 2 TRUE
-16 2 FALSE
-17 3 TRUE
-18 3 FALSE
-19 4 TRUE
-20 4 FALSE
-21 5 TRUE
-22 5 FALSE
-23 1 FALSE
-24 2 FALSE
-25 3 FALSE
-26 4 FALSE
-27 5 FALSE
-30 1 FALSE
-31 2 FALSE
-32 3 FALSE
-33 4 FALSE
-34 5 FALSE
-37 1 FALSE
-38 2 FALSE
-39 3 FALSE
-40 4 FALSE
-41 5 FALSE
-44 1 FALSE
-45 2 FALSE
-46 3 FALSE
-47 4 FALSE
-48 5 FALSE
-51 1 FALSE
-52 2 FALSE
-53 3 FALSE
-54 4 FALSE
-55 5 FALSE
+16 1 TRUE
+17 1 FALSE
+18 2 TRUE
+19 2 FALSE
+20 3 TRUE
+21 3 FALSE
+22 4 TRUE
+23 4 FALSE
+24 5 TRUE
+25 5 FALSE
+31 1 FALSE
+32 2 FALSE
+33 3 FALSE
+34 4 FALSE
+35 5 FALSE
+38 1 FALSE
+39 2 FALSE
+40 3 FALSE
+41 4 FALSE
+42 5 FALSE
+45 1 FALSE
+46 2 FALSE
+47 3 FALSE
+48 4 FALSE
+49 5 FALSE
+52 1 FALSE
+53 2 FALSE
+54 3 FALSE
+55 4 FALSE
+56 5 FALSE
+59 1 FALSE
+60 2 FALSE
+61 3 FALSE
+62 4 FALSE
+63 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -839,7 +839,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB AUTO_INCREMENT=58 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=latin1
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE IF EXISTS t1;
diff --git a/mysql-test/suite/innodb_plugin/r/innodb.result b/mysql-test/suite/innodb_plugin/r/innodb.result
index 0fbe962bab9..1d0f98b0076 100644
--- a/mysql-test/suite/innodb_plugin/r/innodb.result
+++ b/mysql-test/suite/innodb_plugin/r/innodb.result
@@ -1,3 +1,4 @@
+set optimizer_switch='index_condition_pushdown=off,mrr=off';
drop table if exists t1,t2,t3,t4;
drop database if exists mysqltest;
CREATE TABLE bug58912 (a BLOB, b TEXT, PRIMARY KEY(a(1))) ENGINE=InnoDB;
@@ -3256,6 +3257,7 @@ Variable_name Value
Handler_update 1
Variable_name Value
Handler_delete 1
+set optimizer_switch=default;
DROP TABLE bug58912;
create table t1 (f1 integer primary key) engine=innodb;
flush status;
diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result b/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result
index 90ab812f2ae..3f607e20ddf 100644
--- a/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result
+++ b/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result
@@ -1,3 +1,2 @@
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
-ERROR HY000: Can't create table 'test.table_54044' (errno: -1)
diff --git a/mysql-test/suite/innodb_plugin/r/innodb_gis.result b/mysql-test/suite/innodb_plugin/r/innodb_gis.result
index d1237942a6a..3f957dcd606 100644
--- a/mysql-test/suite/innodb_plugin/r/innodb_gis.result
+++ b/mysql-test/suite/innodb_plugin/r/innodb_gis.result
@@ -236,7 +236,7 @@ explain extended select Dimension(g), GeometryType(g), IsEmpty(g), AsText(Envelo
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_geometry ALL NULL NULL NULL NULL 21 100.00
Warnings:
-Note 1003 select dimension(`test`.`gis_geometry`.`g`) AS `Dimension(g)`,geometrytype(`test`.`gis_geometry`.`g`) AS `GeometryType(g)`,isempty(`test`.`gis_geometry`.`g`) AS `IsEmpty(g)`,astext(envelope(`test`.`gis_geometry`.`g`)) AS `AsText(Envelope(g))` from `test`.`gis_geometry`
+Note 1003 select st_dimension(`test`.`gis_geometry`.`g`) AS `Dimension(g)`,st_geometrytype(`test`.`gis_geometry`.`g`) AS `GeometryType(g)`,st_isempty(`test`.`gis_geometry`.`g`) AS `IsEmpty(g)`,st_astext(st_envelope(`test`.`gis_geometry`.`g`)) AS `AsText(Envelope(g))` from `test`.`gis_geometry`
SELECT fid, X(g) FROM gis_point ORDER by fid;
fid X(g)
101 10
@@ -253,7 +253,7 @@ explain extended select X(g),Y(g) FROM gis_point;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_point ALL NULL NULL NULL NULL 4 100.00
Warnings:
-Note 1003 select x(`test`.`gis_point`.`g`) AS `X(g)`,y(`test`.`gis_point`.`g`) AS `Y(g)` from `test`.`gis_point`
+Note 1003 select st_x(`test`.`gis_point`.`g`) AS `X(g)`,st_y(`test`.`gis_point`.`g`) AS `Y(g)` from `test`.`gis_point`
SELECT fid, AsText(StartPoint(g)) FROM gis_line ORDER by fid;
fid AsText(StartPoint(g))
105 POINT(0 0)
@@ -288,7 +288,7 @@ explain extended select AsText(StartPoint(g)),AsText(EndPoint(g)),GLength(g),Num
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_line ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select astext(startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint(g))`,astext(endpoint(`test`.`gis_line`.`g`)) AS `AsText(EndPoint(g))`,glength(`test`.`gis_line`.`g`) AS `GLength(g)`,numpoints(`test`.`gis_line`.`g`) AS `NumPoints(g)`,astext(pointn(`test`.`gis_line`.`g`,2)) AS `AsText(PointN(g, 2))`,isclosed(`test`.`gis_line`.`g`) AS `IsClosed(g)` from `test`.`gis_line`
+Note 1003 select st_astext(st_startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint(g))`,st_astext(st_endpoint(`test`.`gis_line`.`g`)) AS `AsText(EndPoint(g))`,st_length(`test`.`gis_line`.`g`) AS `GLength(g)`,st_numpoints(`test`.`gis_line`.`g`) AS `NumPoints(g)`,st_astext(st_pointn(`test`.`gis_line`.`g`,2)) AS `AsText(PointN(g, 2))`,st_isclosed(`test`.`gis_line`.`g`) AS `IsClosed(g)` from `test`.`gis_line`
SELECT fid, AsText(Centroid(g)) FROM gis_polygon ORDER by fid;
fid AsText(Centroid(g))
108 POINT(15 15)
@@ -318,7 +318,7 @@ explain extended select AsText(Centroid(g)),Area(g),AsText(ExteriorRing(g)),NumI
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_polygon ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select astext(centroid(`test`.`gis_polygon`.`g`)) AS `AsText(Centroid(g))`,area(`test`.`gis_polygon`.`g`) AS `Area(g)`,astext(exteriorring(`test`.`gis_polygon`.`g`)) AS `AsText(ExteriorRing(g))`,numinteriorrings(`test`.`gis_polygon`.`g`) AS `NumInteriorRings(g)`,astext(interiorringn(`test`.`gis_polygon`.`g`,1)) AS `AsText(InteriorRingN(g, 1))` from `test`.`gis_polygon`
+Note 1003 select st_astext(st_centroid(`test`.`gis_polygon`.`g`)) AS `AsText(Centroid(g))`,st_area(`test`.`gis_polygon`.`g`) AS `Area(g)`,st_astext(st_exteriorring(`test`.`gis_polygon`.`g`)) AS `AsText(ExteriorRing(g))`,st_numinteriorrings(`test`.`gis_polygon`.`g`) AS `NumInteriorRings(g)`,st_astext(st_interiorringn(`test`.`gis_polygon`.`g`,1)) AS `AsText(InteriorRingN(g, 1))` from `test`.`gis_polygon`
SELECT fid, IsClosed(g) FROM gis_multi_line ORDER by fid;
fid IsClosed(g)
114 0
@@ -357,7 +357,7 @@ explain extended SELECT fid, NumGeometries(g) from gis_multi_point;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,numgeometries(`test`.`gis_multi_point`.`g`) AS `NumGeometries(g)` from `test`.`gis_multi_point`
+Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_numgeometries(`test`.`gis_multi_point`.`g`) AS `NumGeometries(g)` from `test`.`gis_multi_point`
SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point ORDER by fid;
fid AsText(GeometryN(g, 2))
111 POINT(10 10)
@@ -385,17 +385,17 @@ explain extended SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,astext(geometryn(`test`.`gis_multi_point`.`g`,2)) AS `AsText(GeometryN(g, 2))` from `test`.`gis_multi_point`
+Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,st_astext(st_geometryn(`test`.`gis_multi_point`.`g`,2)) AS `AsText(GeometryN(g, 2))` from `test`.`gis_multi_point`
SELECT g1.fid as first, g2.fid as second,
Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o,
Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
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;
first second w c o e d t i r
-120 120 1 1 0 1 0 0 1 0
+120 120 1 1 0 1 0 1 1 0
120 121 0 0 1 0 0 0 1 0
121 120 0 0 1 0 0 0 1 0
-121 121 1 1 0 1 0 0 1 0
+121 121 1 1 0 1 0 1 1 0
explain extended SELECT g1.fid as first, g2.fid as second,
Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o,
Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
@@ -403,9 +403,9 @@ 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`
+Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,st_within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,st_contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,mbroverlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,st_equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,mbrdisjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,st_touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,mbrintersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,st_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;
CREATE TABLE t1 (
a INTEGER PRIMARY KEY AUTO_INCREMENT,
@@ -494,7 +494,7 @@ mbroverlaps
down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrtouches
-down2,left2,right2,up2
+big,center,down,down2,left,left2,right,right2,small,up,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
mbrwithin
big,center
@@ -515,7 +515,7 @@ overlaps
down,left,right,up
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
touches
-down2,left2,right2,up2
+big,center,down,down2,left,left2,right,right2,small,up,up2
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
within
big,center
diff --git a/mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result b/mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result
index bd8760b8f79..5d8c24ed11f 100644
--- a/mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result
+++ b/mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result
@@ -97,6 +97,9 @@ insert into t1 values (1,1), (2,null), (3,1), (4,1),
# Demonstrate that for the SELECT statement
# used later in the test JT_EQ_REF access method is used.
#
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='index_condition_pushdown=off';
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
explain
select 1 from t1 natural join (select 2 as a, 1 as b union all
select 2 as a, 2 as b) as t2 for update;
@@ -150,6 +153,7 @@ key_len NULL
ref NULL
rows NULL
Extra
+set optimizer_switch=@tmp_optimizer_switch;
#
# Demonstrate that the reported SELECT statement
# no longer produces warnings.
@@ -301,6 +305,9 @@ begin;
# is retreived and processed first.
#
# Verify that JT_EQ_REF is used.
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='index_condition_pushdown=off';
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
explain
select 1 from t1 natural join (select 3 as a, 2 as b union all
select 3 as a, 1 as b) as t2 for update;
@@ -354,6 +361,7 @@ key_len NULL
ref NULL
rows NULL
Extra
+set optimizer_switch=@tmp_optimizer_switch;
# Lock the record.
select 1 from t1 natural join (select 3 as a, 2 as b union all
select 3 as a, 1 as b) as t2 for update;
diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result
index 25633e3657f..6a2cb939557 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
@@ -316,7 +316,7 @@ INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (1);
DELETE IGNORE FROM t1 WHERE i = 1;
Warnings:
-Error 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`) ON DELETE NO ACTION)
+Warning 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`) ON DELETE NO ACTION)
SELECT * FROM t1, t2;
i i
1 1
@@ -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;
@@ -679,8 +679,6 @@ INSERT INTO t1(b,c) SELECT b,c FROM t2;
UPDATE t2 SET c='2007-01-03';
INSERT INTO t1(b,c) SELECT b,c FROM t2;
set @@sort_buffer_size=8192;
-Warnings:
-Warning 1292 Truncated incorrect sort_buffer_size value: '8192'
SELECT COUNT(*) FROM t1;
COUNT(*)
3072
@@ -1426,12 +1424,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='in_to_exists=on,materialization=off';
explain
-select b from t1 where a not in (select b from t1,t2 group by a) group by a;
+select b from t1 where a not in (select max(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` (
@@ -1738,8 +1739,8 @@ EXPLAIN
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
-2 DERIVED t1 ALL c3,c2 c3 5 const 5 Using where; Using filesort
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ref c3,c2 c3 5 const 2 Using where; Using filesort
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3))
ENGINE=InnoDB;
@@ -1752,8 +1753,8 @@ EXPLAIN
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
-2 DERIVED t1 ALL c3,c2 c3 9 const 5 Using where; Using filesort
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ref c3,c2 c3 9 const 2 Using where; Using filesort
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2),
KEY (c3), KEY (c2, c3))
@@ -1767,8 +1768,8 @@ EXPLAIN
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
-2 DERIVED t1 ALL c3,c2 c3 7 const 5 Using where; Using filesort
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ref c3,c2 c3 7 const 2 Using where; Using filesort
DROP TABLE t1;
End of 5.1 tests
drop table if exists t1, t2, t3;
@@ -2439,8 +2440,7 @@ SELECT COUNT(*) FROM
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
-2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 1536 Using sort_union(idx,PRIMARY); Using where
+1 SIMPLE t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 1536 Using sort_union(idx,PRIMARY); Using where
SELECT COUNT(*) FROM
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
diff --git a/mysql-test/suite/innodb_plugin/t/binlog_consistent.test b/mysql-test/suite/innodb_plugin/t/binlog_consistent.test
new file mode 100644
index 00000000000..1a2c84f3439
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/binlog_consistent.test
@@ -0,0 +1,88 @@
+--source include/have_log_bin.inc
+--source include/have_binlog_format_mixed_or_statement.inc
+--source include/have_innodb_plugin.inc
+
+RESET MASTER;
+
+# Test that we get the correct binlog position from START TRANSACTION WITH
+# CONSISTENT SNAPSHOT even when other transactions are active.
+
+connect(con1,localhost,root,,);
+connect(con2,localhost,root,,);
+connect(con3,localhost,root,,);
+connect(con4,localhost,root,,);
+
+connection default;
+--echo # Connection default
+
+CREATE TABLE t1 (a INT, b VARCHAR(100), PRIMARY KEY (a,b)) ENGINE=innodb;
+SHOW MASTER STATUS;
+SHOW STATUS LIKE 'binlog_snapshot_%';
+BEGIN;
+INSERT INTO t1 VALUES (0, "");
+
+connection con1;
+--echo # Connection con1
+BEGIN;
+INSERT INTO t1 VALUES (1, "");
+
+connection con2;
+--echo # Connection con2
+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=myisam;
+BEGIN;
+INSERT INTO t1 VALUES (2, "first");
+INSERT INTO t2 VALUES (2);
+INSERT INTO t1 VALUES (2, "second");
+
+connection default;
+--echo # Connection default
+COMMIT;
+
+SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+
+connection con3;
+--echo # Connection con3
+BEGIN;
+INSERT INTO t1 VALUES (3, "");
+INSERT INTO t2 VALUES (3);
+
+connection con4;
+--echo # Connection con4
+BEGIN;
+INSERT INTO t1 VALUES (4, "");
+COMMIT;
+
+connection default;
+--echo # Connection default
+SELECT * FROM t1 ORDER BY a,b;
+SHOW STATUS LIKE 'binlog_snapshot_%';
+SHOW MASTER STATUS;
+SELECT * FROM t2 ORDER BY a;
+
+connection con1;
+--echo # Connection con1
+COMMIT;
+
+connection con2;
+--echo # Connection con2
+COMMIT;
+
+connection con3;
+--echo # Connection con3
+COMMIT;
+FLUSH LOGS;
+
+connection default;
+--echo # Connection default
+SELECT * FROM t1 ORDER BY a,b;
+SHOW STATUS LIKE 'binlog_snapshot_%';
+SHOW MASTER STATUS;
+COMMIT;
+SHOW STATUS LIKE 'binlog_snapshot_%';
+SHOW MASTER STATUS;
+
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/
+SHOW BINLOG EVENTS;
+
+DROP TABLE t1,t2;
diff --git a/mysql-test/suite/innodb_plugin/t/group_commit.test b/mysql-test/suite/innodb_plugin/t/group_commit.test
new file mode 100644
index 00000000000..6a541f7b068
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/group_commit.test
@@ -0,0 +1,117 @@
+--source include/have_debug_sync.inc
+--source include/have_innodb_plugin.inc
+--source include/have_log_bin.inc
+
+# Test some group commit code paths by using debug_sync to do controlled
+# commits of 6 transactions: first 1 alone, then 3 as a group, then 2 as a
+# group.
+#
+# Group 3 is allowed to race as far as possible ahead before group 2 finishes
+# to check some edge case for concurrency control.
+
+CREATE TABLE t1 (a VARCHAR(10) PRIMARY KEY) ENGINE=innodb;
+
+SELECT variable_value INTO @commits FROM information_schema.global_status
+ WHERE variable_name = 'binlog_commits';
+SELECT variable_value INTO @group_commits FROM information_schema.global_status
+ WHERE variable_name = 'binlog_group_commits';
+
+connect(con1,localhost,root,,);
+connect(con2,localhost,root,,);
+connect(con3,localhost,root,,);
+connect(con4,localhost,root,,);
+connect(con5,localhost,root,,);
+connect(con6,localhost,root,,);
+
+# Start group1 (with one thread) doing commit, waiting for
+# group2 to queue up before finishing.
+
+connection con1;
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group1_running WAIT_FOR group2_queued";
+send INSERT INTO t1 VALUES ("con1");
+
+# Make group2 (with three threads) queue up.
+# Make sure con2 is the group commit leader for group2.
+# Make group2 wait with running commit_ordered() until group3 has committed.
+
+connection con2;
+set DEBUG_SYNC= "now WAIT_FOR group1_running";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con2";
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group2_running";
+SET DEBUG_SYNC= "commit_after_release_LOCK_log WAIT_FOR group3_committed";
+SET DEBUG_SYNC= "commit_after_group_run_commit_ordered SIGNAL group2_visible WAIT_FOR group2_checked";
+send INSERT INTO t1 VALUES ("con2");
+connection con3;
+SET DEBUG_SYNC= "now WAIT_FOR group2_con2";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con3";
+send INSERT INTO t1 VALUES ("con3");
+connection con4;
+SET DEBUG_SYNC= "now WAIT_FOR group2_con3";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con4";
+send INSERT INTO t1 VALUES ("con4");
+
+# When group2 is queued, let group1 continue and queue group3.
+
+connection default;
+SET DEBUG_SYNC= "now WAIT_FOR group2_con4";
+
+# At this point, trasaction 1 is still not visible as commit_ordered() has not
+# been called yet.
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+SELECT * FROM t1 ORDER BY a;
+
+SET DEBUG_SYNC= "now SIGNAL group2_queued";
+connection con1;
+reap;
+
+# Now transaction 1 is visible.
+connection default;
+SELECT * FROM t1 ORDER BY a;
+
+connection con5;
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group3_con5";
+SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con5_leader WAIT_FOR con6_queued";
+set DEBUG_SYNC= "now WAIT_FOR group2_running";
+send INSERT INTO t1 VALUES ("con5");
+
+connection con6;
+SET DEBUG_SYNC= "now WAIT_FOR con5_leader";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con6_queued";
+send INSERT INTO t1 VALUES ("con6");
+
+connection default;
+SET DEBUG_SYNC= "now WAIT_FOR group3_con5";
+# Still only transaction 1 visible, as group2 have not yet run commit_ordered().
+SELECT * FROM t1 ORDER BY a;
+SET DEBUG_SYNC= "now SIGNAL group3_committed";
+SET DEBUG_SYNC= "now WAIT_FOR group2_visible";
+# Now transactions 1-4 visible.
+SELECT * FROM t1 ORDER BY a;
+SET DEBUG_SYNC= "now SIGNAL group2_checked";
+
+connection con2;
+reap;
+
+connection con3;
+reap;
+
+connection con4;
+reap;
+
+connection con5;
+reap;
+
+connection con6;
+reap;
+
+connection default;
+# Check all transactions finally visible.
+SELECT * FROM t1 ORDER BY a;
+
+SELECT variable_value - @commits FROM information_schema.global_status
+ WHERE variable_name = 'binlog_commits';
+SELECT variable_value - @group_commits FROM information_schema.global_status
+ WHERE variable_name = 'binlog_group_commits';
+
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos-master.opt b/mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos-master.opt
new file mode 100644
index 00000000000..425fda95086
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos-master.opt
@@ -0,0 +1 @@
+--skip-stack-trace --skip-core-file
diff --git a/mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos.test b/mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos.test
new file mode 100644
index 00000000000..0e5c60f0e94
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos.test
@@ -0,0 +1,89 @@
+--source include/have_debug_sync.inc
+--source include/have_innodb_plugin.inc
+--source include/have_log_bin.inc
+--source include/have_binlog_format_mixed_or_statement.inc
+
+# Need DBUG to crash the server intentionally
+--source include/have_debug.inc
+# Don't test this under valgrind, memory leaks will occur as we crash
+--source include/not_valgrind.inc
+
+# The test case currently uses grep and tail, which may be unavailable on
+# some windows systems. But see MWL#191 for how to remove the need for grep.
+--source include/not_windows.inc
+
+# XtraDB stores the binlog position corresponding to the last commit, and
+# prints it during crash recovery.
+# Test that we get the correct position when we group commit several
+# transactions together.
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+INSERT INTO t1 VALUES (0);
+
+connect(con1,localhost,root,,);
+connect(con2,localhost,root,,);
+connect(con3,localhost,root,,);
+
+# Queue up three commits for group commit.
+
+connection con1;
+SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con1_waiting WAIT_FOR con3_queued";
+SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont EXECUTE 3";
+send INSERT INTO t1 VALUES (1);
+
+connection con2;
+SET DEBUG_SYNC= "now WAIT_FOR con1_waiting";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con2_queued";
+send INSERT INTO t1 VALUES (2);
+
+connection con3;
+SET DEBUG_SYNC= "now WAIT_FOR con2_queued";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con3_queued";
+send INSERT INTO t1 VALUES (3);
+
+connection default;
+SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
+# At this point, no transactions are committed.
+SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
+SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
+# At this point, 1 transaction is committed.
+SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
+SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
+
+# At this point, 2 transactions are committed.
+SELECT * FROM t1 ORDER BY a;
+
+connection con2;
+reap;
+
+# Now crash the server with 1+2 in-memory committed, 3 only prepared.
+connection default;
+system echo wait-group_commit_binlog_pos.test >> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
+SET SESSION debug="+d,crash_dispatch_command_before";
+--error 2006,2013
+SELECT 1;
+
+connection con1;
+--error 2006,2013
+reap;
+connection con3;
+--error 2006,2013
+reap;
+
+system echo restart-group_commit_binlog_pos.test >> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
+
+connection default;
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+# Crash recovery should recover all three transactions.
+SELECT * FROM t1 ORDER BY a;
+
+# Check that the binlog position reported by InnoDB is the correct one
+# for the end of the second transaction (as can be checked with
+# mysqlbinlog).
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+--exec grep 'InnoDB: Last MySQL binlog file position' $MYSQLD_DATADIR/../../log/mysqld.1.err | tail -1
+
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos_no_optimize_thread-master.opt b/mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos_no_optimize_thread-master.opt
new file mode 100644
index 00000000000..18d43988ffd
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos_no_optimize_thread-master.opt
@@ -0,0 +1 @@
+--binlog-optimize-thread-scheduling=0 --skip-stack-trace --skip-core-file
diff --git a/mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos_no_optimize_thread.test b/mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos_no_optimize_thread.test
new file mode 100644
index 00000000000..b044fa21ad3
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/group_commit_binlog_pos_no_optimize_thread.test
@@ -0,0 +1,90 @@
+--source include/have_debug_sync.inc
+--source include/have_innodb_plugin.inc
+--source include/have_log_bin.inc
+--source include/have_binlog_format_mixed_or_statement.inc
+
+# Need DBUG to crash the server intentionally
+--source include/have_debug.inc
+# Don't test this under valgrind, memory leaks will occur as we crash
+--source include/not_valgrind.inc
+
+# The test case currently uses grep and tail, which may be unavailable on
+# some windows systems. But see MWL#191 for how to remove the need for grep.
+--source include/not_windows.inc
+
+# XtraDB stores the binlog position corresponding to the last commit, and
+# prints it during crash recovery.
+# Test that we get the correct position when we group commit several
+# transactions together.
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+INSERT INTO t1 VALUES (0);
+
+connect(con1,localhost,root,,);
+connect(con2,localhost,root,,);
+connect(con3,localhost,root,,);
+
+# Queue up three commits for group commit.
+
+connection con1;
+SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con1_waiting WAIT_FOR con3_queued";
+SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont";
+send INSERT INTO t1 VALUES (1);
+
+connection con2;
+SET DEBUG_SYNC= "now WAIT_FOR con1_waiting";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con2_queued";
+SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont";
+send INSERT INTO t1 VALUES (2);
+
+connection con3;
+SET DEBUG_SYNC= "now WAIT_FOR con2_queued";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con3_queued";
+SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont";
+send INSERT INTO t1 VALUES (3);
+
+connection default;
+SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
+# At this point, no transactions are committed.
+SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
+SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
+# At this point, 1 transaction is committed.
+SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
+SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
+
+# At this point, 2 transactions are committed.
+SELECT * FROM t1 ORDER BY a;
+
+connection con1;
+reap;
+connection con2;
+reap;
+
+# Now crash the server with 1+2 in-memory committed, 3 only prepared.
+connection default;
+system echo wait-group_commit_binlog_pos_no_optimize_thread.test >> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
+SET SESSION debug="+d,crash_dispatch_command_before";
+--error 2006,2013
+SELECT 1;
+
+connection con3;
+--error 2006,2013
+reap;
+
+system echo restart-group_commit_binlog_pos_no_optimize_thread.test >> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
+
+connection default;
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+# Crash recovery should recover all three transactions.
+SELECT * FROM t1 ORDER BY a;
+
+# Check that the binlog position reported by InnoDB is the correct one
+# for the end of the second transaction (as can be checked with
+# mysqlbinlog).
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+--exec grep 'InnoDB: Last MySQL binlog file position' $MYSQLD_DATADIR/../../log/mysqld.1.err | tail -1
+
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_plugin/t/group_commit_crash-master.opt b/mysql-test/suite/innodb_plugin/t/group_commit_crash-master.opt
new file mode 100644
index 00000000000..425fda95086
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/group_commit_crash-master.opt
@@ -0,0 +1 @@
+--skip-stack-trace --skip-core-file
diff --git a/mysql-test/suite/innodb_plugin/t/group_commit_crash.test b/mysql-test/suite/innodb_plugin/t/group_commit_crash.test
new file mode 100644
index 00000000000..654ca313aab
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/group_commit_crash.test
@@ -0,0 +1,82 @@
+# Testing group commit by crashing a few times.
+# Test adapted from the Facebook patch: lp:mysqlatfacebook
+--source include/not_embedded.inc
+# Don't test this under valgrind, memory leaks will occur
+--source include/not_valgrind.inc
+
+# Binary must be compiled with debug for crash to occur
+--source include/have_debug.inc
+--source include/have_innodb_plugin.inc
+--source include/have_log_bin.inc
+
+let $file_format_check=`SELECT @@innodb_file_format_check`;
+CREATE TABLE t1(a CHAR(255),
+ b CHAR(255),
+ c CHAR(255),
+ d CHAR(255),
+ id INT AUTO_INCREMENT,
+ PRIMARY KEY(id)) ENGINE=InnoDB;
+create table t2 like t1;
+delimiter //;
+create procedure setcrash(IN i INT)
+begin
+ CASE i
+ WHEN 1 THEN SET SESSION debug="d,crash_commit_after_prepare";
+ WHEN 2 THEN SET SESSION debug="d,crash_commit_after_log";
+ WHEN 3 THEN SET SESSION debug="d,crash_commit_before_unlog";
+ WHEN 4 THEN SET SESSION debug="d,crash_commit_after";
+ WHEN 5 THEN SET SESSION debug="d,crash_commit_before";
+ ELSE BEGIN END;
+ END CASE;
+end //
+delimiter ;//
+# Avoid getting a crashed mysql.proc table.
+FLUSH TABLES;
+
+let $numtests = 5;
+
+let $numinserts = 10;
+while ($numinserts)
+{
+ dec $numinserts;
+ INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+}
+
+--enable_reconnect
+
+while ($numtests)
+{
+ SET binlog_format= mixed;
+ RESET MASTER;
+
+ START TRANSACTION;
+ insert into t1 select * from t2;
+ # Write file to make mysql-test-run.pl expect crash
+ --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+ eval call setcrash($numtests);
+
+ # Run the crashing query
+ --error 2006,2013
+ COMMIT;
+
+ # Poll the server waiting for it to be back online again.
+ --source include/wait_until_connected_again.inc
+
+ # table and binlog should be in sync.
+ SELECT * FROM t1 ORDER BY id;
+--replace_column 2 # 5 #
+ SHOW BINLOG EVENTS LIMIT 2,1;
+
+ delete from t1;
+
+ dec $numtests;
+}
+
+# final cleanup
+DROP TABLE t1;
+DROP TABLE t2;
+DROP PROCEDURE setcrash;
+--disable_query_log
+eval SET GLOBAL innodb_file_format_check=$file_format_check;
+--enable_query_log
diff --git a/mysql-test/suite/innodb_plugin/t/group_commit_crash_no_optimize_thread-master.opt b/mysql-test/suite/innodb_plugin/t/group_commit_crash_no_optimize_thread-master.opt
new file mode 100644
index 00000000000..18d43988ffd
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/group_commit_crash_no_optimize_thread-master.opt
@@ -0,0 +1 @@
+--binlog-optimize-thread-scheduling=0 --skip-stack-trace --skip-core-file
diff --git a/mysql-test/suite/innodb_plugin/t/group_commit_crash_no_optimize_thread.test b/mysql-test/suite/innodb_plugin/t/group_commit_crash_no_optimize_thread.test
new file mode 100644
index 00000000000..654ca313aab
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/group_commit_crash_no_optimize_thread.test
@@ -0,0 +1,82 @@
+# Testing group commit by crashing a few times.
+# Test adapted from the Facebook patch: lp:mysqlatfacebook
+--source include/not_embedded.inc
+# Don't test this under valgrind, memory leaks will occur
+--source include/not_valgrind.inc
+
+# Binary must be compiled with debug for crash to occur
+--source include/have_debug.inc
+--source include/have_innodb_plugin.inc
+--source include/have_log_bin.inc
+
+let $file_format_check=`SELECT @@innodb_file_format_check`;
+CREATE TABLE t1(a CHAR(255),
+ b CHAR(255),
+ c CHAR(255),
+ d CHAR(255),
+ id INT AUTO_INCREMENT,
+ PRIMARY KEY(id)) ENGINE=InnoDB;
+create table t2 like t1;
+delimiter //;
+create procedure setcrash(IN i INT)
+begin
+ CASE i
+ WHEN 1 THEN SET SESSION debug="d,crash_commit_after_prepare";
+ WHEN 2 THEN SET SESSION debug="d,crash_commit_after_log";
+ WHEN 3 THEN SET SESSION debug="d,crash_commit_before_unlog";
+ WHEN 4 THEN SET SESSION debug="d,crash_commit_after";
+ WHEN 5 THEN SET SESSION debug="d,crash_commit_before";
+ ELSE BEGIN END;
+ END CASE;
+end //
+delimiter ;//
+# Avoid getting a crashed mysql.proc table.
+FLUSH TABLES;
+
+let $numtests = 5;
+
+let $numinserts = 10;
+while ($numinserts)
+{
+ dec $numinserts;
+ INSERT INTO t2(a, b, c, d) VALUES ('a', 'b', 'c', 'd');
+}
+
+--enable_reconnect
+
+while ($numtests)
+{
+ SET binlog_format= mixed;
+ RESET MASTER;
+
+ START TRANSACTION;
+ insert into t1 select * from t2;
+ # Write file to make mysql-test-run.pl expect crash
+ --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+ eval call setcrash($numtests);
+
+ # Run the crashing query
+ --error 2006,2013
+ COMMIT;
+
+ # Poll the server waiting for it to be back online again.
+ --source include/wait_until_connected_again.inc
+
+ # table and binlog should be in sync.
+ SELECT * FROM t1 ORDER BY id;
+--replace_column 2 # 5 #
+ SHOW BINLOG EVENTS LIMIT 2,1;
+
+ delete from t1;
+
+ dec $numtests;
+}
+
+# final cleanup
+DROP TABLE t1;
+DROP TABLE t2;
+DROP PROCEDURE setcrash;
+--disable_query_log
+eval SET GLOBAL innodb_file_format_check=$file_format_check;
+--enable_query_log
diff --git a/mysql-test/suite/innodb_plugin/t/group_commit_no_optimize_thread-master.opt b/mysql-test/suite/innodb_plugin/t/group_commit_no_optimize_thread-master.opt
new file mode 100644
index 00000000000..97d8c106816
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/group_commit_no_optimize_thread-master.opt
@@ -0,0 +1 @@
+--binlog-optimize-thread-scheduling=0
diff --git a/mysql-test/suite/innodb_plugin/t/group_commit_no_optimize_thread.test b/mysql-test/suite/innodb_plugin/t/group_commit_no_optimize_thread.test
new file mode 100644
index 00000000000..a216cbd2965
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/group_commit_no_optimize_thread.test
@@ -0,0 +1,117 @@
+--source include/have_debug_sync.inc
+--source include/have_innodb_plugin.inc
+--source include/have_log_bin.inc
+
+# Test some group commit code paths by using debug_sync to do controlled
+# commits of 6 transactions: first 1 alone, then 3 as a group, then 2 as a
+# group.
+#
+# Group 3 is allowed to race as far as possible ahead before group 2 finishes
+# to check some edge case for concurrency control.
+
+CREATE TABLE t1 (a VARCHAR(10) PRIMARY KEY) ENGINE=innodb;
+
+SELECT variable_value INTO @commits FROM information_schema.global_status
+ WHERE variable_name = 'binlog_commits';
+SELECT variable_value INTO @group_commits FROM information_schema.global_status
+ WHERE variable_name = 'binlog_group_commits';
+
+connect(con1,localhost,root,,);
+connect(con2,localhost,root,,);
+connect(con3,localhost,root,,);
+connect(con4,localhost,root,,);
+connect(con5,localhost,root,,);
+connect(con6,localhost,root,,);
+
+# Start group1 (with one thread) doing commit, waiting for
+# group2 to queue up before finishing.
+
+connection con1;
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group1_running WAIT_FOR group2_queued";
+send INSERT INTO t1 VALUES ("con1");
+
+# Make group2 (with three threads) queue up.
+# Make sure con2 is the group commit leader for group2.
+# Make group2 wait with running commit_ordered() until group3 has committed.
+
+connection con2;
+set DEBUG_SYNC= "now WAIT_FOR group1_running";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con2";
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group2_running";
+SET DEBUG_SYNC= "commit_after_release_LOCK_log WAIT_FOR group3_committed";
+send INSERT INTO t1 VALUES ("con2");
+connection con3;
+SET DEBUG_SYNC= "now WAIT_FOR group2_con2";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con3";
+send INSERT INTO t1 VALUES ("con3");
+connection con4;
+SET DEBUG_SYNC= "now WAIT_FOR group2_con3";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL group2_con4";
+SET DEBUG_SYNC= "commit_after_group_run_commit_ordered SIGNAL group2_visible WAIT_FOR group2_checked";
+send INSERT INTO t1 VALUES ("con4");
+
+# When group2 is queued, let group1 continue and queue group3.
+
+connection default;
+SET DEBUG_SYNC= "now WAIT_FOR group2_con4";
+
+# At this point, trasaction 1 is still not visible as commit_ordered() has not
+# been called yet.
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+SELECT * FROM t1 ORDER BY a;
+
+SET DEBUG_SYNC= "now SIGNAL group2_queued";
+connection con1;
+reap;
+
+# Now transaction 1 is visible.
+connection default;
+SELECT * FROM t1 ORDER BY a;
+
+connection con5;
+SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL group3_con5";
+SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con5_leader WAIT_FOR con6_queued";
+set DEBUG_SYNC= "now WAIT_FOR group2_running";
+send INSERT INTO t1 VALUES ("con5");
+
+connection con6;
+SET DEBUG_SYNC= "now WAIT_FOR con5_leader";
+SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con6_queued";
+send INSERT INTO t1 VALUES ("con6");
+
+connection default;
+SET DEBUG_SYNC= "now WAIT_FOR group3_con5";
+# Still only transaction 1 visible, as group2 have not yet run commit_ordered().
+SELECT * FROM t1 ORDER BY a;
+SET DEBUG_SYNC= "now SIGNAL group3_committed";
+SET DEBUG_SYNC= "now WAIT_FOR group2_visible";
+# Now transactions 1-4 visible.
+SELECT * FROM t1 ORDER BY a;
+SET DEBUG_SYNC= "now SIGNAL group2_checked";
+
+connection con2;
+reap;
+
+connection con3;
+reap;
+
+connection con4;
+reap;
+
+connection con5;
+reap;
+
+connection con6;
+reap;
+
+connection default;
+# Check all transactions finally visible.
+SELECT * FROM t1 ORDER BY a;
+
+SELECT variable_value - @commits FROM information_schema.global_status
+ WHERE variable_name = 'binlog_commits';
+SELECT variable_value - @group_commits FROM information_schema.global_status
+ WHERE variable_name = 'binlog_group_commits';
+
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_plugin/t/innodb.test b/mysql-test/suite/innodb_plugin/t/innodb.test
index c0b479fee2e..8916bdee5a8 100644
--- a/mysql-test/suite/innodb_plugin/t/innodb.test
+++ b/mysql-test/suite/innodb_plugin/t/innodb.test
@@ -19,6 +19,8 @@ let $MYSQLD_DATADIR= `select @@datadir`;
let collation=utf8_unicode_ci;
--source include/have_collation.inc
+set optimizer_switch='index_condition_pushdown=off,mrr=off';
+
# 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
@@ -2570,6 +2572,7 @@ SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig;
-- enable_query_log
+set optimizer_switch=default;
# Clean up after the Bug#55284/Bug#58912 test case.
DROP TABLE bug58912;
diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test b/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test
index 58f60a54130..10a18dff5ce 100644
--- a/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test
+++ b/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test
@@ -1,11 +1,4 @@
-# This is the test for bug #54044. Special handle MYSQL_TYPE_NULL type
-# during create table, so it will not trigger assertion failure.
-
--source include/have_innodb_plugin.inc
-# This 'create table' operation should fail because of
-# using NULL datatype
---error ER_CANT_CREATE_TABLE
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
-
diff --git a/mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1.test b/mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1.test
index d7272779bdd..f8aef2af86d 100644
--- a/mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1.test
+++ b/mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1.test
@@ -140,9 +140,13 @@ insert into t1 values (1,1), (2,null), (3,1), (4,1),
--echo # used later in the test JT_EQ_REF access method is used.
--echo #
--vertical_results
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='index_condition_pushdown=off';
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
explain
select 1 from t1 natural join (select 2 as a, 1 as b union all
select 2 as a, 2 as b) as t2 for update;
+set optimizer_switch=@tmp_optimizer_switch;
--horizontal_results
--echo #
--echo # Demonstrate that the reported SELECT statement
@@ -236,9 +240,13 @@ begin;
--echo #
--echo # Verify that JT_EQ_REF is used.
--vertical_results
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='index_condition_pushdown=off';
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
explain
select 1 from t1 natural join (select 3 as a, 2 as b union all
select 3 as a, 1 as b) as t2 for update;
+set optimizer_switch=@tmp_optimizer_switch;
--horizontal_results
--echo # Lock the record.
select 1 from t1 natural join (select 3 as a, 2 as b union all
diff --git a/mysql-test/suite/maria/r/compat_aliases.result b/mysql-test/suite/maria/r/compat_aliases.result
deleted file mode 100644
index f0cd5f1d719..00000000000
--- a/mysql-test/suite/maria/r/compat_aliases.result
+++ /dev/null
@@ -1,59 +0,0 @@
-select * from information_schema.plugins where plugin_name like '%aria';
-PLUGIN_NAME PLUGIN_VERSION PLUGIN_STATUS PLUGIN_TYPE PLUGIN_TYPE_VERSION PLUGIN_LIBRARY PLUGIN_LIBRARY_VERSION PLUGIN_AUTHOR PLUGIN_DESCRIPTION PLUGIN_LICENSE PLUGIN_MATURITY PLUGIN_AUTH_VERSION
-Maria 1.5 ACTIVE DAEMON # NULL NULL Monty Program Ab Compatibility aliases for the Aria engine GPL Gamma 1.5
-Aria 1.5 ACTIVE STORAGE ENGINE # NULL NULL Monty Program Ab Crash-safe tables with MyISAM heritage GPL Gamma 1.5
-select maria_vars.variable_name, aria_vars.variable_name from
-information_schema.session_variables as maria_vars left join
-information_schema.session_variables as aria_vars
-on (maria_vars.variable_name = concat('m', aria_vars.variable_name))
-where maria_vars.variable_name like 'maria_%'
- and not (maria_vars.variable_value <=> aria_vars.variable_value);
-variable_name variable_name
-select maria_vars.variable_name, aria_vars.variable_name from
-information_schema.session_status as maria_vars left join
-information_schema.session_status as aria_vars
-on (maria_vars.variable_name = concat('m', aria_vars.variable_name))
-where maria_vars.variable_name like 'maria_%'
- and not (maria_vars.variable_value <=> aria_vars.variable_value);
-variable_name variable_name
-select maria_vars.variable_name, aria_vars.variable_name from
-information_schema.session_variables as aria_vars left join
-information_schema.session_variables as maria_vars
-on (maria_vars.variable_name = concat('m', aria_vars.variable_name))
-where aria_vars.variable_name like 'aria_%'
- and not (maria_vars.variable_value <=> aria_vars.variable_value);
-variable_name variable_name
-NULL ARIA_CHECKPOINT_LOG_ACTIVITY
-select maria_vars.variable_name, aria_vars.variable_name from
-information_schema.session_status as aria_vars left join
-information_schema.session_status as maria_vars
-on (maria_vars.variable_name = concat('m', aria_vars.variable_name))
-where aria_vars.variable_name like 'aria_%'
- and not (maria_vars.variable_value <=> aria_vars.variable_value);
-variable_name variable_name
-set @old_checkpoint_interval=@@global.aria_checkpoint_interval;
-set global maria_checkpoint_interval=10;
-select @@global.aria_checkpoint_interval;
-@@global.aria_checkpoint_interval
-10
-set global maria_checkpoint_interval=@old_checkpoint_interval;
-set @old_sort_buffer_size=@@global.maria_sort_buffer_size;
-set global aria_sort_buffer_size=1024;
-select @@global.maria_sort_buffer_size;
-@@global.maria_sort_buffer_size
-1024
-set global aria_sort_buffer_size=@old_sort_buffer_size;
-set @old_sort_buffer_size=@@session.maria_sort_buffer_size;
-set session aria_sort_buffer_size=2048;
-select @@session.maria_sort_buffer_size;
-@@session.maria_sort_buffer_size
-2048
-set session aria_sort_buffer_size=@old_sort_buffer_size;
-set @old_max_sort_file_size=@@global.maria_max_sort_file_size,
-@old_repair_threads=@@global.aria_repair_threads;
-set @@global.maria_max_sort_file_size=default, @@global.aria_repair_threads=default;
-select @@global.maria_max_sort_file_size, @@global.aria_repair_threads;
-@@global.maria_max_sort_file_size @@global.aria_repair_threads
-9223372036853727232 1
-set @@global.aria_max_sort_file_size=@old_max_sort_file_size,
-@@global.maria_repair_threads=@old_repair_threads;
diff --git a/mysql-test/suite/maria/r/maria-autozerofill.result b/mysql-test/suite/maria/r/maria-autozerofill.result
index 0ce199feeca..22856fe54b0 100644
--- a/mysql-test/suite/maria/r/maria-autozerofill.result
+++ b/mysql-test/suite/maria/r/maria-autozerofill.result
@@ -10,7 +10,7 @@ create table t3 (a int) engine=aria;
INSERT INTO t3 VALUES (1),(2);
create table t4 (a int) engine=aria;
INSERT INTO t4 VALUES (1),(2);
-create table t5 (a int) engine=maria;
+create table t5 (a int) engine=aria;
INSERT INTO t5 VALUES (1),(2);
flush tables;
create_rename_lsn has non-magic value
diff --git a/mysql-test/suite/maria/r/maria-connect.result b/mysql-test/suite/maria/r/maria-connect.result
index a02c29f3d5f..45675deb098 100644
--- a/mysql-test/suite/maria/r/maria-connect.result
+++ b/mysql-test/suite/maria/r/maria-connect.result
@@ -14,10 +14,10 @@ a
2
3
4
-SHOW BINLOG EVENTS FROM 106;
+SHOW BINLOG EVENTS FROM <start_pos>;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 106 Query 1 204 use `test`; CREATE TABLE t1 (a int primary key)
-master-bin.000001 204 Query 1 295 use `test`; insert t1 values (1),(2),(3)
-master-bin.000001 295 Query 1 386 use `test`; insert t1 values (4),(2),(5)
+master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1 (a int primary key)
+master-bin.000001 # Query 1 # use `test`; insert t1 values (1),(2),(3)
+master-bin.000001 # Query 1 # use `test`; insert t1 values (4),(2),(5)
drop table t1;
set binlog_format=default;
diff --git a/mysql-test/suite/maria/r/maria-gis-recovery.result b/mysql-test/suite/maria/r/maria-gis-recovery.result
new file mode 100644
index 00000000000..ca406fc46e5
--- /dev/null
+++ b/mysql-test/suite/maria/r/maria-gis-recovery.result
@@ -0,0 +1,64 @@
+set global aria_log_file_size=4294967295;
+drop database if exists mysqltest;
+create database mysqltest;
+use mysqltest;
+* shut down mysqld, removed logs, restarted it
+CREATE TABLE t1 (
+i int,
+shape GEOMETRY NOT NULL,
+SPATIAL (shape)
+) ENGINE=ARIA;
+insert into t1 values(1,POINT(1, 1));
+* copied t1 for feeding_recovery
+insert into t1 values(2,POINT(2, 2)), (3,POINT(3, 3)), (4,POINT(4, 4));
+flush table t1;
+* copied t1 for comparison
+SET SESSION debug="+d,maria_flush_whole_log,maria_crash";
+* crashing mysqld intentionally
+set global aria_checkpoint_interval=1;
+ERROR HY000: Lost connection to MySQL server during query
+* copied t1 back for feeding_recovery
+* recovery happens
+check table t1 extended;
+Table Op Msg_type Msg_text
+mysqltest.t1 check status OK
+* testing that checksum after recovery is as expected
+Checksum-check
+ok
+use mysqltest;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL,
+ `shape` geometry NOT NULL,
+ SPATIAL KEY `shape` (`shape`)
+) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1
+* TEST of UPDATE vs state.auto_increment
+* copied t1 for feeding_recovery
+update t1 set shape=POINT(5, 5) where i=2;
+flush table t1;
+* copied t1 for comparison
+SET SESSION debug="+d,maria_flush_whole_log,maria_crash";
+* crashing mysqld intentionally
+set global aria_checkpoint_interval=1;
+ERROR HY000: Lost connection to MySQL server during query
+* copied t1 back for feeding_recovery
+* recovery happens
+check table t1 extended;
+Table Op Msg_type Msg_text
+mysqltest.t1 check status OK
+* testing that checksum after recovery is as expected
+Checksum-check
+ok
+use mysqltest;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL,
+ `shape` geometry NOT NULL,
+ SPATIAL KEY `shape` (`shape`)
+) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1
+drop table t1;
+drop database mysqltest_for_feeding_recovery;
+drop database mysqltest_for_comparison;
+drop database mysqltest;
diff --git a/mysql-test/suite/maria/r/maria-gis-rtree-dynamic.result b/mysql-test/suite/maria/r/maria-gis-rtree-dynamic.result
index 743f1785f5c..f4593f2f10a 100644
--- a/mysql-test/suite/maria/r/maria-gis-rtree-dynamic.result
+++ b/mysql-test/suite/maria/r/maria-gis-rtree-dynamic.result
@@ -168,7 +168,7 @@ count(*)
150
EXPLAIN SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range g g 34 NULL 11 Using where
+1 SIMPLE t1 ALL g NULL NULL NULL 150 Using where
SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
fid AsText(g)
1 LINESTRING(150 150,150 150)
@@ -302,7 +302,7 @@ count(*)
EXPLAIN SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range g g 34 NULL 4 Using where
+1 SIMPLE t2 range g g 34 NULL 1 Using where
SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
fid AsText(g)
diff --git a/mysql-test/suite/maria/r/maria-gis-rtree-trans.result b/mysql-test/suite/maria/r/maria-gis-rtree-trans.result
index ae37b9d454d..c4e773c7e0a 100644
--- a/mysql-test/suite/maria/r/maria-gis-rtree-trans.result
+++ b/mysql-test/suite/maria/r/maria-gis-rtree-trans.result
@@ -168,7 +168,7 @@ count(*)
150
EXPLAIN SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range g g 34 NULL 11 Using where
+1 SIMPLE t1 ALL g NULL NULL NULL 150 Using where
SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
fid AsText(g)
1 LINESTRING(150 150,150 150)
@@ -302,7 +302,7 @@ count(*)
EXPLAIN SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range g g 34 NULL 4 Using where
+1 SIMPLE t2 range g g 34 NULL 1 Using where
SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
fid AsText(g)
diff --git a/mysql-test/suite/maria/r/maria-gis-rtree.result b/mysql-test/suite/maria/r/maria-gis-rtree.result
index a61e93d2a3a..430f240d83e 100644
--- a/mysql-test/suite/maria/r/maria-gis-rtree.result
+++ b/mysql-test/suite/maria/r/maria-gis-rtree.result
@@ -168,7 +168,7 @@ count(*)
150
EXPLAIN SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range g g 34 NULL 11 Using where
+1 SIMPLE t1 ALL g NULL NULL NULL 150 Using where
SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
fid AsText(g)
1 LINESTRING(150 150,150 150)
@@ -302,7 +302,7 @@ count(*)
EXPLAIN SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range g g 34 NULL 4 Using where
+1 SIMPLE t2 range g g 34 NULL 1 Using where
SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
fid AsText(g)
diff --git a/mysql-test/suite/maria/r/maria-recover.result b/mysql-test/suite/maria/r/maria-recover.result
index 128467a278c..9b84c47720a 100644
--- a/mysql-test/suite/maria/r/maria-recover.result
+++ b/mysql-test/suite/maria/r/maria-recover.result
@@ -20,7 +20,7 @@ create table t1 (a varchar(1000), index(a)) engine=aria;
insert into t1 values("ThursdayMorningsMarket");
flush table t1;
insert into t1 select concat(a,'b') from t1 limit 1;
-set global maria_checkpoint_interval=1000;
+set global aria_checkpoint_interval=1000;
select * from t_corrupted2;
a
ThursdayMorningsMarket
diff --git a/mysql-test/suite/maria/r/maria.result b/mysql-test/suite/maria/r/maria.result
index 74b1694d7d1..640b91b5cc0 100644
--- a/mysql-test/suite/maria/r/maria.result
+++ b/mysql-test/suite/maria/r/maria.result
@@ -22,6 +22,17 @@ CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;
+create table t1 (a int primary key auto_increment) engine=aria;
+insert into t1 values (1);
+update t1 set a=0 where a=1;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check warning Found row where the auto_increment column has the value 0
+test.t1 check status OK
+select * from t1;
+a
+0
+drop table t1;
create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a));
check table t1;
Table Op Msg_type Msg_text
@@ -350,7 +361,8 @@ ALTER TABLE t1 ADD INDEX t1 (a, b, c, d, e);
ERROR 42000: Specified key was too long; max key length is 1000 bytes
DROP TABLE t1;
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
-INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+INSERT into t1 values (0,null,0), (0,null,1), (0,null,2), (0,null,3), (1,1,4);
+INSERT into t1 values (2,4,5), (7,8,4), (8,3,1), (9,7,2), (5,5,9);
create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
INSERT into t2 values (1,1,1), (2,2,2);
optimize table t1;
@@ -361,44 +373,44 @@ Table Op Msg_type Msg_text
test.t1 check status OK
show index from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
-t1 1 b 1 b A 5 NULL NULL YES BTREE
-t1 1 c 1 c A 5 NULL NULL YES BTREE
-t1 1 a 1 a A 1 NULL NULL BTREE
-t1 1 a 2 b A 5 NULL NULL YES BTREE
-t1 1 c_2 1 c A 5 NULL NULL YES BTREE
-t1 1 c_2 2 a A 5 NULL NULL BTREE
+t1 1 b 1 b A 10 NULL NULL YES BTREE
+t1 1 c 1 c A 10 NULL NULL YES BTREE
+t1 1 a 1 a A 10 NULL NULL BTREE
+t1 1 a 2 b A 10 NULL NULL YES BTREE
+t1 1 c_2 1 c A 10 NULL NULL YES BTREE
+t1 1 c_2 2 a A 10 NULL NULL BTREE
explain select * from t1,t2 where t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL a NULL NULL NULL 2
-1 SIMPLE t1 ref a a 4 test.t2.a 3
+1 SIMPLE t1 ref a a 4 test.t2.a 1
explain select * from t1,t2 force index(a) where t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL a NULL NULL NULL 2
-1 SIMPLE t1 ref a a 4 test.t2.a 3
+1 SIMPLE t1 ref a a 4 test.t2.a 1
explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL a NULL NULL NULL 2
-1 SIMPLE t1 ref a a 4 test.t2.a 3
+1 SIMPLE t1 ref a a 4 test.t2.a 1
explain select * from t1,t2 where t1.b=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL b NULL NULL NULL 2
-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
+1 SIMPLE t1 ref a a 4 test.t2.a 1
explain select * from t1 where a=0 or a=2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 4 NULL 4 Using where
+1 SIMPLE t1 range a a 4 NULL 5 Using index condition; Using where
explain select * from t1 force index (a) where a=0 or a=2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 4 NULL 4 Using where
+1 SIMPLE t1 range a a 4 NULL 5 Using index condition; Using where
explain select * from t1 where c=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref c,c_2 c 5 const 1 Using where
+1 SIMPLE t1 ref c,c_2 c 5 const 2
explain select * from t1 use index() where c=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where
drop table t1,t2;
create table t1 (a int not null auto_increment primary key, b varchar(255));
insert into t1 (b) values (repeat('a',100)),(repeat('b',100)),(repeat('c',100));
@@ -1131,7 +1143,7 @@ qq
*a *a*a *
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v,v_2 # 13 const # Using 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 +1319,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v v 303 const # Using 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/maria/r/maria3.result b/mysql-test/suite/maria/r/maria3.result
index 1a8ada478f6..8018ca03a8e 100644
--- a/mysql-test/suite/maria/r/maria3.result
+++ b/mysql-test/suite/maria/r/maria3.result
@@ -313,7 +313,7 @@ aria_log_file_size 4294959104
aria_log_purge_type immediate
aria_max_sort_file_size 9223372036853727232
aria_pagecache_age_threshold 300
-aria_pagecache_buffer_size 134213632
+aria_pagecache_buffer_size 134217720
aria_pagecache_division_limit 100
aria_page_checksum OFF
aria_recover NORMAL
diff --git a/mysql-test/suite/maria/r/ps_maria.result b/mysql-test/suite/maria/r/ps_maria.result
index 04c14f9c1e4..8ac0fee6f50 100644
--- a/mysql-test/suite/maria/r/ps_maria.result
+++ b/mysql-test/suite/maria/r/ps_maria.result
@@ -63,8 +63,8 @@ def test t9 t9 c11 c11 246 9 6 Y 0 4 63
def test t9 t9 c12 c12 246 10 6 Y 0 4 63
def test t9 t9 c13 c13 10 10 10 Y 128 0 63
def test t9 t9 c14 c14 12 19 19 Y 128 0 63
-def test t9 t9 c15 c15 7 19 19 N 9441 0 63
-def test t9 t9 c16 c16 11 8 8 Y 128 0 63
+def test t9 t9 c15 c15 7 19 19 N 9377 0 63
+def test t9 t9 c16 c16 11 10 8 Y 128 0 63
def test t9 t9 c17 c17 13 4 4 Y 32864 0 63
def test t9 t9 c18 c18 1 4 1 Y 32768 0 63
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
@@ -1793,8 +1793,8 @@ t5 CREATE TABLE `t5` (
`param08` longtext,
`const09` datetime DEFAULT NULL,
`param09` longblob,
- `const10` int(10) NOT NULL DEFAULT '0',
- `param10` bigint(20) DEFAULT NULL,
+ `const10` decimal(22,6) NOT NULL DEFAULT '0.000000',
+ `param10` decimal(65,30) DEFAULT NULL,
`const11` int(4) DEFAULT NULL,
`param11` bigint(20) DEFAULT NULL,
`const12` binary(0) DEFAULT NULL,
@@ -1823,8 +1823,8 @@ def test t5 t5 const08 const08 253 19 19 N 1 0 8
def test t5 t5 param08 param08 252 4294967295 19 Y 16 0 8
def test t5 t5 const09 const09 12 19 19 Y 128 0 63
def test t5 t5 param09 param09 252 4294967295 19 Y 144 0 63
-def test t5 t5 const10 const10 3 10 9 N 32769 0 63
-def test t5 t5 param10 param10 8 20 9 Y 32768 0 63
+def test t5 t5 const10 const10 246 24 16 N 1 6 63
+def test t5 t5 param10 param10 246 67 40 Y 0 30 63
def test t5 t5 const11 const11 3 4 4 Y 32768 0 63
def test t5 t5 param11 param11 8 20 4 Y 32768 0 63
def test t5 t5 const12 const12 254 0 0 Y 128 0 63
@@ -1850,8 +1850,8 @@ const08 1991-08-05 01:01:01
param08 1991-08-05 01:01:01
const09 1991-08-05 01:01:01
param09 1991-08-05 01:01:01
-const10 662680861
-param10 662680861
+const10 662680861.000000
+param10 662680861.000000000000000000000000000000
const11 1991
param11 1991
const12 NULL
@@ -2762,46 +2762,212 @@ c12 -9999.9999
execute my_delete ;
test_sequence
-- insert into string columns --
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 20, '20', '20', '20', '20', '20', '20', '20', '20', '20', '20', '20' ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '21' ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 21, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 22, '22', '22', '22', '22', '22', '22', '22', '22', '22', '22', '22' )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '23';
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 23, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 30, CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary), CAST('30' as binary),
+CAST('30' as binary), CAST('30' as binary) ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= '31' ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 31, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 32, CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary), CAST('32' as binary),
+ CAST('32' as binary), CAST('32' as binary) )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= CAST('33' as binary);
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 33, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 41 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 41, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 43;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 43, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 50, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 51.0 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 51, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 52, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0, 52.0 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 53.0;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 53, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 54, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1, 5.4e+1,
+5.4e+1, 5.4e+1, 5.4e+1 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 5.5e+1 ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 55, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 56, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1, 5.6e+1,
+ 5.6e+1, 5.6e+1, 5.6e+1 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 5.7e+1;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 57, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c20' at row 1
+set @arg00= 'abc' ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 60, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 61, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt1 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 62, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL )" ;
+execute stmt1 ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 63, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 2 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 71, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 73, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+( 81, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00 ) ;
+prepare stmt2 from "insert into t9
+ ( c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 )
+values
+ ( 83, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00, @arg00, @arg00,
+@arg00, @arg00, @arg00, @arg00 ;
select c1, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30
from t9 where c1 >= 20
order by c1 ;
@@ -2960,70 +3126,208 @@ true
delete from t9 ;
test_sequence
-- insert into date/time columns --
+set @arg00= '1991-01-01 01:01:01' ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 20, '1991-01-01 01:01:01', '1991-01-01 01:01:01', '1991-01-01 01:01:01',
+'1991-01-01 01:01:01', '1991-01-01 01:01:01') ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 21, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 22, '1991-01-01 01:01:01', '1991-01-01 01:01:01', '1991-01-01 01:01:01',
+ '1991-01-01 01:01:01', '1991-01-01 01:01:01')" ;
+execute stmt1 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 23, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+set @arg00= CAST('1991-01-01 01:01:01' as datetime) ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 30, CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime),
+CAST('1991-01-01 01:01:01' as datetime)) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 31, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 32, CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime),
+ CAST('1991-01-01 01:01:01' as datetime))" ;
+execute stmt1 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 33, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Note 1265 Data truncated for column 'c13' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
+set @arg00= 2000000000 ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 40, 2000000000, 2000000000, 2000000000, 2000000000, 2000000000 ) ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 41, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 42, 2000000000, 2000000000, 2000000000, 2000000000, 2000000000 )" ;
+execute stmt1 ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 43, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
-Warning 1264 Out of range value for column 'c13' at row 1
-Warning 1264 Out of range value for column 'c14' at row 1
+Warning 1265 Data truncated for column 'c13' at row 1
+Warning 1265 Data truncated for column 'c14' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+set @arg00= 1.0e+10 ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 50, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 ) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 51, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 52, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 )" ;
+execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 53, ?, ?, ?, ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1264 Out of range value for column 'c16' at row 1
+Warning 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
+set @arg00= 'abc' ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 60, NULL, NULL, '1991-01-01 01:01:01',
+NULL, NULL) ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 61, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt1 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 62, NULL, NULL, '1991-01-01 01:01:01',
+ NULL, NULL)" ;
+execute stmt1 ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 63, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 71, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 73, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
+set @arg00= 8.0 ;
+set @arg00= NULL ;
+insert into t9
+( c1, c13, c14, c15, c16, c17 )
+values
+( 81, @arg00, @arg00, '1991-01-01 01:01:01', @arg00, @arg00) ;
+prepare stmt2 from "insert into t9
+ ( c1, c13, c14, c15, c16, c17 )
+values
+ ( 83, ?, ?, '1991-01-01 01:01:01', ?, ? )" ;
+execute stmt2 using @arg00, @arg00, @arg00, @arg00 ;
select c1, c13, c14, c15, c16, c17 from t9 order by c1 ;
c1 c13 c14 c15 c16 c17
20 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
@@ -3034,14 +3338,14 @@ c1 c13 c14 c15 c16 c17
31 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
32 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
33 1991-01-01 1991-01-01 01:01:01 1991-01-01 01:01:01 01:01:01 1991
-40 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-41 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
+40 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+41 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+42 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+43 0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+50 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
51 2010-00-00 2010-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
-53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 838:59:59 0000
+52 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
+53 2001-00-00 2001-00-00 00:00:00 0000-00-00 00:00:00 00:00:00 0000
60 NULL NULL 1991-01-01 01:01:01 NULL NULL
61 NULL NULL 1991-01-01 01:01:01 NULL NULL
62 NULL NULL 1991-01-01 01:01:01 NULL NULL
@@ -3055,25 +3359,25 @@ test_sequence
set @arg00= '1991-01-01 01:01:01' ;
select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
-c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01' ;
found
true
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
found
true
prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
- c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
+ c15= '1991-01-01 01:01:01' and
c17= '1991-01-01 01:01:01'" ;
execute stmt1 ;
found
true
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
found
true
set @arg00= CAST('1991-01-01 01:01:01' as datetime) ;
@@ -3081,12 +3385,11 @@ select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
-c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime) ;
found
true
select 'true' as found from t9
-where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
+where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00
and c17= @arg00 ;
found
true
@@ -3094,14 +3397,43 @@ prepare stmt1 from "select 'true' as found from t9
where c1= 20 and c13= CAST('1991-01-01 00:00:00' as datetime) and
c14= CAST('1991-01-01 01:01:01' as datetime) and
c15= CAST('1991-01-01 01:01:01' as datetime) and
- c16= CAST('1991-01-01 01:01:01' as datetime) and
c17= CAST('1991-01-01 01:01:01' as datetime)" ;
execute stmt1 ;
found
true
prepare stmt1 from "select 'true' as found from t9
-where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
-execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
+where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c17= ?" ;
+execute stmt1 using @arg00, @arg00, @arg00, @arg00 ;
+found
+true
+set @arg00= '01:01:01' ;
+select 'true' as found from t9 where c1= 20 and c16= '01:01:01' ;
+found
+true
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= '01:01:01'" ;
+execute stmt1 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
+found
+true
+set @arg00= CAST('01:01:01' as time) ;
+select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time) ;
+found
+true
+select 'true' as found from t9 where c1= 20 and c16= @arg00 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= CAST('01:01:01' as time)" ;
+execute stmt1 ;
+found
+true
+prepare stmt1 from "select 'true' as found from t9 where c1= 20 and c16= ?" ;
+execute stmt1 using @arg00 ;
found
true
set @arg00= 1991 ;
diff --git a/mysql-test/suite/maria/t/compat_aliases.test b/mysql-test/suite/maria/t/compat_aliases.test
deleted file mode 100644
index 7b94d24e643..00000000000
--- a/mysql-test/suite/maria/t/compat_aliases.test
+++ /dev/null
@@ -1,59 +0,0 @@
-#
-# test for maria* aliases (system variables, status variables,
-# command-line options). They should match aria* variables.
-#
-
---replace_column 5 #
-select * from information_schema.plugins where plugin_name like '%aria';
-
-select maria_vars.variable_name, aria_vars.variable_name from
- information_schema.session_variables as maria_vars left join
- information_schema.session_variables as aria_vars
- on (maria_vars.variable_name = concat('m', aria_vars.variable_name))
- where maria_vars.variable_name like 'maria_%'
- and not (maria_vars.variable_value <=> aria_vars.variable_value);
-
-select maria_vars.variable_name, aria_vars.variable_name from
- information_schema.session_status as maria_vars left join
- information_schema.session_status as aria_vars
- on (maria_vars.variable_name = concat('m', aria_vars.variable_name))
- where maria_vars.variable_name like 'maria_%'
- and not (maria_vars.variable_value <=> aria_vars.variable_value);
-
-select maria_vars.variable_name, aria_vars.variable_name from
- information_schema.session_variables as aria_vars left join
- information_schema.session_variables as maria_vars
- on (maria_vars.variable_name = concat('m', aria_vars.variable_name))
- where aria_vars.variable_name like 'aria_%'
- and not (maria_vars.variable_value <=> aria_vars.variable_value);
-
-select maria_vars.variable_name, aria_vars.variable_name from
- information_schema.session_status as aria_vars left join
- information_schema.session_status as maria_vars
- on (maria_vars.variable_name = concat('m', aria_vars.variable_name))
- where aria_vars.variable_name like 'aria_%'
- and not (maria_vars.variable_value <=> aria_vars.variable_value);
-
-set @old_checkpoint_interval=@@global.aria_checkpoint_interval;
-set global maria_checkpoint_interval=10;
-select @@global.aria_checkpoint_interval;
-set global maria_checkpoint_interval=@old_checkpoint_interval;
-
-set @old_sort_buffer_size=@@global.maria_sort_buffer_size;
-set global aria_sort_buffer_size=1024;
-select @@global.maria_sort_buffer_size;
-set global aria_sort_buffer_size=@old_sort_buffer_size;
-
-set @old_sort_buffer_size=@@session.maria_sort_buffer_size;
-set session aria_sort_buffer_size=2048;
-select @@session.maria_sort_buffer_size;
-set session aria_sort_buffer_size=@old_sort_buffer_size;
-
-set @old_max_sort_file_size=@@global.maria_max_sort_file_size,
- @old_repair_threads=@@global.aria_repair_threads;
-set @@global.maria_max_sort_file_size=default, @@global.aria_repair_threads=default;
---replace_result 4293918720 9223372036853727232
-select @@global.maria_max_sort_file_size, @@global.aria_repair_threads;
-set @@global.aria_max_sort_file_size=@old_max_sort_file_size,
- @@global.maria_repair_threads=@old_repair_threads;
-
diff --git a/mysql-test/suite/maria/t/maria-autozerofill.test b/mysql-test/suite/maria/t/maria-autozerofill.test
index dfdedc220aa..9bb2782105a 100644
--- a/mysql-test/suite/maria/t/maria-autozerofill.test
+++ b/mysql-test/suite/maria/t/maria-autozerofill.test
@@ -31,7 +31,7 @@ create table t3 (a int) engine=aria;
INSERT INTO t3 VALUES (1),(2);
create table t4 (a int) engine=aria;
INSERT INTO t4 VALUES (1),(2);
-create table t5 (a int) engine=maria;
+create table t5 (a int) engine=aria;
INSERT INTO t5 VALUES (1),(2);
flush tables;
diff --git a/mysql-test/suite/maria/t/maria-connect.test b/mysql-test/suite/maria/t/maria-connect.test
index 9efb5844bc2..a1e9bbce4f2 100644
--- a/mysql-test/suite/maria/t/maria-connect.test
+++ b/mysql-test/suite/maria/t/maria-connect.test
@@ -4,6 +4,9 @@
-- source include/have_maria.inc
-- source include/have_log_bin.inc
+-- source include/binlog_start_pos.inc
+
+let $start_pos= `select @binlog_start_pos`;
let $default=`select @@global.storage_engine`;
set global storage_engine=aria;
@@ -27,7 +30,9 @@ insert t1 values (1),(2),(3);
--error ER_DUP_ENTRY
insert t1 values (4),(2),(5);
select * from t1;
-SHOW BINLOG EVENTS FROM 106;
+--replace_result $start_pos <start_pos>
+--replace_column 2 # 5 #
+eval SHOW BINLOG EVENTS FROM $start_pos;
drop table t1;
set binlog_format=default;
diff --git a/mysql-test/suite/maria/t/maria-gis-recovery-master.opt b/mysql-test/suite/maria/t/maria-gis-recovery-master.opt
new file mode 100644
index 00000000000..58d0d012c54
--- /dev/null
+++ b/mysql-test/suite/maria/t/maria-gis-recovery-master.opt
@@ -0,0 +1 @@
+--skip-stack-trace --skip-core-file --loose-aria-log-dir-path=$MYSQLTEST_VARDIR/tmp
diff --git a/mysql-test/suite/maria/t/maria-gis-recovery.test b/mysql-test/suite/maria/t/maria-gis-recovery.test
new file mode 100644
index 00000000000..c40cc3788de
--- /dev/null
+++ b/mysql-test/suite/maria/t/maria-gis-recovery.test
@@ -0,0 +1,64 @@
+--source include/not_embedded.inc
+# Don't test this under valgrind, memory leaks will occur as we crash
+--source include/not_valgrind.inc
+# Binary must be compiled with debug for crash to occur
+--source include/have_debug.inc
+--source include/have_maria.inc
+--source include/have_geometry.inc
+
+set global aria_log_file_size=4294967295;
+let $MARIA_LOG=../../tmp;
+
+--disable_warnings
+drop database if exists mysqltest;
+--enable_warnings
+create database mysqltest;
+let $mms_tname=t;
+
+# Include scripts can perform SQL. For it to not influence the main test
+# they use a separate connection. This way if they use a DDL it would
+# not autocommit in the main test.
+connect (admin, localhost, root,,mysqltest,,);
+--enable_reconnect
+
+connection default;
+use mysqltest;
+--enable_reconnect
+
+-- source include/maria_empty_logs.inc
+let $mms_tables=1;
+CREATE TABLE t1 (
+ i int,
+ shape GEOMETRY NOT NULL,
+ SPATIAL (shape)
+) ENGINE=ARIA;
+insert into t1 values(1,POINT(1, 1));
+-- source include/maria_make_snapshot_for_feeding_recovery.inc
+insert into t1 values(2,POINT(2, 2)), (3,POINT(3, 3)), (4,POINT(4, 4));
+-- source include/maria_make_snapshot_for_comparison.inc
+let $mvr_restore_old_snapshot=1;
+let $mms_compare_physically=0;
+let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash";
+let $mvr_crash_statement= set global aria_checkpoint_interval=1;
+-- source include/maria_verify_recovery.inc
+show create table t1;
+
+# Test that UPDATE's effect on auto-increment is recovered
+--echo * TEST of UPDATE vs state.auto_increment
+-- source include/maria_make_snapshot_for_feeding_recovery.inc
+update t1 set shape=POINT(5, 5) where i=2;
+-- source include/maria_make_snapshot_for_comparison.inc
+let $mvr_restore_old_snapshot=1;
+let $mms_compare_physically=0;
+let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash";
+let $mvr_crash_statement= set global aria_checkpoint_interval=1;
+-- source include/maria_verify_recovery.inc
+show create table t1;
+drop table t1;
+
+# clean up everything
+let $mms_purpose=feeding_recovery;
+eval drop database mysqltest_for_$mms_purpose;
+let $mms_purpose=comparison;
+eval drop database mysqltest_for_$mms_purpose;
+drop database mysqltest;
diff --git a/mysql-test/suite/maria/t/maria-recover.test b/mysql-test/suite/maria/t/maria-recover.test
index 29b05879967..56259ad9a31 100644
--- a/mysql-test/suite/maria/t/maria-recover.test
+++ b/mysql-test/suite/maria/t/maria-recover.test
@@ -10,7 +10,7 @@ call mtr.add_suppression("Recovering table: '\\..mysqltest.t_corrupted2'");
call mtr.add_suppression("Table '\\..mysqltest.t_corrupted2' is marked as crashed and should be repaired");
call mtr.add_suppression("Table 't_corrupted2' is marked as crashed and should be repaired");
-let $def_checkinterval=`select @@global.maria_checkpoint_interval`;
+let $def_checkinterval=`select @@global.aria_checkpoint_interval`;
--enable_query_log
@@ -39,7 +39,7 @@ insert into t1 values("ThursdayMorningsMarket");
flush table t1; # put index page on disk
insert into t1 select concat(a,'b') from t1 limit 1;
# force a checkpoint to get the open count > 0
-set global maria_checkpoint_interval=1000;
+set global aria_checkpoint_interval=1000;
# Wait for checkpoint to happen
--sleep 1
# now t1 has its open_count>0 and so will t2_corrupted.
diff --git a/mysql-test/suite/maria/t/maria.test b/mysql-test/suite/maria/t/maria.test
index e23821b8be9..ebeedbb23cc 100644
--- a/mysql-test/suite/maria/t/maria.test
+++ b/mysql-test/suite/maria/t/maria.test
@@ -42,6 +42,16 @@ CHECK TABLE t1;
drop table t1;
#
+# Test auto_increment warning
+#
+create table t1 (a int primary key auto_increment) engine=aria;
+insert into t1 values (1);
+update t1 set a=0 where a=1;
+check table t1;
+select * from t1;
+drop table t1;
+
+#
# Test problem with rows that are 65517-65520 bytes long
#
@@ -376,7 +386,8 @@ DROP TABLE t1;
#
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
-INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+INSERT into t1 values (0,null,0), (0,null,1), (0,null,2), (0,null,3), (1,1,4);
+INSERT into t1 values (2,4,5), (7,8,4), (8,3,1), (9,7,2), (5,5,9);
create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
INSERT into t2 values (1,1,1), (2,2,2);
optimize table t1;
diff --git a/mysql-test/suite/maria/t/maria3.test b/mysql-test/suite/maria/t/maria3.test
index 868a21d6bfb..f93706cf469 100644
--- a/mysql-test/suite/maria/t/maria3.test
+++ b/mysql-test/suite/maria/t/maria3.test
@@ -260,7 +260,7 @@ check table t1 extended;
drop table t1;
# Fix if we are using safemalloc
---replace_result 8388572 8388600
+--replace_result 8388572 8388600 134217692 134217720
select lower(variable_name) as Variable_name, Variable_value as Value from information_schema.session_variables where variable_name like "aria%" and variable_name not like "aria_used_for_temp_tables" order by 1;
--replace_column 2 #
show status like 'aria%';
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..96c8e1c6d43
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1-innodb.result
@@ -0,0 +1,1110 @@
+set @bug41996_extra1_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=off';
+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;
+set optimizer_switch=@bug41996_extra1_tmp;
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..ab24c2c1166
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug41996-extra1.result
@@ -0,0 +1,1110 @@
+set @bug41996_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=off';
+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;
+set optimizer_switch=@bug41996_tmp;
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..35cbe35bc7e
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43618.result
@@ -0,0 +1,51 @@
+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
+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
+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..5e34d2853e0
--- /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
+SET SESSION optimizer_switch = 'semijoin=off';
+
+# 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);
+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..09fcccb06d1
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra1-innodb.test
@@ -0,0 +1,489 @@
+set @bug41996_extra1_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=off';
+--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;
+set optimizer_switch=@bug41996_extra1_tmp;
+
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..5170ec22c59
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug41996-extra1.test
@@ -0,0 +1,488 @@
+set @bug41996_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=off';
+--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;
+set optimizer_switch=@bug41996_tmp;
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..0b1e560b58d
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/bug43448.test
@@ -0,0 +1,60 @@
+--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;
+
+begin;
+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;
+}
+commit;
+
+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..9e47b56ab16
--- /dev/null
+++ b/mysql-test/suite/optimizer_unfixed_bugs/t/disabled.def
@@ -0,0 +1,6 @@
+# Disabling all subquery problems
+
+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/inc/part_supported_sql_funcs_delete.inc b/mysql-test/suite/parts/inc/part_supported_sql_funcs_delete.inc
index 49d0b6fc69f..844ba70df4a 100644
--- a/mysql-test/suite/parts/inc/part_supported_sql_funcs_delete.inc
+++ b/mysql-test/suite/parts/inc/part_supported_sql_funcs_delete.inc
@@ -16,12 +16,14 @@
--echo --- Delete rows and partitions of tables with $sqlfunc
--echo -------------------------------------------------------------------------
+begin;
eval delete from $t1 where col1=$val2;
eval delete from $t2 where col1=$val2;
eval delete from $t3 where col1=$val2;
eval delete from $t4 where col1=$val2;
eval delete from $t5 where col1=$val2;
eval delete from $t6 where col1=$val2;
+commit;
eval select * from $t1 order by col1;
eval select * from $t2 order by col1;
@@ -29,12 +31,14 @@ eval select * from $t3 order by col1;
eval select * from $t4 order by colint;
eval select * from $t5 order by colint;
+begin;
eval insert into $t1 values ($val2);
eval insert into $t2 values ($val2);
eval insert into $t3 values ($val2);
eval insert into $t4 values (60,$val2);
eval insert into $t5 values (60,$val2);
eval insert into $t6 values (60,$val2);
+commit;
eval select * from $t1 order by col1;
eval select * from $t2 order by col1;
diff --git a/mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc b/mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc
index b7a170dd9d8..565731db75b 100644
--- a/mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc
+++ b/mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc
@@ -114,7 +114,7 @@ let $val4 = '10:30';
let $sqlfunc = microsecond(col1);
let $valsqlfunc = microsecond('10:30:10.000010');
-let $coltype = time;
+let $coltype = time(6);
let $infile = part_supported_sql_funcs_int_time.inc;
let $val1 = '09:09:15.000002';
let $val2 = '04:30:01.000018';
@@ -164,6 +164,8 @@ let $val3 = '2006-09-25';
let $val4 = '2006-07-30';
--source suite/parts/inc/partition_supported_sql_funcs.inc
+# time_to_sec() is now a double function, so it can't be portioned upon
+--disable_parsing
let $sqlfunc = time_to_sec(col1)-(time_to_sec(col1)-20);
let $valsqlfunc = time_to_sec('18:30:14')-(time_to_sec('17:59:59'));
let $coltype = time;
@@ -173,6 +175,7 @@ let $val2 = '14:30:45';
let $val3 = '21:59:22';
let $val4 = '10:33:11';
--source suite/parts/inc/partition_supported_sql_funcs.inc
+--enable_parsing
# to_days(non_date_col) is disabled after bug#54483.
#let $sqlfunc = to_days(col1)-to_days('2006-01-01');
diff --git a/mysql-test/suite/parts/inc/partition_supported_sql_funcs.inc b/mysql-test/suite/parts/inc/partition_supported_sql_funcs.inc
index 83d0fa37375..0de6bd7d2f5 100644
--- a/mysql-test/suite/parts/inc/partition_supported_sql_funcs.inc
+++ b/mysql-test/suite/parts/inc/partition_supported_sql_funcs.inc
@@ -113,6 +113,7 @@ $part_t6;
--echo --- Access tables with $sqlfunc
--echo -------------------------------------------------------------------------
+begin;
eval insert into t1 values ($val1);
eval insert into t1 values ($val2);
@@ -123,6 +124,7 @@ eval insert into t2 values ($val3);
eval insert into t3 values ($val1);
eval insert into t3 values ($val2);
eval insert into t3 values ($val3);
+commit;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval load data infile '$MYSQLTEST_VARDIR/std_data/parts/$infile' into table t4;
@@ -142,12 +144,14 @@ select * from t6 order by colint;
if ($do_long_tests)
{
+ begin;
eval update t1 set col1=$val4 where col1=$val1;
eval update t2 set col1=$val4 where col1=$val1;
eval update t3 set col1=$val4 where col1=$val1;
eval update t4 set col1=$val4 where col1=$val1;
eval update t5 set col1=$val4 where col1=$val1;
eval update t6 set col1=$val4 where col1=$val1;
+ commit;
select * from t1 order by col1;
select * from t2 order by col1;
diff --git a/mysql-test/suite/parts/r/part_supported_sql_func_innodb.result b/mysql-test/suite/parts/r/part_supported_sql_func_innodb.result
index c5b4e0a8665..c4eeb25d6b4 100644
--- a/mysql-test/suite/parts/r/part_supported_sql_func_innodb.result
+++ b/mysql-test/suite/parts/r/part_supported_sql_func_innodb.result
@@ -47,6 +47,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with abs(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values (5 );
insert into t1 values (13 );
insert into t2 values (5 );
@@ -55,6 +56,7 @@ insert into t2 values (17 );
insert into t3 values (5 );
insert into t3 values (13 );
insert into t3 values (17 );
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_int.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_int.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_int.inc' into table t6;
@@ -217,12 +219,14 @@ colint col1
50 56
51 34
55 123
+begin;
update t1 set col1=15 where col1=5 ;
update t2 set col1=15 where col1=5 ;
update t3 set col1=15 where col1=5 ;
update t4 set col1=15 where col1=5 ;
update t5 set col1=15 where col1=5 ;
update t6 set col1=15 where col1=5 ;
+commit;
select * from t1 order by col1;
col1
13
@@ -877,12 +881,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with abs(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1=13 ;
delete from t2 where col1=13 ;
delete from t3 where col1=13 ;
delete from t4 where col1=13 ;
delete from t5 where col1=13 ;
delete from t6 where col1=13 ;
+commit;
select * from t1 order by col1;
col1
15
@@ -986,12 +992,14 @@ colint col1
50 56
51 34
55 123
+begin;
insert into t1 values (13 );
insert into t2 values (13 );
insert into t3 values (13 );
insert into t4 values (60,13 );
insert into t5 values (60,13 );
insert into t6 values (60,13 );
+commit;
select * from t1 order by col1;
col1
13
@@ -1274,12 +1282,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with abs(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1=13 ;
delete from t22 where col1=13 ;
delete from t33 where col1=13 ;
delete from t44 where col1=13 ;
delete from t55 where col1=13 ;
delete from t66 where col1=13 ;
+commit;
select * from t11 order by col1;
col1
15
@@ -1383,12 +1393,14 @@ colint col1
50 56
51 34
55 123
+begin;
insert into t11 values (13 );
insert into t22 values (13 );
insert into t33 values (13 );
insert into t44 values (60,13 );
insert into t55 values (60,13 );
insert into t66 values (60,13 );
+commit;
select * from t11 order by col1;
col1
13
@@ -1732,6 +1744,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with mod(col1,10)
-------------------------------------------------------------------------
+begin;
insert into t1 values (5);
insert into t1 values (19);
insert into t2 values (5);
@@ -1740,6 +1753,7 @@ insert into t2 values (17);
insert into t3 values (5);
insert into t3 values (19);
insert into t3 values (17);
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_int.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_int.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_int.inc' into table t6;
@@ -1902,12 +1916,14 @@ colint col1
50 56
51 34
55 123
+begin;
update t1 set col1=15 where col1=5;
update t2 set col1=15 where col1=5;
update t3 set col1=15 where col1=5;
update t4 set col1=15 where col1=5;
update t5 set col1=15 where col1=5;
update t6 set col1=15 where col1=5;
+commit;
select * from t1 order by col1;
col1
15
@@ -2562,12 +2578,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with mod(col1,10)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1=19;
delete from t2 where col1=19;
delete from t3 where col1=19;
delete from t4 where col1=19;
delete from t5 where col1=19;
delete from t6 where col1=19;
+commit;
select * from t1 order by col1;
col1
15
@@ -2673,12 +2691,14 @@ colint col1
50 56
51 34
55 123
+begin;
insert into t1 values (19);
insert into t2 values (19);
insert into t3 values (19);
insert into t4 values (60,19);
insert into t5 values (60,19);
insert into t6 values (60,19);
+commit;
select * from t1 order by col1;
col1
15
@@ -2970,12 +2990,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with mod(col1,10)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1=19;
delete from t22 where col1=19;
delete from t33 where col1=19;
delete from t44 where col1=19;
delete from t55 where col1=19;
delete from t66 where col1=19;
+commit;
select * from t11 order by col1;
col1
15
@@ -3081,12 +3103,14 @@ colint col1
50 56
51 34
55 123
+begin;
insert into t11 values (19);
insert into t22 values (19);
insert into t33 values (19);
insert into t44 values (60,19);
insert into t55 values (60,19);
insert into t66 values (60,19);
+commit;
select * from t11 order by col1;
col1
15
@@ -3439,6 +3463,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with day(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-02-03');
insert into t1 values ('2006-01-17');
insert into t2 values ('2006-02-03');
@@ -3447,6 +3472,7 @@ insert into t2 values ('2006-01-25');
insert into t3 values ('2006-02-03');
insert into t3 values ('2006-01-17');
insert into t3 values ('2006-01-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -3486,12 +3512,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-02-05' where col1='2006-02-03';
update t2 set col1='2006-02-05' where col1='2006-02-03';
update t3 set col1='2006-02-05' where col1='2006-02-03';
update t4 set col1='2006-02-05' where col1='2006-02-03';
update t5 set col1='2006-02-05' where col1='2006-02-03';
update t6 set col1='2006-02-05' where col1='2006-02-03';
+commit;
select * from t1 order by col1;
col1
2006-01-17
@@ -3695,12 +3723,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with day(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-01-17';
delete from t2 where col1='2006-01-17';
delete from t3 where col1='2006-01-17';
delete from t4 where col1='2006-01-17';
delete from t5 where col1='2006-01-17';
delete from t6 where col1='2006-01-17';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -3722,12 +3752,14 @@ colint col1
1 2006-02-05
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-01-17');
insert into t2 values ('2006-01-17');
insert into t3 values ('2006-01-17');
insert into t4 values (60,'2006-01-17');
insert into t5 values (60,'2006-01-17');
insert into t6 values (60,'2006-01-17');
+commit;
select * from t1 order by col1;
col1
2006-01-17
@@ -3789,12 +3821,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with day(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-01-17';
delete from t22 where col1='2006-01-17';
delete from t33 where col1='2006-01-17';
delete from t44 where col1='2006-01-17';
delete from t55 where col1='2006-01-17';
delete from t66 where col1='2006-01-17';
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -3816,12 +3850,14 @@ colint col1
1 2006-02-05
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-01-17');
insert into t22 values ('2006-01-17');
insert into t33 values ('2006-01-17');
insert into t44 values (60,'2006-01-17');
insert into t55 values (60,'2006-01-17');
insert into t66 values (60,'2006-01-17');
+commit;
select * from t11 order by col1;
col1
2006-01-17
@@ -3944,6 +3980,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with dayofmonth(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-02-03');
insert into t1 values ('2006-01-17');
insert into t2 values ('2006-02-03');
@@ -3952,6 +3989,7 @@ insert into t2 values ('2006-01-25');
insert into t3 values ('2006-02-03');
insert into t3 values ('2006-01-17');
insert into t3 values ('2006-01-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -3991,12 +4029,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-02-05' where col1='2006-02-03';
update t2 set col1='2006-02-05' where col1='2006-02-03';
update t3 set col1='2006-02-05' where col1='2006-02-03';
update t4 set col1='2006-02-05' where col1='2006-02-03';
update t5 set col1='2006-02-05' where col1='2006-02-03';
update t6 set col1='2006-02-05' where col1='2006-02-03';
+commit;
select * from t1 order by col1;
col1
2006-01-17
@@ -4200,12 +4240,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with dayofmonth(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-01-17';
delete from t2 where col1='2006-01-17';
delete from t3 where col1='2006-01-17';
delete from t4 where col1='2006-01-17';
delete from t5 where col1='2006-01-17';
delete from t6 where col1='2006-01-17';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -4227,12 +4269,14 @@ colint col1
1 2006-02-05
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-01-17');
insert into t2 values ('2006-01-17');
insert into t3 values ('2006-01-17');
insert into t4 values (60,'2006-01-17');
insert into t5 values (60,'2006-01-17');
insert into t6 values (60,'2006-01-17');
+commit;
select * from t1 order by col1;
col1
2006-01-17
@@ -4294,12 +4338,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with dayofmonth(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-01-17';
delete from t22 where col1='2006-01-17';
delete from t33 where col1='2006-01-17';
delete from t44 where col1='2006-01-17';
delete from t55 where col1='2006-01-17';
delete from t66 where col1='2006-01-17';
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -4321,12 +4367,14 @@ colint col1
1 2006-02-05
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-01-17');
insert into t22 values ('2006-01-17');
insert into t33 values ('2006-01-17');
insert into t44 values (60,'2006-01-17');
insert into t55 values (60,'2006-01-17');
insert into t66 values (60,'2006-01-17');
+commit;
select * from t11 order by col1;
col1
2006-01-17
@@ -4449,6 +4497,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with dayofweek(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-01-03');
insert into t1 values ('2006-02-17');
insert into t2 values ('2006-01-03');
@@ -4457,6 +4506,7 @@ insert into t2 values ('2006-01-25');
insert into t3 values ('2006-01-03');
insert into t3 values ('2006-02-17');
insert into t3 values ('2006-01-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -4496,12 +4546,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-02-05' where col1='2006-01-03';
update t2 set col1='2006-02-05' where col1='2006-01-03';
update t3 set col1='2006-02-05' where col1='2006-01-03';
update t4 set col1='2006-02-05' where col1='2006-01-03';
update t5 set col1='2006-02-05' where col1='2006-01-03';
update t6 set col1='2006-02-05' where col1='2006-01-03';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -4705,12 +4757,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with dayofweek(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-02-17';
delete from t2 where col1='2006-02-17';
delete from t3 where col1='2006-02-17';
delete from t4 where col1='2006-02-17';
delete from t5 where col1='2006-02-17';
delete from t6 where col1='2006-02-17';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -4734,12 +4788,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-02-17');
insert into t2 values ('2006-02-17');
insert into t3 values ('2006-02-17');
insert into t4 values (60,'2006-02-17');
insert into t5 values (60,'2006-02-17');
insert into t6 values (60,'2006-02-17');
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -4805,12 +4861,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with dayofweek(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-02-17';
delete from t22 where col1='2006-02-17';
delete from t33 where col1='2006-02-17';
delete from t44 where col1='2006-02-17';
delete from t55 where col1='2006-02-17';
delete from t66 where col1='2006-02-17';
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -4834,12 +4892,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-02-17');
insert into t22 values ('2006-02-17');
insert into t33 values ('2006-02-17');
insert into t44 values (60,'2006-02-17');
insert into t55 values (60,'2006-02-17');
insert into t66 values (60,'2006-02-17');
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -4966,6 +5026,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with dayofyear(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-01-03');
insert into t1 values ('2006-01-17');
insert into t2 values ('2006-01-03');
@@ -4974,6 +5035,7 @@ insert into t2 values ('2006-02-25');
insert into t3 values ('2006-01-03');
insert into t3 values ('2006-01-17');
insert into t3 values ('2006-02-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -5013,12 +5075,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-02-05' where col1='2006-01-03';
update t2 set col1='2006-02-05' where col1='2006-01-03';
update t3 set col1='2006-02-05' where col1='2006-01-03';
update t4 set col1='2006-02-05' where col1='2006-01-03';
update t5 set col1='2006-02-05' where col1='2006-01-03';
update t6 set col1='2006-02-05' where col1='2006-01-03';
+commit;
select * from t1 order by col1;
col1
2006-01-17
@@ -5222,12 +5286,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with dayofyear(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-01-17';
delete from t2 where col1='2006-01-17';
delete from t3 where col1='2006-01-17';
delete from t4 where col1='2006-01-17';
delete from t5 where col1='2006-01-17';
delete from t6 where col1='2006-01-17';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -5249,12 +5315,14 @@ colint col1
1 2006-02-03
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-01-17');
insert into t2 values ('2006-01-17');
insert into t3 values ('2006-01-17');
insert into t4 values (60,'2006-01-17');
insert into t5 values (60,'2006-01-17');
insert into t6 values (60,'2006-01-17');
+commit;
select * from t1 order by col1;
col1
2006-01-17
@@ -5317,12 +5385,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with dayofyear(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-01-17';
delete from t22 where col1='2006-01-17';
delete from t33 where col1='2006-01-17';
delete from t44 where col1='2006-01-17';
delete from t55 where col1='2006-01-17';
delete from t66 where col1='2006-01-17';
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -5344,12 +5414,14 @@ colint col1
1 2006-02-03
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-01-17');
insert into t22 values ('2006-01-17');
insert into t33 values ('2006-01-17');
insert into t44 values (60,'2006-01-17');
insert into t55 values (60,'2006-01-17');
insert into t66 values (60,'2006-01-17');
+commit;
select * from t11 order by col1;
col1
2006-01-17
@@ -5473,6 +5545,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with extract(month from col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-01-03');
insert into t1 values ('2006-02-17');
insert into t2 values ('2006-01-03');
@@ -5481,6 +5554,7 @@ insert into t2 values ('2006-01-25');
insert into t3 values ('2006-01-03');
insert into t3 values ('2006-02-17');
insert into t3 values ('2006-01-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -5520,12 +5594,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-02-05' where col1='2006-01-03';
update t2 set col1='2006-02-05' where col1='2006-01-03';
update t3 set col1='2006-02-05' where col1='2006-01-03';
update t4 set col1='2006-02-05' where col1='2006-01-03';
update t5 set col1='2006-02-05' where col1='2006-01-03';
update t6 set col1='2006-02-05' where col1='2006-01-03';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -5729,12 +5805,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with extract(month from col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-02-17';
delete from t2 where col1='2006-02-17';
delete from t3 where col1='2006-02-17';
delete from t4 where col1='2006-02-17';
delete from t5 where col1='2006-02-17';
delete from t6 where col1='2006-02-17';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -5758,12 +5836,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-02-17');
insert into t2 values ('2006-02-17');
insert into t3 values ('2006-02-17');
insert into t4 values (60,'2006-02-17');
insert into t5 values (60,'2006-02-17');
insert into t6 values (60,'2006-02-17');
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -5824,12 +5904,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with extract(month from col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-02-17';
delete from t22 where col1='2006-02-17';
delete from t33 where col1='2006-02-17';
delete from t44 where col1='2006-02-17';
delete from t55 where col1='2006-02-17';
delete from t66 where col1='2006-02-17';
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -5853,12 +5935,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-02-17');
insert into t22 values ('2006-02-17');
insert into t33 values ('2006-02-17');
insert into t44 values (60,'2006-02-17');
insert into t55 values (60,'2006-02-17');
insert into t66 values (60,'2006-02-17');
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -5980,6 +6064,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with hour(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('09:09');
insert into t1 values ('14:30');
insert into t2 values ('09:09');
@@ -5988,6 +6073,7 @@ insert into t2 values ('21:59');
insert into t3 values ('09:09');
insert into t3 values ('14:30');
insert into t3 values ('21:59');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t6;
@@ -6027,12 +6113,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
update t1 set col1='10:30' where col1='09:09';
update t2 set col1='10:30' where col1='09:09';
update t3 set col1='10:30' where col1='09:09';
update t4 set col1='10:30' where col1='09:09';
update t5 set col1='10:30' where col1='09:09';
update t6 set col1='10:30' where col1='09:09';
+commit;
select * from t1 order by col1;
col1
10:30:00
@@ -6236,12 +6324,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with hour(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='14:30';
delete from t2 where col1='14:30';
delete from t3 where col1='14:30';
delete from t4 where col1='14:30';
delete from t5 where col1='14:30';
delete from t6 where col1='14:30';
+commit;
select * from t1 order by col1;
col1
10:30:00
@@ -6265,12 +6355,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
insert into t1 values ('14:30');
insert into t2 values ('14:30');
insert into t3 values ('14:30');
insert into t4 values (60,'14:30');
insert into t5 values (60,'14:30');
insert into t6 values (60,'14:30');
+commit;
select * from t1 order by col1;
col1
10:30:00
@@ -6334,12 +6426,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with hour(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='14:30';
delete from t22 where col1='14:30';
delete from t33 where col1='14:30';
delete from t44 where col1='14:30';
delete from t55 where col1='14:30';
delete from t66 where col1='14:30';
+commit;
select * from t11 order by col1;
col1
10:30:00
@@ -6363,12 +6457,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
insert into t11 values ('14:30');
insert into t22 values ('14:30');
insert into t33 values ('14:30');
insert into t44 values (60,'14:30');
insert into t55 values (60,'14:30');
insert into t66 values (60,'14:30');
+commit;
select * from t11 order by col1;
col1
10:30:00
@@ -6445,7 +6541,7 @@ drop table if exists t44 ;
drop table if exists t55 ;
drop table if exists t66 ;
-------------------------------------------------------------------------
---- microsecond(col1) in partition with coltype time
+--- microsecond(col1) in partition with coltype time(6)
-------------------------------------------------------------------------
drop table if exists t1 ;
drop table if exists t2 ;
@@ -6456,11 +6552,11 @@ drop table if exists t6 ;
-------------------------------------------------------------------------
--- Create tables with microsecond(col1)
-------------------------------------------------------------------------
-create table t1 (col1 time) engine='INNODB'
+create table t1 (col1 time(6)) engine='INNODB'
partition by range(microsecond(col1))
(partition p0 values less than (15),
partition p1 values less than maxvalue);
-create table t2 (col1 time) engine='INNODB'
+create table t2 (col1 time(6)) engine='INNODB'
partition by list(microsecond(col1))
(partition p0 values in (0,1,2,3,4,5,6,7,8,9,10),
partition p1 values in (11,12,13,14,15,16,17,18,19,20),
@@ -6469,14 +6565,14 @@ partition p3 values in (31,32,33,34,35,36,37,38,39,40),
partition p4 values in (41,42,43,44,45,46,47,48,49,50),
partition p5 values in (51,52,53,54,55,56,57,58,59,60)
);
-create table t3 (col1 time) engine='INNODB'
+create table t3 (col1 time(6)) engine='INNODB'
partition by hash(microsecond(col1));
-create table t4 (colint int, col1 time) engine='INNODB'
+create table t4 (colint int, col1 time(6)) engine='INNODB'
partition by range(colint)
subpartition by hash(microsecond(col1)) subpartitions 2
(partition p0 values less than (15),
partition p1 values less than maxvalue);
-create table t5 (colint int, col1 time) engine='INNODB'
+create table t5 (colint int, col1 time(6)) engine='INNODB'
partition by list(colint)
subpartition by hash(microsecond(col1)) subpartitions 2
(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
@@ -6486,13 +6582,14 @@ partition p3 values in (31,32,33,34,35,36,37,38,39,40),
partition p4 values in (41,42,43,44,45,46,47,48,49,50),
partition p5 values in (51,52,53,54,55,56,57,58,59,60)
);
-create table t6 (colint int, col1 time) engine='INNODB'
+create table t6 (colint int, col1 time(6)) engine='INNODB'
partition by range(colint)
(partition p0 values less than (microsecond('10:30:10.000010')),
partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with microsecond(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('09:09:15.000002');
insert into t1 values ('04:30:01.000018');
insert into t2 values ('09:09:15.000002');
@@ -6501,83 +6598,86 @@ insert into t2 values ('00:59:22.000024');
insert into t3 values ('09:09:15.000002');
insert into t3 values ('04:30:01.000018');
insert into t3 values ('00:59:22.000024');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t6;
select microsecond(col1) from t1 order by col1;
microsecond(col1)
-0
-0
+18
+2
select * from t1 order by col1;
col1
-04:30:01
-09:09:15
+04:30:01.000018
+09:09:15.000002
select * from t2 order by col1;
col1
-00:59:22
-04:30:01
-09:09:15
+00:59:22.000024
+04:30:01.000018
+09:09:15.000002
select * from t3 order by col1;
col1
-00:59:22
-04:30:01
-09:09:15
+00:59:22.000024
+04:30:01.000018
+09:09:15.000002
select * from t4 order by colint;
colint col1
-1 09:09:15
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 09:09:15.000002
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
select * from t5 order by colint;
colint col1
-1 09:09:15
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 09:09:15.000002
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
select * from t6 order by colint;
colint col1
-1 09:09:15
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 09:09:15.000002
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
+begin;
update t1 set col1='05:30:34.000037' where col1='09:09:15.000002';
update t2 set col1='05:30:34.000037' where col1='09:09:15.000002';
update t3 set col1='05:30:34.000037' where col1='09:09:15.000002';
update t4 set col1='05:30:34.000037' where col1='09:09:15.000002';
update t5 set col1='05:30:34.000037' where col1='09:09:15.000002';
update t6 set col1='05:30:34.000037' where col1='09:09:15.000002';
+commit;
select * from t1 order by col1;
col1
-04:30:01
-05:30:34
+04:30:01.000018
+05:30:34.000037
select * from t2 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t3 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t4 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
select * from t5 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
select * from t6 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
-------------------------------------------------------------------------
--- Alter tables with microsecond(col1)
-------------------------------------------------------------------------
@@ -6629,36 +6729,36 @@ partition by range(colint)
partition p1 values less than maxvalue);
select * from t11 order by col1;
col1
-04:30:01
-05:30:34
+04:30:01.000018
+05:30:34.000037
select * from t22 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t33 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t44 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
select * from t55 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
select * from t66 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
---------------------------
---- some alter table begin
---------------------------
@@ -6667,16 +6767,16 @@ reorganize partition p0,p1 into
(partition s1 values less than maxvalue);
select * from t11 order by col1;
col1
-04:30:01
-05:30:34
+04:30:01.000018
+05:30:34.000037
alter table t11
reorganize partition s1 into
(partition p0 values less than (15),
partition p1 values less than maxvalue);
select * from t11 order by col1;
col1
-04:30:01
-05:30:34
+04:30:01.000018
+05:30:34.000037
alter table t55
partition by list(colint)
subpartition by hash(microsecond(col1)) subpartitions 5
@@ -6691,7 +6791,7 @@ show create table t55;
Table Create Table
t55 CREATE TABLE `t55` (
`colint` int(11) DEFAULT NULL,
- `col1` time DEFAULT NULL
+ `col1` time(6) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY LIST (colint)
SUBPARTITION BY HASH (microsecond(col1))
@@ -6704,116 +6804,120 @@ SUBPARTITIONS 5
PARTITION p5 VALUES IN (51,52,53,54,55,56,57,58,59,60) ENGINE = InnoDB) */
select * from t55 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
alter table t66
reorganize partition p0,p1 into
(partition s1 values less than maxvalue);
select * from t66 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
alter table t66
reorganize partition s1 into
(partition p0 values less than (microsecond('10:30:10.000010')),
partition p1 values less than maxvalue);
select * from t66 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
alter table t66
reorganize partition p0,p1 into
(partition s1 values less than maxvalue);
select * from t66 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
alter table t66
reorganize partition s1 into
(partition p0 values less than (microsecond('10:30:10.000010')),
partition p1 values less than maxvalue);
select * from t66 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with microsecond(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='04:30:01.000018';
delete from t2 where col1='04:30:01.000018';
delete from t3 where col1='04:30:01.000018';
delete from t4 where col1='04:30:01.000018';
delete from t5 where col1='04:30:01.000018';
delete from t6 where col1='04:30:01.000018';
+commit;
select * from t1 order by col1;
col1
-05:30:34
+05:30:34.000037
select * from t2 order by col1;
col1
-00:59:22
-05:30:34
+00:59:22.000024
+05:30:34.000037
select * from t3 order by col1;
col1
-00:59:22
-05:30:34
+00:59:22.000024
+05:30:34.000037
select * from t4 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
select * from t5 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+begin;
insert into t1 values ('04:30:01.000018');
insert into t2 values ('04:30:01.000018');
insert into t3 values ('04:30:01.000018');
insert into t4 values (60,'04:30:01.000018');
insert into t5 values (60,'04:30:01.000018');
insert into t6 values (60,'04:30:01.000018');
+commit;
select * from t1 order by col1;
col1
-04:30:01
-05:30:34
+04:30:01.000018
+05:30:34.000037
select * from t2 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t3 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t4 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
-60 04:30:01
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+60 04:30:01.000018
select * from t5 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
-60 04:30:01
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+60 04:30:01.000018
select * from t6 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
-60 04:30:01
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+60 04:30:01.000018
alter table t1 drop partition p0;
alter table t2 drop partition p0;
alter table t4 drop partition p0;
@@ -6821,90 +6925,99 @@ alter table t5 drop partition p0;
alter table t6 drop partition p0;
select * from t1 order by col1;
col1
+04:30:01.000018
+05:30:34.000037
select * from t2 order by col1;
col1
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t3 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t4 order by colint;
colint col1
-60 04:30:01
+60 04:30:01.000018
select * from t5 order by colint;
colint col1
-60 04:30:01
+60 04:30:01.000018
select * from t6 order by colint;
colint col1
-60 04:30:01
+60 04:30:01.000018
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with microsecond(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='04:30:01.000018';
delete from t22 where col1='04:30:01.000018';
delete from t33 where col1='04:30:01.000018';
delete from t44 where col1='04:30:01.000018';
delete from t55 where col1='04:30:01.000018';
delete from t66 where col1='04:30:01.000018';
+commit;
select * from t11 order by col1;
col1
-05:30:34
+05:30:34.000037
select * from t22 order by col1;
col1
-00:59:22
-05:30:34
+00:59:22.000024
+05:30:34.000037
select * from t33 order by col1;
col1
-00:59:22
-05:30:34
+00:59:22.000024
+05:30:34.000037
select * from t44 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
select * from t55 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+begin;
insert into t11 values ('04:30:01.000018');
insert into t22 values ('04:30:01.000018');
insert into t33 values ('04:30:01.000018');
insert into t44 values (60,'04:30:01.000018');
insert into t55 values (60,'04:30:01.000018');
insert into t66 values (60,'04:30:01.000018');
+commit;
select * from t11 order by col1;
col1
-04:30:01
-05:30:34
+04:30:01.000018
+05:30:34.000037
select * from t22 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t33 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t44 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
-60 04:30:01
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+60 04:30:01.000018
select * from t55 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
-60 04:30:01
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+60 04:30:01.000018
select * from t66 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
-60 04:30:01
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+60 04:30:01.000018
alter table t11 drop partition p0;
alter table t22 drop partition p0;
alter table t44 drop partition p0;
@@ -6912,22 +7025,27 @@ alter table t55 drop partition p0;
alter table t66 drop partition p0;
select * from t11 order by col1;
col1
+04:30:01.000018
+05:30:34.000037
select * from t22 order by col1;
col1
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t33 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t44 order by colint;
colint col1
-60 04:30:01
+60 04:30:01.000018
select * from t55 order by colint;
colint col1
-60 04:30:01
+60 04:30:01.000018
select * from t66 order by colint;
colint col1
-60 04:30:01
+60 04:30:01.000018
-------------------------
---- some alter table end
-------------------------
@@ -6992,6 +7110,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with minute(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('09:09:15');
insert into t1 values ('14:30:45');
insert into t2 values ('09:09:15');
@@ -7000,6 +7119,7 @@ insert into t2 values ('21:59:22');
insert into t3 values ('09:09:15');
insert into t3 values ('14:30:45');
insert into t3 values ('21:59:22');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t6;
@@ -7039,12 +7159,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
update t1 set col1='10:24:23' where col1='09:09:15';
update t2 set col1='10:24:23' where col1='09:09:15';
update t3 set col1='10:24:23' where col1='09:09:15';
update t4 set col1='10:24:23' where col1='09:09:15';
update t5 set col1='10:24:23' where col1='09:09:15';
update t6 set col1='10:24:23' where col1='09:09:15';
+commit;
select * from t1 order by col1;
col1
10:24:23
@@ -7248,12 +7370,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with minute(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='14:30:45';
delete from t2 where col1='14:30:45';
delete from t3 where col1='14:30:45';
delete from t4 where col1='14:30:45';
delete from t5 where col1='14:30:45';
delete from t6 where col1='14:30:45';
+commit;
select * from t1 order by col1;
col1
10:24:23
@@ -7277,12 +7401,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
insert into t1 values ('14:30:45');
insert into t2 values ('14:30:45');
insert into t3 values ('14:30:45');
insert into t4 values (60,'14:30:45');
insert into t5 values (60,'14:30:45');
insert into t6 values (60,'14:30:45');
+commit;
select * from t1 order by col1;
col1
10:24:23
@@ -7349,12 +7475,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with minute(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='14:30:45';
delete from t22 where col1='14:30:45';
delete from t33 where col1='14:30:45';
delete from t44 where col1='14:30:45';
delete from t55 where col1='14:30:45';
delete from t66 where col1='14:30:45';
+commit;
select * from t11 order by col1;
col1
10:24:23
@@ -7378,12 +7506,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
insert into t11 values ('14:30:45');
insert into t22 values ('14:30:45');
insert into t33 values ('14:30:45');
insert into t44 values (60,'14:30:45');
insert into t55 values (60,'14:30:45');
insert into t66 values (60,'14:30:45');
+commit;
select * from t11 order by col1;
col1
10:24:23
@@ -7511,6 +7641,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with second(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('09:09:09');
insert into t1 values ('14:30:20');
insert into t2 values ('09:09:09');
@@ -7519,6 +7650,7 @@ insert into t2 values ('21:59:22');
insert into t3 values ('09:09:09');
insert into t3 values ('14:30:20');
insert into t3 values ('21:59:22');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t6;
@@ -7558,12 +7690,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
update t1 set col1='10:22:33' where col1='09:09:09';
update t2 set col1='10:22:33' where col1='09:09:09';
update t3 set col1='10:22:33' where col1='09:09:09';
update t4 set col1='10:22:33' where col1='09:09:09';
update t5 set col1='10:22:33' where col1='09:09:09';
update t6 set col1='10:22:33' where col1='09:09:09';
+commit;
select * from t1 order by col1;
col1
10:22:33
@@ -7767,12 +7901,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with second(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='14:30:20';
delete from t2 where col1='14:30:20';
delete from t3 where col1='14:30:20';
delete from t4 where col1='14:30:20';
delete from t5 where col1='14:30:20';
delete from t6 where col1='14:30:20';
+commit;
select * from t1 order by col1;
col1
10:22:33
@@ -7796,12 +7932,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
insert into t1 values ('14:30:20');
insert into t2 values ('14:30:20');
insert into t3 values ('14:30:20');
insert into t4 values (60,'14:30:20');
insert into t5 values (60,'14:30:20');
insert into t6 values (60,'14:30:20');
+commit;
select * from t1 order by col1;
col1
10:22:33
@@ -7868,12 +8006,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with second(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='14:30:20';
delete from t22 where col1='14:30:20';
delete from t33 where col1='14:30:20';
delete from t44 where col1='14:30:20';
delete from t55 where col1='14:30:20';
delete from t66 where col1='14:30:20';
+commit;
select * from t11 order by col1;
col1
10:22:33
@@ -7897,12 +8037,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
insert into t11 values ('14:30:20');
insert into t22 values ('14:30:20');
insert into t33 values ('14:30:20');
insert into t44 values (60,'14:30:20');
insert into t55 values (60,'14:30:20');
insert into t66 values (60,'14:30:20');
+commit;
select * from t11 order by col1;
col1
10:22:33
@@ -8030,6 +8172,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with month(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-01-03');
insert into t1 values ('2006-12-17');
insert into t2 values ('2006-01-03');
@@ -8038,6 +8181,7 @@ insert into t2 values ('2006-05-25');
insert into t3 values ('2006-01-03');
insert into t3 values ('2006-12-17');
insert into t3 values ('2006-05-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -8077,12 +8221,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-11-06' where col1='2006-01-03';
update t2 set col1='2006-11-06' where col1='2006-01-03';
update t3 set col1='2006-11-06' where col1='2006-01-03';
update t4 set col1='2006-11-06' where col1='2006-01-03';
update t5 set col1='2006-11-06' where col1='2006-01-03';
update t6 set col1='2006-11-06' where col1='2006-01-03';
+commit;
select * from t1 order by col1;
col1
2006-11-06
@@ -8286,12 +8432,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with month(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-12-17';
delete from t2 where col1='2006-12-17';
delete from t3 where col1='2006-12-17';
delete from t4 where col1='2006-12-17';
delete from t5 where col1='2006-12-17';
delete from t6 where col1='2006-12-17';
+commit;
select * from t1 order by col1;
col1
2006-11-06
@@ -8315,12 +8463,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-12-17');
insert into t2 values ('2006-12-17');
insert into t3 values ('2006-12-17');
insert into t4 values (60,'2006-12-17');
insert into t5 values (60,'2006-12-17');
insert into t6 values (60,'2006-12-17');
+commit;
select * from t1 order by col1;
col1
2006-11-06
@@ -8384,12 +8534,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with month(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-12-17';
delete from t22 where col1='2006-12-17';
delete from t33 where col1='2006-12-17';
delete from t44 where col1='2006-12-17';
delete from t55 where col1='2006-12-17';
delete from t66 where col1='2006-12-17';
+commit;
select * from t11 order by col1;
col1
2006-11-06
@@ -8413,12 +8565,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-12-17');
insert into t22 values ('2006-12-17');
insert into t33 values ('2006-12-17');
insert into t44 values (60,'2006-12-17');
insert into t55 values (60,'2006-12-17');
insert into t66 values (60,'2006-12-17');
+commit;
select * from t11 order by col1;
col1
2006-11-06
@@ -8543,6 +8697,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with quarter(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-01-03');
insert into t1 values ('2006-12-17');
insert into t2 values ('2006-01-03');
@@ -8551,6 +8706,7 @@ insert into t2 values ('2006-09-25');
insert into t3 values ('2006-01-03');
insert into t3 values ('2006-12-17');
insert into t3 values ('2006-09-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -8590,12 +8746,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-07-30' where col1='2006-01-03';
update t2 set col1='2006-07-30' where col1='2006-01-03';
update t3 set col1='2006-07-30' where col1='2006-01-03';
update t4 set col1='2006-07-30' where col1='2006-01-03';
update t5 set col1='2006-07-30' where col1='2006-01-03';
update t6 set col1='2006-07-30' where col1='2006-01-03';
+commit;
select * from t1 order by col1;
col1
2006-07-30
@@ -8799,12 +8957,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with quarter(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-12-17';
delete from t2 where col1='2006-12-17';
delete from t3 where col1='2006-12-17';
delete from t4 where col1='2006-12-17';
delete from t5 where col1='2006-12-17';
delete from t6 where col1='2006-12-17';
+commit;
select * from t1 order by col1;
col1
2006-07-30
@@ -8828,12 +8988,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-12-17');
insert into t2 values ('2006-12-17');
insert into t3 values ('2006-12-17');
insert into t4 values (60,'2006-12-17');
insert into t5 values (60,'2006-12-17');
insert into t6 values (60,'2006-12-17');
+commit;
select * from t1 order by col1;
col1
2006-07-30
@@ -8896,12 +9058,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with quarter(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-12-17';
delete from t22 where col1='2006-12-17';
delete from t33 where col1='2006-12-17';
delete from t44 where col1='2006-12-17';
delete from t55 where col1='2006-12-17';
delete from t66 where col1='2006-12-17';
+commit;
select * from t11 order by col1;
col1
2006-07-30
@@ -8925,12 +9089,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-12-17');
insert into t22 values ('2006-12-17');
insert into t33 values ('2006-12-17');
insert into t44 values (60,'2006-12-17');
insert into t55 values (60,'2006-12-17');
insert into t66 values (60,'2006-12-17');
+commit;
select * from t11 order by col1;
col1
2006-07-30
@@ -9006,523 +9172,6 @@ drop table if exists t44 ;
drop table if exists t55 ;
drop table if exists t66 ;
-------------------------------------------------------------------------
---- time_to_sec(col1)-(time_to_sec(col1)-20) in partition with coltype time
--------------------------------------------------------------------------
-drop table if exists t1 ;
-drop table if exists t2 ;
-drop table if exists t3 ;
-drop table if exists t4 ;
-drop table if exists t5 ;
-drop table if exists t6 ;
--------------------------------------------------------------------------
---- Create tables with time_to_sec(col1)-(time_to_sec(col1)-20)
--------------------------------------------------------------------------
-create table t1 (col1 time) engine='INNODB'
-partition by range(time_to_sec(col1)-(time_to_sec(col1)-20))
-(partition p0 values less than (15),
-partition p1 values less than maxvalue);
-create table t2 (col1 time) engine='INNODB'
-partition by list(time_to_sec(col1)-(time_to_sec(col1)-20))
-(partition p0 values in (0,1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30),
-partition p3 values in (31,32,33,34,35,36,37,38,39,40),
-partition p4 values in (41,42,43,44,45,46,47,48,49,50),
-partition p5 values in (51,52,53,54,55,56,57,58,59,60)
-);
-create table t3 (col1 time) engine='INNODB'
-partition by hash(time_to_sec(col1)-(time_to_sec(col1)-20));
-create table t4 (colint int, col1 time) engine='INNODB'
-partition by range(colint)
-subpartition by hash(time_to_sec(col1)-(time_to_sec(col1)-20)) subpartitions 2
-(partition p0 values less than (15),
-partition p1 values less than maxvalue);
-create table t5 (colint int, col1 time) engine='INNODB'
-partition by list(colint)
-subpartition by hash(time_to_sec(col1)-(time_to_sec(col1)-20)) subpartitions 2
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30),
-partition p3 values in (31,32,33,34,35,36,37,38,39,40),
-partition p4 values in (41,42,43,44,45,46,47,48,49,50),
-partition p5 values in (51,52,53,54,55,56,57,58,59,60)
-);
-create table t6 (colint int, col1 time) engine='INNODB'
-partition by range(colint)
-(partition p0 values less than (time_to_sec('18:30:14')-(time_to_sec('17:59:59'))),
-partition p1 values less than maxvalue);
--------------------------------------------------------------------------
---- Access tables with time_to_sec(col1)-(time_to_sec(col1)-20)
--------------------------------------------------------------------------
-insert into t1 values ('09:09:15');
-insert into t1 values ('14:30:45');
-insert into t2 values ('09:09:15');
-insert into t2 values ('14:30:45');
-insert into t2 values ('21:59:22');
-insert into t3 values ('09:09:15');
-insert into t3 values ('14:30:45');
-insert into t3 values ('21:59:22');
-load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t4;
-load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t5;
-load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t6;
-select time_to_sec(col1)-(time_to_sec(col1)-20) from t1 order by col1;
-time_to_sec(col1)-(time_to_sec(col1)-20)
-20
-20
-select * from t1 order by col1;
-col1
-09:09:15
-14:30:45
-select * from t2 order by col1;
-col1
-09:09:15
-14:30:45
-21:59:22
-select * from t3 order by col1;
-col1
-09:09:15
-14:30:45
-21:59:22
-select * from t4 order by colint;
-colint col1
-1 09:09:15
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t5 order by colint;
-colint col1
-1 09:09:15
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t6 order by colint;
-colint col1
-1 09:09:15
-2 04:30:01
-3 00:59:22
-4 05:30:34
-update t1 set col1='10:33:11' where col1='09:09:15';
-update t2 set col1='10:33:11' where col1='09:09:15';
-update t3 set col1='10:33:11' where col1='09:09:15';
-update t4 set col1='10:33:11' where col1='09:09:15';
-update t5 set col1='10:33:11' where col1='09:09:15';
-update t6 set col1='10:33:11' where col1='09:09:15';
-select * from t1 order by col1;
-col1
-10:33:11
-14:30:45
-select * from t2 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t3 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t4 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t5 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t6 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
--------------------------------------------------------------------------
---- Alter tables with time_to_sec(col1)-(time_to_sec(col1)-20)
--------------------------------------------------------------------------
-drop table if exists t11 ;
-drop table if exists t22 ;
-drop table if exists t33 ;
-drop table if exists t44 ;
-drop table if exists t55 ;
-drop table if exists t66 ;
-create table t11 engine='INNODB' as select * from t1;
-create table t22 engine='INNODB' as select * from t2;
-create table t33 engine='INNODB' as select * from t3;
-create table t44 engine='INNODB' as select * from t4;
-create table t55 engine='INNODB' as select * from t5;
-create table t66 engine='INNODB' as select * from t6;
-alter table t11
-partition by range(time_to_sec(col1)-(time_to_sec(col1)-20))
-(partition p0 values less than (15),
-partition p1 values less than maxvalue);
-alter table t22
-partition by list(time_to_sec(col1)-(time_to_sec(col1)-20))
-(partition p0 values in (0,1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30),
-partition p3 values in (31,32,33,34,35,36,37,38,39,40),
-partition p4 values in (41,42,43,44,45,46,47,48,49,50),
-partition p5 values in (51,52,53,54,55,56,57,58,59,60)
-);
-alter table t33
-partition by hash(time_to_sec(col1)-(time_to_sec(col1)-20));
-alter table t44
-partition by range(colint)
-subpartition by hash(time_to_sec(col1)-(time_to_sec(col1)-20)) subpartitions 2
-(partition p0 values less than (15),
-partition p1 values less than maxvalue);
-alter table t55
-partition by list(colint)
-subpartition by hash(time_to_sec(col1)-(time_to_sec(col1)-20)) subpartitions 2
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30),
-partition p3 values in (31,32,33,34,35,36,37,38,39,40),
-partition p4 values in (41,42,43,44,45,46,47,48,49,50),
-partition p5 values in (51,52,53,54,55,56,57,58,59,60)
-);
-alter table t66
-partition by range(colint)
-(partition p0 values less than (time_to_sec('18:30:14')-(time_to_sec('17:59:59'))),
-partition p1 values less than maxvalue);
-select * from t11 order by col1;
-col1
-10:33:11
-14:30:45
-select * from t22 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t33 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t44 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t55 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t66 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
----------------------------
----- some alter table begin
----------------------------
-alter table t11
-reorganize partition p0,p1 into
-(partition s1 values less than maxvalue);
-select * from t11 order by col1;
-col1
-10:33:11
-14:30:45
-alter table t11
-reorganize partition s1 into
-(partition p0 values less than (15),
-partition p1 values less than maxvalue);
-select * from t11 order by col1;
-col1
-10:33:11
-14:30:45
-alter table t55
-partition by list(colint)
-subpartition by hash(time_to_sec(col1)-(time_to_sec(col1)-20)) subpartitions 5
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30),
-partition p3 values in (31,32,33,34,35,36,37,38,39,40),
-partition p4 values in (41,42,43,44,45,46,47,48,49,50),
-partition p5 values in (51,52,53,54,55,56,57,58,59,60)
-);
-show create table t55;
-Table Create Table
-t55 CREATE TABLE `t55` (
- `colint` int(11) DEFAULT NULL,
- `col1` time DEFAULT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY LIST (colint)
-SUBPARTITION BY HASH (time_to_sec(col1)-(time_to_sec(col1)-20))
-SUBPARTITIONS 5
-(PARTITION p0 VALUES IN (1,2,3,4,5,6,7,8,9,10) ENGINE = InnoDB,
- PARTITION p1 VALUES IN (11,12,13,14,15,16,17,18,19,20) ENGINE = InnoDB,
- PARTITION p2 VALUES IN (21,22,23,24,25,26,27,28,29,30) ENGINE = InnoDB,
- PARTITION p3 VALUES IN (31,32,33,34,35,36,37,38,39,40) ENGINE = InnoDB,
- PARTITION p4 VALUES IN (41,42,43,44,45,46,47,48,49,50) ENGINE = InnoDB,
- PARTITION p5 VALUES IN (51,52,53,54,55,56,57,58,59,60) ENGINE = InnoDB) */
-select * from t55 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-alter table t66
-reorganize partition p0,p1 into
-(partition s1 values less than maxvalue);
-select * from t66 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-alter table t66
-reorganize partition s1 into
-(partition p0 values less than (time_to_sec('18:30:14')-(time_to_sec('17:59:59'))),
-partition p1 values less than maxvalue);
-select * from t66 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-alter table t66
-reorganize partition p0,p1 into
-(partition s1 values less than maxvalue);
-select * from t66 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-alter table t66
-reorganize partition s1 into
-(partition p0 values less than (time_to_sec('18:30:14')-(time_to_sec('17:59:59'))),
-partition p1 values less than maxvalue);
-select * from t66 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
--------------------------------------------------------------------------
---- Delete rows and partitions of tables with time_to_sec(col1)-(time_to_sec(col1)-20)
--------------------------------------------------------------------------
-delete from t1 where col1='14:30:45';
-delete from t2 where col1='14:30:45';
-delete from t3 where col1='14:30:45';
-delete from t4 where col1='14:30:45';
-delete from t5 where col1='14:30:45';
-delete from t6 where col1='14:30:45';
-select * from t1 order by col1;
-col1
-10:33:11
-select * from t2 order by col1;
-col1
-10:33:11
-21:59:22
-select * from t3 order by col1;
-col1
-10:33:11
-21:59:22
-select * from t4 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t5 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-insert into t1 values ('14:30:45');
-insert into t2 values ('14:30:45');
-insert into t3 values ('14:30:45');
-insert into t4 values (60,'14:30:45');
-insert into t5 values (60,'14:30:45');
-insert into t6 values (60,'14:30:45');
-select * from t1 order by col1;
-col1
-10:33:11
-14:30:45
-select * from t2 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t3 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t4 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-60 14:30:45
-select * from t5 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-60 14:30:45
-select * from t6 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-60 14:30:45
-alter table t1 drop partition p0;
-alter table t2 drop partition p0;
-alter table t4 drop partition p0;
-alter table t5 drop partition p0;
-alter table t6 drop partition p0;
-select * from t1 order by col1;
-col1
-10:33:11
-14:30:45
-select * from t2 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t3 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t4 order by colint;
-colint col1
-60 14:30:45
-select * from t5 order by colint;
-colint col1
-60 14:30:45
-select * from t6 order by colint;
-colint col1
--------------------------------------------------------------------------
---- Delete rows and partitions of tables with time_to_sec(col1)-(time_to_sec(col1)-20)
--------------------------------------------------------------------------
-delete from t11 where col1='14:30:45';
-delete from t22 where col1='14:30:45';
-delete from t33 where col1='14:30:45';
-delete from t44 where col1='14:30:45';
-delete from t55 where col1='14:30:45';
-delete from t66 where col1='14:30:45';
-select * from t11 order by col1;
-col1
-10:33:11
-select * from t22 order by col1;
-col1
-10:33:11
-21:59:22
-select * from t33 order by col1;
-col1
-10:33:11
-21:59:22
-select * from t44 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t55 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-insert into t11 values ('14:30:45');
-insert into t22 values ('14:30:45');
-insert into t33 values ('14:30:45');
-insert into t44 values (60,'14:30:45');
-insert into t55 values (60,'14:30:45');
-insert into t66 values (60,'14:30:45');
-select * from t11 order by col1;
-col1
-10:33:11
-14:30:45
-select * from t22 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t33 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t44 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-60 14:30:45
-select * from t55 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-60 14:30:45
-select * from t66 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-60 14:30:45
-alter table t11 drop partition p0;
-alter table t22 drop partition p0;
-alter table t44 drop partition p0;
-alter table t55 drop partition p0;
-alter table t66 drop partition p0;
-select * from t11 order by col1;
-col1
-10:33:11
-14:30:45
-select * from t22 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t33 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t44 order by colint;
-colint col1
-60 14:30:45
-select * from t55 order by colint;
-colint col1
-60 14:30:45
-select * from t66 order by colint;
-colint col1
--------------------------
----- some alter table end
--------------------------
-drop table if exists t1 ;
-drop table if exists t2 ;
-drop table if exists t3 ;
-drop table if exists t4 ;
-drop table if exists t5 ;
-drop table if exists t6 ;
-drop table if exists t11 ;
-drop table if exists t22 ;
-drop table if exists t33 ;
-drop table if exists t44 ;
-drop table if exists t55 ;
-drop table if exists t66 ;
--------------------------------------------------------------------------
--- weekday(col1) in partition with coltype date
-------------------------------------------------------------------------
drop table if exists t1 ;
@@ -9571,6 +9220,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with weekday(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-12-03');
insert into t1 values ('2006-11-17');
insert into t2 values ('2006-12-03');
@@ -9579,6 +9229,7 @@ insert into t2 values ('2006-05-25');
insert into t3 values ('2006-12-03');
insert into t3 values ('2006-11-17');
insert into t3 values ('2006-05-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -9618,12 +9269,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-02-06' where col1='2006-12-03';
update t2 set col1='2006-02-06' where col1='2006-12-03';
update t3 set col1='2006-02-06' where col1='2006-12-03';
update t4 set col1='2006-02-06' where col1='2006-12-03';
update t5 set col1='2006-02-06' where col1='2006-12-03';
update t6 set col1='2006-02-06' where col1='2006-12-03';
+commit;
select * from t1 order by col1;
col1
2006-02-06
@@ -9827,12 +9480,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with weekday(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-11-17';
delete from t2 where col1='2006-11-17';
delete from t3 where col1='2006-11-17';
delete from t4 where col1='2006-11-17';
delete from t5 where col1='2006-11-17';
delete from t6 where col1='2006-11-17';
+commit;
select * from t1 order by col1;
col1
2006-02-06
@@ -9856,12 +9511,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-11-17');
insert into t2 values ('2006-11-17');
insert into t3 values ('2006-11-17');
insert into t4 values (60,'2006-11-17');
insert into t5 values (60,'2006-11-17');
insert into t6 values (60,'2006-11-17');
+commit;
select * from t1 order by col1;
col1
2006-02-06
@@ -9923,12 +9580,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with weekday(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-11-17';
delete from t22 where col1='2006-11-17';
delete from t33 where col1='2006-11-17';
delete from t44 where col1='2006-11-17';
delete from t55 where col1='2006-11-17';
delete from t66 where col1='2006-11-17';
+commit;
select * from t11 order by col1;
col1
2006-02-06
@@ -9952,12 +9611,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-11-17');
insert into t22 values ('2006-11-17');
insert into t33 values ('2006-11-17');
insert into t44 values (60,'2006-11-17');
insert into t55 values (60,'2006-11-17');
insert into t66 values (60,'2006-11-17');
+commit;
select * from t11 order by col1;
col1
2006-02-06
@@ -10080,6 +9741,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with year(col1)-1990
-------------------------------------------------------------------------
+begin;
insert into t1 values ('1996-01-03');
insert into t1 values ('2000-02-17');
insert into t2 values ('1996-01-03');
@@ -10088,6 +9750,7 @@ insert into t2 values ('2004-05-25');
insert into t3 values ('1996-01-03');
insert into t3 values ('2000-02-17');
insert into t3 values ('2004-05-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -10127,12 +9790,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2002-02-15' where col1='1996-01-03';
update t2 set col1='2002-02-15' where col1='1996-01-03';
update t3 set col1='2002-02-15' where col1='1996-01-03';
update t4 set col1='2002-02-15' where col1='1996-01-03';
update t5 set col1='2002-02-15' where col1='1996-01-03';
update t6 set col1='2002-02-15' where col1='1996-01-03';
+commit;
select * from t1 order by col1;
col1
2000-02-17
@@ -10336,12 +10001,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with year(col1)-1990
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2000-02-17';
delete from t2 where col1='2000-02-17';
delete from t3 where col1='2000-02-17';
delete from t4 where col1='2000-02-17';
delete from t5 where col1='2000-02-17';
delete from t6 where col1='2000-02-17';
+commit;
select * from t1 order by col1;
col1
2002-02-15
@@ -10365,12 +10032,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2000-02-17');
insert into t2 values ('2000-02-17');
insert into t3 values ('2000-02-17');
insert into t4 values (60,'2000-02-17');
insert into t5 values (60,'2000-02-17');
insert into t6 values (60,'2000-02-17');
+commit;
select * from t1 order by col1;
col1
2000-02-17
@@ -10434,12 +10103,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with year(col1)-1990
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2000-02-17';
delete from t22 where col1='2000-02-17';
delete from t33 where col1='2000-02-17';
delete from t44 where col1='2000-02-17';
delete from t55 where col1='2000-02-17';
delete from t66 where col1='2000-02-17';
+commit;
select * from t11 order by col1;
col1
2002-02-15
@@ -10463,12 +10134,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2000-02-17');
insert into t22 values ('2000-02-17');
insert into t33 values ('2000-02-17');
insert into t44 values (60,'2000-02-17');
insert into t55 values (60,'2000-02-17');
insert into t66 values (60,'2000-02-17');
+commit;
select * from t11 order by col1;
col1
2000-02-17
@@ -10593,6 +10266,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with yearweek(col1)-200600
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-01-03');
insert into t1 values ('2006-08-17');
insert into t2 values ('2006-01-03');
@@ -10601,6 +10275,7 @@ insert into t2 values ('2006-03-25');
insert into t3 values ('2006-01-03');
insert into t3 values ('2006-08-17');
insert into t3 values ('2006-03-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -10640,12 +10315,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-11-15' where col1='2006-01-03';
update t2 set col1='2006-11-15' where col1='2006-01-03';
update t3 set col1='2006-11-15' where col1='2006-01-03';
update t4 set col1='2006-11-15' where col1='2006-01-03';
update t5 set col1='2006-11-15' where col1='2006-01-03';
update t6 set col1='2006-11-15' where col1='2006-01-03';
+commit;
select * from t1 order by col1;
col1
2006-08-17
@@ -10849,12 +10526,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with yearweek(col1)-200600
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-08-17';
delete from t2 where col1='2006-08-17';
delete from t3 where col1='2006-08-17';
delete from t4 where col1='2006-08-17';
delete from t5 where col1='2006-08-17';
delete from t6 where col1='2006-08-17';
+commit;
select * from t1 order by col1;
col1
2006-11-15
@@ -10878,12 +10557,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-08-17');
insert into t2 values ('2006-08-17');
insert into t3 values ('2006-08-17');
insert into t4 values (60,'2006-08-17');
insert into t5 values (60,'2006-08-17');
insert into t6 values (60,'2006-08-17');
+commit;
select * from t1 order by col1;
col1
2006-08-17
@@ -10950,12 +10631,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with yearweek(col1)-200600
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-08-17';
delete from t22 where col1='2006-08-17';
delete from t33 where col1='2006-08-17';
delete from t44 where col1='2006-08-17';
delete from t55 where col1='2006-08-17';
delete from t66 where col1='2006-08-17';
+commit;
select * from t11 order by col1;
col1
2006-11-15
@@ -10979,12 +10662,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-08-17');
insert into t22 values ('2006-08-17');
insert into t33 values ('2006-08-17');
insert into t44 values (60,'2006-08-17');
insert into t55 values (60,'2006-08-17');
insert into t66 values (60,'2006-08-17');
+commit;
select * from t11 order by col1;
col1
2006-08-17
diff --git a/mysql-test/suite/parts/r/part_supported_sql_func_myisam.result b/mysql-test/suite/parts/r/part_supported_sql_func_myisam.result
index 3cd8e10a4f3..e4bf955f16a 100644
--- a/mysql-test/suite/parts/r/part_supported_sql_func_myisam.result
+++ b/mysql-test/suite/parts/r/part_supported_sql_func_myisam.result
@@ -47,6 +47,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with abs(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values (5 );
insert into t1 values (13 );
insert into t2 values (5 );
@@ -55,6 +56,7 @@ insert into t2 values (17 );
insert into t3 values (5 );
insert into t3 values (13 );
insert into t3 values (17 );
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_int.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_int.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_int.inc' into table t6;
@@ -217,12 +219,14 @@ colint col1
50 56
51 34
55 123
+begin;
update t1 set col1=15 where col1=5 ;
update t2 set col1=15 where col1=5 ;
update t3 set col1=15 where col1=5 ;
update t4 set col1=15 where col1=5 ;
update t5 set col1=15 where col1=5 ;
update t6 set col1=15 where col1=5 ;
+commit;
select * from t1 order by col1;
col1
13
@@ -877,12 +881,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with abs(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1=13 ;
delete from t2 where col1=13 ;
delete from t3 where col1=13 ;
delete from t4 where col1=13 ;
delete from t5 where col1=13 ;
delete from t6 where col1=13 ;
+commit;
select * from t1 order by col1;
col1
15
@@ -986,12 +992,14 @@ colint col1
50 56
51 34
55 123
+begin;
insert into t1 values (13 );
insert into t2 values (13 );
insert into t3 values (13 );
insert into t4 values (60,13 );
insert into t5 values (60,13 );
insert into t6 values (60,13 );
+commit;
select * from t1 order by col1;
col1
13
@@ -1274,12 +1282,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with abs(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1=13 ;
delete from t22 where col1=13 ;
delete from t33 where col1=13 ;
delete from t44 where col1=13 ;
delete from t55 where col1=13 ;
delete from t66 where col1=13 ;
+commit;
select * from t11 order by col1;
col1
15
@@ -1383,12 +1393,14 @@ colint col1
50 56
51 34
55 123
+begin;
insert into t11 values (13 );
insert into t22 values (13 );
insert into t33 values (13 );
insert into t44 values (60,13 );
insert into t55 values (60,13 );
insert into t66 values (60,13 );
+commit;
select * from t11 order by col1;
col1
13
@@ -1732,6 +1744,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with mod(col1,10)
-------------------------------------------------------------------------
+begin;
insert into t1 values (5);
insert into t1 values (19);
insert into t2 values (5);
@@ -1740,6 +1753,7 @@ insert into t2 values (17);
insert into t3 values (5);
insert into t3 values (19);
insert into t3 values (17);
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_int.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_int.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_int.inc' into table t6;
@@ -1902,12 +1916,14 @@ colint col1
50 56
51 34
55 123
+begin;
update t1 set col1=15 where col1=5;
update t2 set col1=15 where col1=5;
update t3 set col1=15 where col1=5;
update t4 set col1=15 where col1=5;
update t5 set col1=15 where col1=5;
update t6 set col1=15 where col1=5;
+commit;
select * from t1 order by col1;
col1
15
@@ -2562,12 +2578,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with mod(col1,10)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1=19;
delete from t2 where col1=19;
delete from t3 where col1=19;
delete from t4 where col1=19;
delete from t5 where col1=19;
delete from t6 where col1=19;
+commit;
select * from t1 order by col1;
col1
15
@@ -2673,12 +2691,14 @@ colint col1
50 56
51 34
55 123
+begin;
insert into t1 values (19);
insert into t2 values (19);
insert into t3 values (19);
insert into t4 values (60,19);
insert into t5 values (60,19);
insert into t6 values (60,19);
+commit;
select * from t1 order by col1;
col1
15
@@ -2970,12 +2990,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with mod(col1,10)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1=19;
delete from t22 where col1=19;
delete from t33 where col1=19;
delete from t44 where col1=19;
delete from t55 where col1=19;
delete from t66 where col1=19;
+commit;
select * from t11 order by col1;
col1
15
@@ -3081,12 +3103,14 @@ colint col1
50 56
51 34
55 123
+begin;
insert into t11 values (19);
insert into t22 values (19);
insert into t33 values (19);
insert into t44 values (60,19);
insert into t55 values (60,19);
insert into t66 values (60,19);
+commit;
select * from t11 order by col1;
col1
15
@@ -3439,6 +3463,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with day(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-02-03');
insert into t1 values ('2006-01-17');
insert into t2 values ('2006-02-03');
@@ -3447,6 +3472,7 @@ insert into t2 values ('2006-01-25');
insert into t3 values ('2006-02-03');
insert into t3 values ('2006-01-17');
insert into t3 values ('2006-01-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -3486,12 +3512,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-02-05' where col1='2006-02-03';
update t2 set col1='2006-02-05' where col1='2006-02-03';
update t3 set col1='2006-02-05' where col1='2006-02-03';
update t4 set col1='2006-02-05' where col1='2006-02-03';
update t5 set col1='2006-02-05' where col1='2006-02-03';
update t6 set col1='2006-02-05' where col1='2006-02-03';
+commit;
select * from t1 order by col1;
col1
2006-01-17
@@ -3695,12 +3723,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with day(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-01-17';
delete from t2 where col1='2006-01-17';
delete from t3 where col1='2006-01-17';
delete from t4 where col1='2006-01-17';
delete from t5 where col1='2006-01-17';
delete from t6 where col1='2006-01-17';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -3722,12 +3752,14 @@ colint col1
1 2006-02-05
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-01-17');
insert into t2 values ('2006-01-17');
insert into t3 values ('2006-01-17');
insert into t4 values (60,'2006-01-17');
insert into t5 values (60,'2006-01-17');
insert into t6 values (60,'2006-01-17');
+commit;
select * from t1 order by col1;
col1
2006-01-17
@@ -3789,12 +3821,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with day(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-01-17';
delete from t22 where col1='2006-01-17';
delete from t33 where col1='2006-01-17';
delete from t44 where col1='2006-01-17';
delete from t55 where col1='2006-01-17';
delete from t66 where col1='2006-01-17';
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -3816,12 +3850,14 @@ colint col1
1 2006-02-05
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-01-17');
insert into t22 values ('2006-01-17');
insert into t33 values ('2006-01-17');
insert into t44 values (60,'2006-01-17');
insert into t55 values (60,'2006-01-17');
insert into t66 values (60,'2006-01-17');
+commit;
select * from t11 order by col1;
col1
2006-01-17
@@ -3944,6 +3980,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with dayofmonth(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-02-03');
insert into t1 values ('2006-01-17');
insert into t2 values ('2006-02-03');
@@ -3952,6 +3989,7 @@ insert into t2 values ('2006-01-25');
insert into t3 values ('2006-02-03');
insert into t3 values ('2006-01-17');
insert into t3 values ('2006-01-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -3991,12 +4029,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-02-05' where col1='2006-02-03';
update t2 set col1='2006-02-05' where col1='2006-02-03';
update t3 set col1='2006-02-05' where col1='2006-02-03';
update t4 set col1='2006-02-05' where col1='2006-02-03';
update t5 set col1='2006-02-05' where col1='2006-02-03';
update t6 set col1='2006-02-05' where col1='2006-02-03';
+commit;
select * from t1 order by col1;
col1
2006-01-17
@@ -4200,12 +4240,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with dayofmonth(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-01-17';
delete from t2 where col1='2006-01-17';
delete from t3 where col1='2006-01-17';
delete from t4 where col1='2006-01-17';
delete from t5 where col1='2006-01-17';
delete from t6 where col1='2006-01-17';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -4227,12 +4269,14 @@ colint col1
1 2006-02-05
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-01-17');
insert into t2 values ('2006-01-17');
insert into t3 values ('2006-01-17');
insert into t4 values (60,'2006-01-17');
insert into t5 values (60,'2006-01-17');
insert into t6 values (60,'2006-01-17');
+commit;
select * from t1 order by col1;
col1
2006-01-17
@@ -4294,12 +4338,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with dayofmonth(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-01-17';
delete from t22 where col1='2006-01-17';
delete from t33 where col1='2006-01-17';
delete from t44 where col1='2006-01-17';
delete from t55 where col1='2006-01-17';
delete from t66 where col1='2006-01-17';
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -4321,12 +4367,14 @@ colint col1
1 2006-02-05
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-01-17');
insert into t22 values ('2006-01-17');
insert into t33 values ('2006-01-17');
insert into t44 values (60,'2006-01-17');
insert into t55 values (60,'2006-01-17');
insert into t66 values (60,'2006-01-17');
+commit;
select * from t11 order by col1;
col1
2006-01-17
@@ -4449,6 +4497,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with dayofweek(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-01-03');
insert into t1 values ('2006-02-17');
insert into t2 values ('2006-01-03');
@@ -4457,6 +4506,7 @@ insert into t2 values ('2006-01-25');
insert into t3 values ('2006-01-03');
insert into t3 values ('2006-02-17');
insert into t3 values ('2006-01-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -4496,12 +4546,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-02-05' where col1='2006-01-03';
update t2 set col1='2006-02-05' where col1='2006-01-03';
update t3 set col1='2006-02-05' where col1='2006-01-03';
update t4 set col1='2006-02-05' where col1='2006-01-03';
update t5 set col1='2006-02-05' where col1='2006-01-03';
update t6 set col1='2006-02-05' where col1='2006-01-03';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -4705,12 +4757,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with dayofweek(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-02-17';
delete from t2 where col1='2006-02-17';
delete from t3 where col1='2006-02-17';
delete from t4 where col1='2006-02-17';
delete from t5 where col1='2006-02-17';
delete from t6 where col1='2006-02-17';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -4734,12 +4788,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-02-17');
insert into t2 values ('2006-02-17');
insert into t3 values ('2006-02-17');
insert into t4 values (60,'2006-02-17');
insert into t5 values (60,'2006-02-17');
insert into t6 values (60,'2006-02-17');
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -4805,12 +4861,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with dayofweek(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-02-17';
delete from t22 where col1='2006-02-17';
delete from t33 where col1='2006-02-17';
delete from t44 where col1='2006-02-17';
delete from t55 where col1='2006-02-17';
delete from t66 where col1='2006-02-17';
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -4834,12 +4892,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-02-17');
insert into t22 values ('2006-02-17');
insert into t33 values ('2006-02-17');
insert into t44 values (60,'2006-02-17');
insert into t55 values (60,'2006-02-17');
insert into t66 values (60,'2006-02-17');
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -4966,6 +5026,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with dayofyear(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-01-03');
insert into t1 values ('2006-01-17');
insert into t2 values ('2006-01-03');
@@ -4974,6 +5035,7 @@ insert into t2 values ('2006-02-25');
insert into t3 values ('2006-01-03');
insert into t3 values ('2006-01-17');
insert into t3 values ('2006-02-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -5013,12 +5075,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-02-05' where col1='2006-01-03';
update t2 set col1='2006-02-05' where col1='2006-01-03';
update t3 set col1='2006-02-05' where col1='2006-01-03';
update t4 set col1='2006-02-05' where col1='2006-01-03';
update t5 set col1='2006-02-05' where col1='2006-01-03';
update t6 set col1='2006-02-05' where col1='2006-01-03';
+commit;
select * from t1 order by col1;
col1
2006-01-17
@@ -5222,12 +5286,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with dayofyear(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-01-17';
delete from t2 where col1='2006-01-17';
delete from t3 where col1='2006-01-17';
delete from t4 where col1='2006-01-17';
delete from t5 where col1='2006-01-17';
delete from t6 where col1='2006-01-17';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -5249,12 +5315,14 @@ colint col1
1 2006-02-03
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-01-17');
insert into t2 values ('2006-01-17');
insert into t3 values ('2006-01-17');
insert into t4 values (60,'2006-01-17');
insert into t5 values (60,'2006-01-17');
insert into t6 values (60,'2006-01-17');
+commit;
select * from t1 order by col1;
col1
2006-01-17
@@ -5317,12 +5385,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with dayofyear(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-01-17';
delete from t22 where col1='2006-01-17';
delete from t33 where col1='2006-01-17';
delete from t44 where col1='2006-01-17';
delete from t55 where col1='2006-01-17';
delete from t66 where col1='2006-01-17';
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -5344,12 +5414,14 @@ colint col1
1 2006-02-03
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-01-17');
insert into t22 values ('2006-01-17');
insert into t33 values ('2006-01-17');
insert into t44 values (60,'2006-01-17');
insert into t55 values (60,'2006-01-17');
insert into t66 values (60,'2006-01-17');
+commit;
select * from t11 order by col1;
col1
2006-01-17
@@ -5473,6 +5545,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with extract(month from col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-01-03');
insert into t1 values ('2006-02-17');
insert into t2 values ('2006-01-03');
@@ -5481,6 +5554,7 @@ insert into t2 values ('2006-01-25');
insert into t3 values ('2006-01-03');
insert into t3 values ('2006-02-17');
insert into t3 values ('2006-01-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -5520,12 +5594,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-02-05' where col1='2006-01-03';
update t2 set col1='2006-02-05' where col1='2006-01-03';
update t3 set col1='2006-02-05' where col1='2006-01-03';
update t4 set col1='2006-02-05' where col1='2006-01-03';
update t5 set col1='2006-02-05' where col1='2006-01-03';
update t6 set col1='2006-02-05' where col1='2006-01-03';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -5729,12 +5805,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with extract(month from col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-02-17';
delete from t2 where col1='2006-02-17';
delete from t3 where col1='2006-02-17';
delete from t4 where col1='2006-02-17';
delete from t5 where col1='2006-02-17';
delete from t6 where col1='2006-02-17';
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -5758,12 +5836,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-02-17');
insert into t2 values ('2006-02-17');
insert into t3 values ('2006-02-17');
insert into t4 values (60,'2006-02-17');
insert into t5 values (60,'2006-02-17');
insert into t6 values (60,'2006-02-17');
+commit;
select * from t1 order by col1;
col1
2006-02-05
@@ -5824,12 +5904,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with extract(month from col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-02-17';
delete from t22 where col1='2006-02-17';
delete from t33 where col1='2006-02-17';
delete from t44 where col1='2006-02-17';
delete from t55 where col1='2006-02-17';
delete from t66 where col1='2006-02-17';
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -5853,12 +5935,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-02-17');
insert into t22 values ('2006-02-17');
insert into t33 values ('2006-02-17');
insert into t44 values (60,'2006-02-17');
insert into t55 values (60,'2006-02-17');
insert into t66 values (60,'2006-02-17');
+commit;
select * from t11 order by col1;
col1
2006-02-05
@@ -5980,6 +6064,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with hour(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('09:09');
insert into t1 values ('14:30');
insert into t2 values ('09:09');
@@ -5988,6 +6073,7 @@ insert into t2 values ('21:59');
insert into t3 values ('09:09');
insert into t3 values ('14:30');
insert into t3 values ('21:59');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t6;
@@ -6027,12 +6113,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
update t1 set col1='10:30' where col1='09:09';
update t2 set col1='10:30' where col1='09:09';
update t3 set col1='10:30' where col1='09:09';
update t4 set col1='10:30' where col1='09:09';
update t5 set col1='10:30' where col1='09:09';
update t6 set col1='10:30' where col1='09:09';
+commit;
select * from t1 order by col1;
col1
10:30:00
@@ -6236,12 +6324,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with hour(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='14:30';
delete from t2 where col1='14:30';
delete from t3 where col1='14:30';
delete from t4 where col1='14:30';
delete from t5 where col1='14:30';
delete from t6 where col1='14:30';
+commit;
select * from t1 order by col1;
col1
10:30:00
@@ -6265,12 +6355,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
insert into t1 values ('14:30');
insert into t2 values ('14:30');
insert into t3 values ('14:30');
insert into t4 values (60,'14:30');
insert into t5 values (60,'14:30');
insert into t6 values (60,'14:30');
+commit;
select * from t1 order by col1;
col1
10:30:00
@@ -6334,12 +6426,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with hour(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='14:30';
delete from t22 where col1='14:30';
delete from t33 where col1='14:30';
delete from t44 where col1='14:30';
delete from t55 where col1='14:30';
delete from t66 where col1='14:30';
+commit;
select * from t11 order by col1;
col1
10:30:00
@@ -6363,12 +6457,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
insert into t11 values ('14:30');
insert into t22 values ('14:30');
insert into t33 values ('14:30');
insert into t44 values (60,'14:30');
insert into t55 values (60,'14:30');
insert into t66 values (60,'14:30');
+commit;
select * from t11 order by col1;
col1
10:30:00
@@ -6445,7 +6541,7 @@ drop table if exists t44 ;
drop table if exists t55 ;
drop table if exists t66 ;
-------------------------------------------------------------------------
---- microsecond(col1) in partition with coltype time
+--- microsecond(col1) in partition with coltype time(6)
-------------------------------------------------------------------------
drop table if exists t1 ;
drop table if exists t2 ;
@@ -6456,11 +6552,11 @@ drop table if exists t6 ;
-------------------------------------------------------------------------
--- Create tables with microsecond(col1)
-------------------------------------------------------------------------
-create table t1 (col1 time) engine='MYISAM'
+create table t1 (col1 time(6)) engine='MYISAM'
partition by range(microsecond(col1))
(partition p0 values less than (15),
partition p1 values less than maxvalue);
-create table t2 (col1 time) engine='MYISAM'
+create table t2 (col1 time(6)) engine='MYISAM'
partition by list(microsecond(col1))
(partition p0 values in (0,1,2,3,4,5,6,7,8,9,10),
partition p1 values in (11,12,13,14,15,16,17,18,19,20),
@@ -6469,14 +6565,14 @@ partition p3 values in (31,32,33,34,35,36,37,38,39,40),
partition p4 values in (41,42,43,44,45,46,47,48,49,50),
partition p5 values in (51,52,53,54,55,56,57,58,59,60)
);
-create table t3 (col1 time) engine='MYISAM'
+create table t3 (col1 time(6)) engine='MYISAM'
partition by hash(microsecond(col1));
-create table t4 (colint int, col1 time) engine='MYISAM'
+create table t4 (colint int, col1 time(6)) engine='MYISAM'
partition by range(colint)
subpartition by hash(microsecond(col1)) subpartitions 2
(partition p0 values less than (15),
partition p1 values less than maxvalue);
-create table t5 (colint int, col1 time) engine='MYISAM'
+create table t5 (colint int, col1 time(6)) engine='MYISAM'
partition by list(colint)
subpartition by hash(microsecond(col1)) subpartitions 2
(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
@@ -6486,13 +6582,14 @@ partition p3 values in (31,32,33,34,35,36,37,38,39,40),
partition p4 values in (41,42,43,44,45,46,47,48,49,50),
partition p5 values in (51,52,53,54,55,56,57,58,59,60)
);
-create table t6 (colint int, col1 time) engine='MYISAM'
+create table t6 (colint int, col1 time(6)) engine='MYISAM'
partition by range(colint)
(partition p0 values less than (microsecond('10:30:10.000010')),
partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with microsecond(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('09:09:15.000002');
insert into t1 values ('04:30:01.000018');
insert into t2 values ('09:09:15.000002');
@@ -6501,83 +6598,86 @@ insert into t2 values ('00:59:22.000024');
insert into t3 values ('09:09:15.000002');
insert into t3 values ('04:30:01.000018');
insert into t3 values ('00:59:22.000024');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t6;
select microsecond(col1) from t1 order by col1;
microsecond(col1)
-0
-0
+18
+2
select * from t1 order by col1;
col1
-04:30:01
-09:09:15
+04:30:01.000018
+09:09:15.000002
select * from t2 order by col1;
col1
-00:59:22
-04:30:01
-09:09:15
+00:59:22.000024
+04:30:01.000018
+09:09:15.000002
select * from t3 order by col1;
col1
-00:59:22
-04:30:01
-09:09:15
+00:59:22.000024
+04:30:01.000018
+09:09:15.000002
select * from t4 order by colint;
colint col1
-1 09:09:15
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 09:09:15.000002
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
select * from t5 order by colint;
colint col1
-1 09:09:15
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 09:09:15.000002
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
select * from t6 order by colint;
colint col1
-1 09:09:15
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 09:09:15.000002
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
+begin;
update t1 set col1='05:30:34.000037' where col1='09:09:15.000002';
update t2 set col1='05:30:34.000037' where col1='09:09:15.000002';
update t3 set col1='05:30:34.000037' where col1='09:09:15.000002';
update t4 set col1='05:30:34.000037' where col1='09:09:15.000002';
update t5 set col1='05:30:34.000037' where col1='09:09:15.000002';
update t6 set col1='05:30:34.000037' where col1='09:09:15.000002';
+commit;
select * from t1 order by col1;
col1
-04:30:01
-05:30:34
+04:30:01.000018
+05:30:34.000037
select * from t2 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t3 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t4 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
select * from t5 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
select * from t6 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
-------------------------------------------------------------------------
--- Alter tables with microsecond(col1)
-------------------------------------------------------------------------
@@ -6629,36 +6729,36 @@ partition by range(colint)
partition p1 values less than maxvalue);
select * from t11 order by col1;
col1
-04:30:01
-05:30:34
+04:30:01.000018
+05:30:34.000037
select * from t22 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t33 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t44 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
select * from t55 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
select * from t66 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
---------------------------
---- some alter table begin
---------------------------
@@ -6667,16 +6767,16 @@ reorganize partition p0,p1 into
(partition s1 values less than maxvalue);
select * from t11 order by col1;
col1
-04:30:01
-05:30:34
+04:30:01.000018
+05:30:34.000037
alter table t11
reorganize partition s1 into
(partition p0 values less than (15),
partition p1 values less than maxvalue);
select * from t11 order by col1;
col1
-04:30:01
-05:30:34
+04:30:01.000018
+05:30:34.000037
alter table t55
partition by list(colint)
subpartition by hash(microsecond(col1)) subpartitions 5
@@ -6691,7 +6791,7 @@ show create table t55;
Table Create Table
t55 CREATE TABLE `t55` (
`colint` int(11) DEFAULT NULL,
- `col1` time DEFAULT NULL
+ `col1` time(6) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
/*!50100 PARTITION BY LIST (colint)
SUBPARTITION BY HASH (microsecond(col1))
@@ -6704,116 +6804,120 @@ SUBPARTITIONS 5
PARTITION p5 VALUES IN (51,52,53,54,55,56,57,58,59,60) ENGINE = MyISAM) */
select * from t55 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
alter table t66
reorganize partition p0,p1 into
(partition s1 values less than maxvalue);
select * from t66 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
alter table t66
reorganize partition s1 into
(partition p0 values less than (microsecond('10:30:10.000010')),
partition p1 values less than maxvalue);
select * from t66 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
alter table t66
reorganize partition p0,p1 into
(partition s1 values less than maxvalue);
select * from t66 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
alter table t66
reorganize partition s1 into
(partition p0 values less than (microsecond('10:30:10.000010')),
partition p1 values less than maxvalue);
select * from t66 order by colint;
colint col1
-1 05:30:34
-2 04:30:01
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+2 04:30:01.000018
+3 00:59:22.000024
+4 05:30:34.000037
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with microsecond(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='04:30:01.000018';
delete from t2 where col1='04:30:01.000018';
delete from t3 where col1='04:30:01.000018';
delete from t4 where col1='04:30:01.000018';
delete from t5 where col1='04:30:01.000018';
delete from t6 where col1='04:30:01.000018';
+commit;
select * from t1 order by col1;
col1
-05:30:34
+05:30:34.000037
select * from t2 order by col1;
col1
-00:59:22
-05:30:34
+00:59:22.000024
+05:30:34.000037
select * from t3 order by col1;
col1
-00:59:22
-05:30:34
+00:59:22.000024
+05:30:34.000037
select * from t4 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
select * from t5 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+begin;
insert into t1 values ('04:30:01.000018');
insert into t2 values ('04:30:01.000018');
insert into t3 values ('04:30:01.000018');
insert into t4 values (60,'04:30:01.000018');
insert into t5 values (60,'04:30:01.000018');
insert into t6 values (60,'04:30:01.000018');
+commit;
select * from t1 order by col1;
col1
-04:30:01
-05:30:34
+04:30:01.000018
+05:30:34.000037
select * from t2 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t3 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t4 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
-60 04:30:01
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+60 04:30:01.000018
select * from t5 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
-60 04:30:01
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+60 04:30:01.000018
select * from t6 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
-60 04:30:01
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+60 04:30:01.000018
alter table t1 drop partition p0;
alter table t2 drop partition p0;
alter table t4 drop partition p0;
@@ -6821,90 +6925,99 @@ alter table t5 drop partition p0;
alter table t6 drop partition p0;
select * from t1 order by col1;
col1
+04:30:01.000018
+05:30:34.000037
select * from t2 order by col1;
col1
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t3 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t4 order by colint;
colint col1
-60 04:30:01
+60 04:30:01.000018
select * from t5 order by colint;
colint col1
-60 04:30:01
+60 04:30:01.000018
select * from t6 order by colint;
colint col1
-60 04:30:01
+60 04:30:01.000018
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with microsecond(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='04:30:01.000018';
delete from t22 where col1='04:30:01.000018';
delete from t33 where col1='04:30:01.000018';
delete from t44 where col1='04:30:01.000018';
delete from t55 where col1='04:30:01.000018';
delete from t66 where col1='04:30:01.000018';
+commit;
select * from t11 order by col1;
col1
-05:30:34
+05:30:34.000037
select * from t22 order by col1;
col1
-00:59:22
-05:30:34
+00:59:22.000024
+05:30:34.000037
select * from t33 order by col1;
col1
-00:59:22
-05:30:34
+00:59:22.000024
+05:30:34.000037
select * from t44 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
select * from t55 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+begin;
insert into t11 values ('04:30:01.000018');
insert into t22 values ('04:30:01.000018');
insert into t33 values ('04:30:01.000018');
insert into t44 values (60,'04:30:01.000018');
insert into t55 values (60,'04:30:01.000018');
insert into t66 values (60,'04:30:01.000018');
+commit;
select * from t11 order by col1;
col1
-04:30:01
-05:30:34
+04:30:01.000018
+05:30:34.000037
select * from t22 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t33 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t44 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
-60 04:30:01
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+60 04:30:01.000018
select * from t55 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
-60 04:30:01
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+60 04:30:01.000018
select * from t66 order by colint;
colint col1
-1 05:30:34
-3 00:59:22
-4 05:30:34
-60 04:30:01
+1 05:30:34.000037
+3 00:59:22.000024
+4 05:30:34.000037
+60 04:30:01.000018
alter table t11 drop partition p0;
alter table t22 drop partition p0;
alter table t44 drop partition p0;
@@ -6912,22 +7025,27 @@ alter table t55 drop partition p0;
alter table t66 drop partition p0;
select * from t11 order by col1;
col1
+04:30:01.000018
+05:30:34.000037
select * from t22 order by col1;
col1
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t33 order by col1;
col1
-00:59:22
-04:30:01
-05:30:34
+00:59:22.000024
+04:30:01.000018
+05:30:34.000037
select * from t44 order by colint;
colint col1
-60 04:30:01
+60 04:30:01.000018
select * from t55 order by colint;
colint col1
-60 04:30:01
+60 04:30:01.000018
select * from t66 order by colint;
colint col1
-60 04:30:01
+60 04:30:01.000018
-------------------------
---- some alter table end
-------------------------
@@ -6992,6 +7110,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with minute(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('09:09:15');
insert into t1 values ('14:30:45');
insert into t2 values ('09:09:15');
@@ -7000,6 +7119,7 @@ insert into t2 values ('21:59:22');
insert into t3 values ('09:09:15');
insert into t3 values ('14:30:45');
insert into t3 values ('21:59:22');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t6;
@@ -7039,12 +7159,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
update t1 set col1='10:24:23' where col1='09:09:15';
update t2 set col1='10:24:23' where col1='09:09:15';
update t3 set col1='10:24:23' where col1='09:09:15';
update t4 set col1='10:24:23' where col1='09:09:15';
update t5 set col1='10:24:23' where col1='09:09:15';
update t6 set col1='10:24:23' where col1='09:09:15';
+commit;
select * from t1 order by col1;
col1
10:24:23
@@ -7248,12 +7370,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with minute(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='14:30:45';
delete from t2 where col1='14:30:45';
delete from t3 where col1='14:30:45';
delete from t4 where col1='14:30:45';
delete from t5 where col1='14:30:45';
delete from t6 where col1='14:30:45';
+commit;
select * from t1 order by col1;
col1
10:24:23
@@ -7277,12 +7401,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
insert into t1 values ('14:30:45');
insert into t2 values ('14:30:45');
insert into t3 values ('14:30:45');
insert into t4 values (60,'14:30:45');
insert into t5 values (60,'14:30:45');
insert into t6 values (60,'14:30:45');
+commit;
select * from t1 order by col1;
col1
10:24:23
@@ -7349,12 +7475,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with minute(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='14:30:45';
delete from t22 where col1='14:30:45';
delete from t33 where col1='14:30:45';
delete from t44 where col1='14:30:45';
delete from t55 where col1='14:30:45';
delete from t66 where col1='14:30:45';
+commit;
select * from t11 order by col1;
col1
10:24:23
@@ -7378,12 +7506,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
insert into t11 values ('14:30:45');
insert into t22 values ('14:30:45');
insert into t33 values ('14:30:45');
insert into t44 values (60,'14:30:45');
insert into t55 values (60,'14:30:45');
insert into t66 values (60,'14:30:45');
+commit;
select * from t11 order by col1;
col1
10:24:23
@@ -7511,6 +7641,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with second(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('09:09:09');
insert into t1 values ('14:30:20');
insert into t2 values ('09:09:09');
@@ -7519,6 +7650,7 @@ insert into t2 values ('21:59:22');
insert into t3 values ('09:09:09');
insert into t3 values ('14:30:20');
insert into t3 values ('21:59:22');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t6;
@@ -7558,12 +7690,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
update t1 set col1='10:22:33' where col1='09:09:09';
update t2 set col1='10:22:33' where col1='09:09:09';
update t3 set col1='10:22:33' where col1='09:09:09';
update t4 set col1='10:22:33' where col1='09:09:09';
update t5 set col1='10:22:33' where col1='09:09:09';
update t6 set col1='10:22:33' where col1='09:09:09';
+commit;
select * from t1 order by col1;
col1
10:22:33
@@ -7767,12 +7901,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with second(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='14:30:20';
delete from t2 where col1='14:30:20';
delete from t3 where col1='14:30:20';
delete from t4 where col1='14:30:20';
delete from t5 where col1='14:30:20';
delete from t6 where col1='14:30:20';
+commit;
select * from t1 order by col1;
col1
10:22:33
@@ -7796,12 +7932,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
insert into t1 values ('14:30:20');
insert into t2 values ('14:30:20');
insert into t3 values ('14:30:20');
insert into t4 values (60,'14:30:20');
insert into t5 values (60,'14:30:20');
insert into t6 values (60,'14:30:20');
+commit;
select * from t1 order by col1;
col1
10:22:33
@@ -7868,12 +8006,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with second(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='14:30:20';
delete from t22 where col1='14:30:20';
delete from t33 where col1='14:30:20';
delete from t44 where col1='14:30:20';
delete from t55 where col1='14:30:20';
delete from t66 where col1='14:30:20';
+commit;
select * from t11 order by col1;
col1
10:22:33
@@ -7897,12 +8037,14 @@ colint col1
2 04:30:01
3 00:59:22
4 05:30:34
+begin;
insert into t11 values ('14:30:20');
insert into t22 values ('14:30:20');
insert into t33 values ('14:30:20');
insert into t44 values (60,'14:30:20');
insert into t55 values (60,'14:30:20');
insert into t66 values (60,'14:30:20');
+commit;
select * from t11 order by col1;
col1
10:22:33
@@ -8030,6 +8172,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with month(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-01-03');
insert into t1 values ('2006-12-17');
insert into t2 values ('2006-01-03');
@@ -8038,6 +8181,7 @@ insert into t2 values ('2006-05-25');
insert into t3 values ('2006-01-03');
insert into t3 values ('2006-12-17');
insert into t3 values ('2006-05-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -8077,12 +8221,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-11-06' where col1='2006-01-03';
update t2 set col1='2006-11-06' where col1='2006-01-03';
update t3 set col1='2006-11-06' where col1='2006-01-03';
update t4 set col1='2006-11-06' where col1='2006-01-03';
update t5 set col1='2006-11-06' where col1='2006-01-03';
update t6 set col1='2006-11-06' where col1='2006-01-03';
+commit;
select * from t1 order by col1;
col1
2006-11-06
@@ -8286,12 +8432,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with month(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-12-17';
delete from t2 where col1='2006-12-17';
delete from t3 where col1='2006-12-17';
delete from t4 where col1='2006-12-17';
delete from t5 where col1='2006-12-17';
delete from t6 where col1='2006-12-17';
+commit;
select * from t1 order by col1;
col1
2006-11-06
@@ -8315,12 +8463,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-12-17');
insert into t2 values ('2006-12-17');
insert into t3 values ('2006-12-17');
insert into t4 values (60,'2006-12-17');
insert into t5 values (60,'2006-12-17');
insert into t6 values (60,'2006-12-17');
+commit;
select * from t1 order by col1;
col1
2006-11-06
@@ -8384,12 +8534,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with month(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-12-17';
delete from t22 where col1='2006-12-17';
delete from t33 where col1='2006-12-17';
delete from t44 where col1='2006-12-17';
delete from t55 where col1='2006-12-17';
delete from t66 where col1='2006-12-17';
+commit;
select * from t11 order by col1;
col1
2006-11-06
@@ -8413,12 +8565,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-12-17');
insert into t22 values ('2006-12-17');
insert into t33 values ('2006-12-17');
insert into t44 values (60,'2006-12-17');
insert into t55 values (60,'2006-12-17');
insert into t66 values (60,'2006-12-17');
+commit;
select * from t11 order by col1;
col1
2006-11-06
@@ -8543,6 +8697,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with quarter(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-01-03');
insert into t1 values ('2006-12-17');
insert into t2 values ('2006-01-03');
@@ -8551,6 +8706,7 @@ insert into t2 values ('2006-09-25');
insert into t3 values ('2006-01-03');
insert into t3 values ('2006-12-17');
insert into t3 values ('2006-09-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -8590,12 +8746,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-07-30' where col1='2006-01-03';
update t2 set col1='2006-07-30' where col1='2006-01-03';
update t3 set col1='2006-07-30' where col1='2006-01-03';
update t4 set col1='2006-07-30' where col1='2006-01-03';
update t5 set col1='2006-07-30' where col1='2006-01-03';
update t6 set col1='2006-07-30' where col1='2006-01-03';
+commit;
select * from t1 order by col1;
col1
2006-07-30
@@ -8799,12 +8957,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with quarter(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-12-17';
delete from t2 where col1='2006-12-17';
delete from t3 where col1='2006-12-17';
delete from t4 where col1='2006-12-17';
delete from t5 where col1='2006-12-17';
delete from t6 where col1='2006-12-17';
+commit;
select * from t1 order by col1;
col1
2006-07-30
@@ -8828,12 +8988,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-12-17');
insert into t2 values ('2006-12-17');
insert into t3 values ('2006-12-17');
insert into t4 values (60,'2006-12-17');
insert into t5 values (60,'2006-12-17');
insert into t6 values (60,'2006-12-17');
+commit;
select * from t1 order by col1;
col1
2006-07-30
@@ -8896,12 +9058,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with quarter(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-12-17';
delete from t22 where col1='2006-12-17';
delete from t33 where col1='2006-12-17';
delete from t44 where col1='2006-12-17';
delete from t55 where col1='2006-12-17';
delete from t66 where col1='2006-12-17';
+commit;
select * from t11 order by col1;
col1
2006-07-30
@@ -8925,12 +9089,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-12-17');
insert into t22 values ('2006-12-17');
insert into t33 values ('2006-12-17');
insert into t44 values (60,'2006-12-17');
insert into t55 values (60,'2006-12-17');
insert into t66 values (60,'2006-12-17');
+commit;
select * from t11 order by col1;
col1
2006-07-30
@@ -9006,523 +9172,6 @@ drop table if exists t44 ;
drop table if exists t55 ;
drop table if exists t66 ;
-------------------------------------------------------------------------
---- time_to_sec(col1)-(time_to_sec(col1)-20) in partition with coltype time
--------------------------------------------------------------------------
-drop table if exists t1 ;
-drop table if exists t2 ;
-drop table if exists t3 ;
-drop table if exists t4 ;
-drop table if exists t5 ;
-drop table if exists t6 ;
--------------------------------------------------------------------------
---- Create tables with time_to_sec(col1)-(time_to_sec(col1)-20)
--------------------------------------------------------------------------
-create table t1 (col1 time) engine='MYISAM'
-partition by range(time_to_sec(col1)-(time_to_sec(col1)-20))
-(partition p0 values less than (15),
-partition p1 values less than maxvalue);
-create table t2 (col1 time) engine='MYISAM'
-partition by list(time_to_sec(col1)-(time_to_sec(col1)-20))
-(partition p0 values in (0,1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30),
-partition p3 values in (31,32,33,34,35,36,37,38,39,40),
-partition p4 values in (41,42,43,44,45,46,47,48,49,50),
-partition p5 values in (51,52,53,54,55,56,57,58,59,60)
-);
-create table t3 (col1 time) engine='MYISAM'
-partition by hash(time_to_sec(col1)-(time_to_sec(col1)-20));
-create table t4 (colint int, col1 time) engine='MYISAM'
-partition by range(colint)
-subpartition by hash(time_to_sec(col1)-(time_to_sec(col1)-20)) subpartitions 2
-(partition p0 values less than (15),
-partition p1 values less than maxvalue);
-create table t5 (colint int, col1 time) engine='MYISAM'
-partition by list(colint)
-subpartition by hash(time_to_sec(col1)-(time_to_sec(col1)-20)) subpartitions 2
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30),
-partition p3 values in (31,32,33,34,35,36,37,38,39,40),
-partition p4 values in (41,42,43,44,45,46,47,48,49,50),
-partition p5 values in (51,52,53,54,55,56,57,58,59,60)
-);
-create table t6 (colint int, col1 time) engine='MYISAM'
-partition by range(colint)
-(partition p0 values less than (time_to_sec('18:30:14')-(time_to_sec('17:59:59'))),
-partition p1 values less than maxvalue);
--------------------------------------------------------------------------
---- Access tables with time_to_sec(col1)-(time_to_sec(col1)-20)
--------------------------------------------------------------------------
-insert into t1 values ('09:09:15');
-insert into t1 values ('14:30:45');
-insert into t2 values ('09:09:15');
-insert into t2 values ('14:30:45');
-insert into t2 values ('21:59:22');
-insert into t3 values ('09:09:15');
-insert into t3 values ('14:30:45');
-insert into t3 values ('21:59:22');
-load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t4;
-load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t5;
-load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_time.inc' into table t6;
-select time_to_sec(col1)-(time_to_sec(col1)-20) from t1 order by col1;
-time_to_sec(col1)-(time_to_sec(col1)-20)
-20
-20
-select * from t1 order by col1;
-col1
-09:09:15
-14:30:45
-select * from t2 order by col1;
-col1
-09:09:15
-14:30:45
-21:59:22
-select * from t3 order by col1;
-col1
-09:09:15
-14:30:45
-21:59:22
-select * from t4 order by colint;
-colint col1
-1 09:09:15
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t5 order by colint;
-colint col1
-1 09:09:15
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t6 order by colint;
-colint col1
-1 09:09:15
-2 04:30:01
-3 00:59:22
-4 05:30:34
-update t1 set col1='10:33:11' where col1='09:09:15';
-update t2 set col1='10:33:11' where col1='09:09:15';
-update t3 set col1='10:33:11' where col1='09:09:15';
-update t4 set col1='10:33:11' where col1='09:09:15';
-update t5 set col1='10:33:11' where col1='09:09:15';
-update t6 set col1='10:33:11' where col1='09:09:15';
-select * from t1 order by col1;
-col1
-10:33:11
-14:30:45
-select * from t2 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t3 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t4 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t5 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t6 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
--------------------------------------------------------------------------
---- Alter tables with time_to_sec(col1)-(time_to_sec(col1)-20)
--------------------------------------------------------------------------
-drop table if exists t11 ;
-drop table if exists t22 ;
-drop table if exists t33 ;
-drop table if exists t44 ;
-drop table if exists t55 ;
-drop table if exists t66 ;
-create table t11 engine='MYISAM' as select * from t1;
-create table t22 engine='MYISAM' as select * from t2;
-create table t33 engine='MYISAM' as select * from t3;
-create table t44 engine='MYISAM' as select * from t4;
-create table t55 engine='MYISAM' as select * from t5;
-create table t66 engine='MYISAM' as select * from t6;
-alter table t11
-partition by range(time_to_sec(col1)-(time_to_sec(col1)-20))
-(partition p0 values less than (15),
-partition p1 values less than maxvalue);
-alter table t22
-partition by list(time_to_sec(col1)-(time_to_sec(col1)-20))
-(partition p0 values in (0,1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30),
-partition p3 values in (31,32,33,34,35,36,37,38,39,40),
-partition p4 values in (41,42,43,44,45,46,47,48,49,50),
-partition p5 values in (51,52,53,54,55,56,57,58,59,60)
-);
-alter table t33
-partition by hash(time_to_sec(col1)-(time_to_sec(col1)-20));
-alter table t44
-partition by range(colint)
-subpartition by hash(time_to_sec(col1)-(time_to_sec(col1)-20)) subpartitions 2
-(partition p0 values less than (15),
-partition p1 values less than maxvalue);
-alter table t55
-partition by list(colint)
-subpartition by hash(time_to_sec(col1)-(time_to_sec(col1)-20)) subpartitions 2
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30),
-partition p3 values in (31,32,33,34,35,36,37,38,39,40),
-partition p4 values in (41,42,43,44,45,46,47,48,49,50),
-partition p5 values in (51,52,53,54,55,56,57,58,59,60)
-);
-alter table t66
-partition by range(colint)
-(partition p0 values less than (time_to_sec('18:30:14')-(time_to_sec('17:59:59'))),
-partition p1 values less than maxvalue);
-select * from t11 order by col1;
-col1
-10:33:11
-14:30:45
-select * from t22 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t33 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t44 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t55 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t66 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
----------------------------
----- some alter table begin
----------------------------
-alter table t11
-reorganize partition p0,p1 into
-(partition s1 values less than maxvalue);
-select * from t11 order by col1;
-col1
-10:33:11
-14:30:45
-alter table t11
-reorganize partition s1 into
-(partition p0 values less than (15),
-partition p1 values less than maxvalue);
-select * from t11 order by col1;
-col1
-10:33:11
-14:30:45
-alter table t55
-partition by list(colint)
-subpartition by hash(time_to_sec(col1)-(time_to_sec(col1)-20)) subpartitions 5
-(partition p0 values in (1,2,3,4,5,6,7,8,9,10),
-partition p1 values in (11,12,13,14,15,16,17,18,19,20),
-partition p2 values in (21,22,23,24,25,26,27,28,29,30),
-partition p3 values in (31,32,33,34,35,36,37,38,39,40),
-partition p4 values in (41,42,43,44,45,46,47,48,49,50),
-partition p5 values in (51,52,53,54,55,56,57,58,59,60)
-);
-show create table t55;
-Table Create Table
-t55 CREATE TABLE `t55` (
- `colint` int(11) DEFAULT NULL,
- `col1` time DEFAULT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY LIST (colint)
-SUBPARTITION BY HASH (time_to_sec(col1)-(time_to_sec(col1)-20))
-SUBPARTITIONS 5
-(PARTITION p0 VALUES IN (1,2,3,4,5,6,7,8,9,10) ENGINE = MyISAM,
- PARTITION p1 VALUES IN (11,12,13,14,15,16,17,18,19,20) ENGINE = MyISAM,
- PARTITION p2 VALUES IN (21,22,23,24,25,26,27,28,29,30) ENGINE = MyISAM,
- PARTITION p3 VALUES IN (31,32,33,34,35,36,37,38,39,40) ENGINE = MyISAM,
- PARTITION p4 VALUES IN (41,42,43,44,45,46,47,48,49,50) ENGINE = MyISAM,
- PARTITION p5 VALUES IN (51,52,53,54,55,56,57,58,59,60) ENGINE = MyISAM) */
-select * from t55 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-alter table t66
-reorganize partition p0,p1 into
-(partition s1 values less than maxvalue);
-select * from t66 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-alter table t66
-reorganize partition s1 into
-(partition p0 values less than (time_to_sec('18:30:14')-(time_to_sec('17:59:59'))),
-partition p1 values less than maxvalue);
-select * from t66 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-alter table t66
-reorganize partition p0,p1 into
-(partition s1 values less than maxvalue);
-select * from t66 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-alter table t66
-reorganize partition s1 into
-(partition p0 values less than (time_to_sec('18:30:14')-(time_to_sec('17:59:59'))),
-partition p1 values less than maxvalue);
-select * from t66 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
--------------------------------------------------------------------------
---- Delete rows and partitions of tables with time_to_sec(col1)-(time_to_sec(col1)-20)
--------------------------------------------------------------------------
-delete from t1 where col1='14:30:45';
-delete from t2 where col1='14:30:45';
-delete from t3 where col1='14:30:45';
-delete from t4 where col1='14:30:45';
-delete from t5 where col1='14:30:45';
-delete from t6 where col1='14:30:45';
-select * from t1 order by col1;
-col1
-10:33:11
-select * from t2 order by col1;
-col1
-10:33:11
-21:59:22
-select * from t3 order by col1;
-col1
-10:33:11
-21:59:22
-select * from t4 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t5 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-insert into t1 values ('14:30:45');
-insert into t2 values ('14:30:45');
-insert into t3 values ('14:30:45');
-insert into t4 values (60,'14:30:45');
-insert into t5 values (60,'14:30:45');
-insert into t6 values (60,'14:30:45');
-select * from t1 order by col1;
-col1
-10:33:11
-14:30:45
-select * from t2 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t3 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t4 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-60 14:30:45
-select * from t5 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-60 14:30:45
-select * from t6 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-60 14:30:45
-alter table t1 drop partition p0;
-alter table t2 drop partition p0;
-alter table t4 drop partition p0;
-alter table t5 drop partition p0;
-alter table t6 drop partition p0;
-select * from t1 order by col1;
-col1
-10:33:11
-14:30:45
-select * from t2 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t3 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t4 order by colint;
-colint col1
-60 14:30:45
-select * from t5 order by colint;
-colint col1
-60 14:30:45
-select * from t6 order by colint;
-colint col1
--------------------------------------------------------------------------
---- Delete rows and partitions of tables with time_to_sec(col1)-(time_to_sec(col1)-20)
--------------------------------------------------------------------------
-delete from t11 where col1='14:30:45';
-delete from t22 where col1='14:30:45';
-delete from t33 where col1='14:30:45';
-delete from t44 where col1='14:30:45';
-delete from t55 where col1='14:30:45';
-delete from t66 where col1='14:30:45';
-select * from t11 order by col1;
-col1
-10:33:11
-select * from t22 order by col1;
-col1
-10:33:11
-21:59:22
-select * from t33 order by col1;
-col1
-10:33:11
-21:59:22
-select * from t44 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-select * from t55 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-insert into t11 values ('14:30:45');
-insert into t22 values ('14:30:45');
-insert into t33 values ('14:30:45');
-insert into t44 values (60,'14:30:45');
-insert into t55 values (60,'14:30:45');
-insert into t66 values (60,'14:30:45');
-select * from t11 order by col1;
-col1
-10:33:11
-14:30:45
-select * from t22 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t33 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t44 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-60 14:30:45
-select * from t55 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-60 14:30:45
-select * from t66 order by colint;
-colint col1
-1 10:33:11
-2 04:30:01
-3 00:59:22
-4 05:30:34
-60 14:30:45
-alter table t11 drop partition p0;
-alter table t22 drop partition p0;
-alter table t44 drop partition p0;
-alter table t55 drop partition p0;
-alter table t66 drop partition p0;
-select * from t11 order by col1;
-col1
-10:33:11
-14:30:45
-select * from t22 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t33 order by col1;
-col1
-10:33:11
-14:30:45
-21:59:22
-select * from t44 order by colint;
-colint col1
-60 14:30:45
-select * from t55 order by colint;
-colint col1
-60 14:30:45
-select * from t66 order by colint;
-colint col1
--------------------------
----- some alter table end
--------------------------
-drop table if exists t1 ;
-drop table if exists t2 ;
-drop table if exists t3 ;
-drop table if exists t4 ;
-drop table if exists t5 ;
-drop table if exists t6 ;
-drop table if exists t11 ;
-drop table if exists t22 ;
-drop table if exists t33 ;
-drop table if exists t44 ;
-drop table if exists t55 ;
-drop table if exists t66 ;
--------------------------------------------------------------------------
--- weekday(col1) in partition with coltype date
-------------------------------------------------------------------------
drop table if exists t1 ;
@@ -9571,6 +9220,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with weekday(col1)
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-12-03');
insert into t1 values ('2006-11-17');
insert into t2 values ('2006-12-03');
@@ -9579,6 +9229,7 @@ insert into t2 values ('2006-05-25');
insert into t3 values ('2006-12-03');
insert into t3 values ('2006-11-17');
insert into t3 values ('2006-05-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -9618,12 +9269,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-02-06' where col1='2006-12-03';
update t2 set col1='2006-02-06' where col1='2006-12-03';
update t3 set col1='2006-02-06' where col1='2006-12-03';
update t4 set col1='2006-02-06' where col1='2006-12-03';
update t5 set col1='2006-02-06' where col1='2006-12-03';
update t6 set col1='2006-02-06' where col1='2006-12-03';
+commit;
select * from t1 order by col1;
col1
2006-02-06
@@ -9827,12 +9480,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with weekday(col1)
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-11-17';
delete from t2 where col1='2006-11-17';
delete from t3 where col1='2006-11-17';
delete from t4 where col1='2006-11-17';
delete from t5 where col1='2006-11-17';
delete from t6 where col1='2006-11-17';
+commit;
select * from t1 order by col1;
col1
2006-02-06
@@ -9856,12 +9511,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-11-17');
insert into t2 values ('2006-11-17');
insert into t3 values ('2006-11-17');
insert into t4 values (60,'2006-11-17');
insert into t5 values (60,'2006-11-17');
insert into t6 values (60,'2006-11-17');
+commit;
select * from t1 order by col1;
col1
2006-02-06
@@ -9923,12 +9580,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with weekday(col1)
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-11-17';
delete from t22 where col1='2006-11-17';
delete from t33 where col1='2006-11-17';
delete from t44 where col1='2006-11-17';
delete from t55 where col1='2006-11-17';
delete from t66 where col1='2006-11-17';
+commit;
select * from t11 order by col1;
col1
2006-02-06
@@ -9952,12 +9611,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-11-17');
insert into t22 values ('2006-11-17');
insert into t33 values ('2006-11-17');
insert into t44 values (60,'2006-11-17');
insert into t55 values (60,'2006-11-17');
insert into t66 values (60,'2006-11-17');
+commit;
select * from t11 order by col1;
col1
2006-02-06
@@ -10080,6 +9741,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with year(col1)-1990
-------------------------------------------------------------------------
+begin;
insert into t1 values ('1996-01-03');
insert into t1 values ('2000-02-17');
insert into t2 values ('1996-01-03');
@@ -10088,6 +9750,7 @@ insert into t2 values ('2004-05-25');
insert into t3 values ('1996-01-03');
insert into t3 values ('2000-02-17');
insert into t3 values ('2004-05-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -10127,12 +9790,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2002-02-15' where col1='1996-01-03';
update t2 set col1='2002-02-15' where col1='1996-01-03';
update t3 set col1='2002-02-15' where col1='1996-01-03';
update t4 set col1='2002-02-15' where col1='1996-01-03';
update t5 set col1='2002-02-15' where col1='1996-01-03';
update t6 set col1='2002-02-15' where col1='1996-01-03';
+commit;
select * from t1 order by col1;
col1
2000-02-17
@@ -10336,12 +10001,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with year(col1)-1990
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2000-02-17';
delete from t2 where col1='2000-02-17';
delete from t3 where col1='2000-02-17';
delete from t4 where col1='2000-02-17';
delete from t5 where col1='2000-02-17';
delete from t6 where col1='2000-02-17';
+commit;
select * from t1 order by col1;
col1
2002-02-15
@@ -10365,12 +10032,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2000-02-17');
insert into t2 values ('2000-02-17');
insert into t3 values ('2000-02-17');
insert into t4 values (60,'2000-02-17');
insert into t5 values (60,'2000-02-17');
insert into t6 values (60,'2000-02-17');
+commit;
select * from t1 order by col1;
col1
2000-02-17
@@ -10434,12 +10103,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with year(col1)-1990
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2000-02-17';
delete from t22 where col1='2000-02-17';
delete from t33 where col1='2000-02-17';
delete from t44 where col1='2000-02-17';
delete from t55 where col1='2000-02-17';
delete from t66 where col1='2000-02-17';
+commit;
select * from t11 order by col1;
col1
2002-02-15
@@ -10463,12 +10134,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2000-02-17');
insert into t22 values ('2000-02-17');
insert into t33 values ('2000-02-17');
insert into t44 values (60,'2000-02-17');
insert into t55 values (60,'2000-02-17');
insert into t66 values (60,'2000-02-17');
+commit;
select * from t11 order by col1;
col1
2000-02-17
@@ -10593,6 +10266,7 @@ partition p1 values less than maxvalue);
-------------------------------------------------------------------------
--- Access tables with yearweek(col1)-200600
-------------------------------------------------------------------------
+begin;
insert into t1 values ('2006-01-03');
insert into t1 values ('2006-08-17');
insert into t2 values ('2006-01-03');
@@ -10601,6 +10275,7 @@ insert into t2 values ('2006-03-25');
insert into t3 values ('2006-01-03');
insert into t3 values ('2006-08-17');
insert into t3 values ('2006-03-25');
+commit;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t4;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t5;
load data infile 'MYSQLTEST_VARDIR/std_data/parts/part_supported_sql_funcs_int_date.inc' into table t6;
@@ -10640,12 +10315,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
update t1 set col1='2006-11-15' where col1='2006-01-03';
update t2 set col1='2006-11-15' where col1='2006-01-03';
update t3 set col1='2006-11-15' where col1='2006-01-03';
update t4 set col1='2006-11-15' where col1='2006-01-03';
update t5 set col1='2006-11-15' where col1='2006-01-03';
update t6 set col1='2006-11-15' where col1='2006-01-03';
+commit;
select * from t1 order by col1;
col1
2006-08-17
@@ -10849,12 +10526,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with yearweek(col1)-200600
-------------------------------------------------------------------------
+begin;
delete from t1 where col1='2006-08-17';
delete from t2 where col1='2006-08-17';
delete from t3 where col1='2006-08-17';
delete from t4 where col1='2006-08-17';
delete from t5 where col1='2006-08-17';
delete from t6 where col1='2006-08-17';
+commit;
select * from t1 order by col1;
col1
2006-11-15
@@ -10878,12 +10557,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t1 values ('2006-08-17');
insert into t2 values ('2006-08-17');
insert into t3 values ('2006-08-17');
insert into t4 values (60,'2006-08-17');
insert into t5 values (60,'2006-08-17');
insert into t6 values (60,'2006-08-17');
+commit;
select * from t1 order by col1;
col1
2006-08-17
@@ -10950,12 +10631,14 @@ colint col1
-------------------------------------------------------------------------
--- Delete rows and partitions of tables with yearweek(col1)-200600
-------------------------------------------------------------------------
+begin;
delete from t11 where col1='2006-08-17';
delete from t22 where col1='2006-08-17';
delete from t33 where col1='2006-08-17';
delete from t44 where col1='2006-08-17';
delete from t55 where col1='2006-08-17';
delete from t66 where col1='2006-08-17';
+commit;
select * from t11 order by col1;
col1
2006-11-15
@@ -10979,12 +10662,14 @@ colint col1
2 2006-01-17
3 2006-01-25
4 2006-02-05
+begin;
insert into t11 values ('2006-08-17');
insert into t22 values ('2006-08-17');
insert into t33 values ('2006-08-17');
insert into t44 values (60,'2006-08-17');
insert into t55 values (60,'2006-08-17');
insert into t66 values (60,'2006-08-17');
+commit;
select * from t11 order by col1;
col1
2006-08-17
diff --git a/mysql-test/suite/parts/r/partition_bit_innodb.result b/mysql-test/suite/parts/r/partition_bit_innodb.result
index a9ae917f13d..2e802d85b1f 100644
--- a/mysql-test/suite/parts/r/partition_bit_innodb.result
+++ b/mysql-test/suite/parts/r/partition_bit_innodb.result
@@ -1,7 +1,7 @@
SET @max_row = 20;
drop table if exists t1;
create table t1 (a bit(65), primary key (a)) engine='INNODB' partition by key (a);
-ERROR 42000: Display width out of range for column 'a' (max = 64)
+ERROR 42000: Display width out of range for 'a' (max = 64)
create table t1 (a bit(0), primary key (a)) engine='INNODB' partition by key (a);
show create table t1;
Table Create Table
diff --git a/mysql-test/suite/parts/r/partition_bit_myisam.result b/mysql-test/suite/parts/r/partition_bit_myisam.result
index 680845c9971..c396cf66521 100644
--- a/mysql-test/suite/parts/r/partition_bit_myisam.result
+++ b/mysql-test/suite/parts/r/partition_bit_myisam.result
@@ -1,7 +1,7 @@
SET @max_row = 20;
drop table if exists t1;
create table t1 (a bit(65), primary key (a)) engine='MyISAM' partition by key (a);
-ERROR 42000: Display width out of range for column 'a' (max = 64)
+ERROR 42000: Display width out of range for 'a' (max = 64)
create table t1 (a bit(0), primary key (a)) engine='MyISAM' partition by key (a);
show create table t1;
Table Create Table
diff --git a/mysql-test/suite/parts/r/partition_repair_myisam.result b/mysql-test/suite/parts/r/partition_repair_myisam.result
index 058aff4ea4d..f9dd05c2996 100644
--- a/mysql-test/suite/parts/r/partition_repair_myisam.result
+++ b/mysql-test/suite/parts/r/partition_repair_myisam.result
@@ -394,6 +394,8 @@ partition b a length(c)
6 34 6 row 2 64
6 83 64
6 97 zzzzzZzzzzz 64
+SET @save_optimizer_switch= @@optimizer_switch;
+SET @@optimizer_switch='derived_merge=off';
SELECT (b % 7) AS partition, b, a FROM (SELECT b,a FROM t1_will_crash) q
WHERE (b % 7) = 6
ORDER BY partition, b, a;
@@ -405,6 +407,7 @@ partition b a
6 62 6 row 6
6 83
6 97 zzzzzZzzzzz
+SET @@optimizer_switch=@save_optimizer_switch;
ALTER TABLE t1_will_crash CHECK PARTITION p6;
Table Op Msg_type Msg_text
test.t1_will_crash check warning Size of datafile is: 868 Should be: 604
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/parts/r/rpl_partition.result b/mysql-test/suite/parts/r/rpl_partition.result
index 00247f218e4..048ae77b367 100644
--- a/mysql-test/suite/parts/r/rpl_partition.result
+++ b/mysql-test/suite/parts/r/rpl_partition.result
@@ -96,13 +96,19 @@ DELETE FROM t3 WHERE id = del_count;
SET del_count = del_count - 2;
END WHILE;
END|
+begin;
CALL p1();
+commit;
SELECT count(*) as "Master regular" FROM t1;
Master regular 500
+begin;
CALL p2();
+commit;
SELECT count(*) as "Master bykey" FROM t2;
Master bykey 500
+begin;
CALL p3();
+commit;
SELECT count(*) as "Master byrange" FROM t3;
Master byrange 500
show create table t3;
diff --git a/mysql-test/suite/parts/t/part_supported_sql_func_innodb.test b/mysql-test/suite/parts/t/part_supported_sql_func_innodb.test
index 115bc08a624..20348cc331d 100644
--- a/mysql-test/suite/parts/t/part_supported_sql_func_innodb.test
+++ b/mysql-test/suite/parts/t/part_supported_sql_func_innodb.test
@@ -26,13 +26,11 @@ let $debug= 0;
let $do_long_tests= 1;
#
+# This test takes long time, so only run it with the --big mtr-flag.
--source include/big_test.inc
# The server must support partitioning.
--source include/have_partition.inc
-# This test takes long time, so only run it with the --big mtr-flag.
---source include/big_test.inc
-
#------------------------------------------------------------------------------#
# Engine specific settings and requirements
diff --git a/mysql-test/suite/parts/t/partition_repair_myisam.test b/mysql-test/suite/parts/t/partition_repair_myisam.test
index a7ceb5b7faf..849f175b920 100644
--- a/mysql-test/suite/parts/t/partition_repair_myisam.test
+++ b/mysql-test/suite/parts/t/partition_repair_myisam.test
@@ -230,9 +230,12 @@ FLUSH TABLES;
SELECT (b % 7) AS partition, b, a, length(c) FROM t1_will_crash
WHERE (b % 7) = 6
ORDER BY partition, b, a;
+SET @save_optimizer_switch= @@optimizer_switch;
+SET @@optimizer_switch='derived_merge=off';
SELECT (b % 7) AS partition, b, a FROM (SELECT b,a FROM t1_will_crash) q
WHERE (b % 7) = 6
ORDER BY partition, b, a;
+SET @@optimizer_switch=@save_optimizer_switch;
# NOTE: REBUILD PARTITION without CHECK before, 2 + (1) records will be lost!
#ALTER TABLE t1_will_crash REBUILD PARTITION p6;
ALTER TABLE t1_will_crash CHECK PARTITION p6;
diff --git a/mysql-test/suite/parts/t/rpl_partition.test b/mysql-test/suite/parts/t/rpl_partition.test
index 409f428b34b..5294ff9fe3c 100644
--- a/mysql-test/suite/parts/t/rpl_partition.test
+++ b/mysql-test/suite/parts/t/rpl_partition.test
@@ -127,11 +127,17 @@ delimiter ;|
############ Test Section ###################
+begin;
CALL p1();
+commit;
SELECT count(*) as "Master regular" FROM t1;
+begin;
CALL p2();
+commit;
SELECT count(*) as "Master bykey" FROM t2;
+begin;
CALL p3();
+commit;
SELECT count(*) as "Master byrange" FROM t3;
--sync_slave_with_master
diff --git a/mysql-test/suite/pbxt/r/cast.result b/mysql-test/suite/pbxt/r/cast.result
index bc0c983c8e1..262c8ea48e5 100644
--- a/mysql-test/suite/pbxt/r/cast.result
+++ b/mysql-test/suite/pbxt/r/cast.result
@@ -1,9 +1,13 @@
select CAST(1-2 AS UNSIGNED);
CAST(1-2 AS UNSIGNED)
18446744073709551615
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER)
-1
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select CAST('10 ' as unsigned integer);
CAST('10 ' as unsigned integer)
10
@@ -12,9 +16,15 @@ Warning 1292 Truncated incorrect INTEGER value: '10 '
select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
cast(-5 as unsigned) | 1 cast(-5 as unsigned) & -1
18446744073709551611 18446744073709551611
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
cast(-5 as unsigned) -1 cast(-5 as unsigned) + 1
18446744073709551610 18446744073709551612
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select ~5, cast(~5 as signed);
~5 cast(~5 as signed)
18446744073709551610 -6
@@ -254,7 +264,7 @@ cast("2001-1-1" as datetime) = "2001-01-01 00:00:00"
1
select cast("1:2:3" as TIME) = "1:02:03";
cast("1:2:3" as TIME) = "1:02:03"
-0
+1
select cast(NULL as DATE);
cast(NULL as DATE)
NULL
diff --git a/mysql-test/suite/pbxt/r/date_formats.result b/mysql-test/suite/pbxt/r/date_formats.result
index 808c84d7c13..da62ff7a2f8 100644
--- a/mysql-test/suite/pbxt/r/date_formats.result
+++ b/mysql-test/suite/pbxt/r/date_formats.result
@@ -185,16 +185,16 @@ date format datetime
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
-2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
-2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
-2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450
+2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12
+2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12
+2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
10:20:10 %H:%i:%s 0000-00-00 10:20:10
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
10:20:10 %T 0000-00-00 10:20:10
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
10:20:10AM %r 0000-00-00 10:20:10
-10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000
+10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
15 September 2001 %d %M %Y 2001-09-15 00:00:00
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
@@ -404,14 +404,14 @@ date format str_to_date
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
Warnings:
-Warning 1292 Incorrect datetime value: '10:20:10AM'
+Warning 1292 Truncated incorrect datetime value: '10:20:10AM'
select date,format,concat(str_to_date(date, format),'') as con from t1;
date format con
10:20:10AM %h:%i:%s 0000-00-00 10:20:10
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
Warnings:
-Warning 1292 Incorrect datetime value: '10:20:10AM'
+Warning 1292 Truncated incorrect datetime value: '10:20:10AM'
drop table t1;
select get_format(DATE, 'USA') as a;
a
@@ -454,14 +454,14 @@ str_to_date("2003-01-02", "%Y-%m-%d") as f3,
str_to_date("02", "%d") as f4, str_to_date("02 10", "%d %H") as f5;
describe t1;
Field Type Null Key Default Extra
-f1 datetime YES NULL
-f2 time YES NULL
+f1 datetime(6) YES NULL
+f2 time(6) YES NULL
f3 date YES NULL
f4 date YES NULL
f5 time YES NULL
select * from t1;
f1 f2 f3 f4 f5
-2003-01-02 10:11:12 10:11:12 2003-01-02 0000-00-02 58:00:00
+2003-01-02 10:11:12.001200 10:11:12.001200 2003-01-02 0000-00-02 58:00:00
drop table t1;
create table t1 select "02 10" as a, "%d %H" as b;
select str_to_date(a,b) from t1;
@@ -470,7 +470,7 @@ str_to_date(a,b)
create table t2 select str_to_date(a,b) from t1;
describe t2;
Field Type Null Key Default Extra
-str_to_date(a,b) datetime YES NULL
+str_to_date(a,b) datetime(6) YES NULL
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S") as f2,
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
@@ -478,7 +478,7 @@ str_to_date("02 10:11:12", "%d %H:%i:%S.%f") as f4,
str_to_date("02 10:11:12", "%d %H:%i:%S") as f5,
str_to_date("02 10", "%d %f") as f6;
f1 f2 f3 f4 f5 f6
-2003-01-02 10:11:12.001200 2003-01-02 10:11:12 2003-01-02 58:11:12 58:11:12 48:00:00.100000
+2003-01-02 10:11:12.001200 2003-01-02 10:11:12 2003-01-02 58:11:12.000000 58:11:12 48:00:00.100000
Warnings:
Warning 1292 Truncated incorrect datetime value: '2003-01-02 10:11:12.0012'
drop table t1, t2;
diff --git a/mysql-test/suite/pbxt/r/derived.result b/mysql-test/suite/pbxt/r/derived.result
index fb723c45c0f..d59316b04db 100644
--- a/mysql-test/suite/pbxt/r/derived.result
+++ b/mysql-test/suite/pbxt/r/derived.result
@@ -1,4 +1,6 @@
drop table if exists t1,t2,t3;
+set @save_derived_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
select * from (select 2 from DUAL) b;
2
2
@@ -58,7 +60,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;
@@ -91,7 +93,7 @@ a b
2 b
explain select * from (select * from t1 union select * from t1) a;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8
2 DERIVED t1 ALL NULL NULL NULL NULL 4
3 UNION t1 ALL NULL NULL NULL NULL 4
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
@@ -113,9 +115,9 @@ a b
3 c
explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
2 DERIVED t2 ALL NULL NULL NULL NULL 1
-2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer
+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 +145,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 +192,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 9 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 9 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;
@@ -208,6 +210,7 @@ create table t1 select 1 as a;
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
select 2 as a from (select * from t1) b;
ERROR 3D000: No database selected
use test;
@@ -249,8 +252,8 @@ a a
2 2
explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
-1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 Using join buffer
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+1 PRIMARY <derived4> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
4 DERIVED t1 ALL NULL NULL NULL NULL 2
5 UNION t1 ALL NULL NULL NULL NULL 2
NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL
@@ -315,9 +318,9 @@ a 7.0000
b 3.5000
explain SELECT s.name, AVG(s.val) AS median FROM (SELECT x.name, x.val FROM t1 x, t1 y WHERE x.name=y.name GROUP BY x.name, x.val HAVING SUM(y.val <= x.val) >= COUNT(*)/2 AND SUM(y.val >= x.val) >= COUNT(*)/2) AS s GROUP BY s.name;
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
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 289 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);
@@ -326,7 +329,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
explain select a from (select a from t2 where a>1) tt;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
drop table t2;
CREATE TABLE `t1` ( `itemid` int(11) NOT NULL default '0', `grpid` varchar(15) NOT NULL default '', `vendor` int(11) NOT NULL default '0', `date_` date NOT NULL default '0000-00-00', `price` decimal(12,2) NOT NULL default '0.00', PRIMARY KEY (`itemid`,`grpid`,`vendor`,`date_`), KEY `itemid` (`itemid`,`vendor`), KEY `itemid_2` (`itemid`,`date_`));
@@ -389,3 +392,4 @@ select t2.* from (select * from t1) as A inner join t2 on A.ID = t2.FID;
ID DATA FID
drop table t1, t2;
drop user mysqltest_1;
+set optimizer_switch=@save_derived_optimizer_switch;
diff --git a/mysql-test/suite/pbxt/r/distinct.result b/mysql-test/suite/pbxt/r/distinct.result
index c3e8342a6e1..aa4ba4bef06 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
@@ -280,6 +280,8 @@ unique (id, idx)
insert into t1 values (1,'yes'), (2,'no');
insert into t2 values (1,1);
insert into t3 values (1,1);
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
EXPLAIN
SELECT DISTINCT
t1.id
@@ -300,11 +302,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
@@ -326,6 +328,7 @@ AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2));
id
2
drop table t1,t2,t3;
+set join_cache_level=@save_join_cache_level;
create table t1 (a int not null, b int not null, t time);
insert into t1 values (1,1,"00:06:15"),(1,2,"00:06:15"),(1,2,"00:30:15"),(1,3,"00:06:15"),(1,3,"00:30:15");
select a,sec_to_time(sum(time_to_sec(t))) from t1 group by a,b;
@@ -515,7 +518,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/errors.result b/mysql-test/suite/pbxt/r/errors.result
index 0c84f24a2e4..eca18ed6434 100644
--- a/mysql-test/suite/pbxt/r/errors.result
+++ b/mysql-test/suite/pbxt/r/errors.result
@@ -24,7 +24,7 @@ select count(*),b from t1;
ERROR 42S22: Unknown column 'b' in 'field list'
drop table t1;
create table t1 (a int(256));
-ERROR 42000: Display width out of range for column 'a' (max = 255)
+ERROR 42000: Display width out of range for 'a' (max = 255)
set sql_mode='traditional';
create table t1 (a varchar(66000));
ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead
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..8817afa6462 100644
--- a/mysql-test/suite/pbxt/r/func_group.result
+++ b/mysql-test/suite/pbxt/r/func_group.result
@@ -215,6 +215,8 @@ a1 a2 a1 a2
10 bbb BBB 20
20 zzz AAA 10
20 zzz BBB 20
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select max(t1.a1), max(t2.a1) from t1, t2 where t2.a2=9;
max(t1.a1) max(t2.a1)
NULL NULL
@@ -245,6 +247,7 @@ NULL
select max(t1.a2),max(t2.a1) from t1 left outer join t2 on t1.a1=10;
max(t1.a2) max(t2.a1)
zzz BBB
+SET optimizer_switch=@save_optimizer_switch;
drop table t1,t2;
CREATE TABLE t1 (a int, b int);
select count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1;
@@ -601,7 +604,7 @@ AME AME
explain
select min(a1) from t1 where a1 > 'KKK' or a1 < 'XXX';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index PRIMARY PRIMARY 3 NULL 15 Using where; Using index
+1 SIMPLE t1 range PRIMARY PRIMARY 0 NULL 1 Using where; Using index
explain
select min(a1) from t1 where a1 != 'KKK';
id select_type table type possible_keys key key_len ref rows Extra
@@ -614,7 +617,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 +654,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/func_op.result b/mysql-test/suite/pbxt/r/func_op.result
index 636163e6b29..ce755e86b4c 100644
--- a/mysql-test/suite/pbxt/r/func_op.result
+++ b/mysql-test/suite/pbxt/r/func_op.result
@@ -40,9 +40,12 @@ create table t1(a int);
create table t2(a int, b int);
insert into t1 values (1), (2), (3);
insert into t2 values (1, 7), (3, 7);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select t1.a, t2.a, t2.b, bit_count(t2.b) from t1 left join t2 on t1.a=t2.a;
a a b bit_count(t2.b)
1 1 7 3
2 NULL NULL NULL
3 3 7 3
+SET optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
diff --git a/mysql-test/suite/pbxt/r/func_sapdb.result b/mysql-test/suite/pbxt/r/func_sapdb.result
index b0c697e54ac..9e8775c876a 100644
--- a/mysql-test/suite/pbxt/r/func_sapdb.result
+++ b/mysql-test/suite/pbxt/r/func_sapdb.result
@@ -104,10 +104,10 @@ subtime("01:00:00.999999", "02:00:00.999998")
-00:59:59.999999
select subtime("02:01:01.999999", "01:01:01.999999");
subtime("02:01:01.999999", "01:01:01.999999")
-01:00:00.000000
+01:00:00
select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002");
timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002")
-838:59:59
+838:59:59.999999
Warnings:
Warning 1292 Truncated incorrect time value: '8807:59:59.999999'
select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002");
@@ -186,17 +186,17 @@ time("1997-12-31 23:59:59.000001") as f9;
describe t1;
Field Type Null Key Default Extra
f1 date YES NULL
-f2 datetime YES NULL
-f3 time YES NULL
-f4 time YES NULL
-f5 time YES NULL
+f2 datetime(6) YES NULL
+f3 time(6) YES NULL
+f4 time(6) YES NULL
+f5 time(6) YES NULL
f6 time YES NULL
-f7 datetime YES NULL
+f7 datetime(6) YES NULL
f8 date YES NULL
-f9 time YES NULL
+f9 time(6) YES NULL
select * from t1;
f1 f2 f3 f4 f5 f6 f7 f8 f9
-1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -24:00:00 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59
+1997-01-01 1998-01-02 01:01:00.000002 49:01:00.000002 46:58:57.999999 -24:00:00.000001 10:11:12 2001-12-01 01:01:01.000000 1997-12-31 23:59:59.000001
create table test(t1 datetime, t2 time, t3 time, t4 datetime);
insert into test values
('2001-01-01 01:01:01', '01:01:01', null, '2001-02-01 01:01:01'),
@@ -241,6 +241,8 @@ a
select microsecond(19971231235959.01) as a;
a
10000
+Warnings:
+Warning 1292 Truncated incorrect time value: '19971231235959.01'
select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a;
a
1997-12-31 00:00:10.090000
diff --git a/mysql-test/suite/pbxt/r/func_str.result b/mysql-test/suite/pbxt/r/func_str.result
index 4dc909f42e4..39d79d7ec45 100644
--- a/mysql-test/suite/pbxt/r/func_str.result
+++ b/mysql-test/suite/pbxt/r/func_str.result
@@ -1504,7 +1504,7 @@ select locate('lo','hello',-18446744073709551615);
locate('lo','hello',-18446744073709551615)
0
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select locate('lo','hello',18446744073709551615);
locate('lo','hello',18446744073709551615)
0
@@ -1512,22 +1512,22 @@ select locate('lo','hello',-18446744073709551616);
locate('lo','hello',-18446744073709551616)
0
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select locate('lo','hello',18446744073709551616);
locate('lo','hello',18446744073709551616)
0
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select locate('lo','hello',-18446744073709551617);
locate('lo','hello',-18446744073709551617)
0
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select locate('lo','hello',18446744073709551617);
locate('lo','hello',18446744073709551617)
0
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select left('hello', 10);
left('hello', 10)
hello
@@ -1559,8 +1559,8 @@ select left('hello', -18446744073709551615);
left('hello', -18446744073709551615)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select left('hello', 18446744073709551615);
left('hello', 18446744073709551615)
hello
@@ -1568,26 +1568,26 @@ select left('hello', -18446744073709551616);
left('hello', -18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select left('hello', 18446744073709551616);
left('hello', 18446744073709551616)
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select left('hello', -18446744073709551617);
left('hello', -18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select left('hello', 18446744073709551617);
left('hello', 18446744073709551617)
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select right('hello', 10);
right('hello', 10)
hello
@@ -1619,8 +1619,8 @@ select right('hello', -18446744073709551615);
right('hello', -18446744073709551615)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select right('hello', 18446744073709551615);
right('hello', 18446744073709551615)
hello
@@ -1628,26 +1628,26 @@ select right('hello', -18446744073709551616);
right('hello', -18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select right('hello', 18446744073709551616);
right('hello', 18446744073709551616)
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select right('hello', -18446744073709551617);
right('hello', -18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select right('hello', 18446744073709551617);
right('hello', 18446744073709551617)
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select substring('hello', 2, -1);
substring('hello', 2, -1)
@@ -1679,8 +1679,8 @@ select substring('hello', -18446744073709551615, 1);
substring('hello', -18446744073709551615, 1)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select substring('hello', 18446744073709551615, 1);
substring('hello', 18446744073709551615, 1)
@@ -1688,26 +1688,26 @@ select substring('hello', -18446744073709551616, 1);
substring('hello', -18446744073709551616, 1)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select substring('hello', 18446744073709551616, 1);
substring('hello', 18446744073709551616, 1)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select substring('hello', -18446744073709551617, 1);
substring('hello', -18446744073709551617, 1)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select substring('hello', 18446744073709551617, 1);
substring('hello', 18446744073709551617, 1)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select substring('hello', 1, -1);
substring('hello', 1, -1)
@@ -1733,8 +1733,8 @@ select substring('hello', 1, -18446744073709551615);
substring('hello', 1, -18446744073709551615)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select substring('hello', 1, 18446744073709551615);
substring('hello', 1, 18446744073709551615)
hello
@@ -1742,26 +1742,26 @@ select substring('hello', 1, -18446744073709551616);
substring('hello', 1, -18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select substring('hello', 1, 18446744073709551616);
substring('hello', 1, 18446744073709551616)
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select substring('hello', 1, -18446744073709551617);
substring('hello', 1, -18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select substring('hello', 1, 18446744073709551617);
substring('hello', 1, 18446744073709551617)
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select substring('hello', -1, -1);
substring('hello', -1, -1)
@@ -1787,10 +1787,10 @@ select substring('hello', -18446744073709551615, -18446744073709551615);
substring('hello', -18446744073709551615, -18446744073709551615)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select substring('hello', 18446744073709551615, 18446744073709551615);
substring('hello', 18446744073709551615, 18446744073709551615)
@@ -1798,34 +1798,34 @@ select substring('hello', -18446744073709551616, -18446744073709551616);
substring('hello', -18446744073709551616, -18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select substring('hello', 18446744073709551616, 18446744073709551616);
substring('hello', 18446744073709551616, 18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select substring('hello', -18446744073709551617, -18446744073709551617);
substring('hello', -18446744073709551617, -18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select substring('hello', 18446744073709551617, 18446744073709551617);
substring('hello', 18446744073709551617, 18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select insert('hello', -1, 1, 'hi');
insert('hello', -1, 1, 'hi')
hello
@@ -1851,7 +1851,7 @@ select insert('hello', -18446744073709551615, 1, 'hi');
insert('hello', -18446744073709551615, 1, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select insert('hello', 18446744073709551615, 1, 'hi');
insert('hello', 18446744073709551615, 1, 'hi')
hello
@@ -1859,22 +1859,22 @@ select insert('hello', -18446744073709551616, 1, 'hi');
insert('hello', -18446744073709551616, 1, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select insert('hello', 18446744073709551616, 1, 'hi');
insert('hello', 18446744073709551616, 1, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select insert('hello', -18446744073709551617, 1, 'hi');
insert('hello', -18446744073709551617, 1, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select insert('hello', 18446744073709551617, 1, 'hi');
insert('hello', 18446744073709551617, 1, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select insert('hello', 1, -1, 'hi');
insert('hello', 1, -1, 'hi')
hi
@@ -1900,7 +1900,7 @@ select insert('hello', 1, -18446744073709551615, 'hi');
insert('hello', 1, -18446744073709551615, 'hi')
hi
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select insert('hello', 1, 18446744073709551615, 'hi');
insert('hello', 1, 18446744073709551615, 'hi')
hi
@@ -1908,22 +1908,22 @@ select insert('hello', 1, -18446744073709551616, 'hi');
insert('hello', 1, -18446744073709551616, 'hi')
hi
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select insert('hello', 1, 18446744073709551616, 'hi');
insert('hello', 1, 18446744073709551616, 'hi')
hi
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select insert('hello', 1, -18446744073709551617, 'hi');
insert('hello', 1, -18446744073709551617, 'hi')
hi
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select insert('hello', 1, 18446744073709551617, 'hi');
insert('hello', 1, 18446744073709551617, 'hi')
hi
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select insert('hello', -1, -1, 'hi');
insert('hello', -1, -1, 'hi')
hello
@@ -1949,8 +1949,8 @@ select insert('hello', -18446744073709551615, -18446744073709551615, 'hi');
insert('hello', -18446744073709551615, -18446744073709551615, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select insert('hello', 18446744073709551615, 18446744073709551615, 'hi');
insert('hello', 18446744073709551615, 18446744073709551615, 'hi')
hello
@@ -1958,26 +1958,26 @@ select insert('hello', -18446744073709551616, -18446744073709551616, 'hi');
insert('hello', -18446744073709551616, -18446744073709551616, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select insert('hello', 18446744073709551616, 18446744073709551616, 'hi');
insert('hello', 18446744073709551616, 18446744073709551616, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
select insert('hello', -18446744073709551617, -18446744073709551617, 'hi');
insert('hello', -18446744073709551617, -18446744073709551617, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select insert('hello', 18446744073709551617, 18446744073709551617, 'hi');
insert('hello', 18446744073709551617, 18446744073709551617, 'hi')
hello
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
select repeat('hello', -1);
repeat('hello', -1)
@@ -2009,8 +2009,8 @@ select repeat('hello', -18446744073709551615);
repeat('hello', -18446744073709551615)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select repeat('hello', 18446744073709551615);
repeat('hello', 18446744073709551615)
NULL
@@ -2020,27 +2020,27 @@ select repeat('hello', -18446744073709551616);
repeat('hello', -18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select repeat('hello', 18446744073709551616);
repeat('hello', 18446744073709551616)
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
select repeat('hello', -18446744073709551617);
repeat('hello', -18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select repeat('hello', 18446744073709551617);
repeat('hello', 18446744073709551617)
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
select space(-1);
space(-1)
@@ -2073,8 +2073,8 @@ select space(-18446744073709551615);
space(-18446744073709551615)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select space(18446744073709551615);
space(18446744073709551615)
NULL
@@ -2084,27 +2084,27 @@ select space(-18446744073709551616);
space(-18446744073709551616)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select space(18446744073709551616);
space(18446744073709551616)
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
select space(-18446744073709551617);
space(-18446744073709551617)
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select space(18446744073709551617);
space(18446744073709551617)
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated
select rpad('hello', -1, '1');
rpad('hello', -1, '1')
@@ -2137,8 +2137,8 @@ select rpad('hello', -18446744073709551615, '1');
rpad('hello', -18446744073709551615, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select rpad('hello', 18446744073709551615, '1');
rpad('hello', 18446744073709551615, '1')
NULL
@@ -2148,27 +2148,27 @@ select rpad('hello', -18446744073709551616, '1');
rpad('hello', -18446744073709551616, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select rpad('hello', 18446744073709551616, '1');
rpad('hello', 18446744073709551616, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
Warning 1301 Result of rpad() was larger than max_allowed_packet (1048576) - truncated
select rpad('hello', -18446744073709551617, '1');
rpad('hello', -18446744073709551617, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select rpad('hello', 18446744073709551617, '1');
rpad('hello', 18446744073709551617, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
Warning 1301 Result of rpad() was larger than max_allowed_packet (1048576) - truncated
select lpad('hello', -1, '1');
lpad('hello', -1, '1')
@@ -2201,8 +2201,8 @@ select lpad('hello', -18446744073709551615, '1');
lpad('hello', -18446744073709551615, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551615' to INT. Value truncated.
select lpad('hello', 18446744073709551615, '1');
lpad('hello', 18446744073709551615, '1')
NULL
@@ -2212,27 +2212,27 @@ select lpad('hello', -18446744073709551616, '1');
lpad('hello', -18446744073709551616, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551616' to INT. Value truncated.
select lpad('hello', 18446744073709551616, '1');
lpad('hello', 18446744073709551616, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated.
Warning 1301 Result of lpad() was larger than max_allowed_packet (1048576) - truncated
select lpad('hello', -18446744073709551617, '1');
lpad('hello', -18446744073709551617, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '-18446744073709551617' to INT. Value truncated.
select lpad('hello', 18446744073709551617, '1');
lpad('hello', 18446744073709551617, '1')
NULL
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
+Error 1916 Got overflow when converting '18446744073709551617' to INT. Value truncated.
Warning 1301 Result of lpad() was larger than max_allowed_packet (1048576) - truncated
SET @orig_sql_mode = @@SQL_MODE;
SET SQL_MODE=traditional;
diff --git a/mysql-test/suite/pbxt/r/func_timestamp.result b/mysql-test/suite/pbxt/r/func_timestamp.result
index 495fedea9e6..18fcbd947e7 100644
--- a/mysql-test/suite/pbxt/r/func_timestamp.result
+++ b/mysql-test/suite/pbxt/r/func_timestamp.result
@@ -7,7 +7,7 @@ SELECT CONCAT(Jahr,'-',Monat,'-',Tag,' ',Zeit) AS Date,
UNIX_TIMESTAMP(CONCAT(Jahr,'-',Monat,'-',Tag,' ',Zeit)) AS Unix
FROM t1;
Date Unix
-1998-9-16 09:26:00 905927160
-1998-9-16 09:26:00 905927160
+1998-9-16 09:26:00 905927160.000000
+1998-9-16 09:26:00 905927160.000000
drop table t1;
set time_zone= @@global.time_zone;
diff --git a/mysql-test/suite/pbxt/r/grant_cache.result b/mysql-test/suite/pbxt/r/grant_cache.result
index 500965fd646..d5189532370 100644
--- a/mysql-test/suite/pbxt/r/grant_cache.result
+++ b/mysql-test/suite/pbxt/r/grant_cache.result
@@ -168,7 +168,7 @@ Variable_name Value
Qcache_hits 7
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 7
+Qcache_not_cached 4
select "user4";
user4
user4
@@ -198,7 +198,7 @@ Variable_name Value
Qcache_hits 8
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 8
+Qcache_not_cached 5
set names binary;
delete from mysql.user where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
delete from mysql.db where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
diff --git a/mysql-test/suite/pbxt/r/greedy_optimizer.result b/mysql-test/suite/pbxt/r/greedy_optimizer.result
index 1d3e42b70fb..6297b51328a 100644
--- a/mysql-test/suite/pbxt/r/greedy_optimizer.result
+++ b/mysql-test/suite/pbxt/r/greedy_optimizer.result
@@ -1,4 +1,6 @@
drop table if exists t1,t2,t3,t4,t5,t6,t7;
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
create table t1 (
c11 integer,c12 integer,c13 integer,c14 integer,c15 integer,c16 integer,
primary key (c11)
@@ -121,11 +123,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 +135,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
@@ -200,76 +202,76 @@ select @@optimizer_search_depth;
0
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
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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 822.625316
+Last_query_cost 1372.225316
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
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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 822.625316
+Last_query_cost 1372.225316
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
+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 290.146368
+Last_query_cost 363.346368
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
+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 290.146368
+Last_query_cost 363.346368
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
+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 290.146368
+Last_query_cost 363.346368
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
+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 290.146368
+Last_query_cost 363.346368
set optimizer_search_depth=1;
select @@optimizer_search_depth;
@@optimizer_search_depth
@@ -277,151 +279,151 @@ 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
-Last_query_cost 822.625316
+Last_query_cost 1694.425316
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
+Last_query_cost 1694.425316
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
+Last_query_cost 844.825316
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
+Last_query_cost 844.825316
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
+Last_query_cost 844.825316
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
+Last_query_cost 844.825316
set optimizer_search_depth=62;
select @@optimizer_search_depth;
@@optimizer_search_depth
62
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
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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 822.625316
+Last_query_cost 1372.225316
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
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
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
show status like 'Last_query_cost';
Variable_name Value
-Last_query_cost 822.625316
+Last_query_cost 1372.225316
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
+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 290.146368
+Last_query_cost 363.346368
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index
+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 290.146368
+Last_query_cost 363.346368
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
+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 290.146368
+Last_query_cost 363.346368
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 t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where
+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 290.146368
+Last_query_cost 363.346368
set optimizer_prune_level=1;
select @@optimizer_prune_level;
@@optimizer_prune_level
@@ -433,75 +435,75 @@ 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
-Last_query_cost 822.625316
+Last_query_cost 1694.425316
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
+Last_query_cost 1694.425316
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 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 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 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 (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
+Last_query_cost 844.825316
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 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 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 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 (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
+Last_query_cost 844.825316
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 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 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 t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
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 (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
+Last_query_cost 844.825316
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 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 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 t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
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 (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
+Last_query_cost 844.825316
set optimizer_search_depth=1;
select @@optimizer_search_depth;
@@optimizer_search_depth
@@ -509,75 +511,75 @@ 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
-Last_query_cost 822.625316
+Last_query_cost 1694.425316
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
+Last_query_cost 1694.425316
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
+Last_query_cost 844.825316
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
+Last_query_cost 844.825316
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
+Last_query_cost 844.825316
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
+Last_query_cost 844.825316
set optimizer_search_depth=62;
select @@optimizer_search_depth;
@@optimizer_search_depth
@@ -585,73 +587,74 @@ 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
-Last_query_cost 822.625316
+Last_query_cost 1694.425316
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
+Last_query_cost 1694.425316
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 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 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 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 (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
+Last_query_cost 844.825316
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 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 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 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 (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
+Last_query_cost 844.825316
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 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 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 t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
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 (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
+Last_query_cost 844.825316
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 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 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 t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer
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 (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
+Last_query_cost 844.825316
drop table t1,t2,t3,t4,t5,t6,t7;
+set join_cache_level=@save_join_cache_level;
diff --git a/mysql-test/suite/pbxt/r/group_by.result b/mysql-test/suite/pbxt/r/group_by.result
index c5c9099af0d..06cb168b3aa 100644
--- a/mysql-test/suite/pbxt/r/group_by.result
+++ b/mysql-test/suite/pbxt/r/group_by.result
@@ -450,6 +450,8 @@ drop table t1,t2;
CREATE TABLE t1 (ID1 int, ID2 int, ID int NOT NULL AUTO_INCREMENT,PRIMARY KEY(ID
));
insert into t1 values (1,244,NULL),(2,243,NULL),(134,223,NULL),(185,186,NULL);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select S.ID as xID, S.ID1 as xID1 from t1 as S left join t1 as yS on S.ID1 between yS.ID1 and yS.ID2;
xID xID1
1 1
@@ -468,6 +470,7 @@ xID xID1 Level
2 2 **
3 134 ***
4 185 ****
+SET optimizer_switch=@save_optimizer_switch;
drop table t1;
CREATE TABLE t1 (
pid int(11) unsigned NOT NULL default '0',
@@ -537,11 +540,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 +859,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..15554216056 100644
--- a/mysql-test/suite/pbxt/r/group_min_max.result
+++ b/mysql-test/suite/pbxt/r/group_min_max.result
@@ -876,10 +876,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 129 Using where; Using index for group-by
explain select a1,a2,b, max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL idx_t1_1 163 NULL 129 Using where; Using index for group-by
+1 SIMPLE t1 range NULL idx_t1_1 147 NULL 129 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL idx_t1_1 163 NULL 129 Using where; Using index for group-by
+1 SIMPLE t1 range NULL idx_t1_1 147 NULL 129 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b111') and (c <= 'g112') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 129 Using where; Using index for group-by
@@ -924,7 +924,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
explain select a1,a2,b, max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
+1 SIMPLE t2 range NULL idx_t2_1 146 NULL # Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
@@ -1364,7 +1364,7 @@ explain select a1,a2,b,min(c),max(c) from t1
where exists ( select * from t2 where t2.c > 'b1' )
group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 range NULL idx_t1_1 147 NULL 129 Using index for group-by
+1 PRIMARY t1 range NULL idx_t1_1 147 NULL 129 Using where; Using index for group-by
2 SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
explain select a1,a2,b,min(c),max(c) from t1 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
@@ -2247,17 +2247,18 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE EXISTS
(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 index
-2 SUBQUERY t1 index NULL a 10 NULL 15 Using index
+2 SUBQUERY t1 index NULL a 10 NULL 1 Using index
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
(SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 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
+1 PRIMARY t1_outer index NULL a 10 NULL 15 Using index
2 SUBQUERY t1 index NULL a 10 NULL 15 Using index
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
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 15
+1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 1 Using index
+2 MATERIALIZED 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 +2269,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/join.result b/mysql-test/suite/pbxt/r/join.result
index a74ee3d3b35..3a1759a18f4 100644
--- a/mysql-test/suite/pbxt/r/join.result
+++ b/mysql-test/suite/pbxt/r/join.result
@@ -1,4 +1,6 @@
drop table if exists t1,t2,t3;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
CREATE TABLE t1 (S1 INT);
CREATE TABLE t2 (S1 INT);
INSERT INTO t1 VALUES (1);
@@ -699,9 +701,9 @@ select * from v1a join v1b on t1.b = t2.b;
ERROR 42S22: Unknown column 't1.b' in 'on clause'
select * from information_schema.statistics join information_schema.columns
using(table_name,column_name) where table_name='user';
-TABLE_NAME COLUMN_NAME TABLE_CATALOG TABLE_SCHEMA NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT TABLE_CATALOG TABLE_SCHEMA ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-user Host NULL mysql 0 mysql PRIMARY 1 A NULL NULL NULL BTREE NULL mysql 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI #
-user User NULL mysql 0 mysql PRIMARY 2 A 3 NULL NULL BTREE NULL mysql 2 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI #
+TABLE_NAME COLUMN_NAME TABLE_CATALOG TABLE_SCHEMA NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT TABLE_CATALOG TABLE_SCHEMA ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
+user Host NULL mysql 0 mysql PRIMARY 1 A NULL NULL NULL BTREE NULL mysql 1 NO char 60 180 NULL NULL NULL utf8 utf8_bin char(60) PRI #
+user User NULL mysql 0 mysql PRIMARY 2 A 3 NULL NULL BTREE NULL mysql 2 NO char 16 48 NULL NULL NULL utf8 utf8_bin char(16) PRI #
drop table t1;
drop table t2;
drop table t3;
@@ -774,7 +776,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,12 +796,12 @@ 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
-Last_query_cost 24.262158
+Last_query_cost 28.262158
select '^^: The above should be ~= 20 + cost(select * from t1). Value less than 20 is an error' Z;
Z
^^: The above should be ~= 20 + cost(select * from t1). Value less than 20 is an error
@@ -819,4 +821,5 @@ Field Type Null Key Default Extra
Name varchar(50) YES NULL
DROP VIEW v1;
DROP TABLE t1,t2,tv1,tv2;
+SET optimizer_switch=@save_optimizer_switch;
End of 5.0 tests.
diff --git a/mysql-test/suite/pbxt/r/join_nested.result b/mysql-test/suite/pbxt/r/join_nested.result
index 99a260e0e6a..edbf3f94fca 100644
--- a/mysql-test/suite/pbxt/r/join_nested.result
+++ b/mysql-test/suite/pbxt/r/join_nested.result
@@ -1,4 +1,6 @@
DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5,t6,t7,t8,t9;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
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);
@@ -74,7 +76,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 +152,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 +182,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 +231,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 +546,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 +641,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 +649,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 +838,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 +852,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 +908,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 +916,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 +958,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 +1007,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,10 +1015,11 @@ 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
+INSERT INTO t1 VALUES (-1,133,0), (-2,12,0), (-3,11,0), (-5,15,0);
CREATE INDEX idx_b ON t1(b);
CREATE INDEX idx_a ON t0(a);
EXPLAIN
@@ -1041,7 +1044,7 @@ ON t6.b >= 2 AND t5.b=t7.b
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
-(t1.a != 2),
+(t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -1064,7 +1067,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
@@ -1089,7 +1092,7 @@ ON t6.b >= 2 AND t5.b=t7.b
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
-(t1.a != 2),
+(t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -1204,13 +1207,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 +1283,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
@@ -1317,7 +1320,7 @@ c11 c21
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 t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t2 ALL NULL NULL NULL NULL 0
+1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where
SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON c21=c31) ON c11=c21;
c11 c21 c31
4 NULL NULL
@@ -1325,8 +1328,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 +1456,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 +1464,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 +1489,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));
@@ -1613,3 +1616,4 @@ WHERE t1.id='5';
id ct pc nm
5 NULL NULL NULL
DROP TABLE t1,t2,t3,t4;
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/suite/pbxt/r/join_outer.result b/mysql-test/suite/pbxt/r/join_outer.result
index 31813a4f06c..fa41e005e07 100644
--- a/mysql-test/suite/pbxt/r/join_outer.result
+++ b/mysql-test/suite/pbxt/r/join_outer.result
@@ -1,4 +1,6 @@
drop table if exists t0,t1,t2,t3,t4,t5;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
CREATE TABLE t1 (
grp int(11) default NULL,
a bigint(20) unsigned default NULL,
@@ -630,7 +632,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 +690,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 +861,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 +877,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 +888,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);
@@ -1194,3 +1196,4 @@ a b
3 3
4 NULL
DROP TABLE t1,t2;
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/suite/pbxt/r/key_cache.result b/mysql-test/suite/pbxt/r/key_cache.result
index 1ea3b2a714a..4df1bbf0ff7 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/key_diff.result b/mysql-test/suite/pbxt/r/key_diff.result
index 33bedfcc39e..99bc7e7f8ad 100644
--- a/mysql-test/suite/pbxt/r/key_diff.result
+++ b/mysql-test/suite/pbxt/r/key_diff.result
@@ -6,7 +6,12 @@ KEY (a),
KEY (b)
);
INSERT INTO t1 VALUES ('A','B'),('b','A'),('C','c'),('D','E'),('a','a');
-select * from t1,t1 as t2;
+INSERT INTO t1 VALUES
+('AA','BB'),('bb','AA'),('CC','cc'),('DD','EE'),('aa','aa');
+INSERT INTO t1 VALUES
+('AAA','BBB'),('bbb','AAA'),('CCC','ccc'),('DDD','EEE'),('aaa','aaa');
+select * from t1,t1 as t2
+where length(t1.A)=1 and length(t2.B)=1 ;
a b a b
A B A B
b A A B
@@ -33,11 +38,14 @@ b A a a
C c a a
D E a a
a a a a
-explain select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B;
+explain select t1.*,t2.* from t1,t1 as t2
+where t1.A=t2.B and length(t1.A)=1 and length(t2.B)=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL a NULL NULL NULL 5
+1 SIMPLE t1 ALL a NULL NULL NULL 15 Using where
1 SIMPLE t2 ref b b 4 test.t1.a 1 Using where
-select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B order by binary t1.a,t2.a;
+select t1.*,t2.* from t1,t1 as t2
+where t1.A=t2.B and length(t1.A)=1 and length(t2.B)=1
+order by binary t1.a,t2.a;
a b a b
A B a a
A B b A
diff --git a/mysql-test/suite/pbxt/r/lock_multi.result b/mysql-test/suite/pbxt/r/lock_multi.result
index 731ccedeecb..d9ff5f3fc55 100644
--- a/mysql-test/suite/pbxt/r/lock_multi.result
+++ b/mysql-test/suite/pbxt/r/lock_multi.result
@@ -139,7 +139,7 @@ lock table t1 read;
update t1 set i= 10;
select * from t1;
Timeout in wait_condition.inc for select count(*) = 1 from information_schema.processlist
-where state = "Locked" and info = "select * from t1"
+where state = "Table Lock" and info = "select * from t1"
kill query ID;
i
ERROR 70100: Query execution was interrupted
diff --git a/mysql-test/suite/pbxt/r/metadata.result b/mysql-test/suite/pbxt/r/metadata.result
index c46c6e26ce4..878163a360e 100644
--- a/mysql-test/suite/pbxt/r/metadata.result
+++ b/mysql-test/suite/pbxt/r/metadata.result
@@ -21,7 +21,7 @@ def test t1 t1 g g 5 4 0 Y 32768 3 63
def test t1 t1 h h 246 7 0 Y 0 4 63
def test t1 t1 i i 13 4 0 Y 32864 0 63
def test t1 t1 j j 10 10 0 Y 128 0 63
-def test t1 t1 k k 7 19 0 N 9441 0 63
+def test t1 t1 k k 7 19 0 N 9377 0 63
def test t1 t1 l l 12 19 0 Y 128 0 63
def test t1 t1 m m 254 1 0 Y 256 0 8
def test t1 t1 n n 254 3 0 Y 2048 0 8
diff --git a/mysql-test/suite/pbxt/r/negation_elimination.result b/mysql-test/suite/pbxt/r/negation_elimination.result
index 3b968e396c5..886a4215d11 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
@@ -321,13 +321,13 @@ select * from t1 where not(NULL or a);
a
explain select * from t1 where not(NULL and a);
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(NULL and a);
a
0
explain select * from t1 where not((a < 5 or a < 10) and (not(a > 16) or a > 17));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index
select * from t1 where not((a < 5 or a < 10) and (not(a > 16) or a > 17));
a
10
@@ -342,7 +342,7 @@ a
19
explain select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index
+1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index
select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17));
a
5
diff --git a/mysql-test/suite/pbxt/r/null_key.result b/mysql-test/suite/pbxt/r/null_key.result
index 8a440284c53..cc2b417b263 100644
--- a/mysql-test/suite/pbxt/r/null_key.result
+++ b/mysql-test/suite/pbxt/r/null_key.result
@@ -76,13 +76,13 @@ 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));
explain select * from t1 where a is null and b = 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
+1 SIMPLE t1 ref a,b a 5 const 3 Using index condition; Using where
explain select * from t1 where a is null and b = 2 and c=0;
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
+1 SIMPLE t1 ref a,b a 5 const 3 Using index condition; Using where
explain select * from t1 where a is null and b = 7 and c=0;
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
+1 SIMPLE t1 ref a,b a 5 const 3 Using index condition; Using where
explain select * from t1 where a=2 and b = 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a,b a 5 const 1 Using where
@@ -91,25 +91,25 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 12 Using where
explain select * from t1 where (a is null or a > 0 and a < 3) and b < 5 and c=0 limit 3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a,b a 5 NULL 5 Using where
+1 SIMPLE t1 range a,b a 5 NULL 5 Using index condition; Using where
explain select * from t1 where (a is null or a = 7) and b=7 and c=0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null a,b a 5 const 4 Using where
+1 SIMPLE t1 ref_or_null a,b a 5 const 4 Using index condition; Using where
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
+1 SIMPLE t1 ref a,b a 5 const 3 Using index condition; Using where
explain select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
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
+1 SIMPLE t1 ref a,b a 5 const 3 Using index condition; Using where
explain select * from t1 where a > 1 and a < 3 limit 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 1 Using where
+1 SIMPLE t1 range a a 5 NULL 1 Using index condition
explain select * from t1 where a is null and b=7 or a > 1 and a < 3 limit 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a,b a 5 NULL 4 Using where
+1 SIMPLE t1 range a,b a 5 NULL 4 Using index condition; Using where
explain select * from t1 where a > 8 and a < 9;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 1 Using where
+1 SIMPLE t1 range a a 5 NULL 1 Using index condition
explain select * from t1 where b like "6%";
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range b b 12 NULL 1 Using where
@@ -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,7 +191,7 @@ 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 t2 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t1 ref_or_null a a 10 test.t2.a,const 4 Using where; Using index
select * from t2,t1 where t1.a=t2.a and (b= 7 or b is null);
a a b
@@ -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;
@@ -427,5 +427,6 @@ Handler_read_key 6
Handler_read_next 2
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 5
DROP TABLE t1,t2,t3,t4;
diff --git a/mysql-test/suite/pbxt/r/order_by.result b/mysql-test/suite/pbxt/r/order_by.result
index 79ff2d6bb3f..4f56f433169 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 '',
@@ -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 6adc79ce1ff..1d89d43bcfa 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
@@ -651,7 +651,7 @@ Variable_name Value
Handler_read_rnd_next 0
show status like 'Handler_read_key';
Variable_name Value
-Handler_read_key 10
+Handler_read_key 5
show status like 'Handler_read_prev';
Variable_name Value
Handler_read_prev 0
diff --git a/mysql-test/suite/pbxt/r/pbxt_locking.result b/mysql-test/suite/pbxt/r/pbxt_locking.result
index 5da337c62d1..fa823b9a7e2 100644
--- a/mysql-test/suite/pbxt/r/pbxt_locking.result
+++ b/mysql-test/suite/pbxt/r/pbxt_locking.result
@@ -13,9 +13,9 @@ id
update t1 set id = 8 where id = 5;
update t1 set id = 8 where id = 4;
show processlist;
-Id User Host db Command Time State Info
-x root x test Query x NULL show processlist
-x root x test Query x Searching rows for update update t1 set id = 8 where id = 4
+Id User Host db Command Time State Info Progress
+x root x test Query x NULL show processlist 0.000
+x root x test Query x Searching rows for update update t1 set id = 8 where id = 4 0.000
commit;
select * from t1;
id
@@ -49,9 +49,9 @@ id
update t1 set id = 8 where id < 4;
update t1 set id = 8 where id = 5;
show processlist;
-Id User Host db Command Time State Info
-x root x test Query x NULL show processlist
-x root x test Query x Searching rows for update update t1 set id = 8 where id = 5
+Id User Host db Command Time State Info Progress
+x root x test Query x NULL show processlist 0.000
+x root x test Query x Searching rows for update update t1 set id = 8 where id = 5 0.000
commit;
select * from t1;
id
diff --git a/mysql-test/suite/pbxt/r/pbxt_xa_binlog.result b/mysql-test/suite/pbxt/r/pbxt_xa_binlog.result
new file mode 100644
index 00000000000..abfeebb5b96
--- /dev/null
+++ b/mysql-test/suite/pbxt/r/pbxt_xa_binlog.result
@@ -0,0 +1,32 @@
+drop table if exists t1, t2;
+SET binlog_format = 'mixed';
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+SELECT @@log_bin;
+@@log_bin
+1
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+a
+1
+select * from t2;
+b
+2
+SET sql_log_bin = 0;
+BEGIN;
+INSERT INTO t1 VALUES (3);
+INSERT INTO t2 VALUES (4);
+COMMIT;
+select * from t1 order by a;
+a
+1
+3
+select * from t2 order by b;
+b
+2
+4
+drop table t1, t2;
+drop database pbxt;
diff --git a/mysql-test/suite/pbxt/r/ps_11bugs.result b/mysql-test/suite/pbxt/r/ps_11bugs.result
index 0be781bca27..5a2743436e1 100644
--- a/mysql-test/suite/pbxt/r/ps_11bugs.result
+++ b/mysql-test/suite/pbxt/r/ps_11bugs.result
@@ -120,9 +120,9 @@ create table t1 (a int primary key);
insert into t1 values (1);
explain select * from t1 where 3 in (select (1+1) union select 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 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
-3 UNION NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 1 Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
select * from t1 where 3 in (select (1+1) union select 1);
a
diff --git a/mysql-test/suite/pbxt/r/ps_1general.result b/mysql-test/suite/pbxt/r/ps_1general.result
index baa944eebab..2f4fa8200c2 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 37 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 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 fb7ce4b4049..3d512626a73 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
SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
a b
DROP TABLE t1;
@@ -922,17 +922,11 @@ 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
-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
+1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using index condition
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
item started price
-A1 2005-11-01 08:00:00 1000.000
-A1 2005-11-15 00:00:00 2000.000
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
+Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00'
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
item started price
A1 2005-11-01 08:00:00 1000.000
@@ -941,14 +935,10 @@ DROP INDEX `PRIMARY` ON t1;
EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
-Warnings:
-Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
item started price
-A1 2005-11-01 08:00:00 1000.000
-A1 2005-11-15 00:00:00 2000.000
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'
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
item started price
A1 2005-11-01 08:00:00 1000.000
diff --git a/mysql-test/suite/pbxt/r/read_only.result b/mysql-test/suite/pbxt/r/read_only.result
index 2eecb0a891d..32648cebfcc 100644
--- a/mysql-test/suite/pbxt/r/read_only.result
+++ b/mysql-test/suite/pbxt/r/read_only.result
@@ -48,7 +48,7 @@ unlock tables ;
set global read_only=1;
select @@global.read_only;
@@global.read_only
-0
+1
unlock tables ;
select @@global.read_only;
@@global.read_only
@@ -62,7 +62,7 @@ unlock tables ;
set global read_only=1;
select @@global.read_only;
@@global.read_only
-0
+1
unlock tables ;
select @@global.read_only;
@@global.read_only
diff --git a/mysql-test/suite/pbxt/r/select.result b/mysql-test/suite/pbxt/r/select.result
index 36bf4ea82ad..091451ac6b7 100644
--- a/mysql-test/suite/pbxt/r/select.result
+++ b/mysql-test/suite/pbxt/r/select.result
@@ -1,6 +1,8 @@
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;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
CREATE TABLE t1 (
Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
@@ -1397,15 +1399,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 +1423,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 +1439,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
@@ -2121,8 +2123,8 @@ INSERT INTO t2 VALUES (1,3,10,'2002-06-01 08:00:00',35),(1,3,1010,'2002-06-01 12
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
+Warning 1292 Incorrect datetime value: 'wrong-date-value'
+Warning 1292 Incorrect datetime value: 'wrong-date-value'
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;
@@ -2202,10 +2204,10 @@ a a
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 2
2 3
+3 2
3 3
select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
a a
@@ -2334,8 +2336,8 @@ 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 t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1
-1 SIMPLE t3 ALL NULL NULL NULL NULL 0
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where
1 SIMPLE t4 ref id4 id4 4 test.t3.id3 1 Using where
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;
@@ -2369,7 +2371,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 +2379,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 +2405,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 +2724,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 +2748,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 +2758,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 +2912,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
@@ -3265,7 +3267,7 @@ f1 f2
4 2005-10-01
5 2005-12-30
Warnings:
-Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1
+Warning 1292 Truncated incorrect date value: '2005-09-3a'
select * from t1 where f2 <= '2005-09-31';
f1 f2
1 2005-01-01
@@ -3276,7 +3278,7 @@ 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
+Warning 1292 Truncated incorrect date value: '2005-09-3a'
drop table t1;
create table t1 (f1 int, f2 int);
insert into t1 values (1, 30), (2, 20), (3, 10);
@@ -3466,12 +3468,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 +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 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 +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 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;
@@ -3639,3 +3641,4 @@ 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;
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/suite/pbxt/r/select_found.result b/mysql-test/suite/pbxt/r/select_found.result
index f707f703098..7232b24c7c6 100644
--- a/mysql-test/suite/pbxt/r/select_found.result
+++ b/mysql-test/suite/pbxt/r/select_found.result
@@ -84,7 +84,7 @@ UNIQUE KEY e_n (email,name)
EXPLAIN SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 200 Using temporary
-1 SIMPLE t1 ref kid kid 2 test.t2.id 1 Using where; Not exists; Distinct
+1 SIMPLE t1 ALL kid NULL NULL NULL 0 Using where; Not exists; Distinct; Using join buffer (flat, BNL join)
SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
email
email1
diff --git a/mysql-test/suite/pbxt/r/select_safe.result b/mysql-test/suite/pbxt/r/select_safe.result
index 70c66337b9f..25ac99dd17c 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/skip_name_resolve.result b/mysql-test/suite/pbxt/r/skip_name_resolve.result
index 8ef52e75238..ad74a2dfcc4 100644
--- a/mysql-test/suite/pbxt/r/skip_name_resolve.result
+++ b/mysql-test/suite/pbxt/r/skip_name_resolve.result
@@ -9,6 +9,6 @@ select user();
user()
#
show processlist;
-Id User Host db Command Time State Info
-<id> root <host> test <command> <time> <state> <info>
-<id> root <host> test <command> <time> <state> <info>
+Id User Host db Command Time State Info Progress
+<id> root <host> test <command> <time> <state> <info> 0.000
+<id> root <host> test <command> <time> <state> <info> 0.000
diff --git a/mysql-test/suite/pbxt/r/status.result b/mysql-test/suite/pbxt/r/status.result
index 519a55301a3..b0bcca00608 100644
--- a/mysql-test/suite/pbxt/r/status.result
+++ b/mysql-test/suite/pbxt/r/status.result
@@ -100,22 +100,30 @@ Variable_name Value
Com_show_status 3
show status like 'hand%write%';
Variable_name Value
+Handler_tmp_write 0
Handler_write 5
show status like '%tmp%';
Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_files 0
Created_tmp_tables 0
+Handler_tmp_update 0
+Handler_tmp_write 0
+Rows_tmp_read 5
show status like 'hand%write%';
Variable_name Value
+Handler_tmp_write 0
Handler_write 7
show status like '%tmp%';
Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_files 0
Created_tmp_tables 0
+Handler_tmp_update 0
+Handler_tmp_write 0
+Rows_tmp_read 13
show status like 'com_show_status';
Variable_name Value
Com_show_status 8
rnd_diff tmp_table_diff
-20 8
+28 8
diff --git a/mysql-test/suite/pbxt/r/subselect.result b/mysql-test/suite/pbxt/r/subselect.result
index 0b5c98324f4..7ce54f02327 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
@@ -196,14 +196,17 @@ 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
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
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
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 100.00
3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
Warnings:
-Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,'2' AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`tt`.`a` AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
+set optimizer_switch=@tmp_optimizer_switch;
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
@@ -224,7 +227,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t4.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select `test`.`t4`.`b` AS `b`,(select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+Note 1003 select `test`.`t4`.`b` AS `b`,<expr_cache><`test`.`t4`.`a`>((select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`)) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
select * from t3 where exists (select * from t2 where t2.b=t3.a);
a
7
@@ -270,7 +273,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(((select min(`test`.`t2`.`b`) from `test`.`t2`) <= `test`.`t3`.`a`))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2);
a
7
@@ -314,7 +317,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 +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;
@@ -362,12 +365,12 @@ INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where; Using index
4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
-2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where
3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
Warnings:
-Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
+Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
ERROR 21000: Operand should contain 1 column(s)
@@ -420,7 +423,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
+Note 1003 select 1 AS `1` from `test`.`t1` where (1 = (select 1 union select 1))
drop table t1;
CREATE TABLE `t1` (
`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
@@ -535,6 +538,12 @@ SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT
numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY t1 ref PRIMARY PRIMARY 3 const 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select 1 from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
ERROR 21000: Subquery returns more than 1 row
EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
id select_type table type possible_keys key key_len ref rows filtered Extra
@@ -543,10 +552,10 @@ 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
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select '3' AS `numreponse` from `test`.`t1` where (('1' = '1'))
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
drop table t1;
CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1);
@@ -719,7 +728,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 +740,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 +752,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 +885,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 +902,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;
@@ -904,9 +915,9 @@ explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) F
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 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 `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`)))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
drop table t1,t2,t3;
create table t1 (a float);
select 10.5 IN (SELECT * from t1 LIMIT 1);
@@ -1177,9 +1188,9 @@ SELECT 0 IN (SELECT 1 FROM t1 a);
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 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
INSERT INTO t1 (pseudo) VALUES ('test1');
SELECT 0 IN (SELECT 1 FROM t1 a);
0 IN (SELECT 1 FROM t1 a)
@@ -1187,9 +1198,9 @@ SELECT 0 IN (SELECT 1 FROM t1 a);
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 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
drop table t1;
CREATE TABLE `t1` (
`i` int(11) NOT NULL default '0',
@@ -1231,7 +1242,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using where
+1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using where
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
@@ -1256,7 +1267,7 @@ 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
+Warning 1242 Subquery returns more than 1 row
select * from t1;
a b
1 1
@@ -1293,31 +1304,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));
@@ -1325,6 +1336,8 @@ create table t3 (a int, b int, index a (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);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
select * from t2 where t2.a in (select a from t1);
a
2
@@ -1332,31 +1345,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
+1 PRIMARY t1 ref a a 5 test.t2.a 1 100.00 Using where; Using index
+1 PRIMARY t3 ref a a 5 test.t1.b 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>(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 +1382,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 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))
+SET optimizer_switch=@save_optimizer_switch;
drop table t1, t2, t3;
create table t1 (a int, b int);
create table t2 (a int, b int);
@@ -1463,25 +1477,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 not null);
create table t3 (a int);
@@ -1496,7 +1510,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(((select max(`test`.`t2`.`b`) from `test`.`t2`) > `test`.`t3`.`a`))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(`test`.`t2`.`b`) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2);
a
explain extended select * from t3 where a >= some (select b from t2);
@@ -1504,7 +1518,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(((select min(`test`.`t2`.`b`) from `test`.`t2`) <= `test`.`t3`.`a`))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2 group by 1);
a
6
@@ -1513,49 +1527,49 @@ a
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 ALL NULL NULL NULL NULL 0 0.00 Using temporary; Using filesort
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((<max>(select `test`.`t2`.`b` from `test`.`t2` group by 1) > `test`.`t3`.`a`))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(`test`.`t2`.`b`) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2 group by 1);
a
explain extended select * from t3 where a >= some (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00 Using temporary; Using filesort
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((<min>(select `test`.`t2`.`b` from `test`.`t2` group by 1) <= `test`.`t3`.`a`))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where NULL >= any (select b from t2);
a
explain extended select * from t3 where NULL >= any (select b from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= any (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
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 ALL NULL NULL NULL NULL 0 0.00 Using temporary; Using filesort
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= some (select b from t2);
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
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= some (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
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 ALL NULL NULL NULL NULL 0 0.00 Using temporary; Using filesort
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where 0
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= NULL)))
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
@@ -1564,9 +1578,9 @@ a
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
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= `test`.`t3`.`a`))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= <cache>(`test`.`t3`.`a`))))
drop table t2, t3;
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
@@ -1617,7 +1631,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION t1 ALL NULL NULL NULL NULL 1 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select `test`.`t1`.`s1` AS `s1` from `test`.`t1` where 1
+Note 1003 select `test`.`t1`.`s1` AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',(<min>(select `test`.`t1`.`s1` from `test`.`t1` union select `test`.`t1`.`s1` from `test`.`t1`) < 'f')))
drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
@@ -1736,14 +1750,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 +1785,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 +2294,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 +2765,9 @@ 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";
+SET optimizer_switch='semijoin_with_cache=off';
CREATE TABLE t1 (one int, two int, flag char(1));
CREATE TABLE t2 (one int, two int, flag char(1));
INSERT INTO t1 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
@@ -2820,20 +2838,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`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` 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
+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') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') 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`
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'));
@@ -2948,7 +2968,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using index
-1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 1 Using where
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
@@ -2960,7 +2980,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using index
-1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 1 Using where
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
@@ -3004,6 +3024,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 +3041,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
@@ -3102,10 +3125,10 @@ 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
+2
3
+4
SELECT a FROM t1
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
@@ -3114,8 +3137,8 @@ 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
+2
3
4
SELECT a FROM t1
@@ -3412,7 +3435,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
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
ALTER TABLE t1 ADD INDEX(a);
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
a b
@@ -3422,8 +3446,9 @@ 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
+1 PRIMARY t1 ALL a NULL NULL NULL 9 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
DROP TABLE t1;
create table t1( f1 int,f2 int);
insert into t1 values (1,1),(2,2);
@@ -3545,7 +3570,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
@@ -3667,8 +3692,6 @@ CREATE TABLE t1 (a int, b int auto_increment, PRIMARY KEY (b));
CREATE TABLE t2 (x int auto_increment, y int, z int,
PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
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;
@@ -4040,7 +4063,7 @@ CREATE TABLE t1 (a int, b int, KEY (a));
INSERT INTO t1 VALUES (1,1),(2,1);
EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref a a 5 const 1 Using where; Using index
+1 PRIMARY t1 ref a a 5 const 0 Using where; Using index
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
DROP TABLE t1;
CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
@@ -4104,8 +4127,6 @@ 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
@@ -4204,6 +4225,9 @@ LEFT(t1.a1,1)
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;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+SET optimizer_switch='materialization=off';
CREATE TABLE t1 (a CHAR(1), b VARCHAR(10));
INSERT INTO t1 VALUES ('a', 'aa');
INSERT INTO t1 VALUES ('a', 'aaa');
@@ -4213,8 +4237,8 @@ CREATE INDEX I1 ON t1 (a);
CREATE INDEX I2 ON t1 (b);
EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 1 Using index; Using where
+1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where
+1 PRIMARY t1 ref I1 I1 2 test.t1.b 1 Using where; Using index; FirstMatch(t1)
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
a b
CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10));
@@ -4223,18 +4247,19 @@ CREATE INDEX I1 ON t2 (a);
CREATE INDEX I2 ON t2 (b);
EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2 index_subquery I1 I1 4 func 1 Using index; Using where
+1 PRIMARY t2 ALL I2 NULL NULL NULL 2 Using where
+1 PRIMARY t2 ref I1 I1 4 test.t2.b 1 Using where; Using index; FirstMatch(t2)
SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
a b
EXPLAIN
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 1 Using index; Using where
+1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where
+1 PRIMARY t1 ref I1 I1 2 test.t1.b 1 Using where; Using index; FirstMatch(t1)
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
a b
DROP TABLE t1,t2;
+SET optimizer_switch= @save_optimizer_switch;
CREATE TABLE t1(a INT, b INT);
INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4);
EXPLAIN
@@ -4275,7 +4300,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/type_bit.result b/mysql-test/suite/pbxt/r/type_bit.result
index c2969d00f74..bfe4e2aa8d9 100644
--- a/mysql-test/suite/pbxt/r/type_bit.result
+++ b/mysql-test/suite/pbxt/r/type_bit.result
@@ -36,7 +36,7 @@ select 0 + b'1000000000000001';
32769
drop table if exists t1,t2;
create table t1 (a bit(65));
-ERROR 42000: Display width out of range for column 'a' (max = 64)
+ERROR 42000: Display width out of range for 'a' (max = 64)
create table t1 (a bit(0));
show create table t1;
Table Create Table
diff --git a/mysql-test/suite/pbxt/r/type_datetime.result b/mysql-test/suite/pbxt/r/type_datetime.result
index 4ad10269211..255e8c33735 100644
--- a/mysql-test/suite/pbxt/r/type_datetime.result
+++ b/mysql-test/suite/pbxt/r/type_datetime.result
@@ -53,7 +53,7 @@ t
truncate table t1;
insert into t1 values("2003-0303 12:13:14");
Warnings:
-Warning 1264 Out of range value for column 't' at row 1
+Warning 1265 Data truncated for column 't' at row 1
select * from t1;
t
0000-00-00 00:00:00
@@ -116,12 +116,12 @@ create table t1 (t datetime);
insert into t1 values (20030102030460),(20030102036301),(20030102240401),
(20030132030401),(20031302030401),(100001202030401);
Warnings:
-Warning 1264 Out of range value for column 't' at row 1
-Warning 1264 Out of range value for column 't' at row 2
-Warning 1264 Out of range value for column 't' at row 3
-Warning 1264 Out of range value for column 't' at row 4
-Warning 1264 Out of range value for column 't' at row 5
-Warning 1264 Out of range value for column 't' at row 6
+Warning 1265 Data truncated for column 't' at row 1
+Warning 1265 Data truncated for column 't' at row 2
+Warning 1265 Data truncated for column 't' at row 3
+Warning 1265 Data truncated for column 't' at row 4
+Warning 1265 Data truncated for column 't' at row 5
+Warning 1265 Data truncated for column 't' at row 6
select * from t1;
t
0000-00-00 00:00:00
@@ -135,12 +135,12 @@ insert into t1 values
("2003-01-02 03:04:60"),("2003-01-02 03:63:01"),("2003-01-02 24:04:01"),
("2003-01-32 03:04:01"),("2003-13-02 03:04:01"), ("10000-12-02 03:04:00");
Warnings:
-Warning 1264 Out of range value for column 't' at row 1
-Warning 1264 Out of range value for column 't' at row 2
-Warning 1264 Out of range value for column 't' at row 3
-Warning 1264 Out of range value for column 't' at row 4
-Warning 1264 Out of range value for column 't' at row 5
-Warning 1264 Out of range value for column 't' at row 6
+Warning 1265 Data truncated for column 't' at row 1
+Warning 1265 Data truncated for column 't' at row 2
+Warning 1265 Data truncated for column 't' at row 3
+Warning 1265 Data truncated for column 't' at row 4
+Warning 1265 Data truncated for column 't' at row 5
+Warning 1265 Data truncated for column 't' at row 6
select * from t1;
t
0000-00-00 00:00:00
@@ -152,8 +152,8 @@ t
delete from t1;
insert into t1 values ("0000-00-00 00:00:00 some trailer"),("2003-01-01 00:00:00 some trailer");
Warnings:
-Warning 1264 Out of range value for column 't' at row 1
-Warning 1264 Out of range value for column 't' at row 2
+Warning 1265 Data truncated for column 't' at row 1
+Warning 1265 Data truncated for column 't' at row 2
select * from t1 order by t;
t
0000-00-00 00:00:00
@@ -191,4 +191,4 @@ CAST(CAST('2006-08-10 10:11:12' AS DATETIME) + INTERVAL 14 MICROSECOND AS DECIMA
20060810101112.000014
SELECT CAST(CAST('10:11:12.098700' AS TIME) AS DECIMAL(20,6));
CAST(CAST('10:11:12.098700' AS TIME) AS DECIMAL(20,6))
-101112.098700
+101112.000000
diff --git a/mysql-test/suite/pbxt/r/type_decimal.result b/mysql-test/suite/pbxt/r/type_decimal.result
index a478a369404..138e804362d 100644
--- a/mysql-test/suite/pbxt/r/type_decimal.result
+++ b/mysql-test/suite/pbxt/r/type_decimal.result
@@ -720,7 +720,7 @@ t1 CREATE TABLE `t1` (
) ENGINE=PBXT DEFAULT CHARSET=latin1
drop table t1;
create table t1 (d decimal(66,0));
-ERROR 42000: Too big precision 66 specified for column 'd'. Maximum is 65.
+ERROR 42000: Too big precision 66 specified for 'd'. Maximum is 65.
CREATE TABLE t1 (i INT, d1 DECIMAL(9,2), d2 DECIMAL(9,2));
INSERT INTO t1 VALUES (1, 101.40, 21.40), (1, -80.00, 0.00),
(2, 0.00, 0.00), (2, -13.20, 0.00), (2, 59.60, 46.40),
diff --git a/mysql-test/suite/pbxt/r/type_float.result b/mysql-test/suite/pbxt/r/type_float.result
index 4029909bce3..df5499f91a5 100644
--- a/mysql-test/suite/pbxt/r/type_float.result
+++ b/mysql-test/suite/pbxt/r/type_float.result
@@ -133,7 +133,7 @@ min(a)
-0.010
drop table t1;
create table t1 (a float(200,100), b double(200,100));
-ERROR 42000: Too big scale 100 specified for column 'a'. Maximum is 30.
+ERROR 42000: Too big scale 100 specified for 'a'. Maximum is 30.
create table t1 (c20 char);
insert into t1 values (5000.0);
Warnings:
diff --git a/mysql-test/suite/pbxt/r/type_newdecimal.result b/mysql-test/suite/pbxt/r/type_newdecimal.result
index 4978a244c76..565c37bb6e1 100644
--- a/mysql-test/suite/pbxt/r/type_newdecimal.result
+++ b/mysql-test/suite/pbxt/r/type_newdecimal.result
@@ -825,7 +825,7 @@ Error 1365 Division by 0
Error 1365 Division by 0
Error 1365 Division by 0
INSERT INTO Sow6_2f VALUES ('a59b');
-ERROR HY000: Incorrect decimal value: 'a59b' for column 'col1' at row 1
+ERROR 22007: Incorrect decimal value: 'a59b' for column 'col1' at row 1
drop table Sow6_2f;
select 10.3330000000000/12.34500000;
10.3330000000000/12.34500000
@@ -838,12 +838,12 @@ select 9999999999999999999999999999999999999999999999999999999999999999999999999
x
99999999999999999999999999999999999999999999999999999999999999999
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 1 as x;
x
100000000000000000000000000000000000000000000000000000000000000000
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
select 0.190287977636363637 + 0.040372670 * 0 - 0;
0.190287977636363637 + 0.040372670 * 0 - 0
0.190287977636363637
@@ -923,11 +923,11 @@ ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column
select cast(ln(14000) as decimal(2,3)) c1;
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '').
create table t1 (sl decimal(70,30));
-ERROR 42000: Too big precision 70 specified for column 'sl'. Maximum is 65.
+ERROR 42000: Too big precision 70 specified for 'sl'. Maximum is 65.
create table t1 (sl decimal(32,31));
-ERROR 42000: Too big scale 31 specified for column 'sl'. Maximum is 30.
+ERROR 42000: Too big scale 31 specified for 'sl'. Maximum is 30.
create table t1 (sl decimal(0,38));
-ERROR 42000: Too big scale 38 specified for column 'sl'. Maximum is 30.
+ERROR 42000: Too big scale 38 specified for 'sl'. Maximum is 30.
create table t1 (sl decimal(0,30));
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'sl').
create table t1 (sl decimal(5, 5));
@@ -1368,15 +1368,15 @@ create table t1 (c1 decimal(64));
insert into t1 values(
89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Warning 1264 Out of range value for column 'c1' at row 1
insert into t1 values(
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 *
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999);
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
+Error 1916 Got overflow when converting '' to DECIMAL. Value truncated.
Warning 1264 Out of range value for column 'c1' at row 1
insert into t1 values(1e100);
Warnings:
@@ -1447,4 +1447,4 @@ select cast(19999999999999999999 as unsigned);
cast(19999999999999999999 as unsigned)
18446744073709551615
Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
+Error 1916 Got overflow when converting '19999999999999999999' to UNSIGNED INT. Value truncated.
diff --git a/mysql-test/suite/pbxt/r/type_time.result b/mysql-test/suite/pbxt/r/type_time.result
index ce820c0cb8e..86aef8683ce 100644
--- a/mysql-test/suite/pbxt/r/type_time.result
+++ b/mysql-test/suite/pbxt/r/type_time.result
@@ -1,6 +1,8 @@
drop table if exists t1;
create table t1 (t time);
insert into t1 values("10:22:33"),("12:34:56.78"),(10),(1234),(123456.78),(1234559.99),("1"),("1:23"),("1:23:45"), ("10.22"), ("-10 1:22:33.45"),("20 10:22:33"),("1999-02-03 20:33:34");
+Warnings:
+Note 1265 Data truncated for column 't' at row 13
insert t1 values (30),(1230),("1230"),("12:30"),("12:30:35"),("1 12:30:31.32");
select * from t1;
t
@@ -26,9 +28,9 @@ t
insert into t1 values("10.22.22"),(1234567),(123456789),(123456789.10),("10 22:22"),("12.45a");
Warnings:
Warning 1265 Data truncated for column 't' at row 1
-Warning 1264 Out of range value for column 't' at row 2
-Warning 1264 Out of range value for column 't' at row 3
-Warning 1264 Out of range value for column 't' at row 4
+Warning 1265 Data truncated for column 't' at row 2
+Warning 1265 Data truncated for column 't' at row 3
+Warning 1265 Data truncated for column 't' at row 4
Warning 1265 Data truncated for column 't' at row 6
select * from t1;
t
@@ -53,8 +55,8 @@ t
36:30:31
00:00:10
00:00:00
-838:59:59
-838:59:59
+00:00:00
+00:00:00
262:22:00
00:00:12
drop table t1;
diff --git a/mysql-test/suite/pbxt/r/type_timestamp.result b/mysql-test/suite/pbxt/r/type_timestamp.result
index b04dcf01b9c..fdc86a3cf61 100644
--- a/mysql-test/suite/pbxt/r/type_timestamp.result
+++ b/mysql-test/suite/pbxt/r/type_timestamp.result
@@ -97,30 +97,6 @@ date date_time time_stamp
2005-01-01 2005-01-01 00:00:00 2005-01-01 00:00:00
2030-01-01 2030-01-01 00:00:00 2030-01-01 00:00:00
drop table t1;
-create table t1 (t2 timestamp(2), t4 timestamp(4), t6 timestamp(6),
-t8 timestamp(8), t10 timestamp(10), t12 timestamp(12),
-t14 timestamp(14));
-Warnings:
-Warning 1287 'TIMESTAMP(2)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-Warning 1287 'TIMESTAMP(4)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-Warning 1287 'TIMESTAMP(6)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-Warning 1287 'TIMESTAMP(8)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-Warning 1287 'TIMESTAMP(10)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-Warning 1287 'TIMESTAMP(12)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-Warning 1287 'TIMESTAMP(14)' is deprecated and will be removed in a future release. Please use 'TIMESTAMP' instead
-insert t1 values (0,0,0,0,0,0,0),
-("1997-12-31 23:47:59", "1997-12-31 23:47:59", "1997-12-31 23:47:59",
-"1997-12-31 23:47:59", "1997-12-31 23:47:59", "1997-12-31 23:47:59",
-"1997-12-31 23:47:59");
-select * from t1;
-t2 t4 t6 t8 t10 t12 t14
-0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00
-1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59
-select * from t1;
-t2 t4 t6 t8 t10 t12 t14
-0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00
-1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59
-drop table t1;
create table t1 (ix timestamp);
insert into t1 values (0),(20030101010160),(20030101016001),(20030101240101),(20030132010101),(20031301010101),(20031200000000),(20030000000000);
Warnings:
@@ -436,12 +412,12 @@ max(t)
2004-02-01 00:00:00
drop table t1;
set sql_mode='maxdb';
-create table t1 (a timestamp, b timestamp(19));
+create table t1 (a timestamp, b timestamp(5));
show create table t1;
Table Create Table
t1 CREATE TABLE "t1" (
"a" datetime DEFAULT NULL,
- "b" datetime DEFAULT NULL
+ "b" datetime(5) DEFAULT NULL
)
set sql_mode='';
drop table t1;
diff --git a/mysql-test/suite/pbxt/r/union.result b/mysql-test/suite/pbxt/r/union.result
index 5d9dfb07965..424604fb4bb 100644
--- a/mysql-test/suite/pbxt/r/union.result
+++ b/mysql-test/suite/pbxt/r/union.result
@@ -480,7 +480,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 UNION t2 const PRIMARY PRIMARY 4 const 1 100.00
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 (select '1' AS `a`,'1' AS `b` from `test`.`t1` where 1) union (select '1' AS `a`,'10' AS `b` from `test`.`t2` where 1)
+Note 1003 (select 1 AS `a`,1 AS `b` from `test`.`t1` where 1) union (select 1 AS `a`,10 AS `b` from `test`.`t2` where 1)
(select * from t1 where a=5) union (select * from t2 where a=1);
a b
1 10
@@ -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 );
@@ -876,6 +876,8 @@ Slow_queries 0
drop table t1;
create table t1 ( RID int(11) not null default '0', IID int(11) not null default '0', nada varchar(50) not null,NAME varchar(50) not null,PHONE varchar(50) not null) engine=MyISAM;
insert into t1 ( RID,IID,nada,NAME,PHONE) values (1, 1, 'main', 'a', '111'), (2, 1, 'main', 'b', '222'), (3, 1, 'main', 'c', '333'), (4, 1, 'main', 'd', '444'), (5, 1, 'main', 'e', '555'), (6, 2, 'main', 'c', '333'), (7, 2, 'main', 'd', '454'), (8, 2, 'main', 'e', '555'), (9, 2, 'main', 'f', '666'), (10, 2, 'main', 'g', '777');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select A.NAME, A.PHONE, B.NAME, B.PHONE from t1 A left join t1 B on A.NAME = B.NAME and B.IID = 2 where A.IID = 1 and (A.PHONE <> B.PHONE or B.NAME is null) union select A.NAME, A.PHONE, B.NAME, B.PHONE from t1 B left join t1 A on B.NAME = A.NAME and A.IID = 1 where B.IID = 2 and (A.PHONE <> B.PHONE or A.NAME is null);
NAME PHONE NAME PHONE
a 111 NULL NULL
@@ -883,6 +885,7 @@ b 222 NULL NULL
d 444 d 454
NULL NULL f 666
NULL NULL g 777
+SET optimizer_switch=@save_optimizer_switch;
drop table t1;
create table t1 (col1 tinyint unsigned, col2 tinyint unsigned);
insert into t1 values (1,2),(3,4),(5,6),(7,8),(9,10);
diff --git a/mysql-test/suite/pbxt/r/update.result b/mysql-test/suite/pbxt/r/update.result
index 9154583fa81..46321d6f3bf 100644
--- a/mysql-test/suite/pbxt/r/update.result
+++ b/mysql-test/suite/pbxt/r/update.result
@@ -276,6 +276,7 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
flush status;
update t1 set a=9999 order by a limit 1;
@@ -290,6 +291,7 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 2
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 18
flush status;
delete from t1 order by a limit 1;
@@ -300,6 +302,7 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 1
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 9
flush status;
delete from t1 order by a desc limit 1;
@@ -310,6 +313,7 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 1
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 8
alter table t1 disable keys;
Warnings:
@@ -323,6 +327,7 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 1
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 7
select * from t1;
a b
@@ -376,6 +381,7 @@ Handler_read_key 1
Handler_read_next 1
Handler_read_prev 0
Handler_read_rnd 1
+Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
drop table t1, t2;
create table t1(f1 int, `*f2` int);
diff --git a/mysql-test/suite/pbxt/t/derived.test b/mysql-test/suite/pbxt/t/derived.test
index a9127b49741..49effe4f14b 100644
--- a/mysql-test/suite/pbxt/t/derived.test
+++ b/mysql-test/suite/pbxt/t/derived.test
@@ -3,6 +3,9 @@
drop table if exists t1,t2,t3;
--enable_warnings
+set @save_derived_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+
select * from (select 2 from DUAL) b;
-- error 1054
SELECT 1 as a FROM (SELECT 1 UNION SELECT a) b;
@@ -107,6 +110,7 @@ create table t1 select 1 as a;
analyze table t1; # PBXT: Required to get a consitent result
connect (con1,localhost,mysqltest_1,,*NO-ONE*,$MASTER_MYPORT,$MASTER_MYSOCK);
connection con1;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
--error 1046
select 2 as a from (select * from t1) b;
use test;
@@ -283,3 +287,5 @@ drop user mysqltest_1;
drop database pbxt;
--enable_query_log
# End of 4.1 tests
+
+set optimizer_switch=@save_derived_optimizer_switch;
diff --git a/mysql-test/suite/pbxt/t/distinct.test b/mysql-test/suite/pbxt/t/distinct.test
index 5d02b38aed8..854d7fc838e 100644
--- a/mysql-test/suite/pbxt/t/distinct.test
+++ b/mysql-test/suite/pbxt/t/distinct.test
@@ -158,6 +158,10 @@ create table t3 (
insert into t1 values (1,'yes'), (2,'no');
insert into t2 values (1,1);
insert into t3 values (1,1);
+
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
+
EXPLAIN
SELECT DISTINCT
t1.id
@@ -195,6 +199,8 @@ WHERE
AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2));
drop table t1,t2,t3;
+set join_cache_level=@save_join_cache_level;
+
#
# Test using DISTINCT on a function that contains a group function
# This also test the case when one doesn't use all fields in GROUP BY.
diff --git a/mysql-test/suite/pbxt/t/func_group.test b/mysql-test/suite/pbxt/t/func_group.test
index ca303030749..f3b466c463d 100644
--- a/mysql-test/suite/pbxt/t/func_group.test
+++ b/mysql-test/suite/pbxt/t/func_group.test
@@ -136,6 +136,8 @@ insert into t2 values('AAA', 10, 0.5);
insert into t2 values('BBB', 20, 1.0);
select t1.a1, t1.a2, t2.a1, t2.a2 from t1,t2;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select max(t1.a1), max(t2.a1) from t1, t2 where t2.a2=9;
select max(t2.a1), max(t1.a1) from t1, t2 where t2.a2=9;
select t1.a1, t1.a2, t2.a1, t2.a2 from t1 left outer join t2 on t1.a1=10;
@@ -144,6 +146,7 @@ select max(t2.a1) from t2 left outer join t1 on t2.a2=10 where t2.a2=20;
select max(t2.a1) from t2 left outer join t1 on t2.a2=10 where t2.a2=10;
select max(t2.a1) from t1 left outer join t2 on t1.a2=t2.a1 and 1=0 where t2.a1='AAA';
select max(t1.a2),max(t2.a1) from t1 left outer join t2 on t1.a1=10;
+SET optimizer_switch=@save_optimizer_switch;
drop table t1,t2;
#
diff --git a/mysql-test/suite/pbxt/t/func_op.test b/mysql-test/suite/pbxt/t/func_op.test
index 5ac127ad25f..4a6474df946 100644
--- a/mysql-test/suite/pbxt/t/func_op.test
+++ b/mysql-test/suite/pbxt/t/func_op.test
@@ -28,7 +28,10 @@ create table t1(a int);
create table t2(a int, b int);
insert into t1 values (1), (2), (3);
insert into t2 values (1, 7), (3, 7);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select t1.a, t2.a, t2.b, bit_count(t2.b) from t1 left join t2 on t1.a=t2.a;
+SET optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
--disable_query_log
diff --git a/mysql-test/suite/pbxt/t/grant_cache.test b/mysql-test/suite/pbxt/t/grant_cache.test
index f3faa579035..ce53a88ac0c 100644
--- a/mysql-test/suite/pbxt/t/grant_cache.test
+++ b/mysql-test/suite/pbxt/t/grant_cache.test
@@ -5,6 +5,17 @@
--source include/add_anonymous_users.inc
#
+# some statements have different results in ps-mode
+#
+let $actual1=4;
+let $actual2=5;
+if (`SELECT $PS_PROTOCOL + $SP_PROTOCOL + $CURSOR_PROTOCOL + $VIEW_PROTOCOL > 0`)
+{
+ let $actual1=3;
+ let $actual2=4;
+}
+
+#
# Test grants with query cache
#
--disable_warnings
@@ -112,6 +123,7 @@ select * from t2;
select mysqltest.t1.c from test.t1,mysqltest.t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
+--replace_result $actual1 4
show status like "Qcache_not_cached";
# Connect without a database
@@ -128,6 +140,7 @@ select a from mysqltest.t1;
select a from mysqltest.t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
+--replace_result $actual2 5
show status like "Qcache_not_cached";
# Cleanup
diff --git a/mysql-test/suite/pbxt/t/greedy_optimizer.test b/mysql-test/suite/pbxt/t/greedy_optimizer.test
index fd0be172e83..b3c05f4b3cd 100644
--- a/mysql-test/suite/pbxt/t/greedy_optimizer.test
+++ b/mysql-test/suite/pbxt/t/greedy_optimizer.test
@@ -10,6 +10,9 @@
drop table if exists t1,t2,t3,t4,t5,t6,t7;
--enable_warnings
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
+
create table t1 (
c11 integer,c12 integer,c13 integer,c14 integer,c15 integer,c16 integer,
primary key (c11)
@@ -312,6 +315,8 @@ show status like 'Last_query_cost';
drop table t1,t2,t3,t4,t5,t6,t7;
+set join_cache_level=@save_join_cache_level;
+
--disable_query_log
drop database pbxt;
--enable_query_log
diff --git a/mysql-test/suite/pbxt/t/group_by.test b/mysql-test/suite/pbxt/t/group_by.test
index c1909668b55..b29519369c7 100644
--- a/mysql-test/suite/pbxt/t/group_by.test
+++ b/mysql-test/suite/pbxt/t/group_by.test
@@ -338,8 +338,11 @@ drop table t1,t2;
CREATE TABLE t1 (ID1 int, ID2 int, ID int NOT NULL AUTO_INCREMENT,PRIMARY KEY(ID
));
insert into t1 values (1,244,NULL),(2,243,NULL),(134,223,NULL),(185,186,NULL);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select S.ID as xID, S.ID1 as xID1 from t1 as S left join t1 as yS on S.ID1 between yS.ID1 and yS.ID2;
select S.ID as xID, S.ID1 as xID1, repeat('*',count(distinct yS.ID)) as Level from t1 as S left join t1 as yS on S.ID1 between yS.ID1 and yS.ID2 group by xID order by xID1;
+SET optimizer_switch=@save_optimizer_switch;
drop table t1;
#
diff --git a/mysql-test/suite/pbxt/t/join.test b/mysql-test/suite/pbxt/t/join.test
index 7e7e1c10f06..fe73c67a6a3 100644
--- a/mysql-test/suite/pbxt/t/join.test
+++ b/mysql-test/suite/pbxt/t/join.test
@@ -4,6 +4,9 @@
drop table if exists t1,t2,t3;
--enable_warnings
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
#
# Test different join syntaxes
#
@@ -521,7 +524,7 @@ select * from v1a join v1b on t1.b = t2.b;
# Bug #17523 natural join and information_schema
#
# We mask out the Privileges column because it differs with embedded server
---replace_column 31 #
+--replace_column 32 #
select * from information_schema.statistics join information_schema.columns
using(table_name,column_name) where table_name='user';
@@ -648,6 +651,8 @@ DESCRIBE tv2;
DROP VIEW v1;
DROP TABLE t1,t2,tv1,tv2;
+SET optimizer_switch=@save_optimizer_switch;
+
--disable_query_log
drop database pbxt;
--enable_query_log
diff --git a/mysql-test/suite/pbxt/t/join_nested.test b/mysql-test/suite/pbxt/t/join_nested.test
index 3b72dc1e293..25c8a5a782e 100644
--- a/mysql-test/suite/pbxt/t/join_nested.test
+++ b/mysql-test/suite/pbxt/t/join_nested.test
@@ -3,6 +3,9 @@
DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5,t6,t7,t8,t9;
--enable_warnings
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
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);
@@ -587,6 +590,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
--echo . costs. To combat the plan change it uses --sorted_result and
--echo . and --replace tricks
+INSERT INTO t1 VALUES (-1,133,0), (-2,12,0), (-3,11,0), (-5,15,0);
CREATE INDEX idx_b ON t1(b);
CREATE INDEX idx_a ON t0(a);
@@ -614,7 +618,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
- (t1.a != 2),
+ (t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -653,7 +657,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
- (t1.a != 2),
+ (t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -1062,6 +1066,9 @@ SELECT t1.*, t4.nm
DROP TABLE t1,t2,t3,t4;
+
+SET optimizer_switch=@save_optimizer_switch;
+
--disable_query_log
drop database pbxt;
--enable_query_log
diff --git a/mysql-test/suite/pbxt/t/join_outer.test b/mysql-test/suite/pbxt/t/join_outer.test
index a9635de7081..4c5006c6b0a 100644
--- a/mysql-test/suite/pbxt/t/join_outer.test
+++ b/mysql-test/suite/pbxt/t/join_outer.test
@@ -6,6 +6,9 @@
drop table if exists t0,t1,t2,t3,t4,t5;
--enable_warnings
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
CREATE TABLE t1 (
grp int(11) default NULL,
a bigint(20) unsigned default NULL,
@@ -809,6 +812,8 @@ SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 1=0);
DROP TABLE t1,t2;
+SET optimizer_switch=@save_optimizer_switch;
+
--disable_query_log
drop database pbxt;
--enable_query_log
diff --git a/mysql-test/suite/pbxt/t/key_diff.test b/mysql-test/suite/pbxt/t/key_diff.test
index 5e9d7bac9cc..fc93c7418ab 100644
--- a/mysql-test/suite/pbxt/t/key_diff.test
+++ b/mysql-test/suite/pbxt/t/key_diff.test
@@ -13,11 +13,19 @@ CREATE TABLE t1 (
);
INSERT INTO t1 VALUES ('A','B'),('b','A'),('C','c'),('D','E'),('a','a');
+INSERT INTO t1 VALUES
+ ('AA','BB'),('bb','AA'),('CC','cc'),('DD','EE'),('aa','aa');
+INSERT INTO t1 VALUES
+ ('AAA','BBB'),('bbb','AAA'),('CCC','ccc'),('DDD','EEE'),('aaa','aaa');
-select * from t1,t1 as t2;
-explain select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B;
+select * from t1,t1 as t2
+ where length(t1.A)=1 and length(t2.B)=1 ;
+explain select t1.*,t2.* from t1,t1 as t2
+ where t1.A=t2.B and length(t1.A)=1 and length(t2.B)=1;
#select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B;
-select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B order by binary t1.a,t2.a;
+select t1.*,t2.* from t1,t1 as t2
+ where t1.A=t2.B and length(t1.A)=1 and length(t2.B)=1
+order by binary t1.a,t2.a;
select * from t1 where a='a';
drop table t1;
diff --git a/mysql-test/suite/pbxt/t/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/mysqlshow.test b/mysql-test/suite/pbxt/t/mysqlshow.test
index d8f5c20afcd..41505cc0b10 100644
--- a/mysql-test/suite/pbxt/t/mysqlshow.test
+++ b/mysql-test/suite/pbxt/t/mysqlshow.test
@@ -1,5 +1,6 @@
# Can't run test of external client with embedded server
-- source include/not_embedded.inc
+-- source include/have_innodb.inc
--disable_warnings
DROP TABLE IF EXISTS t1,t2,test1,test2;
diff --git a/mysql-test/suite/pbxt/t/pbxt_xa_binlog.test b/mysql-test/suite/pbxt/t/pbxt_xa_binlog.test
new file mode 100644
index 00000000000..4a4578a5595
--- /dev/null
+++ b/mysql-test/suite/pbxt/t/pbxt_xa_binlog.test
@@ -0,0 +1,32 @@
+--source include/have_innodb.inc
+--source include/have_log_bin.inc
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+SET binlog_format = 'mixed';
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+# verify that binlog is on
+SELECT @@log_bin;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+select * from t2;
+
+# Test 2-phase commit when we disable binlogging.
+SET sql_log_bin = 0;
+BEGIN;
+INSERT INTO t1 VALUES (3);
+INSERT INTO t2 VALUES (4);
+COMMIT;
+select * from t1 order by a;
+select * from t2 order by b;
+
+drop table t1, t2;
+drop database pbxt;
+
diff --git a/mysql-test/suite/pbxt/t/select.test b/mysql-test/suite/pbxt/t/select.test
index 7074f4ac364..3a1cdcf5451 100644
--- a/mysql-test/suite/pbxt/t/select.test
+++ b/mysql-test/suite/pbxt/t/select.test
@@ -13,6 +13,9 @@ drop table if exists t1_1,t1_2,t9_1,t9_2,t1aa,t2aa;
drop view if exists v1;
--enable_warnings
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
CREATE TABLE t1 (
Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
@@ -3130,6 +3133,9 @@ SELECT * FROM t1 LIMIT 2, -1;
DROP TABLE t1;
+
+SET optimizer_switch=@save_optimizer_switch;
+
--disable_query_log
drop database pbxt;
--enable_query_log
diff --git a/mysql-test/suite/pbxt/t/subselect.test b/mysql-test/suite/pbxt/t/subselect.test
index 154e8d1e627..aae7ff2d5f5 100644
--- a/mysql-test/suite/pbxt/t/subselect.test
+++ b/mysql-test/suite/pbxt/t/subselect.test
@@ -80,8 +80,11 @@ explain extended (select * from t2 where t2.b=(select a from t3 order by 1 desc
select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
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;
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
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;
+set optimizer_switch=@tmp_optimizer_switch;
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);
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);
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);
@@ -278,8 +281,9 @@ SELECT (SELECT numeropost FROM t1 HAVING numreponse=a),numreponse FROM (SELECT *
SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=a) FROM (SELECT * FROM t1) as a;
SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT * FROM t1) as a;
INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
--- error 1242
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+-- error 1242
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
drop table t1;
@@ -477,6 +481,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);
@@ -825,6 +832,8 @@ commit;
enable_query_log;
insert into t2 values (2), (3), (4), (5);
insert into t3 values (10,3), (20,4), (30,5);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
select * from t2 where t2.a in (select a from t1);
explain extended select * from t2 where t2.a in (select a from t1);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
@@ -835,6 +844,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);
+SET optimizer_switch=@save_optimizer_switch;
drop table t1, t2, t3;
#
@@ -1121,6 +1131,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 +1796,10 @@ 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";
+SET optimizer_switch='semijoin_with_cache=off';
+
CREATE TABLE t1 (one int, two int, flag char(1));
CREATE TABLE t2 (one int, two int, flag char(1));
INSERT INTO t1 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
@@ -1811,6 +1827,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 +1991,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 +2006,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
#
@@ -2036,7 +2060,7 @@ SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2);
--error 1242
SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1);
-
+--sorted_result
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;
@@ -2044,7 +2068,7 @@ SELECT a FROM t1 GROUP BY a
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;
-
+--sorted_result
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;
@@ -2052,7 +2076,7 @@ SELECT a FROM t1 GROUP BY a
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;
-
+--sorted_result
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));
@@ -2060,7 +2084,7 @@ SELECT a FROM t1
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));
-
+--sorted_result
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));
@@ -3075,6 +3099,10 @@ DROP TABLE t1, t2, t3;
# Bug #30788: Inconsistent retrieval of char/varchar
#
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+SET optimizer_switch='materialization=off';
+
CREATE TABLE t1 (a CHAR(1), b VARCHAR(10));
INSERT INTO t1 VALUES ('a', 'aa');
INSERT INTO t1 VALUES ('a', 'aaa');
@@ -3096,6 +3124,8 @@ SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
DROP TABLE t1,t2;
+SET optimizer_switch= @save_optimizer_switch;
+
#
# Bug #32400: Complex SELECT query returns correct result only on some
# occasions
@@ -3211,6 +3241,7 @@ INSERT INTO t1 VALUES ('a');
SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1);
DROP TABLE t1;
+
--disable_query_log
drop database pbxt;
--enable_query_log
diff --git a/mysql-test/suite/pbxt/t/type_timestamp.test b/mysql-test/suite/pbxt/t/type_timestamp.test
index 88b4c4e2587..65659b2acca 100644
--- a/mysql-test/suite/pbxt/t/type_timestamp.test
+++ b/mysql-test/suite/pbxt/t/type_timestamp.test
@@ -67,17 +67,6 @@ INSERT INTO t1 VALUES ("2030-01-01","2030-01-01 00:00:00",20300101000000);
SELECT * FROM t1;
drop table t1;
-create table t1 (t2 timestamp(2), t4 timestamp(4), t6 timestamp(6),
- t8 timestamp(8), t10 timestamp(10), t12 timestamp(12),
- t14 timestamp(14));
-insert t1 values (0,0,0,0,0,0,0),
-("1997-12-31 23:47:59", "1997-12-31 23:47:59", "1997-12-31 23:47:59",
-"1997-12-31 23:47:59", "1997-12-31 23:47:59", "1997-12-31 23:47:59",
-"1997-12-31 23:47:59");
-select * from t1;
-select * from t1;
-drop table t1;
-
#
# Let us check if we properly treat wrong datetimes and produce proper warnings
# (for both strings and numbers)
@@ -298,7 +287,7 @@ drop table t1;
# mode regardless of whether a display width is given.
#
set sql_mode='maxdb';
-create table t1 (a timestamp, b timestamp(19));
+create table t1 (a timestamp, b timestamp(5));
show create table t1;
# restore default mode
set sql_mode='';
diff --git a/mysql-test/suite/pbxt/t/union.test b/mysql-test/suite/pbxt/t/union.test
index c216b3caceb..5a719f00cb3 100644
--- a/mysql-test/suite/pbxt/t/union.test
+++ b/mysql-test/suite/pbxt/t/union.test
@@ -481,7 +481,10 @@ drop table t1;
#
create table t1 ( RID int(11) not null default '0', IID int(11) not null default '0', nada varchar(50) not null,NAME varchar(50) not null,PHONE varchar(50) not null) engine=MyISAM;
insert into t1 ( RID,IID,nada,NAME,PHONE) values (1, 1, 'main', 'a', '111'), (2, 1, 'main', 'b', '222'), (3, 1, 'main', 'c', '333'), (4, 1, 'main', 'd', '444'), (5, 1, 'main', 'e', '555'), (6, 2, 'main', 'c', '333'), (7, 2, 'main', 'd', '454'), (8, 2, 'main', 'e', '555'), (9, 2, 'main', 'f', '666'), (10, 2, 'main', 'g', '777');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select A.NAME, A.PHONE, B.NAME, B.PHONE from t1 A left join t1 B on A.NAME = B.NAME and B.IID = 2 where A.IID = 1 and (A.PHONE <> B.PHONE or B.NAME is null) union select A.NAME, A.PHONE, B.NAME, B.PHONE from t1 B left join t1 A on B.NAME = A.NAME and A.IID = 1 where B.IID = 2 and (A.PHONE <> B.PHONE or A.NAME is null);
+SET optimizer_switch=@save_optimizer_switch;
drop table t1;
#
diff --git a/mysql-test/suite/rpl/extension/README.checksum b/mysql-test/suite/rpl/extension/README.checksum
new file mode 100644
index 00000000000..1adcaff49ca
--- /dev/null
+++ b/mysql-test/suite/rpl/extension/README.checksum
@@ -0,0 +1,23 @@
+Binlog checksum testing
+=======================
+
+1. How it works.
+The script copies a <suite> to directory <suite>_checksum,
+collects test case names for t/ directory (except tests from
+disabled def), randomly choose 90% of tests and add them
+to disabled.def.
+It means that mtr will run only 10% of random tests from each
+suite.
+At end the script run mtr:
+./mysql-test-run.pl --suite=aaa_checksum,bbb_checksum \
+ --mysqld=--binlog-checksum=CRC32 arg1 ... argN
+
+aaa,bbb - suite names from --suite option
+arg1,argN - other command-line arguments of checksum.pl
+
+2. The options:
+
+--suite=suite1,suite2. Mandatory option. The list of suites for
+ binlog checksum testing.
+
+--percent=N, where N is 1..99. Percent of running tests.
diff --git a/mysql-test/suite/rpl/extension/checksum.pl b/mysql-test/suite/rpl/extension/checksum.pl
new file mode 100644
index 00000000000..60dca18c8f8
--- /dev/null
+++ b/mysql-test/suite/rpl/extension/checksum.pl
@@ -0,0 +1,164 @@
+#!/usr/bin/perl
+
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+use File::Basename;
+use File::Copy qw(copy);
+use File::Spec qw(catdir);
+use File::Path;
+use IO::File;
+use strict;
+
+# Constants and variables with default values
+my $suites;
+my $suffix = "_checksum";
+my $percent_random_test = 10;
+my $mtr_script;
+my @mtr_argv;
+my @mtr_suites;
+
+# Check some arguments
+foreach my $arg ( @ARGV )
+{
+ if ($arg =~ m/\-\-suite\=(.+)/i)
+ {
+ $suites = $1;
+ }
+ elsif ($arg =~ m/\-\-percent\=(\d{1,2})/i)
+ {
+ $percent_random_test= $1;
+ }
+ else
+ {
+ push(@mtr_argv, $arg);
+ }
+
+}
+if (! defined( $suites ) )
+{
+ die("The script requires --suite argument");
+}
+
+print "#################################################################\n";
+print "# Binlog checksum testing\n";
+print "# Run randomly $percent_random_test\% of tests from following suites: $suites\n";
+print "#################################################################\n";
+
+# Set extension directory
+my $ext_dir= dirname(File::Spec->rel2abs($0));
+# Set mysql-test directory
+my $mysql_test_dir= $ext_dir;
+$mysql_test_dir =~ s/(\/|\\)suite(\/|\\)rpl(\/|\\)extension$//;
+
+# Main loop
+foreach my $src_suite (split(",", $suites))
+{
+ $src_suite=~ s/ //g;
+ my $dest_suite= $src_suite . $suffix;
+ push( @mtr_suites, $dest_suite);
+ print "Creating suite $dest_suite\n";
+ # *** Set platform-independent pathes ***
+ # Set source directory of suite
+ my $src_suite_dir = File::Spec->catdir($mysql_test_dir, "suite", $src_suite);
+ # Set destination directory of suite
+ my $dest_suite_dir = File::Spec->catdir($mysql_test_dir, "suite", $dest_suite);
+ print "Copying files\n\tfrom '$src_suite_dir'\n\tto '$dest_suite_dir'\n";
+ dircopy($src_suite_dir, $dest_suite_dir);
+ my $test_case_dir= File::Spec->catdir($dest_suite_dir, "t");
+ # Read disabled.def
+ my %disabled = ();
+ print "Read disabled.def\n";
+ my $fh = new IO::File File::Spec->catdir($test_case_dir, "disabled.def"), "r";
+ if ( defined $fh )
+ {
+ my @lines = <$fh>;
+ undef $fh;
+ foreach my $line ( @lines )
+ {
+ if ($line =~ m/^([a-zA-Z0-9_]+).+\:.+/i)
+ {
+ $disabled{$1}= 1;
+ }
+ }
+ }
+ # Read test case list
+ my %tests = ();
+ print "Generate test case list\n";
+ opendir my ($dh), $test_case_dir or die "Could not open dir '$test_case_dir': $!";
+ for my $entry (readdir $dh)
+ {
+ if ( $entry =~ m/^([a-zA-Z0-9_]+)\.test$/i )
+ {
+ my $test= $1;
+ if ( ! defined( $disabled{$test}) )
+ {
+ $tests{$test}= 1;
+ }
+ }
+ }
+ closedir($dh);
+ #
+ my @excluded = ();
+ my $excluded_test= int((((100 - $percent_random_test)/100) * scalar( keys %tests )));
+ while ( $excluded_test > 0 )
+ {
+ my @cases = keys %tests;
+ my $test = $cases[int(rand(scalar(@cases)))];
+ push ( @excluded, $test . "\t\t: Excluded for $dest_suite\n" );
+ delete $tests{$test};
+ $excluded_test--;
+ }
+ my $fh = new IO::File File::Spec->catdir($test_case_dir, "disabled.def"), O_WRONLY|O_APPEND;
+ if (defined $fh) {
+ print $fh join ("", sort @excluded);
+ undef $fh;
+ }
+ print "\t" . join("\n\t", sort keys %tests) . "\n";
+
+}
+
+# Set path to mtr with arguments
+my $mtr_script = "perl " . File::Spec->catdir($mysql_test_dir, "mysql-test-run.pl") .
+ " --suite=" . join(",", @mtr_suites) . " " .
+ " --mysqld=--binlog-checksum=CRC32 " .
+ join (" ", @mtr_argv);
+
+print "Run $mtr_script\n";
+system( $mtr_script );
+
+sub dircopy
+{
+ my ($from_dir, $to_dir)= @_;
+ mkdir $to_dir if (! -e $to_dir);
+ opendir my($dh), $from_dir or die "Could not open dir '$from_dir': $!";
+ for my $entry (readdir $dh)
+ {
+ next if $entry =~ /^(\.|\.\.)$/;
+ my $source = File::Spec->catdir($from_dir, $entry);
+ my $destination = File::Spec->catdir($to_dir, $entry);
+ if (-d $source)
+ {
+ mkdir $destination or die "mkdir '$destination' failed: $!" if not -e $destination;
+ dircopy($source, $destination);
+ }
+ else
+ {
+ copy($source, $destination) or die "copy '$source' to '$destination' failed: $!";
+ }
+ }
+ closedir $dh;
+ return;
+}
diff --git a/mysql-test/suite/rpl/include/hrtime.inc b/mysql-test/suite/rpl/include/hrtime.inc
new file mode 100644
index 00000000000..b49bf0c7792
--- /dev/null
+++ b/mysql-test/suite/rpl/include/hrtime.inc
@@ -0,0 +1,27 @@
+--source include/master-slave.inc
+
+set time_zone='+03:00';
+set timestamp=unix_timestamp('2011-01-01 01:01:01') + 0.123456;
+
+create table t1 (a timestamp(4), b varchar(100), c datetime(2));
+
+insert t1 (b,c) values (now(6), now(6));
+
+insert t1 values ('2010-10-10 10:10:10.101010','2010-10-10 10:10:10.101010','2010-10-10 10:10:10.101010');
+
+set timestamp=unix_timestamp('2022-02-02 02:02:02') + 0.654321;
+insert t1 (b,c) values (now(), now());
+insert t1 (b,c) values (0,0);
+insert t1 (a,b,c) values (0,0,now(6));
+
+select * from t1;
+
+sync_slave_with_master;
+connection slave;
+set time_zone='+03:00';
+select * from t1;
+connection master;
+drop table t1;
+
+--source include/rpl_end.inc
+
diff --git a/mysql-test/suite/rpl/r/rpl_change_master.result b/mysql-test/suite/rpl/r/rpl_change_master.result
index 6674ab168ef..1b1f040b726 100644
--- a/mysql-test/suite/rpl/r/rpl_change_master.result
+++ b/mysql-test/suite/rpl/r/rpl_change_master.result
@@ -1,5 +1,6 @@
include/master-slave.inc
[connection master]
+call mtr.add_suppression("Slave I/O: The slave I/O thread stops because a fatal error is encountered when it tried to SET @master_binlog_checksum");
create table t1(n int);
select * from t1;
n
diff --git a/mysql-test/suite/rpl/r/rpl_checksum.result b/mysql-test/suite/rpl/r/rpl_checksum.result
new file mode 100644
index 00000000000..3613ffd25e1
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_checksum.result
@@ -0,0 +1,135 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression('Slave can not handle replication events with the checksum that master is configured to log');
+call mtr.add_suppression('Replication event checksum verification failed');
+call mtr.add_suppression('Relay log write failure: could not queue event from master');
+call mtr.add_suppression('Master is configured to log replication events with checksum, but will not send such events to slaves that cannot process them');
+set @master_save_binlog_checksum= @@global.binlog_checksum;
+set @save_master_verify_checksum = @@global.master_verify_checksum;
+select @@global.binlog_checksum as 'must be CRC32 because of the command line option';
+must be CRC32 because of the command line option
+CRC32
+select @@session.binlog_checksum as 'no session var';
+ERROR HY000: Variable 'binlog_checksum' is a GLOBAL variable
+select @@global.master_verify_checksum as 'must be zero because of default';
+must be zero because of default
+0
+select @@session.master_verify_checksum as 'no session var';
+ERROR HY000: Variable 'master_verify_checksum' is a GLOBAL variable
+set @slave_save_binlog_checksum= @@global.binlog_checksum;
+set @save_slave_sql_verify_checksum = @@global.slave_sql_verify_checksum;
+select @@global.slave_sql_verify_checksum as 'must be one because of default';
+must be one because of default
+1
+select @@session.slave_sql_verify_checksum as 'no session var';
+ERROR HY000: Variable 'slave_sql_verify_checksum' is a GLOBAL variable
+show binary logs;
+Log_name File_size
+master-bin.000001 #
+set @@global.binlog_checksum = NONE;
+select @@global.binlog_checksum;
+@@global.binlog_checksum
+NONE
+*** must be rotations seen ***
+show binary logs;
+Log_name File_size
+master-bin.000001 #
+master-bin.000002 #
+set @@global.binlog_checksum = default;
+select @@global.binlog_checksum;
+@@global.binlog_checksum
+NONE
+set @@global.binlog_checksum = CRC32;
+select @@global.binlog_checksum;
+@@global.binlog_checksum
+CRC32
+set @@global.binlog_checksum = CRC32;
+set @@global.master_verify_checksum = 0;
+set @@global.master_verify_checksum = default;
+set @@global.binlog_checksum = ADLER32;
+ERROR 42000: Variable 'checksum' can't be set to the value of 'ADLER32'
+set @@global.master_verify_checksum = 2;
+ERROR 42000: Variable 'master_verify_checksum' can't be set to the value of '2'
+set @@global.slave_sql_verify_checksum = 0;
+set @@global.slave_sql_verify_checksum = default;
+set @@global.slave_sql_verify_checksum = 2;
+ERROR 42000: Variable 'slave_sql_verify_checksum' can't be set to the value of '2'
+set @@global.binlog_checksum = NONE;
+create table t1 (a int);
+flush logs;
+flush logs;
+flush logs;
+flush logs;
+flush logs;
+flush logs;
+select count(*) as zero from t1;
+zero
+0
+include/stop_slave.inc
+set @@global.binlog_checksum = CRC32;
+insert into t1 values (1) /* will not be applied on slave due to simulation */;
+set @@global.debug='d,simulate_slave_unaware_checksum';
+start slave;
+include/wait_for_slave_io_error.inc [errno=1236]
+Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'Slave can not handle replication events with the checksum that master is configured to log''
+select count(*) as zero from t1;
+zero
+0
+set @@global.debug='';
+include/start_slave.inc
+set @@global.master_verify_checksum = 1;
+set @@session.debug='d,simulate_checksum_test_failure';
+show binlog events;
+ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error
+set @@session.debug='';
+set @@global.master_verify_checksum = default;
+include/stop_slave.inc
+create table t2 (a int);
+set @@global.debug='d,simulate_checksum_test_failure';
+start slave io_thread;
+include/wait_for_slave_io_error.inc [errno=1595]
+Last_IO_Error = 'Relay log write failure: could not queue event from master'
+set @@global.debug='';
+start slave io_thread;
+include/wait_for_slave_param.inc [Read_Master_Log_Pos]
+set @@global.slave_sql_verify_checksum = 1;
+set @@global.debug='d,simulate_checksum_test_failure';
+start slave sql_thread;
+include/wait_for_slave_sql_error.inc [errno=1593]
+Last_SQL_Error = 'Error initializing relay log position: I/O error reading event at position 4'
+set @@global.debug='';
+include/start_slave.inc
+select count(*) as 'must be zero' from t2;
+must be zero
+0
+stop slave;
+reset slave;
+set @@global.binlog_checksum= IF(floor((rand()*1000)%2), "CRC32", "NONE");
+flush logs;
+set @@global.binlog_checksum= CRC32;
+reset master;
+flush logs;
+create table t3 (a int, b char(5));
+include/start_slave.inc
+select count(*) as 'must be zero' from t3;
+must be zero
+0
+include/stop_slave.inc
+change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root';
+flush logs;
+reset master;
+insert into t3 value (1, @@global.binlog_checksum);
+include/start_slave.inc
+flush logs;
+select count(*) as 'must be one' from t3;
+must be one
+1
+set @@global.binlog_checksum= IF(floor((rand()*1000)%2), "CRC32", "NONE");
+insert into t3 value (1, @@global.binlog_checksum);
+drop table t1, t2, t3;
+set @@global.binlog_checksum = @master_save_binlog_checksum;
+set @@global.master_verify_checksum = @save_master_verify_checksum;
+set @@global.binlog_checksum = @slave_save_binlog_checksum;
+set @@global.slave_sql_verify_checksum = @save_slave_sql_verify_checksum;
+End of tests
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_checksum_cache.result b/mysql-test/suite/rpl/r/rpl_checksum_cache.result
new file mode 100644
index 00000000000..9508e94e7f2
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_checksum_cache.result
@@ -0,0 +1,119 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. Statement: insert into t2 set data=repeat.*'a', @act_size.*");
+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. Statement: insert into t1 values.* NAME_CONST.*'n',.*, @data .*");
+set @save_binlog_cache_size = @@global.binlog_cache_size;
+set @save_binlog_checksum = @@global.binlog_checksum;
+set @save_master_verify_checksum = @@global.master_verify_checksum;
+set @@global.binlog_cache_size = 4096;
+set @@global.binlog_checksum = CRC32;
+set @@global.master_verify_checksum = 1;
+include/stop_slave.inc
+include/start_slave.inc
+flush status;
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 0
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 0
+drop table if exists t1;
+create table t1 (a int PRIMARY KEY, b CHAR(32)) engine=innodb;
+create procedure test.p_init (n int, size int)
+begin
+while n > 0 do
+select round(RAND() * size) into @act_size;
+set @data = repeat('a', @act_size);
+insert into t1 values(n, @data );
+set n= n-1;
+end while;
+end|
+begin;
+call test.p_init(4000, 32);
+commit;
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 1
+*** binlog_cache_disk_use must be non-zero ***
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 1
+include/diff_tables.inc [master:test.t1, slave:test.t1]
+begin;
+delete from t1;
+commit;
+flush status;
+create table t2(a int auto_increment primary key, data VARCHAR(12288)) ENGINE=Innodb;
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 1
+*** binlog_cache_disk_use must be non-zero ***
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 1
+include/diff_tables.inc [master:test.t2, slave:test.t2]
+begin;
+delete from t2;
+commit;
+flush status;
+create table t3(a int auto_increment primary key, data VARCHAR(8192)) engine=innodb;
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 1
+*** binlog_cache_disk_use must be non-zero ***
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 1
+include/diff_tables.inc [master:test.t3, slave:test.t3]
+begin;
+delete from t3;
+commit;
+flush status;
+create procedure test.p1 (n int)
+begin
+while n > 0 do
+case (select (round(rand()*100) % 3) + 1)
+when 1 then
+select round(RAND() * 32) into @act_size;
+set @data = repeat('a', @act_size);
+insert into t1 values(n, @data);
+when 2 then
+begin
+select round(8192 + RAND() * 4096) into @act_size;
+insert into t2 set data=repeat('a', @act_size);
+end;
+when 3 then
+begin
+select round(3686.4000 + RAND() * 819.2000) into @act_size;
+insert into t3 set data= repeat('a', @act_size);
+end;
+end case;
+set n= n-1;
+end while;
+end|
+set autocommit= 0;
+begin;
+call test.p1(1000);
+commit;
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 1
+*** binlog_cache_disk_use must be non-zero ***
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 1
+include/diff_tables.inc [master:test.t1, slave:test.t1]
+include/diff_tables.inc [master:test.t2, slave:test.t2]
+include/diff_tables.inc [master:test.t3, slave:test.t3]
+begin;
+delete from t1;
+delete from t2;
+delete from t3;
+commit;
+drop table t1, t2, t3;
+set @@global.binlog_cache_size = @save_binlog_cache_size;
+set @@global.binlog_checksum = @save_binlog_checksum;
+set @@global.master_verify_checksum = @save_master_verify_checksum;
+drop procedure test.p_init;
+drop procedure test.p1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_corruption.result b/mysql-test/suite/rpl/r/rpl_corruption.result
new file mode 100644
index 00000000000..a35bfbad92c
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_corruption.result
@@ -0,0 +1,51 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression('Found invalid event in binary log');
+call mtr.add_suppression('Slave I/O: Relay log write failure: could not queue event from master');
+call mtr.add_suppression('event read from binlog did not pass crc check');
+call mtr.add_suppression('Replication event checksum verification failed');
+call mtr.add_suppression('Event crc check failed! Most likely there is event corruption');
+call mtr.add_suppression('Slave SQL: Error initializing relay log position: I/O error reading event at position .*, Error_code: 1593');
+SET @old_master_verify_checksum = @@master_verify_checksum;
+# 1. Creating test table/data and set corruption position for testing
+* insert/update/delete rows in table t1 *
+CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b VARCHAR(10), c VARCHAR(100));
+include/stop_slave.inc
+# 2. Corruption in master binlog and SHOW BINLOG EVENTS
+SET GLOBAL debug="+d,corrupt_read_log_event_char";
+SHOW BINLOG EVENTS;
+ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error
+SET GLOBAL debug="-d,corrupt_read_log_event_char";
+# 3. Master read a corrupted event from binlog and send the error to slave
+SET GLOBAL debug="+d,corrupt_read_log_event2";
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_error.inc [errno=1236]
+SET GLOBAL debug="-d,corrupt_read_log_event2";
+# 4. Master read a corrupted event from binlog and send it to slave
+SET GLOBAL master_verify_checksum=0;
+SET GLOBAL debug="+d,corrupt_read_log_event2";
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_error.inc [errno=1595,1722]
+SET GLOBAL debug="-d,corrupt_read_log_event2";
+SET GLOBAL debug= "";
+SET GLOBAL master_verify_checksum=1;
+# 5. Slave. Corruption in network
+SET GLOBAL debug="+d,corrupt_queue_event";
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_error.inc [errno=1595,1722]
+SET GLOBAL debug="-d,corrupt_queue_event";
+# 6. Slave. Corruption in relay log
+SET GLOBAL debug="+d,corrupt_read_log_event_char";
+START SLAVE SQL_THREAD;
+include/wait_for_slave_sql_error.inc [errno=1593]
+SET GLOBAL debug="-d,corrupt_read_log_event_char";
+SET GLOBAL debug= "";
+# 7. Seek diff for tables on master and slave
+include/start_slave.inc
+include/diff_tables.inc [master:test.t1, slave:test.t1]
+# 8. Clean up
+SET GLOBAL debug= "";
+SET GLOBAL master_verify_checksum = @old_master_verify_checksum;
+DROP TABLE t1;
+SET GLOBAL debug= "";
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result b/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result
index c399b408d5c..37d209bbcf6 100644
--- a/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result
+++ b/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result
@@ -51,7 +51,7 @@ include/check_slave_is_running.inc
*** Test lock wait timeout ***
include/stop_slave.inc
DELETE FROM t2;
-CHANGE MASTER TO MASTER_LOG_POS=MASTER_POS_BEGIN;
+CHANGE MASTER TO MASTER_LOG_POS=<master_pos_begin>;
BEGIN;
SELECT * FROM t1 FOR UPDATE;
a
@@ -78,7 +78,7 @@ SET @my_max_relay_log_size= @@global.max_relay_log_size;
SET global max_relay_log_size=0;
include/stop_slave.inc
DELETE FROM t2;
-CHANGE MASTER TO MASTER_LOG_POS=MASTER_POS_BEGIN;
+CHANGE MASTER TO MASTER_LOG_POS=<master_pos_begin>;
BEGIN;
SELECT * FROM t1 FOR UPDATE;
a
diff --git a/mysql-test/suite/rpl/r/rpl_hrtime.result b/mysql-test/suite/rpl/r/rpl_hrtime.result
new file mode 100644
index 00000000000..89e7ee6b490
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_hrtime.result
@@ -0,0 +1,67 @@
+include/master-slave.inc
+[connection master]
+set time_zone='+03:00';
+set timestamp=unix_timestamp('2011-01-01 01:01:01') + 0.123456;
+create table t1 (a timestamp(4), b varchar(100), c datetime(2));
+insert t1 (b,c) values (now(6), now(6));
+insert t1 values ('2010-10-10 10:10:10.101010','2010-10-10 10:10:10.101010','2010-10-10 10:10:10.101010');
+set timestamp=unix_timestamp('2022-02-02 02:02:02') + 0.654321;
+insert t1 (b,c) values (now(), now());
+insert t1 (b,c) values (0,0);
+insert t1 (a,b,c) values (0,0,now(6));
+select * from t1;
+a b c
+2011-01-01 01:01:01.1234 2011-01-01 01:01:01.123456 2011-01-01 01:01:01.12
+2010-10-10 10:10:10.1010 2010-10-10 10:10:10.101010 2010-10-10 10:10:10.10
+2022-02-02 02:02:02.6543 2022-02-02 02:02:02 2022-02-02 02:02:02.00
+2022-02-02 02:02:02.6543 0 0000-00-00 00:00:00.00
+0000-00-00 00:00:00.0000 0 2022-02-02 02:02:02.65
+set time_zone='+03:00';
+select * from t1;
+a b c
+2011-01-01 01:01:01.1234 2011-01-01 01:01:01.123456 2011-01-01 01:01:01.12
+2010-10-10 10:10:10.1010 2010-10-10 10:10:10.101010 2010-10-10 10:10:10.10
+2022-02-02 02:02:02.6543 2022-02-02 02:02:02 2022-02-02 02:02:02.00
+2022-02-02 02:02:02.6543 0 0000-00-00 00:00:00.00
+0000-00-00 00:00:00.0000 0 2022-02-02 02:02:02.65
+drop table t1;
+include/rpl_end.inc
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+ROLLBACK/*!*/;
+use `test`/*!*/;
+SET TIMESTAMP=1293832861/*!*/;
+SET @@session.pseudo_thread_id=999999999/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+create table t1 (a timestamp(4), b varchar(100), c datetime(2))
+/*!*/;
+SET TIMESTAMP=1293832861.123456/*!*/;
+SET @@session.time_zone='+03:00'/*!*/;
+insert t1 (b,c) values (now(6), now(6))
+/*!*/;
+SET TIMESTAMP=1293832861/*!*/;
+insert t1 values ('2010-10-10 10:10:10.101010','2010-10-10 10:10:10.101010','2010-10-10 10:10:10.101010')
+/*!*/;
+SET TIMESTAMP=1643756522.654321/*!*/;
+insert t1 (b,c) values (now(), now())
+/*!*/;
+SET TIMESTAMP=1643756522.654321/*!*/;
+insert t1 (b,c) values (0,0)
+/*!*/;
+SET TIMESTAMP=1643756522.654321/*!*/;
+insert t1 (a,b,c) values (0,0,now(6))
+/*!*/;
+SET TIMESTAMP=1643756522/*!*/;
+drop table t1
+/*!*/;
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
diff --git a/mysql-test/suite/rpl/r/rpl_hrtime_row.result b/mysql-test/suite/rpl/r/rpl_hrtime_row.result
new file mode 100644
index 00000000000..aaf8b1c2466
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_hrtime_row.result
@@ -0,0 +1,28 @@
+include/master-slave.inc
+[connection master]
+set time_zone='+03:00';
+set timestamp=unix_timestamp('2011-01-01 01:01:01') + 0.123456;
+create table t1 (a timestamp(4), b varchar(100), c datetime(2));
+insert t1 (b,c) values (now(6), now(6));
+insert t1 values ('2010-10-10 10:10:10.101010','2010-10-10 10:10:10.101010','2010-10-10 10:10:10.101010');
+set timestamp=unix_timestamp('2022-02-02 02:02:02') + 0.654321;
+insert t1 (b,c) values (now(), now());
+insert t1 (b,c) values (0,0);
+insert t1 (a,b,c) values (0,0,now(6));
+select * from t1;
+a b c
+2011-01-01 01:01:01.1234 2011-01-01 01:01:01.123456 2011-01-01 01:01:01.12
+2010-10-10 10:10:10.1010 2010-10-10 10:10:10.101010 2010-10-10 10:10:10.10
+2022-02-02 02:02:02.6543 2022-02-02 02:02:02 2022-02-02 02:02:02.00
+2022-02-02 02:02:02.6543 0 0000-00-00 00:00:00.00
+0000-00-00 00:00:00.0000 0 2022-02-02 02:02:02.65
+set time_zone='+03:00';
+select * from t1;
+a b c
+2011-01-01 01:01:01.1234 2011-01-01 01:01:01.123456 2011-01-01 01:01:01.12
+2010-10-10 10:10:10.1010 2010-10-10 10:10:10.101010 2010-10-10 10:10:10.10
+2022-02-02 02:02:02.6543 2022-02-02 02:02:02 2022-02-02 02:02:02.00
+2022-02-02 02:02:02.6543 0 0000-00-00 00:00:00.00
+0000-00-00 00:00:00.0000 0 2022-02-02 02:02:02.65
+drop table t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_innodb_bug28430.result b/mysql-test/suite/rpl/r/rpl_innodb_bug28430.result
index f8734b48295..b02164ac61b 100644
--- a/mysql-test/suite/rpl/r/rpl_innodb_bug28430.result
+++ b/mysql-test/suite/rpl/r/rpl_innodb_bug28430.result
@@ -90,13 +90,19 @@ DELETE FROM test.byrange_tbl WHERE id = del_count;
SET del_count = del_count - 2;
END WHILE;
END|
+begin;
CALL test.proc_norm();
+commit;
SELECT count(*) as "Master regular" FROM test.regular_tbl;
Master regular 500
+begin;
CALL test.proc_bykey();
+commit;
SELECT count(*) as "Master bykey" FROM test.bykey_tbl;
Master bykey 500
+begin;
CALL test.proc_byrange();
+commit;
SELECT count(*) as "Master byrange" FROM test.byrange_tbl;
Master byrange 500
show create table test.byrange_tbl;
diff --git a/mysql-test/suite/rpl/r/rpl_rewrt_db.result b/mysql-test/suite/rpl/r/rpl_rewrt_db.result
index 12071faecfd..6cbd107fdcf 100644
--- a/mysql-test/suite/rpl/r/rpl_rewrt_db.result
+++ b/mysql-test/suite/rpl/r/rpl_rewrt_db.result
@@ -25,8 +25,8 @@ Warnings:
Warning 1265 Data truncated for column 'a' at row 1
Warning 1265 Data truncated for column 'c' at row 1
Warning 1265 Data truncated for column 'd' at row 1
-Warning 1265 Data truncated for column 'a' at row 2
-Warning 1265 Data truncated for column 'b' at row 2
+Warning 1264 Out of range value for column 'a' at row 2
+Warning 1264 Out of range value for column 'b' at row 2
Warning 1265 Data truncated for column 'd' at row 2
load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' IGNORE 2 LINES;
select * from rewrite.t1;
@@ -40,7 +40,7 @@ load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated
Warnings:
Warning 1265 Data truncated for column 'c' at row 1
Warning 1265 Data truncated for column 'd' at row 1
-Warning 1265 Data truncated for column 'b' at row 2
+Warning 1264 Out of range value for column 'b' at row 2
Warning 1265 Data truncated for column 'd' at row 2
select * from rewrite.t1;
a b c d
diff --git a/mysql-test/suite/rpl/r/rpl_rotate_logs.result b/mysql-test/suite/rpl/r/rpl_rotate_logs.result
index 1166b0d18a9..329a480783a 100644
--- a/mysql-test/suite/rpl/r/rpl_rotate_logs.result
+++ b/mysql-test/suite/rpl/r/rpl_rotate_logs.result
@@ -70,7 +70,7 @@ insert into temp_table values ("testing temporary tables part 2");
create table t3 (n int);
select count(*) from t3 where n >= 4;
count(*)
-100
+90
create table t4 select * from temp_table;
show binary logs;
Log_name File_size
@@ -89,7 +89,7 @@ include/check_slave_is_running.inc
lock tables t3 read;
select count(*) from t3 where n >= 4;
count(*)
-100
+90
unlock tables;
drop table if exists t1,t2,t3,t4;
End of 4.1 tests
diff --git a/mysql-test/suite/rpl/r/rpl_row_annotate_do.result b/mysql-test/suite/rpl/r/rpl_row_annotate_do.result
new file mode 100644
index 00000000000..a7dc2a569a1
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_row_annotate_do.result
@@ -0,0 +1,141 @@
+include/master-slave.inc
+[connection master]
+########################################################################
+# TABLES ON MASTER
+########################################################################
+SELECT * FROM t1 ORDER BY a;
+a b
+0 1
+SELECT * FROM t2 ORDER BY a;
+a b
+SELECT * FROM t3 ORDER BY a;
+a b
+1 1
+2 2
+3 3
+SELECT * FROM t5 ORDER BY a;
+a b
+1 foo
+2 bar
+3 baz
+4 gås
+5 gås
+########################################################################
+# TABLES ON SLAVE: should be the same as on master
+########################################################################
+SELECT * FROM t1 ORDER BY a;
+a b
+0 1
+SELECT * FROM t2 ORDER BY a;
+a b
+SELECT * FROM t3 ORDER BY a;
+a b
+1 1
+2 2
+3 3
+SELECT * FROM t5 ORDER BY a;
+a b
+1 foo
+2 bar
+3 baz
+4 gås
+5 gås
+########################################################################
+# EVENTS ON SLAVE
+# The following Annotate_rows events should appear below:
+# - UPDATE t1 SET b = b + 1;
+# - REPLACE t1 VALUES (1,1), (2,2), (3,3);
+# - INSERT INTO t2 VALUES (1,1), (2,2), (3,3)
+# - INSERT INTO t3 VALUES (1,1), (2,2), (3,3)
+# - DELETE t1, t2 FROM <...>
+# - INSERT INTO t2 VALUES (1,1), (2,2), (3,3)
+# - DELETE xt1, t2 FROM <...>
+# - INSERT INTO t5(b) VALUES <...> (3 instances)
+########################################################################
+FLUSH LOGS;
+show binlog events in 'slave-bin.000001' from <start_pos>;
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Query 1 # DROP DATABASE IF EXISTS test1
+slave-bin.000001 # Query 1 # CREATE DATABASE test1
+slave-bin.000001 # Query 1 # use `test1`; CREATE TABLE t1(a int primary key, b int)
+slave-bin.000001 # Query 1 # use `test1`; CREATE TABLE t2(a int, b int)
+slave-bin.000001 # Query 1 # use `test1`; CREATE TABLE t3(a int, b int)
+slave-bin.000001 # Query 1 # use `test1`; CREATE TABLE t4(a int, b int)
+slave-bin.000001 # Query 1 # use `test1`; CREATE TABLE t5 (
+a INT PRIMARY KEY AUTO_INCREMENT,
+b VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_bin
+)
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t1)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Annotate_rows 1 # UPDATE t1 SET b = b + 1
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t1)
+slave-bin.000001 # Update_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Annotate_rows 1 # REPLACE t1 VALUES (1,1), (2,2), (3,3)
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t1)
+slave-bin.000001 # Update_rows 1 # table_id: #
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Annotate_rows 1 # INSERT INTO t2 VALUES (1,1), (2,2), (3,3)
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t2)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Annotate_rows 1 # INSERT INTO t3 VALUES (1,1), (2,2), (3,3)
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t3)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Annotate_rows 1 # DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t2)
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t1)
+slave-bin.000001 # Delete_rows 1 # table_id: #
+slave-bin.000001 # Delete_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Annotate_rows 1 # INSERT INTO t2 VALUES (1,1), (2,2), (3,3)
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t2)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Annotate_rows 1 # DELETE xt1, t2 FROM xt1 INNER JOIN t2 INNER JOIN t3 WHERE xt1.a=t2.a AND t2.a=t3.a
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t2)
+slave-bin.000001 # Delete_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Annotate_rows 1 # INSERT INTO t5(b) VALUES ('foo'), ('bar'), ('baz')
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t5)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Annotate_rows 1 # INSERT INTO t5(b) VALUES ('gås')
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t5)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Annotate_rows 1 # INSERT INTO t5(b) VALUES ('gås')
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t5)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4
+#
+########################################################################
+# INSERTs DELAYED ON MASTERs
+########################################################################
+SET SESSION binlog_annotate_row_events = ON;
+INSERT DELAYED INTO test1.t4 VALUES (1,1);
+FLUSH TABLES;
+SELECT * FROM test1.t4 ORDER BY a;
+a b
+1 1
+########################################################################
+# ON SLAVE
+# No Annotate_rows events should appear below
+########################################################################
+FLUSH LOGS;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_row_annotate_dont.result b/mysql-test/suite/rpl/r/rpl_row_annotate_dont.result
new file mode 100644
index 00000000000..2a3b5b1870e
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_row_annotate_dont.result
@@ -0,0 +1,123 @@
+include/master-slave.inc
+[connection master]
+########################################################################
+# TABLES ON MASTER
+########################################################################
+SELECT * FROM t1 ORDER BY a;
+a b
+0 1
+SELECT * FROM t2 ORDER BY a;
+a b
+SELECT * FROM t3 ORDER BY a;
+a b
+1 1
+2 2
+3 3
+SELECT * FROM t5 ORDER BY a;
+a b
+1 foo
+2 bar
+3 baz
+4 gås
+5 gås
+########################################################################
+# TABLES ON SLAVE: should be the same as on master
+########################################################################
+SELECT * FROM t1 ORDER BY a;
+a b
+0 1
+SELECT * FROM t2 ORDER BY a;
+a b
+SELECT * FROM t3 ORDER BY a;
+a b
+1 1
+2 2
+3 3
+SELECT * FROM t5 ORDER BY a;
+a b
+1 foo
+2 bar
+3 baz
+4 gås
+5 gås
+########################################################################
+# EVENTS ON SLAVE
+# No Annotate_rows events should appear below
+########################################################################
+FLUSH LOGS;
+show binlog events in 'slave-bin.000001' from <start_pos>;
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Query 1 # DROP DATABASE IF EXISTS test1
+slave-bin.000001 # Query 1 # CREATE DATABASE test1
+slave-bin.000001 # Query 1 # use `test1`; CREATE TABLE t1(a int primary key, b int)
+slave-bin.000001 # Query 1 # use `test1`; CREATE TABLE t2(a int, b int)
+slave-bin.000001 # Query 1 # use `test1`; CREATE TABLE t3(a int, b int)
+slave-bin.000001 # Query 1 # use `test1`; CREATE TABLE t4(a int, b int)
+slave-bin.000001 # Query 1 # use `test1`; CREATE TABLE t5 (
+a INT PRIMARY KEY AUTO_INCREMENT,
+b VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_bin
+)
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t1)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t1)
+slave-bin.000001 # Update_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t1)
+slave-bin.000001 # Update_rows 1 # table_id: #
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t2)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t3)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t2)
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t1)
+slave-bin.000001 # Delete_rows 1 # table_id: #
+slave-bin.000001 # Delete_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t2)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t2)
+slave-bin.000001 # Delete_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t5)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t5)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Query 1 # BEGIN
+slave-bin.000001 # Table_map 1 # table_id: # (test1.t5)
+slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+slave-bin.000001 # Query 1 # COMMIT
+slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4
+#
+########################################################################
+# INSERTs DELAYED ON MASTERs
+########################################################################
+SET SESSION binlog_annotate_row_events = ON;
+INSERT DELAYED INTO test1.t4 VALUES (1,1);
+FLUSH TABLES;
+SELECT * FROM test1.t4 ORDER BY a;
+a b
+1 1
+########################################################################
+# ON SLAVE
+# No Annotate_rows events should appear below
+########################################################################
+FLUSH LOGS;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_row_conflicts.result b/mysql-test/suite/rpl/r/rpl_row_conflicts.result
index 51d23cf7128..05da799ba6f 100644
--- a/mysql-test/suite/rpl/r/rpl_row_conflicts.result
+++ b/mysql-test/suite/rpl/r/rpl_row_conflicts.result
@@ -22,7 +22,7 @@ a
[on slave]
---- Wait until slave stops with an error ----
include/wait_for_slave_sql_error.inc [errno=1062]
-Last_SQL_Error = Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log master-bin.000001, end_log_pos 346 (expected "duplicate key" error)
+Last_SQL_Error = Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log master-bin.000001, end_log_pos 485 (expected "duplicate key" error)
call mtr.add_suppression("Slave SQL.*Duplicate entry .1. for key .PRIMARY.* Error_code: 1062");
SELECT * FROM t1;
a
diff --git a/mysql-test/suite/rpl/r/rpl_row_index_choice.result b/mysql-test/suite/rpl/r/rpl_row_index_choice.result
new file mode 100644
index 00000000000..2d955299e6e
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_row_index_choice.result
@@ -0,0 +1,140 @@
+include/master-slave.inc
+[connection master]
+CREATE TABLE t1 (a int, b varchar(100), fulltext(b)) engine=MyISAM;
+INSERT INTO t1 VALUES (1,"a"), (2,"b");
+UPDATE t1 SET b='A' WHERE a=1;
+DELETE FROM t1 WHERE a=2;
+SELECT * FROM t1 ORDER BY a;
+a b
+1 A
+DROP TABLE t1;
+CREATE TABLE t1 (d INT PRIMARY KEY) ENGINE=myisam;
+INSERT INTO t1 VALUES (0);
+INSERT INTO t1 SELECT d+1 FROM t1;
+INSERT INTO t1 SELECT d+2 FROM t1;
+INSERT INTO t1 SELECT d+4 FROM t1;
+INSERT INTO t1 SELECT d+8 FROM t1;
+INSERT INTO t1 SELECT d+16 FROM t1;
+INSERT INTO t1 SELECT d+32 FROM t1;
+INSERT INTO t1 SELECT d+64 FROM t1;
+INSERT INTO t1 SELECT d+128 FROM t1;
+INSERT INTO t1 SELECT d+256 FROM t1;
+INSERT INTO t1 SELECT d+512 FROM t1;
+CREATE TABLE t2 (a INT, b INT, c INT, d INT,
+KEY wrong_key(a),
+KEY expected_key(b,c),
+KEY wrong_key2(c)) ENGINE=myisam;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d FROM t1;
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+# Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan";
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+a b c d
+4 1 5 10042
+DROP TABLE t2;
+CREATE TABLE t2 (a INT, b INT, c INT, d INT NOT NULL, e INT,
+UNIQUE wrong_key3(a,e),
+KEY wrong_key4(b,c),
+UNIQUE expected_key(d)) ENGINE=myisam;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d, NULL FROM t1;
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+# Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan";
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+a b c d e
+4 1 5 10042 NULL
+DROP TABLE t2;
+CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT NOT NULL,
+KEY wrong_key5(b),
+UNIQUE expected_key(d),
+KEY wrong_key6(c)) ENGINE=myisam;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d FROM t1;
+# Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan";
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+a b c d
+4 1 5 10042
+DROP TABLE t2;
+CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT NOT NULL,
+KEY expected_key(b),
+KEY wrong_key7(d),
+KEY wrong_key8(c)) ENGINE=myisam;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d FROM t1;
+# Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan";
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+a b c d
+4 1 5 10042
+DROP TABLE t2;
+CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT,
+UNIQUE wrong_key9(d),
+KEY wrong_key10(a),
+PRIMARY KEY expected_key(c,b)) ENGINE=innodb;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d FROM t1;
+# Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan,slave_crash_if_index_scan";
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+a b c d
+4 1 5 10042
+DROP TABLE t2;
+CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT, e INT,
+UNIQUE wrong_key11(e),
+KEY wrong_key12(a),
+KEY expected_key(c,b)) ENGINE=innodb;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d, IF(d<10, d, NULL) FROM t1;
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+# Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan";
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+a b c d e
+4 1 5 10042 NULL
+DROP TABLE t2;
+CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT, e INT,
+KEY wrong_key13(a),
+UNIQUE expected_key(e),
+KEY wrong_key14(c,b)) ENGINE=innodb;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d, IF(d<10, d, NULL) FROM t1;
+# Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan";
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+a b c d e
+4 1 5 10042 NULL
+DROP TABLE t2;
+CREATE TABLE t2 (a INT NOT NULL, d INT) ENGINE=innodb;
+INSERT INTO t2 SELECT d DIV 10, d FROM t1;
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+SELECT * FROM t2 WHERE d IN (10042,53);
+a d
+4 10042
+DROP TABLE t2;
+DROP TABLE t1;
+SET GLOBAL debug="";
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_stm_000001.result b/mysql-test/suite/rpl/r/rpl_stm_000001.result
index 3a67772d11a..afe4096b84c 100644
--- a/mysql-test/suite/rpl/r/rpl_stm_000001.result
+++ b/mysql-test/suite/rpl/r/rpl_stm_000001.result
@@ -48,7 +48,7 @@ select (@id := id) - id from t2;
kill @id;
drop table t2;
Got one of the listed errors
-include/wait_for_slave_sql_error_and_skip.inc [errno=1053]
+include/wait_for_slave_sql_error_and_skip.inc [errno=1927]
select count(*) from t1;
count(*)
5000
diff --git a/mysql-test/suite/rpl/r/rpl_switch_stm_row_mixed.result b/mysql-test/suite/rpl/r/rpl_switch_stm_row_mixed.result
index bd3d170c9f0..b88071391c5 100644
--- a/mysql-test/suite/rpl/r/rpl_switch_stm_row_mixed.result
+++ b/mysql-test/suite/rpl/r/rpl_switch_stm_row_mixed.result
@@ -135,6 +135,8 @@ create table t2 ENGINE=MyISAM select rpad(UUID(),100,' ');
create table t3 select 1 union select UUID();
create table t4 select * from t1 where 3 in (select 1 union select 2 union select UUID() union select 3);
create table t5 select * from t1 where 3 in (select 1 union select 2 union select curdate() union select 3);
+Warnings:
+Warning 1292 Incorrect datetime value: '3'
insert into t5 select UUID() from t1 where 3 in (select 1 union select 2 union select 3 union select * from t4);
create procedure foo()
begin
diff --git a/mysql-test/suite/rpl/r/rpl_variables_stm.result b/mysql-test/suite/rpl/r/rpl_variables_stm.result
index 553a1710d77..faef89f2d80 100644
--- a/mysql-test/suite/rpl/r/rpl_variables_stm.result
+++ b/mysql-test/suite/rpl/r/rpl_variables_stm.result
@@ -482,8 +482,8 @@ id num text
52 NULL latin7
53 NULL latin7_estonian_cs
54 NULL latin7
-55 NULL 47114711
-56 NULL 47124712
+55 NULL 47114711.000000
+56 NULL 47124712.000000
57 NULL 1616
58 NULL 1717
include/diff_tables.inc [master:tstmt,tproc,tfunc,ttrig,tprep, slave:tstmt,tproc,tfunc,ttrig,tprep]
diff --git a/mysql-test/suite/rpl/t/rpl_change_master.test b/mysql-test/suite/rpl/t/rpl_change_master.test
index 65af5e72865..36db1de8d40 100644
--- a/mysql-test/suite/rpl/t/rpl_change_master.test
+++ b/mysql-test/suite/rpl/t/rpl_change_master.test
@@ -3,6 +3,7 @@
# I/O thread left (some old bug fixed in 4.0.17)
source include/master-slave.inc;
+call mtr.add_suppression("Slave I/O: The slave I/O thread stops because a fatal error is encountered when it tried to SET @master_binlog_checksum");
connection master;
# Make SQL slave thread advance a bit
diff --git a/mysql-test/suite/rpl/t/rpl_checksum-master.opt b/mysql-test/suite/rpl/t/rpl_checksum-master.opt
new file mode 100644
index 00000000000..a6e99a9fd5a
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_checksum-master.opt
@@ -0,0 +1 @@
+--binlog-checksum=CRC32
diff --git a/mysql-test/suite/rpl/t/rpl_checksum.test b/mysql-test/suite/rpl/t/rpl_checksum.test
new file mode 100644
index 00000000000..237fffaf33e
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_checksum.test
@@ -0,0 +1,264 @@
+# WL2540 replication events checksum
+# Testing configuration parameters
+
+--source include/master-slave.inc
+--source include/have_debug.inc
+--source include/have_binlog_format_mixed.inc
+
+call mtr.add_suppression('Slave can not handle replication events with the checksum that master is configured to log');
+call mtr.add_suppression('Replication event checksum verification failed');
+# due to C failure simulation
+call mtr.add_suppression('Relay log write failure: could not queue event from master');
+call mtr.add_suppression('Master is configured to log replication events with checksum, but will not send such events to slaves that cannot process them');
+
+# A. read/write access to the global vars:
+# binlog_checksum master_verify_checksum slave_sql_verify_checksum
+
+connection master;
+
+set @master_save_binlog_checksum= @@global.binlog_checksum;
+set @save_master_verify_checksum = @@global.master_verify_checksum;
+
+select @@global.binlog_checksum as 'must be CRC32 because of the command line option';
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.binlog_checksum as 'no session var';
+
+select @@global.master_verify_checksum as 'must be zero because of default';
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.master_verify_checksum as 'no session var';
+
+connection slave;
+
+set @slave_save_binlog_checksum= @@global.binlog_checksum;
+set @save_slave_sql_verify_checksum = @@global.slave_sql_verify_checksum;
+
+select @@global.slave_sql_verify_checksum as 'must be one because of default';
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.slave_sql_verify_checksum as 'no session var';
+
+connection master;
+
+source include/show_binary_logs.inc;
+set @@global.binlog_checksum = NONE;
+select @@global.binlog_checksum;
+--echo *** must be rotations seen ***
+source include/show_binary_logs.inc;
+
+set @@global.binlog_checksum = default;
+select @@global.binlog_checksum;
+
+# testing lack of side-effects in non-effective update of binlog_checksum:
+set @@global.binlog_checksum = CRC32;
+select @@global.binlog_checksum;
+set @@global.binlog_checksum = CRC32;
+
+set @@global.master_verify_checksum = 0;
+set @@global.master_verify_checksum = default;
+
+--error ER_WRONG_VALUE_FOR_VAR
+set @@global.binlog_checksum = ADLER32;
+--error ER_WRONG_VALUE_FOR_VAR
+set @@global.master_verify_checksum = 2; # the var is of bool type
+
+connection slave;
+
+set @@global.slave_sql_verify_checksum = 0;
+set @@global.slave_sql_verify_checksum = default;
+--error ER_WRONG_VALUE_FOR_VAR
+set @@global.slave_sql_verify_checksum = 2; # the var is of bool type
+
+#
+# B. Old Slave to New master conditions
+#
+# while master does not send a checksum-ed binlog the Old Slave can
+# work with the New Master
+
+connection master;
+
+set @@global.binlog_checksum = NONE;
+create table t1 (a int);
+
+# testing that binlog rotation preserves opt_binlog_checksum value
+flush logs;
+flush logs;
+flush logs;
+
+sync_slave_with_master;
+#connection slave;
+# checking that rotation on the slave side leaves slave stable
+flush logs;
+flush logs;
+flush logs;
+select count(*) as zero from t1;
+
+source include/stop_slave.inc;
+
+connection master;
+set @@global.binlog_checksum = CRC32;
+insert into t1 values (1) /* will not be applied on slave due to simulation */;
+
+# instruction to the dump thread
+
+connection slave;
+set @@global.debug='d,simulate_slave_unaware_checksum';
+start slave;
+--let $slave_io_errno= 1236
+--let $show_slave_io_error= 1
+source include/wait_for_slave_io_error.inc;
+
+select count(*) as zero from t1;
+
+###connection master;
+set @@global.debug='';
+
+connection slave;
+source include/start_slave.inc;
+
+#
+# C. checksum failure simulations
+#
+
+# C1. Failure by a client thread
+connection master;
+set @@global.master_verify_checksum = 1;
+set @@session.debug='d,simulate_checksum_test_failure';
+--error ER_ERROR_WHEN_EXECUTING_COMMAND
+show binlog events;
+set @@session.debug='';
+set @@global.master_verify_checksum = default;
+
+#connection master;
+sync_slave_with_master;
+
+connection slave;
+source include/stop_slave.inc;
+
+connection master;
+create table t2 (a int);
+let $pos_master= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+connection slave;
+
+# C2. Failure by IO thread
+# instruction to io thread
+set @@global.debug='d,simulate_checksum_test_failure';
+start slave io_thread;
+--let $slave_io_errno= 1595
+--let $show_slave_io_error= 1
+source include/wait_for_slave_io_error.inc;
+set @@global.debug='';
+
+# to make IO thread re-read it again w/o the failure
+start slave io_thread;
+let $slave_param= Read_Master_Log_Pos;
+let $slave_param_value= $pos_master;
+source include/wait_for_slave_param.inc;
+
+# C3. Failure by SQL thread
+# instruction to sql thread;
+set @@global.slave_sql_verify_checksum = 1;
+
+set @@global.debug='d,simulate_checksum_test_failure';
+
+start slave sql_thread;
+--let $slave_sql_errno= 1593
+--let $show_slave_sql_error= 1
+source include/wait_for_slave_sql_error.inc;
+
+# resuming SQL thread to parse out the event w/o the failure
+
+set @@global.debug='';
+source include/start_slave.inc;
+
+connection master;
+sync_slave_with_master;
+
+#connection slave;
+select count(*) as 'must be zero' from t2;
+
+#
+# D. Reset slave, Change-Master, Binlog & Relay-log rotations with
+# random value on binlog_checksum on both master and slave
+#
+connection slave;
+stop slave;
+reset slave;
+
+# randomize slave server's own checksum policy
+set @@global.binlog_checksum= IF(floor((rand()*1000)%2), "CRC32", "NONE");
+flush logs;
+
+connection master;
+set @@global.binlog_checksum= CRC32;
+reset master;
+flush logs;
+create table t3 (a int, b char(5));
+
+connection slave;
+source include/start_slave.inc;
+
+connection master;
+sync_slave_with_master;
+
+#connection slave;
+select count(*) as 'must be zero' from t3;
+source include/stop_slave.inc;
+--replace_result $MASTER_MYPORT MASTER_PORT
+eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root';
+
+connection master;
+flush logs;
+reset master;
+insert into t3 value (1, @@global.binlog_checksum);
+
+connection slave;
+source include/start_slave.inc;
+flush logs;
+
+connection master;
+sync_slave_with_master;
+
+#connection slave;
+select count(*) as 'must be one' from t3;
+
+connection master;
+set @@global.binlog_checksum= IF(floor((rand()*1000)%2), "CRC32", "NONE");
+insert into t3 value (1, @@global.binlog_checksum);
+sync_slave_with_master;
+
+#connection slave;
+
+#clean-up
+
+connection master;
+drop table t1, t2, t3;
+set @@global.binlog_checksum = @master_save_binlog_checksum;
+set @@global.master_verify_checksum = @save_master_verify_checksum;
+
+#
+# BUG#58564: flush_read_lock fails in mysql-trunk-bugfixing after merging with WL#2540
+#
+# Sanity check that verifies that no assertions are triggered because
+# of old FD events (generated by versions prior to server released with
+# checksums feature)
+#
+# There is no need for query log, if something wrong this should trigger
+# an assertion
+
+--disable_query_log
+
+BINLOG '
+MfmqTA8BAAAAZwAAAGsAAAABAAQANS41LjctbTMtZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAx+apMEzgNAAgAEgAEBAQEEgAAVAAEGggAAAAICAgCAA==
+';
+
+--enable_query_log
+
+#connection slave;
+sync_slave_with_master;
+set @@global.binlog_checksum = @slave_save_binlog_checksum;
+set @@global.slave_sql_verify_checksum = @save_slave_sql_verify_checksum;
+
+--echo End of tests
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_checksum_cache.test b/mysql-test/suite/rpl/t/rpl_checksum_cache.test
new file mode 100644
index 00000000000..5667d599aff
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_checksum_cache.test
@@ -0,0 +1,255 @@
+-- source include/have_innodb.inc
+-- source include/master-slave.inc
+
+--disable_warnings
+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. Statement: insert into t2 set data=repeat.*'a', @act_size.*");
+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. Statement: insert into t1 values.* NAME_CONST.*'n',.*, @data .*");
+--enable_warnings
+
+connection master;
+set @save_binlog_cache_size = @@global.binlog_cache_size;
+set @save_binlog_checksum = @@global.binlog_checksum;
+set @save_master_verify_checksum = @@global.master_verify_checksum;
+set @@global.binlog_cache_size = 4096;
+set @@global.binlog_checksum = CRC32;
+set @@global.master_verify_checksum = 1;
+
+# restart slave to force the dump thread to verify events (on master side)
+connection slave;
+source include/stop_slave.inc;
+source include/start_slave.inc;
+
+connection master;
+
+#
+# Testing a critical part of checksum handling dealing with transaction cache.
+# The cache's buffer size is set to be less than the transaction's footprint
+# in binlog.
+#
+# To verify combined buffer-by-buffer read out of the file and fixing crc per event
+# there are the following parts:
+#
+# 1. the event size is much less than the cache's buffer
+# 2. the event size is bigger than the cache's buffer
+# 3. the event size if approximately the same as the cache's buffer
+# 4. all in above
+
+#
+# 1. the event size is much less than the cache's buffer
+#
+
+flush status;
+show status like "binlog_cache_use";
+show status like "binlog_cache_disk_use";
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+#
+# parameter to ensure the test slightly varies binlog content
+# between different invocations
+#
+let $deviation_size=32;
+eval create table t1 (a int PRIMARY KEY, b CHAR($deviation_size)) engine=innodb;
+
+# Now we are going to create transaction which is long enough so its
+# transaction binlog will be flushed to disk...
+
+delimiter |;
+create procedure test.p_init (n int, size int)
+begin
+ while n > 0 do
+ select round(RAND() * size) into @act_size;
+ set @data = repeat('a', @act_size);
+ insert into t1 values(n, @data );
+ set n= n-1;
+ end while;
+end|
+
+delimiter ;|
+
+let $1 = 4000; # PB2 can run it slow to time out on following sync_slave_with_master:s
+
+begin;
+--disable_warnings
+# todo: check if it is really so.
+#+Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statement uses a system function whose value may differ on slave.
+eval call test.p_init($1, $deviation_size);
+--enable_warnings
+commit;
+
+show status like "binlog_cache_use";
+--echo *** binlog_cache_disk_use must be non-zero ***
+show status like "binlog_cache_disk_use";
+
+sync_slave_with_master;
+
+let $diff_tables=master:test.t1, slave:test.t1;
+source include/diff_tables.inc;
+
+# undoing changes with verifying the above once again
+connection master;
+
+begin;
+delete from t1;
+commit;
+
+sync_slave_with_master;
+
+
+#
+# 2. the event size is bigger than the cache's buffer
+#
+connection master;
+
+flush status;
+let $t2_data_size= `select 3 * @@global.binlog_cache_size`;
+let $t2_aver_size= `select 2 * @@global.binlog_cache_size`;
+let $t2_max_rand= `select 1 * @@global.binlog_cache_size`;
+
+eval create table t2(a int auto_increment primary key, data VARCHAR($t2_data_size)) ENGINE=Innodb;
+let $1=100;
+--disable_query_log
+begin;
+while ($1)
+{
+ eval select round($t2_aver_size + RAND() * $t2_max_rand) into @act_size;
+ set @data = repeat('a', @act_size);
+ insert into t2 set data = @data;
+ dec $1;
+}
+commit;
+--enable_query_log
+show status like "binlog_cache_use";
+--echo *** binlog_cache_disk_use must be non-zero ***
+show status like "binlog_cache_disk_use";
+
+sync_slave_with_master;
+
+let $diff_tables=master:test.t2, slave:test.t2;
+source include/diff_tables.inc;
+
+# undoing changes with verifying the above once again
+connection master;
+
+begin;
+delete from t2;
+commit;
+
+sync_slave_with_master;
+
+#
+# 3. the event size if approximately the same as the cache's buffer
+#
+
+connection master;
+
+flush status;
+let $t3_data_size= `select 2 * @@global.binlog_cache_size`;
+let $t3_aver_size= `select (9 * @@global.binlog_cache_size) / 10`;
+let $t3_max_rand= `select (2 * @@global.binlog_cache_size) / 10`;
+
+eval create table t3(a int auto_increment primary key, data VARCHAR($t3_data_size)) engine=innodb;
+
+let $1= 300;
+--disable_query_log
+begin;
+while ($1)
+{
+ eval select round($t3_aver_size + RAND() * $t3_max_rand) into @act_size;
+ insert into t3 set data= repeat('a', @act_size);
+ dec $1;
+}
+commit;
+--enable_query_log
+show status like "binlog_cache_use";
+--echo *** binlog_cache_disk_use must be non-zero ***
+show status like "binlog_cache_disk_use";
+
+sync_slave_with_master;
+
+let $diff_tables=master:test.t3, slave:test.t3;
+source include/diff_tables.inc;
+
+# undoing changes with verifying the above once again
+connection master;
+
+begin;
+delete from t3;
+commit;
+
+sync_slave_with_master;
+
+
+#
+# 4. all in above
+#
+
+connection master;
+flush status;
+
+delimiter |;
+eval create procedure test.p1 (n int)
+begin
+ while n > 0 do
+ case (select (round(rand()*100) % 3) + 1)
+ when 1 then
+ select round(RAND() * $deviation_size) into @act_size;
+ set @data = repeat('a', @act_size);
+ insert into t1 values(n, @data);
+ when 2 then
+ begin
+ select round($t2_aver_size + RAND() * $t2_max_rand) into @act_size;
+ insert into t2 set data=repeat('a', @act_size);
+ end;
+ when 3 then
+ begin
+ select round($t3_aver_size + RAND() * $t3_max_rand) into @act_size;
+ insert into t3 set data= repeat('a', @act_size);
+ end;
+ end case;
+ set n= n-1;
+ end while;
+end|
+delimiter ;|
+
+let $1= 1000;
+set autocommit= 0;
+begin;
+--disable_warnings
+eval call test.p1($1);
+--enable_warnings
+commit;
+
+show status like "binlog_cache_use";
+--echo *** binlog_cache_disk_use must be non-zero ***
+show status like "binlog_cache_disk_use";
+
+sync_slave_with_master;
+
+let $diff_tables=master:test.t1, slave:test.t1;
+source include/diff_tables.inc;
+
+let $diff_tables=master:test.t2, slave:test.t2;
+source include/diff_tables.inc;
+
+let $diff_tables=master:test.t3, slave:test.t3;
+source include/diff_tables.inc;
+
+
+connection master;
+
+begin;
+delete from t1;
+delete from t2;
+delete from t3;
+commit;
+
+drop table t1, t2, t3;
+set @@global.binlog_cache_size = @save_binlog_cache_size;
+set @@global.binlog_checksum = @save_binlog_checksum;
+set @@global.master_verify_checksum = @save_master_verify_checksum;
+drop procedure test.p_init;
+drop procedure test.p1;
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_corruption-master.opt b/mysql-test/suite/rpl/t/rpl_corruption-master.opt
new file mode 100644
index 00000000000..2612c17aa67
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_corruption-master.opt
@@ -0,0 +1 @@
+--binlog-checksum=CRC32 --master-verify-checksum=1
diff --git a/mysql-test/suite/rpl/t/rpl_corruption-slave.opt b/mysql-test/suite/rpl/t/rpl_corruption-slave.opt
new file mode 100644
index 00000000000..b32a52403c2
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_corruption-slave.opt
@@ -0,0 +1 @@
+--binlog-checksum=CRC32 --slave-sql-verify-checksum=1
diff --git a/mysql-test/suite/rpl/t/rpl_corruption.test b/mysql-test/suite/rpl/t/rpl_corruption.test
new file mode 100644
index 00000000000..a46325bf1f4
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_corruption.test
@@ -0,0 +1,165 @@
+############################################################
+# Purpose: WL#5064 Testing with corrupted events.
+# The test emulates the corruption at the vary stages
+# of replication:
+# - in binlog file
+# - in network
+# - in relay log
+############################################################
+
+#
+# The tests intensively utilize @@global.debug. Note,
+# Bug#11765758 - 58754,
+# @@global.debug is read by the slave threads through dbug-interface.
+# Hence, before a client thread set @@global.debug we have to ensure that:
+# (a) the slave threads are stopped, or (b) the slave threads are in
+# sync and waiting.
+
+--source include/have_debug.inc
+--source include/master-slave.inc
+
+# Block legal errors for MTR
+call mtr.add_suppression('Found invalid event in binary log');
+call mtr.add_suppression('Slave I/O: Relay log write failure: could not queue event from master');
+call mtr.add_suppression('event read from binlog did not pass crc check');
+call mtr.add_suppression('Replication event checksum verification failed');
+call mtr.add_suppression('Event crc check failed! Most likely there is event corruption');
+call mtr.add_suppression('Slave SQL: Error initializing relay log position: I/O error reading event at position .*, Error_code: 1593');
+
+SET @old_master_verify_checksum = @@master_verify_checksum;
+
+# Creating test table/data and set corruption position for testing
+--echo # 1. Creating test table/data and set corruption position for testing
+--connection master
+--echo * insert/update/delete rows in table t1 *
+# Corruption algorithm modifies only the first event and
+# then will be reset. To avoid checking always the first event
+# from binlog (usually it is FD) we randomly execute different
+# statements and set position for corruption inside events.
+
+CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b VARCHAR(10), c VARCHAR(100));
+--disable_query_log
+let $i=`SELECT 3+CEILING(10*RAND())`;
+let $j=1;
+let $pos=0;
+while ($i) {
+ eval INSERT INTO t1 VALUES ($j, 'a', NULL);
+ if (`SELECT RAND() > 0.7`)
+ {
+ eval UPDATE t1 SET c = REPEAT('a', 20) WHERE a = $j;
+ }
+ if (`SELECT RAND() > 0.8`)
+ {
+ eval DELETE FROM t1 WHERE a = $j;
+ }
+ if (!$pos) {
+ let $pos= query_get_value(SHOW MASTER STATUS, Position, 1);
+ --sync_slave_with_master
+ --source include/stop_slave.inc
+ --disable_query_log
+ --connection master
+ }
+ dec $i;
+ inc $j;
+}
+--enable_query_log
+
+
+# Emulate corruption in binlog file when SHOW BINLOG EVENTS is executing
+--echo # 2. Corruption in master binlog and SHOW BINLOG EVENTS
+SET GLOBAL debug="+d,corrupt_read_log_event_char";
+--echo SHOW BINLOG EVENTS;
+--disable_query_log
+send_eval SHOW BINLOG EVENTS FROM $pos;
+--enable_query_log
+--error ER_ERROR_WHEN_EXECUTING_COMMAND
+reap;
+
+SET GLOBAL debug="-d,corrupt_read_log_event_char";
+
+# Emulate corruption on master with crc checking on master
+--echo # 3. Master read a corrupted event from binlog and send the error to slave
+
+# We have a rare but nasty potential race here: if the dump thread on
+# the master for the _old_ slave connection has not yet discovered
+# that the slave has disconnected, we will inject the corrupt event on
+# the wrong connection, and the test will fail
+# (+d,corrupt_read_log_event2 corrupts only one event).
+# So kill any lingering dump thread (we need to kill; otherwise dump thread
+# could manage to send all events down the socket before seeing it close, and
+# hang forever waiting for new binlog events to be created).
+let $id= `select id from information_schema.processlist where command = "Binlog Dump"`;
+if ($id)
+{
+ --disable_query_log
+ --error 0,1094
+ eval kill $id;
+ --enable_query_log
+}
+let $wait_condition=
+ SELECT COUNT(*)=0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE command = 'Binlog Dump';
+--source include/wait_condition.inc
+
+SET GLOBAL debug="+d,corrupt_read_log_event2";
+--connection slave
+START SLAVE IO_THREAD;
+let $slave_io_errno= 1236;
+--source include/wait_for_slave_io_error.inc
+--connection master
+SET GLOBAL debug="-d,corrupt_read_log_event2";
+
+# Emulate corruption on master without crc checking on master
+--echo # 4. Master read a corrupted event from binlog and send it to slave
+--connection master
+SET GLOBAL master_verify_checksum=0;
+SET GLOBAL debug="+d,corrupt_read_log_event2";
+--connection slave
+START SLAVE IO_THREAD;
+let $slave_io_errno= 1595,1722;
+--source include/wait_for_slave_io_error.inc
+--connection master
+SET GLOBAL debug="-d,corrupt_read_log_event2";
+SET GLOBAL debug= "";
+SET GLOBAL master_verify_checksum=1;
+
+# Emulate corruption in network
+--echo # 5. Slave. Corruption in network
+--connection slave
+SET GLOBAL debug="+d,corrupt_queue_event";
+START SLAVE IO_THREAD;
+let $slave_io_errno= 1595,1722;
+--source include/wait_for_slave_io_error.inc
+SET GLOBAL debug="-d,corrupt_queue_event";
+
+# Emulate corruption in relay log
+--echo # 6. Slave. Corruption in relay log
+
+SET GLOBAL debug="+d,corrupt_read_log_event_char";
+
+START SLAVE SQL_THREAD;
+let $slave_sql_errno= 1593;
+--source include/wait_for_slave_sql_error.inc
+
+SET GLOBAL debug="-d,corrupt_read_log_event_char";
+SET GLOBAL debug= "";
+
+# Start normal replication and compare same table on master
+# and slave
+--echo # 7. Seek diff for tables on master and slave
+--connection slave
+--source include/start_slave.inc
+--connection master
+--sync_slave_with_master
+let $diff_tables= master:test.t1, slave:test.t1;
+--source include/diff_tables.inc
+
+# Clean up
+--echo # 8. Clean up
+--connection master
+SET GLOBAL debug= "";
+SET GLOBAL master_verify_checksum = @old_master_verify_checksum;
+DROP TABLE t1;
+--sync_slave_with_master
+SET GLOBAL debug= "";
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_hrtime.test b/mysql-test/suite/rpl/t/rpl_hrtime.test
new file mode 100644
index 00000000000..98b08abec67
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_hrtime.test
@@ -0,0 +1,7 @@
+--source include/have_binlog_format_mixed_or_statement.inc
+
+--source suite/rpl/include/hrtime.inc
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--exec $MYSQL_BINLOG --short-form $MYSQLD_DATADIR/master-bin.000001
+
diff --git a/mysql-test/suite/rpl/t/rpl_hrtime_row.test b/mysql-test/suite/rpl/t/rpl_hrtime_row.test
new file mode 100644
index 00000000000..e1d49f5324b
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_hrtime_row.test
@@ -0,0 +1,3 @@
+--source include/have_binlog_format_row.inc
+--source suite/rpl/include/hrtime.inc
+
diff --git a/mysql-test/suite/rpl/t/rpl_innodb_bug28430.test b/mysql-test/suite/rpl/t/rpl_innodb_bug28430.test
index 782c01ec04f..afc0c2cbd4b 100644
--- a/mysql-test/suite/rpl/t/rpl_innodb_bug28430.test
+++ b/mysql-test/suite/rpl/t/rpl_innodb_bug28430.test
@@ -127,11 +127,17 @@ delimiter ;|
############ Test Section ###################
+begin;
CALL test.proc_norm();
+commit;
SELECT count(*) as "Master regular" FROM test.regular_tbl;
+begin;
CALL test.proc_bykey();
+commit;
SELECT count(*) as "Master bykey" FROM test.bykey_tbl;
+begin;
CALL test.proc_byrange();
+commit;
SELECT count(*) as "Master byrange" FROM test.byrange_tbl;
--sync_slave_with_master
diff --git a/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test b/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test
index 09bc715f9a5..db603c3f5ba 100644
--- a/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test
+++ b/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test
@@ -4,11 +4,14 @@
# imitate the bug, so it has to stop).
source include/have_debug.inc;
+# because of pretend_version_50034_in_binlog the test can't run with checksum
+source include/have_binlog_checksum_off.inc;
source include/master-slave.inc;
# Currently only statement-based-specific bugs are here
-- source include/have_binlog_format_mixed_or_statement.inc
+
#
# This is to test that slave properly detects if
# master may suffer from:
diff --git a/mysql-test/suite/rpl/t/rpl_rotate_logs.test b/mysql-test/suite/rpl/t/rpl_rotate_logs.test
index fefb04d7ed9..6002666a70a 100644
--- a/mysql-test/suite/rpl/t/rpl_rotate_logs.test
+++ b/mysql-test/suite/rpl/t/rpl_rotate_logs.test
@@ -143,7 +143,10 @@ select * from t2;
connection master;
create temporary table temp_table (a char(80) not null);
insert into temp_table values ("testing temporary tables part 2");
-let $1=100;
+
+# the nummber of produced logs is sensitive to whether checksum is NONE or CRC32
+# the value of 90 makes it even
+let $1=90;
create table t3 (n int);
disable_query_log;
diff --git a/mysql-test/suite/rpl/t/rpl_row_annotate_do-slave.opt b/mysql-test/suite/rpl/t/rpl_row_annotate_do-slave.opt
new file mode 100644
index 00000000000..18de9bd1e33
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_annotate_do-slave.opt
@@ -0,0 +1 @@
+--log-slave-updates --replicate-annotate-row-events --replicate-ignore-table=test1.xt1 --replicate-ignore-table=test1.xt2
diff --git a/mysql-test/suite/rpl/t/rpl_row_annotate_do.test b/mysql-test/suite/rpl/t/rpl_row_annotate_do.test
new file mode 100644
index 00000000000..4114f90b90b
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_annotate_do.test
@@ -0,0 +1,16 @@
+###############################################################################
+# WL47: Store in binlog text of statements that caused RBR events
+# Wrapper for extra/rpl/rpl_row_annotate.test.
+# Intended to test that if the --replicate-annotate-row-events option
+# is switched on on slave then Annotate_events:
+# - are reproduced on slave
+# - are reproduced only once for "multi-table-maps" rbr queries
+# - are not reproduced when the corresponding queries are filtered away
+# on replication
+# - are reproduced when the corresponding queries are filtered away partialy
+# (e.g. in case of multi-delete)
+# - are not generated on slave for queries that are not annotated on master.
+###############################################################################
+
+--source include/have_binlog_format_row.inc
+--source extra/rpl_tests/rpl_row_annotate.test
diff --git a/mysql-test/suite/rpl/t/rpl_row_annotate_dont-slave.opt b/mysql-test/suite/rpl/t/rpl_row_annotate_dont-slave.opt
new file mode 100644
index 00000000000..74ac3bfefcb
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_annotate_dont-slave.opt
@@ -0,0 +1 @@
+--log-slave-updates --replicate-ignore-table=test1.xt1 --replicate-ignore-table=test1.xt2 \ No newline at end of file
diff --git a/mysql-test/suite/rpl/t/rpl_row_annotate_dont.test b/mysql-test/suite/rpl/t/rpl_row_annotate_dont.test
new file mode 100644
index 00000000000..ef746e76b4d
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_annotate_dont.test
@@ -0,0 +1,9 @@
+###############################################################################
+# WL47: Store in binlog text of statements that caused RBR events
+# Wrapper for extra/rpl/rpl_row_annotate.test.
+# Intended to test that if the --replicate-annotate-row-events option
+# is switched off on slave then Annotate_events are not reproduced.
+###############################################################################
+
+--source include/have_binlog_format_row.inc
+--source extra/rpl_tests/rpl_row_annotate.test
diff --git a/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test b/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test
index c592e50be1b..8003595e578 100644
--- a/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test
+++ b/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test
@@ -1,3 +1,4 @@
+-- source include/have_query_cache.inc
--source include/have_binlog_format_row.inc
let $SERVER_VERSION=`select version()`;
diff --git a/mysql-test/suite/rpl/t/rpl_row_flsh_tbls.test b/mysql-test/suite/rpl/t/rpl_row_flsh_tbls.test
index f506d0c54f5..2429dbc1142 100644
--- a/mysql-test/suite/rpl/t/rpl_row_flsh_tbls.test
+++ b/mysql-test/suite/rpl/t/rpl_row_flsh_tbls.test
@@ -1,7 +1,8 @@
# depends on the binlog output
-- source include/have_binlog_format_row.inc
+--source include/binlog_start_pos.inc
-let $rename_event_pos= 925;
+let $rename_event_pos= `select @binlog_start_pos + 819`;
# Bug#18326: Do not lock table for writing during prepare of statement
# The use of the ps protocol causes extra table maps in the binlog, so
diff --git a/mysql-test/suite/rpl/t/rpl_row_index_choice.test b/mysql-test/suite/rpl/t/rpl_row_index_choice.test
new file mode 100644
index 00000000000..d393c65438a
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_index_choice.test
@@ -0,0 +1,243 @@
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+--source include/have_debug.inc
+--source include/have_innodb.inc
+
+# Bug#58997: Row-based replication breaks on table with only fulltext index:
+connection master;
+CREATE TABLE t1 (a int, b varchar(100), fulltext(b)) engine=MyISAM;
+INSERT INTO t1 VALUES (1,"a"), (2,"b");
+UPDATE t1 SET b='A' WHERE a=1;
+DELETE FROM t1 WHERE a=2;
+
+sync_slave_with_master;
+
+connection slave;
+
+SELECT * FROM t1 ORDER BY a;
+
+connection master;
+DROP TABLE t1;
+
+
+# A utility table used to populate subsequent tables in various ways.
+connection master;
+CREATE TABLE t1 (d INT PRIMARY KEY) ENGINE=myisam;
+INSERT INTO t1 VALUES (0);
+INSERT INTO t1 SELECT d+1 FROM t1;
+INSERT INTO t1 SELECT d+2 FROM t1;
+INSERT INTO t1 SELECT d+4 FROM t1;
+INSERT INTO t1 SELECT d+8 FROM t1;
+INSERT INTO t1 SELECT d+16 FROM t1;
+INSERT INTO t1 SELECT d+32 FROM t1;
+INSERT INTO t1 SELECT d+64 FROM t1;
+INSERT INTO t1 SELECT d+128 FROM t1;
+INSERT INTO t1 SELECT d+256 FROM t1;
+INSERT INTO t1 SELECT d+512 FROM t1;
+
+# Test that we pick the better multi-column index, even if the
+# single-column index is more selective in the first column.
+CREATE TABLE t2 (a INT, b INT, c INT, d INT,
+ KEY wrong_key(a),
+ KEY expected_key(b,c),
+ KEY wrong_key2(c)) ENGINE=myisam;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d FROM t1;
+
+sync_slave_with_master;
+connection slave;
+ANALYZE TABLE t2;
+--echo # Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan";
+
+connection master;
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+
+sync_slave_with_master;
+connection slave;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+
+# Test that we don't pick a unique index with NULLS over a more selective
+# non-unique index.
+connection master;
+DROP TABLE t2;
+CREATE TABLE t2 (a INT, b INT, c INT, d INT NOT NULL, e INT,
+ UNIQUE wrong_key3(a,e),
+ KEY wrong_key4(b,c),
+ UNIQUE expected_key(d)) ENGINE=myisam;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d, NULL FROM t1;
+
+sync_slave_with_master;
+connection slave;
+ANALYZE TABLE t2;
+--echo # Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan";
+
+connection master;
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+
+sync_slave_with_master;
+connection slave;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+
+connection master;
+DROP TABLE t2;
+
+# Test that we pick a reasonable index when there is no rec_per_key[]
+# information (no ANALYZE TABLE).
+CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT NOT NULL,
+ KEY wrong_key5(b),
+ UNIQUE expected_key(d),
+ KEY wrong_key6(c)) ENGINE=myisam;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d FROM t1;
+
+sync_slave_with_master;
+connection slave;
+--echo # Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan";
+
+connection master;
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+
+sync_slave_with_master;
+connection slave;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+
+connection master;
+DROP TABLE t2;
+
+
+# Also test without ANALYZE when we pick the sub-optimal index.
+# In this case the key on (d) is the best one, but without ANALYZE TABLE we
+# have no information and will pick the first one on (b).
+# (This test should be updated if we improve the index selection, of course).
+CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT NOT NULL,
+ KEY expected_key(b),
+ KEY wrong_key7(d),
+ KEY wrong_key8(c)) ENGINE=myisam;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d FROM t1;
+
+sync_slave_with_master;
+connection slave;
+--echo # Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan";
+
+connection master;
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+
+sync_slave_with_master;
+connection slave;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+
+connection master;
+DROP TABLE t2;
+
+
+# Test that we pick the primary key for InnoDB, if available.
+CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT,
+ UNIQUE wrong_key9(d),
+ KEY wrong_key10(a),
+ PRIMARY KEY expected_key(c,b)) ENGINE=innodb;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d FROM t1;
+
+sync_slave_with_master;
+connection slave;
+--echo # Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan,slave_crash_if_index_scan";
+
+connection master;
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+
+sync_slave_with_master;
+connection slave;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+
+connection master;
+DROP TABLE t2;
+
+
+# Test that we pick a good index for InnoDB when primary key is not available.
+CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT, e INT,
+ UNIQUE wrong_key11(e),
+ KEY wrong_key12(a),
+ KEY expected_key(c,b)) ENGINE=innodb;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d, IF(d<10, d, NULL) FROM t1;
+
+sync_slave_with_master;
+connection slave;
+ANALYZE TABLE t2;
+--echo # Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan";
+
+connection master;
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+
+sync_slave_with_master;
+connection slave;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+
+connection master;
+DROP TABLE t2;
+
+
+# When there is no ANALYZE TABLE, InnoDB will just report "1" for index
+# cardinality for all indexes in rec_per_key. So currently we cannot choose
+# index to use intelligently. Just test that we work as expected (select
+# first index, remember that unique keys are sorted first by server).
+CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, d INT, e INT,
+ KEY wrong_key13(a),
+ UNIQUE expected_key(e),
+ KEY wrong_key14(c,b)) ENGINE=innodb;
+INSERT INTO t2 SELECT d DIV 10, d MOD 41, d MOD 37, d, IF(d<10, d, NULL) FROM t1;
+
+sync_slave_with_master;
+connection slave;
+--echo # Slave will crash if using the wrong or no index
+SET GLOBAL debug="+d,slave_crash_if_wrong_index,slave_crash_if_table_scan";
+
+connection master;
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+
+sync_slave_with_master;
+connection slave;
+SET GLOBAL debug="";
+SELECT * FROM t2 WHERE d IN (10042,53);
+
+connection master;
+DROP TABLE t2;
+
+
+# Finally, test behaviour when no indexes are available at all.
+CREATE TABLE t2 (a INT NOT NULL, d INT) ENGINE=innodb;
+INSERT INTO t2 SELECT d DIV 10, d FROM t1;
+
+UPDATE t2 SET d=10042 WHERE d=42;
+DELETE FROM t2 WHERE d=53;
+
+sync_slave_with_master;
+connection slave;
+SELECT * FROM t2 WHERE d IN (10042,53);
+
+connection master;
+DROP TABLE t2;
+
+
+connection master;
+DROP TABLE t1;
+sync_slave_with_master;
+connection slave;
+SET GLOBAL debug="";
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test b/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test
index eb4eb2e0ce8..dd46eeb393e 100644
--- a/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test
+++ b/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test
@@ -164,15 +164,18 @@ connection master;
remove_file $MYSQLTEST_VARDIR/tmp/master.sql;
+--source include/binlog_start_pos.inc
# this test for position option
-# By setting this position to 416, we should only get the create of t3
+# By setting this position to start_binlog_pos + 310, we should only get the create of t3
+let $start_pos= `select @binlog_start_pos + 310`;
+let $stop_pos= `select @binlog_start_pos + 463`;
--disable_query_log
select "--- Test 2 position test --" as "";
--enable_query_log
let $MYSQLD_DATADIR= `select @@datadir;`;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
---exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=416 --stop-position=569 $MYSQLD_DATADIR/master-bin.000001
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=$start_pos --stop-position=$stop_pos $MYSQLD_DATADIR/master-bin.000001
# These are tests for remote binlog.
# They should return the same as previous test.
@@ -183,7 +186,7 @@ select "--- Test 3 First Remote test --" as "";
# This is broken now
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
---exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --stop-position=569 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --stop-position=$stop_pos --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
# This part is disabled due to bug #17654
@@ -259,7 +262,7 @@ connection master;
select "--- Test 5 LOAD DATA --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
---exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --stop-position=106 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --stop-position=$binlog_start_pos --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
# Bug#7853 (mysqlbinlog does not accept input from stdin)
@@ -267,14 +270,17 @@ select "--- Test 5 LOAD DATA --" as "";
select "--- Test 6 reading stdin --" as "";
--enable_query_log
let $MYSQLD_DATADIR= `select @@datadir;`;
+let $stop_pos= `select @binlog_start_pos + 463`;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
---exec $MYSQL_BINLOG --short-form --stop-position=569 - < $MYSQLD_DATADIR/master-bin.000001
+--exec $MYSQL_BINLOG --short-form --stop-position=$stop_pos - < $MYSQLD_DATADIR/master-bin.000001
--disable_query_log
select "--- Test 7 reading stdin w/position --" as "";
--enable_query_log
+let $start_pos= `select @binlog_start_pos + 310`;
+let $stop_pos= `select @binlog_start_pos + 463`;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
---exec $MYSQL_BINLOG --short-form --position=416 --stop-position=569 - < $MYSQLD_DATADIR/master-bin.000001
+--exec $MYSQL_BINLOG --short-form --position=$start_pos --stop-position=$stop_pos - < $MYSQLD_DATADIR/master-bin.000001
# Bug#16217 (mysql client did not know how not switch its internal charset)
--disable_query_log
diff --git a/mysql-test/suite/rpl/t/rpl_start_stop_slave.test b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test
index 15f98916485..fff457b2e55 100644
--- a/mysql-test/suite/rpl/t/rpl_start_stop_slave.test
+++ b/mysql-test/suite/rpl/t/rpl_start_stop_slave.test
@@ -12,7 +12,7 @@ create table t1(n int);
sync_slave_with_master;
stop slave;
connection master;
-let $1=5000;
+let $1=2500;
disable_query_log;
while ($1)
{
diff --git a/mysql-test/suite/rpl/t/rpl_stm_000001.test b/mysql-test/suite/rpl/t/rpl_stm_000001.test
index 9841ecb040a..6b693b8dcb7 100644
--- a/mysql-test/suite/rpl/t/rpl_stm_000001.test
+++ b/mysql-test/suite/rpl/t/rpl_stm_000001.test
@@ -96,14 +96,15 @@ drop table t2;
connection master;
# The get_lock function causes warning for unsafe statement.
--disable_warnings
---error 1317,2013
+# 2013 = CR_SERVER_LOST
+--error ER_QUERY_INTERRUPTED,ER_CONNECTION_KILLED,2013
reap;
--enable_warnings
connection slave;
# The SQL slave thread should now have stopped because the query was killed on
# the master (so it has a non-zero error code in the binlog).
-# 1053 = ER_SERVER_SHUTDOWN
---let $slave_sql_errno= 1053
+# 1927 = ER_CONNECTION_KILLED
+--let $slave_sql_errno= 1927
--source include/wait_for_slave_sql_error_and_skip.inc
select count(*) from t1;
diff --git a/mysql-test/suite/rpl/t/rpl_stm_flsh_tbls.test b/mysql-test/suite/rpl/t/rpl_stm_flsh_tbls.test
index f0a2e660830..83ef8699425 100644
--- a/mysql-test/suite/rpl/t/rpl_stm_flsh_tbls.test
+++ b/mysql-test/suite/rpl/t/rpl_stm_flsh_tbls.test
@@ -1,5 +1,6 @@
# depends on the binlog output
--source include/have_binlog_format_mixed_or_statement.inc
+--source include/binlog_start_pos.inc
-let $rename_event_pos= 684;
+let $rename_event_pos= `select @binlog_start_pos + 578`;
-- source extra/rpl_tests/rpl_flsh_tbls.test
diff --git a/mysql-test/suite/rpl_ndb/t/rpl_ndb_multi.test b/mysql-test/suite/rpl_ndb/t/rpl_ndb_multi.test
index 65093319fbe..a245b054ebd 100644
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_multi.test
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_multi.test
@@ -37,8 +37,10 @@ stop slave;
# get the master binlog pos from the epoch, from the _other_ "master", server2
connection server2;
--replace_result $the_epoch <the_epoch>
+--disable_result_log
eval SELECT @the_pos:=Position,@the_file:=SUBSTRING_INDEX(FILE, '/', -1)
FROM mysql.ndb_binlog_index WHERE epoch = $the_epoch ;
+--enable_result_log
let $the_pos= `SELECT @the_pos` ;
let $the_file= `SELECT @the_file` ;
diff --git a/mysql-test/suite/sys_vars/r/binlog_checksum_basic.result b/mysql-test/suite/sys_vars/r/binlog_checksum_basic.result
new file mode 100644
index 00000000000..2821a4a7e63
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/binlog_checksum_basic.result
@@ -0,0 +1,14 @@
+set @save_binlog_checksum= @@global.binlog_checksum;
+set @@global.binlog_checksum = default;
+select @@global.binlog_checksum as 'must be NONE by default';
+must be NONE by default
+NONE
+select @@session.binlog_checksum as 'no session var';
+ERROR HY000: Variable 'binlog_checksum' is a GLOBAL variable
+set @@global.binlog_checksum = CRC32;
+set @@global.binlog_checksum = CRC32;
+set @@global.master_verify_checksum = 0;
+set @@global.master_verify_checksum = default;
+set @@global.binlog_checksum = ADLER32;
+ERROR 42000: Variable 'checksum' can't be set to the value of 'ADLER32'
+set @@global.binlog_checksum = @save_binlog_checksum;
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/r/master_verify_checksum_basic.result b/mysql-test/suite/sys_vars/r/master_verify_checksum_basic.result
new file mode 100644
index 00000000000..83a1283c358
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/master_verify_checksum_basic.result
@@ -0,0 +1,11 @@
+set @save_master_verify_checksum = @@global.master_verify_checksum;
+select @@global.master_verify_checksum as 'must be zero because of default';
+must be zero because of default
+0
+select @@session.master_verify_checksum as 'no session var';
+ERROR HY000: Variable 'master_verify_checksum' is a GLOBAL variable
+set @@global.master_verify_checksum = 0;
+set @@global.master_verify_checksum = default;
+set @@global.master_verify_checksum = 2;
+ERROR 42000: Variable 'master_verify_checksum' can't be set to the value of '2'
+set @@global.master_verify_checksum = @save_master_verify_checksum;
diff --git a/mysql-test/suite/sys_vars/r/slave_sql_verify_checksum_basic.result b/mysql-test/suite/sys_vars/r/slave_sql_verify_checksum_basic.result
new file mode 100644
index 00000000000..cd80381239a
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/slave_sql_verify_checksum_basic.result
@@ -0,0 +1,11 @@
+set @save_slave_sql_verify_checksum = @@global.slave_sql_verify_checksum;
+select @@global.slave_sql_verify_checksum as 'must be one because of default';
+must be one because of default
+1
+select @@session.slave_sql_verify_checksum as 'no session var';
+ERROR HY000: Variable 'slave_sql_verify_checksum' is a GLOBAL variable
+set @@global.slave_sql_verify_checksum = 0;
+set @@global.slave_sql_verify_checksum = default;
+set @@global.slave_sql_verify_checksum = 2;
+ERROR 42000: Variable 'slave_sql_verify_checksum' can't be set to the value of '2'
+set @@global.slave_sql_verify_checksum = @save_slave_sql_verify_checksum;
diff --git a/mysql-test/suite/sys_vars/t/binlog_checksum_basic.test b/mysql-test/suite/sys_vars/t/binlog_checksum_basic.test
new file mode 100644
index 00000000000..fb3d8e33fa1
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/binlog_checksum_basic.test
@@ -0,0 +1,25 @@
+--source include/not_embedded.inc
+
+# suite/rpl/t/rpl_checksum.test contains similar testing of
+# all checksum related system variables.
+
+set @save_binlog_checksum= @@global.binlog_checksum;
+set @@global.binlog_checksum = default;
+
+select @@global.binlog_checksum as 'must be NONE by default';
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.binlog_checksum as 'no session var';
+
+
+# testing lack of side-effects in non-effective update of binlog_checksum:
+set @@global.binlog_checksum = CRC32;
+set @@global.binlog_checksum = CRC32;
+
+set @@global.master_verify_checksum = 0;
+set @@global.master_verify_checksum = default;
+
+--error ER_WRONG_VALUE_FOR_VAR
+set @@global.binlog_checksum = ADLER32;
+
+# cleanup
+set @@global.binlog_checksum = @save_binlog_checksum;
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/master_verify_checksum_basic.test b/mysql-test/suite/sys_vars/t/master_verify_checksum_basic.test
new file mode 100644
index 00000000000..b70040ff2a2
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/master_verify_checksum_basic.test
@@ -0,0 +1,19 @@
+--source include/not_embedded.inc
+
+# suite/rpl/t/rpl_checksum.test contains similar testing of
+# all checksum related system variables.
+
+set @save_master_verify_checksum = @@global.master_verify_checksum;
+
+select @@global.master_verify_checksum as 'must be zero because of default';
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.master_verify_checksum as 'no session var';
+
+set @@global.master_verify_checksum = 0;
+set @@global.master_verify_checksum = default;
+
+--error ER_WRONG_VALUE_FOR_VAR
+set @@global.master_verify_checksum = 2; # the var is of bool type
+
+# cleanup
+set @@global.master_verify_checksum = @save_master_verify_checksum;
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/slave_sql_verify_checksum_basic.test b/mysql-test/suite/sys_vars/t/slave_sql_verify_checksum_basic.test
new file mode 100644
index 00000000000..3eb4f4b4e6d
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/slave_sql_verify_checksum_basic.test
@@ -0,0 +1,18 @@
+--source include/not_embedded.inc
+
+# suite/rpl/t/rpl_checksum.test contains similar testing of
+# all checksum related system variables.
+
+set @save_slave_sql_verify_checksum = @@global.slave_sql_verify_checksum;
+
+select @@global.slave_sql_verify_checksum as 'must be one because of default';
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.slave_sql_verify_checksum as 'no session var';
+
+set @@global.slave_sql_verify_checksum = 0;
+set @@global.slave_sql_verify_checksum = default;
+--error ER_WRONG_VALUE_FOR_VAR
+set @@global.slave_sql_verify_checksum = 2; # the var is of bool type
+
+# cleanup
+set @@global.slave_sql_verify_checksum = @save_slave_sql_verify_checksum;
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/inc/vcol_select.inc b/mysql-test/suite/vcol/inc/vcol_select.inc
index 28c3416a55a..0641e14564a 100644
--- a/mysql-test/suite/vcol/inc/vcol_select.inc
+++ b/mysql-test/suite/vcol/inc/vcol_select.inc
@@ -84,10 +84,16 @@ eval $s;
eval explain $s;
--echo # select_type=DERIVED, type=system
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+
let $s = select * from (select a,b,c from t1) as t11;
eval $s;
eval explain $s;
+set optimizer_switch=@tmp_optimizer_switch;
+
--echo ###
--echo ### Using aggregate functions with/without DISTINCT
--echo ###
diff --git a/mysql-test/suite/vcol/inc/vcol_view.inc b/mysql-test/suite/vcol/inc/vcol_view.inc
index 2bf413e2471..abbeda60b75 100644
--- a/mysql-test/suite/vcol/inc/vcol_view.inc
+++ b/mysql-test/suite/vcol/inc/vcol_view.inc
@@ -69,10 +69,14 @@ create table t1 (a int not null,
insert into t1 (a) values (1), (2), (3), (4);
create view v1 as select b+1 from t1 order by 1 desc limit 2;
select * from v1;
+--echo MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
+--echo MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
explain select * from v1;
drop view v1;
create view v1 as select c+1 from t1 order by 1 desc limit 2;
select * from v1;
+--echo MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
+--echo MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
explain select * from v1;
drop view v1;
drop table t1;
@@ -102,6 +106,10 @@ drop view v1;
#
# outer join based on VIEW with WHERE clause
#
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
create table t1 (a int,
b int as (-a),
c int as (-a) persistent,
@@ -115,6 +123,8 @@ select t1.a, v1.x, v1.y, v1.z from t1 left join v1 on (t1.c= v1.z);
drop view v1;
drop table t1;
+SET optimizer_switch=@save_optimizer_switch;
+
#
# VIEW built over UNION
#
diff --git a/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result b/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result
index b1f96f8f4d9..db16d25000a 100644
--- a/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result
+++ b/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result
@@ -114,7 +114,7 @@ t1 CREATE TABLE `t1` (
describe t1;
Field Type Null Key Default Extra
a int(11) YES NULL
-b int(11) YES NULL VIRTUAL
+b int(11) YES NULL PERSISTENT
insert into t1 (a) values (1);
select * from t1;
a b
diff --git a/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result b/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result
index 9fde339cb06..1b4a5060e40 100644
--- a/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result
@@ -114,7 +114,7 @@ t1 CREATE TABLE `t1` (
describe t1;
Field Type Null Key Default Extra
a int(11) YES NULL
-b int(11) YES NULL VIRTUAL
+b int(11) YES NULL PERSISTENT
insert into t1 (a) values (1);
select * from t1;
a b
diff --git a/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result b/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result
index a2ebc7a8cd8..44fcae7a6e5 100644
--- a/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result
+++ b/mysql-test/suite/vcol/r/vcol_ins_upd_innodb.result
@@ -25,8 +25,8 @@ a b c
# INSERT INTO tbl_name VALUES... a non-NULL value is specified against vcols
insert into t1 values (1,2,3);
Warnings:
-Warning 1647 The value specified for computed column 'b' in table 't1' ignored
-Warning 1647 The value specified for computed column 'c' in table 't1' ignored
+Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+Warning 1906 The value specified for computed column 'c' in table 't1' ignored
select * from t1;
a b c
1 -1 -1
@@ -65,8 +65,8 @@ a b c
# against vcols
insert into t1 (a,b) values (1,3), (2,4);
Warnings:
-Warning 1647 The value specified for computed column 'b' in table 't1' ignored
-Warning 1647 The value specified for computed column 'b' in table 't1' ignored
+Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+Warning 1906 The value specified for computed column 'b' in table 't1' ignored
select * from t1;
a b c
1 -1 -1
@@ -107,8 +107,8 @@ a b c
create table t2 like t1;
insert into t2 select * from t1;
Warnings:
-Warning 1647 The value specified for computed column 'b' in table 't2' ignored
-Warning 1647 The value specified for computed column 'c' in table 't2' ignored
+Warning 1906 The value specified for computed column 'b' in table 't2' ignored
+Warning 1906 The value specified for computed column 'c' in table 't2' ignored
select * from t1;
a b c
2 -2 -2
@@ -123,8 +123,8 @@ a b c
create table t2 like t1;
insert into t2 (a,b) select a,b from t1;
Warnings:
-Warning 1647 The value specified for computed column 'b' in table 't2' ignored
-Warning 1647 The value specified for computed column 'b' in table 't2' ignored
+Warning 1906 The value specified for computed column 'b' in table 't2' ignored
+Warning 1906 The value specified for computed column 'b' in table 't2' ignored
select * from t2;
a b c
2 -2 -2
@@ -159,7 +159,7 @@ a b c
2 -2 -2
update t1 set c=3 where a=2;
Warnings:
-Warning 1647 The value specified for computed column 'c' in table 't1' ignored
+Warning 1906 The value specified for computed column 'c' in table 't1' ignored
select * from t1;
a b c
1 -1 -1
@@ -189,7 +189,7 @@ a b c
2 -2 -2
update t1 set c=3 where b=-2;
Warnings:
-Warning 1647 The value specified for computed column 'c' in table 't1' ignored
+Warning 1906 The value specified for computed column 'c' in table 't1' ignored
select * from t1;
a b c
1 -1 -1
diff --git a/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result b/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result
index 161a82171ce..66745862c22 100644
--- a/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_ins_upd_myisam.result
@@ -25,8 +25,8 @@ a b c
# INSERT INTO tbl_name VALUES... a non-NULL value is specified against vcols
insert into t1 values (1,2,3);
Warnings:
-Warning 1647 The value specified for computed column 'b' in table 't1' ignored
-Warning 1647 The value specified for computed column 'c' in table 't1' ignored
+Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+Warning 1906 The value specified for computed column 'c' in table 't1' ignored
select * from t1;
a b c
1 -1 -1
@@ -65,8 +65,8 @@ a b c
# against vcols
insert into t1 (a,b) values (1,3), (2,4);
Warnings:
-Warning 1647 The value specified for computed column 'b' in table 't1' ignored
-Warning 1647 The value specified for computed column 'b' in table 't1' ignored
+Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+Warning 1906 The value specified for computed column 'b' in table 't1' ignored
select * from t1;
a b c
1 -1 -1
@@ -107,8 +107,8 @@ a b c
create table t2 like t1;
insert into t2 select * from t1;
Warnings:
-Warning 1647 The value specified for computed column 'b' in table 't2' ignored
-Warning 1647 The value specified for computed column 'c' in table 't2' ignored
+Warning 1906 The value specified for computed column 'b' in table 't2' ignored
+Warning 1906 The value specified for computed column 'c' in table 't2' ignored
select * from t1;
a b c
2 -2 -2
@@ -123,8 +123,8 @@ a b c
create table t2 like t1;
insert into t2 (a,b) select a,b from t1;
Warnings:
-Warning 1647 The value specified for computed column 'b' in table 't2' ignored
-Warning 1647 The value specified for computed column 'b' in table 't2' ignored
+Warning 1906 The value specified for computed column 'b' in table 't2' ignored
+Warning 1906 The value specified for computed column 'b' in table 't2' ignored
select * from t2;
a b c
2 -2 -2
@@ -159,7 +159,7 @@ a b c
2 -2 -2
update t1 set c=3 where a=2;
Warnings:
-Warning 1647 The value specified for computed column 'c' in table 't1' ignored
+Warning 1906 The value specified for computed column 'c' in table 't1' ignored
select * from t1;
a b c
1 -1 -1
@@ -189,7 +189,7 @@ a b c
2 -2 -2
update t1 set c=3 where b=-2;
Warnings:
-Warning 1647 The value specified for computed column 'c' in table 't1' ignored
+Warning 1906 The value specified for computed column 'c' in table 't1' ignored
select * from t1;
a b c
1 -1 -1
diff --git a/mysql-test/suite/vcol/r/vcol_keys_innodb.result b/mysql-test/suite/vcol/r/vcol_keys_innodb.result
index 857dcb8423f..5070981f08f 100644
--- a/mysql-test/suite/vcol/r/vcol_keys_innodb.result
+++ b/mysql-test/suite/vcol/r/vcol_keys_innodb.result
@@ -19,7 +19,7 @@ t1 CREATE TABLE `t1` (
describe t1;
Field Type Null Key Default Extra
a int(11) YES NULL
-b int(11) YES UNI NULL VIRTUAL
+b int(11) YES UNI NULL PERSISTENT
drop table t1;
create table t1 (a int, b int as (a*2), unique key (b));
ERROR HY000: Key/Index cannot be defined on a non-stored computed column
@@ -34,7 +34,7 @@ t1 CREATE TABLE `t1` (
describe t1;
Field Type Null Key Default Extra
a int(11) YES NULL
-b int(11) YES UNI NULL VIRTUAL
+b int(11) YES UNI NULL PERSISTENT
drop table t1;
create table t1 (a int, b int as (a*2));
alter table t1 add unique key (b);
@@ -64,7 +64,7 @@ t1 CREATE TABLE `t1` (
describe t1;
Field Type Null Key Default Extra
a int(11) YES NULL
-b int(11) YES MUL NULL VIRTUAL
+b int(11) YES MUL NULL PERSISTENT
drop table t1;
create table t1 (a int, b int as (a*2) persistent, index (a,b));
show create table t1;
@@ -77,7 +77,7 @@ t1 CREATE TABLE `t1` (
describe t1;
Field Type Null Key Default Extra
a int(11) YES MUL NULL
-b int(11) YES NULL VIRTUAL
+b int(11) YES NULL PERSISTENT
drop table t1;
create table t1 (a int, b int as (a*2));
alter table t1 add index (b);
diff --git a/mysql-test/suite/vcol/r/vcol_keys_myisam.result b/mysql-test/suite/vcol/r/vcol_keys_myisam.result
index f7b47316ca8..86ba90130ff 100644
--- a/mysql-test/suite/vcol/r/vcol_keys_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_keys_myisam.result
@@ -19,7 +19,7 @@ t1 CREATE TABLE `t1` (
describe t1;
Field Type Null Key Default Extra
a int(11) YES NULL
-b int(11) YES UNI NULL VIRTUAL
+b int(11) YES UNI NULL PERSISTENT
drop table t1;
create table t1 (a int, b int as (a*2), unique key (b));
ERROR HY000: Key/Index cannot be defined on a non-stored computed column
@@ -34,7 +34,7 @@ t1 CREATE TABLE `t1` (
describe t1;
Field Type Null Key Default Extra
a int(11) YES NULL
-b int(11) YES UNI NULL VIRTUAL
+b int(11) YES UNI NULL PERSISTENT
drop table t1;
create table t1 (a int, b int as (a*2));
alter table t1 add unique key (b);
@@ -64,7 +64,7 @@ t1 CREATE TABLE `t1` (
describe t1;
Field Type Null Key Default Extra
a int(11) YES NULL
-b int(11) YES MUL NULL VIRTUAL
+b int(11) YES MUL NULL PERSISTENT
drop table t1;
create table t1 (a int, b int as (a*2) persistent, index (a,b));
show create table t1;
@@ -77,7 +77,7 @@ t1 CREATE TABLE `t1` (
describe t1;
Field Type Null Key Default Extra
a int(11) YES MUL NULL
-b int(11) YES NULL VIRTUAL
+b int(11) YES NULL PERSISTENT
drop table t1;
create table t1 (a int, b int as (a*2));
alter table t1 add index (b);
diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result
index 4c301795f5c..14467b2d630 100644
--- a/mysql-test/suite/vcol/r/vcol_misc.result
+++ b/mysql-test/suite/vcol/r/vcol_misc.result
@@ -108,10 +108,10 @@ DROP TABLE t1,t2;
CREATE TABLE t1 (p int, a double NOT NULL, v double AS (ROUND(a,p)) VIRTUAL);
INSERT INTO t1 VALUES (0,1,0);
Warnings:
-Warning 1647 The value specified for computed column 'v' in table 't1' ignored
+Warning 1906 The value specified for computed column 'v' in table 't1' ignored
INSERT INTO t1 VALUES (NULL,0,0);
Warnings:
-Warning 1647 The value specified for computed column 'v' in table 't1' ignored
+Warning 1906 The value specified for computed column 'v' in table 't1' ignored
SELECT a, p, v, ROUND(a,p), ROUND(a,p+NULL) FROM t1;
a p v ROUND(a,p) ROUND(a,p+NULL)
1 0 1 1 NULL
@@ -193,3 +193,115 @@ SELECT COUNT(*) FROM t1;
COUNT(*)
2
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);
+insert into t2(c,d) values
+(120, 100), (150, 300), (130, 100), (130, 200), (140, 500),
+(170, 100), (180, 300), (160, 100), (40, 100), (170, 100);
+set join_cache_level=6;
+explain
+select * from t1,t2 where t1.b=t2.c and d <= 100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+1 SIMPLE t2 ref idx idx 5 test.t1.b 2 Using where
+select * from t1,t2 where t1.b=t2.c and d <= 100;
+a b c d v
+3 30 30 100 101
+4 20 20 100 101
+1 20 20 100 101
+set join_cache_level=default;
+drop table t1, t2;
+create table t1 (a bigint, b bigint as (a > '2'));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) DEFAULT NULL,
+ `b` bigint(20) AS (a > '2') VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 (a) values (1),(3);
+select * from t1;
+a b
+1 0
+3 1
+select * from t1;
+a b
+1 0
+3 1
+drop table t1;
+create table t1 (a bigint, b bigint as (a between 0 and 2));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) DEFAULT NULL,
+ `b` bigint(20) AS (a between 0 and 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 (a) values (1),(3);
+select * from t1;
+a b
+1 1
+3 0
+select * from t1;
+a b
+1 1
+3 0
+drop table t1;
+create table t1 (a char(10), b char(10) as (a between 0 and 2));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(10) DEFAULT NULL,
+ `b` char(10) AS (a between 0 and 2) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 (a) values (1),(3);
+select * from t1;
+a b
+1 1
+3 0
+select * from t1;
+a b
+1 1
+3 0
+drop table t1;
+CREATE TABLE `t1` (
+`a` int(11) NOT NULL,
+`b` varchar(32) DEFAULT NULL,
+`c` int(11) AS (a MOD 10) VIRTUAL,
+`d` varchar(5) AS (LEFT(b,5)) PERSISTENT
+) ENGINE=MyISAM;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `b` varchar(32) DEFAULT NULL,
+ `c` int(11) AS (a MOD 10) VIRTUAL,
+ `d` varchar(5) AS (LEFT(b,5)) PERSISTENT
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+show columns from t1;
+Field Type Null Key Default Extra
+a int(11) NO NULL
+b varchar(32) YES NULL
+c int(11) YES NULL VIRTUAL
+d varchar(5) YES NULL PERSISTENT
+show full columns from t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+a int(11) NULL NO NULL #
+b varchar(32) latin1_swedish_ci YES NULL #
+c int(11) NULL YES NULL VIRTUAL #
+d varchar(5) latin1_swedish_ci YES NULL PERSISTENT #
+INSERT INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,NULL);
+UPDATE `test`.`t1` SET `d`='b' WHERE `a`='1' AND `b`='a' AND `c`='1' AND `d`='a';
+Warnings:
+Warning 1906 The value specified for computed column 'd' in table 't1' ignored
+INSERT INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,'a');
+Warnings:
+Warning 1906 The value specified for computed column 'd' in table 't1' ignored
+set sql_mode='strict_all_tables';
+UPDATE `test`.`t1` SET `d`='b' WHERE `a`='1' AND `b`='a' AND `c`='1' AND `d`='a';
+ERROR HY000: The value specified for computed column 'd' in table 't1' ignored
+INSERT INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,'a');
+ERROR HY000: The value specified for computed column 'd' in table 't1' ignored
+drop table t1;
diff --git a/mysql-test/suite/vcol/r/vcol_select_innodb.result b/mysql-test/suite/vcol/r/vcol_select_innodb.result
index 0612d5a06b3..14cf325feb1 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
# 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 ALL c NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
# select_type=UNION, type=system
# select_type=UNION RESULT, type=<union1,2>
select * from t1 union select * from t2;
@@ -89,6 +89,8 @@ id select_type table type possible_keys key key_len ref rows Extra
2 UNION t2 ALL NULL NULL NULL NULL 1
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
# select_type=DERIVED, type=system
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
select * from (select a,b,c from t1) as t11;
a b c
2 -2 -2
@@ -100,6 +102,7 @@ explain select * from (select a,b,c from t1) as t11;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5
2 DERIVED t1 ALL NULL NULL NULL NULL 5
+set optimizer_switch=@tmp_optimizer_switch;
###
### Using aggregate functions with/without DISTINCT
###
@@ -141,7 +144,7 @@ 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
# SELECT * FROM tbl_name WHERE <non-vcol expr>
select * from t3 where a between 1 and 2;
a b c
@@ -165,7 +168,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 2 Using where
+1 SIMPLE t3 range c c 5 NULL 2 Using index condition
# 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 +208,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 2 Using where; Using filesort
+1 SIMPLE t3 range c c 5 NULL 2 Using index condition; 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 +224,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 2 Using where
+1 SIMPLE t3 range c c 5 NULL 2 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 04ae7e0f7cd..ea3cbd3bc11 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
# 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;
@@ -89,6 +89,8 @@ id select_type table type possible_keys key key_len ref rows Extra
2 UNION t2 system NULL NULL NULL NULL 1
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
# select_type=DERIVED, type=system
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
select * from (select a,b,c from t1) as t11;
a b c
2 -2 -2
@@ -100,6 +102,7 @@ explain select * from (select a,b,c from t1) as t11;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5
2 DERIVED t1 ALL NULL NULL NULL NULL 5
+set optimizer_switch=@tmp_optimizer_switch;
###
### Using aggregate functions with/without DISTINCT
###
@@ -141,7 +144,7 @@ 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
# SELECT * FROM tbl_name WHERE <non-vcol expr>
select * from t3 where a between 1 and 2;
a b c
@@ -149,7 +152,7 @@ a b c
2 -2 -2
explain select * from t3 where a between 1 and 2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 1 Using where
+1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 1 Using index condition
# SELECT * FROM tbl_name WHERE <non-indexed vcol expr>
select * from t3 where b between -2 and -1;
a b c
@@ -165,7 +168,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
# 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 +176,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 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 +192,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 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 +208,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 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 +224,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)
@@ -270,14 +273,14 @@ INSERT INTO t1 VALUES (NULL),( 78), (185), (0), (154);
CREATE TABLE t2 (a int, b int AS (a) VIRTUAL);
INSERT INTO t2 VALUES (187,187), (9,9), (187,187);
Warnings:
-Warning 1647 The value specified for computed column 'b' in table 't2' ignored
-Warning 1647 The value specified for computed column 'b' in table 't2' ignored
-Warning 1647 The value specified for computed column 'b' in table 't2' ignored
+Warning 1906 The value specified for computed column 'b' in table 't2' ignored
+Warning 1906 The value specified for computed column 'b' in table 't2' ignored
+Warning 1906 The value specified for computed column 'b' in table 't2' ignored
EXPLAIN EXTENDED
SELECT * FROM t1 JOIN t2 USING (b);
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 t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`b` = `test`.`t2`.`b`)
SELECT * FROM t1 JOIN t2 USING (b);
@@ -286,7 +289,7 @@ EXPLAIN EXTENDED
SELECT * FROM t1 NATURAL JOIN t2;
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 t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`b` = `test`.`t2`.`b`)
SELECT * FROM t1 NATURAL JOIN t2;
diff --git a/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_innodb.result b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_innodb.result
index 83f755a2e7f..5983d5e96c1 100644
--- a/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_innodb.result
+++ b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_innodb.result
@@ -2251,7 +2251,7 @@ t1 CREATE TABLE `t1` (
insert into t1 values ('2003-02-05',default);
insert into t1 values ('2003-02-32',default);
Warnings:
-Warning 1264 Out of range value for column 'a' at row 1
+Warning 1265 Data truncated for column 'a' at row 1
select * from t1;
a b
2003-02-05 00:00:00 2003-02-28 00:00:00
@@ -2686,10 +2686,15 @@ t1 CREATE TABLE `t1` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1
insert into t1 values (1,default);
insert into t1 values (-1,default);
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select * from t1;
a b
1 1
-1 18446744073709551615
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
drop table t1;
set sql_warnings = 0;
# Convert()
@@ -2703,10 +2708,15 @@ t1 CREATE TABLE `t1` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1
insert into t1 values (1,default);
insert into t1 values (-1,default);
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select * from t1;
a b
1 1
-1 18446744073709551615
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
drop table t1;
set sql_warnings = 0;
#
diff --git a/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_myisam.result b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_myisam.result
index 844aae38af2..fa84fb046b3 100644
--- a/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs_myisam.result
@@ -2251,7 +2251,7 @@ t1 CREATE TABLE `t1` (
insert into t1 values ('2003-02-05',default);
insert into t1 values ('2003-02-32',default);
Warnings:
-Warning 1264 Out of range value for column 'a' at row 1
+Warning 1265 Data truncated for column 'a' at row 1
select * from t1;
a b
2003-02-05 00:00:00 2003-02-28 00:00:00
@@ -2686,10 +2686,15 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values (1,default);
insert into t1 values (-1,default);
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select * from t1;
a b
1 1
-1 18446744073709551615
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
drop table t1;
set sql_warnings = 0;
# Convert()
@@ -2703,10 +2708,15 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values (1,default);
insert into t1 values (-1,default);
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select * from t1;
a b
1 1
-1 18446744073709551615
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
drop table t1;
set sql_warnings = 0;
#
diff --git a/mysql-test/suite/vcol/r/vcol_view_innodb.result b/mysql-test/suite/vcol/r/vcol_view_innodb.result
index ae834722606..d117b030f94 100644
--- a/mysql-test/suite/vcol/r/vcol_view_innodb.result
+++ b/mysql-test/suite/vcol/r/vcol_view_innodb.result
@@ -63,7 +63,7 @@ b
-3
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
select * from t1;
a b c
@@ -82,7 +82,7 @@ c
-3
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
select * from t1;
a b c
@@ -103,6 +103,8 @@ select * from v1;
b+1
0
-1
+MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
+MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
@@ -113,6 +115,8 @@ select * from v1;
c+1
0
-1
+MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
+MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
@@ -150,6 +154,8 @@ insert into v1 (a,e) values (60,15);
ERROR HY000: The target table v1 of the INSERT is not insertable-into
drop table t1;
drop view v1;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
create table t1 (a int,
b int as (-a),
c int as (-a) persistent,
@@ -170,6 +176,7 @@ a x y z
3 3 -3 -3
drop view v1;
drop table t1;
+SET optimizer_switch=@save_optimizer_switch;
create table t1 (a1 int,
b1 int as (-a1),
c1 int as (-a1) persistent);
diff --git a/mysql-test/suite/vcol/r/vcol_view_myisam.result b/mysql-test/suite/vcol/r/vcol_view_myisam.result
index bd5999792ff..fe48be4c794 100644
--- a/mysql-test/suite/vcol/r/vcol_view_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_view_myisam.result
@@ -63,7 +63,7 @@ b
-3
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
select * from t1;
a b c
@@ -82,7 +82,7 @@ c
-3
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
select * from t1;
a b c
@@ -103,6 +103,8 @@ select * from v1;
b+1
0
-1
+MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
+MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
@@ -113,6 +115,8 @@ select * from v1;
c+1
0
-1
+MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
+MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
@@ -150,6 +154,8 @@ insert into v1 (a,e) values (60,15);
ERROR HY000: The target table v1 of the INSERT is not insertable-into
drop table t1;
drop view v1;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
create table t1 (a int,
b int as (-a),
c int as (-a) persistent,
@@ -170,6 +176,7 @@ a x y z
3 3 -3 -3
drop view v1;
drop table t1;
+SET optimizer_switch=@save_optimizer_switch;
create table t1 (a1 int,
b1 int as (-a1),
c1 int as (-a1) persistent);
diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test
index 0a689795b4c..3c51ee4b685 100644
--- a/mysql-test/suite/vcol/t/vcol_misc.test
+++ b/mysql-test/suite/vcol/t/vcol_misc.test
@@ -155,7 +155,6 @@ SELECT table_schema, table_name, column_name, column_type, extra
DROP TABLE t1,t2;
-
#
# Bug mdev-354: virtual columns of ENUM and SET types
#
@@ -198,3 +197,71 @@ SELECT COUNT(*) FROM 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);
+insert into t2(c,d) values
+ (120, 100), (150, 300), (130, 100), (130, 200), (140, 500),
+ (170, 100), (180, 300), (160, 100), (40, 100), (170, 100);
+
+set join_cache_level=6;
+explain
+select * from t1,t2 where t1.b=t2.c and d <= 100;
+
+select * from t1,t2 where t1.b=t2.c and d <= 100;
+set join_cache_level=default;
+
+drop table t1, t2;
+
+#
+# Test crashes when using convert_const_item()
+#
+create table t1 (a bigint, b bigint as (a > '2'));
+show create table t1;
+insert into t1 (a) values (1),(3);
+select * from t1;
+select * from t1;
+drop table t1;
+create table t1 (a bigint, b bigint as (a between 0 and 2));
+show create table t1;
+insert into t1 (a) values (1),(3);
+select * from t1;
+select * from t1;
+drop table t1;
+create table t1 (a char(10), b char(10) as (a between 0 and 2));
+show create table t1;
+insert into t1 (a) values (1),(3);
+select * from t1;
+select * from t1;
+drop table t1;
+
+#
+# Test output of show columns
+#
+
+CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `b` varchar(32) DEFAULT NULL,
+ `c` int(11) AS (a MOD 10) VIRTUAL,
+ `d` varchar(5) AS (LEFT(b,5)) PERSISTENT
+) ENGINE=MyISAM;
+show create table t1;
+show columns from t1;
+--replace_column 8 #
+show full columns from t1;
+INSERT INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,NULL);
+UPDATE `test`.`t1` SET `d`='b' WHERE `a`='1' AND `b`='a' AND `c`='1' AND `d`='a';
+INSERT INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,'a');
+set sql_mode='strict_all_tables';
+--error ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN
+UPDATE `test`.`t1` SET `d`='b' WHERE `a`='1' AND `b`='a' AND `c`='1' AND `d`='a';
+--error ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN
+INSERT INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,'a');
+drop table t1;
diff --git a/mysql-test/t/adddate_454.test b/mysql-test/t/adddate_454.test
new file mode 100644
index 00000000000..1d69cdc9558
--- /dev/null
+++ b/mysql-test/t/adddate_454.test
@@ -0,0 +1,9 @@
+#
+# MDEV-454 Addition of a time interval reduces the resulting value
+#
+create table t1 (d date);
+insert into t1 values ('2012-00-00');
+select * from t1;
+update t1 set d = adddate(d, interval 1 day);
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/alter_table_online.test b/mysql-test/t/alter_table_online.test
new file mode 100644
index 00000000000..19096efe0fa
--- /dev/null
+++ b/mysql-test/t/alter_table_online.test
@@ -0,0 +1,108 @@
+#
+# Test of alter online table
+#
+
+--source include/have_innodb.inc
+--disable_warnings
+drop table if exists t1,t2,t3;
+--enable_warnings
+#
+# Test of things that can be done online
+#
+
+create table t1 (a int not null primary key, b int, c varchar(80), e enum('a','b'));
+insert into t1 (a) values (1),(2),(3);
+
+alter online table t1 modify b int default 5;
+alter online table t1 change b new_name int;
+alter online table t1 modify e enum('a','b','c');
+alter online table t1 comment "new comment";
+alter online table t1 rename to t2;
+alter online table t2 rename to t1;
+
+drop table t1;
+
+#
+# temporary tables always require a copy
+#
+
+create temporary table t1 (a int not null primary key, b int, c varchar(80), e enum('a','b'));
+insert into t1 (a) values (1),(2),(3);
+
+--error ER_CANT_DO_ONLINE
+alter online table t1 modify b int default 5;
+--error ER_CANT_DO_ONLINE
+alter online table t1 change b new_name int;
+--error ER_CANT_DO_ONLINE
+alter online table t1 modify e enum('a','b','c');
+--error ER_CANT_DO_ONLINE
+alter online table t1 comment "new comment";
+--error ER_CANT_DO_ONLINE
+alter online table t1 rename to t2;
+
+drop table t1;
+
+#
+# Test of things that is not possible to do online
+#
+
+create table t1 (a int not null primary key, b int, c varchar(80), e enum('a','b'));
+insert into t1 (a) values (1),(2),(3);
+
+--error ER_CANT_DO_ONLINE
+alter online table t1 drop column b, add b int;
+--error ER_CANT_DO_ONLINE
+alter online table t1 modify b bigint;
+--error ER_CANT_DO_ONLINE
+alter online table t1 modify e enum('c','a','b');
+--error ER_CANT_DO_ONLINE
+alter online table t1 modify c varchar(50);
+--error ER_CANT_DO_ONLINE
+alter online table t1 modify c varchar(100);
+--error ER_CANT_DO_ONLINE
+alter online table t1 add f int;
+--error ER_CANT_DO_ONLINE
+alter online table t1 engine=memory;
+
+alter table t1 engine=innodb;
+alter table t1 add index (b);
+--error ER_CANT_DO_ONLINE
+alter online table t1 add index c (c);
+--error ER_CANT_DO_ONLINE
+alter online table t1 drop index b;
+drop table t1;
+
+create temporary table t1 (a int not null primary key, b int, c varchar(80), e enum('a','b'));
+insert into t1 (a) values (1),(2),(3);
+
+--error ER_CANT_DO_ONLINE
+alter online table t1 drop column b, add b int;
+--error ER_CANT_DO_ONLINE
+alter online table t1 modify b bigint;
+--error ER_CANT_DO_ONLINE
+alter online table t1 modify e enum('c','a','b');
+--error ER_CANT_DO_ONLINE
+alter online table t1 modify c varchar(50);
+--error ER_CANT_DO_ONLINE
+alter online table t1 modify c varchar(100);
+--error ER_CANT_DO_ONLINE
+alter online table t1 add f int;
+--error ER_CANT_DO_ONLINE
+alter online table t1 engine=memory;
+
+alter table t1 engine=innodb;
+alter table t1 add index (b);
+--error ER_CANT_DO_ONLINE
+alter online table t1 add index c (c);
+--error ER_CANT_DO_ONLINE
+alter online table t1 drop index b;
+drop table t1;
+
+#
+# Test merge tables
+#
+create table t1 (a int not null primary key, b int, c varchar(80));
+create table t2 (a int not null primary key, b int, c varchar(80));
+create table t3 (a int not null primary key, b int, c varchar(80)) engine=merge UNION=(t1);
+alter online table t3 union=(t1,t2);
+drop table t1,t2,t3;
diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test
index 6f788fc3cc6..0f274b6225d 100644
--- a/mysql-test/t/archive.test
+++ b/mysql-test/t/archive.test
@@ -1727,3 +1727,14 @@ CHECKSUM TABLE t1 EXTENDED;
FLUSH TABLE t1;
OPTIMIZE TABLE t1;
DROP TABLE t1;
+
+--echo #
+--echo # BUG#917689 Using wrong archive table causes crash
+--echo #
+create table t1 (a int, b char(50)) engine=archive;
+--remove_file $MYSQLD_DATADIR/test/t1.ARZ
+copy_file std_data/t917689.ARZ $MYSQLD_DATADIR/test/t1.ARZ;
+--error 1194
+select * from t1;
+show warnings;
+drop table t1;
diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test
index 81855dfc97f..cb197aba89f 100644
--- a/mysql-test/t/case.test
+++ b/mysql-test/t/case.test
@@ -172,7 +172,7 @@ drop table t1, t2;
--echo End of 5.0 tests
#
-# LP BUG#1001510
+# lp:1001510
# Bug #11764313 57135: CRASH IN ITEM_FUNC_CASE::FIND_ITEM WITH CASE WHEN
# ELSE CLAUSE
#
@@ -180,3 +180,13 @@ drop table t1, t2;
CREATE TABLE t1(a YEAR);
SELECT 1 FROM t1 WHERE a=1 AND CASE 1 WHEN a THEN 1 ELSE 1 END;
DROP TABLE t1;
+
+#
+# lp:839387 Assertion `(Item_result)i != TIME_RESULT' failed with CASE + datetime
+#
+
+create table t1 (f1 time);
+insert t1 values ('00:00:00'),('00:01:00');
+select case t1.f1 when '00:00:00' then 1 end from t1;
+drop table t1;
+
diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test
index 4474736200c..b3bda315673 100644
--- a/mysql-test/t/cast.test
+++ b/mysql-test/t/cast.test
@@ -9,14 +9,60 @@ select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
select ~5, cast(~5 as signed);
explain extended select ~5, cast(~5 as signed);
+select cast(18446744073709551615 as signed);
select cast(5 as unsigned) -6.0;
select cast(NULL as signed), cast(1/0 as signed);
+select cast(1 as double(5,2));
+select cast("5.2222" as double(5,2));
+select cast(12.444 as double(5,2));
+select cast(cast(12.444 as decimal(10,3)) as double(5,2));
+select cast(null as double(5,2));
+select cast(12.444 as double);
+select cast(cast("20:01:01" as time) as datetime);
+select cast(cast("8:46:06.23434" AS time) as decimal(32,10));
+select cast(cast("2011-04-05 8:46:06.23434" AS datetime) as decimal(32,6));
+
+--echo #
+--echo # Check handling of cast with microseconds
+--echo #
+select cast(cast(20010203101112.121314 as double) as datetime);
+select cast(cast(010203101112.12 as double) as datetime);
+select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime);
+select cast(20010203101112.121314 as datetime);
+select cast(110203101112.121314 as datetime);
+select cast(cast(010203101112.12 as double) as datetime);
+
+select cast("2011-02-03 10:11:12.123456" as datetime);
+select cast("2011-02-03 10:11:12.123456" as datetime(0));
+select cast("2011-02-03 10:11:12.123456" as datetime(5));
+select cast("2011-02-03 10:11:12.123456" as datetime(6));
+select cast("2011-02-03 10:11:12" as datetime(6));
+select cast(cast(20010203101112.5 as double) as datetime(1));
+select cast(cast(010203101112.12 as double) as datetime(2));
+select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime(6));
+select cast(20010203101112.121314 as datetime(6));
+select cast(110203101112.121314 as datetime(6));
+select cast(cast(010203101112.12 as double) as datetime(6));
+
+select cast("2011-02-03 10:11:12.123456" as time);
+select cast("2011-02-03 10:11:12.123456" as time(6));
+select cast("10:11:12.123456" as time);
+select cast("10:11:12.123456" as time(0));
+select cast("10:11:12.123456" as time(5));
+select cast("10:11:12.123456" as time(6));
+select cast("10:11:12" as time(6));
+select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time);
+select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time(6));
+select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time);
+select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time(6));
+
#
# Bug #28250: Run-Time Check Failure #3 - The variable 'value' is being used
# without being def
#
# The following line causes Run-Time Check Failure on
# binaries built with Visual C++ 2005
+#
select cast(NULL as unsigned), cast(1/0 as unsigned);
select cast("A" as binary) = "a", cast(BINARY "a" as CHAR) = "A";
select cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME);
@@ -42,6 +88,44 @@ select cast('a10' as unsigned integer);
select 10+'a';
select 10.0+cast('a' as decimal);
select 10E+0+'a';
+select cast("a" as double(5,2));
+select cast(1000 as decimal(5,2));
+select cast(-1000 as decimal(5,2));
+select cast(1000 as double(5,2));
+select cast(-1000 as double(5,2));
+select cast(010203101112.121314 as datetime);
+select cast(120010203101112.121314 as datetime);
+select cast(cast(1.1 as decimal) as datetime);
+select cast(cast(-1.1 as decimal) as datetime);
+select cast('0' as date);
+select cast('' as date);
+select cast('0' as datetime);
+select cast('' as datetime);
+select cast('0' as time);
+select cast('' as time);
+select cast(NULL as DATE);
+select cast(NULL as DATETIME);
+select cast(NULL as TIME);
+select cast(NULL as BINARY);
+
+#
+# We have to disable warnings for these as the printed double value is
+# not portable
+#
+--disable_warnings
+select cast(cast(120010203101112.121314 as double) as datetime);
+select cast(cast(1.1 as double) as datetime);
+select cast(cast(-1.1 as double) as datetime);
+--enable_warnings
+
+
+#
+# Some EXPLAIN EXTENDED to ensure the print functions are correct
+#
+
+explain extended select cast(10 as double(5,2));
+explain extended select cast(10 as double);
+explain extended select cast(10 as decimal(5,2));
# out-of-range cases
select cast('18446744073709551616' as unsigned);
@@ -52,6 +136,20 @@ select cast('abc' as signed);
select cast('1a' as signed);
select cast('' as signed);
+--error ER_M_BIGGER_THAN_D
+select cast(1 as double(5,6));
+--error ER_M_BIGGER_THAN_D
+select cast(1 as decimal(5,6));
+--error ER_TOO_BIG_PRECISION
+select cast(1 as double(66,6));
+--error ER_TOO_BIG_PRECISION
+select cast(1 as decimal(66,6));
+--error ER_TOO_BIG_SCALE
+select cast(1 as decimal(64,63));
+--error ER_TOO_BIG_SCALE
+select cast(1 as double(64,63));
+
+
#
# Character set conversion
#
@@ -124,8 +222,6 @@ set names binary;
select cast("2001-1-1" as date) = "2001-01-01";
select cast("2001-1-1" as datetime) = "2001-01-01 00:00:00";
select cast("1:2:3" as TIME) = "1:02:03";
-select cast(NULL as DATE);
-select cast(NULL as BINARY);
#
# Bug #5228 ORDER BY CAST(enumcol) sorts incorrectly under certain conditions
@@ -172,6 +268,14 @@ select cast(repeat('1',20) as signed);
select cast(1.0e+300 as signed int);
#
+# Test that we create the correct types with create ... select cast()
+#
+
+create table t1 select cast(1 as unsigned), cast(1 as signed), cast(1 as double(5,2)), cast(1 as decimal(5,3)), cast("A" as binary), cast("A" as char(100)), cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME), cast("1:2:3" as TIME);
+show create table t1;
+drop table t1;
+
+#
# Bugs: #15098: CAST(column double TO signed int), wrong result
#
CREATE TABLE t1 (f1 double);
@@ -292,6 +396,7 @@ SET @@GLOBAL.max_allowed_packet=2048;
SELECT CONVERT('a', BINARY(2049));
SELECT CONVERT('a', CHAR(2049));
+SELECT length(CONVERT(repeat('a',2048), CHAR(2049)));
connection default;
disconnect newconn;
@@ -310,3 +415,27 @@ WHERE CAST(a as BINARY)=x'62736D697468'
DROP TABLE t1;
--echo End of 5.1 tests
+
+select cast("2101-00-01 02:03:04" as datetime);
+select cast(cast("2101-00-01 02:03:04" as datetime) as time);
+SELECT CAST(CAST('20:05:05' AS TIME) as date);
+set sql_mode= TRADITIONAL;
+select cast("2101-00-01 02:03:04" as datetime);
+select cast(cast("2101-00-01 02:03:04" as datetime) as time);
+SELECT CAST(CAST('20:05:05' AS TIME) as date);
+set sql_mode=DEFAULT;
+
+#
+# lp:737458 Casting dates and times into integers works differently
+# in 5.1-micro
+#
+create table t1 (f1 time, f2 date, f3 datetime);
+insert into t1 values ('11:22:33','2011-12-13','2011-12-13 11:22:33');
+select cast(f1 as unsigned), cast(f2 as unsigned), cast(f3 as unsigned) from t1;
+drop table t1;
+
+#
+# CAST(... AS DATE) and invalid dates
+#
+SELECT CAST(TIME('10:20:30') AS DATE) + INTERVAL 1 DAY;
+
diff --git a/mysql-test/t/comments.test b/mysql-test/t/comments.test
index 3a18a8bd483..08c74c99d0c 100644
--- a/mysql-test/t/comments.test
+++ b/mysql-test/t/comments.test
@@ -21,6 +21,17 @@ select 1 # The rest of the row will be ignored
# End of 4.1 tests
#
+# Testing of MariaDB executable comments
+#
+
+select 1 /*M! +1 */;
+select 1 /*M!50000 +1 */;
+select 1 /*M!50300 +1 */;
+select 2 /*M!99999 +1 */;
+--error ER_PARSE_ERROR
+select 2 /*M!0000 +1 */;
+
+#
# Bug#25411 (trigger code truncated)
#
diff --git a/mysql-test/t/ctype_cp1251.test b/mysql-test/t/ctype_cp1251.test
index bde72d04ba7..dfe97cb28f3 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/ctype_cp932_binlog_stm.test b/mysql-test/t/ctype_cp932_binlog_stm.test
index 95252a95368..07eee7709d1 100644
--- a/mysql-test/t/ctype_cp932_binlog_stm.test
+++ b/mysql-test/t/ctype_cp932_binlog_stm.test
@@ -33,10 +33,10 @@ delimiter ;|
# Note: 364 is a magic position (found experimentally, depends on
# the log's contents) that caused the server crash.
-call mtr.add_suppression("Error in Log_event::read_log_event\\\(\\\): 'Sanity check failed', data_len: 258, event_type: 49");
+call mtr.add_suppression("Error in Log_event::read_log_event\\\(\\\): 'Found invalid");
--error 1220
-SHOW BINLOG EVENTS FROM 365;
+SHOW BINLOG EVENTS FROM 504;
--echo Bug#44352 UPPER/LOWER function doesn't work correctly on cp932 and sjis environment.
CREATE TABLE t1 (a varchar(16)) character set cp932;
diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test
index 1f55aea414a..ee07ef24def 100644
--- a/mysql-test/t/ctype_recoding.test
+++ b/mysql-test/t/ctype_recoding.test
@@ -210,3 +210,21 @@ drop table t1;
create table t1(a char character set latin1 default _cp1251 0xFF);
--echo End of 4.1 tests
+
+SET CHARACTER SET DEFAULT;
+--echo #
+--echo # LP BUG#944504 Item_func_conv_charset tries to execute subquery constant
+--echo #
+SET optimizer_switch = 'in_to_exists=on';
+SET character_set_connection = utf8;
+CREATE TABLE t1 ( a VARCHAR(1) );
+INSERT INTO t1 VALUES ('m'),('n');
+CREATE VIEW v1 AS SELECT 'w' ;
+--error ER_CANT_AGGREGATE_2COLLATIONS
+SELECT * FROM t1 WHERE a < ALL ( SELECT * FROM v1 );
+drop view v1;
+drop table t1;
+SET character_set_connection = default;
+SET optimizer_switch= default;
+
+--echo #End of 5.3 tests
diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test
index 2a5de8ca9ba..55e08e420b1 100644
--- a/mysql-test/t/date_formats.test
+++ b/mysql-test/t/date_formats.test
@@ -128,12 +128,9 @@ SET datetime_format=default;
# Test of str_to_date
#
-# PS doesn't support fractions of a second
---disable_ps_protocol
select str_to_date(concat('15-01-2001',' 2:59:58.999'),
concat('%d-%m-%Y',' ','%H:%i:%s.%f'));
select STR_TO_DATE('2004.12.12 22.30.61','%Y.%m.%d %T');
---enable_ps_protocol
create table t1 (date char(30), format char(30) not null);
insert into t1 values
@@ -169,8 +166,6 @@ insert into t1 values
('15-01-20', '%d-%m-%y'),
('15-2001-1', '%d-%Y-%c');
-# PS doesn't support fractional seconds
---disable_ps_protocol
select date,format,str_to_date(date, format) as str_to_date from t1;
# Use as a string
select date,format,concat('',str_to_date(date, format)) as con from t1;
@@ -217,7 +212,6 @@ select date,format,str_to_date(date, format) as str_to_date from t1;
select date,format,concat(str_to_date(date, format),'') as con from t1;
drop table t1;
---enable_ps_protocol
#
# Test of get_format
diff --git a/mysql-test/t/datetime_456.test b/mysql-test/t/datetime_456.test
new file mode 100644
index 00000000000..0c187959d52
--- /dev/null
+++ b/mysql-test/t/datetime_456.test
@@ -0,0 +1,8 @@
+#
+# MDEV-456 An out-of-range datetime value (with a 5-digit year) can be created and cause troubles
+#
+create table t1 (d datetime);
+insert t1 values (addtime('9999-12-31 23:59:59', '00:00:01')),
+ (from_days(3652499));
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test
index 962cec95add..7defc55b473 100644
--- a/mysql-test/t/derived.test
+++ b/mysql-test/t/derived.test
@@ -3,6 +3,9 @@
drop table if exists t1,t2,t3;
--enable_warnings
+set @save_derived_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+
select * from (select 2 from DUAL) b;
-- error 1054
SELECT 1 as a FROM (SELECT 1 UNION SELECT a) b;
@@ -106,6 +109,7 @@ create user mysqltest_1;
create table t1 select 1 as a;
connect (con1,localhost,mysqltest_1,,*NO-ONE*,$MASTER_MYPORT,$MASTER_MYSOCK);
connection con1;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
--error 1046
select 2 as a from (select * from t1) b;
use test;
@@ -315,3 +319,5 @@ WHERE j = SUBSTRING('12', (SELECT * FROM (SELECT MIN(j) FROM t1) t2))) t3;
DROP TABLE t1;
--echo # End of 5.0 tests
+
+set optimizer_switch=@save_derived_optimizer_switch;
diff --git a/mysql-test/t/derived_opt.test b/mysql-test/t/derived_opt.test
new file mode 100644
index 00000000000..b01c479111b
--- /dev/null
+++ b/mysql-test/t/derived_opt.test
@@ -0,0 +1,276 @@
+# Initialize
+--disable_warnings
+drop table if exists t1,t2,t3;
+--enable_warnings
+
+set @exit_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+# The 'default' value within the scope of this test:
+set @save_optimizer_switch=@@optimizer_switch;
+
+CREATE TABLE t1 (a int not null, b char (10) not null);
+insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
+CREATE TABLE t2 (a int not null, b char (10) not null);
+insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e');
+CREATE TABLE t3 (a int not null, b char (10) not null);
+insert into t3 values (3,'f'),(4,'y'),(5,'z'),(6,'c');
+select * from t1 as x1, (select * from t1) as x2;
+explain select * from t1 as x1, (select * from t1) as x2;
+drop table if exists t2,t3;
+
+CREATE TABLE t2 (a int not null);
+insert into t2 values(1);
+select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
+explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
+drop table t1, t2;
+
+create table t1(a int not null, t char(8), index(a));
+--disable_query_log
+begin;
+let $1 = 10000;
+while ($1)
+ {
+ eval insert into t1 values ($1,'$1');
+ dec $1;
+ }
+commit;
+--enable_query_log
+SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20;
+explain select count(*) from t1 as tt1, (select * from t1) as tt2;
+drop table t1;
+
+#
+# test->used_keys test for derived tables
+#
+create table t1 (mat_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, matintnum CHAR(6) NOT NULL, test MEDIUMINT UNSIGNED NULL);
+create table t2 (mat_id MEDIUMINT UNSIGNED NOT NULL, pla_id MEDIUMINT UNSIGNED NOT NULL);
+insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd', 4), (NULL, 'e', 5), (NULL, 'f', 6), (NULL, 'g', 7), (NULL, 'h', 8), (NULL, 'i', 9);
+insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
+
+SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+
+explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+drop table t1,t2;
+
+#
+# deived tables with subquery inside all by one table
+#
+create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1)
+);
+insert into t1 VALUES(1,1,1), (2,2,1);
+select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2;
+explain select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2;
+drop table t1;
+
+create table t1 (a int);
+insert into t1 values (1),(2);
+select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
+explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
+drop table t1;
+
+#
+# "Using index" in explain
+#
+create table t2 (a int, b int, primary key (a));
+insert into t2 values (1,7),(2,7);
+explain select a from t2 where a>1;
+explain select a from (select a from t2 where a>1) tt;
+drop table t2;
+
+#
+# prepared EXPLAIN
+#
+create table t1
+(
+ c1 tinyint, c2 smallint, c3 mediumint, c4 int,
+ c5 integer, c6 bigint, c7 float, c8 double,
+ c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
+ c13 date, c14 datetime, c15 timestamp, c16 time,
+ c17 year, c18 bit, c19 bool, c20 char,
+ c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
+ c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
+ c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
+ c32 set('monday', 'tuesday', 'wednesday')
+) engine = MYISAM ;
+create table t2 like t1;
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+
+set @stmt= ' explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25 ' ;
+prepare stmt1 from @stmt ;
+execute stmt1 ;
+execute stmt1 ;
+explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
+deallocate prepare stmt1;
+drop tables t1,t2;
+
+set @@optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # LP bug #793436: query with a derived table for which optimizer proves
+--echo # that it contains not more than 1 row
+--echo #
+
+CREATE TABLE t1 (a int, KEY (a)) ;
+INSERT INTO t1 VALUES (3), (1);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (3);
+
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a;
+SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #800518: crash with a query over a derived table
+--echo # when a min/max optimization is applied
+--echo #
+
+CREATE TABLE t1 (a int, b int, c varchar(10), INDEX idx(a,b)) ;
+INSERT INTO t1 VALUES
+ (100, 3, 'xxx'), (200, 7, 'yyyyyyy'), (100, 1, 't'),
+ (200, 4, 'aaaa'), (100, 3, 'eee'), (100, 5, 'zzzzz');
+
+EXPLAIN
+SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100;
+SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100;
+
+DROP TABLE t1;
+
+--echo #
+--echo # LP bug #799499: query over a materialized view
+--echo # accessed by a key
+--echo #
+
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (8);
+
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES
+ (262, NULL), (253, 190), (260, NULL), (250, 163), (188, 8),
+ (257,200), (256, NULL), (255, 8), (249, NULL), (259, 7);
+
+CREATE VIEW v1 AS SELECT a, MIN(b) AS b FROM t2 GROUP BY a;
+
+EXPLAIN
+SELECT * FROM v1, t1 WHERE v1.b=t1.a ORDER BY v1.a;
+SELECT * FROM v1, t1 WHERE v1.b=t1.a ORDER BY v1.a;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #800085: crash with a query using a simple derived table
+--echo # (fixed by the patch for bug 798621)
+--echo #
+
+CREATE TABLE t1 (f1 int, f2 varchar(32)) ;
+INSERT INTO t1 VALUES (NULL,'j'), (8,'c');
+
+CREATE TABLE t2 (f1 int);
+INSERT INTO t2 VALUES (1), (5);
+
+SELECT DISTINCT t.f1 FROM (SELECT * FROM t1) AS t, t2
+ WHERE t.f2='s' AND t.f2 LIKE '%a%' OR t.f1<>0 ORDER BY t.f2;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG##806524: Assertion `join->best_read < 1.7976931348623157e+308 with table_elimination=on and derived_merge=on
+--echo #
+CREATE TABLE t1 ( f4 int) ;
+CREATE TABLE t2 ( f4 int) ;
+CREATE TABLE t3 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+CREATE TABLE t4 ( f2 int, f4 int) ;
+
+SELECT *
+FROM ( SELECT * FROM t1 ) AS alias1
+RIGHT JOIN (
+ t2 AS alias2
+ LEFT JOIN (
+ SELECT t4.*
+ FROM ( SELECT * FROM t3 ) AS SQ1_alias1
+ RIGHT JOIN t4
+ ON t4.f2 = SQ1_alias1.f1
+ ) AS alias3
+ ON alias3.f4 != 0
+) ON alias3.f4 != 0;
+
+drop table t1,t2,t3,t4;
+
+--echo #
+--echo # LP BUG#910123 MariaDB 5.3.3 causes 1093 error on Drupal
+--echo # Fix: force materialization in case of conflict
+--echo #
+SET optimizer_switch='derived_merge=on';
+CREATE TABLE t1 ( i INT );
+INSERT INTO t1 VALUES ( (SELECT 1 FROM ( SELECT * FROM t1 ) as a) );
+drop table t1;
+set optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # MDEV-3801 Reproducible sub select join crash on 5.3.8 and 5.3.9
+--echo #
+
+CREATE TABLE t1 (
+ pk int(10) unsigned NOT NULL AUTO_INCREMENT,
+ a char(2) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY a (a)
+) ENGINE=MyISAM;
+INSERT INTO t1 (a)
+VALUES (NULL),(NULL),(NULL),('AB'),(NULL),('CD'),(NULL),(NULL);
+INSERT INTO t1 SELECT NULL, a1.a FROM t1 a1, t1 a2, t1 a3, t1 a4, t1 a5;
+
+CREATE TABLE t2 (
+ pk int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
+INSERT INTO t2 SELECT NULL FROM t2 a1, t2 a2, t2 a3, t2 a4, t2 a5;
+
+CREATE TABLE t3 (
+ pk int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY
+) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
+INSERT INTO t3 SELECT NULL FROM t3 a1, t3 a2, t3 a3, t3 a4, t3 a5;
+
+CREATE TABLE t4 (
+ a char(2) NOT NULL DEFAULT '',
+ PRIMARY KEY (a)
+) ENGINE=MyISAM;
+INSERT INTO t4 VALUES ('CD');
+
+set @@tmp_table_size=8192;
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM t3 AS tx JOIN t2 AS ty ON (tx.pk = ty.pk)
+WHERE
+ tx.pk IN
+ (SELECT *
+ FROM (SELECT DISTINCT ta.pk
+ FROM t3 AS ta
+ JOIN t2 AS tb ON (ta.pk = tb.pk)
+ JOIN t1 AS tc ON (tb.pk = tc.pk)
+ JOIN t4 AS td ON tc.a = td.a) tu)
+limit 10;
+
+SELECT * FROM t3 AS tX JOIN t2 AS tY ON (tX.pk = tY.pk)
+WHERE
+ tX.pk IN
+ (SELECT *
+ FROM (SELECT DISTINCT tA.pk
+ FROM t3 AS tA
+ JOIN t2 AS tB ON (tA.pk = tB.pk)
+ JOIN t1 AS tC ON (tB.pk = tC.pk)
+ JOIN t4 AS tD ON tC.a = tD.a) tU)
+limit 10;
+
+drop table t1, t2, t3, t4;
+
+# The following command must be the last one the file
+set optimizer_switch=@exit_optimizer_switch;
diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test
new file mode 100644
index 00000000000..c7705294ef2
--- /dev/null
+++ b/mysql-test/t/derived_view.test
@@ -0,0 +1,1520 @@
+--disable_warnings
+drop table if exists t1,t2;
+drop view if exists v1,v2,v3,v4;
+--enable_warnings
+
+set @exit_optimizer_switch=@@optimizer_switch;
+set @exit_join_cache_level=@@join_cache_level;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+# The 'default' value within the scope of this test:
+set @save_optimizer_switch=@@optimizer_switch;
+set join_cache_level=1;
+
+create table t1(f1 int, f11 int);
+create table t2(f2 int, f22 int);
+insert into t1 values(1,1),(2,2),(3,3),(5,5),(9,9),(7,7);
+insert into t1 values(17,17),(13,13),(11,11),(15,15),(19,19);
+insert into t2 values(1,1),(3,3),(2,2),(4,4),(8,8),(6,6);
+insert into t2 values(12,12),(14,14),(10,10),(18,18),(16,16);
+
+--echo Tests:
+
+--echo for merged derived tables
+--echo explain for simple derived
+explain select * from (select * from t1) tt;
+select * from (select * from t1) tt;
+--echo explain for multitable derived
+explain extended select * from (select * from t1 join t2 on f1=f2) tt;
+select * from (select * from t1 join t2 on f1=f2) tt;
+--echo explain for derived with where
+explain extended
+ select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
+select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
+--echo join of derived
+explain extended
+ select * from (select * from t1 where f1 in (2,3)) tt join
+ (select * from t1 where f1 in (1,2)) aa on tt.f1=aa.f1;
+select * from (select * from t1 where f1 in (2,3)) tt join
+ (select * from t1 where f1 in (1,2)) aa on tt.f1=aa.f1;
+
+flush status;
+explain extended
+ select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
+show status like 'Handler_read%';
+flush status;
+select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
+show status like 'Handler_read%';
+
+--echo for merged views
+create view v1 as select * from t1;
+create view v2 as select * from t1 join t2 on f1=f2;
+create view v3 as select * from t1 where f1 in (2,3);
+create view v4 as select * from t2 where f2 in (2,3);
+--echo explain for simple views
+explain extended select * from v1;
+select * from v1;
+--echo explain for multitable views
+explain extended select * from v2;
+select * from v2;
+--echo explain for views with where
+explain extended select * from v3 where f11 in (1,3);
+select * from v3 where f11 in (1,3);
+--echo explain for joined views
+explain extended
+ select * from v3 join v4 on f1=f2;
+select * from v3 join v4 on f1=f2;
+
+flush status;
+explain extended select * from v4 where f2 in (1,3);
+show status like 'Handler_read%';
+flush status;
+select * from v4 where f2 in (1,3);
+show status like 'Handler_read%';
+
+--echo for materialized derived tables
+--echo explain for simple derived
+explain extended select * from (select * from t1 group by f1) tt;
+select * from (select * from t1 having f1=f1) tt;
+--echo explain showing created indexes
+explain extended
+ select * from t1 join (select * from t2 group by f2) tt on f1=f2;
+select * from t1 join (select * from t2 group by f2) tt on f1=f2;
+--echo explain showing late materialization
+flush status;
+explain select * from t1 join (select * from t2 group by f2) tt on f1=f2;
+show status like 'Handler_read%';
+flush status;
+select * from t1 join (select * from t2 group by f2) tt on f1=f2;
+show status like 'Handler_read%';
+
+--echo for materialized views
+drop view v1,v2,v3;
+create view v1 as select * from t1 group by f1;
+create view v2 as select * from t2 group by f2;
+create view v3 as select t1.f1,t1.f11 from t1 join t1 as t11 where t1.f1=t11.f1
+ having t1.f1<100;
+--echo explain for simple derived
+explain extended select * from v1;
+select * from v1;
+--echo explain showing created indexes
+explain extended select * from t1 join v2 on f1=f2;
+select * from t1 join v2 on f1=f2;
+explain extended
+ select * from t1,v3 as v31,v3 where t1.f1=v31.f1 and t1.f1=v3.f1;
+flush status;
+select * from t1,v3 as v31,v3 where t1.f1=v31.f1 and t1.f1=v3.f1;
+show status like 'Handler_read%';
+--echo explain showing late materialization
+flush status;
+explain select * from t1 join v2 on f1=f2;
+show status like 'Handler_read%';
+flush status;
+select * from t1 join v2 on f1=f2;
+show status like 'Handler_read%';
+
+explain extended select * from v1 join v4 on f1=f2;
+select * from v1 join v4 on f1=f2;
+
+--echo merged derived in merged derived
+explain extended select * from (select * from
+ (select * from t1 where f1 < 7) tt where f1 > 2) zz;
+select * from (select * from
+ (select * from t1 where f1 < 7) tt where f1 > 2) zz;
+
+--echo materialized derived in merged derived
+explain extended select * from (select * from
+ (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) zz;
+select * from (select * from
+ (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) zz;
+
+--echo merged derived in materialized derived
+explain extended select * from (select * from
+ (select * from t1 where f1 < 7) tt where f1 > 2 group by f1) zz;
+select * from (select * from
+ (select * from t1 where f1 < 7) tt where f1 > 2 group by f1) zz;
+
+--echo materialized derived in materialized derived
+explain extended select * from (select * from
+ (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) zz;
+select * from (select * from
+ (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) zz;
+
+--echo mat in merged derived join mat in merged derived
+explain extended select * from
+ (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) x
+join
+ (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) z
+ on x.f1 = z.f1;
+
+flush status;
+select * from
+ (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) x
+join
+ (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) z
+ on x.f1 = z.f1;
+show status like 'Handler_read%';
+flush status;
+
+--echo merged in merged derived join merged in merged derived
+explain extended select * from
+ (select * from
+ (select * from t1 where f1 < 7 ) tt where f1 > 2 ) x
+join
+ (select * from
+ (select * from t1 where f1 < 7 ) tt where f1 > 2 ) z
+ on x.f1 = z.f1;
+
+select * from
+ (select * from
+ (select * from t1 where f1 < 7 ) tt where f1 > 2 ) x
+join
+ (select * from
+ (select * from t1 where f1 < 7 ) tt where f1 > 2 ) z
+ on x.f1 = z.f1;
+
+--echo materialized in materialized derived join
+--echo materialized in materialized derived
+explain extended select * from
+ (select * from
+ (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) x
+join
+ (select * from
+ (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) z
+ on x.f1 = z.f1;
+
+select * from
+ (select * from
+ (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) x
+join
+ (select * from
+ (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) z
+ on x.f1 = z.f1;
+
+--echo merged view in materialized derived
+explain extended
+select * from (select * from v4 group by 1) tt;
+select * from (select * from v4 group by 1) tt;
+
+--echo materialized view in merged derived
+explain extended
+select * from ( select * from v1 where f1 < 7) tt;
+select * from ( select * from v1 where f1 < 7) tt;
+
+--echo merged view in a merged view in a merged derived
+create view v6 as select * from v4 where f2 < 7;
+explain extended select * from (select * from v6) tt;
+select * from (select * from v6) tt;
+
+--echo materialized view in a merged view in a materialized derived
+create view v7 as select * from v1;
+explain extended select * from (select * from v7 group by 1) tt;
+select * from (select * from v7 group by 1) tt;
+
+--echo join of above two
+explain extended select * from v6 join v7 on f2=f1;
+select * from v6 join v7 on f2=f1;
+
+--echo test two keys
+explain select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1;
+select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1;
+
+
+--echo TODO: Add test with 64 tables mergeable view to test fall back to
+--echo materialization on tables > MAX_TABLES merge
+drop table t1,t2;
+drop view v1,v2,v3,v4,v6,v7;
+
+--echo #
+--echo # LP bug #794909: crash when defining possible keys for
+--echo # a materialized view/derived_table
+--echo #
+
+CREATE TABLE t1 (f1 int) ;
+INSERT INTO t1 VALUES (149), (150), (224), (29);
+
+CREATE TABLE t2 (f1 int, KEY (f1));
+INSERT INTO t2 VALUES (149), (NULL), (224);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+
+EXPLAIN
+SELECT * FROM v1 JOIN t2 ON v1.f1 = t2.f1;
+SELECT * FROM v1 JOIN t2 ON v1.f1 = t2.f1;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #794890: abort failure on multi-update with view
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (20), (7);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (7), (9), (7);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT a FROM t1;
+
+CREATE VIEW v2 AS SELECT t2.a FROM t2, v1 WHERE t2.a=t2.a;
+UPDATE v2 SET a = 2;
+SELECT * FROM t2;
+
+UPDATE t1,v2 SET t1.a = 3;
+SELECT * FROM t1;
+
+DELETE t1 FROM t1,v2;
+SELECT * FROM t1;
+
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #802023: MIN/MAX optimization
+--echo # for mergeable derived tables and views
+--echo #
+
+CREATE TABLE t1 (a int, b int, c varchar(32), INDEX idx(a,b));
+INSERT INTO t1 VALUES
+ (7, 74, 'yyyyyyy'), (9, 97, 'aaaaaaaaa'), (2, 23, 'tt'),
+ (5, 55, 'ddddd'), (2, 27, 'ss'), (7, 76, 'xxxxxxx'),
+ (7, 79, 'zzzzzzz'), (9, 92, 'bbbbbbbbb'), (2, 25, 'pp'),
+ (5, 53, 'eeeee'), (2, 23, 'qq'), (7, 76,'wwwwwww'),
+ (7, 74, 'uuuuuuu'), (9, 92, 'ccccccccc'), (2, 25, 'oo');
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT MIN(a) FROM t1 WHERE a >= 5;
+EXPLAIN
+SELECT MIN(a) FROM t1 WHERE a >= 5;
+
+SELECT MIN(a) FROM (SELECT * FROM t1) t WHERE a >= 5;
+EXPLAIN
+SELECT MIN(a) FROM(SELECT * FROM t1) t WHERE a >= 5;
+
+SELECT MIN(a) FROM v1 WHERE a >= 5;
+EXPLAIN
+SELECT MIN(a) FROM v1 WHERE a >= 5;
+
+SELECT MAX(b) FROM t1 WHERE a=7 AND b<75;
+EXPLAIN
+SELECT MAX(b) FROM t1 WHERE a=7 AND b<75;
+
+SELECT MAX(b) FROM (SELECT * FROM t1) t WHERE a=7 AND b<75;
+EXPLAIN
+SELECT MAX(b) FROM (SELECT * FROM t1) t WHERE a=7 AND b<75;
+
+SELECT MAX(b) FROM v1 WHERE a=7 AND b<75;
+EXPLAIN
+SELECT MAX(b) FROM v1 WHERE a=7 AND b<75;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # LP bug #800535: GROUP BY query with nested left join
+--echo # and a derived table in the nest
+--echo #
+
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (1), (2);
+
+CREATE TABLE t2 (a int NOT NULL);
+INSERT INTO t2 VALUES (1), (2);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (3,3), (4,4);
+
+EXPLAIN EXTENDED
+SELECT t.a FROM t1 LEFT JOIN
+ (t2 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+ GROUP BY t.a;
+SELECT t.a FROM t1 LEFT JOIN
+ (t2 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+ GROUP BY t.a;
+
+EXPLAIN EXTENDED
+SELECT t.a FROM t1 LEFT JOIN
+ (( SELECT * FROM t2 ) t JOIN t3 ON t3.b > 5) ON t.a >= 1
+ GROUP BY t.a;
+SELECT t.a FROM t1 LEFT JOIN
+ (( SELECT * FROM t2 ) t JOIN t3 ON t3.b > 5) ON t.a >= 1
+ GROUP BY t.a;
+
+CREATE VIEW v1 AS SELECT * FROM t2;
+
+EXPLAIN EXTENDED
+SELECT t.a FROM t1 LEFT JOIN
+ (v1 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+ GROUP BY t.a;
+SELECT t.a FROM t1 LEFT JOIN
+ (v1 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+ GROUP BY t.a;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #803410: materialized view/dt accessed by two-component key
+--echo #
+
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('c');
+
+CREATE TABLE t2 (a varchar(1) , KEY (a)) ;
+INSERT INTO t2 VALUES ('c'), (NULL), ('r');
+
+CREATE TABLE t3 (a varchar(1), b varchar(1));
+INSERT INTO t3 VALUES
+ ('e', 'c'), ('c', 'c'), ('c', 'r'), ('g', 'a'), ('b', 'x'), ('b', 'y'),
+ ('h', 'w'), ('d', 'z'), ('k', 'v'), ('j', 's'), ('m', 'p'), ('l', 'q');
+
+CREATE VIEW v1 AS SELECT a, MIN(b) AS b FROM t3 GROUP BY a;
+
+EXPLAIN
+SELECT * FROM t1, t2, v1 WHERE t2.a=t1.a AND t2.a=v1.a AND t2.a=v1.b;
+SELECT * FROM t1, t2, v1 WHERE t2.a=t1.a AND t2.a=v1.a AND t2.a=v1.b;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+
+--echo #
+--echo # LP bug #802845: select from derived table with limit 0
+--echo #
+
+SELECT * FROM (SELECT 1 LIMIT 0) t;
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (7), (1), (3);
+
+SELECT * FROM (SELECT * FROM t1 LIMIT 0) t;
+
+DROP TABLE t1;
+
+--echo #
+--echo # LP bug #803851: materialized view + IN->EXISTS
+--echo #
+
+SET SESSION optimizer_switch='semijoin=off,derived_with_keys=on,materialization=off';
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (2,2), (3,3), (1,1);
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1), (2), (1);
+
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (3), (1), (2), (1);
+
+CREATE VIEW v1 AS SELECT a, MAX(b) AS b FROM t1 GROUP BY a;
+
+EXPLAIN EXTENDED
+SELECT * FROM t3
+ WHERE t3.a IN (SELECT v1.a FROM v1, t2 WHERE t2.a = v1.b);
+SELECT * FROM t3
+ WHERE t3.a IN (SELECT v1.a FROM v1, t2 WHERE t2.a = v1.b);
+
+SET SESSION optimizer_switch=@save_optimizer_switch;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #804515: materialized derived + ORDER BY
+--echo #
+
+CREATE TABLE t1 (f1 varchar(1), f2 varchar(1), KEY (f2));
+INSERT INTO t1 VALUES
+ ('r','x'), ('x','d'), ('x','r'), ('r','f'), ('x','x');
+
+CREATE TABLE t2 (f1 varchar(1), f2 varchar(1));
+INSERT INTO t2 VALUES ('s','x');
+
+CREATE TABLE t3 (f1 varchar(1), f2 varchar(1), KEY (f2));
+INSERT INTO t3 VALUES
+ (NULL,'x'), (NULL,'f'), ('t','p'), (NULL,'j'), ('g','c');
+
+CREATE TABLE t4 (f1 int, f2 varchar(1), KEY (f2,f1)) ;
+INSERT INTO t4 VALUES (1,'x'), (5,'r');
+
+EXPLAIN
+SELECT t.f1 AS f
+ FROM (SELECT DISTINCT t1.* FROM t1,t2 WHERE t2.f2 = t1.f2) t,t3,t4
+ WHERE t4.f2 = t3.f2 AND t4.f2 = t.f1 ORDER BY f;
+SELECT t.f1 AS f
+ FROM (SELECT DISTINCT t1.* FROM t1,t2 WHERE t2.f2 = t1.f2) t,t3,t4
+ WHERE t4.f2 = t3.f2 AND t4.f2 = t.f1 ORDER BY f;
+
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # LP bug #806431: join over materialized derived with key
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (0,0),(3,0),(1,0);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT a,b FROM t1 ;
+
+SET SESSION optimizer_switch='derived_with_keys=off';
+SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
+SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
+
+SET SESSION optimizer_switch=@save_optimizer_switch;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo #
+--echo # LP bug #806477: left join over merged join with
+--echo # where condition containing f=f
+--echo #
+
+CREATE TABLE t1 (a int NOT NULL);
+INSERT INTO t1 VALUES (1), (50), (0);
+
+CREATE TABLE t2 (a int);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (76,2), (1,NULL);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT t3.b, v1.a
+ FROM t3 LEFT JOIN (t2, v1) ON t3.a <> 0
+ WHERE v1.a = v1.a OR t3.b <> 0;
+EXPLAIN EXTENDED
+SELECT t3.b, v1.a
+ FROM t3 LEFT JOIN (t2, v1) ON t3.a <> 0
+ WHERE v1.a = v1.a OR t3.b <> 0;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #806510: subquery with outer reference
+--echo # to a derived_table/view
+--echo #
+
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (4), (NULL);
+
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (8), (0);
+
+CREATE TABLE t3 (a int, b int) ;
+INSERT INTO t3 VALUES (7,8);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT * FROM t1 t
+ WHERE EXISTS (SELECT t3.a FROM t3, t2
+ WHERE t2.a = t3.b AND t.a != 0);
+EXPLAIN
+SELECT * FROM t1 t
+ WHERE EXISTS (SELECT t3.a FROM t3, t2
+ WHERE t2.a = t3.b AND t.a != 0);
+
+SELECT * FROM (SELECT * FROM t1) t
+ WHERE EXISTS (SELECT t3.a FROM t3, t2
+ WHERE t2.a = t3.b AND t.a != 0);
+EXPLAIN
+SELECT * FROM (SELECT * FROM t1) t
+ WHERE EXISTS (SELECT t3.a FROM t3, t2
+ WHERE t2.a = t3.b AND t.a != 0);
+
+SELECT * FROM v1 t
+ WHERE EXISTS (SELECT t3.a FROM t3, t2
+ WHERE t2.a = t3.b AND t.a != 0);
+EXPLAIN
+SELECT * FROM v1 t
+ WHERE EXISTS (SELECT t3.a FROM t3, t2
+ WHERE t2.a = t3.b AND t.a != 0);
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #806097: left join over a view + DISTINCT
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (252,6), (232,0), (174,232);
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (232), (174);
+
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (1), (2);
+
+CREATE VIEW v1 AS SELECT t2.a FROM t3,t2;
+
+SELECT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0;
+
+SELECT DISTINCT t2.a FROM t1 LEFT JOIN (t3,t2) ON t1.b = 0;
+EXPLAIN
+SELECT DISTINCT t2.a FROM t1 LEFT JOIN (t3,t2) ON t1.b = 0;
+
+SELECT DISTINCT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0;
+EXPLAIN
+SELECT DISTINCT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #806504: right join over a view/derived table
+--echo #
+
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0);
+
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (0), (0);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #809206: DISTINCT in derived table / view
+--echo #
+
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (0);
+
+CREATE TABLE t2 (a varchar(32), b int, KEY (a)) ;
+INSERT INTO t2 VALUES
+ ('j',28), ('c',29), ('i',26), ('c',29), ('k',27),
+ ('j',28), ('c',29), ('i',25), ('d',26), ('k',27),
+ ('n',28), ('d',29), ('m',26), ('e',29), ('p',27),
+ ('w',28), ('x',29), ('y',25), ('z',26), ('s',27);
+
+
+CREATE TABLE t3 (a varchar(32));
+INSERT INTO t3 VALUES ('j'), ('c');
+
+CREATE VIEW v1 AS SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
+
+SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
+EXPLAIN
+SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
+
+SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t;
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t;
+
+SELECT * FROM v1;
+EXPLAIN
+SELECT * FROM v1;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #809179: right join over a derived table / view
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (6,5);
+
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (1,0);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (6,5);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT t.a,t.b FROM t3 RIGHT JOIN (t1 AS t, t2) ON t2.b != 0
+ WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+EXPLAIN EXTENDED
+SELECT t.a,t.b FROM t3 RIGHT JOIN (t1 AS t, t2) ON t2.b != 0
+ WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+
+SELECT t.a,t.b FROM t3 RIGHT JOIN ((SELECT * FROM t1) AS t, t2) ON t2.b != 0
+ WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+EXPLAIN EXTENDED
+SELECT t.a,t.b FROM t3 RIGHT JOIN ((SELECT * FROM t1) AS t, t2) ON t2.b != 0
+ WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+
+SELECT t.a,t.b FROM t3 RIGHT JOIN (v1 AS t, t2) ON t2.b != 0
+ WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+EXPLAIN EXTENDED
+SELECT t.a,t.b FROM t3 RIGHT JOIN (v1 AS t, t2) ON t2.b != 0
+ WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #794901: insert into a multi-table view
+--echo #
+
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int);
+
+CREATE VIEW v1 AS SELECT t1.a FROM t1,t2;
+CREATE VIEW v2 AS SELECT a FROM t2 GROUP BY a;
+CREATE VIEW v3 AS SELECT v1.a FROM v1,v2;
+
+-- error ER_NON_INSERTABLE_TABLE
+INSERT INTO v3(a) VALUES (1);
+
+DROP VIEW v1,v2,v3;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #793448: materialized view accessed by two-component key
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (9,3), (2,5);
+
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (9,3), (3,7), (9,1), (2,5), (2,4), (3,8);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,3), (9,7), (9,1), (2,4);
+
+CREATE VIEW v1(a,b) AS SELECT a, MAX(b) FROM t2 GROUP BY a;
+CREATE VIEW v2(a,b) AS SELECT a,b FROM t2 UNION SELECT a,b FROM t3;
+
+SELECT * FROM v1;
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+
+SELECT * FROM v2;
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+
+DROP VIEW v1,v2;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #804686: query over a derived table using a view
+--echo # with a degenerated where condition
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (0,0), (1,0), (0,0), (1,1), (1,0);
+CREATE VIEW v1 AS SELECT a,b FROM t1;
+CREATE VIEW v2 AS SELECT a, MAX(b) AS b FROM t1 GROUP BY a;
+
+SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b<>0;
+SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b<>0;
+SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b;
+SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b;
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b;
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b;
+
+DROP VIEW v1,v2;
+DROP TABLE t1;
+
+--echo #
+--echo # LP bug #819716: crash with embedded tableless materialized derived
+--echo # with a variable
+--echo #
+
+set optimizer_switch='derived_merge=off';
+EXPLAIN
+SELECT * FROM (SELECT * FROM (SELECT @b) AS t) AS s;
+SELECT * FROM (SELECT * FROM (SELECT @b) AS t) AS s;
+set optimizer_switch='derived_merge=on';
+
+--echo #
+--echo # LP bug #823826: view over join + IS NULL in WHERE
+--echo #
+
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (1), (1);
+
+CREATE TABLE t2 (b int) ;
+INSERT INTO t2 VALUES (9), (NULL), (7);
+
+CREATE VIEW v1 AS SELECT * FROM t1,t2;
+
+EXPLAIN
+SELECT * FROM (SELECT * FROM t1,t2) t WHERE b IS NULL;
+SELECT * FROM (SELECT * FROM t1,t2) t WHERE b IS NULL;
+
+EXPLAIN
+SELECT * FROM v1 WHERE b IS NULL;
+SELECT * FROM v1 WHERE b IS NULL;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #823835: a duplicate of #823189 with derived table
+--echo #
+
+CREATE TABLE t1 (a varchar(32)) ;
+INSERT INTO t1 VALUES ('r'), ('p');
+
+CREATE TABLE t2 (a int NOT NULL, b varchar(32)) ;
+INSERT INTO t2 VALUES (28,'j');
+
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (0), (0);
+
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT * FROM t1) AS t
+WHERE EXISTS (SELECT t2.a FROM t3 RIGHT JOIN t2 ON (t3.a = t2.a)
+ WHERE t2.b < t.a);
+SELECT * FROM (SELECT * FROM t1) AS t
+WHERE EXISTS (SELECT t2.a FROM t3 RIGHT JOIN t2 ON (t3.a = t2.a)
+ WHERE t2.b < t.a);
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #824463: nested outer join using a merged view
+--echo # as an inner table
+--echo #
+
+CREATE TABLE t1 (b int, a int) ;
+
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (5), (6);
+
+CREATE TABLE t3 (a int , c int) ;
+INSERT INTO t3 VALUES (22,1), (23,-1);
+
+CREATE TABLE t4 (a int);
+
+CREATE TABLE t5 (d int) ;
+INSERT INTO t5 VALUES (0), (7), (3), (5);
+
+CREATE VIEW v2 AS SELECT * FROM t2;
+CREATE VIEW v3 AS SELECT * FROM t3;
+
+EXPLAIN EXTENDED
+SELECT STRAIGHT_JOIN *
+ FROM ( t2 AS s2
+ JOIN
+ ( t3 AS s3
+ LEFT JOIN
+ ( t4 LEFT JOIN t3 ON t4.a != 0 )
+ ON s3.a != 0)
+ ON s2.a != 0)
+ JOIN t5 ON s3.c != 0 AND t5.d = 0;
+SELECT STRAIGHT_JOIN *
+ FROM ( t2 AS s2
+ JOIN
+ ( t3 AS s3
+ LEFT JOIN
+ ( t4 LEFT JOIN t3 ON t4.a != 0 )
+ ON s3.a != 0)
+ ON s2.a != 0)
+ JOIN t5 ON s3.c != 0 AND t5.d = 0;
+
+EXPLAIN EXTENDED
+SELECT STRAIGHT_JOIN *
+ FROM t2 AS s2 , t5,
+ (t3 LEFT JOIN (t4 LEFT JOIN t3 AS s3 ON t4.a != 0) ON t3.a != 0)
+ WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+SELECT STRAIGHT_JOIN *
+ FROM t2 AS s2 , t5,
+ (t3 LEFT JOIN (t4 LEFT JOIN t3 AS s3 ON t4.a != 0) ON t3.a != 0)
+ WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+
+EXPLAIN EXTENDED
+SELECT STRAIGHT_JOIN *
+ FROM v2 AS s2 , t5,
+ (t3 LEFT JOIN (t4 LEFT JOIN v3 AS s3 ON t4.a != 0) ON t3.a != 0)
+ WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+SELECT STRAIGHT_JOIN *
+ FROM v2 AS s2 , t5,
+ (t3 LEFT JOIN (t4 LEFT JOIN v3 AS s3 ON t4.a != 0) ON t3.a != 0)
+ WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+
+SELECT STRAIGHT_JOIN *
+ FROM ( ( t2 AS s2
+ LEFT JOIN
+ ( t3 AS s3
+ LEFT JOIN
+ ( t4 AS s4 JOIN t3 ON s4.a != 0)
+ ON s3.a != 0 )
+ ON s2.a != 0)
+ LEFT JOIN
+ t1 AS s1
+ ON s1.a != 0)
+ JOIN t5 ON s3.c != 0;
+SELECT STRAIGHT_JOIN *
+ FROM ( ( v2 AS s2
+ LEFT JOIN
+ ( v3 AS s3
+ LEFT JOIN
+ ( t4 AS s4 JOIN v3 ON s4.a != 0)
+ ON s3.a != 0 )
+ ON s2.a != 0)
+ LEFT JOIN
+ t1 AS s1
+ ON s1.a != 0)
+ JOIN t5 ON s3.c != 0;
+
+DROP VIEW v2,v3;
+DROP TABLE t1,t2,t3,t4,t5;
+
+--echo #
+--echo # LP bug #872735: derived used in a NOT IN subquery
+--echo #
+
+CREATE TABLE t1 (b int NOT NULL);
+INSERT INTO t1 VALUES (9), (7);
+
+CREATE TABLE t2 (a int NOT NULL) ;
+INSERT INTO t2 VALUES (1), (2);
+
+CREATE TABLE t3 (
+ a int NOT NULL , c int NOT NULL, d varchar(1) NOT NULL,
+ KEY (c,a) , PRIMARY KEY (a)
+);
+INSERT INTO t3 VALUES
+ (14,4,'a'), (15,7,'b'), (16,4,'c'), (17,1,'d'), (18,9,'e'),
+ (19,4,'f'), (20,8,'g');
+
+SET SESSION optimizer_switch='derived_merge=on,subquery_cache=off,materialization=off';
+
+--echo # The following two EXPLAINs must return the same execution plan
+EXPLAIN
+SELECT * FROM t1 , t2
+ WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM t3 t);
+EXPLAIN
+SELECT * FROM t1 , t2
+ WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t);
+
+SELECT * FROM t1 , t2
+ WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t);
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #874006: materialized view used in IN subquery
+--echo #
+
+CREATE TABLE t3 (a int NOT NULL, b varchar(1), c varchar(1));
+INSERT INTO t3 VALUES (19,NULL,NULL), (20,'r','r');
+
+CREATE TABLE t1 (a int, b varchar(1) , c varchar(1));
+INSERT INTO t1 VALUES (1,NULL,NULL), (5,'r','r'), (7,'y','y');
+
+CREATE TABLE t2 (a int NOT NULL , b int, c varchar(1));
+INSERT INTO t2 VALUES (4,3,'r');
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+SET optimizer_switch=@save_optimizer_switch;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #873263: materialized view used in correlated IN subquery
+--echo #
+
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (5,4), (9,8);
+
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (4,5), (5,1);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+
+DROP VIEW v2;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #877316: query over a view with correlated subquery in WHERE
+--echo #
+
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (18,2), (19,9);
+
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (10,8), (5,10);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT t1.a FROM t1
+ WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < t1.b);
+EXPLAIN
+SELECT t1.a FROM t1
+ WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < t1.b);
+
+SELECT v1.a FROM v1
+ WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < v1.b);
+EXPLAIN
+SELECT v1.a FROM v1
+ WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < v1.b);
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #878199: join of two materialized views
+--echo #
+
+CREATE TABLE t1 (a int, b varchar(1)) ;
+INSERT INTO t1 VALUES (7,'c'), (3,'h'), (7,'c');
+
+CREATE TABLE t2 (b varchar(1)) ;
+INSERT INTO t2 VALUES ('p'), ('c'), ('j'), ('c'), ('p');
+
+CREATE VIEW v1 AS SELECT * FROM t1 GROUP BY a,b;
+
+CREATE VIEW v2 AS SELECT * FROM t2 GROUP BY b;
+
+SET SESSION optimizer_switch = 'derived_with_keys=on';
+
+SELECT v1.a FROM v1,v2 WHERE v2.b = v1.b ORDER BY 1;
+EXPLAIN
+SELECT v1.a FROM v1,v2 WHERE v2.b = v1.b ORDER BY 1;
+
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+
+
+--echo #
+--echo # Bug #743378: join over merged view employing BNL
+--echo #
+
+CREATE TABLE t1 ( d varchar(1) NOT NULL) ;
+INSERT INTO t1 VALUES ('j'),('v'),('c');
+
+CREATE TABLE t2 (h time NOT NULL, d varchar(1) NOT NULL) ;
+INSERT INTO t2 VALUES ('05:03:03','w'),('02:59:24','d'),('00:01:58','e');
+
+CREATE TABLE t3 (
+ b int NOT NULL, e varchar(1) NOT NULL, d varchar(1) NOT NULL, KEY (e,b)
+);
+INSERT INTO t3 VALUES (4,'x','x'),(9,'w','w'),(4,'d','d'),(8,'e','e');
+INSERT INTO t3 VALUES (14,'a','a'),(19,'b','b'),(14,'c','c'),(18,'d','d');
+
+CREATE TABLE t4 (i int NOT NULL, m varchar(1) NOT NULL) ;
+INSERT INTO t4 VALUES (8,'m'),(9,'d'),(2,'s'),(4,'r'),(8,'m');
+
+CREATE TABLE t5 (
+ a int NOT NULL, c int NOT NULL, b int NOT NULL, f date NOT NULL,
+ g date NOT NULL, h time NOT NULL, j time NOT NULL, k datetime NOT NULL
+);
+
+INSERT INTO t5 VALUES
+ (1,4,0,'0000-00-00','0000-00-00','21:22:34','21:22:34','2002-02-13 17:30'),
+ (2,6,8,'2004-09-18','2004-09-18','10:50:38','10:50:38','2008-09-27 00:34');
+
+CREATE VIEW v3 AS SELECT t3.*, t4.i FROM t3, t4, t5;
+
+SET SESSION join_cache_level = 1;
+SET SESSION join_buffer_size = 512;
+
+EXPLAIN
+SELECT t2.d FROM t1,t2,v3 WHERE v3.e = t2.d AND v3.i < 3;
+SELECT t2.d FROM t1,t2,v3 WHERE v3.e = t2.d AND v3.i < 3;
+
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION join_buffer_size = DEFAULT;
+
+DROP VIEW v3;
+DROP TABLE t1,t2,t3,t4,t5;
+
+--echo #
+--echo # Bug #879882: right join within mergeable derived table
+--echo #
+
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('c'), ('a');
+
+CREATE TABLE t2 (a int, b int, c varchar(1));
+INSERT INTO t2 VALUES (29,8,'c'), (39,7,'b');
+
+CREATE TABLE t3 (b int);
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b AND t.c = t1.a;
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b AND t.c = t1.a;
+
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b <> 0 AND t.c = t1.a;
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b <> 0 AND t.c = t1.a;
+
+INSERT INTO t3 VALUES (100), (200);
+
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b AND t.c = t1.a;
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b AND t.c = t1.a;
+
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b <> 0 AND t.c = t1.a;
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b <> 0 AND t.c = t1.a;
+
+SET optimizer_switch=@save_optimizer_switch;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #880724: materialized const view as inner table of outer join
+--echo #
+
+CREATE TABLE t1 (a int, b varchar(1));
+INSERT INTO t1 VALUES (9,NULL), (6,'r'), (7,'c');
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (6);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
+SET SESSION optimizer_switch = 'derived_with_keys=on';
+SET SESSION join_cache_level = 4;
+
+EXPLAIN
+SELECT t1.b,v2.a FROM t1 LEFT JOIN v2 ON v2.a = t1.a;
+SELECT t1.b,v2.a FROM t1 LEFT JOIN v2 ON v2.a = t1.a;
+
+CREATE TABLE t3 (a int, b varchar(1));
+INSERT INTO t3 VALUES (8,'x'), (5,'r'), (9,'y');
+
+EXPLAIN
+SELECT * FROM t3
+ WHERE t3.b <> ANY (SELECT t1.b FROM t1 LEFT JOIN v2 ON v2.a = t1.a);
+SELECT * FROM t3
+ WHERE t3.b <> ANY (SELECT t1.b FROM t1 LEFT JOIN v2 ON v2.a = t1.a);
+
+SET SESSION join_cache_level = default;
+
+SET optimizer_switch=@save_optimizer_switch;
+
+DROP VIEW v2;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #881449: OUTER JOIN usin a merged view within IN subquery
+--echo #
+
+CREATE TABLE t1 (a varchar(1)) ;
+INSERT INTO t1 VALUES ('y'), ('x');
+
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (1), (2);
+
+CREATE TABLE t3 (a int, b varchar(1)) ;
+INSERT INTO t3 VALUES (1,'x');
+
+CREATE VIEW v3 AS SELECT * FROM t3;
+
+SET SESSION optimizer_switch='semijoin=on';
+
+EXPLAIN
+SELECT * FROM t1 WHERE a IN (SELECT v3.b FROM t2 RIGHT JOIN v3 ON v3.a = t2.a);
+SELECT * FROM t1 WHERE a IN (SELECT v3.b FROM t2 RIGHT JOIN v3 ON v3.a = t2.a);
+
+set optimizer_switch= @save_optimizer_switch;
+
+DROP VIEW v3;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #874035: view as an inner table of a materialized derived
+--echo #
+
+CREATE TABLE t2 (a int NOT NULL);
+INSERT INTO t2 VALUES (7), (4);
+
+CREATE TABLE t1 (b int NOT NULL);
+INSERT INTO t1 VALUES (5), (7);
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='derived_merge=off';
+
+PREPARE st1 FROM
+'SELECT * FROM (SELECT * FROM t2 LEFT JOIN v1 ON t2.a = v1.b) AS t';
+EXECUTE st1;
+EXECUTE st1;
+DEALLOCATE PREPARE st1;
+
+set SESSION optimizer_switch= @save_optimizer_switch;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+
+
+--echo #
+--echo # LP bug #879939: assertion in ha_maria::enable_indexes
+--echo # with derived_with_keys=on
+--echo #
+
+CREATE TABLE t2 (a varchar(3));
+INSERT INTO t2 VALUES ('USA'), ('USA'), ('USA'), ('USA'), ('USA');
+
+CREATE TABLE t1 (a varchar(3), b varchar(35));
+INSERT INTO t1 VALUES
+ ('USA','Lansing'), ('USA','Laredo'), ('USA','Las Vegas'),
+ ('USA','Lexington-Fayett'), ('USA','Lincoln'), ('USA','Little Rock'),
+ ('USA','Livonia'), ('USA','Long Beach'), ('USA','Los Angeles'),
+ ('USA','Louisville'), ('USA','Lowell'), ('USA','Lubbock'),
+ ('USA','Macon'), ('USA','Madison'), ('USA','Manchester'),
+ ('USA','McAllen'), ('USA','Memphis'), ('USA','Mesa'),
+ ('USA','Mesquite'), ('USA','Metairie'), ('USA','Miami');
+
+CREATE TABLE t3 (a varchar(35));
+INSERT INTO t3 VALUES ('Miami');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'derived_with_keys=on';
+SET @@tmp_table_size=1024*4;
+explain SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
+SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
+SET @@tmp_table_size=1024*1024*16;
+SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
+SET @@tmp_table_size=default;
+set SESSION optimizer_switch= @save_optimizer_switch;
+drop table t1,t2,t3;
+
+--echo #
+--echo # BUG#882994: Crash in QUICK_RANGE_SELECT::reset with derived_with_keys
+--echo #
+CREATE TABLE t2 (
+ pk varchar(33),
+ col_varchar_key varchar(3) NOT NULL,
+ col_varchar_nokey varchar(52) NOT NULL);
+
+INSERT INTO t2 VALUES ('NICSpanish','NIC','Spanish'),
+ ('NERHausa','NER','Hausa'),('NGAJoruba','NGA','Joruba'),
+ ('NIUNiue','NIU','Niue'),('NFKEnglish','NFK','English'),
+ ('NORNorwegian','NOR','Norwegian'),('CIVAkan','CIV','Akan'),
+ ('OMNArabic','OMN','Arabic'),('PAKPunjabi','PAK','Punjabi'),
+ ('PLWPalau','PLW','Palau'),('PANSpanish','PAN','Spanish'),
+ ('PNGPapuan Langua','PNG','Papuan Languages'), ('PRYSpanish','PRY','Spanish'),
+ ('PERSpanish','PER','Spanish'), ('PCNPitcairnese','PCN','Pitcairnese'),
+ ('MNPPhilippene La','MNP','Philippene Langu'),('PRTPortuguese','PRT','Portuguese'),
+ ('PRISpanish','PRI','Spanish'),('POLPolish','POL','Polish'),('GNQFang','GNQ','Fang');
+
+CREATE TABLE t1 ( col_varchar_nokey varchar(52) NOT NULL ) ;
+INSERT INTO t1 VALUES ('Chinese'),('English'),('French'),('German'),
+ ('Italian'),('Japanese'),('Korean'),('Polish'),('Portuguese'),('Spanish'),
+ ('Tagalog'),('Vietnamese');
+CREATE TABLE t3 ( col_varchar_key varchar(52)) ;
+INSERT INTO t3 VALUES ('United States');
+
+set @tmp_882994= @@max_heap_table_size;
+--disable_warnings
+set max_heap_table_size=1;
+--enable_warnings
+
+SELECT *
+FROM t3 JOIN
+( SELECT t2.* FROM t1, t2 ) AS alias2
+ON ( alias2.col_varchar_nokey = t3.col_varchar_key )
+ORDER BY CONCAT(alias2.col_varchar_nokey);
+
+set max_heap_table_size= @tmp_882994;
+drop table t1,t2,t3;
+
+--echo #
+--echo # LP bug #917990: Bad estimate of #rows for derived table with LIMIT
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES
+ (8), (3), (4), (7), (9), (5), (1), (2);
+
+SELECT * FROM (SELECT * FROM t1 LIMIT 3) t;
+EXPLAIN
+SELECT * FROM (SELECT * FROM t1 LIMIT 3) t;
+
+DROP TABLE t1;
+
+--echo #
+--echo # LP BUG#921878 incorrect check of items during columns union types
+--echo # aggregation for merged derived tables
+--echo #
+SET @save_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='derived_merge=on';
+CREATE TABLE t1 ( a ENUM( 'x', 'y' ) );
+insert into t1 values ('x');
+CREATE TABLE t2 LIKE t1;
+insert into t1 values ('y');
+CREATE TABLE t3 LIKE t1;
+INSERT INTO t3
+ SELECT * FROM ( SELECT * FROM t1 ) AS A
+ UNION SELECT * FROM t2;
+select * from t3;
+
+drop table t1,t2,t3;
+
+set SESSION optimizer_switch= @save_optimizer_switch;
+
+--echo #
+--echo # LP BUG#944782: derived table from an information schema table
+--echo #
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='derived_merge=on';
+SET SESSION optimizer_switch='derived_with_keys=on';
+
+CREATE TABLE t1 (c1 int PRIMARY KEY, c2 char(5));
+
+EXPLAIN
+SELECT COUNT(*) > 0
+ FROM INFORMATION_SCHEMA.COLUMNS
+ INNER JOIN
+ (SELECT TABLE_SCHEMA,
+ GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COL_NAMES
+ FROM INFORMATION_SCHEMA.STATISTICS
+ GROUP BY TABLE_SCHEMA) AS UNIQUES
+ ON ( COLUMNS.TABLE_SCHEMA = UNIQUES.TABLE_SCHEMA);
+
+# this query crashed in mariadb-5.5.20
+SELECT COUNT(*) > 0
+ FROM INFORMATION_SCHEMA.COLUMNS
+ INNER JOIN
+ (SELECT TABLE_SCHEMA,
+ GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COL_NAMES
+ FROM INFORMATION_SCHEMA.STATISTICS
+ GROUP BY TABLE_SCHEMA) AS UNIQUES
+ ON ( COLUMNS.TABLE_SCHEMA = UNIQUES.TABLE_SCHEMA);
+
+DROP TABLE t1;
+
+SET SESSION optimizer_switch= @save_optimizer_switch;
+
+--echo #
+--echo # LP BUG#953649: crash when estimating the cost of a look-up
+--echo # into a derived table to be materialized
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (132);
+
+CREATE TABLE t2 (b int, c varchar(256));
+INSERT INTO t2 VALUES (132,'test1'), (120,'text2'), (132,'text3');
+
+CREATE VIEW v AS
+ SELECT b, GROUP_CONCAT(c) AS gc FROM t2 GROUP BY b;
+
+SET @save_optimizer_switch=@@optimizer_switch;
+
+SET SESSION optimizer_switch='derived_merge=off';
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t1, v WHERE a = b;
+SELECT * FROM t1, v WHERE a = b;
+
+SET SESSION optimizer_switch='derived_merge=on';
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1, v WHERE a = b;
+SELECT * FROM t1, v WHERE a = b;
+
+SET SESSION optimizer_switch= @save_optimizer_switch;
+
+DROP VIEW v;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP BUG#968720 crash due to converting to materialized and
+--echo # natural join made only once
+--echo #
+
+SET @save968720_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on';
+
+CREATE TABLE t1 (a int, INDEX(a));
+INSERT INTO t1 VALUES (1);
+
+CREATE TABLE t2 (a int, INDEX(a));
+INSERT INTO t2 VALUES (1), (2);
+
+INSERT INTO t1 SELECT a FROM (SELECT a FROM test.t1) AS s1 NATURAL JOIN
+t2 AS s2;
+SELECT * FROM t1;
+
+DELETE FROM t1;
+INSERT INTO t1 VALUES (1);
+
+PREPARE stmt FROM "
+INSERT INTO t1 SELECT a FROM (SELECT a FROM test.t1) AS s1 NATURAL JOIN
+t2 AS s2;
+";
+EXECUTE stmt;
+SELECT * FROM t1;
+EXECUTE stmt;
+SELECT * FROM t1;
+
+drop table t1,t2;
+set optimizer_switch=@save968720_optimizer_switch;
+
+--echo #
+--echo # LP BUG#978847 Server crashes in Item_ref::real_item on
+--echo # INSERT .. SELECT with FROM subquery and derived_merge=ON
+SET @save978847_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on';
+
+CREATE TABLE t1 ( a INT, b INT );
+INSERT INTO t1 VALUES (2,1),(3,2);
+
+select * from t1;
+INSERT INTO t1 SELECT * FROM
+ ( SELECT * FROM t1 ) AS alias;
+select * from t1;
+prepare stmt1 from 'INSERT INTO t1 SELECT SQL_BIG_RESULT * FROM
+ ( SELECT * FROM t1 ) AS alias';
+execute stmt1;
+select * from t1;
+execute stmt1;
+select * from t1;
+
+drop table t1;
+
+set optimizer_switch=@save978847_optimizer_switch;
+
+
+--echo #
+--echo # LP bug998516 Server hangs on INSERT .. SELECT with derived_merge,
+--echo # FROM subquery, UNION
+--echo #
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (3),(4);
+INSERT INTO t1 SELECT * FROM ( SELECT * FROM t1 ) AS alias UNION SELECT * FROM t2;
+select * from t1;
+drop table t1,t2;
+
+--echo #
+--echo # MDEV-3873: Wrong result (extra rows) with NOT IN and
+--echo # a subquery from a MERGE view
+--echo #
+
+CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4),(7),(0);
+
+CREATE TABLE t2 (b INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1),(2);
+
+CREATE TABLE t3 (c INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (4),(6),(3);
+
+CREATE TABLE t4 (d INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t4 VALUES (4),(5),(3);
+
+CREATE TABLE tv (e INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO tv VALUES (1),(3);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v_temptable AS SELECT * FROM tv;
+CREATE ALGORITHM=MERGE VIEW v_merge AS SELECT * FROM tv;
+
+SELECT * FROM t1, t2
+WHERE a NOT IN ( SELECT e FROM t3 LEFT JOIN v_temptable ON (c = e) WHERE c <> b ) AND a < b;
+
+SELECT * FROM t1, t2
+WHERE a NOT IN ( SELECT e FROM t3 LEFT JOIN v_merge ON (c = e) WHERE c <> b ) AND a < b;
+
+SELECT * FROM t1, t2
+WHERE a NOT IN ( SELECT e FROM t3 LEFT JOIN (SELECT * FROM tv) as derived ON (c = e) WHERE c <> b ) AND a < b;
+
+drop view v_temptable, v_merge;
+drop table t1,t2,t3,t4,tv;
+
+--echo #
+--echo # MDEV-3912: Wrong result (extra rows) with FROM subquery inside
+--echo # ALL subquery, LEFT JOIN, derived_merge.
+--echo # (duplicate of MDEV-3873 (above))
+--echo #
+
+SET @save3912_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on,in_to_exists=on';
+
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4),(8);
+
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (7),(0);
+
+CREATE TABLE t3 (c INT, d INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (0,4),(8,6);
+
+SELECT * FROM t1
+WHERE a >= ALL (
+SELECT d FROM t2 LEFT JOIN ( SELECT * FROM t3 ) AS alias ON ( c = b )
+WHERE b >= a
+);
+set optimizer_switch=@save3912_optimizer_switch;
+drop table t1, t2, t3;
+
+--echo #
+--echo # end of 5.3 tests
+--echo #
+
+# The following command must be the last one the file
+set optimizer_switch=@exit_optimizer_switch;
+set join_cache_level=@exit_join_cache_level;
diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test
index bf4c23562cf..302fb24f18c 100644
--- a/mysql-test/t/distinct.test
+++ b/mysql-test/t/distinct.test
@@ -158,6 +158,10 @@ create table t3 (
insert into t1 values (1,'yes'), (2,'no');
insert into t2 values (1,1);
insert into t3 values (1,1);
+
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
+
EXPLAIN
SELECT DISTINCT
t1.id
@@ -195,6 +199,8 @@ WHERE
AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2));
drop table t1,t2,t3;
+set join_cache_level=@save_join_cache_level;
+
#
# Test using DISTINCT on a function that contains a group function
# This also test the case when one doesn't use all fields in GROUP BY.
@@ -614,3 +620,65 @@ SET @@sort_buffer_size = @old_sort_buffer_size;
SET @@max_heap_table_size = @old_max_heap_table_size;
--echo End of 5.1 tests
+
+#
+# test_if_equality_guarantees_uniqueness() and dates
+#
+create table t1 (a varchar(100));
+insert t1 values ('2010-10-10'), ('20101010');
+select * from t1 where a = DATE('2010-10-10');
+select distinct a from t1 where a = DATE('2010-10-10');
+explain select distinct a from t1 where a = DATE('2010-10-10');
+drop table t1;
+#
+# test_if_equality_guarantees_uniqueness() and different type combinations
+#
+--echo # date = string
+create table t1 (a date);
+insert t1 values ('2010-10-10'), ('20101010');
+explain select distinct a from t1 where a = '2010-10-10';
+drop table t1;
+--echo # double = string
+create table t1 (a double);
+insert t1 values (2), (2);
+explain select distinct a from t1 where a = '2';
+--echo # double = int
+explain select distinct a from t1 where a = 2;
+--echo # string = double
+alter table t1 modify a varchar(100);
+explain select distinct a from t1 where a = 2e0;
+drop table t1;
+
+#
+# lp:731124 Loss of precision on DISTINCT
+#
+create table t1 (f1 varchar(40));
+insert into t1 values ('2010-10-10 00:00:00.0001'),('2010-10-10 00:00:00.0002'),('2010-10-10 00:00:00.0003');
+select time(f1) from t1 ;
+select distinct time(f1) from t1 ;
+drop table t1;
+
+#
+# MDEV-3875 Wrong result (missing row) on a DISTINCT query with the same subquery in the SELECT list and GROUP BY
+# MySQL Bug#66896 Distinct not distinguishing 0 from NULL when GROUP BY is used
+#
+create table t1(i int, g int); # remove_dup_with_hash_index
+insert into t1 values (null, 1), (0, 2);
+select distinct i from t1 group by g;
+drop table t1;
+
+create table t1(i int, g blob); # remove_dup_with_compare
+insert into t1 values (null, 1), (0, 2);
+select distinct i from t1 group by g;
+drop table t1;
+
+create table t1 (a int) engine=myisam;
+insert into t1 values (0),(7);
+create table t2 (b int) engine=myisam;
+insert into t2 values (7),(0),(3);
+create algorithm=temptable view v as
+select distinct (select max(a) from t1 where alias.b = a) as field1 from t2 as alias group by field1;
+select * from v;
+select distinct (select max(a) from t1 where alias.b = a) as field1 from t2 as alias group by field1;
+drop view v;
+drop table t1, t2;
diff --git a/mysql-test/t/dyncol.test b/mysql-test/t/dyncol.test
new file mode 100644
index 00000000000..1901a998732
--- /dev/null
+++ b/mysql-test/t/dyncol.test
@@ -0,0 +1,548 @@
+#
+# Dynamic column function test
+#
+
+--echo #
+--echo # column create
+--echo #
+select hex(COLUMN_CREATE(1, NULL AS char character set utf8));
+select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8));
+select hex(COLUMN_CREATE(1, 1212 AS char character set utf8));
+select hex(COLUMN_CREATE(1, 12.12 AS char character set utf8));
+select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS char character set utf8));
+select hex(COLUMN_CREATE(1, NULL AS unsigned int));
+select hex(COLUMN_CREATE(1, 1212 AS unsigned int));
+select hex(COLUMN_CREATE(1, 7 AS unsigned int));
+select hex(COLUMN_CREATE(1, 8 AS unsigned int));
+select hex(COLUMN_CREATE(1, 127 AS unsigned int));
+select hex(COLUMN_CREATE(1, 128 AS unsigned int));
+select hex(COLUMN_CREATE(1, 12.12 AS unsigned int));
+select hex(COLUMN_CREATE(1, ~0));
+select hex(COLUMN_CREATE(1, -1));
+select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS unsigned int));
+select hex(COLUMN_CREATE(1, NULL AS int));
+select hex(COLUMN_CREATE(1, 1212 AS int));
+select hex(COLUMN_CREATE(1, 7 AS int));
+select hex(COLUMN_CREATE(1, 8 AS int));
+select hex(COLUMN_CREATE(1, 127 AS int));
+select hex(COLUMN_CREATE(1, 128 AS int));
+select hex(COLUMN_CREATE(1, 12.12 AS int));
+select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS int));
+select hex(COLUMN_CREATE(1, NULL AS double));
+select hex(COLUMN_CREATE(1, 1212 AS double));
+select hex(COLUMN_CREATE(1, 12.12 AS double));
+select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS double));
+select hex(COLUMN_CREATE(1, NULL AS decimal));
+select hex(COLUMN_CREATE(1, 1212 AS decimal));
+select hex(COLUMN_CREATE(1, 7 AS decimal));
+select hex(COLUMN_CREATE(1, 8 AS decimal));
+select hex(COLUMN_CREATE(1, 127 AS decimal));
+select hex(COLUMN_CREATE(1, 128 AS decimal));
+select hex(COLUMN_CREATE(1, 12.12 AS decimal));
+select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS decimal));
+select hex(COLUMN_CREATE(1, NULL AS date));
+select hex(COLUMN_CREATE(1, "2011-04-05" AS date));
+select hex(COLUMN_CREATE(1, NULL AS time));
+select hex(COLUMN_CREATE(1, "0:45:49.000001" AS time));
+select hex(COLUMN_CREATE(1, NULL AS datetime));
+select hex(COLUMN_CREATE(1, "2011-04-05 0:45:49.000001" AS datetime));
+select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8,
+ 2, 1212 AS unsigned int,
+ 3, 1212 AS int,
+ 4, 12.12 AS double,
+ 4+1, 12.12 AS decimal,
+ 6, "2011-04-05" AS date,
+ 7, "- 0:45:49.000001" AS time,
+ 8, "2011-04-05 0:45:49.000001" AS datetime));
+explain extended
+select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8,
+ 2, 1212 AS unsigned int,
+ 3, 1212 AS int,
+ 4, 12.12 AS double,
+ 4+1, 12.12 AS decimal,
+ 6, "2011-04-05" AS date,
+ 7, "- 0:45:49.000001" AS time,
+ 8, "2011-04-05 0:45:49.000001" AS datetime));
+select hex(column_create(1, 0.0 AS decimal));
+select hex(column_create(1, 1.0 AS decimal));
+
+--echo #
+--echo # column get uint
+--echo #
+select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int);
+explain extended
+select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int);
+explain extended
+select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned);
+select column_get(column_create(1, 1212 AS decimal), 1 as unsigned int);
+select column_get(column_create(1, 1212 AS double), 1 as unsigned int);
+select column_get(column_create(1, 1212 AS int), 1 as unsigned int);
+select column_get(column_create(1, "1212" AS char), 1 as unsigned int);
+select column_get(column_create(1, "2011-04-05" AS date), 1 as unsigned int);
+select column_get(column_create(1, "8:46:06.23434" AS time), 1 as unsigned int);
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as unsigned int);
+select column_get(column_create(1, NULL AS unsigned int), 1 as unsigned int);
+--echo # column geint truncation & warnings
+select column_get(column_create(1, -1212 AS int), 1 as unsigned int);
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as unsigned int);
+select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as unsigned int);
+select column_get(column_create(1, -1 AS decimal), 1 as unsigned int);
+--replace_result e+029 e+29
+select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as unsigned int);
+select column_get(column_create(1, 999.9 AS double), 1 as unsigned int);
+select column_get(column_create(1, -1 AS double), 1 as unsigned int);
+select column_get(column_create(1, "1212III" AS char), 1 as unsigned int);
+
+--echo #
+--echo # column get int
+--echo #
+select column_get(column_create(1, 1212 AS int), 1 as int);
+explain extended
+select column_get(column_create(1, 1212 AS int), 1 as int);
+explain extended
+select column_get(column_create(1, 1212 AS int), 1 as signed int);
+select column_get(column_create(1, -1212 AS int), 1 as int);
+select column_get(column_create(1, 1212 AS decimal), 1 as int);
+select column_get(column_create(1, 1212 AS double), 1 as int);
+select column_get(column_create(1, 1212 AS unsigned int), 1 as int);
+select column_get(column_create(1, "1212" AS char), 1 as int);
+select column_get(column_create(1, "-1212" AS char), 1 as int);
+select column_get(column_create(1, "2011-04-05" AS date), 1 as int);
+select column_get(column_create(1, "8:46:06.23434" AS time), 1 as int);
+select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as int);
+select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as int);
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as int);
+select column_get(column_create(1, NULL AS int), 1 as int);
+--echo #column gett truncation & warnings
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as int);
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as int);
+select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as int);
+select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as int);
+select column_get(column_create(1, 999.9 AS double), 1 as int);
+--replace_result e+029 e+29
+select column_get(column_create(1, -99999999999999999999999999999 AS double), 1 as int);
+select column_get(column_create(1, "-1212III" AS char), 1 as int);
+select column_get(column_create(1, "1212III" AS char), 1 as int);
+select column_get(COLUMN_CREATE(1, ~0), 1 as signed);
+select column_get(COLUMN_CREATE(1, ~0), 1 as unsigned);
+select column_get(COLUMN_CREATE(1, -1), 1 as signed);
+select column_get(COLUMN_CREATE(1, -1), 1 as unsigned);
+
+--echo #
+--echo #column get char
+--echo #
+select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8);
+explain extended
+select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8);
+select column_get(column_create(1, 1212 AS unsigned int), 1 as char charset utf8);
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as char charset utf8);
+select column_get(column_create(1, 1212 AS int), 1 as char charset utf8);
+select column_get(column_create(1, -1212 AS int), 1 as char charset utf8);
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as char charset utf8);
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as char charset utf8);
+select column_get(column_create(1, 1212.12 AS decimal), 1 as char charset utf8);
+select column_get(column_create(1, 1212.12 AS double), 1 as char charset utf8);
+select column_get(column_create(1, "2011-04-05" AS date), 1 as char charset utf8);
+select column_get(column_create(1, "8:46:06.23434" AS time), 1 as char charset utf8);
+select column_get(column_create(1, "8:46:06.23434" AS time(0)), 1 as char charset utf8);
+select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as char charset utf8);
+select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as char charset utf8);
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as char charset utf8);
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(0)), 1 as char charset utf8);
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as char charset utf8);
+select column_get(column_create(1, NULL AS char charset utf8), 1 as char charset utf8);
+select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary);
+explain extended
+select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary);
+
+--echo #
+--echo # column get real
+--echo #
+select column_get(column_create(1, 1212.12 AS double), 1 as double);
+explain extended
+select column_get(column_create(1, 1212.12 AS double), 1 as double);
+explain extended
+select column_get(column_create(1, 1212.12 AS double), 1 as double(6,2));
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as double);
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as double);
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as double);
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as double);
+select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as double);
+select column_get(column_create(1, "2011-04-05" AS date), 1 as double);
+select column_get(column_create(1, "8:46:06.23434" AS time), 1 as double);
+select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as double);
+select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as double);
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double);
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as double);
+# The replace result is needed for windows.
+select round(column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double(20,6)),3);
+select column_get(column_create(1, NULL AS double), 1 as double);
+
+-- echo # column get real truncation & warnings
+select column_get(column_create(1, "1223.5aa" AS char), 1 as double);
+select column_get(column_create(1, "aa" AS char), 1 as double);
+select column_get(column_create(1, "1223.5555" AS double), 1 as double(5,2));
+select column_get(column_create(1, "1223.5555" AS double), 1 as double(3,2));
+
+--echo #
+--echo # column get decimal
+--echo #
+select column_get(column_create(1, 1212.12 AS double), 1 as decimal);
+select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2));
+explain extended
+select column_get(column_create(1, 1212.12 AS double), 1 as decimal);
+explain extended
+select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2));
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal(20,0));
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal(32,0));
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal(32,0));
+select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as decimal(40,10));
+select column_get(column_create(1, "2011-04-05" AS date), 1 as decimal(32,6));
+select column_get(column_create(1, "8:46:06.23434" AS time), 1 as decimal(32,6));
+select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as decimal(32,6));
+select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as decimal(32,6));
+select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime), 1 as decimal(32,6));
+select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime(6)), 1 as decimal(32,6));
+select column_get(column_create(1, "2011-04-05 8:46:06.12345678" AS datetime(6)), 1 as decimal(32,8));
+select column_get(column_create(1, NULL as decimal), 1 as decimal(32,10));
+select column_get(column_create(1, "1223.5555" as decimal(10,5)), 1 as decimal(6,2));
+
+-- echo # column get decimal truncation & warnings
+select column_get(column_create(1, "1223.5aa" AS char), 1 as decimal(32,10));
+select column_get(column_create(1, "aa" AS char), 1 as decimal(32,10));
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal);
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal);
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal);
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as decimal);
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as decimal);
+select column_get(column_create(1, "1223.5555" as double), 1 as decimal(5,2));
+select column_get(column_create(1, "-1223.5555" as double), 1 as decimal(5,2));
+select column_get(column_create(1, "1223.5555" AS double), 1 as decimal(3,2));
+select column_get(column_create(1, "1223.5555" AS decimal(10,5)), 1 as decimal(3,2));
+select column_get(column_create(1, 0.0 AS decimal,2, 0.0 as decimal), 1 as decimal);
+
+--echo #
+--echo # column get datetime
+--echo #
+select column_get(column_create(1, 20010203101112.121314 as double), 1 as datetime);
+select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as datetime);
+select column_get(column_create(1, 20010203101112 as unsigned int), 1 as datetime);
+select column_get(column_create(1, 20010203101112 as int), 1 as datetime);
+select column_get(column_create(1, "20010203101112" as char), 1 as datetime);
+select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as datetime);
+select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as datetime);
+select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as datetime);
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime);
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(0));
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(6));
+select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as datetime);
+select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as datetime);
+
+select column_get(column_create(1, 20010203 as unsigned int), 1 as datetime);
+select column_get(column_create(1, 20010203 as int), 1 as datetime);
+select column_get(column_create(1, 20010203), 1 as datetime);
+select column_get(column_create(1, 20010203.0), 1 as datetime);
+select column_get(column_create(1, 20010203.0 as double), 1 as datetime);
+select column_get(column_create(1, "2001-02-03"), 1 as datetime);
+select column_get(column_create(1, "20010203"), 1 as datetime);
+select column_get(column_create(1, 0), 1 as datetime);
+select column_get(column_create(1, "2001021"), 1 as datetime);
+
+select column_get(column_create(1, "8:46:06.23434" AS time), 1 as datetime);
+select column_get(column_create(1, "-808:46:06.23434" AS time), 1 as datetime);
+
+set @@sql_mode="allow_invalid_dates";
+select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as datetime);
+select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as datetime);
+select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as datetime);
+set @@sql_mode="";
+
+-- echo # column get datetime truncation & warnings
+select column_get(column_create(1, "1223.5aa" AS char), 1 as datetime);
+--replace_result e+019 e+19
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as datetime);
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as datetime);
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as datetime);
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as datetime);
+--replace_result e+029 e+29
+select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as datetime);
+select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as datetime);
+select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as datetime);
+select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as datetime);
+select column_get(column_create(1, "20010231"), 1 as datetime);
+select column_get(column_create(1, "0" AS CHAR), 1 as datetime);
+
+
+--echo #
+--echo # column get date
+--echo #
+select column_get(column_create(1, 20010203101112.121314 as double), 1 as date);
+select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as date);
+select column_get(column_create(1, 20010203101112 as unsigned int), 1 as date);
+select column_get(column_create(1, 20010203101112 as int), 1 as date);
+select column_get(column_create(1, "20010203101112" as char), 1 as date);
+select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as date);
+select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as date);
+select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as date);
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as date);
+select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as date);
+select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as date);
+
+select column_get(column_create(1, 20010203 as unsigned int), 1 as date);
+select column_get(column_create(1, 20010203 as int), 1 as date);
+select column_get(column_create(1, 20010203), 1 as date);
+select column_get(column_create(1, 20010203.0), 1 as date);
+select column_get(column_create(1, 20010203.0 as double), 1 as date);
+select column_get(column_create(1, "2001-02-03"), 1 as date);
+select column_get(column_create(1, "20010203"), 1 as date);
+select column_get(column_create(1, 0), 1 as date);
+select column_get(column_create(1, "2001021"), 1 as date);
+
+set @@sql_mode="allow_invalid_dates";
+select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as date);
+select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as date);
+select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as date);
+set @@sql_mode="";
+
+-- echo # column get date truncation & warnings
+select column_get(column_create(1, "1223.5aa" AS char), 1 as date);
+--replace_result e+019 e+19
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as date);
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as date);
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as date);
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as date);
+--replace_result e+029 e+29
+select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as date);
+select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as date);
+select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as date);
+select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as date);
+select column_get(column_create(1, "20010231"), 1 as date);
+select column_get(column_create(1, "0" AS CHAR), 1 as date);
+
+--echo #
+--echo # column get time
+--echo #
+select column_get(column_create(1, 20010203101112.121314 as double), 1 as time);
+select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as time);
+select column_get(column_create(1, 20010203101112 as unsigned int), 1 as time);
+select column_get(column_create(1, 8080102 as unsigned int), 1 as time);
+select column_get(column_create(1, 20010203101112 as int), 1 as time);
+select column_get(column_create(1, -8080102 as int), 1 as time);
+select column_get(column_create(1, "20010203101112" as char), 1 as time);
+select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as time);
+select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time);
+select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time(6));
+select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as time);
+select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as time(6));
+select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as time(6));
+select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as time(6));
+select column_get(column_create(1, "830:46:06.23434" AS CHAR), 1 as time(6));
+select column_get(column_create(1, "830:46:06" AS CHAR), 1 as time(6));
+select cast("-830:46:06.23434" AS time(6));
+select 1,cast("-830:46:06.23434" AS time(6));
+select hex(column_create(1, "-830:46:06.23434" AS CHAR));
+select column_get(column_create(1, "-830:46:06.23434" AS CHAR), 1 as time(6));
+select column_get(column_create(1, "0" AS CHAR), 1 as time);
+select column_get(column_create(1, "6" AS CHAR), 1 as time);
+select column_get(column_create(1, "1:6" AS CHAR), 1 as time);
+select column_get(column_create(1, "2:1:6" AS CHAR), 1 as time);
+
+select column_get(column_create(1, 0), 1 as time);
+select column_get(column_create(1, "2001021"), 1 as time);
+
+set @@sql_mode="allow_invalid_dates";
+select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as time);
+set @@sql_mode="";
+
+-- echo # column get date truncation & warnings
+select column_get(column_create(1, "1223.5aa" AS char), 1 as time);
+select column_get(column_create(1, "1223.5aa" AS char), 1 as time(3));
+--replace_result e+019 e+19
+select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as time);
+select column_get(column_create(1, 9223372036854775807 AS int), 1 as time);
+select column_get(column_create(1, -9223372036854775808 AS int), 1 as time);
+select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as time);
+--replace_result e+029 e+29
+select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as time);
+select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as time);
+select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as time);
+select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as time);
+select column_get(column_create(1, "2001-02-03"), 1 as time);
+select column_get(column_create(1, "20010203"), 1 as time);
+
+
+-- echo # column add
+select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer));
+select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer));
+select hex(column_add(column_create(1, 1212 as integer), 1, NULL as integer));
+select hex(column_add(column_create(1, 1212 as integer), 2, NULL as integer));
+select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer));
+select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 1 as integer);
+select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 2 as integer);
+select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer, 2, 11 as integer));
+select hex(column_add(column_create(1, NULL as integer), 1, 1212 as integer, 2, 11 as integer));
+select hex(column_add(column_create(1, 1212 as integer, 2, 1212 as integer), 1, 11 as integer));
+select hex(column_add(column_create(1, 1), 1, null));
+select column_list(column_add(column_create(1, 1), 1, null));
+select column_list(column_add(column_create(1, 1), 1, ""));
+select hex(column_add("", 1, 1));
+
+-- echo # column delete
+select hex(column_delete(column_create(1, 1212 as integer, 2, 1212 as integer), 1));
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2));
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 3));
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 4));
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 1));
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 3));
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3));
+select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3, 10));
+select hex(column_delete(column_create(1, 1), 1));
+select hex(column_delete("", 1));
+
+-- echo # column exists
+select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 1);
+select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 4);
+
+-- echo # column list
+select column_list(column_create(1, 1212 as integer, 2, 1212 as integer));
+select column_list(column_create(1, 1212 as integer));
+select column_list(column_create(1, NULL as integer));
+
+--echo #
+--echo # check error handling
+--echo #
+--error ER_DYN_COL_DATA
+select HEX(COLUMN_CREATE(1, 5, 1, 5));
+--error 1064
+select HEX(COLUMN_CREATE("", 1, 5, 1, 5));
+--error ER_DYN_COL_WRONG_FORMAT
+select COLUMN_LIST("a");
+--error ER_DYN_COL_WRONG_FORMAT
+select column_delete("a", 1);
+select hex(column_delete("", 1));
+--error ER_DYN_COL_DATA
+select hex(column_delete("", -1));
+--error ER_DYN_COL_DATA
+select hex(column_create(-1, 1));
+--error ER_DYN_COL_DATA
+select hex(column_create(65536, 1));
+--error ER_DYN_COL_DATA
+select hex(column_add("", -1, 1));
+--error ER_DYN_COL_DATA
+select hex(column_add("", 65536, 1));
+select hex(column_get("", -1 as int));
+
+--echo #
+--echo # Test with table
+--echo #
+
+# create table with 'str' to hold a set of dynamic columns
+create table t1 (id int primary key, str mediumblob);
+insert into t1 values (1, ''), (2, ''), (3, ''), (4, ''), (5, null);
+
+# Selecting a non existing column
+select id, str, column_get(str, 1 as int) from t1;
+
+# Add some dynamic columns. One and do it with create or add.
+update t1 set str=column_create(1, id, 2, "a") where id < 3;
+update t1 set str=column_add(str, 1, id, 2, "b") where id >= 4;
+
+# Show some data, if it exists
+select id, column_get(str, 1 as int), column_get(str, 2 as char) from t1 where column_exists(str,1) or column_exists(str,2);
+
+# Add data to row 5 and 6
+update t1 set str=column_create(1, id, 10, "test") where id = 5;
+insert into t1 values (6, column_create(10, "test2"));
+
+# Update some of the columns and add a new column 3
+update t1 set str=column_add(str, 2, 'c', 1, column_get(str, 1 as int) + 1, 3, 100) where id > 2;
+
+# Check data
+select id, length(str), column_get(str, 1 as int), column_get(str, 2 as char), column_get(str, 3 as int) from t1;
+
+# You can do anything with the columns, like SUM() or GROUP
+select column_get(str, 2 as char), sum(column_get(str, 1 as int)) from t1 group by column_get(str, 2 as char);
+select column_get(str, 2 as char), sum(column_get(str, 1 as int)) from t1 where column_exists(str, 2) <> 0 group by 1;
+select sum(column_get(str, 1 as int)) from t1 group by column_get(str, 2 as char) order by sum(column_get(str, 1 as int)) desc;
+select sum(column_get(str, 1 as int)) from t1 group by column_get(str, 2 as char) having sum(column_get(str, 1 as int)) > 2;
+select sum(column_get(str, 1 as int)) from t1 where column_get(str, 3 as int) > 50 group by column_get(str, 2 as char);
+
+# Deleting of column
+select id, column_list(str) from t1 where id= 5;
+update t1 set str=column_delete(str, 3, 4, 2) where id= 5;
+
+select id, length(str), column_list(str), column_get(str, 1 as int), column_get(str, 2 as char), column_get(str, 3 as int) from t1;
+
+update t1 set str=column_add(str, 4, 45 as char, 2, 'c') where id= 5;
+select id, length(str), column_list(str), column_get(str, 1 as int), column_get(str, 2 as char), column_get(str, 3 as int) from t1 where id = 5;
+
+# Check which column exists
+select id, length(str), column_list(str), column_exists(str, 4) from t1;
+select sum(column_get(str, 1 as int)), column_list(str) from t1 group by 2;
+select id, hex(str) from t1;
+
+# Check with a bit larger strings
+
+update t1 set str=column_add(str, 4, repeat("a", 100000)) where id=5;
+select id from t1 where column_get(str,4 as char(100000)) = repeat("a", 100000);
+select id from t1 where column_get(str,4 as char(100)) = repeat("a", 100);
+update t1 set str=column_add(str, 4, repeat("b", 10000)) where id=5;
+select id from t1 where column_get(str,4 as char(100000)) = repeat("b", 10000);
+update t1 set str=column_add(str, 4, repeat("c", 100)) where id=5;
+select id from t1 where column_get(str,4 as char(100000)) = repeat("c", 100);
+update t1 set str=column_add(str, 4, repeat("d", 10000)) where id=5;
+select id from t1 where column_get(str,4 as char(100000)) = repeat("d", 10000);
+update t1 set str=column_add(str, 4, repeat("e", 10), 5, repeat("f", 100000)) where id=5;
+select id from t1 where column_get(str,5 as char(100000)) = repeat("f", 100000);
+select id, column_list(str), length(str) from t1 where id=5;
+update t1 set str=column_delete(str, 5) where id=5;
+select id, column_list(str), length(str) from t1 where id=5;
+
+drop table t1;
+
+--echo #
+--echo # LP#778905: Assertion `value->year <= 9999' failed in
+--echo # dynamic_column_date_store
+--echo #
+
+--error ER_DYN_COL_WRONG_FORMAT
+SELECT COLUMN_GET( 'a' , 2 AS DATE );
+--error ER_DYN_COL_WRONG_FORMAT
+SELECT COLUMN_CREATE( 1 , COLUMN_GET( 'a' , 2 AS DATE ) );
+
+--echo #
+--echo # LP#778912: Assertion `field_pos < field_count' failed in
+--echo # Protocol_text::store in maria-5.3-mwl34
+--echo #
+
+CREATE TABLE t1 ( f1 blob );
+INSERT INTO t1 VALUES (NULL);
+INSERT INTO t1 SET f1 = COLUMN_CREATE( 2 , 'cde' );
+SELECT HEX(COLUMN_ADD(f1, 1, 'abc')), COLUMN_LIST(f1) FROM t1;
+
+# Don't print strange characters on screen
+--disable_result_log
+SELECT COLUMN_ADD(f1, 1, 'abc'), COLUMN_LIST(f1) FROM t1;
+--enable_result_log
+DROP TABLE t1;
+
+--echo #
+--echo # Some dynamic strings that caused crashes in the past
+--echo #
+
+set @a=0x0102000200030004000F0D086B74697A6A7176746F6B687563726A746E7A746A666163726C6F7A6B62636B6B756B666779666977617369796F67756C726D62677A72756E63626D78636D7077706A6F736C6D636464696770786B6371637A6A6A6463737A6A676879716462637178646C666E6B6C726A637677696E7271746C616D646368687A6C707869786D666F666261797470616A63797673737A796D74747475666B717573687A79696E7276706F796A6E767361796A6F6D646F6378677A667074746363736A796D67746C786F697873686464616265616A7A6F7168707A6B776B6376737A6B72666C6F666C69636163686F6B666D627166786A71616F;
+--error ER_DYN_COL_WRONG_FORMAT
+select column_add(@a, 3, "a");
+
+--echo #
+--echo # LP#781233 mysqld: decimal.c:1459: decimal_bin_size:
+--echo # Assertion `scale >= 0 && precision > 0 && scale <= precision' ...
+--echo #
+
+set @a=0x00020008000009000C2C010080;
+select COLUMN_GET(@a, 9 AS DECIMAL);
+select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL)));
+select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL(19,0))));
+
+select hex(COLUMN_CREATE(0, COLUMN_GET(COLUMN_CREATE(0, 0.0 as decimal), 0 as decimal)));
+select hex(COLUMN_CREATE(0, 0.0 as decimal));
diff --git a/mysql-test/t/error_simulation.test b/mysql-test/t/error_simulation.test
index 95ec2c5b21d..5dcc1fa9dcf 100644
--- a/mysql-test/t/error_simulation.test
+++ b/mysql-test/t/error_simulation.test
@@ -78,6 +78,9 @@ INSERT INTO t2 VALUES (1, 1, 'data');
--echo # we would need to have thousands of records and/or more columns in both
--echo # tables so that the join buffer is filled and re-scans are triggered).
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
SET SESSION debug = '+d,only_one_Unique_may_be_created';
--replace_column 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x
@@ -87,6 +90,8 @@ SELECT * FROM t1 LEFT JOIN t2 ON ( t2.a < 10 OR t2.b < 10 );
SET SESSION debug = DEFAULT;
+SET optimizer_switch=@save_optimizer_switch;
+
DROP TABLE t1, t2;
@@ -97,7 +102,8 @@ CREATE TABLE t1(f1 INT, KEY(f1));
CREATE TABLE t2(f1 INT);
INSERT INTO t1 VALUES (1),(2);
INSERT INTO t2 VALUES (1),(2);
-SET SESSION debug='d,bug11747970_simulate_error';
+SET SESSION debug="+d,bug11747970_raise_error";
+--error 1105
INSERT IGNORE INTO t2 SELECT f1 FROM t1 a WHERE NOT EXISTS (SELECT 1 FROM t2 b WHERE a.f1 = b.f1);
SET SESSION debug = DEFAULT;
DROP TABLE t1,t2;
diff --git a/mysql-test/t/errors.test b/mysql-test/t/errors.test
index b426d9fd5b0..b6aeee63677 100644
--- a/mysql-test/t/errors.test
+++ b/mysql-test/t/errors.test
@@ -85,3 +85,12 @@ INSERT INTO t2 VALUES (1,0) ON DUPLICATE KEY UPDATE
INSERT INTO t2(a,b) VALUES (1,0) ON DUPLICATE KEY UPDATE
b=(SELECT VALUES(a)+2 FROM t1);
DROP TABLE t1, t2;
+
+--echo #
+--echo # MDEV-492: incorrect error check before sending OK in mysql_update
+--echo #
+CREATE TABLE t1 (a CHAR(3), b BLOB);
+--error ER_DYN_COL_DATA
+UPDATE t1 SET a = 'new'
+WHERE COLUMN_CREATE( 1, 'v', 1, 'w' ) IS NULL;
+drop table t1;
diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test
index f516ec6ab03..3e585656ba9 100644
--- a/mysql-test/t/explain.test
+++ b/mysql-test/t/explain.test
@@ -157,13 +157,15 @@ CREATE TABLE t1 (f1 INT not null);
SELECT @@session.sql_mode INTO @old_sql_mode;
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
-# EXPLAIN EXTENDED (with subselect). used to crash.
-# This is actually a valid query for this sql_mode,
-# but it was transformed in such a way that it failed, see
-# Bug#12329653 - EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+# EXPLAIN EXTENDED (with subselect). used to crash. should give NOTICE.
+# Before moving max/min optimization to optimize phase this statement
+# generated error, but as far as original query do not contain aggregate
+# function user should not see error
+# --error ER_MIX_OF_GROUP_FUNC_AND_FIELDS
EXPLAIN EXTENDED SELECT 1 FROM t1
WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
+SHOW WARNINGS;
SET SESSION sql_mode=@old_sql_mode;
DROP TABLE t1;
@@ -178,6 +180,8 @@ create table t2 (dt datetime not null);
insert into t1 values ('2001-01-01 1:1:1', '1:1:1'),
('2001-01-01 1:1:1', '1:1:1');
insert into t2 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1');
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
flush tables;
EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
flush tables;
@@ -186,6 +190,7 @@ flush tables;
EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
flush tables;
SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+SET join_cache_level=@save_join_cache_level;
drop tables t1, t2;
--echo #
@@ -238,12 +243,12 @@ FULLTEXT KEY(f1),UNIQUE(f1));
INSERT INTO t1 VALUES ('test');
EXPLAIN SELECT 1 FROM t1
-WHERE 1 > ALL((SELECT 1 FROM t1 JOIN t1 a ON (MATCH(t1.f1) AGAINST (""))
+WHERE 1 > ALL((SELECT t1.f1 FROM t1 JOIN t1 a ON (MATCH(t1.f1) AGAINST (""))
WHERE t1.f1 GROUP BY t1.f1));
PREPARE stmt FROM
'EXPLAIN SELECT 1 FROM t1
- WHERE 1 > ALL((SELECT 1 FROM t1 RIGHT OUTER JOIN t1 a
+ WHERE 1 > ALL((SELECT t1.f1 FROM t1 RIGHT OUTER JOIN t1 a
ON (MATCH(t1.f1) AGAINST (""))
WHERE t1.f1 GROUP BY t1.f1))';
@@ -254,7 +259,7 @@ DEALLOCATE PREPARE stmt;
PREPARE stmt FROM
'EXPLAIN SELECT 1 FROM t1
- WHERE 1 > ALL((SELECT 1 FROM t1 JOIN t1 a
+ WHERE 1 > ALL((SELECT t1.f1 FROM t1 JOIN t1 a
ON (MATCH(t1.f1) AGAINST (""))
WHERE t1.f1 GROUP BY t1.f1))';
@@ -266,3 +271,22 @@ DEALLOCATE PREPARE stmt;
DROP TABLE t1;
--echo End of 5.1 tests.
+
+--echo #
+--echo # Bug#776295: EXPLAIN EXTENDED with always false multiple equality
+--echo # in the WHERE condition of a derived table
+--echo #
+
+CREATE TABLE t1 (a int) ;
+
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (8);
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+EXPLAIN EXTENDED
+SELECT * FROM ( SELECT t1.a FROM t1,t2 WHERE t2.a = t1.a ) AS t;
+set optimizer_switch=@tmp_optimizer_switch;
+
+DROP TABLE t1,t2;
+
diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test
index f27d4cf2fad..b0d685e2b41 100644
--- a/mysql-test/t/flush.test
+++ b/mysql-test/t/flush.test
@@ -28,7 +28,7 @@ enable_query_log;
connection con1;
select * from t1;
connection con2;
-flush tables with read lock;
+flush tables with read lock and disable checkpoint;
--error 1223
drop table t2;
connection con1;
diff --git a/mysql-test/t/flush_read_lock_kill.test b/mysql-test/t/flush_read_lock_kill.test
index 2d359383949..ada73755067 100644
--- a/mysql-test/t/flush_read_lock_kill.test
+++ b/mysql-test/t/flush_read_lock_kill.test
@@ -57,7 +57,7 @@ connection con1;
# debug build running without our --debug=make_global..., will be
# error 0 (no error). The only important thing to test is that on
# debug builds with our --debug=make_global... we don't hang forever.
---error 0,1317,2013
+--error 0,ER_CONNECTION_KILLED,2013
reap;
connection con2;
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index 7af9d3706e6..11cb4eedf05 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -428,6 +428,8 @@ DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(255), b INT, FULLTEXT(a), KEY(b));
INSERT INTO t1 VALUES('test', 1),('test', 1),('test', 1),('test', 1),
('test', 1),('test', 2),('test', 3),('test', 4);
+INSERT INTO t1 VALUES('test', 5),('test', 6),('test', 7),('test', 8),
+ ('test', 5),('test', 6),('test', 7),('test', 8);
EXPLAIN SELECT * FROM t1
WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
diff --git a/mysql-test/t/fulltext_left_join.test b/mysql-test/t/fulltext_left_join.test
index 8c13ae5cad9..3a81c1a5d1b 100644
--- a/mysql-test/t/fulltext_left_join.test
+++ b/mysql-test/t/fulltext_left_join.test
@@ -98,3 +98,16 @@ INSERT INTO t1 VALUES(1);
INSERT INTO t2(b,c) VALUES(2,'castle'),(3,'castle');
SELECT * FROM t1 LEFT JOIN t2 ON a=b WHERE MATCH(c) AGAINST('+castle' IN BOOLEAN MODE);
DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#906357: Incorrect result with outer join and full text match
+--echo #
+CREATE TABLE t1(f1 VARCHAR(6) NOT NULL, FULLTEXT KEY(f1), UNIQUE(f1));
+INSERT INTO t1 VALUES ('test');
+
+CREATE TABLE t2(f2 VARCHAR(6) NOT NULL, FULLTEXT KEY(f2), UNIQUE(f2));
+INSERT INTO t2 VALUES ('test');
+SELECT * FROM t2 LEFT OUTER JOIN t1 ON (MATCH(f1) against (""));
+SELECT * FROM t1 RIGHT OUTER JOIN t2 ON (MATCH(f1) against (""));
+
+DROP table t1,t2;
diff --git a/mysql-test/t/fulltext_order_by.test b/mysql-test/t/fulltext_order_by.test
index 814cd4a5954..0f800e5c077 100644
--- a/mysql-test/t/fulltext_order_by.test
+++ b/mysql-test/t/fulltext_order_by.test
@@ -28,8 +28,8 @@ SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) FROM t1 WHERE a=7 and MATC
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY 1;
# ORDER BY MATCH
-SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) as rel FROM t1 ORDER BY rel;
-SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel;
+SELECT IF(a=7,'steve-is-cool',IF(a=4,'cool', 'other')), FORMAT(MATCH (message) AGAINST ('steve'),6) as rel FROM t1 ORDER BY rel;
+SELECT IF(a=7,'match',IF(a=4,'match', 'no-match')), MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel;
#
# BUG#6635 - test_if_skip_sort_order() thought it can skip filesort
diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test
index 927c4b084da..3e31c61ac37 100644
--- a/mysql-test/t/func_group.test
+++ b/mysql-test/t/func_group.test
@@ -138,6 +138,8 @@ insert into t2 values('AAA', 10, 0.5);
insert into t2 values('BBB', 20, 1.0);
select t1.a1, t1.a2, t2.a1, t2.a2 from t1,t2;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select max(t1.a1), max(t2.a1) from t1, t2 where t2.a2=9;
select max(t2.a1), max(t1.a1) from t1, t2 where t2.a2=9;
select t1.a1, t1.a2, t2.a1, t2.a2 from t1 left outer join t2 on t1.a1=10;
@@ -146,6 +148,7 @@ select max(t2.a1) from t2 left outer join t1 on t2.a2=10 where t2.a2=20;
select max(t2.a1) from t2 left outer join t1 on t2.a2=10 where t2.a2=10;
select max(t2.a1) from t1 left outer join t2 on t1.a2=t2.a1 and 1=0 where t2.a1='AAA';
select max(t1.a2),max(t2.a1) from t1 left outer join t2 on t1.a1=10;
+SET optimizer_switch=@save_optimizer_switch;
drop table t1,t2;
#
@@ -1063,7 +1066,8 @@ insert into t1 values
(02,2002,20020101,"2002-01-01 23:59:59"),
(60,2060,20600101,"2060-01-01 11:11:11"),
(70,1970,19700101,"1970-11-11 22:22:22"),
- (NULL,NULL,NULL,NULL);
+ (NULL,NULL,NULL,NULL),
+ (71,1971,19710101,"1971-11-11 22:22:22");
select min(f1),max(f1) from t1;
select min(f2),max(f2) from t1;
select min(f3),max(f3) from t1;
@@ -1138,10 +1142,7 @@ INSERT INTO t1 VALUES (0000),(2001);
--disable_metadata
DROP TABLE t1;
-
--echo #
---echo End of 5.1 tests
-
--echo # LP BUG#813418 - incorrect optimisation of max/min by index for
--echo # negated BETWEEN
CREATE TABLE t1 (a int, KEY (a));
@@ -1150,6 +1151,9 @@ SELECT MAX(a) FROM t1 WHERE a NOT BETWEEN 3 AND 9;
drop table t1;
--echo #
+--echo End of 5.1 tests
+
+--echo #
--echo # Bug #904345: MIN/MAX optimization with constant FALSE condition
--echo #
@@ -1228,3 +1232,143 @@ DROP TABLE t1;
--echo End of 5.2 tests
+
+--echo #
+--echo # BUG#46680 - Assertion failed in file item_subselect.cc,
+--echo # line 305 crashing on HAVING subquery
+--echo #
+
+--echo # Create tables
+--echo #
+
+CREATE TABLE t1 (
+ pk INT,
+ v VARCHAR(1) DEFAULT NULL,
+ PRIMARY KEY(pk)
+);
+CREATE TABLE t2 LIKE t1;
+CREATE TABLE t3 LIKE t1;
+CREATE TABLE empty1 (a int);
+
+INSERT INTO t1 VALUES (1,'c'),(2,NULL);
+INSERT INTO t2 VALUES (3,'m'),(4,NULL);
+INSERT INTO t3 VALUES (1,'n');
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+
+--echo
+--echo #
+--echo # 1) Test that subquery materialization is setup for query with
+--echo # premature optimize() exit due to "Impossible WHERE"
+--echo #
+SELECT MIN(t2.pk)
+FROM t2 JOIN t1 ON t1.pk=t2.pk
+WHERE 'j'
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+
+--echo
+EXPLAIN
+SELECT MIN(t2.pk)
+FROM t2 JOIN t1 ON t1.pk=t2.pk
+WHERE 'j'
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+
+--echo
+--echo #
+--echo # 2) Test that subquery materialization is setup for query with
+--echo # premature optimize() exit due to "No matching min/max row"
+--echo #
+SELECT MIN(t2.pk)
+FROM t2
+WHERE t2.pk>10
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+
+--echo
+EXPLAIN
+SELECT MIN(t2.pk)
+FROM t2
+WHERE t2.pk>10
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+
+--echo
+--echo #
+--echo # 3) Test that subquery materialization is setup for query with
+--echo # premature optimize() exit due to "Select tables optimized away"
+--echo #
+SELECT MIN(pk)
+FROM t1
+WHERE pk=NULL
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+
+--echo
+EXPLAIN
+SELECT MIN(pk)
+FROM t1
+WHERE pk=NULL
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+
+--echo
+--echo #
+--echo # 4) Test that subquery materialization is setup for query with
+--echo # premature optimize() exit due to "No matching row in const table"
+--echo #
+--echo
+SELECT MIN(a)
+FROM (SELECT a FROM empty1) tt
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+
+--echo
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+EXPLAIN
+SELECT MIN(a)
+FROM (SELECT a FROM empty1) tt
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+set optimizer_switch=@tmp_optimizer_switch;
+
+--echo
+--echo #
+--echo # 5) Test that subquery materialization is setup for query with
+--echo # premature optimize() exit due to "Impossible WHERE noticed
+--echo # after reading const tables"
+--echo #
+SELECT min(t1.pk)
+FROM t1
+WHERE t1.pk IN (SELECT 1 from t3 where pk>10)
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+
+--echo
+EXPLAIN
+SELECT min(t1.pk)
+FROM t1
+WHERE t1.pk IN (SELECT 1 from t3 where pk>10)
+HAVING ('m') IN (
+SELECT v
+FROM t2);
+
+set @@optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # Cleanup for BUG#46680
+--echo #
+DROP TABLE IF EXISTS t1,t2,t3,empty1;
+
diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test
index 0d51b95ebe4..be7fb0f63c1 100644
--- a/mysql-test/t/func_if.test
+++ b/mysql-test/t/func_if.test
@@ -161,8 +161,9 @@ DROP TABLE t1;
#
CREATE TABLE t1 (c LONGTEXT);
-INSERT INTO t1 VALUES(1), (2), (3), (4), ('12345678901234567890');
+INSERT INTO t1 VALUES(1), (2), (3), (4), ('1234567890123456789');
+SELECT IF(1, CAST(c AS UNSIGNED), 0) FROM t1;
SELECT * FROM (SELECT MAX(IF(1, CAST(c AS UNSIGNED), 0)) FROM t1) AS te;
SELECT * FROM (SELECT MAX(IFNULL(CAST(c AS UNSIGNED), 0)) FROM t1) AS te;
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index 9e054da3fe2..fea3a2ed6d3 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -587,3 +587,22 @@ EXECUTE s;
DROP TABLE t1;
+#
+# lp:817966 int_column IN (string_constant)
+#
+# rather illogically, when BIGINT field is compared to a string,
+# the string is converted to an integer, not to a double.
+# When some other integer field (not BIGINT) is compared to a string,
+# or when the BIGINT is not a field, but an expression, both
+# operands are compared as doubles. The latter behavior is correct,
+# according to the manual.
+#
+create table t1 (a bigint, b int);
+insert t1 values (1,1),(2,2),(3,3);
+select * from t1 where a in ('2.1');
+select * from t1 where b in ('2.1');
+select * from t1 where a='2.1';
+select * from t1 where b='2.1';
+select * from t1 where IF(1,a,a)='2.1';
+drop table t1;
+--echo # End of 5.3 tests
diff --git a/mysql-test/t/func_op.test b/mysql-test/t/func_op.test
index 0a4f5034f4c..13fa40b513b 100644
--- a/mysql-test/t/func_op.test
+++ b/mysql-test/t/func_op.test
@@ -28,7 +28,10 @@ create table t1(a int);
create table t2(a int, b int);
insert into t1 values (1), (2), (3);
insert into t2 values (1, 7), (3, 7);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select t1.a, t2.a, t2.b, bit_count(t2.b) from t1 left join t2 on t1.a=t2.a;
+SET optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
# End of 4.1 tests
diff --git a/mysql-test/t/func_sapdb.test b/mysql-test/t/func_sapdb.test
index 1292c475732..5c31cee403a 100644
--- a/mysql-test/t/func_sapdb.test
+++ b/mysql-test/t/func_sapdb.test
@@ -91,8 +91,8 @@ select microsecond("1997-12-31 23:59:59.000001");
create table t1
select makedate(1997,1) as f1,
- addtime(cast("1997-12-31 23:59:59.000001" as datetime), "1 1:1:1.000002") as f2,
- addtime(cast("23:59:59.999999" as time) , "1 1:1:1.000002") as f3,
+ addtime(cast("1997-12-31 23:59:59.000001" as datetime(6)), "1 1:1:1.000002") as f2,
+ addtime(cast("23:59:59.999999" as time(6)) , "1 1:1:1.000002") as f3,
timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") as f4,
timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") as f5,
maketime(10,11,12) as f6,
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index 9909974d3be..406411eb704 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1314,9 +1314,13 @@ DROP TABLE t1, t2;
drop table if exists t1;
--enable_warnings
create table t1(f1 tinyint default null)engine=myisam;
-insert into t1 values (-1),(null);
+insert into t1 values (-1),(null);
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
explain select 1 as a from t1,(select decode(f1,f1) as b from t1) a;
explain select 1 as a from t1,(select encode(f1,f1) as b from t1) a;
+set optimizer_switch=@tmp_optimizer_switch;
drop table t1;
--echo #
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 4862324817e..c3d1d74ec50 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -15,7 +15,14 @@ select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_times
select from_unixtime(unix_timestamp("1994-03-02 10:11:12")),from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s"),from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0;
select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"),
sec_to_time(time_to_sec("0:30:47")/6.21);
+select sec_to_time(9001.1), time_to_sec('15:12:22.123456'), time_to_sec(15.5566778899);
select sec_to_time(time_to_sec('-838:59:59'));
+select sec_to_time('9001.1'), sec_to_time('1234567890123.123');
+select sec_to_time(-9001.1), sec_to_time(-9001.1) / 1,
+ sec_to_time(-9001.1) / 1e0, sec_to_time(-9001) div 1;
+--replace_result e+042 e+42
+select sec_to_time(90011e-1), sec_to_time(1234567890123e30);
+select sec_to_time(1234567890123), sec_to_time('99999999999999999999999999999');
select now()-curdate()*1000000-curtime();
select strcmp(current_timestamp(),concat(current_date()," ",current_time()));
select strcmp(localtime(),concat(current_date()," ",current_time()));
@@ -27,6 +34,7 @@ select month("1997-01-02"),year("98-02-03"),dayofyear("1997-12-31");
select month("2001-02-00"),year("2001-00-00");
select DAYOFYEAR("1997-03-03"), WEEK("1998-03-03"), QUARTER(980303);
select HOUR("1997-03-03 23:03:22"), MINUTE("23:03:22"), SECOND(230322);
+select TIME(230322), TIME(230322.33), TIME("230322.33");
# Test of week and yearweek
select week(19980101),week(19970101),week(19980101,1),week(19970101,1);
@@ -66,10 +74,10 @@ select date_format('1999-12-31','%x-%v'),date_format('2000-01-01','%x-%v');
select dayname("1962-03-03"),dayname("1962-03-03")+0;
select monthname("1972-03-04"),monthname("1972-03-04")+0;
-select time_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
-select time_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
-select time_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
-select time_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
+select time_format(000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
+select time_format(010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
+select time_format(131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
+select time_format(010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
select date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w');
select date_format(19980021000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w');
select date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND);
@@ -539,6 +547,7 @@ DROP TABLE t1;
# Bug #20927: sec_to_time treats big unsigned as signed
#
# check if SEC_TO_TIME() handles BIGINT UNSIGNED values correctly
+--replace_regex /'1.8446.*e.*19'/'1.84467440737096e+19'/
SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED));
#
@@ -723,6 +732,7 @@ set time_zone= @@global.time_zone;
#
select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE;
+select str_to_date("1997-00-04 22:23:00","%Y-%m-%D") + interval 10 minute;
#
# Bug #21103: DATE column not compared as DATE
@@ -827,7 +837,7 @@ SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
--disable_result_log
--error ER_WRONG_VALUE_FOR_VAR
SET TIMESTAMP=-147490000; SELECT UTC_TIMESTAMP();
---error ER_WRONG_VALUE_FOR_VAR
+--error 0,ER_WRONG_VALUE_FOR_VAR
SET TIMESTAMP=2147483648; SELECT UTC_TIMESTAMP();
SET TIMESTAMP=2147483646; SELECT UTC_TIMESTAMP();
SET TIMESTAMP=2147483647; SELECT UTC_TIMESTAMP();
@@ -905,7 +915,9 @@ SELECT FORMAT(YEAR(STR_TO_DATE('',GET_FORMAT(TIME,''))),1);
--echo # Bug#11766126 59166: ANOTHER DATETIME VALGRIND UNINITIALIZED WARNING
--echo #
+--disable_result_log
SELECT CAST((MONTH(FROM_UNIXTIME(@@GLOBAL.SQL_MODE))) AS BINARY(1025));
+--enable_result_log
--echo #
--echo # Bug#11766124 59164: VALGRIND: UNINITIALIZED VALUE IN NUMBER_TO_DATETIME
@@ -996,3 +1008,139 @@ query_vertical SELECT
TO_DAYs(STR_TO_DATE('000001','%Y%m'));
--echo End of 5.1 tests
+
+select time('10:10:10') > 10;
+select time('10:10:10') > 1010;
+select time('10:10:09') > 101010;
+select time('10:10:10') > 101010;
+select time('10:10:11') > 101010;
+
+select time(' 1 02:03:04') + interval 9 microsecond;
+select time(' 1 02:03:04') - interval 9 microsecond;
+select time('-1 02:03:04') + interval 9 microsecond;
+select time('-1 02:03:04') - interval 9 microsecond;
+select time(' 1 02:03:04') + interval '4:4:4' hour_second;
+select time(' 1 02:03:04') - interval '4:4:4' hour_second;
+select time('-1 02:03:04') + interval '4:4:4' hour_second;
+select time('-1 02:03:04') - interval '4:4:4' hour_second;
+select time(' 1 02:03:04') + interval 2 day;
+select time(' 1 02:03:04') - interval 2 day;
+select time('-1 02:03:04') + interval 2 day;
+select time('-1 02:03:04') - interval 2 day;
+
+select time('10 02:03:04') + interval 30 day;
+select time('10 02:03:04') + interval 1 year;
+
+# specially constructed queries to reach obscure places in the code
+# not touched by the more "normal" queries (and to increase the coverage)
+select cast('131415.123e0' as time);
+select cast('2010-01-02 03:04:05' as datetime) between null and '2010-01-02 03:04:04';
+select least(time('1:2:3'), '01:02:04', null) div 1;
+select truncate(least(time('1:2:3'), '01:02:04', null), 6);
+select cast(least(time('1:2:3'), '01:02:04', null) as decimal(3,1));
+select unix_timestamp(null);
+select truncate(date('2010-40-10'), 6);
+select extract(month from '2010-40-50');
+select subtime('0000-00-10 10:10:10', '30 10:00:00');
+
+#
+# lp:730637 Valgrind warnings in 5.1-micro
+#
+select cast(str_to_date(NULL, '%H:%i:%s') as time);
+
+create table t1 (f1 datetime, key (f1));
+insert into t1 values ('2000-09-12 00:00:00'), ('2007-04-25 05:08:49');
+select * from t1 where f1 > time('-23:00:06');
+drop table t1;
+
+#
+# lp:730627 TIME_to_ulonglong: Assertion `0' failed in 5.1-micro on wrong argument to MAKETIME
+#
+select maketime(20,61,10)+0;
+
+#
+# lp:731103 Assertion `maybe_null && item->null_value' failed with ORDER BY LAST_DAY()
+#
+create table t1 (f2 int not null) ;
+insert into t1 values (0),(0);
+select last_day(f2) from t1;
+select last_day(f2) from t1 where last_day(f2) is null;
+select * from t1 order by last_day (f2);
+drop table t1;
+
+#
+# lp:731815 Crash/valgrind warning Item::send with 5.1-micro
+#
+select convert_tz(timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' as datetime)), 'UTC', 'Europe/Moscow');
+
+#
+# lp:736370 Datetime functions in subquery context cause wrong result and bogus warnings in mysql-5.1-micr
+#
+create table t1 (f1 integer, f2 date);
+insert into t1 values (1,'2011-05-05'),(2,'2011-05-05'),(3,'2011-05-05'),(4,'2011-05-05'),(5,'2011-05-05'),(6, '2011-05-06');
+select * from t1 where 1 and concat(f2)=MAKEDATE(2011, 125);
+drop table t1;
+
+#
+# lp:736791 Crash in make_truncated_value_warning with LEAST()/GREATEST/COALESCE
+#
+create table t1 (f1 timestamp);
+insert into t1 values ('0000-00-00 00:00:00');
+select least(1, f1) from t1;
+drop table t1;
+
+#
+# lp:737092 Assertion `item->null_value' failed in get_datetime_value in 5.1-micro
+#
+select now() > coalesce(time('21:43:24'), date('2010-05-03'));
+
+#
+# lp:737104 Crash in DTCollation::set in 5.1-micro
+#
+create table t1 (f1 timestamp);
+select * from t1 where f1 > f1 and f1 <=> timestampadd(hour, 9 , '2010-01-01 16:55:35');
+drop table t1;
+
+#
+# lp:737111 Different behavior for TIMESTAMPADD with 0000-00-00 argument in 5.1-micro
+#
+create table t1 (f1 date);
+insert into t1 values ('0000-00-00');
+select timestampadd(week, 1, f1) from t1;
+select timestampadd(week, 1, date("0000-00-00"));
+drop table t1;
+
+#
+# lp:737450 Second Assertion `item->null_value' failed in 5.1-micro
+#
+create table t1 (f2 time not null, f3 datetime, f4 int not null, f5 timestamp);
+insert ignore t1 values ('04:38:11','0000-00-00 00:00:00',0,'0000-00-00 00:00:00');
+select least(greatest(f3, f2, f4), f5) from t1;
+drop table t1;
+
+#
+# lp:737474 Wrong result with DAY(COALESCE(NULL)) in 5.1-micro
+#
+select day(coalesce(null));
+
+#
+# lp:738067 Crash in get_datetime_value() in 5.1-micro
+#
+select timestamp(greatest('2002-08-20', '0000-00-00 00:00:00'));
+
+#
+# lp:738091 cast(timestamp() AS time returns NULL for 0000-00-00 00:00:00 in 5.1-micro
+#
+create table t1 (f1 datetime);
+insert into t1 values ('0000-00-00 00:00:00');
+select cast(f1 AS time) from t1;
+drop table t1;
+
+select greatest(cast("0-0-0" as date), cast("10:20:05" as time));
+select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00';
+select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6));
+
+select microsecond('12:00:00.123456'), microsecond('2009-12-31 23:59:59.000010');
+
+--error ER_TOO_BIG_PRECISION
+select now(258);
diff --git a/mysql-test/t/func_time_hires.test b/mysql-test/t/func_time_hires.test
new file mode 100644
index 00000000000..4dcd51a85ba
--- /dev/null
+++ b/mysql-test/t/func_time_hires.test
@@ -0,0 +1,108 @@
+#
+# Test of timestamp with hires resolution;
+
+set time_zone='+03:00';
+set timestamp=unix_timestamp('2011-01-01 01:01:01.123456');
+
+--vertical_results
+select sec_to_time(12345), sec_to_time(12345.6789), sec_to_time(1234567e-2);
+select now(), curtime(0), utc_timestamp(1), utc_time(2), current_time(3),
+ current_timestamp(4), localtime(5), localtimestamp(6), time_to_sec('12:34:56'),
+ time_to_sec('12:34:56.789');
+select sec_to_time(time_to_sec('1:2:3')), sec_to_time(time_to_sec('2:3:4.567890'));
+select time_to_sec(sec_to_time(11111)), time_to_sec(sec_to_time(11111.22222));
+--horizontal_results
+--error ER_TOO_BIG_PRECISION
+select current_timestamp(7);
+--error ER_TOO_BIG_PRECISION
+select curtime(7);
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+create table t1 select sec_to_time(12345), sec_to_time(12345.6789),
+ sec_to_time(1234567e-2), now(), curtime(0),
+ utc_timestamp(1), utc_time(2), current_time(3),
+ current_timestamp(4), localtime(5), localtimestamp(6),
+ time_to_sec(123456), time_to_sec('12:34:56.789');
+show create table t1;
+--query_vertical select * from t1
+drop table t1;
+
+--query_vertical select unix_timestamp('2011-01-01 01:01:01'), unix_timestamp('2011-01-01 01:01:01.123456'), unix_timestamp(cast('2011-01-01 01:01:01.123456' as datetime(0))), unix_timestamp(cast('2011-01-01 01:01:01.123456' as datetime(4)));
+--query_vertical select from_unixtime(unix_timestamp('2011/1/1 1:1:1')), from_unixtime(unix_timestamp('2011/1/1 1:1:1.123456')), from_unixtime(unix_timestamp(cast('2011/1/1 1:1:1.123456' as datetime(0)))), from_unixtime(unix_timestamp(cast('2011/1/1 1:1:1.123456' as datetime(4))));
+
+select sec_to_time(3020399.99999), sec_to_time(3020399.999999), sec_to_time(3020399.9999999);
+select sec_to_time(-3020399.99999), sec_to_time(-3020399.999999), sec_to_time(-3020399.9999999);
+select 20010101000203.000000004 + interval 1 day;
+select 20010101000203.4 + interval 1 day;
+#
+# precision of expressions
+#
+set @a=cast('2011-01-02 12:13:14' as datetime);
+select @a + interval 1 minute;
+select @a + interval 10 microsecond;
+select @a + interval 10 microsecond + interval 999990 microsecond;
+
+#
+# CAST
+#
+set @a='2011-01-02 12:13:14.123456';
+create table t1 select CAST(@a AS DATETIME) as dauto,
+ CAST(@a AS DATETIME(0)) as d0,
+ CAST(@a AS DATETIME(1)) as d1,
+ CAST(@a AS DATETIME(2)) as d2,
+ CAST(@a AS DATETIME(3)) as d3,
+ CAST(@a AS DATETIME(4)) as d4,
+ CAST(@a AS DATETIME(5)) as d5,
+ CAST(@a AS DATETIME(6)) as d6,
+ CAST(@a AS TIME) as tauto,
+ CAST(@a AS TIME(0)) as t0,
+ CAST(@a AS TIME(1)) as t1,
+ CAST(@a AS TIME(2)) as t2,
+ CAST(@a AS TIME(3)) as t3,
+ CAST(@a AS TIME(4)) as t4,
+ CAST(@a AS TIME(5)) as t5,
+ CAST(@a AS TIME(6)) as t6;
+show create table t1;
+--query_vertical select * from t1
+drop table t1;
+explain extended select cast(cast(@a as datetime(4)) as time(0));
+select cast(cast(@a as time(2)) as time(6));
+
+--error ER_TOO_BIG_PRECISION
+select CAST(@a AS DATETIME(7));
+
+#
+# CONVERT_TZ
+#
+SELECT CONVERT_TZ('2011-01-02 12:00:00', '+00:00', '+03:00');
+SELECT CONVERT_TZ('2011-01-02 12:00:00.123', '+00:00', '+03:00');
+SELECT CONVERT_TZ('2011-01-02 12:00:00.123456', '+00:00', '+03:00');
+SELECT CONVERT_TZ(CAST('2010-10-10 10:10:10.123456' AS DATETIME(4)), '+00:00', '+03:00');
+
+#
+# Field::store_time()
+#
+create table t1 (a varchar(200));
+insert t1 values (now(6));
+select * from t1;
+drop table t1;
+
+#
+# lp:736358 Unexpected increased timestamp resolution with UNION
+#
+# timestamp(6) case is fixed:
+create table t1 (f1 timestamp(6));
+insert into t1 values ('2002-07-15 21:00:00');
+select time(f1) from t1;
+select time(f1) from t1 union all select time(f1 + interval 1 second) from t1;
+alter table t1 modify f1 timestamp;
+select time(f1) from t1;
+select time(f1) from t1 union all select time(f1 + interval 1 second) from t1;
+# but the effect cannot be eliminated completely:
+alter table t1 modify f1 varchar(100);
+select time(f1) from t1;
+select time(f1) from t1 union all select time(f1 + interval 1 second) from t1;
+drop table t1;
diff --git a/mysql-test/t/gis-precise.test b/mysql-test/t/gis-precise.test
new file mode 100644
index 00000000000..d021bb0b53d
--- /dev/null
+++ b/mysql-test/t/gis-precise.test
@@ -0,0 +1,327 @@
+-- source include/have_geometry.inc
+
+
+#
+# Spatial objects
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+select 1, ST_Intersects(GeomFromText('POLYGON((0 0,20 0,20 20,0 20,0 0))'), GeomFromText('POLYGON((10 10,30 10,30 30,10 30,10 10))'));
+select 0, ST_Intersects(GeomFromText('POLYGON((0 0,20 10,10 30, 0 0))'), GeomFromText('POLYGON((10 40, 40 50, 20 70, 10 40))'));
+select 1, ST_Intersects(GeomFromText('POLYGON((0 0,20 10,10 30, 0 0))'), GeomFromText('POINT(10 10)'));
+select 1, ST_Intersects(GeomFromText('POLYGON((0 0,20 10,10 30, 0 0))'), GeomFromText('POLYGON((10 10,30 20,20 40, 10 10))'));
+select 0, ST_Within(GeomFromText('POLYGON((0 0,20 10,10 30, 0 0))'), GeomFromText('POLYGON((10 10,30 20,20 40, 10 10))'));
+select 1, ST_Within(GeomFromText('POLYGON((1 1,20 10,10 30, 1 1))'), GeomFromText('POLYGON((0 0,30 5,10 40, 0 0))'));
+
+
+create table t1 (g point);
+insert into t1 values
+(GeomFromText('POINT(2 2)')), (GeomFromText('POINT(2 4)')), (GeomFromText('POINT(2 6)')), (GeomFromText('POINT(2 8)')),
+(GeomFromText('POINT(4 2)')), (GeomFromText('POINT(4 4)')), (GeomFromText('POINT(4 6)')), (GeomFromText('POINT(4 8)')),
+(GeomFromText('POINT(6 2)')), (GeomFromText('POINT(6 4)')), (GeomFromText('POINT(6 6)')), (GeomFromText('POINT(6 8)')),
+(GeomFromText('POINT(8 2)')), (GeomFromText('POINT(8 4)')), (GeomFromText('POINT(8 6)')), (GeomFromText('POINT(8 8)'));
+
+select astext(g) from t1 where ST_Within(g, GeomFromText('POLYGON((5 1, 7 1, 7 7, 5 7, 3 3, 5 3, 5 1))'));
+select 'Contains';
+select astext(g) from t1 where ST_Contains(GeomFromText('POLYGON((5 1, 7 1, 7 7, 5 7, 3 3, 5 3, 5 1))'), g);
+select 'Intersects';
+select astext(g) from t1 where ST_Intersects(GeomFromText('POLYGON((5 1, 7 1, 7 7, 5 7, 3 3, 5 3, 5 1))'), g);
+select 'Contains';
+select astext(g) from t1 where ST_Contains(GeomFromText('POLYGON((5 1, 7 1, 7 7, 5 7, 3 3, 5 3, 5 1))'), g);
+select 'Contains2';
+select astext(g) from t1 where ST_Contains(GeomFromText('POLYGON((5 1, 7 1, 7 7, 5 7, 3 3, 5 3, 5 1), (5.01 3.01, 6 5, 9 5, 8 3, 5.01 3.01))'), g);
+
+DROP TABLE t1;
+
+select 0, ST_Within(GeomFromText('LINESTRING(15 15, 50 50, 60 60)'), GeomFromText('POLYGON((10 10,30 20,20 40, 10 10))'));
+select 1, ST_Within(GeomFromText('LINESTRING(15 15, 16 16)'), GeomFromText('POLYGON((10 10,30 20,20 40, 10 10))'));
+
+
+select 1, ST_Intersects(GeomFromText('LINESTRING(15 15, 50 50)'), GeomFromText('LINESTRING(50 15, 15 50)'));
+select 0, ST_Intersects(GeomFromText('LINESTRING(15 15, 50 50)'), GeomFromText('LINESTRING(16 16, 51 51)'));
+
+select 1, ST_Intersects(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('POLYGON((50 5, 55 10, 0 45, 50 5))'));
+
+select astext(ST_Union(geometryfromtext('point(1 1)'), geometryfromtext('polygon((0 0, 2 0, 1 2, 0 0))')));
+select astext(ST_Intersection(geometryfromtext('point(1 1)'), geometryfromtext('polygon((0 0, 2 0, 1 2, 0 0))')));
+
+select ST_Intersects(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('POLYGON((50 5, 55 10, 0 45, 50 5))'));
+select ST_contains(GeomFromText('MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)), ((6 6, 6 11, 11 11, 11 6, 6 6)))'), GeomFromText('POINT(5 10)'));
+select ST_Disjoint(GeomFromText('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'), GeomFromText('POLYGON((10 10, 10 15, 15 15, 15 10, 10 10))'));
+select ST_Disjoint(GeomFromText('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'), GeomFromText('POLYGON((10 10, 10 4, 4 4, 4 10, 10 10))'));
+select ST_Overlaps(GeomFromText('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'), GeomFromText('POLYGON((10 10, 10 4, 4 4, 4 10, 10 10))'));
+select ST_Overlaps(GeomFromText('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'), GeomFromText('POLYGON((1 1, 1 4, 4 4, 4 1, 1 1))'));
+
+# Distance tests
+select ST_DISTANCE(geomfromtext('polygon((0 0, 1 2, 2 1, 0 0))'), geomfromtext('polygon((2 2, 3 4, 4 3, 2 2))'));
+select ST_DISTANCE(geomfromtext('polygon((0 0, 1 2, 2 1, 0 0))'), geomfromtext('linestring(0 1, 1 0)'));
+select ST_DISTANCE(geomfromtext('polygon((0 0, 3 6, 6 3, 0 0))'), geomfromtext('polygon((2 2, 3 4, 4 3, 2 2))'));
+select ST_DISTANCE(geomfromtext('polygon((0 0, 3 6, 6 3, 0 0),(2 2, 3 4, 4 3, 2 2))'), geomfromtext('point(3 3)'));
+select ST_DISTANCE(geomfromtext('linestring(0 0, 3 6, 6 3, 0 0)'), geomfromtext('polygon((2 2, 3 4, 4 3, 2 2))'));
+
+
+# Operations tests
+select astext(ST_Intersection(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('POLYGON((50 5, 55 10, 0 45, 50 5))')));
+select astext(ST_Intersection(GeomFromText('LINESTRING(0 0, 50 45, 40 50, 0 0)'), GeomFromText('LINESTRING(50 5, 55 10, 0 45, 50 5)')));
+select astext(ST_Intersection(GeomFromText('LINESTRING(0 0, 50 45, 40 50)'), GeomFromText('LINESTRING(50 5, 55 10, 0 45)')));
+select astext(ST_Intersection(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('POINT(20 20)')));
+select astext(ST_Intersection(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('LINESTRING(-10 -10, 200 200)')));
+select astext(ST_Intersection(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('LINESTRING(-10 -10, 200 200, 199 201, -11 -9)')));
+select astext(ST_UNION(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('LINESTRING(-10 -10, 200 200, 199 201, -11 -9)')));
+
+select astext(ST_intersection(geomfromtext('polygon((0 0, 1 0, 0 1, 0 0))'), geomfromtext('polygon((0 0, 1 1, 0 2, 0 0))')));
+
+select astext(ST_symdifference(geomfromtext('polygon((0 0, 1 0, 0 1, 0 0))'), geomfromtext('polygon((0 0, 1 1, 0 2, 0 0))')));
+select astext(ST_UNION(GeomFromText('POLYGON((0 0, 50 45, 40 50, 0 0))'), GeomFromText('LINESTRING(-10 -10, 200 200, 199 201, -11 -9)')));
+
+# Buffer() tests
+--replace_result 0012045437948276 00120454379482759
+select astext(ST_buffer(geometryfromtext('point(1 1)'), 1));
+create table t1(geom geometrycollection);
+insert into t1 values (geomfromtext('POLYGON((0 0, 10 10, 0 8, 0 0))'));
+insert into t1 values (geomfromtext('POLYGON((1 1, 10 10, 0 8, 1 1))'));
+select astext(geom), area(geom),area(ST_buffer(geom,2)) from t1;
+select astext(ST_buffer(geom,2)) from t1;
+
+set @geom=geomfromtext('LINESTRING(2 1, 4 2, 2 3, 2 5)');
+set @buff=ST_buffer(@geom,1);
+--replace_result 40278744502097 40278744502096
+select astext(@buff);
+
+# cleanup
+DROP TABLE t1;
+
+#Touches tests
+select st_touches(geomfromtext('point(0 0)'), geomfromtext('point(1 1)'));
+select st_touches(geomfromtext('point(1 1)'), geomfromtext('point(1 1)'));
+select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('point(1 1)'));
+select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('point(1 0)'));
+select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('point(1 2)'));
+select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1.2, 1 0, 2 0, 1 1.2))'));
+select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1, 1 0, 2 0, 1 1))'));
+
+#Equals test
+SELECT ST_Equals(PolyFromText('POLYGON((67 13, 67 18, 67 18, 59 18, 59 13, 67 13) )'),PolyFromText('POLYGON((67 13, 67 18, 59 19, 59 13, 59 13, 67 13) )')) as result;
+SELECT ST_Equals(PolyFromText('POLYGON((67 13, 67 18, 67 18, 59 18, 59 13, 67 13) )'),PolyFromText('POLYGON((67 13, 67 18, 59 18, 59 13, 59 13, 67 13) )')) as result;
+SELECT ST_Equals(PointFromText('POINT (12 13)'),PointFromText('POINT (12 13)')) as result;
+
+# bug #801243 Assertion `(0)' failed in Gis_geometry_collection::init_from_opresult on ST_UNION
+
+SELECT astext(ST_UNION (
+ PolyFromText('POLYGON(( 2 2 ,3 2,2 7,2 2),( 0 0,8 2,1 9,0 0))'),
+ ExteriorRing( Envelope( MultiLineStringFromText('MULTILINESTRING((3 4,5 3),(3 0,0 5))')))));
+
+#bug 801189 ST_BUFFER asserts if radius = 0
+SELECT astext(ST_BUFFER(LineStringFromText('LINESTRING(0 0,1 1)'),0));
+
+#bug 801199 Infinite recursion in Gcalc_function::count_internal with ST_BUFFER over MULTIPOINT
+SELECT Round(ST_Area(ST_BUFFER(MultipointFromText('MULTIPOINT(7 7,3 7,7 2,7 4 ,7 7)'), 3)), 5);
+
+#bug 801212 Assertion with ST_INTERSECTION on NULL values
+SELECT ST_INTERSECTION(NULL, NULL);
+
+#bug 804305 Crash in wkb_get_double with ST_INTERSECTION
+SELECT ASTEXT(ST_INTERSECTION(
+ MULTIPOLYGONFROMTEXT('MULTIPOLYGON(((2 2,2 8,8 8,8 2,2 2),(4 4,4 6,6 6,6 4,4 4)),
+ ((0 5,3 5,3 0,0 0,0 1,2 1,2 2,0 2,0 5), (1 3,2 3,2 4,1 4,1 3)),
+ ((2 2,5 2,4 4,2 8,2 2)))'),
+ MULTIPOLYGONFROMTEXT('MULTIPOLYGON(((3 5,2 4,2 5,3 5)),
+ ((2 2,9 2,0 2,2 6,2 2)),
+ ((2 2,2 8,8 8,8 2,2 2), (4 4,4 6,6 6,6 4,4 4)),
+ ((9 9,6 8,7 0,9 9)))')));
+
+#bug 804324 Assertion 0 in Gcalc_scan_iterator::pop_suitable_intersection
+
+--replace_result 61538461538462 61538461538461
+SELECT ASTEXT(ST_UNION(
+ MULTILINESTRINGFROMTEXT('MULTILINESTRING((6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
+ (8 2,1 3,9 0,4 4))'),
+ MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 5,6 7,9 7,5 2,1 6,3 6))')));
+
+SELECT ST_NUMGEOMETRIES((ST_UNION(ST_UNION(
+ MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 0,4 2,0 2,1 5,0 3,7 0,8 5,5 8),
+ (6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
+ (7 8,3 1,0 9,6 0,4 8),
+ (9 3,0 4,5 9,6 4),
+ (8 2,1 3,9 0,4 4))'),
+ MULTILINESTRINGFROMTEXT('MULTILINESTRING((6 0,9 3,2 5,3 6,3 2),
+ (2 5,6 7,9 7,5 2,1 6,3 6))')),
+ MULTIPOLYGONFROMTEXT('MULTIPOLYGON(((7 7,3 7,3 1,7 8,7 7)),
+ ((3 5,2 4,2 5,3 5)),
+ ((7 7,8 7,3 7,7 7,7 7)),
+ ((0 5,3 5,3 4,1 4,1 3,3 3,3 0,0 0,0 5), (1 1,2 1,2 2,1 2,1 1)))'))));
+
+#bug #805860 Second assertion Assertion `n > 0 && n < SINUSES_CALCULATED*2+1' in get_n_sinco
+
+SELECT Round(ST_AREA(ST_BUFFER( ST_UNION(
+ POLYGONFROMTEXT('POLYGON((7 7, 7 7, 7 4, 7 7, 7 7))'),
+ POLYGONFROMTEXT('POLYGON((7 7, 4 7, 2 9, 7 6, 7 7))')), 1)), 6);
+
+
+#bug #804259 Second assertion in Gis_geometry_collection::init_from_opresult
+
+SELECT AsText(ST_UNION(MultiPolygonFromText('
+ MULTIPOLYGON(((2 2, 2 8, 8 8, 8 2, 2 2), (4 4, 4 6, 6 6, 6 4, 4 4)),
+ ((0 0, 8 3, 7 4, 0 0)),
+ ((2 2, 2 8, 8 8, 8 2, 2 2), (4 4, 4 6, 6 6, 6 4, 4 4)))'),
+MultiPolygonFromText(' MULTIPOLYGON(((0 0, 1 9, 4 6, 0 0)),
+ ((0 5, 3 5, 3 4, 1 4, 1 3, 3 3, 3 0, 0 0, 0 5), (1 1, 2 1, 2 2, 1 2, 1 1)),
+ ((7 7, 4 7, 6 3, 7 2, 7 7)),
+ ((0 5, 3 5, 3 4, 1 4, 1 3, 3 3, 3 0, 0 0, 0 5), (1 1, 2 1, 2 2, 1 2, 1 1))) ')));
+
+
+#bug 801217 Assertion `t1->result_range' in Gcalc_operation_reducer::end_couple
+
+SELECT AsText(ST_SYMDIFFERENCE(
+ MultiLineStringFromText('MULTILINESTRING((7 7, 1 7, 8 5, 7 8, 7 7),
+ (6 3, 3 4, 1 1, 9 9, 9 0, 8 4, 9 9))'),
+ Envelope(GeometryFromText('MULTIPOINT(7 9, 0 0, 3 7, 1 6, 0 0)'))));
+
+#bug 804266 Memory corruption/valgrind warning/crash in move_hole() with ST_UNION
+
+SELECT AsText(ST_UNION(
+ MultiPolygonFromText('MULTIPOLYGON(((9 9, 7 9, 1 1, 9 9)),
+ ((2 2, 1 2, 3 3, 2 2, 2 2)),
+ ((0 0, 7 5, 9 6, 0 0)),
+ ((7 7, 5 7, 1 5, 7 1, 7 7)))'),
+ MultiPolygonFromText('MULTIPOLYGON(((2 2, 2 2, 1 5, 2 7, 2 2)),
+ ((0 5, 3 5, 3 0, 0 0, 0 5), (1 1, 2 1, 2 4, 1 4, 1 1)))')));
+
+#bug 802376 ST_INTERSECTION returns wrong result on two overlapping linestrings in maria-5.3-gis
+
+SELECT AsText( ST_INTERSECTION(
+ LinestringFromText('LINESTRING( 3 5, 2 5, 2 4, 3 4, 3 5 ) ') ,
+ LinestringFromText('LINESTRING( 3 5, 2 4, 2 5, 3 5 ) ')
+));
+
+#bug 801560 ST_UNION of adjacent polygons includes extra line in maria-5.3-gis
+
+SELECT AsText( ST_UNION(
+ PolygonFromText(' POLYGON( ( 2 2 , 3 2 , 7 5 , 2 0 , 2 2 ) ) ') ,
+ PolygonFromText(' POLYGON( ( 2 2 , 3 2 , 3 3 , 2 5 , 2 2 ) ) ') ) );
+
+#bug 801466 ST_INTERSECTION() returns invalid value on empty intersection in maria-5.3-gis
+
+SELECT AsText(ST_INTERSECTION(LinestringFromText('LINESTRING(1 1, 2 2)'), GeometryFromText('LINESTRING(3 3, 4 4)')));
+
+#bug 839341 100% CPU usage with ST_UNION in maria-5.3-gis
+SELECT AsText(ST_UNION(GEOMETRYFROMTEXT('POINT(8 1)') ,MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 5, 2 5, 2 4, 3 4, 3 5))')));
+
+#bug 839318 Crash in Gcalc_scan_iterator::point::get_shape with ST_DISTANCE and MULTILINESTRING in maria-5.3-gis
+SELECT ST_DISTANCE(POINTFROMTEXT('POINT(7 1)'),MULTILINESTRINGFROMTEXT('MULTILINESTRING(
+ (4 7,9 7,6 1,3 4,1 1), (3 5, 2 5, 2 4, 3 4, 3 5))'));
+
+#bug 839327 Crash in Gcalc_operation_reducer::end_couple with ST_UNION and MULTIPOLYGONs in 5.3-gis
+SELECT AsText(ST_UNION(POLYGONFROMTEXT('POLYGON((12 9, 3 6, 3 0, 12 9))'), POLYGONFROMTEXT('POLYGON((2 2, 7 2, 4 2, 2 0, 2 2))')));
+
+#bug 841622 Assertion `t->rp->type == Gcalc_function::shape_line' failed in Gcalc_operation_reducer::end_line in maria-5.3-gis
+
+SELECT ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER(ST_UNION(
+ MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 2 5, 7 6, 1 8),(0 0 ,1 6 ,0 1, 8 9, 2 4, 6 1, 3 5, 4 8), (9 3, 5 4, 1 8, 4 2, 5 8, 3 0))' ) ,
+ MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 3 1, 2 7, 4 2, 6 2, 1 5))')
+ ), 16)));
+
+#bug 841625 Assertion `m_poly_borders->next' failed in Gcalc_operation_reducer::count_slice in maria-5.3-gis
+
+SELECT ST_NUMGEOMETRIES(ST_DIFFERENCE (
+ ST_UNION (
+ MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 4 , 5 0 , 2 9 , 6 2 , 0 2 ) , ( 4 3 , 5 6 , 9 4 , 0 7 , 7 2 , 2 0 , 8 2 ) , ( 5 0 , 1 5 , 3 7 , 7 7 ) , ( 2 3 , 9 5 , 2 0 , 8 1 ) , ( 0 9 , 9 3 , 2 8 , 8 1 , 9 4 ) ) ' ),
+ ST_UNION (
+ MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( ( 2 2 , 7 2 , 6 2 , 2 6 , 2 2 ) ) , ( (3 5, 2 5, 2 4, 3 4, 3 5) ) ) ' ) ,
+ ENVELOPE(
+ MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( (3 5, 2 5, 2 4, 3 4, 3 5) ) ) ' )
+ )
+ )
+ ),
+ MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 9 , 1 3 , 7 3 , 8 5 ) , ( 5 0 , 8 1 , 2 0 , 7 4 , 1 0 ) , ( 9 2 , 5 2 , 6 5 , 8 8 , 0 2 ) , ( 0 8 , 3 9 , 4 0 , 1 0 ) , ( 0 0 , 7 6 , 8 3 , 0 0 ) ) ' )
+));
+
+
+#bug 841745 ssertion `!sp0->is_bottom()' failed in Gcalc_scan_iterator::find_intersections in maria-5.3-gis
+SELECT ASTEXT(ST_DIFFERENCE (
+ POLYGONFROMTEXT( ' POLYGON( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) ' ) ,
+ ST_UNION (
+ MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( (3 5, 2 5, 2 4, 3 4, 3 5) ) ' ) ,
+ ST_SYMDIFFERENCE (
+ MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 3 8 , 0 8 , 6 6 , 6 1 , 0 5 , 6 7 , 3 7 ) , ( 5 8 , 7 7 , 9 0 , 8 7 ) , ( 1 5 , 1 8 , 2 3 , 3 9 ) , ( 1 3 , 9 7 , 5 5 , 0 8 , 6 9 ) , ( 3 6 , 6 9 , 8 7 , 0 2 , 4 6 , 9 5 ) ) ' ) ,
+ ST_UNION (
+ MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 9 4 , 2 0 , 2 2 , 7 2 , 6 2 ) , ( 5 2 , 8 2 , 4 8 , 3 4 ) , ( 1 0 , 1 4 , 2 7 , 7 0 , 1 5 ) , ( 2 8 , 4 4 , 5 0 , 7 0 , 4 0 ) ) ' ) ,
+ GEOMETRYFROMTEXT( ' MULTILINESTRING( ( 3 7 , 7 3 , 5 8 , 4 8 ) , ( 3 2 , 5 0 , 9 3 , 4 4 ) , ( 6 0 , 4 2 , 7 8 , 1 3 ) ) ' )
+ )
+ )
+ )
+));
+
+#bug 841773 Assertion `t0->rp->type == t1->rp->type' failed in Gcalc_operation_reducer::end_couple in maria-5.3-gis
+SELECT ST_NUMGEOMETRIES(ST_UNION (
+ MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 0 8 , 1 9 , 5 7 , 2 8 , 5 8 , 6 7 ) , ( 4 5 , 8 4 , 0 3 , 5 1 ) , ( 6 8 , 2 7 , 1 6 , 9 9 , 7 2 ) , ( 9 5 , 2 8 , 1 2 , 9 6 , 2 0 ) ) ' ) ,
+ MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( ( 7 7 , 2 7, 6 8, 7 1 , 7 7 ) ) ) ' )
+));
+
+#bug 841662 Third assertion `n > 0 && n < SINUSES_CALCULATED*2+1' in get_n_sincos
+SELECT ST_BUFFER (
+ LINESTRINGFROMTEXT( ' LINESTRING( 5 4 , 3 8 , 2 6 , 5 5 , 7 9 ) ' ) ,
+ ST_DISTANCE (
+ MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( (3 5, 2 4, 2 5, 3 5) ) , ( (3 5, 2 5, 2 4, 3 4, 3 5) ) , ( ( 0 0 , 8 3 , 9 5 , 0 0 ) ) ) ' ) ,
+ ST_DIFFERENCE (
+ MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( (3 5, 2 5, 2 4, 3 4, 3 5) ) ) ' ) ,
+ MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) , ( ( 0 0 , 3 8 , 9 4 , 0 0 ) ) ) ' )
+ )
+ )
+ ) ;
+SELECT ST_DISTANCE ( ST_DIFFERENCE ( MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( (3 5, 2 5, 2 4, 3 4, 3 5) ) ) ' ) , MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) , ( ( 0 0 , 3 8 , 9 4 , 0 0 ) ) ) ' ) ), MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( (3 5, 2 4, 2 5, 3 5) ) , ( (3 5, 2 5, 2 4, 3 4, 3 5) ) , ( ( 0 0 , 8 3 , 9 5 , 0 0 ) ) ) ' ) ) ;
+
+#bug 848939 Wrong result with ST_INTERSECTION between linestrings and a polygon in 5.3-gis
+SELECT ASTEXT(ST_INTERSECTION( GEOMETRYFROMTEXT('GEOMETRYCOLLECTION(LINESTRING(7 7,5.33333333333333 7),LINESTRING(5.33333333333333 7,0 7,5 8,5.33333333333333 7),LINESTRING(5.33333333333333 7,7 2,7 7),POLYGON((0 5,3 5,3 2,1 2,1 1,3 1,3 0,0 0,0 3,2 3,2 4,0 4,0 5)))'), geomETRYFROMTEXT(' MULTILINESTRING( ( 5 1 , 3 7 , 6 1 , 7 0 ) , ( 1 6 , 8 5 , 7 5 , 5 6 ) )') ));
+
+#bug 855485 ST_CROSSES returns different result than PostGIS for overlapping polygons
+
+SELECT ST_CROSSES( GEOMETRYFROMTEXT(' POLYGON( (3 5, 2 4, 2 5, 3 5) ) ') , POLYGONFROMTEXT(' POLYGON((2 4,3 4,3 5,2 5,2 4)) '));
+
+#bug 855487 ST_WITHIN returns wrong result for partially overlapping polygons
+
+SELECT ST_WITHIN( POLYGONFROMTEXT(' POLYGON( (0 5, 3 5, 3 4, 2 0 , 1 0, 2 4 , 0 4, 0 5) ) ') , POLYGONFROMTEXT(' POLYGON( (0 5, 3 5, 3 4, 1 4 , 1 3 , 3 3 , 3 0 , 0 0 , 0 5), ( 1 1 , 2 1 , 2 2 , 1 2 , 1 1 ) ) ') );
+
+#bug 855492 ST_WITHIN returns TRUE on point on the edge of a polygon
+
+SELECT ST_WITHIN( POINTFROMTEXT(' POINT(1 2 ) ') , MULTIPOLYGONFROMTEXT(' MULTIPOLYGON( ( (0 5, 3 5, 3 0, 0 0, 0 5), ( 1 1 , 2 1 , 2 4, 1 4, 1 1 ) ) ) '));
+
+#bug 855497 ST_ENVELOPE of GEOMETRYCOLLECTION EMPTY returns NULL and not GEOMETRYCOLLECTION EMPTY
+
+select ST_ASTEXT(envelope(ST_GEOMCOLLFROMTEXT('GEOMETRYCOLLECTION EMPTY')));
+
+#bug 855503 ST_EQUALS reports TRUE between a POLYGON and a MULTILINESTRING
+
+SELECT ST_EQUALS( GEOMETRYFROMTEXT(' MULTILINESTRING( (3 5, 2 5, 2 4, 3 4, 3 5) ) ') , GEOMETRYFROMTEXT(' POLYGON( (3 5, 2 5, 2 4, 3 4, 3 5) ) ') );
+
+#bug 855505 ST_TOUCHES reports TRUE for intersecting polygon and linestring
+
+SELECT ST_TOUCHES( GEOMETRYFROMTEXT(' LINESTRING( 1 1 , 1 4 , 5 0 , 8 3 ) ') , POLYGONFROMTEXT(' POLYGON( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) ') );
+
+#bug 857051 ST_EQUALS returns TRUE on two nonidentical MULTIPOINTs
+
+SELECT ST_EQUALS( MULTIPOINTFROMTEXT(' MULTIPOINT( 5 1 , 6 9 , 1 4 , 4 0 ) ') , MULTIPOINTFROMTEXT(' MULTIPOINT( 5 8 , 5 2 , 1 8 , 3 0 , 3 0 , 7 8 ) ') );
+SELECT ST_EQUALS( MULTIPOINTFROMTEXT(' MULTIPOINT( 5 1 , 6 9 , 1 4 , 4 0 ) ') , MULTIPOINTFROMTEXT('MULTIPOINT( 4 0 , 6 9 , 5 1, 1 4 )') );
+
+#bug 857050 ST_WITHIN returns wrong result with MULTIPOINT and POLYGON
+SELECT ST_WITHIN( MULTIPOINTFROMTEXT(' MULTIPOINT( 2 9 , 2 9 , 4 9 , 9 1 ) ') , POLYGONFROMTEXT(' POLYGON( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) '));
+
+#bug 857087 Wrong result with ST_INTERSECTS and LINESTRINGs
+
+SELECT ST_INTERSECTS( GeomFromText('MULTILINESTRING( ( 4030 3045 , 3149 2461 , 3004 3831 , 3775 2976 ) )') , GeomFromText('LINESTRING(3058.41 3187.91,3081.52 3153.19,3042.99 3127.57,3019.89 3162.29,3039.07 3175.05,3039.07 3175.05,3058.41 3187.91,3081.52 3153.19,3042.99 3127.57,3019.89 3162.29)') );
+
+#bug 977201 ST_BUFFER fails with the negative D
+select ASTEXT(ST_BUFFER(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))'), -3));
+
+#bug 986977 Assertion `!cur_p->event' failed in Gcalc_scan_iterator::arrange_event(int, int)
+SELECT ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER( POLYGONFROMTEXT( 'POLYGON( ( 0.0 -3.0,
+ -2.910427500435995 0.727606875108998,
+ -0.910427500435995 8.727606875108998,
+ 7.664100588675687 1.503849116986468,
+ 1.664100588675687 -2.496150883013531,
+ 0.0 -3.0
+))' ), 3 )));
+
diff --git a/mysql-test/t/gis-rt-precise.test b/mysql-test/t/gis-rt-precise.test
new file mode 100644
index 00000000000..4cae10a9076
--- /dev/null
+++ b/mysql-test/t/gis-rt-precise.test
@@ -0,0 +1,64 @@
+-- source include/have_geometry.inc
+
+#
+# test of rtree (using with spatial data)
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+ fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ g GEOMETRY NOT NULL,
+ SPATIAL KEY(g)
+) ENGINE=MyISAM;
+
+SHOW CREATE TABLE t1;
+
+--disable_query_log
+let $1=150;
+let $2=150;
+while ($1)
+{
+ eval INSERT INTO t1 (g) VALUES (GeomFromText('LineString($1 $1, $2 $2)'));
+ dec $1;
+ inc $2;
+}
+--enable_query_log
+
+SELECT count(*) FROM t1;
+EXPLAIN SELECT fid, AsText(g) FROM t1 WHERE ST_Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 140))'));
+SELECT fid, AsText(g) FROM t1 WHERE ST_Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ g GEOMETRY NOT NULL
+) ENGINE=MyISAM;
+
+--disable_query_log
+let $1=10;
+while ($1)
+{
+ let $2=10;
+ while ($2)
+ {
+ eval INSERT INTO t1 (g) VALUES (LineString(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10)));
+ dec $2;
+ }
+ dec $1;
+}
+--enable_query_log
+
+ALTER TABLE t1 ADD SPATIAL KEY(g);
+SHOW CREATE TABLE t1;
+SELECT count(*) FROM t1;
+EXPLAIN SELECT fid, AsText(g) FROM t1 WHERE ST_Within(g,
+ GeomFromText('Polygon((40 40,60 40,60 60,40 40))'));
+SELECT fid, AsText(g) FROM t1 WHERE ST_Within(g,
+ GeomFromText('Polygon((40 40,60 40,60 60,40 40))'));
+
+DROP TABLE t1;
+
+--echo End of 5.5 tests.
diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test
index b99d35ecd48..e7e6fa59df0 100644
--- a/mysql-test/t/gis-rtree.test
+++ b/mysql-test/t/gis-rtree.test
@@ -17,16 +17,12 @@ SHOW CREATE TABLE t1;
let $1=150;
let $2=150;
---disable_query_log
-begin;
while ($1)
{
eval INSERT INTO t1 (g) VALUES (GeomFromText('LineString($1 $1, $2 $2)'));
dec $1;
inc $2;
}
-commit;
---enable_query_log
SELECT count(*) FROM t1;
EXPLAIN SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
@@ -39,8 +35,6 @@ CREATE TABLE t2 (
g GEOMETRY NOT NULL
) ENGINE=MyISAM;
---disable_query_log
-begin;
let $1=10;
while ($1)
{
@@ -52,8 +46,6 @@ while ($1)
}
dec $1;
}
-commit;
---enable_query_log
ALTER TABLE t2 ADD SPATIAL KEY(g);
SHOW CREATE TABLE t2;
@@ -63,8 +55,6 @@ EXPLAIN SELECT fid, AsText(g) FROM t2 WHERE Within(g,
SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
---disable_query_log
-begin;
let $1=10;
while ($1)
{
@@ -77,8 +67,6 @@ while ($1)
}
dec $1;
}
-commit;
---enable_query_log
DROP TABLE t2;
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index abda3e997bd..cdbc253869e 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -62,7 +62,9 @@ INSERT INTO gis_multi_polygon VALUES
INSERT INTO gis_geometrycollection VALUES
(120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),
-(121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9))))));
+(121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))),
+(122, GeomFromText('GeometryCollection()')),
+(123, GeomFromText('GeometryCollection EMPTY'));
INSERT into gis_geometry SELECT * FROM gis_point;
INSERT into gis_geometry SELECT * FROM gis_line;
@@ -353,6 +355,9 @@ insert into t1 values ('85984',GeomFromText('MULTIPOLYGON(((-115.006363
36.248666,-115.263639 36.247466,-115.263839 36.252766,-115.261439
36.252666,-115.261439 36.247366,-115.247239 36.247066)))'));
+# Expected result is 115.31877315203187, but IA64 returns 115.31877315203188
+# due to fused multiply-add instructions.
+--replace_result 115.31877315203188 115.31877315203187
select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
t1 where object_id=85998;
@@ -536,18 +541,6 @@ insert into t1 values(default);
drop table t1;
#
-# Bug #27300: create view with geometry functions lost columns types
-#
-CREATE TABLE t1 (a GEOMETRY);
-CREATE VIEW v1 AS SELECT GeomFromwkb(ASBINARY(a)) FROM t1;
-CREATE VIEW v2 AS SELECT a FROM t1;
-DESCRIBE v1;
-DESCRIBE v2;
-
-DROP VIEW v1,v2;
-DROP TABLE t1;
-
-#
# Bug#24563: MBROverlaps does not seem to function propertly
# Bug#54888: MBROverlaps missing in 5.1?
#
@@ -760,6 +753,7 @@ drop table t1;
--echo # on char > 31 bytes".
--echo #
create table t1(a char(32) not null) engine=myisam;
+--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
--error ER_WRONG_ARGUMENTS
create spatial index i on t1 (a);
drop table t1;
@@ -828,3 +822,552 @@ SELECT GEOMETRYCOLLECTION((SELECT @@OLD));
--echo End of 5.1 tests
+
+#bug 850775 ST_AREA does not work on GEOMETRYCOLLECTIONs in maria-5.3-gis
+select ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))'));
+
+#bug 855336 ST_LENGTH does not work on GEOMETRYCOLLECTIONs
+select ST_LENGTH(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 100 30, 20 30), POINT(3 3), LINESTRING(20 20, 30 20))'));
+
+
+# Conformance tests
+#
+# C.3.3 Geometry types and functions
+#
+
+--disable_warnings
+DROP DATABASE IF EXISTS gis_ogs;
+--enable_warnings
+
+CREATE DATABASE gis_ogs;
+USE gis_ogs;
+
+--echo #
+--echo # C.3.3.1 Geometry types and functions schema construction
+--echo #
+
+# TODO: WL#2377
+#CREATE TABLE spatial_ref_sys (
+#srid INTEGER NOT NULL PRIMARY KEY,
+#auth_name CHARACTER VARYING,
+#auth_srid INTEGER,
+#srtext CHARACTER VARYING(2048));
+
+CREATE TABLE lakes (
+ fid INTEGER NOT NULL PRIMARY KEY,
+ name CHARACTER VARYING(64),
+ shore POLYGON);
+
+CREATE TABLE road_segments (
+ fid INTEGER NOT NULL PRIMARY KEY,
+ name CHARACTER VARYING(64),
+ aliases CHARACTER VARYING(64),
+ num_lanes INTEGER,
+ centerline LINESTRING);
+
+CREATE TABLE divided_routes (
+ fid INTEGER NOT NULL PRIMARY KEY,
+ name CHARACTER VARYING(64),
+ num_lanes INTEGER,
+ centerlines MULTILINESTRING);
+
+CREATE TABLE forests (
+ fid INTEGER NOT NULL PRIMARY KEY,
+ name CHARACTER VARYING(64),
+ boundary MULTIPOLYGON);
+
+CREATE TABLE bridges (
+ fid INTEGER NOT NULL PRIMARY KEY,
+ name CHARACTER VARYING(64),
+ position POINT);
+
+CREATE TABLE streams (
+ fid INTEGER NOT NULL PRIMARY KEY,
+ name CHARACTER VARYING(64),
+ centerline LINESTRING);
+
+CREATE TABLE buildings (
+ fid INTEGER NOT NULL PRIMARY KEY,
+ address CHARACTER VARYING(64),
+ position POINT,
+ footprint POLYGON);
+
+CREATE TABLE ponds (
+ fid INTEGER NOT NULL PRIMARY KEY,
+ name CHARACTER VARYING(64),
+ type CHARACTER VARYING(64),
+ shores MULTIPOLYGON);
+
+CREATE TABLE named_places (
+ fid INTEGER NOT NULL PRIMARY KEY,
+ name CHARACTER VARYING(64),
+ boundary POLYGON);
+
+CREATE TABLE map_neatlines (
+ fid INTEGER NOT NULL PRIMARY KEY,
+ neatline POLYGON);
+
+--echo #
+--echo # C.3.3.2 Geometry types and functions schema data loading
+--echo #
+
+# TODO: WL#2377
+#-- Spatial Reference System
+#INSERT INTO spatial_ref_sys VALUES
+#(101, 'POSC', 32214, 'PROJCS["UTM_ZONE_14N",
+#GEOGCS["World Geodetic System 72",
+#DATUM["WGS_72",
+#ELLIPSOID["NWL_10D", 6378135, 298.26]],
+#PRIMEM["Greenwich", 0],
+#UNIT["Meter", 1.0]],
+#PROJECTION["Transverse_Mercator"],
+#PARAMETER["False_Easting", 500000.0],
+#PARAMETER["False_Northing", 0.0],
+#PARAMETER["Central_Meridian", -99.0],
+#PARAMETER["Scale_Factor", 0.9996],
+#PARAMETER["Latitude_of_origin", 0.0],
+#UNIT["Meter", 1.0]]');
+
+--echo # Lakes
+INSERT INTO lakes VALUES (
+101, 'BLUE LAKE',
+PolyFromText(
+'POLYGON(
+(52 18,66 23,73 9,48 6,52 18),
+(59 18,67 18,67 13,59 13,59 18)
+)',
+101));
+
+
+--echo # Road Segments
+
+INSERT INTO road_segments VALUES(102, 'Route 5', NULL, 2,
+LineFromText(
+'LINESTRING( 0 18, 10 21, 16 23, 28 26, 44 31 )' ,101));
+
+INSERT INTO road_segments VALUES(103, 'Route 5', 'Main Street', 4,
+LineFromText(
+'LINESTRING( 44 31, 56 34, 70 38 )' ,101));
+
+INSERT INTO road_segments VALUES(104, 'Route 5', NULL, 2,
+LineFromText(
+'LINESTRING( 70 38, 72 48 )' ,101));
+
+INSERT INTO road_segments VALUES(105, 'Main Street', NULL, 4,
+LineFromText(
+'LINESTRING( 70 38, 84 42 )' ,101));
+
+INSERT INTO road_segments VALUES(106, 'Dirt Road by Green Forest', NULL,
+1,
+LineFromText(
+'LINESTRING( 28 26, 28 0 )',101));
+
+--echo # DividedRoutes
+
+INSERT INTO divided_routes VALUES(119, 'Route 75', 4,
+MLineFromText(
+'MULTILINESTRING((10 48,10 21,10 0),
+(16 0,16 23,16 48))', 101));
+
+--echo # Forests
+
+INSERT INTO forests VALUES(109, 'Green Forest',
+MPolyFromText(
+'MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),
+(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))',
+101));
+
+--echo # Bridges
+
+INSERT INTO bridges VALUES(110, 'Cam Bridge', PointFromText(
+'POINT( 44 31 )', 101));
+
+--echo # Streams
+
+INSERT INTO streams VALUES(111, 'Cam Stream',
+LineFromText(
+'LINESTRING( 38 48, 44 41, 41 36, 44 31, 52 18 )', 101));
+
+INSERT INTO streams VALUES(112, NULL,
+LineFromText(
+'LINESTRING( 76 0, 78 4, 73 9 )', 101));
+
+--echo # Buildings
+
+INSERT INTO buildings VALUES(113, '123 Main Street',
+PointFromText(
+'POINT( 52 30 )', 101),
+PolyFromText(
+'POLYGON( ( 50 31, 54 31, 54 29, 50 29, 50 31) )', 101));
+
+INSERT INTO buildings VALUES(114, '215 Main Street',
+PointFromText(
+'POINT( 64 33 )', 101),
+PolyFromText(
+'POLYGON( ( 66 34, 62 34, 62 32, 66 32, 66 34) )', 101));
+
+
+--echo # Ponds
+
+INSERT INTO ponds VALUES(120, NULL, 'Stock Pond',
+MPolyFromText(
+'MULTIPOLYGON( ( ( 24 44, 22 42, 24 40, 24 44) ),
+( ( 26 44, 26 40, 28 42, 26 44) ) )', 101));
+
+--echo # Named Places
+
+INSERT INTO named_places VALUES(117, 'Ashton',
+PolyFromText(
+'POLYGON( ( 62 48, 84 48, 84 30, 56 30, 56 34, 62 48) )', 101));
+
+INSERT INTO named_places VALUES(118, 'Goose Island',
+PolyFromText(
+'POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )', 101));
+
+--echo # Map Neatlines
+
+INSERT INTO map_neatlines VALUES(115,
+PolyFromText(
+'POLYGON( ( 0 0, 0 48, 84 48, 84 0, 0 0 ) )', 101));
+
+--echo #
+--echo # C.3.3.3 Geometry types and functions schema test queries
+--echo
+
+# TODO: WL#2377
+#--echo # Conformance Item T1
+#SELECT f_table_name
+#FROM geometry_columns;
+#
+#--echo # Conformance Item T2
+#SELECT f_geometry_column
+#FROM geometry_columns
+#WHERE f_table_name = 'streams';
+#
+#--echo # Conformance Item T3
+#SELECT coord_dimension
+#FROM geometry_columns
+#WHERE f_table_name = 'streams';
+#
+#--echo # Conformance Item T4
+#
+#SELECT srid
+#FROM geometry_columns
+#WHERE f_table_name = 'streams';
+#
+#--echo # Conformance Item T5
+#
+#SELECT srtext
+#FROM SPATIAL_REF_SYS
+#WHERE SRID = 101;
+#
+
+
+--echo # Conformance Item T6
+# TODO: ST_Dimension() alias
+SELECT Dimension(shore)
+FROM lakes
+WHERE name = 'Blue Lake';
+
+--echo # Conformance Item T7
+# TODO: ST_GeometryType() alias
+SELECT GeometryType(centerlines)
+FROM divided_routes
+WHERE name = 'Route 75';
+
+--echo # Conformance Item T8
+# TODO: ST_AsText() alias
+SELECT AsText(boundary)
+FROM named_places
+WHERE name = 'Goose Island';
+
+--echo # Conformance Item T9
+# TODO: ST_AsBinary(), ST_PolyFromWKB() aliases
+SELECT AsText(PolyFromWKB(AsBinary(boundary),101))
+FROM named_places
+WHERE name = 'Goose Island';
+
+--echo # Conformance Item T10
+# TODO: ST_SRID() alias
+SELECT SRID(boundary)
+FROM named_places
+WHERE name = 'Goose Island';
+
+--echo # Conformance Item T11
+# TODO: ST_IsEmpty() alias
+SELECT IsEmpty(centerline)
+FROM road_segments
+WHERE name = 'Route 5'
+AND aliases = 'Main Street';
+
+# FIXME: get wrong result:0, expected 1.
+#--echo # Conformance Item T12
+# TODO: ST_IsSimple() alias
+#SELECT IsSimple(shore)
+#FROM lakes
+#WHERE name = 'Blue Lake';
+
+# TODO: WL#2377
+#--echo # Conformance Item T13
+#SELECT AsText(Boundary((boundary),101)
+#FROM named_places
+#WHERE name = 'Goose Island';
+
+--echo # Conformance Item T14
+# TODO: ST_Envelope( ) alias
+# FIXME: we get anticlockwise, GIS suggests clockwise
+SELECT AsText(Envelope(boundary))
+FROM named_places
+WHERE name = 'Goose Island';
+
+--echo # Conformance Item T15
+# TODO: ST_X() alias
+SELECT X(position)
+FROM bridges
+WHERE name = 'Cam Bridge';
+
+--echo # Conformance Item T16
+# TODO: ST_Y() alias
+SELECT Y(position)
+FROM bridges
+WHERE name = 'Cam Bridge';
+
+--echo # Conformance Item T17
+# TODO: ST_StartPoint() alias
+SELECT AsText(StartPoint(centerline))
+FROM road_segments
+WHERE fid = 102;
+
+--echo # Conformance Item T18
+# TODO: ST_EndPoint
+SELECT AsText(EndPoint(centerline))
+FROM road_segments
+WHERE fid = 102;
+
+# TODO: WL#2377
+#--echo # Conformance Item T19
+# TODO: ST_LineFromWKB() alias
+#SELECT IsClosed(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary)))
+#FROM named_places
+#WHERE name = 'Goose Island';
+
+# TODO: WL#2377
+#--echo # Conformance Item T20
+#SELECT IsRing(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary)))
+#FROM named_places
+#WHERE name = 'Goose Island';
+
+--echo # Conformance Item T21
+# TODO: ST_Length() alias
+SELECT GLength(centerline)
+FROM road_segments
+WHERE fid = 106;
+
+--echo # Conformance Item T22
+# TODO: ST_NumPoints() alias
+SELECT NumPoints(centerline)
+FROM road_segments
+WHERE fid = 102;
+
+--echo # Conformance Item T23
+# TODO: ST_PointN() alias
+SELECT AsText(PointN(centerline, 1))
+FROM road_segments
+WHERE fid = 102;
+
+--echo # Conformance Item T24
+# TODO: ST_Centroid() alias
+SELECT AsText(Centroid(boundary))
+FROM named_places
+WHERE name = 'Goose Island';
+
+# TODO: WL#2377
+#--echo # Conformance Item T25
+#SELECT Contains(boundary, PointOnSurface(boundary))
+#FROM named_places
+#WHERE name = 'Goose Island';
+
+--echo # Conformance Item T26
+# TODO: ST_Area() alias
+SELECT Area(boundary)
+FROM named_places
+WHERE name = 'Goose Island';
+
+--echo # Conformance Item T27
+# TODO: ST_ExteriorRing() alias
+SELECT AsText(ExteriorRing(shore))
+FROM lakes
+WHERE name = 'Blue Lake';
+
+--echo # Conformance Item T28
+# TODO: ST_NumInteriorRings() alias
+SELECT NumInteriorRings(shore)
+FROM lakes
+WHERE name = 'Blue Lake';
+
+--echo # Conformance Item T29
+# TODO: ST_InteriorRingN() alias
+SELECT AsText(InteriorRingN(shore, 1))
+FROM lakes
+WHERE name = 'Blue Lake';
+
+--echo # Conformance Item T30
+# TODO: ST_NumGeometries() alias
+SELECT NumGeometries(centerlines)
+FROM divided_routes
+WHERE name = 'Route 75';
+
+--echo # Conformance Item T31
+# TODO: ST_GeometryN() alias
+SELECT AsText(GeometryN(centerlines, 2))
+FROM divided_routes
+WHERE name = 'Route 75';
+
+--echo # Conformance Item T32
+# TODO: ST_IsClosed() alias
+SELECT IsClosed(centerlines)
+FROM divided_routes
+WHERE name = 'Route 75';
+
+--echo # Conformance Item T33
+# TODO: ST_Length() alias
+SELECT GLength(centerlines)
+FROM divided_routes
+WHERE name = 'Route 75';
+
+--echo # Conformance Item T34
+# TODO: ST_Centroid() alias
+SELECT AsText(Centroid(shores))
+FROM ponds
+WHERE fid = 120;
+
+# TODO: WL#2377
+#--echo # Conformance Item T35
+#SELECT Contains(shores, PointOnSurface(shores))
+#FROM ponds
+#WHERE fid = 120;
+
+--echo # Conformance Item T36
+# TODO: ST_Area() alias
+SELECT Area(shores)
+FROM ponds
+WHERE fid = 120;
+
+--echo # Conformance Item T37
+# TODO: ST_PolyFromText() alias
+SELECT ST_Equals(boundary,
+PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1))
+FROM named_places
+WHERE name = 'Goose Island';
+
+--echo # Conformance Item T38
+SELECT ST_Disjoint(centerlines, boundary)
+FROM divided_routes, named_places
+WHERE divided_routes.name = 'Route 75'
+AND named_places.name = 'Ashton';
+
+--echo # Conformance Item T39
+SELECT ST_Touches(centerline, shore)
+FROM streams, lakes
+WHERE streams.name = 'Cam Stream'
+AND lakes.name = 'Blue Lake';
+
+# FIXME: wrong result: get 0, expected 1
+#--echo # Conformance Item T40
+#SELECT ST_Within(boundary, footprint)
+#FROM named_places, buildings
+#WHERE named_places.name = 'Ashton'
+#AND buildings.address = '215 Main Street';
+
+# FIXME: wrong result: get 0, expected 1
+#--echo # Conformance Item T41
+#SELECT ST_Overlaps(forests.boundary, named_places.boundary)
+#FROM forests, named_places
+#WHERE forests.name = 'Green Forest'
+#AND named_places.name = 'Ashton';
+
+--echo # Conformance Item T42
+# FIXME: TODO: ST_Crosses() alias
+SELECT Crosses(road_segments.centerline, divided_routes.centerlines)
+FROM road_segments, divided_routes
+WHERE road_segments.fid = 102
+AND divided_routes.name = 'Route 75';
+
+--echo # Conformance Item T43
+SELECT ST_Intersects(road_segments.centerline, divided_routes.centerlines)
+FROM road_segments, divided_routes
+WHERE road_segments.fid = 102
+AND divided_routes.name = 'Route 75';
+
+--echo # Conformance Item T44
+SELECT ST_Contains(forests.boundary, named_places.boundary)
+FROM forests, named_places
+WHERE forests.name = 'Green Forest'
+AND named_places.name = 'Ashton';
+
+# TODO: WL#2377
+#--echo # Conformance Item T45
+#SELECT Relate(forests.boundary, named_places.boundary, 'TTTTTTTTT')
+#FROM forests, named_places
+#WHERE forests.name = 'Green Forest'
+#AND named_places.name = 'Ashton';
+
+--echo # Conformance Item T46
+SELECT ST_Distance(position, boundary)
+FROM bridges, named_places
+WHERE bridges.name = 'Cam Bridge'
+AND named_places.name = 'Ashton';
+
+# FIXME: wrong result: NULL, expected 12
+#--echo # Conformance Item T47
+#SELECT AsText(ST_Intersection(centerline, shore))
+#FROM streams, lakes
+#WHERE streams.name = 'Cam Stream'
+#AND lakes.name = 'Blue Lake';
+
+--echo # Conformance Item T48
+SELECT AsText(ST_Difference(named_places.boundary, forests.boundary))
+FROM named_places, forests
+WHERE named_places.name = 'Ashton'
+AND forests.name = 'Green Forest';
+
+#--echo # Conformance Item T49
+SELECT AsText(ST_Union(shore, boundary))
+FROM lakes, named_places
+WHERE lakes.name = 'Blue Lake'
+AND named_places.name = 'Goose Island';
+
+--echo # Conformance Item T50
+SELECT AsText(ST_SymDifference(shore, boundary))
+FROM lakes, named_places
+WHERE lakes.name = 'Blue Lake'
+AND named_places.name = 'Ashton';
+
+--echo # Conformance Item T51
+SELECT count(*)
+FROM buildings, bridges
+WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1;
+
+# TODO: WL#2377
+#--echo # Conformance Item T52
+#SELECT AsText(ConvexHull(shore))
+#FROM lakes
+#WHERE lakes.name = 'Blue Lake';
+
+DROP DATABASE gis_ogs;
+
+--echo #
+--echo # BUG #1043845 st_distance() results are incorrect depending on variable order
+--echo #
+
+select st_distance(geomfromtext('LINESTRING(-95.9673005697771 36.13509598461,
+ -95.9673057475387 36.1344478941074,
+ -95.9673063519371 36.134484524621,
+ -95.9673049102515 36.1343976584193)'),
+ geomfromtext('point(-95.96269500000000000000 36.14181833333330000000)')) ;
+select st_distance(geomfromtext('point(-95.96269500000000000000 36.14181833333330000000)'),
+ geomfromtext('LINESTRING(-95.9673005697771 36.13509598461,
+ -95.9673057475387 36.1344478941074,
+ -95.9673063519371 36.134484524621,
+ -95.9673049102515 36.1343976584193) ')) ;
+
diff --git a/mysql-test/t/greedy_optimizer.test b/mysql-test/t/greedy_optimizer.test
index 5131c97f122..8f969f2562a 100644
--- a/mysql-test/t/greedy_optimizer.test
+++ b/mysql-test/t/greedy_optimizer.test
@@ -10,6 +10,9 @@
drop table if exists t1,t2,t3,t4,t5,t6,t7;
--enable_warnings
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
+
create table t1 (
c11 integer,c12 integer,c13 integer,c14 integer,c15 integer,c16 integer,
primary key (c11)
@@ -384,3 +387,5 @@ SET optimizer_search_depth = DEFAULT;
DROP TABLE t1,t2,t2_1,t3,t3_1,t4,t4_1,t5,t5_1;
--echo End of 5.0 tests
+
+set join_cache_level=@save_join_cache_level;
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index 71d53fc9592..4722a84822d 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -338,8 +338,11 @@ drop table t1,t2;
CREATE TABLE t1 (ID1 int, ID2 int, ID int NOT NULL AUTO_INCREMENT,PRIMARY KEY(ID
));
insert into t1 values (1,244,NULL),(2,243,NULL),(134,223,NULL),(185,186,NULL);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select S.ID as xID, S.ID1 as xID1 from t1 as S left join t1 as yS on S.ID1 between yS.ID1 and yS.ID2;
select S.ID as xID, S.ID1 as xID1, repeat('*',count(distinct yS.ID)) as Level from t1 as S left join t1 as yS on S.ID1 between yS.ID1 and yS.ID2 group by xID order by xID1;
+SET optimizer_switch=@save_optimizer_switch;
drop table t1;
#
@@ -1031,16 +1034,22 @@ EXPLAIN SELECT a FROM t1
USE INDEX FOR JOIN (i2)
USE INDEX FOR JOIN (i2,i2);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
EXPLAIN SELECT 1 FROM t1 WHERE a IN
(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+SET optimizer_switch=@save_optimizer_switch;
CREATE TABLE t2 (a INT, b INT, KEY(a));
INSERT INTO t2 VALUES (1, 1), (2, 2), (3,3), (4,4);
EXPLAIN SELECT a, SUM(b) FROM t2 GROUP BY a LIMIT 2;
EXPLAIN SELECT a, SUM(b) FROM t2 IGNORE INDEX (a) GROUP BY a LIMIT 2;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
EXPLAIN SELECT 1 FROM t2 WHERE a IN
(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+SET optimizer_switch=@save_optimizer_switch;
SHOW VARIABLES LIKE 'old';
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
@@ -1442,7 +1451,17 @@ t2_1.b + 1 > 0 OR
a = t2_1.c
GROUP BY zzz;
---echo #TODO: in merge with 5.3 add original test suite
+SET @save_optimizer_switch967242=@@optimizer_switch;
+SET optimizer_switch = 'in_to_exists=on';
+
+SELECT t2_1.b
+FROM t1 JOIN t2 AS t2_1 JOIN t2 AS t2_2
+ ON (t2_2.b = t2_1.b ) AND (t2_2.c = t2_1.c )
+WHERE
+ ( SELECT COUNT(*) FROM t2 ) IS NOT NULL
+ OR a = t2_1.c
+GROUP BY t2_1.b;
+SET optimizer_switch=@save_optimizer_switch967242;
drop table t1, t2;
@@ -1509,3 +1528,71 @@ SELECT max(1) FROM t1 WHERE a!=0;
drop table t1;
--echo # End of 5.2 tests
+
+--echo #
+--echo # lp:872702 Crash in add_ref_to_table_cond() when grouping by a PK
+--echo #
+CREATE TABLE t1 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (14),(15),(16),(17),(18),(19),(20);
+
+CREATE TABLE t2 (a int) ;
+
+SELECT a
+FROM t1
+WHERE a = (
+ SELECT t2.a
+ FROM t2
+) OR t1.a = 73
+GROUP BY 1;
+DROP TABLE t1, t2;
+
+#
+# MDEV-736 LP:1004615 - Unexpected warnings "Encountered illegal value '' when converting to DECIMAL" on a query with aggregate functions and GROUP BY
+#
+
+FLUSH STATUS; # this test case *must* use Aria temp tables
+
+CREATE TABLE t1 (f1 INT, f2 decimal(20,1), f3 blob);
+INSERT INTO t1 values(11,NULL,'blob'),(11,NULL,'blob');
+SELECT f3, MIN(f2) FROM t1 GROUP BY f1 LIMIT 1;
+DROP TABLE t1;
+
+--echo the value below *must* be 1
+show status like 'Created_tmp_disk_tables';
+
+--echo #
+--echo # Bug #1002146: Unneeded filesort if usage of join buffer is not allowed
+--echo # (bug mdev-645)
+--echo #
+
+CREATE TABLE t1 (pk int PRIMARY KEY, a int, INDEX idx(a));
+INSERT INTO t1 VALUES (3,2), (2,3), (5,3), (6,4);
+
+CREATE TABLE t2 (pk int PRIMARY KEY, a int, INDEX idx(a));
+INSERT INTO t2 VALUES (9,0), (10,3), (6,4), (1,6), (3,100), (5,200);
+
+set join_cache_level=0;
+
+EXPLAIN
+SELECT t2.a FROM t2 STRAIGHT_JOIN t1 ON t2.a <> 0 WHERE t2.a <> 6
+ GROUP BY t2.a;
+SELECT t2.a FROM t2 STRAIGHT_JOIN t1 ON t2.a <> 0 WHERE t2.a <> 6
+ GROUP BY t2.a;
+
+set join_cache_level=default;
+
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='outer_join_with_cache=off';
+
+EXPLAIN
+SELECT t2.a FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t2.a <> 6
+ GROUP BY t2.a;
+SELECT t2.a FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t2.a <> 6
+ GROUP BY t2.a;
+
+set optimizer_switch=@save_optimizer_switch;
+
+
+DROP TABLE t1,t2;
+
+--echo # End of 5.3 tests
diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test
index e033111707e..28d375f7dda 100644
--- a/mysql-test/t/group_min_max.test
+++ b/mysql-test/t/group_min_max.test
@@ -406,11 +406,67 @@ explain select a1,a2,b,min(c),max(c) from t1
where exists ( select * from t2 where t2.c = t1.c )
group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1
+where exists ( select * from t2 where t2.c = t1.c )
+group by a1,a2,b;
+
# the sub-select is unrelated to MIN/MAX
explain select a1,a2,b,min(c),max(c) from t1
where exists ( select * from t2 where t2.c > 'b1' )
group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1
+where exists ( select * from t2 where t2.c > 'b1' )
+group by a1,a2,b;
+
+# correlated subselect that doesn't reference the min/max argument
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2 where t1.b > 'a' and t2.c > 'b1' )
+group by a1,a2,b;
+
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2 where t1.b > 'a' and t2.c > 'b1' )
+group by a1,a2,b;
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+ where t2.c in (select c from t3 where t3.c > t1.b) and
+ t2.c > 'b1' )
+group by a1,a2,b;
+
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+ where t2.c in (select c from t3 where t3.c > t1.b) and
+ t2.c > 'b1' )
+group by a1,a2,b;
+SET optimizer_switch=@save_optimizer_switch;
+
+# correlated subselect that references the min/max argument
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2 where t1.c > 'a' and t2.c > 'b1' )
+group by a1,a2,b;
+
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2 where t1.c > 'a' and t2.c > 'b1' )
+group by a1,a2,b;
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+ where t2.c in (select c from t3 where t3.c > t1.c) and
+ t2.c > 'b1' )
+group by a1,a2,b;
+
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+ where t2.c in (select c from t3 where t3.c > t1.c) and
+ t2.c > 'b1' )
+group by a1,a2,b;
+SET optimizer_switch=@save_optimizer_switch;
+
# A,B,C) Predicates referencing mixed classes of attributes
# plans
@@ -1147,3 +1203,62 @@ WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
drop table t1;
--echo End of 5.1 tests
+
+--echo #
+--echo # MDEV-765: LP:825075 - Wrong result with GROUP BY + multipart key + MIN/MAX loose scan
+--echo #
+
+CREATE TABLE t1 (a varchar(1), b varchar(1), KEY (b,a));
+INSERT INTO t1 VALUES
+('0',NULL),('9',NULL),('8','c'),('4','d'),('7','d'),(NULL,'f'),
+('7','f'),('8','g'),(NULL,'j');
+
+explain
+SELECT max(a) , b FROM t1 WHERE a IS NULL OR b = 'z' GROUP BY b;
+SELECT max(a) , b FROM t1 WHERE a IS NULL OR b = 'z' GROUP BY b;
+
+explain
+SELECT b, min(a) FROM t1 WHERE a = '7' OR b = 'z' GROUP BY b;
+SELECT b, min(a) FROM t1 WHERE a = '7' OR b = 'z' GROUP BY b;
+
+explain
+SELECT b, min(a) FROM t1 WHERE (a = b OR b = 'd' OR b is NULL) GROUP BY b;
+SELECT b, min(a) FROM t1 WHERE (a = b OR b = 'd' OR b is NULL) GROUP BY b;
+
+explain
+SELECT b, min(a) FROM t1 WHERE a > ('0' = b) AND b = 'z' GROUP BY b;
+SELECT b, min(a) FROM t1 WHERE a > ('0' = b) AND b = 'z' GROUP BY b;
+
+explain
+SELECT b, min(a) FROM t1 WHERE a > '0' AND (b < (a = '7')) GROUP BY b;
+SELECT b, min(a) FROM t1 WHERE a > '0' AND (b < (a = '7')) GROUP BY b;
+
+explain
+SELECT b, min(a) FROM t1 WHERE (a > '0' AND (a > '1' OR b = 'd')) GROUP BY b;
+SELECT b, min(a) FROM t1 WHERE (a > '0' AND (a > '1' OR b = 'd')) GROUP BY b;
+
+drop table t1;
+
+--echo #
+--echo # MDEV-4140 Wrong result with GROUP BY + multipart key + MIN/MAX loose scan and a subquery
+--echo #
+
+CREATE TABLE t1 (a int, b int, KEY (b, a)) ;
+INSERT INTO t1 VALUES (0,99),(9,99),(4,0),(7,0),(99,0),(7,0),(8,0),(99,0),(1,0);
+CREATE TABLE t2 (c int) ;
+INSERT INTO t2 VALUES (0),(1);
+
+EXPLAIN
+SELECT MIN(a), b FROM t1 WHERE a > 0 GROUP BY b;
+SELECT MIN(a), b FROM t1 WHERE a > 0 GROUP BY b;
+EXPLAIN
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT c FROM t2 WHERE c = 0 ) GROUP BY b;
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT c FROM t2 WHERE c = 0 ) GROUP BY b;
+# this test is for 5.5 to ensure that the subquery is expensive
+EXPLAIN
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT min(c) FROM t2, t1 t1a, t1 t1b WHERE c = 0 ) GROUP BY b;
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT min(c) FROM t2, t1 t1a, t1 t1b WHERE c = 0 ) GROUP BY b;
+
+drop table t1, t2;
+
+--echo End of 5.3 tests
diff --git a/mysql-test/t/handlersocket.test b/mysql-test/t/handlersocket.test
new file mode 100644
index 00000000000..3d6499d3af5
--- /dev/null
+++ b/mysql-test/t/handlersocket.test
@@ -0,0 +1,11 @@
+--source include/have_dynamic_loading.inc
+--source include/not_windows_embedded.inc
+
+if (`select length('$HANDLERSOCKET_SO') = 0`) {
+ skip handlersocket plugin is not built;
+}
+
+install plugin handlersocket soname 'handlersocket.so';
+--query_vertical select plugin_name, plugin_version, plugin_status, plugin_type, plugin_library, plugin_library_version, plugin_author, plugin_description plugin_license, plugin_maturity, plugin_auth_version from information_schema.plugins where plugin_name = 'handlersocket'
+uninstall plugin handlersocket;
+
diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test
index df3f217be85..3edf449c92d 100644
--- a/mysql-test/t/having.test
+++ b/mysql-test/t/having.test
@@ -629,7 +629,6 @@ DROP TABLE t1,t2,t3;
--echo # LP bug:806955 HAVING not observed with aggregate +subquery
--echo #
-#in 5.3 here optimizer_switch should be saved, and semijoin switched off
CREATE TABLE t1 (f3 int, f10 varchar(1), f11 int, KEY (f10) );
INSERT INTO t1 VALUES (NULL,'a',0),(8,'b',0);
@@ -639,19 +638,22 @@ INSERT INTO t2 VALUES (7);
CREATE TABLE t3 (f3 int);
INSERT INTO t3 VALUES (0),(8);
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=off,materialization=off';
+
SELECT MIN( t1.f10 ) AS field1
FROM t1 , t2
WHERE t2.f2 IN ( SELECT f3 FROM t3 )
HAVING field1 < 's';
-explain extended
+explain extended
SELECT MIN( t1.f10 ) AS field1
FROM t1 , t2
WHERE t2.f2 IN ( SELECT f3 FROM t3 )
HAVING field1 < 's';
-#in 5.3 here optimizer_switch should be restored
-drop table t1,t2,t3;
+set optimizer_switch=@save_optimizer_switch;
+drop table t1,t2,t3;
--echo End of 5.2 tests
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 c8efddc9958..920f261201d 100644
--- a/mysql-test/t/heap_hash.test
+++ b/mysql-test/t/heap_hash.test
@@ -299,3 +299,22 @@ INSERT INTO t1 VALUES (4, NULL);
EXPLAIN SELECT * FROM t1 WHERE val IS NULL;
SELECT * FROM t1 WHERE val IS NULL;
drop table t1;
+
+--echo End of 5.2 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/ignore_db_dirs_basic-master.opt b/mysql-test/t/ignore_db_dirs_basic-master.opt
new file mode 100644
index 00000000000..30ee4f67284
--- /dev/null
+++ b/mysql-test/t/ignore_db_dirs_basic-master.opt
@@ -0,0 +1,11 @@
+--ignore-db-dir=a
+--ignore-db-dir=b
+--ignore-db-dir=c
+--ignore-db-dir=
+--ignore-db-dir=d
+--ignore-db-dir x
+--ignore-db-dir=
+--ignore-db-dir=e
+--ignore-db-dir=lost+found
+--ignore-db-dir=.mysqlgui
+--ignore-db-dir=ignored_db
diff --git a/mysql-test/t/ignore_db_dirs_basic.test b/mysql-test/t/ignore_db_dirs_basic.test
new file mode 100644
index 00000000000..9544fc540f9
--- /dev/null
+++ b/mysql-test/t/ignore_db_dirs_basic.test
@@ -0,0 +1,38 @@
+select @@ignore_db_dirs;
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+mkdir $MYSQLD_DATADIR/.mysqlgui;
+mkdir $MYSQLD_DATADIR/.otherdir;
+mkdir $MYSQLD_DATADIR/lost+found;
+mkdir $MYSQLD_DATADIR/ignored_db;
+--echo # Check that SHOW DATABASES ignores all directories from
+--echo # @@ignore_db_dirs and all directories with names starting
+--echo # with '.'
+SHOW DATABASES;
+--error ER_WRONG_DB_NAME
+USE ignored_db;
+--error ER_WRONG_DB_NAME
+SELECT * FROM ignored_db.t1;
+--error ER_WRONG_DB_NAME
+CALL ignored_db.p1();
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='ignored_db';
+--error ER_WRONG_DB_NAME
+CREATE DATABASE ignored_db;
+CREATE DATABASE `lost+found`;
+USE `lost+found`;
+CREATE TABLE t1(id INT);
+INSERT INTO t1 VALUES (1), (2);
+SELECT * FROM `lost+found`.t1;
+SHOW DATABASES;
+DROP DATABASE `lost+found`;
+rmdir $MYSQLD_DATADIR/.mysqlgui;
+rmdir $MYSQLD_DATADIR/.otherdir;
+rmdir $MYSQLD_DATADIR/lost+found;
+rmdir $MYSQLD_DATADIR/ignored_db;
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@global.ignore_db_dirs = 'aha';
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@local.ignore_db_dirs = 'aha';
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@ignore_db_dirs = 'aha';
diff --git a/mysql-test/t/in_datetime_241.test b/mysql-test/t/in_datetime_241.test
new file mode 100644
index 00000000000..f95a456f5e2
--- /dev/null
+++ b/mysql-test/t/in_datetime_241.test
@@ -0,0 +1,9 @@
+#
+# MDEV-241 lp:992722 - Server crashes in get_datetime_value
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+CREATE TABLE t1 ( a DATE );
+SELECT * FROM t1 WHERE ( SELECT a FROM t1 ) IN ('2012-04-25','2012-04-26');
+DROP TABLE t1;
diff --git a/mysql-test/t/index_intersect.test b/mysql-test/t/index_intersect.test
new file mode 100644
index 00000000000..c2834e685eb
--- /dev/null
+++ b/mysql-test/t/index_intersect.test
@@ -0,0 +1,453 @@
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2,t3,t4;
+DROP DATABASE IF EXISTS world;
+--enable_warnings
+
+set names utf8;
+
+CREATE DATABASE world;
+
+use world;
+
+--source include/world_schema.inc
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+--source include/world.inc
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+SELECT COUNT(*) FROM Country;
+SELECT COUNT(*) FROM City;
+SELECT COUNT(*) FROM CountryLanguage;
+
+CREATE INDEX Name ON City(Name);
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+ANALYZE TABLE City;
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+SET SESSION optimizer_switch='index_merge_sort_intersection=on';
+
+SELECT COUNT(*) FROM City;
+
+# The output of the next 6 queries tells us about selectivities
+# of the conditions utilized in 4 queries following after them
+
+SELECT COUNT(*) FROM City WHERE Name LIKE 'C%';
+SELECT COUNT(*) FROM City WHERE Name LIKE 'M%';
+SELECT COUNT(*) FROM City WHERE Population > 1000000;
+SELECT COUNT(*) FROM City WHERE Population > 1500000;
+SELECT COUNT(*) FROM City WHERE Population > 300000;
+SELECT COUNT(*) FROM City WHERE Population > 7000000;
+
+# The pattern of the WHERE condition used in the following 4 queries is
+# range(key1) AND range(key2)
+# Varying values of the constants in the conjuncts of the condition
+# we can get either an index intersection retrieval over key1 and key2
+# or a range index scan for one of these indexes
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City WHERE
+ Name LIKE 'C%' AND Population > 1000000;
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City WHERE
+ Name LIKE 'M%' AND Population > 1500000;
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE Name LIKE 'M%' AND Population > 300000;
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE Name LIKE 'M%' AND Population > 7000000;
+
+
+# The following 8 queries check that
+# the previous 4 plans are valid and return
+# the correct results when executed
+
+--sorted_result
+SELECT * FROM City USE INDEX ()
+ WHERE Name LIKE 'C%' AND Population > 1000000;
+--sorted_result
+SELECT * FROM City
+ WHERE Name LIKE 'C%' AND Population > 1000000;
+
+--sorted_result
+SELECT * FROM City USE INDEX ()
+ WHERE Name LIKE 'M%' AND Population > 1500000;
+--sorted_result
+SELECT * FROM City
+ WHERE Name LIKE 'M%' AND Population > 1500000;
+
+--sorted_result
+SELECT * FROM City USE INDEX ()
+ WHERE Name LIKE 'M%' AND Population > 300000;
+--sorted_result
+SELECT * FROM City
+ WHERE Name LIKE 'M%' AND Population > 300000;
+
+
+SELECT * FROM City USE INDEX ()
+ WHERE Name LIKE 'M%' AND Population > 7000000;
+
+SELECT * FROM City
+ WHERE Name LIKE 'M%' AND Population > 7000000;
+
+
+# The output of the next 7 queries tells us about selectivities
+# of the conditions utilized in 3 queries following after them
+
+SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N';
+SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'J';
+SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'K';
+SELECT COUNT(*) FROM City WHERE Population > 1000000;
+SELECT COUNT(*) FROM City WHERE Population > 500000;
+SELECT COUNT(*) FROM City WHERE Country LIKE 'C%';
+SELECT COUNT(*) FROM City WHERE Country LIKE 'B%';
+
+
+# The pattern of the WHERE condition used in the following 3 queries is
+# range(key1) AND range(key2) AND range(key3)
+# Varying values of the constants in the conjuncts of the condition
+# we can get index intersection over different pairs of keys:
+# over(key1,key2), over(key1,key3) and over(key2,key3)
+
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
+
+--replace_column 7 # 9 #
+--replace_result Population,Country,Name Population,Name,Country
+EXPLAIN
+SELECT * FROM City
+ WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+
+
+# The following 6 queries check that
+# the previous 3 plans are valid and return
+# the correct results when executed
+
+
+SELECT * FROM City USE INDEX ()
+ WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
+
+SELECT * FROM City
+ WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
+
+
+SELECT * FROM City USE INDEX ()
+ WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
+
+SELECT * FROM City
+ WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
+
+
+SELECT * FROM City USE INDEX ()
+ WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+
+SELECT * FROM City
+ WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+
+
+# The output of the next 12 queries tells us about selectivities
+# of the conditions utilized in 5 queries following after them
+
+SELECT COUNT(*) FROM City WHERE ID BETWEEN 501 AND 1000;
+SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 500;
+SELECT COUNT(*) FROM City WHERE ID BETWEEN 2001 AND 2500;
+SELECT COUNT(*) FROM City WHERE ID BETWEEN 3701 AND 4000;
+SELECT COUNT(*) FROM City WHERE Population > 700000;
+SELECT COUNT(*) FROM City WHERE Population > 1000000;
+SELECT COUNT(*) FROM City WHERE Population > 300000;
+SELECT COUNT(*) FROM City WHERE Population > 600000;
+SELECT COUNT(*) FROM City WHERE Country LIKE 'C%';
+SELECT COUNT(*) FROM City WHERE Country LIKE 'A%';
+SELECT COUNT(*) FROM City WHERE Country LIKE 'H%';
+SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z';
+
+
+# The pattern of the WHERE condition used in the following 5 queries is
+# range(key1) AND range(key2) AND range(key3)
+# with key1 happens to be a primary key (it matters only for InnoDB)
+# Varying values of the constants in the conjuncts of the condition
+# we can get index intersection either over all three keys, or over
+# different pairs, or a range scan over one of these keys.
+# Bear in mind that the condition (Country LIKE 'A%') is actually
+# equivalent to the condition (Country BETWEEN 'A' AND 'B') for the
+# tested instance the table City.
+
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%';
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000
+ AND Country BETWEEN 'S' AND 'Z';
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+ AND Country BETWEEN 'S' AND 'Z' ;
+
+
+# The following 10 queries check that
+# the previous 5 plans are valid and return
+# the correct results when executed
+
+
+SELECT * FROM City USE INDEX ()
+ WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
+
+SELECT * FROM City
+ WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
+
+--sorted_result
+SELECT * FROM City USE INDEX ()
+ WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+--sorted_result
+SELECT * FROM City
+ WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+
+
+SELECT * FROM City USE INDEX ()
+ WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%';
+
+SELECT * FROM City
+ WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%';
+
+--sorted_result
+SELECT * FROM City USE INDEX ()
+ WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000
+ AND Country BETWEEN 'S' AND 'Z';
+--sorted_result
+SELECT * FROM City
+ WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000
+ AND Country BETWEEN 'S' AND 'Z';
+
+--sorted_result
+SELECT * FROM City USE INDEX ()
+ WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+ AND Country BETWEEN 'S' AND 'Z' ;
+--sorted_result
+SELECT * FROM City
+ WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+ AND Country BETWEEN 'S' AND 'Z' ;
+
+
+SET SESSION sort_buffer_size = 2048;
+
+
+# The following EXPLAIN command demonstrate that the execution plans
+# may be different if sort_buffer_size is set to a small value
+
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City WHERE
+ Name LIKE 'C%' AND Population > 1000000;
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City WHERE
+ Name LIKE 'M%' AND Population > 1500000;
+
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+ AND Country BETWEEN 'S' AND 'Z';
+
+
+#Yet the query themselves return the correct results in this case as well
+
+--sorted_result
+SELECT * FROM City WHERE
+ Name LIKE 'C%' AND Population > 1000000;
+
+SELECT * FROM City WHERE
+ Name LIKE 'M%' AND Population > 1500000;
+
+
+SELECT * FROM City
+ WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'B%';
+
+SELECT * FROM City
+ WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+
+
+SELECT * FROM City
+ WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
+--sorted_result
+SELECT * FROM City
+ WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
+ AND Country BETWEEN 'S' AND 'Z';
+
+
+SET SESSION sort_buffer_size = default;
+
+# Instead of the index on the column Country create two compound indexes
+# including this column as the first component
+
+DROP INDEX Country ON City;
+
+CREATE INDEX CountryID ON City(Country,ID);
+CREATE INDEX CountryName ON City(Country,Name);
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+ANALYZE TABLE City;
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+# Check that the first component of a compound index can be used for
+# index intersection, even in the cases when we have a ref access
+# for this component
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE Country LIKE 'M%' AND Population > 1000000;
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE Country='CHN' AND Population > 1500000;
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%';
+
+
+# Check that the previous 3 plans return the right results when executed
+
+--sorted_result
+SELECT * FROM City USE INDEX ()
+ WHERE Country LIKE 'M%' AND Population > 1000000;
+--sorted_result
+SELECT * FROM City
+ WHERE Country LIKE 'M%' AND Population > 1000000;
+
+--sorted_result
+SELECT * FROM City USE INDEX ()
+ WHERE Country='CHN' AND Population > 1500000;
+--sorted_result
+SELECT * FROM City
+ WHERE Country='CHN' AND Population > 1500000;
+
+
+SELECT * FROM City USE INDEX ()
+ WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%';
+
+SELECT * FROM City
+ WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%';
+
+
+#
+# Bug #754521: wrong cost of index intersection leading
+# to the choice of a suboptimal execution plan
+#
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City, Country
+ WHERE City.Name LIKE 'C%' AND City.Population > 1000000 AND
+ Country.Code=City.Country;
+
+DROP DATABASE world;
+
+use test;
+
+#
+# Bug #684086: crash with EXPLAIN in InnoDB for index intersection
+# of two indexes one of which is primary
+#
+
+CREATE TABLE t1 (
+ f1 int,
+ f4 varchar(32),
+ f5 int,
+ PRIMARY KEY (f1),
+ KEY (f4)
+) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES
+ (5,'H',1), (9,'g',0), (527,'i',0), (528,'y',1), (529,'S',6),
+ (530,'m',7), (531,'b',2), (532,'N',1), (533,'V',NULL), (534,'l',1),
+ (535,'M',0), (536,'w',1), (537,'j',5), (538,'l',0), (539,'n',2),
+ (540,'m',2), (541,'r',2), (542,'l',2), (543,'h',3),(544,'o',0),
+ (956,'h',0), (957,'g',0), (958,'W',5), (959,'s',3), (960,'w',0),
+ (961,'q',0), (962,'e',NULL), (963,'u',7), (964,'q',1), (965,'N',NULL),
+ (966,'e',0), (967,'t',3), (968,'e',6), (969,'f',NULL), (970,'j',0),
+ (971,'s',3), (972,'I',0), (973,'h',4), (974,'g',1), (975,'s',0),
+ (976,'r',3), (977,'x',1), (978,'v',8), (979,'j',NULL), (980,'z',7),
+ (981,'t',9), (982,'j',5), (983,'u',NULL), (984,'g',6), (985,'w',1),
+ (986,'h',1), (987,'v',0), (988,'v',0), (989,'c',2), (990,'b',7),
+ (991,'z',0), (992,'M',1), (993,'u',2), (994,'r',2), (995,'b',4),
+ (996,'A',2), (997,'u',0), (998,'a',0), (999,'j',2), (1,'I',2);
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+
+DROP TABLE t1;
+
+SET SESSION optimizer_switch='index_merge_sort_intersection=on';
diff --git a/mysql-test/t/index_intersect_innodb.test b/mysql-test/t/index_intersect_innodb.test
new file mode 100644
index 00000000000..22c0e807558
--- /dev/null
+++ b/mysql-test/t/index_intersect_innodb.test
@@ -0,0 +1,7 @@
+--source include/have_innodb.inc
+
+SET SESSION STORAGE_ENGINE='InnoDB';
+
+--source t/index_intersect.test
+
+SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test
index 04f8c5a659b..8ca36b14490 100644
--- a/mysql-test/t/index_merge_innodb.test
+++ b/mysql-test/t/index_merge_innodb.test
@@ -18,6 +18,11 @@ let $engine_type= InnoDB;
# InnoDB does not support Merge tables (affects include/index_merge1.inc)
let $merge_table_support= 0;
+set @optimizer_switch_save= @@optimizer_switch;
+
+set optimizer_switch='index_merge_sort_intersection=off';
+
+
# The first two tests are disabled because of non deterministic explain output.
# If include/index_merge1.inc can be enabled for InnoDB and all other
# storage engines, please remove the subtest for Bug#21277 from
@@ -63,6 +68,8 @@ INSERT INTO t1(a,b) SELECT a,b FROM t1;
INSERT INTO t1 VALUES (1000000, 0, 0);
SET SESSION sort_buffer_size = 1024*36;
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
# We have to use FORCE INDEX here as Innodb gives inconsistent estimates
# which causes different query plans.
@@ -84,3 +91,72 @@ SELECT COUNT(*) FROM
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
DROP TABLE t1;
+set optimizer_switch=@tmp_optimizer_switch;
+
+--echo #
+--echo # Testcase Backport: BUG#48093: 6.0 Server not processing equivalent IN clauses properly
+--echo # with Innodb tables
+--echo #
+
+CREATE TABLE t1 (
+ i int(11) DEFAULT NULL,
+ v1 varchar(1) DEFAULT NULL,
+ v2 varchar(20) DEFAULT NULL,
+ KEY i (i),
+ KEY v (v1,i)
+) ENGINE=innodb;
+
+INSERT INTO t1 VALUES (1,'f','no');
+INSERT INTO t1 VALUES (2,'u','yes-u');
+INSERT INTO t1 VALUES (2,'h','yes-h');
+INSERT INTO t1 VALUES (3,'d','no');
+
+--echo
+SELECT v2
+FROM t1
+WHERE v1 IN ('f', 'd', 'h', 'u' ) AND i = 2;
+
+--echo
+--echo # Should not use index_merge
+EXPLAIN
+SELECT v2
+FROM t1
+WHERE v1 IN ('f', 'd', 'h', 'u' ) AND i = 2;
+
+DROP TABLE t1;
+
+--echo #
+--echo # BUG#1006164: Multi-table DELETE that uses innodb + index_merge/intersect may fail to delete rows
+--echo #
+
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (
+ pk int auto_increment,
+ zone_id int,
+ modified tinyint,
+ primary key(pk),
+ key (zone_id),
+ key (modified)
+) engine=innodb;
+
+insert into t1 (zone_id, modified) select 0,0 from t0 A, t0 B, t0 C, t0 D;
+update t1 set zone_id=487, modified=9 where pk=7259;
+update t1 set zone_id=487, modified=9 where pk=7260;
+update t1 set zone_id=830, modified=9 where pk=8434;
+update t1 set zone_id=830, modified=9 where pk=8435;
+update t1 set zone_id=830, modified=9 where pk=8436;
+update t1 set zone_id=830, modified=9 where pk=8437;
+
+select * from t1 where t1.zone_id=830 AND modified=9;
+begin;
+DELETE t1 FROM t1 WHERE t1.zone_id=830 AND modified=9;
+commit;
+select * from t1 where t1.zone_id=830 AND modified=9;
+
+drop table t0, t1;
+
+
+set optimizer_switch= @optimizer_switch_save;
+
diff --git a/mysql-test/t/index_merge_myisam.test b/mysql-test/t/index_merge_myisam.test
index 0c4b9c6886c..614c6595d61 100644
--- a/mysql-test/t/index_merge_myisam.test
+++ b/mysql-test/t/index_merge_myisam.test
@@ -14,84 +14,16 @@ let $engine_type= MyISAM;
# MyISAM supports Merge tables
let $merge_table_support= 1;
+set @optimizer_switch_save= @@optimizer_switch;
+
+set optimizer_switch='index_merge_sort_intersection=off';
+
--source include/index_merge1.inc
--source include/index_merge_ror.inc
--source include/index_merge2.inc
--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),
@@ -164,7 +96,7 @@ set optimizer_switch='default,index_merge=off';
explain select * from t1 where a=10 and b=10;
--echo No intersect if it is disabled:
-set optimizer_switch='default,index_merge_intersection=off';
+set optimizer_switch='default,index_merge_sort_intersection=off,index_merge_intersection=off';
explain select * from t1 where a=10 and b=10;
--echo Do intersect when union was disabled
@@ -190,8 +122,32 @@ 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;
+
+--echo #
+--echo # BUG#834514 Assertion `!table || (!table->read_set || bitmap_is_set(...' with aggregates
+--echo #
+CREATE TABLE t1 ( a int , b int, c int, KEY (b), PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (1,4,0),(5,0,0),(6,7,0),(7,7,0),(8,1,0),(9,7,0),(10,1,0);
+
+CREATE TABLE t2 ( b int, c int, KEY (c,b)) ;
+INSERT INTO t2 VALUES (7,0),(1,0),(7,0),(1,0);
+
+CREATE TABLE t3 ( a int ) ;
+
+SELECT COUNT(DISTINCT t2.b), CONCAT(t1.c)
+FROM t1, t2
+WHERE (t2.c = t1.c)
+AND (
+ t1.b IN ( 4 )
+ OR t1.a = 137
+ AND EXISTS ( SELECT a FROM t3 )
+)
+GROUP BY 2;
+
+DROP TABLE t1,t2,t3;
+
+set optimizer_switch= @optimizer_switch_save;
+
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index ae733443479..616b22245f3 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -962,6 +962,8 @@ DROP FUNCTION get_value;
#
# Bug#22413 EXPLAIN SELECT FROM view with ORDER BY yield server crash
#
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
create view v1 as
select table_schema as object_schema,
table_name as object_name,
@@ -970,6 +972,7 @@ from information_schema.tables
order by object_schema;
explain select * from v1;
explain select * from (select table_name from information_schema.tables) as a;
+set optimizer_switch=@tmp_optimizer_switch;
drop view v1;
#
diff --git a/mysql-test/t/information_schema_all_engines.test b/mysql-test/t/information_schema_all_engines.test
index 9ede9f7d92a..db40889006c 100644
--- a/mysql-test/t/information_schema_all_engines.test
+++ b/mysql-test/t/information_schema_all_engines.test
@@ -29,7 +29,7 @@ SELECT t.table_name, c1.column_name
WHERE c2.table_schema = t.table_schema AND
c2.table_name = t.table_name AND
c2.column_name LIKE '%SCHEMA%'
- );
+ ) order by t.table_name;
--sorted_result
SELECT t.table_name, c1.column_name
FROM information_schema.tables t
@@ -44,7 +44,7 @@ SELECT t.table_name, c1.column_name
WHERE c2.table_schema = 'information_schema' AND
c2.table_name = t.table_name AND
c2.column_name LIKE '%SCHEMA%'
- );
+ ) order by t.table_name;
#
# Bug#24630 Subselect query crashes mysqld
@@ -72,8 +72,11 @@ group by t.table_name order by num1, t.table_name;
#
# Bug #19147: mysqlshow INFORMATION_SCHEMA does not work
#
+--sorted_result
--exec $MYSQL_SHOW information_schema
+--sorted_result
--exec $MYSQL_SHOW INFORMATION_SCHEMA
+--sorted_result
--exec $MYSQL_SHOW inf_rmation_schema
#
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 2c9f84e823a..49e535aad53 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -15,6 +15,12 @@
-- source include/have_innodb.inc
+set @innodb_test_tmp=@@optimizer_switch;
+set optimizer_switch =
+ if(@innodb_test_dont_touch_optimizer_switch,
+ @@optimizer_switch,
+ 'mrr=on,mrr_sort_keys=on,index_condition_pushdown=on');
+
# Save the original values of some variables in order to be able to
# estimate how much they have changed during the tests. Previously this
# test assumed that e.g. rows_deleted is 0 here and after deleting 23
@@ -2549,6 +2555,8 @@ SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig;
-- enable_query_log
+set optimizer_switch=@innodb_test_tmp;
+
#######################################################################
# #
# Please, DO NOT TOUCH this file as well as the innodb.result file. #
diff --git a/mysql-test/t/innodb_bug878769.test b/mysql-test/t/innodb_bug878769.test
new file mode 100644
index 00000000000..157c7827dde
--- /dev/null
+++ b/mysql-test/t/innodb_bug878769.test
@@ -0,0 +1,56 @@
+--source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+
+--echo #
+--echo # Bug #878769: valgrind complains when using join cache
+--echo # to join an InnoDB table without primary key
+--echo #
+
+CREATE TABLE t1 (
+ col_int_key int(11), col_time_key time, col_varchar_key varchar(1),
+ KEY (col_int_key), KEY (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT IGNORE INTO t1 VALUES
+ (7,'10:19:31','d'),(1,'14:40:36','r'),(7,'04:37:47','f'),(9,'19:34:06','y'),
+ (2,'00:00:00','m'),(4,'00:13:25','q'),(0,'03:47:16',NULL),(4,'01:41:48','d'),
+ (8,'00:00:00','g'),(NULL,'22:32:04','x'),(NULL,'16:44:14','f'),
+ (0,'17:38:37','p'),(NULL,'08:46:48','j'),(8,'14:11:27','c');
+
+CREATE TABLE t2 (
+ col_int_nokey int(11), col_int_key int(11),
+ col_datetime_key datetime, col_datetime_nokey datetime,
+ col_varchar_key varchar(1), col_varchar_nokey varchar(1),
+ KEY (col_int_key), KEY (col_varchar_key,col_int_key)
+);
+INSERT IGNORE INTO t2 VALUES
+ (150,62,'2008-01-03 10:33:32','2008-01-03 10:33:32','v','v'),
+ (2,1,'2007-10-09 19:53:04','2007-10-09 19:53:04',NULL,NULL),
+ (5,0,'2001-11-08 21:02:12','2001-11-08 21:02:12','x','x'),
+ (3,7,'2003-04-01 00:00','2003-04-01 00:00','i','i'),
+ (1,7,'1900-01-01 00:00','1900-01-01 00:00:00','e','e'),
+ (NULL,7,'2005-04-04 01:21','2005-04-04 01:21','s','s'),
+ (2,1,'1900-01-01 00:00','1900-01-01 00:00','j','j'),
+ (8,0,'2004-04-28 21:44','2004-04-28 21:44','a','a'),
+ (6,8,'2001-04-18 00:00','2001-04-18 00:00:00','y','y'),
+ (8,1,'2008-12-18 19:39:55','2008-12-18 19:39:55',NULL,NULL),
+ (3,1,'2000-08-01 12:19:39','2000-08-01 12:19:39','r','r'),
+ (3,9,'2004-09-25 21:29:06','2004-09-25 21:29:06','v','v');
+
+set session optimizer_switch='mrr=on,mrr_sort_keys=on';
+set session join_cache_level=6;
+
+EXPLAIN
+SELECT t1.col_time_key, t1.col_varchar_key
+ FROM t2 STRAIGHT_JOIN t1 ON t1.col_int_key = t2.col_int_key
+GROUP BY 1,2;
+SELECT t1.col_time_key, t1.col_varchar_key
+ FROM t2 STRAIGHT_JOIN t1 ON t1.col_int_key = t2.col_int_key
+GROUP BY 1,2;
+
+set session optimizer_switch=default;
+set session join_cache_level=default;
+
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/innodb_icp.test b/mysql-test/t/innodb_icp.test
new file mode 100644
index 00000000000..0fb42355f96
--- /dev/null
+++ b/mysql-test/t/innodb_icp.test
@@ -0,0 +1,17 @@
+#
+# ICP/InnoDB tests (Index Condition Pushdown)
+#
+
+--source include/have_innodb.inc
+
+set @save_storage_engine= @@storage_engine;
+set storage_engine=InnoDB;
+
+set @innodb_icp_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+--source include/icp_tests.inc
+
+set optimizer_switch=@innodb_icp_tmp;
+set storage_engine= @save_storage_engine;
+
diff --git a/mysql-test/t/innodb_mrr.test b/mysql-test/t/innodb_mrr.test
new file mode 100644
index 00000000000..996ceca0d2c
--- /dev/null
+++ b/mysql-test/t/innodb_mrr.test
@@ -0,0 +1,462 @@
+-- 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;
+
+set @innodb_mrr_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+--source include/mrr_tests.inc
+
+set storage_engine= @save_storage_engine;
+
+# 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;
+
+
+--echo #
+--echo # BUG#665669: Result differences on query re-execution
+--echo #
+create table t1 (pk int primary key, b int, c int default 0, index idx(b)) engine=innodb;
+insert into t1(pk,b) values (3, 30), (2, 20), (9, 90), (7, 70), (4, 40), (5, 50), (10, 100), (12, 120);
+set @bug665669_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=off';
+explain select * from t1 where b > 1000;
+--echo # The following two must produce indentical results:
+select * from t1 where pk < 2 or pk between 3 and 4;
+select * from t1 where pk < 2 or pk between 3 and 4;
+drop table t1;
+set optimizer_switch = @bug665669_tmp;
+--echo #
+--echo # Bug#43360 - Server crash with a simple multi-table update
+--echo #
+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;
+
+--echo #
+--echo # Testcase backport: Bug#43249
+--echo # (Note: Fixed by patch for BUG#42580)
+--echo #
+CREATE TABLE t1(c1 TIME NOT NULL, c2 TIME NULL, c3 DATE, PRIMARY KEY(c1), UNIQUE INDEX(c2)) engine=innodb;
+INSERT INTO t1 VALUES('8:29:45',NULL,'2009-02-01');
+# 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`;
+
+--echo #
+--echo # BUG#707925: Wrong result with join_cache_level=6 optimizer_use_mrr =
+--echo # force (incremental, BKA join)
+--echo #
+set @_save_join_cache_level= @@join_cache_level;
+set join_cache_level = 6;
+CREATE TABLE t1 (
+ f1 int(11), f2 int(11), f3 varchar(1), f4 varchar(1),
+ PRIMARY KEY (f1),
+ KEY (f3),
+ KEY (f2)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('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 (
+ SELECT alias1.f2
+ FROM
+ t1 AS alias1 JOIN (
+ t1 AS alias2 FORCE KEY (f3) JOIN
+ t1 AS alias3 FORCE KEY (f2) ON alias3.f2 = alias2.f2 AND alias3.f4 = alias2.f3
+ ) ON alias3.f1 <= alias2.f1
+) X;
+
+set join_cache_level=@_save_join_cache_level;
+set optimizer_switch= @innodb_mrr_tmp;
+drop table t1;
diff --git a/mysql-test/t/innodb_mrr_cpk.test b/mysql-test/t/innodb_mrr_cpk.test
new file mode 100644
index 00000000000..a157ddd792f
--- /dev/null
+++ b/mysql-test/t/innodb_mrr_cpk.test
@@ -0,0 +1,141 @@
+#
+# 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 @innodb_mrr_cpk_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=6;
+
+set @save_storage_engine=@@storage_engine;
+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;
+set optimizer_switch=@innodb_mrr_cpk_tmp;
+drop table t0;
+
diff --git a/mysql-test/t/innodb_no_mrricp.test b/mysql-test/t/innodb_no_mrricp.test
new file mode 100644
index 00000000000..e81d5207249
--- /dev/null
+++ b/mysql-test/t/innodb_no_mrricp.test
@@ -0,0 +1,10 @@
+
+set @innodb_with_mrricp=@@optimizer_switch;
+set optimizer_switch='mrr=off,mrr_sort_keys=off,index_condition_pushdown=off';
+set @innodb_test_dont_touch_optimizer_switch=1;
+
+--source t/innodb.test
+
+set @innodb_test_dont_touch_optimizer_switch=NULL;
+set optimizer_switch=@innodb_with_mrricp;
+
diff --git a/mysql-test/t/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 dc5fc3a2206..907d39e95fe 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -5,6 +5,9 @@ drop table if exists t1,t2,t3;
drop view if exists v1,v2;
--enable_warnings
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
#
# Test different join syntaxes
#
@@ -938,6 +941,25 @@ SELECT f1 , MIN(f2) FROM v2 GROUP BY f1;
drop table t1,t2;
drop view v1,v2;
+--echo #
+--echo # BUG#47217 Lost optimization caused slowdown & wrong result.
+--echo #
+CREATE TABLE t1 (pk INT, v VARCHAR(2), PRIMARY KEY(pk));
+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
--echo #
@@ -978,5 +1000,139 @@ FROM t4 STRAIGHT_JOIN
ON t4.ref_t1=t1.c1;
drop table t1,t2,t3,t4;
-
--echo End of 5.2 tests
+
+--echo #
+--echo # BUG#724275: Crash in JOIN::optimize in maria-5.3
+--echo #
+
+create table t1 (a int);
+insert into t1 values (1),(2);
+insert into t1 select * from t1;
+
+create table t2 (a int, b int, key(a,b));
+insert into t2 values (1,1),(1,2),(1,3),(1,4),(2,5),(2,6),(2,7),(2,8),(2,9);
+insert into t2 select * from t2;
+insert into t2 select * from t2;
+insert into t2 select * from t2;
+
+create table t3 (a int, b int, key(a));
+insert into t3 values (1,1),(2,2);
+select * from
+ t3 straight_join t1 straight_join t2 force index(a)
+where t2.a=1 and t2.b=t1.a and t1.a=t3.b and t3.a=1;
+
+drop table t1,t2,t3;
+
+--echo #
+--echo # BUG#729067/730466: unexpected 'Range checked for each record'
+--echo # for queries with OR in WHERE clause
+--echo #
+
+CREATE TABLE t1 (f1 int, f2 int) ;
+INSERT INTO t1 VALUES (4,0),(5,1);
+
+CREATE TABLE t2 (f1 int, f2 int, KEY (f2)) ;
+INSERT INTO t2 VALUES (5,7), (8,9);
+
+EXPLAIN
+SELECT * FROM t1 STRAIGHT_JOIN t2 ON t2.f1 = t1.f1
+ WHERE t1.f1<>0 OR t1.f2<>0 AND t1.f1 = t2.f2;
+SELECT * FROM t1 STRAIGHT_JOIN t2 ON t2.f1 = t1.f1
+ WHERE t1.f1<>0 OR t1.f2<>0 AND t1.f1 = t2.f2;
+
+DROP TABLE t1,t2;
+
+CREATE TABLE t1(f1 int PRIMARY KEY, f2 int) ;
+INSERT INTO t1 VALUES (9,4), (10,9);
+
+CREATE TABLE t2(f1 int PRIMARY KEY, f2 int) ;
+INSERT INTO t2 VALUES (9,4), (10,9);
+
+EXPLAIN
+SELECT STRAIGHT_JOIN * FROM t1 JOIN t2 ON t2.f2 = t1.f1
+ WHERE t1.f1 IN (SELECT f1 FROM t1) AND t1.f1 = t2.f1 OR t1.f1 = 9;
+SELECT STRAIGHT_JOIN * FROM t1 JOIN t2 ON t2.f2 = t1.f1
+ WHERE t1.f1 IN (SELECT f1 FROM t1) AND t1.f1 = t2.f1 OR t1.f1 = 9;
+
+DROP TABLE t1,t2;
+
+#
+# Item_equal used cmp_item::get_comparator() incorrectly
+#
+create table t1 (i time key);
+insert into t1 values ('1:1:1'), ('2:2:2');
+create table t2 (i time);
+insert into t2 values ('1:1:1');
+select t2.i from t1 left join t2 on t2.i = t1.i where t1.i = '1:1:1';
+drop table t1,t2;
+
+--echo #
+--echo # BUG#954900: unexpected empty set due to an invalid build of key ref
+--echo #
+
+CREATE TABLE t1 (dog_id int(10), birthday date, PRIMARY KEY (dog_id,birthday));
+INSERT INTO t1 VALUES (5918,'2004-07-22');
+
+CREATE TABLE t2 (dog_id int(10) unsigned, t_id char(1), birthday date, a_id int(10),
+PRIMARY KEY (dog_id,t_id,birthday,a_id));
+INSERT INTO t2 VALUES
+(5918,'N','2004-07-22',5216551), (5918,'N','2004-07-22',5223640),
+(5918,'N','2004-07-22',5389491), (5918,'N','2004-07-22',5749434),
+(5918,'N','2004-07-22',5992424), (5922,'N','2005-06-30',5076957),
+(5924,'N','2000-08-11',20264), (5924,'N','2000-08-11',64251),
+(5924,'N','2000-08-11',74748), (5924,'N','2000-08-11',87590),
+(5924,'N','2000-08-11',104695), (5924,'N','2000-08-11',133136),
+(5924,'N','2000-08-11',5027806), (5924,'N','2000-08-11',5076957),
+(5924,'N','2000-08-11',5166821), (5924,'N','2000-08-11',5181896),
+(5924,'N','2000-08-11',5217908), (5924,'N','2000-08-11',5220812),
+(5924,'N','2000-08-11',5226473), (5924,'N','2000-08-11',5339111),
+(5925,'N','2005-02-10',19227), (5925,'N','2005-02-10',74529),
+(5925,'N','2005-02-10',74748), (5927,'N','2005-08-18',20264),
+(5927,'N','2005-08-18',58364), (5929,'N','2005-01-19',58364),
+(5935,'N','2006-03-10',19227), (5935,'N','2006-03-10',64251),
+(5935,'N','2006-03-10',5222400), (5935,'N','2006-03-10',5226473),
+(5936,'N','2004-10-29',5015032), (5937,'N','2002-04-05',11237),
+(5937,'N','2002-04-05',23911), (5937,'N','2002-04-05',112133),
+(5937,'N','2002-04-05',169721), (5937,'N','2002-04-05',170650),
+(5937,'N','2002-04-05',5014494), (5937,'N','2002-04-05',5166009),
+(5937,'N','2002-04-05',5181871), (5937,'N','2002-04-05',5213380),
+(5937,'N','2002-04-05',5214875), (5937,'N','2002-04-05',5895062),
+(5938,'N','2006-03-24',11237), (5938,'N','2006-03-24',19227),
+(5938,'N','2006-03-24',23911), (5938,'N','2006-03-24',58364),
+(5938,'N','2006-03-24',64251), (5938,'N','2006-03-24',111716),
+(5938,'N','2006-03-24',112702), (5938,'N','2006-03-24',133136),
+(5938,'N','2006-03-24',168718), (5938,'N','2006-03-24',5137136),
+(5938,'N','2006-03-24',5161519), (5938,'N','2006-03-24',5168120),
+(5938,'N','2006-03-24',5219034), (6234,'N','2006-06-02',103058),
+(6234,'N','2006-06-02',5146844), (6235,'N','2006-06-01',12900),
+(6235,'N','2006-06-01',20264), (6235,'N','2006-06-01',64251),
+(6235,'N','2006-06-01',75160), (6235,'N','2006-06-01',5014494),
+(6235,'N','2006-06-01',5181638), (6236,'N','2006-06-06',112595),
+(6236,'N','2006-06-06',5219601), (6236,'N','2006-06-06',5808374);
+
+CREATE TABLE t3 (dog_id int(10) unsigned);
+INSERT INTO t3 VALUES (5918);
+
+CREATE TABLE t4 (dog_id int(10), t_id char(1), birthday date, KEY (t_id));
+INSERT INTO t4 VALUES (5918,'N','2004-07-22'), (5919,'N','2004-07-20');
+
+CREATE TABLE t5 (dog_id int(10) unsigned, UNIQUE KEY (dog_id));
+INSERT INTO t5 VALUES (5918);
+
+SET @tmp_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='index_condition_pushdown=off';
+
+EXPLAIN
+SELECT * FROM t5 DU, t1 D, t4 DT, t2 DSA, t3 DSAR
+WHERE DU.dog_id=D.dog_id AND D.dog_id=DT.dog_id AND D.birthday=DT.birthday AND
+ DT.t_id=DSA.t_id AND DT.birthday=DSA.birthday AND DSA.dog_id=DSAR.dog_id;
+SELECT * FROM t5 DU, t1 D, t4 DT, t2 DSA, t3 DSAR
+WHERE DU.dog_id=D.dog_id AND D.dog_id=DT.dog_id AND D.birthday=DT.birthday AND
+ DT.t_id=DSA.t_id AND DT.birthday=DSA.birthday AND DSA.dog_id=DSAR.dog_id;
+
+SET optimizer_switch=@tmp_optimizer_switch;
+
+DROP TABLE t1,t2,t3,t4,t5;
+
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test
new file mode 100644
index 00000000000..eabab4891ce
--- /dev/null
+++ b/mysql-test/t/join_cache.test
@@ -0,0 +1,3640 @@
+--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='optimize_join_buffer_size=on';
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+set @local_join_cache_test_optimizer_switch_default=@@optimizer_switch;
+set names utf8;
+
+CREATE DATABASE world;
+
+use world;
+
+--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';
+
+set join_cache_level=1;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+
+SELECT Country.Name, Country.Population, City.Name, City.Population
+ FROM Country LEFT JOIN City
+ ON City.Country=Country.Code AND City.Population > 5000000
+ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+
+SELECT Country.Name, Country.Population, City.Name, City.Population
+ FROM Country LEFT JOIN City
+ ON City.Country=Country.Code AND
+ (City.Population > 5000000 OR City.Name LIKE 'Za%')
+ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+
+CREATE INDEX City_Population ON City(Population);
+CREATE INDEX City_Name ON City(Name);
+
+--disable_result_log
+ANALYZE TABLE City;
+--enable_result_log
+
+EXPLAIN
+SELECT Country.Name, Country.Population, City.Name, City.Population
+ FROM Country LEFT JOIN City
+ ON City.Country=Country.Code AND City.Population > 5000000
+ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+
+SELECT Country.Name, Country.Population, City.Name, City.Population
+ FROM Country LEFT JOIN City
+ ON City.Country=Country.Code AND City.Population > 5000000
+ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+
+EXPLAIN
+SELECT Country.Name, Country.Population, City.Name, City.Population
+ FROM Country LEFT JOIN City
+ ON City.Country=Country.Code AND
+ (City.Population > 5000000 OR City.Name LIKE 'Za%')
+ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+
+SELECT Country.Name, Country.Population, City.Name, City.Population
+ FROM Country LEFT JOIN City
+ ON City.Country=Country.Code AND
+ (City.Population > 5000000 OR City.Name LIKE 'Za%')
+ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+
+DROP INDEX City_Population ON City;
+DROP INDEX City_Name ON City;
+
+set join_cache_level=1;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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;
+
+
+--replace_column 9 #
+EXPLAIN
+SELECT Country.Name, Country.Population, City.Name, City.Population
+ FROM Country LEFT JOIN City
+ ON City.Country=Country.Code AND City.Population > 5000000
+ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+
+SELECT Country.Name, Country.Population, City.Name, City.Population
+ FROM Country LEFT JOIN City
+ ON City.Country=Country.Code AND City.Population > 5000000
+ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+
+CREATE INDEX City_Name ON City(Name);
+
+EXPLAIN
+SELECT Country.Name, Country.Population, City.Name, City.Population
+ FROM Country LEFT JOIN City
+ ON City.Country=Country.Code AND
+ (City.Population > 5000000 OR City.Name LIKE 'Za%')
+ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+
+SELECT Country.Name, Country.Population, City.Name, City.Population
+ FROM Country LEFT JOIN City
+ ON City.Country=Country.Code AND
+ (City.Population > 5000000 OR City.Name LIKE 'Za%')
+ WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
+
+DROP INDEX City_Name ON City;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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 AND
+ LENGTH(Language) < LENGTH(City.Name) - 2;
+
+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);
+INSERT INTO t2 VALUES (17,10), (11,20), (12,20), (18,20), (18,10), (11,20);
+INSERT INTO t2 VALUES (11,10), (14,20), (13,20), (17,20), (17,10), (11,20);
+
+set join_buffer_size=32;
+set join_cache_level=8;
+
+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);
+INSERT INTO t2 VALUES (14,10), (12,10), (15,30), (12,20), (14,20);
+
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL;
+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');
+
+flush status;
+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;
+show status like "Handler_icp%";
+
+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;
+show status like "Handler_icp%";
+
+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;
+show status like "Handler_icp%";
+
+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;
+show status like "Handler_icp%";
+
+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);
+insert into t2 values
+ (21, 10), (31, 400), (21, 400), (31, 200), (11, 300), (11, 200), (41, 100),
+ (41, 200), (31, 300), (11, 400), (21, 200), (21, 300);
+
+set join_cache_level=6;
+
+explain
+select t1.id1, sum(t2.id2) from t1 join t2 on t1.id1=t2.id1
+ 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 t2 values
+ (130, 'bbb'), (110, 'b'), (170, 'bbbbbbb'), (160, 'bbbbbb'),
+ (131, 'bbb'), (111, 'b'), (171, 'bbbbbbb'), (161, 'bbbbbb'),
+ (132, 'bbb'), (112, 'b'), (172, 'bbbbbbb'), (162, 'bbbbbb');
+insert into t3 values
+ (4000, 'dddd'), (3000, 'ddd'), (1000, 'd'), (8000, 'dddddddd'),
+ (4001, 'dddd'), (3001, 'ddd'), (1001, 'd'), (8001, 'dddddddd'),
+ (4002, 'dddd'), (3002, 'ddd'), (1002, 'd'), (8002, 'dddddddd');
+insert into t3 values
+ (14000, 'dddd'), (13000, 'ddd'), (11000, 'd'), (18000, 'dddddddd'),
+ (14001, 'dddd'), (13001, 'ddd'), (11001, 'd'), (18001, 'dddddddd'),
+ (4002, 'dddd'), (3002, 'ddd'), (1002, 'd'), (8002, 'dddddddd');
+insert into t4 values
+ (200, 'cc'), (600, 'cccccc'), (300, 'ccc'), (500, 'ccccc'),
+ (201, 'cc'), (601, 'cccccc'), (301, 'ccc'), (501, 'ccccc'),
+ (202, 'cc'), (602, 'cccccc'), (302, 'ccc'), (502, 'ccccc');
+insert into t4 values
+ (1200, 'cc'), (1600, 'cccccc'), (1300, 'ccc'), (1500, 'ccccc'),
+ (1201, 'cc'), (1601, 'cccccc'), (1301, 'ccc'), (1501, 'ccccc'),
+ (1202, 'cc'), (1602, 'cccccc'), (1302, 'ccc'), (1502, 'ccccc');
+
+--disable_result_log
+--disable_warnings
+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);
+
+set join_cache_level=1;
+
+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),(50,150),(250,350),(180,210),(100,150),
+ (101,NULL),(151,200),(51,150),(251,350),(181,210),(101,150);
+
+set join_cache_level = 5;
+explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+--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");
+INSERT INTO t2 VALUES (100,NULL),(150,"long varchar"),(200,"varchar"),(250,"long long long varchar");
+
+set join_cache_level = 5;
+explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
+--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');
+INSERT INTO t3 VALUES
+ (103,108,'2008-12-04','00:00:00','a','v'), (103,108,'2009-03-28','00:00:00','b','f'),
+ (103,105,'1900-01-01','00:55:47','c','v'), (102,108,'2009-10-02','00:00:00','d','s'),
+ (100,108,'1900-01-01','20:51:59','e','a'), (100,106,'2008-06-04','09:47:27','f','p'),
+ (108,107,'2009-01-13','21:58:29','g','z'), (105,102,'1900-01-01','22:45:53','h','a'),
+ (109,105,'2008-01-28','14:06:48','i','h'), (105,107,'2004-09-18','22:17:16','j','h'),
+ (104,102,'2006-10-14','14:59:37','k','v'), (102,109,'1900-01-01','23:37:40','l','v'),
+ (1033,1142,'2000-11-28','14:14:01','m','b'), (105,103,'2008-04-04','02:54:19','n','y'),
+ (100,100,'2002-07-13','06:34:26','o','v'), (109,103,'2003-01-03','18:07:38','p','m'),
+ (100,105,'2006-04-02','13:55:23','q','z'), (103,109,'2006-10-19','20:32:28','s','n'),
+ (108,100,'2005-06-08','11:57:44','t','d'), (1231,1107,'2006-12-26','03:10:35','v','a');
+
+CREATE TABLE t1 SELECT * FROM t3;
+DELETE FROM t1 WHERE i > 8;
+CREATE TABLE t2 SELECT * FROM t3;
+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,'a'), (27,9,'n'), (28,1,'d'), (29,107,'a');
+INSERT INTO t1 VALUES
+ (110,8,'x'), (111,8,'y'), (112,5,'v'), (113,8,'z'), (114,8,'i'),
+ (115,6,'j'), (116,7,'t'), (117,2,'b'), (118,5,'j'), (119,7,'w'),
+ (125,3,'q'), (126,5,'o'), (127,9,'n'), (128,1,'e'), (129,107,'c');
+INSERT INTO t1 VALUES
+ (210,8,'b'), (211,8,'c'), (212,5,'d'), (213,8,'e'), (214,8,'g'),
+ (215,6,'f'), (216,7,'h'), (217,2,'i'), (218,5,'j'), (219,7,'k'),
+ (225,3,'l'), (226,5,'m'), (227,9,'n'), (228,1,'o'), (229,107,'p');
+
+CREATE TABLE t2 (
+ pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
+ PRIMARY KEY (pk), INDEX idx1(i), INDEX idx2(v,i)
+) 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,'b'), (27,9,'n'), (28,1,'d'), (29,107,'a');
+
+CREATE TABLE t3 (
+ pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
+ PRIMARY KEY (pk), INDEX idx1(i), INDEX idx2(v,i)
+) 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 AND t1.pk*2<100
+ GROUP BY t2.v ORDER BY t1.pk,t2.v;
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
+ GROUP BY t2.v ORDER BY t1.pk,t2.v;
+
+SET SESSION join_cache_level=6;
+EXPLAIN
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
+ GROUP BY t2.v ORDER BY t1.pk,t2.v;
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
+ GROUP BY t2.v ORDER BY t1.pk,t2.v;
+
+SET SESSION join_cache_level=4;
+EXPLAIN
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
+ GROUP BY t2.v ORDER BY t1.pk,t2.v;
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
+ 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);
+INSERT INTO t2 VALUES
+ ('dig',5), ('were',-1631322112), ('is',3), ('abcdefjhjl',3),
+ ('abcdefjh',4), ('told',-824573952), ('tt',0),('vv',-1711013888),
+ ('abcdefjhjj',1015414784), ('and',4), ('here',0), ('abcdefjhjm',-32702464),
+ ('abcdefjhji',4), ('space',1078394880), ('fs',4), ('mn',-1845559296),
+ ('fq', 5), ('abcdefjhjp',-1074397184);
+
+EXPLAIN
+SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
+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');
+INSERT INTO t2 VALUES
+ (101,6,'yes'), (102,NULL,'will'), (103,NULL,'o'), (104,NULL,'k'), (105,NULL,'she'),
+ (106,-1450835968,'abcdefjhjkl'), (107,-975831040,'abcdefjhjkl'), (108,NULL,'z'),
+ (100,-343932928,'t'),
+ (111,6,'yes'), (112,NULL,'will'), (113,NULL,'o'), (114,NULL,'k'), (115,NULL,'she'),
+ (116,-1450835968,'abcdefjhjkl'), (117,-975831040,'abcdefjhjkl'), (118,NULL,'z'),
+ (119,-343932928,'t');
+
+CREATE TABLE t3 (
+ pk int NOT NULL PRIMARY KEY,
+ i int,
+ 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');
+INSERT INTO t3 VALUES
+(101,7,'abcdefjhjkl'),(102,6,'y'), (103,NULL,'to'),(104,7,'n'),(105,7,'look'),
+(106,NULL,'all'), (107,1443168256,'c'), (108,1427046400,'right'),
+(111,7,'abcdefjhjkl'), (112,6,'y'), (113,NULL,'to'), (114,7,'n'), (115,7,'look'),
+(116,NULL,'all'), (117,1443168256,'c'), (118,1427046400,'right'),
+(121,7,'abcdefjhjkl'), (122,6,'y'), (123,NULL,'to'), (124,7,'n'), (125,7,'look'),
+(126,NULL,'all'), (127,1443168256,'c'), (128,1427046400,'right'),
+(131,7,'abcdefjhjkl'), (132,6,'y'), (133,NULL,'to'), (134,7,'n'), (135,7,'look'),
+(136,NULL,'all'), (137,1443168256,'c'), (138,1427046400,'right');
+
+SET SESSION join_buffer_size = 192;
+
+SET SESSION join_cache_level = 4;
+EXPLAIN
+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');
+INSERT INTO t2 VALUES
+ (110, 'a'), (120, 'c'), (130, 'aa'), (14, 'bb'),
+ (111, 'a'), (121, 'c'), (131, 'aa'), (141, 'cc'),
+ (112, 'a'), (122, 'c'), (132, 'bb'), (142, 'aa');
+
+SELECT * FROM t1,t2 WHERE t2.a=t1.a;
+
+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);
+INSERT IGNORE INTO t4 VALUES (12,10), (18,20);
+INSERT IGNORE INTO t4 VALUES (22,11), (28,21);
+INSERT IGNORE INTO t4 VALUES (32,12), (38,22);
+
+CREATE TABLE t5 (pk int, a5 int) ;
+INSERT IGNORE INTO t5 VALUES (2,0), (8,0);
+
+
+SET SESSION optimizer_switch = 'outer_join_with_cache=on';
+
+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'),
+ (101,'Bbbb'), (102,'BBB'), (103,'bbbb'), (104,'AaA'), (105,'CC'),
+ (106,'cC'), (107,'CCC'), (108,'AAA'), (109,'bBbB'), (110,'aaaa'),
+ (111,'a'), (112,'dd'), (113,'EE'), (114,'ee'), (115,'D');
+
+SET SESSION join_cache_level = 4;
+
+EXPLAIN
+SELECT * FROM t1,t2 WHERE t1.a=t2.a;
+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 = @local_join_cache_test_optimizer_switch_default;
+
+DROP TABLE t1,t2;
+
+# The same cause of the problem but no join buffer is used (see bug #695442)
+
+CREATE TABLE t1 (f1 int, f2 varchar(10), KEY (f1), KEY (f2)) ;
+INSERT INTO t1 VALUES
+ (4,'e'), (891879424,'l'), (-243400704,'ectlyqupbk'), (1851981824,'of'),
+ (-1495203840,'you'), (4,'no'), (-1436942336,'c'), (891420672,'DQQYO'),
+ (608698368,'qergldqmec'), (1,'x');
+
+CREATE TABLE t2 (f3 varchar(64), KEY (f3));
+INSERT INTO t2 VALUES
+ ('d'), ('UALLN'), ('d'), ('z'), ('r'), ('YVAKV'), ('d'), ('TNGZK'), ('e'),
+ ('xucupaxdyythsgiw'), ('why'), ('ttugkxucupaxdyyt'), ('l'), ('LHTKN'),
+ ('d'), ('o'), ('v'), ('KGLCJ'), ('your');
+
+
+SET SESSION optimizer_switch='index_merge_sort_intersection=off';
+
+SET SESSION optimizer_switch = 'index_condition_pushdown=off';
+EXPLAIN SELECT * FROM t1,t2
+ WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0, 100) ORDER BY t1.f2 LIMIT 1;
+SELECT * FROM t1,t2
+ WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1;
+SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default;
+
+SET SESSION optimizer_switch = 'index_condition_pushdown=on';
+EXPLAIN SELECT * FROM t1,t2
+ WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1;
+SELECT * FROM t1,t2
+ WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1;
+
+SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #694443: hash join using IS NULL the an equi-join condition
+--echo #
+
+CREATE TABLE t1 (a int PRIMARY KEY);
+INSERT INTO t1 VALUES
+ (7), (4), (9), (1), (3), (8), (2);
+
+CREATE TABLE t2 (a int, b int, INDEX idx (a));
+INSERT INTO t2 VALUES
+ (NULL,10), (4,80), (7,70), (6,11), (7,90), (NULL,40),
+ (4,77), (4,50), (NULL,41), (7,99), (7,88), (8,12),
+ (1,21), (4,90), (7,91), (8,22), (6,92), (NULL,42),
+ (2,78), (2,51), (1,43), (5,97), (5,89);
+
+SET SESSION join_cache_level = 1;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL;
+SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL;
+
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL;
+SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL;
+
+
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #697557: hash join on a varchar field
+--echo #
+
+CREATE TABLE t1 ( f1 varchar(10) , f2 int(11) , KEY (f1));
+INSERT INTO t1 VALUES ('r',1), ('m',2);
+
+CREATE TABLE t2 ( f1 varchar(10) , f2 int(11) , KEY (f1));
+INSERT INTO t2 VALUES
+ ('hgtofubn',1), ('GDOXZ',91), ('n',2), ('fggxgalh',88),
+ ('hgtofu',1), ('GDO',101), ('n',3), ('fggxga',55),
+ ('hgtofu',3), ('GDO',33), ('nn',3), ('fggxgarrr',77),
+ ('jgtofu',3), ('JDO',33), ('mn',3), ('jggxgarrr',77),
+ ('igtofu',3), ('IDO',33), ('ln',3), ('iggxgarrr',77);
+
+
+SET SESSION join_cache_level=3;
+
+EXPLAIN
+SELECT * FROM t1,t2 WHERE t2.f1 = t1.f1;
+SELECT * FROM t1,t2 WHERE t2.f1 = t1.f1;
+
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #707827: hash join on varchar column with NULLs
+--echo #
+
+CREATE TABLE t1 (v varchar(1));
+INSERT INTO t1 VALUES ('o'), ('u');
+
+CREATE TABLE t2 (a int, v varchar(1), INDEX idx (v)) ;
+INSERT INTO t2 VALUES
+ (8,NULL), (10,'b'), (5,'k'), (4,NULL),
+ (1,NULL), (11,'u'), (7,NULL), (2,'d'),
+ (18,'u'), (11,'b'), (15,'k'), (12,'d'),
+ (18,'x'), (11,'y'), (15,'l'), (12,'e');
+
+SET SESSION join_buffer_size = 255;
+
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT a FROM t1,t2 WHERE t2.v = t1.v ;
+SELECT a FROM t1,t2 WHERE t2.v = t1.v ;
+
+SET SESSION join_cache_level = 1;
+EXPLAIN
+SELECT a FROM t1,t2 WHERE t2.v = t1.v ;
+SELECT a FROM t1,t2 WHERE t2.v = t1.v ;
+
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION join_buffer_size = DEFAULT;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #802860: crash on join cache + derived + duplicate_weedout
+--echo #
+
+SET SESSION optimizer_switch=
+ 'semijoin=on,materialization=off,firstmatch=off,loosescan=off,derived_with_keys=on';
+
+CREATE TABLE t1 (a int) ;
+INSERT IGNORE INTO t1 VALUES (0), (1), (0);
+
+CREATE TABLE t2 (a int) ;
+INSERT IGNORE INTO t2 VALUES (0), (3), (0), (2);
+
+SET SESSION join_cache_level = 0;
+
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+ WHERE t.a IN (SELECT t2.a FROM t2);
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+ WHERE t.a IN (SELECT t2.a FROM t2);
+
+SET SESSION join_cache_level = 1;
+
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+ WHERE t.a IN (SELECT t2.a FROM t2);
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+ WHERE t.a IN (SELECT t2.a FROM t2);
+
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug #887479: join_cache_level=3 + semijoin=on
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (3914,17), (3710,5), (3888,20);
+
+CREATE TABLE t2 (c int, KEY (c));
+INSERT INTO t2 VALUES (27), (17), (33), (20), (3), (7), (18), (2);
+
+SET @tmp887479_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on';
+SET SESSION optimizer_switch='semijoin_with_cache=on';
+
+SET SESSION join_cache_level=1;
+EXPLAIN
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+
+SET SESSION join_cache_level=3;
+EXPLAIN
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+
+SET SESSION join_cache_level = DEFAULT;
+SET optimizer_switch=@tmp887479_optimizer_switch;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #899777: join_cache_level=4 + semijoin=on
+--echo #
+
+CREATE TABLE t1 (a int, b int, c int, UNIQUE INDEX idx (a));
+INSERT INTO t1 VALUES (1,8,6), (2,2,8);
+CREATE TABLE t2 (a int, b int, c int, UNIQUE INDEX idx (a));
+INSERT INTO t2 VALUES (1,8,6), (2,2,8);
+CREATE TABLE t3 (a int, b int, c int, UNIQUE INDEX idx (a));
+INSERT INTO t3 VALUES (1,8,6), (2,2,8);
+CREATE TABLE t4 (a int, b int, c int, UNIQUE INDEX idx (a));
+INSERT INTO t4 VALUES (1,8,6), (2,2,8);
+
+SET @tmp_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on';
+SET SESSION optimizer_switch='semijoin_with_cache=on';
+
+SET SESSION join_cache_level=1;
+EXPLAIN
+SELECT t1.* FROM t1,t2
+ WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
+ AND t1.a = 1;
+SELECT t1.* FROM t1,t2
+ WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
+ AND t1.a = 1;
+
+SET SESSION join_cache_level=4;
+EXPLAIN
+SELECT t1.* FROM t1,t2
+ WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
+ AND t1.a = 1;
+SELECT t1.* FROM t1,t2
+ WHERE (t1.b,t2.b) IN (SELECT t3.b,t4.b FROM t3,t4 WHERE t4.c=t3.b)
+ AND t1.a = 1;
+
+SET SESSION join_cache_level = DEFAULT;
+SET optimizer_switch=@tmp_optimizer_switch;
+
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # Bug #899509: an attempt to use hash join with join_cache_level=0
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (8), (7);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (8), (7);
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (8), (7);
+
+SET @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch=default;
+set @@optimizer_switch='semijoin_with_cache=off';
+set @@optimizer_switch='outer_join_with_cache=off';
+SET optimizer_switch='derived_merge=off,derived_with_keys=off';
+SET join_cache_level=0;
+
+EXPLAIN
+SELECT * FROM (SELECT t1.* FROM t1, t2) t WHERE t.a IN (SELECT * FROM t3);
+SELECT * FROM (SELECT t1.* FROM t1, t2) t WHERE t.a IN (SELECT * FROM t3);
+
+SELECT * FROM ( SELECT ta.* FROM t1 AS ta, t1 ) tb WHERE a IN ( SELECT * FROM t1 );
+
+SET SESSION join_cache_level = DEFAULT;
+SET optimizer_switch=@tmp_optimizer_switch;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #900469: semijoin + BNLH + ORDER BY
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (8,10);
+
+CREATE TABLE t2 (c int, d int);
+INSERT INTO t2 VALUES (8,10);
+INSERT INTO t2 VALUES (9,11);
+
+CREATE TABLE t3 (c int, d int);
+INSERT INTO t3 VALUES (8,10);
+INSERT INTO t3 VALUES (9,11);
+
+SET @tmp_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='semijoin_with_cache=on';
+
+SET join_cache_level=1;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
+SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
+
+SET join_cache_level=3;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c);
+SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c);
+
+SET join_cache_level=3;
+EXPLAIN
+SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
+SELECT * FROM t1,t2 WHERE b IN (SELECT d FROM t3 WHERE c <= t2.c) ORDER BY a,d;
+
+SET SESSION join_cache_level = DEFAULT;
+SET optimizer_switch=@tmp_optimizer_switch;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #901478: semijoin + ORDER BY + join_cache_level=4|6
+--echo #
+
+CREATE TABLE t1 (a char(1));
+INSERT INTO t1 VALUES ('x');
+CREATE TABLE t2 (a int, b int, c int, KEY(a), KEY(b), KEY(c));
+INSERT INTO t2 VALUES
+ (9,1,0), (7,2,8), (2,3,5), (4,2,9), (8,3,8), (3,4,1), (5,5,4);
+CREATE TABLE t3 (a CHAR(1));
+INSERT INTO t3 VALUES ('x');
+CREATE TABLE t4 (a int, b int, c int, KEY(b), KEY(c));
+INSERT INTO t4 VALUES
+ (9,1,0), (7,2,8), (2,3,5), (4,2,9), (8,3,8), (3,4,1), (5,5,4);
+INSERT INTO t4 VALUES
+ (19,11,10), (17,12,18), (12,13,15), (14,12,19),
+ (18,13,18), (13,14,11), (15,15,14);
+
+SET @tmp_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch='semijoin=on';
+SET @@optimizer_switch='firstmatch=off';
+SET @@optimizer_switch='mrr=off';
+SET @@optimizer_switch='semijoin_with_cache=off';
+
+set join_cache_level=1;
+EXPLAIN
+SELECT * FROM t1,t2
+ WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
+ t2.a BETWEEN 4 and 5
+ ORDER BY t2.b;
+SELECT * FROM t1,t2
+ WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
+ t2.a BETWEEN 4 and 5
+ ORDER BY t2.b;
+
+set join_cache_level=4;
+EXPLAIN
+SELECT * FROM t1,t2
+ WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
+ t2.a BETWEEN 4 and 5
+ ORDER BY t2.b;
+SELECT * FROM t1,t2
+ WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
+ t2.a BETWEEN 4 and 5
+ ORDER BY t2.b;
+
+SET @@optimizer_switch='semijoin_with_cache=on';
+set join_cache_level=6;
+EXPLAIN
+SELECT * FROM t1,t2
+ WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
+ t2.a BETWEEN 4 and 5
+ ORDER BY t2.b;
+SELECT * FROM t1,t2
+ WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
+ t2.a BETWEEN 4 and 5
+ ORDER BY t2.b;
+
+SET join_cache_level = DEFAULT;
+SET optimizer_switch=@tmp_optimizer_switch;
+
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # Bug#53305 Duplicate weedout + join buffer (join cache --level=7,8)
+--echo #
+
+create table t1 (uid int, fid int, index(uid));
+insert into t1 values
+ (1,1), (1,2), (1,3), (1,4),
+ (2,5), (2,6), (2,7), (2,8),
+ (3,1), (3,2), (3,9);
+
+create table t2 (uid int primary key, name varchar(128), index(name));
+insert into t2 values
+ (1, "A"), (2, "B"), (3, "C"), (4, "D"), (5, "E"),
+ (6, "F"), (7, "G"), (8, "H"), (9, "I");
+
+create table t3 (uid int, fid int, index(uid));
+insert into t3 values
+ (1,1), (1,2), (1,3),(1,4),
+ (2,5), (2,6), (2,7), (2,8),
+ (3,1), (3,2), (3,9);
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='semijoin=on';
+set optimizer_switch='materialization=off';
+set optimizer_switch='loosescan=off,firstmatch=off';
+set optimizer_switch='mrr_sort_keys=off';
+set join_cache_level=7;
+
+create table t4 (uid int primary key, name varchar(128), index(name));
+insert into t4 values
+ (1, "A"), (2, "B"), (3, "C"), (4, "D"), (5, "E"),
+ (6, "F"), (7, "G"), (8, "H"), (9, "I");
+
+explain select name from t2, t1
+ where t1.uid in (select t4.uid from t4, t3 where t3.uid=1 and t4.uid=t3.fid)
+ and t2.uid=t1.fid;
+
+--sorted_result
+select name from t2, t1
+ where t1.uid in (select t4.uid from t4, t3 where t3.uid=1 and t4.uid=t3.fid)
+ and t2.uid=t1.fid;
+
+set join_cache_level = default;
+set optimizer_switch=@tmp_optimizer_switch;
+
+drop table t1,t2,t3,t4;
+
+--echo #
+--echo # Bug#50358 - semijoin execution of subquery with outerjoin
+--echo # emplying join buffer
+--echo #
+
+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 (6);
+INSERT INTO t3 VALUES (1), (2);
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='semijoin=on';
+set optimizer_switch='materialization=on';
+
+set join_cache_level=0;
+EXPLAIN
+SELECT * FROM t1 WHERE t1.i IN
+ (SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i);
+SELECT * FROM t1 WHERE t1.i IN
+ (SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i);
+
+set join_cache_level=2;
+EXPLAIN
+SELECT * FROM t1 WHERE t1.i IN
+ (SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i);
+SELECT * FROM t1 WHERE t1.i IN
+ (SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i);
+
+set join_cache_level = default;
+set optimizer_switch=@tmp_optimizer_switch;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #12546542: missing row with semijoin=off + join cache
+--echo # (LP bug #922971)
+--echo #
+
+CREATE TABLE t1 (a varchar(1024));
+INSERT INTO t1 VALUES ('v'), ('we');
+CREATE TABLE t2 (
+ a varchar(1024) CHARACTER SET utf8 DEFAULT NULL, b int, c int
+);
+INSERT INTO t2 VALUES ('we',4,NULL), ('v',1305673728,6);
+CREATE TABLE t3 (b int, c int);
+INSERT INTO t3 VALUES (4,4);
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=off';
+set optimizer_switch='materialization=off';
+
+set join_cache_level=0;
+EXPLAIN
+SELECT * FROM t1
+ WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b
+ WHERE t2.c < 10 OR t3.c > 1);
+
+SELECT * FROM t1
+ WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b
+ WHERE t2.c < 10 OR t3.c > 1);
+
+set join_cache_level=2;
+EXPLAIN
+SELECT * FROM t1
+ WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b
+ WHERE t2.c < 10 OR t3.c > 1);
+SELECT * FROM t1
+ WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b
+ WHERE t2.c < 10 OR t3.c > 1);
+
+set join_cache_level = default;
+set optimizer_switch=@tmp_optimizer_switch;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #925985: LEFT JOIN with optimize_join_buffer_size=off +
+--echo # join_buffer_size > join_buffer_space_limit
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (5), (3);
+
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES
+ (3,30), (1,10), (7,70), (2,20),
+ (3,31), (1,11), (7,71), (2,21),
+ (3,32), (1,12), (7,72), (2,22);
+
+CREATE TABLE t3 (b int, c int);
+INSERT INTO t3 VALUES (32, 302), (42,400), (30,300);
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='optimize_join_buffer_size=off';
+set join_buffer_space_limit=4096;
+set join_buffer_size=4096*2;
+set join_cache_level=2;
+set optimizer_switch='outer_join_with_cache=on';
+
+EXPLAIN
+SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a;
+SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a;
+
+set join_buffer_space_limit=default;
+set join_buffer_size=default;
+set join_cache_level=default;
+set optimizer_switch=@tmp_optimizer_switch;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #1058071: LEFT JOIN using blobs
+--echo # (mdev-564) when join buffer size is small
+--echo #
+
+CREATE TABLE t1 (
+ col269 decimal(31,10) unsigned DEFAULT NULL,
+ col280 multipoint DEFAULT NULL,
+ col281 tinyint(1) DEFAULT NULL,
+ col282 time NOT NULL,
+ col284 datetime DEFAULT NULL,
+ col286 date DEFAULT NULL,
+ col287 datetime DEFAULT NULL,
+ col288 decimal(30,29) DEFAULT NULL,
+ col291 time DEFAULT NULL,
+ col292 time DEFAULT NULL
+) ENGINE=Aria;
+
+INSERT INTO t1 VALUES
+(0.0,PointFromText('POINT(9 0)'),0,'11:24:05','2013-04-14 21:30:28',NULL,'2011-12-20 06:00:34',9.9,'13:04:39',NULL),
+(0.0,NULL,127,'05:43:12','2012-09-05 06:15:27','2027-01-01','2011-10-29 10:48:29',0.0,'06:24:05','11:33:37'),
+(0.0,NULL,127,'12:54:41','2013-01-12 11:32:58','2011-11-03','2013-01-03 02:00:34',00,'11:54:15','20:19:15'),
+(0.0,PointFromText('POINT(9 0)'),0,'19:48:07','2012-07-16 15:45:25','2012-03-25','2013-09-07 17:21:52',0.5,'17:36:54','21:24:19'),
+(0.0,PointFromText('POINT(9 0)'),0,'03:43:48','2012-09-28 00:00:00','2012-06-26','2011-11-16 05:01:09',00,'01:25:42','19:30:06'),
+(0.0,LineStringFromText('LINESTRING(0 0,9 9,0 0,9 0,0 0)'),127,'11:33:21','2012-03-31 10:29:22','2012-10-10','2012-04-21 19:21:06',NULL,'05:13:22','09:48:34'),
+(NULL,PointFromText('POINT(9 0)'),127,'00:00:00','0000-00-00','2012-04-04 21:26:12','2013-03-04',0.0,'12:54:30',NULL),
+(NULL,PointFromText('POINT(9 0)'),1,'00:00:00','2013-05-01 22:37:49','2013-06-26','2012-09-22 17:31:03',0.0,'08:09:57','11:15:36');
+
+CREATE TABLE t2 (b int) ENGINE=Aria;
+INSERT INTO t2 VALUES (NULL);
+CREATE TABLE t3 (c int) ENGINE=Aria;
+INSERT INTO t3 VALUES (NULL);
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch = 'outer_join_with_cache=on,join_cache_incremental=on';
+set join_buffer_size=128;
+
+EXPLAIN
+SELECT 1 AS c FROM t1 NATURAL LEFT JOIN t2 LEFT OUTER JOIN t3 ON 1
+ GROUP BY elt(t1.col282,1,t1.col280);
+
+SELECT 1 AS c FROM t1 NATURAL LEFT JOIN t2 LEFT OUTER JOIN t3 ON 1
+ GROUP BY elt(t1.col282,1,t1.col280);
+
+set join_buffer_size=default;
+set optimizer_switch=@tmp_optimizer_switch;
+
+DROP table t1,t2,t3;
+
+# 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..3168e95f620 100644
--- a/mysql-test/t/join_nested.test
+++ b/mysql-test/t/join_nested.test
@@ -3,6 +3,18 @@
DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5,t6,t7,t8,t9;
--enable_warnings
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch=ifnull(@optimizer_switch_for_join_nested_test,'outer_join_with_cache=off');
+if (`select @join_cache_level_for_join_nested_test is null`)
+{
+ set join_cache_level=1;
+}
+if (`select @join_cache_level_for_join_nested_test is not null`)
+{
+ set join_cache_level=@join_cache_level_for_join_nested_test;
+}
+
+
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);
@@ -454,6 +466,7 @@ SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
ON t3.a=1 AND t2.b=t4.b
WHERE t1.a <= 2;
+INSERT INTO t2 VALUES (-1,9,0), (-3,10,0), (-2,8,0), (-4,11,0), (-5,15,0);
CREATE INDEX idx_b ON t2(b);
EXPLAIN EXTENDED
@@ -461,13 +474,12 @@ SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
FROM (t3,t4)
LEFT JOIN
(t1,t2)
- ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
-
+ ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0;
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
FROM (t3,t4)
LEFT JOIN
(t1,t2)
- ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
+ ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0;
EXPLAIN EXTENDED
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
@@ -478,7 +490,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t2
LEFT JOIN
(t3, t4)
- ON t3.a=1 AND t2.b=t4.b,
+ ON t3.a=1 AND t2.b=t4.b AND t2.a>0,
t5
LEFT JOIN
(
@@ -505,6 +517,8 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
(t8.b=t9.b OR t8.c IS NULL) AND
(t9.a=1);
+INSERT INTO t4 VALUES (-3,12,0), (-4,13,0), (-1,11,0), (-3,11,0), (-5,15,0);
+INSERT INTO t5 VALUES (-3,11,0), (-2,12,0), (-3,13,0), (-4,12,0);
CREATE INDEX idx_b ON t4(b);
CREATE INDEX idx_b ON t5(b);
@@ -517,7 +531,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t2
LEFT JOIN
(t3, t4)
- ON t3.a=1 AND t2.b=t4.b,
+ ON t3.a=1 AND t2.b=t4.b AND t2.a>0 AND t4.a>0,
t5
LEFT JOIN
(
@@ -526,7 +540,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t8
ON t7.b=t8.b AND t6.b < 10
)
- ON t6.b >= 2 AND t5.b=t7.b
+ ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
@@ -544,6 +558,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
(t8.b=t9.b OR t8.c IS NULL) AND
(t9.a=1);
+INSERT INTO t8 VALUES (-3,12,0), (-1,14,0), (-5,15,0), (-1,11,0), (-4,13,0);
CREATE INDEX idx_b ON t8(b);
EXPLAIN EXTENDED
@@ -555,16 +570,16 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t2
LEFT JOIN
(t3, t4)
- ON t3.a=1 AND t2.b=t4.b,
+ ON t3.a=1 AND t2.b=t4.b AND t2.a>0 AND t4.a>0,
t5
LEFT JOIN
(
(t6, t7)
LEFT JOIN
t8
- ON t7.b=t8.b AND t6.b < 10
+ ON t7.b=t8.b AND t6.b < 10 AND t8.a>=0
)
- ON t6.b >= 2 AND t5.b=t7.b
+ ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
@@ -582,6 +597,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
(t8.b=t9.b OR t8.c IS NULL) AND
(t9.a=1);
+INSERT INTO t1 VALUES (-1,133,0), (-2,12,0), (-3,11,0), (-5,15,0);
CREATE INDEX idx_b ON t1(b);
CREATE INDEX idx_a ON t0(a);
@@ -607,7 +623,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
- (t1.a != 2),
+ (t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -642,7 +658,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
- (t1.a != 2),
+ (t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -1236,5 +1252,38 @@ SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a
DROP TABLE t1, t2, t3;
+
+#
+# LP BUG#817360: Nested left joins + not-exist optimization
+#
+
+CREATE TABLE t1 (a int NOT NULL );
+INSERT INTO t1 VALUES (9), (9);
+
+CREATE TABLE t2 (a int NOT NULL );
+INSERT INTO t2 VALUES (9);
+
+CREATE TABLE t3 (a int NOT NULL, b int);
+INSERT INTO t3 VALUES (19,9);
+
+CREATE TABLE t4 (b int) ;
+
+SELECT * FROM t1 LEFT JOIN
+ ((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ ON t1.a=t2.a;
+SELECT * FROM t1 LEFT JOIN
+ ((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ ON t1.a=t2.a
+ WHERE t3.a IS NULL;
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN
+ ((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ ON t1.a=t2.a
+ WHERE t3.a IS NULL;
+
+DROP TABLE t1,t2,t3,t4;
+
+SET optimizer_switch=@save_optimizer_switch;
+
--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..0e8646bceda
--- /dev/null
+++ b/mysql-test/t/join_nested_jcl6.test
@@ -0,0 +1,111 @@
+#
+# Run join_nested.test with BKA enabled
+#
+
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set @@optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+set @optimizer_switch_for_join_nested_test=@@optimizer_switch;
+set @join_cache_level_for_join_nested_test=@@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);
+INSERT INTO t6 VALUES (-1,12,0), (-3,13,0), (-6,11,0), (-4,14,0);
+INSERT INTO t7 VALUES (-1,11,0), (-2,12,0), (-3,13,0), (-4,14,0), (-5,15,0);
+INSERT INTO t8 VALUES (-3,13,0), (-1,12,0), (-2,14,0), (-5,15,0), (-4,16,0);
+
+EXPLAIN
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t5
+ 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) AND t6.a>0 AND t7.a>0;
+
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t5
+ 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) AND t6.a>0 AND t7.a>0;
+
+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;
+set @optimizer_switch_for_join_nested_test=NULL;
+set @join_cache_level_for_join_nested_test=NULL;
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index 01f1980b4c1..69c08cd54bd 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -8,6 +8,17 @@
drop table if exists t0,t1,t2,t3,t4,t5;
--enable_warnings
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch=ifnull(@optimizer_switch_for_join_outer_test,'outer_join_with_cache=off');
+if (`select @join_cache_level_for_join_outer_test is null`)
+{
+ set join_cache_level=1;
+}
+if (`select @join_cache_level_for_join_outer_test is not null`)
+{
+ set join_cache_level=@join_cache_level_for_join_outer_test;
+}
+
CREATE TABLE t1 (
grp int(11) default NULL,
a bigint(20) unsigned default NULL,
@@ -310,6 +321,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;
@@ -1063,6 +1075,8 @@ insert into t2 select if(t1.a is null, 10, t1.a) from t1;
create table t3 (a int, b int, index idx(a));
insert into t3 values (1, 100), (3, 301), (4, 402), (1, 102), (1, 101);
+insert into t3 values (11, 100), (33, 301), (44, 402), (11, 102), (11, 101);
+insert into t3 values (22, 100), (53, 301), (64, 402), (22, 102), (22, 101);
analyze table t1,t2,t3;
@@ -1075,6 +1089,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 #
@@ -1181,3 +1196,167 @@ SELECT * FROM t3 LEFT JOIN t2 ON(c = b) WHERE b not in (SELECT a FROM t1 WHERE a
drop table t1,t2,t3;
--echo End of 5.2 tests
+
+--echo #
+--echo # LP bug #813447: LEFT JOIN with single-row inner table and
+--echo # a subquery in ON expression
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0);
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (0);
+
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (0), (0);
+
+SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3);
+EXPLAIN EXTENDED
+SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3);
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #817384 Wrong result with outer join + subquery in ON
+--echo # clause +unique key
+--echo #
+
+CREATE TABLE t1 ( c int NOT NULL , b char(1) NOT NULL ) ;
+INSERT INTO t1 VALUES (1,'b');
+
+CREATE TABLE t2 ( a int NOT NULL , b char(1) NOT NULL , PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (1,'a');
+
+create table t3 (c1 char(1), c2 char(2));
+insert into t3 values ('c','d');
+insert into t3 values ('c','d');
+
+
+EXPLAIN SELECT t2.b
+FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3);
+SELECT t2.b
+FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3);
+
+EXPLAIN SELECT t2.b
+FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1;
+SELECT t2.b
+FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #825035: second execution of PS with outer join
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+
+CREATE TABLE t2 (a int);
+
+PREPARE stmt FROM
+"SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a";
+
+EXECUTE stmt;
+EXECUTE stmt;
+
+DEALLOCATE PREPARE stmt;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #838633: second execution of PS with outer join
+--echo # converted to inner join
+--echo #
+
+CREATE TABLE t1 ( b int NOT NULL ) ;
+INSERT INTO t1 VALUES (9),(10);
+
+CREATE TABLE t2 ( b int NOT NULL, PRIMARY KEY (b)) ;
+INSERT INTO t2 VALUES
+ (75),(76),(77),(78),(79),(80),(81),(82),(83),(84),(85),(86),(87),(88),(89),
+ (10), (90),(91),(92),(93),(94),(95),(96),(97),(98),(99),(100);
+
+CREATE TABLE t3 ( a int, b int NOT NULL , PRIMARY KEY (b)) ;
+INSERT INTO t3 VALUES
+ (0,6),(0,7),(0,8),(2,9),(0,10),(2,21),(0,22),(2,23),(2,24),(2,25);
+
+SET SESSION join_cache_level=4;
+
+EXPLAIN EXTENDED
+SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b;
+
+PREPARE stmt FROM
+'SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b';
+
+EXECUTE stmt;
+EXECUTE stmt;
+
+DEALLOCATE PREPARE stmt;
+
+SET SESSION join_cache_level=default;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #943543: LEFT JOIN converted to JOIN with
+--echo # ORed IS NULL(primary key) in WHERE clause
+--echo #
+
+CREATE TABLE t1 (
+ a int, b int NOT NULL, pk int NOT NULL,
+ PRIMARY KEY (pk), INDEX idx(b)
+);
+INSERT INTO t1 VALUES
+ (NULL,1,1), (6,2,2), (5,3,3), (NULL,4,4),
+ (1,9,6), (8,5,7), (NULL,8,8), (8,1,5);
+
+CREATE TABLE t2 (pk int PRIMARY KEY);
+INSERT INTO t2 VALUES (3), (8), (5);
+
+EXPLAIN EXTENDED
+SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a
+ WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
+ORDER BY t1.pk;
+SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a
+ WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
+ORDER BY t1.pk;
+
+EXPLAIN EXTENDED
+SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a
+ WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
+ORDER BY t1.pk;
+SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a
+ WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
+ORDER BY t1.pk;
+
+DROP TABLE t2;
+
+CREATE TABLE t2 (c int, d int, KEY (c));
+INSERT INTO t2 VALUES
+ (3,30), (8,88), (5,50), (8,81),
+ (4,40), (9,90), (7,70), (9,90),
+ (13,130), (18,188), (15,150), (18,181),
+ (14,140), (19,190), (17,170), (19,190);
+
+INSERT INTO t1 VALUES (8,5,9);
+
+EXPLAIN EXTENDED
+SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a
+ WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5
+ORDER BY t1.b;
+SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a
+ WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5
+ORDER BY t1.b;
+
+EXPLAIN EXTENDED
+SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a
+ WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5
+ORDER BY t1.b;
+SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a
+ WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5
+ORDER BY t1.b;
+
+DROP TABLE t1,t2;
+
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/join_outer_jcl6.test b/mysql-test/t/join_outer_jcl6.test
new file mode 100644
index 00000000000..e34cc615216
--- /dev/null
+++ b/mysql-test/t/join_outer_jcl6.test
@@ -0,0 +1,24 @@
+#
+# Run join_outer.test with BKA enabled
+#
+
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+set @optimizer_switch_for_join_outer_test=@@optimizer_switch;
+set @join_cache_level_for_join_outer_test=@@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;
+set @optimizer_switch_for_join_outer_test=NULL;
+set @join_cache_level_for_join_outer_test=NULL;
diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test
index b199a1224c3..f51b9723142 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -99,7 +99,7 @@ select ((@id := kill_id) - kill_id) from t3;
kill @id;
connection conn1;
--- error 1317,2013
+-- error ER_QUERY_INTERRUPTED,ER_CONNECTION_KILLED,2013
reap;
connection default;
@@ -337,5 +337,35 @@ SELECT 1;
###########################################################################
+--echo #
+--echo # Test kill USER
+--echo #
+
+grant ALL on test.* to test@localhost;
+grant ALL on test.* to test2@localhost;
+connect (con3, localhost, test,,);
+connect (con4, localhost, test2,,);
+connection default;
+--enable_info
+kill hard query user test2@nohost;
+kill soft query user test@localhost;
+kill hard query user test@localhost;
+kill soft connection user test2;
+kill hard connection user test@localhost;
+--disable_info
+revoke all privileges on test.* from test@localhost;
+revoke all privileges on test.* from test2@localhost;
+drop user test@localhost;
+drop user test2@localhost;
+
+connection con3;
+--error 2013,2006
+select 1;
+connection con4;
+--error 2013,2006
+select 1;
+connection default;
+
+
# Restore global concurrent_insert value. Keep in the end of the test file.
set @@global.concurrent_insert= @old_concurrent_insert;
diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test
index 742a83f7bad..044af931489 100644
--- a/mysql-test/t/lock_multi.test
+++ b/mysql-test/t/lock_multi.test
@@ -5,6 +5,7 @@
--disable_warnings
drop table if exists t1,t2;
+drop DATABASE if exists mysqltest_1;
--enable_warnings
# Test to see if select will get the lock ahead of low priority update
@@ -24,7 +25,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 +33,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 +53,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 +97,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 +121,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 +300,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 +308,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 +463,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 +607,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/lock_multi_bug38499.test b/mysql-test/t/lock_multi_bug38499.test
index 3d3f084ba5f..b812984e516 100644
--- a/mysql-test/t/lock_multi_bug38499.test
+++ b/mysql-test/t/lock_multi_bug38499.test
@@ -16,7 +16,9 @@ connect (writer,localhost,root,,);
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1( a INT, b INT );
+CREATE TABLE t2( a INT, b INT );
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
--echo # 1. test regular tables
--echo # 1.1. test altering of columns that multiupdate doesn't use
@@ -28,7 +30,7 @@ while ($i) {
--dec $i
--connection writer
- send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0;
+ send UPDATE t1, (SELECT 1 FROM t2 t1i) d SET a = 0 WHERE 1=0;
--connection locker
ALTER TABLE t1 ADD COLUMN (c INT);
@@ -41,7 +43,7 @@ while ($i) {
--echo # 1.1.2. PS mode
--connection writer
-PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0';
+PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t2 t1i) d SET a = 0 WHERE 1=0';
let $i = 100;
while ($i) {
@@ -75,7 +77,7 @@ while ($i) {
UPDATE t1 SET a=b;
--connection writer
---send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0;
+--send UPDATE t1, (SELECT 1 FROM t2 t1i) d SET a = 0 WHERE 1=0;
--connection locker
--error 0,ER_CANT_DROP_FIELD_OR_KEY
@@ -100,7 +102,7 @@ while ($i) {
UPDATE t1 SET a=b;
--connection writer
- PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0';
+ PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t2 t1i) d SET a = 0 WHERE 1=0';
--send EXECUTE stmt
--connection locker
@@ -210,7 +212,7 @@ while ($i) {
}
--enable_query_log
--connection default
-DROP TABLE t1;
+DROP TABLE t1,t2;
# Close connections
diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test
index af6c34dec37..01528f3658d 100644
--- a/mysql-test/t/log_tables.test
+++ b/mysql-test/t/log_tables.test
@@ -283,7 +283,7 @@ drop table mysql.slow_log;
use mysql;
CREATE TABLE `general_log` (
- `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
@@ -293,11 +293,11 @@ CREATE TABLE `general_log` (
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log';
CREATE TABLE `slow_log` (
- `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
- `query_time` time NOT NULL,
- `lock_time` time NOT NULL,
+ `query_time` time(6) NOT NULL,
+ `lock_time` time(6) NOT NULL,
`rows_sent` int(11) NOT NULL,
`rows_examined` int(11) NOT NULL,
`db` varchar(512) NOT NULL,
@@ -710,10 +710,10 @@ DROP DATABASE IF EXISTS `db_17876`;
CREATE DATABASE db_17876;
CREATE TABLE `db_17876.slow_log_data` (
- `start_time` timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`user_host` mediumtext ,
- `query_time` time ,
- `lock_time` time ,
+ `query_time` time(6) ,
+ `lock_time` time(6) ,
`rows_sent` int(11) ,
`rows_examined` int(11) ,
`db` varchar(512) default NULL,
@@ -724,7 +724,7 @@ CREATE TABLE `db_17876.slow_log_data` (
);
CREATE TABLE `db_17876.general_log_data` (
- `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext,
`thread_id` int(11) DEFAULT NULL,
`server_id` int(11) DEFAULT NULL,
@@ -736,7 +736,7 @@ DELIMITER //;
CREATE procedure `db_17876.archiveSlowLog`()
BEGIN
- DECLARE start_time, query_time, lock_time CHAR(20);
+ DECLARE start_time, query_time, lock_time CHAR(28);
DECLARE user_host MEDIUMTEXT;
DECLARE rows_set, rows_examined, last_insert_id, insert_id, server_id INT;
DECLARE dbname MEDIUMTEXT;
@@ -776,7 +776,7 @@ END //
CREATE procedure `db_17876.archiveGeneralLog`()
BEGIN
- DECLARE event_time CHAR(20);
+ DECLARE event_time CHAR(28);
DECLARE user_host, argument MEDIUMTEXT;
DECLARE thread_id, server_id INT;
DECLARE sql_text BLOB;
diff --git a/mysql-test/t/maria_icp.test b/mysql-test/t/maria_icp.test
new file mode 100644
index 00000000000..d8af34daf2e
--- /dev/null
+++ b/mysql-test/t/maria_icp.test
@@ -0,0 +1,17 @@
+#
+# ICP/Maria tests (Index Condition Pushdown)
+#
+
+--source include/have_maria.inc
+
+set @save_storage_engine= @@storage_engine;
+set storage_engine=Maria;
+set @maria_icp_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+--source include/icp_tests.inc
+
+set storage_engine= @save_storage_engine;
+set optimizer_switch=@maria_icp_tmp;
+
+
diff --git a/mysql-test/t/maria_mrr.test b/mysql-test/t/maria_mrr.test
new file mode 100644
index 00000000000..fe7dc7acc79
--- /dev/null
+++ b/mysql-test/t/maria_mrr.test
@@ -0,0 +1,213 @@
+-- source include/have_maria.inc
+#
+# MRR/Maria tests.
+#
+
+--disable_warnings
+drop table if exists t1,t2,t3,t4;
+--enable_warnings
+
+set @maria_mrr_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+set @mrr_buffer_size_save= @@mrr_buffer_size;
+
+set @save_storage_engine= @@storage_engine;
+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'), (87, 442, 'z'), (98, 445, 'v'), (86, 442, 'x'),
+ (97, 445, 't'), (85, 442, 'b'), (96, 445, 'l'), (84, 442, 'a'), (95, 445, 'k');
+
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
+
+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;
+
+set join_cache_level=@save_join_cache_level;
+
+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 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'),
+ (11,'zx'), (12,'abcdefjhjm'), (13,'jn'), (14,'abcdefjhjp'), (16,'abcdefjhjr');
+
+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;
+
+--echo #
+--echo # BUG#693747: Assertion multi_range_read.cc:908: int DsMrr_impl::dsmrr_init(
+--echo #
+set @_save_join_cache_level= @@join_cache_level;
+set @_save_join_buffer_size= @@join_buffer_size;
+
+set join_cache_level=8;
+set join_buffer_size=10000;
+
+CREATE TABLE t1 (
+ f2 varchar(32) COLLATE latin1_swedish_ci,
+ f3 int(11),
+ f4 varchar(1024) COLLATE utf8_bin,
+ f5 varchar(1024) COLLATE latin1_bin,
+ KEY (f5)
+) ENGINE=Aria TRANSACTIONAL=0 ;
+
+--echo # Fill the table with some data
+--disable_query_log
+INSERT IGNORE INTO t1 VALUES
+('cueikuirqr','0','f4-data','hcueikuirqrzflno'),('her','0','f4-data','ehcueikuirqrzfln'),
+('YKAOE','0','f4-data','qieehcueikuirqrz'),('youre','0','f4-data','nkqieehcueikuirq'),
+('b','0','f4-data','the'),('MGUDG','0','f4-data','m'),
+('UXAGU','0','f4-data','HZXVA'),('bwbgsnkqie','0','f4-data','something'),
+('s','0','f4-data','slelfhjawbwbgsnk'),('the','0','f4-data','if'),
+('TDLKE','0','f4-data','MGWNJ'),('do','0','f4-data','see'),
+('why','0','f4-data','mean'),('THKCG','0','f4-data','YFLDY'),
+('x','0','f4-data','e'),('yncitaeysb','0','f4-data','tgyncitaeysbgucs'),
+('ZEOXX','0','f4-data','jawbwbgsnkqieehc'),('hjawbwbgsn','0','f4-data','fhjawbwbgsnkqiee'),
+('all','0','f4-data','sbgucsgqslelfhja'),('the','0','f4-data','would'),
+('mtgyncitae','0','f4-data','ISNQQ'),('KNCUI','0','f4-data','want'),
+('is','0','f4-data','i'),('out','0','f4-data','jvcmjlmtgyncitae'),
+('it','0','f4-data','you'),('LHDIH','0','f4-data','txmtxyjvcmjlmtgy'),
+('z','0','f4-data','ntxmtxyjvcmjlmtg'),('vyhnmvgmcn','0','f4-data','AIGQK'),
+('ytvyhnmvgm','0','f4-data','z'),('t','0','f4-data','on'),
+('xqegbytvyh','0','f4-data','ixqegbytvyhnmvgm'),('WGVRU','0','f4-data','h'),
+('b','0','f4-data','z'),('who','0','f4-data','gddixqegbytvy'),
+('PMLFL','0','f4-data','vgmcntxmtxyjvcmj'),('back','0','f4-data','n'),
+('i','0','f4-data','PZGUB'),('f','0','f4-data','the'),
+('PNXVP','0','f4-data','v'),('MAKKL','0','f4-data','CGCWF'),
+('RMDAV','0','f4-data','v'),('l','0','f4-data','n'),
+('rhnoypgddi','0','f4-data','VIZNE'),('t','0','f4-data','a'),
+('like','0','f4-data','JSHPZ'),('pskeywslmk','0','f4-data','q'),
+('QZZJJ','0','f4-data','c'),('atlxepskey','0','f4-data','YJRMA'),
+('YUVOU','0','f4-data','eywslmkdrhnoypgd'),('some','0','f4-data','r'),
+('c','0','f4-data','her'),('o','0','f4-data','EMURT'),
+('if','0','f4-data','had'),('when','0','f4-data','CLVWT'),
+('blfufrcdjm','0','f4-data','IZCZN'),('vutblfufrc','0','f4-data','how'),
+('why','0','f4-data','I'),('IXLYQ','0','f4-data','weuwuvutblfufrcd'),
+('here','0','f4-data','m'),('ZOCTJ','0','f4-data','IDSFD'),
+('kqsweuwuvu','0','f4-data','oh'),('ykqsweuwuv','0','f4-data','zykqsweuwuvutblf'),
+('zezykqsweu','0','f4-data','t'),('q','0','f4-data','o'),
+('IBKAU','0','f4-data','oh'),('ivjisuzezy','0','f4-data','XHXKE'),
+('xsivjisuze','0','f4-data','plxsivjisuzezykq'),('have','0','f4-data','uvplxsivjisuzezy'),
+('on','0','f4-data','me'),('ijkfuvplxs','0','f4-data','OGEHV'),
+('u','0','f4-data','okay'),('i','0','f4-data','pajzbbojshnijkfu'),
+('of','0','f4-data','g'),('for','0','f4-data','Im'),
+('or','0','f4-data','ZOJHX'),('n','0','f4-data','you'),
+('that','0','f4-data','just'),('bbojshnijk','0','f4-data','JYGSJ'),
+('k','0','f4-data','y'),('k','0','f4-data','y'),
+('be','0','f4-data','m'),('fnbmxwicrk','0','f4-data','t'),
+('yaffpegvav','0','f4-data','have'),('crkdymahya','0','f4-data','QQWQI'),
+('t','0','f4-data','hnijkfuvplxsivji'),('dgxpajzbbo','0','f4-data','vavdgxpajzbbojsh'),
+('g','0','f4-data','pegvavdgxpajzbbo'),('Im','0','f4-data','ffpegvavdgxpajzb');
+--enable_query_log
+
+
+SELECT alias2.* , alias1.f2
+FROM
+ t1 AS alias1
+ LEFT JOIN t1 AS alias2 ON alias1.f2 = alias2.f5
+WHERE
+ alias2.f3 < 0;
+
+set join_cache_level=@_save_join_cache_level;
+set join_buffer_size=@_save_join_buffer_size;
+set optimizer_switch=@maria_mrr_tmp;
+
+drop table t1;
diff --git a/mysql-test/t/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/metadata.test b/mysql-test/t/metadata.test
index 9bfb47c53be..115c320003a 100644
--- a/mysql-test/t/metadata.test
+++ b/mysql-test/t/metadata.test
@@ -143,3 +143,11 @@ DROP VIEW v1;
DROP TABLE t1;
--echo End of 5.0 tests
+
+--enable_metadata
+
+#
+# lp:740173 5.1-micro reports incorrect Length metadata for TIME expressions
+#
+select cast('01:01:01' as time), cast('01:01:01' as time(2));
+
diff --git a/mysql-test/t/mrr_icp_extra.test b/mysql-test/t/mrr_icp_extra.test
new file mode 100644
index 00000000000..f1b21154449
--- /dev/null
+++ b/mysql-test/t/mrr_icp_extra.test
@@ -0,0 +1,239 @@
+
+set @mrr_icp_extra_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+SET NAMES latin1;
+CREATE TABLE t1
+(s1 char(10) COLLATE latin1_german1_ci,
+ s2 char(10) COLLATE latin1_swedish_ci,
+ KEY(s1),
+ KEY(s2));
+
+INSERT INTO t1 VALUES ('a','a');
+INSERT INTO t1 VALUES ('b','b');
+INSERT INTO t1 VALUES ('c','c');
+INSERT INTO t1 VALUES ('d','d');
+INSERT INTO t1 VALUES ('e','e');
+INSERT INTO t1 VALUES ('f','f');
+INSERT INTO t1 VALUES ('g','g');
+INSERT INTO t1 VALUES ('h','h');
+INSERT INTO t1 VALUES ('i','i');
+INSERT INTO t1 VALUES ('j','j');
+
+EXPLAIN SELECT * FROM t1 WHERE s1='a';
+EXPLAIN SELECT * FROM t1 WHERE s2='a';
+EXPLAIN SELECT * FROM t1 WHERE s1='a' COLLATE latin1_german1_ci;
+EXPLAIN SELECT * FROM t1 WHERE s2='a' COLLATE latin1_german1_ci;
+
+EXPLAIN SELECT * FROM t1 WHERE s1 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci;
+EXPLAIN SELECT * FROM t1 WHERE s2 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci;
+
+EXPLAIN SELECT * FROM t1 WHERE s1 IN ('a','b' COLLATE latin1_german1_ci);
+EXPLAIN SELECT * FROM t1 WHERE s2 IN ('a','b' COLLATE latin1_german1_ci);
+
+EXPLAIN SELECT * FROM t1 WHERE s1 LIKE 'a' COLLATE latin1_german1_ci;
+EXPLAIN SELECT * FROM t1 WHERE s2 LIKE 'a' COLLATE latin1_german1_ci;
+
+DROP TABLE t1;
+
+--echo #
+--echo #
+
+CREATE TABLE t2 (a varchar(32), b int(11), c float, d double,
+UNIQUE KEY a (a,b,c), KEY b (b), KEY c (c));
+CREATE TABLE t1 (a varchar(32), b char(3), UNIQUE KEY a (a,b), KEY b (b));
+CREATE TABLE t3 (a varchar(32), b char(3), UNIQUE KEY a (a,b));
+INSERT INTO t3 SELECT * FROM t1;
+EXPLAIN
+SELECT d FROM t1, t2
+WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
+ORDER BY t2.c LIMIT 1;
+SELECT d FROM t1, t2
+WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
+ORDER BY t2.c LIMIT 1;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo #
+create table t1(a int, b int, index(b));
+insert into t1 values (2, 1), (1, 1), (4, NULL), (3, NULL), (6, 2), (5, 2);
+insert into t1 values (2, 11), (1, 11), (4, 14), (3, 14), (6, 12), (5, 12);
+explain select * from t1 where b=1 or b is null order by a;
+select * from t1 where b=1 or b is null order by a;
+explain select * from t1 where b=2 or b is null order by a;
+select * from t1 where b=2 or b is null order by a;
+drop table t1;
+
+--echo #
+--echo #
+CREATE TABLE t1 (
+FieldKey varchar(36) NOT NULL default '',
+LongVal bigint(20) default NULL,
+StringVal mediumtext,
+KEY FieldKey (FieldKey),
+KEY LongField (FieldKey,LongVal),
+KEY StringField (FieldKey,StringVal(32))
+);
+INSERT INTO t1 VALUES ('0',3,'0'),('0',2,'1'),('0',1,'2'),('1',2,'1'),('1',1,'3'), ('1',0,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('3',2,'1'),('3',1,'2'),('3','3','3');
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (LongField, StringField) WHERE FieldKey > '2' ORDER BY LongVal;
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (FieldKey, LongField) WHERE FieldKey > '2' ORDER BY LongVal;
+SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
+DROP TABLE t1;
+--echo #
+--echo #
+CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
+INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
+INSERT into t2 values (1,1,1), (2,2,2);
+optimize table t1;
+explain select * from t1 force index (a) where a=0 or a=2;
+select * from t1 force index (a) where a=0 or a=2;
+drop table t1;
+--echo #
+--echo #
+create table t1
+(
+ pk1 int not null,
+ pk2 int not null,
+
+ key1 int not null,
+ key2 int not null,
+
+ pktail1ok int not null,
+ pktail2ok int not null,
+ pktail3bad int not null,
+ pktail4bad int not null,
+ pktail5bad int not null,
+
+ pk2copy int not null,
+ badkey int not null,
+
+ filler1 char (200),
+ filler2 char (200),
+ key (key1),
+ key (key2),
+
+ /* keys with tails from CPK members */
+ key (pktail1ok, pk1),
+ key (pktail2ok, pk1, pk2),
+ key (pktail3bad, pk2, pk1),
+ key (pktail4bad, pk1, pk2copy),
+ key (pktail5bad, pk1, pk2, pk2copy),
+
+ primary key (pk1, pk2)
+);
+
+--disable_query_log
+set autocommit=0;
+let $1=10000;
+while ($1)
+{
+ eval insert into t1 values ($1 div 10,$1 mod 100, $1/100,$1/100, $1/100,$1/100,$1/100,$1/100,$1/100, $1 mod 100, $1/1000,'filler-data-$1','filler2');
+ dec $1;
+}
+set autocommit=1;
+--enable_query_log
+explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
+select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
+drop table t1;
+
+--echo #
+--echo #
+CREATE TABLE t1 (
+f1 int,
+f4 varchar(32),
+f5 int,
+PRIMARY KEY (f1),
+KEY (f4)
+);
+INSERT INTO t1 VALUES
+(5,'H',1), (9,'g',0), (527,'i',0), (528,'y',1), (529,'S',6),
+(530,'m',7), (531,'b',2), (532,'N',1), (533,'V',NULL), (534,'l',1),
+(535,'M',0), (536,'w',1), (537,'j',5), (538,'l',0), (539,'n',2),
+(540,'m',2), (541,'r',2), (542,'l',2), (543,'h',3),(544,'o',0),
+(956,'h',0), (957,'g',0), (958,'W',5), (959,'s',3), (960,'w',0),
+(961,'q',0), (962,'e',NULL), (963,'u',7), (964,'q',1), (965,'N',NULL),
+(966,'e',0), (967,'t',3), (968,'e',6), (969,'f',NULL), (970,'j',0),
+(971,'s',3), (972,'I',0), (973,'h',4), (974,'g',1), (975,'s',0),
+(976,'r',3), (977,'x',1), (978,'v',8), (979,'j',NULL), (980,'z',7),
+(981,'t',9), (982,'j',5), (983,'u',NULL), (984,'g',6), (985,'w',1),
+(986,'h',1), (987,'v',0), (988,'v',0), (989,'c',2), (990,'b',7),
+(991,'z',0), (992,'M',1), (993,'u',2), (994,'r',2), (995,'b',4),
+(996,'A',2), (997,'u',0), (998,'a',0), (999,'j',2), (1,'I',2);
+EXPLAIN
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+drop table t1;
+
+--echo #
+--echo #
+--source include/varchar.inc
+
+--echo #
+--echo #
+--disable_warnings
+drop database if exists world;
+--enable_warnings
+CREATE DATABASE world;
+
+use world;
+
+--source include/world_schema.inc
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+--source include/world.inc
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+
+--replace_column 9 #
+explain
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+
+--replace_column 9 #
+explain
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 7000000;
+
+--replace_column 9 #
+explain
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 7000000;
+
+--replace_column 6 # 7 # 9 #
+explain
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+
+--replace_column 6 # 7 # 9 #
+explain
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+
+drop database world;
+use test;
+
+set @mrr_icp_extra_tmp=@@optimizer_switch;
+
diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test
index 09efdb74995..7743aa5efca 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;
@@ -685,7 +685,57 @@ CREATE FUNCTION f1 () RETURNS BLOB RETURN 1;
CREATE TABLE t1 (f1 DATE);
INSERT INTO t1 VALUES('2001-01-01');
UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1;
+CREATE view v1 as SELECT f1() FROM t1;
+UPDATE (SELECT 1 FROM t1 WHERE f1 = (select * from v1)) x, t1 SET f1 = 1;
+DROP VIEW v1;
DROP FUNCTION f1;
DROP TABLE t1;
+--echo #
+--echo # MDEV-4123: Incorrect results after multi-table update or
+--echo # assertion `!table || (!table->read_set ||
+--echo # bitmap_is_set(table->read_set, field_index))' failure
+--echo #
+
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+ id int(10) unsigned NOT NULL,
+ level tinyint(3) unsigned NOT NULL,
+ PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES (2519583,1);
+
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t2 (
+ club_id int(11) NOT NULL DEFAULT '0',
+ profile_id int(11) NOT NULL DEFAULT '0',
+ member_level_id int(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (profile_id,club_id)
+);
+INSERT INTO t2 VALUES (2,2519583,12);
+
+DROP TABLE IF EXISTS t3;
+CREATE TABLE t3 (
+ member_level_id int(11) unsigned NOT NULL DEFAULT '0',
+ map_level int(11) unsigned NOT NULL DEFAULT '0',
+ map_status int(11) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (member_level_id)
+);
+INSERT INTO t3 VALUES (12,12,1);
+
+CREATE
+ VIEW v1 AS
+ select club_id,profile_id,
+ map_level AS member_level_id,map_status AS member_status
+ from (t2 tc join t3 map
+ on(((tc.member_level_id = map.member_level_id) and
+ (club_id = 2))));
+
+select level, count(*) as cnt from t1 group by level;
+UPDATE t1 c LEFT JOIN v1 t ON (c.id = t.profile_id AND t.club_id = 2)
+ SET c.level = IF (t.member_status IS NULL, 1, IF (t.member_status = 1, 2,3));
+select level, count(*) as cnt from t1 group by level;
+drop view v1;
+drop table t1,t2,t3;
+
--echo end of tests
diff --git a/mysql-test/t/myisam-big.test b/mysql-test/t/myisam-big.test
new file mode 100644
index 00000000000..2fec2450ecd
--- /dev/null
+++ b/mysql-test/t/myisam-big.test
@@ -0,0 +1,64 @@
+#
+# Test bugs in the MyISAM code that require more space/time
+--source include/big_test.inc
+
+# Initialise
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+
+#
+# BUG#925377:
+# Querying myisam table metadata while 'alter table..enable keys' is
+# running may corrupt the table
+#
+create table t1 (id int, sometext varchar(100)) engine=myisam;
+insert into t1 values (1, "hello"),(2, "hello2"),(4, "hello3"),(4, "hello4");
+create table t2 like t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+insert into t2 select * from t1;
+insert into t1 select * from t1;
+select count(*) from t1;
+connect (con2,localhost,root,,);
+connection con2;
+alter table t1 add index (id), add index(sometext), add index(sometext,id);
+alter table t1 disable keys;
+send alter table t1 enable keys;
+connection default;
+--sleep 1
+--disable_query_log
+--disable_result_log
+show table status like 't1';
+--enable_query_log
+--enable_result_log
+connection con2;
+reap;
+disconnect con2;
+connection default;
+drop table t1,t2;
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index d2a4a773c2d..70e62c62d3f 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -350,7 +350,7 @@ DROP TABLE t1;
#
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
-INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+INSERT into t1 values (0,null,0), (0,null,1), (0,null,2), (0,null,3), (1,1,4);
create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
INSERT into t2 values (1,1,1), (2,2,2);
optimize table t1;
@@ -358,7 +358,13 @@ show index from t1;
explain select * from t1,t2 where t1.a=t2.a;
explain select * from t1,t2 force index(a) where t1.a=t2.a;
explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a;
+INSERT into t1 values (2,4,5), (7,8,4), (8,3,1), (9,7,2), (5,5,9);
+optimize table t1;
+show index from t1;
explain select * from t1,t2 where t1.b=t2.b;
+delete from t1 where t1.a>1;
+optimize table t1;
+show index from t1;
explain select * from t1,t2 force index(c) where t1.a=t2.a;
explain select * from t1 where a=0 or a=2;
explain select * from t1 force index (a) where a=0 or a=2;
diff --git a/mysql-test/t/myisam_icp.test b/mysql-test/t/myisam_icp.test
new file mode 100644
index 00000000000..508c282b1dc
--- /dev/null
+++ b/mysql-test/t/myisam_icp.test
@@ -0,0 +1,286 @@
+#
+# ICP/MyISAM tests (Index Condition Pushdown)
+#
+
+set @myisam_icp_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+--source include/icp_tests.inc
+
+--disable_warnings
+drop table if exists t0, t1, t1i, t1m;
+--enable_warnings
+
+#
+# BUG#711565 Index Condition Pushdown can make a thread hold MyISAM locks as well as be unKILLable for long time
+# This is not a ready mysqltest testcase but rather a set of queries that
+# allow to check the bug[fix] manually. Making this testcase automatic is
+# difficult because
+# - big tables are involved
+# - it's difficult to have automatic checks of whether the query could be
+# KILLed that would reliably work on fast/slow buildslaves, etc.
+
+--disable_parsing
+
+ 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,
+ filler char(100),
+ col int,
+ key(kp1, kp2)
+ );
+
+ set myisam_sort_buffer_size=32*1000*1000;
+ insert into t1
+ select
+ 1000 + A.a + 10*B.a + 100*C.a + 1000*D.a + 10000 * F.a,
+ 1,
+ 'filler-data filler-data filler-data filler-data filler-data',
+ 1
+ from
+ t0 A, t0 B, t0 C, t0 D, t0 E, t0 F, t0 G
+ ;
+
+ insert into t1 values (990, 100, 'a record to test index_next checks',100);
+
+ update t1 set kp2=10 where kp1 between 20000+100 and 28000;
+
+ update t1 set kp1=20000 where kp1 between 20000 and 28000;
+
+ insert into t1 values (20000, 100, 'last-20K-record',1);
+
+ create table t1i like t1;
+ alter table t1i engine=innodb;
+ insert into t1i select * from t1;
+
+ create table t1m like t1;
+ alter table t1m engine=maria;
+ insert into t1m select * from t1;
+
+#
+# XtraDB has one check for all kinds of ranges.
+#
+ explain
+ select * from t1i
+ where
+ kp1 < 8000 and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ kp2 +1 > 10;
+
+
+#
+# MyISAM, check range access + mi_rnext():
+# (will return HA_ERR_END_OF_FILE)
+ explain
+ select * from t1
+ where
+ kp1 < 10000 and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ kp2 +1 > 10;
+
+
+#
+# MyISAM, check range access + mi_rkey():
+# (will return HA_ERR_END_OF_FILE)
+ explain
+ select * from t1
+ where
+ kp1 >= 999 and kp1 < 10000 and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ kp2 +1 > 10;
+
+
+
+#
+# MyISAM, check mi_rnext_same:
+#
+
+ explain
+ select * from t1
+ where
+ kp1 = 20000 and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ kp2 +1 < 10;
+
+
+#
+# MyISAM, check mi_rprev:
+#
+
+ explain
+ select * from t1
+ where
+ kp1 = 20000 and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ kp2 +1 > 20
+ order by kp1, kp2 desc;
+
+
+
+#
+# Maria, check range access + maria_rkey():
+#
+ explain
+ select * from t1m
+ where
+ kp1 >= 999 and kp1 < 10000 and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ kp2 +1 > 10;
+
+
+
+#
+# Maria, check range access + maria_rnext():
+#
+ explain
+ select * from t1m
+ where
+ kp1 < 10000 and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ kp2 +1 > 10;
+
+
+#
+# Maria, check maria_rnext_same:
+#
+
+ explain
+ select * from t1m
+ where
+ kp1 = 20000 and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ kp2 +1 > 100;
+
+#
+# Maria, check maria_rprev:
+#
+
+ explain
+ select * from t1m
+ where
+ kp1 = 20000 and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and
+ kp2 +1 > 20
+ order by kp1, kp2 desc;
+
+drop table t0, t1, t1i, t1m;
+
+--enable_parsing
+
+--echo #
+--echo # BUG#826935 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed
+--echo #
+CREATE TABLE t1 ( a int, b varchar(1024), c int, KEY (c), KEY (c,a)) ;
+INSERT INTO t1 VALUES
+ (NULL,'x','-678428672'),
+ (NULL,'ok',NULL),
+ (796262400,'byluovkgwoukfxedyeffsedajyqkyhpaqqpozn', NULL),
+ (7,'STQUF',146014208),
+ (955711488,'WWVOR','-1515388928');
+SELECT b FROM t1 WHERE a != 1 AND c IS NULL ORDER BY 1;
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#870046: ICP for a GROUP BY query
+--echo #
+
+CREATE TABLE t1 (a int, b varchar(1), c varchar(1), INDEX idx(b));
+INSERT INTO t1 VALUES (2,'x','x'), (5,'x','y');
+
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+
+DROP TABLE t1;
+
+--echo #
+--echo # BUG#887026: Wrong result with ICP, outer join, subquery in maria-5.3-icp
+--echo #
+
+CREATE TABLE t1 (c varchar(1));
+INSERT INTO t1 VALUES ('c'), ('c');
+
+CREATE TABLE t2 (c varchar(1), b int);
+INSERT INTO t2 VALUES ('d', NULL),('d', NULL);
+
+CREATE TABLE t3 (c varchar(1));
+INSERT INTO t3 VALUES ('c');
+INSERT INTO t3 VALUES ('c');
+
+CREATE TABLE t4 ( b int, c varchar(1), KEY (b));
+INSERT INTO t4 VALUES (7,'c');
+INSERT INTO t4 VALUES (7,'c');
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
+--echo # Must be t1,t2,t3,t4, with t4 having Full-scan-on-NULL but not Using index condition
+explain
+SELECT * FROM t1 LEFT JOIN t2 ON t1.c=t2.b
+WHERE
+ t2.b NOT IN (SELECT t4.b FROM t3 STRAIGHT_JOIN t4 WHERE t4.b <= 2 AND t4.c = t3.c);
+
+SELECT * FROM t1 LEFT JOIN t2 ON t1.c=t2.b
+WHERE
+ t2.b NOT IN (SELECT t4.b FROM t3 STRAIGHT_JOIN t4 WHERE t4.b <= 2 AND t4.c = t3.c);
+
+SET optimizer_switch=@save_optimizer_switch;
+
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # BUG#1000051: Query with simple join and ORDER BY takes thousands times longer when run with ICP
+--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, col int, filler char(100), key(a, col));
+insert into t1 select A.a + 10*B.a, 1234, 'filler' from t0 A, t0 B, t0 C;
+
+set @tmp_10000051= @@optimizer_switch;
+set optimizer_switch='mrr=off';
+--echo # Must not use ICP:
+explain select * from t1 where a between 5 and 8 order by a desc, col desc;
+set optimizer_switch= @tmp_10000051;
+
+--echo # Must not use ICP:
+explain select * from t1 where a=3 and col > 500 order by a desc, col desc;
+
+drop table t0, t1;
+
+set optimizer_switch=@myisam_icp_tmp;
+
diff --git a/mysql-test/t/myisam_icp_notembedded.test b/mysql-test/t/myisam_icp_notembedded.test
new file mode 100644
index 00000000000..139a9edf648
--- /dev/null
+++ b/mysql-test/t/myisam_icp_notembedded.test
@@ -0,0 +1,139 @@
+-- source include/not_embedded.inc
+
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+
+set @myisam_icp_notembedded_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+--echo #
+--echo # BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN
+--echo #
+CREATE TABLE t1 (
+ b INT,
+ c VARCHAR(1) NOT NULL,
+ d DATETIME,
+ KEY (c, b)
+) ENGINE=MyISAM;
+--echo # INSERT some data
+--disable_query_log
+INSERT INTO t1 ( b, d, c ) VALUES
+(4,'2005-01-08 00:00:00','f'),
+(1,'2004-05-20 10:45:51','c'),(2,'2006-08-11 21:33:49','e'),
+(5,'2003-05-19 00:20:40','a'),(3,'2005-01-03 06:18:39','a'),
+(7,'2008-11-25 18:18:14','b'),(6,'2008-11-09 15:53:46','b'),
+(9,'2003-03-01 03:40:36','c'),(8,'2003-09-25 23:14:09','d'),
+(0,'2007-01-17 09:18:31','f'),(9,'2008-09-08 09:52:24','c'),
+(2,'2008-03-10 00:00:00','a'),(0,'2003-03-14 09:31:07','c'),
+(4,'2005-04-25 00:00:00','h'),(6,'2001-08-01 05:55:55','e'),
+(3,'2005-04-09 01:22:48','f'),(7,'2009-11-12 13:27:22','r'),
+(0,'2009-03-28 05:05:28','h'),(15,'2005-05-16 04:35:41','f'),
+(7,'2006-03-26 05:19:58','c'),(9,'2002-10-06 02:17:00','g'),
+(4,'2007-01-28 03:28:20','b'),(1,'2009-04-22 10:16:40','c'),
+(2,'2003-01-01 19:39:00','f'),(0,'2008-05-03 19:16:29','t'),
+(2,'2005-01-28 00:00:00','j'),(8,'2004-01-10 00:00:00','w'),
+(8,'2000-06-13 21:56:37','a'),(5,'2001-03-21 19:24:49','o'),
+(99,'2003-12-20 21:29:06','f'),(0,'1900-01-01 00:00:00','w'),
+(7,'2000-12-19 00:00:00','c'),(0,'2000-03-03 06:10:19','l'),
+(3,'2000-08-11 00:00:00','q'),(0,'2007-05-25 03:46:41','e'),
+(241,'2005-05-17 00:00:00','j'),(4,'2005-11-02 00:44:06','r'),
+(43,'2001-07-11 00:00:00','a'),(1,'2008-12-01 18:30:27','z'),
+(4,'2004-10-25 00:00:00','i'),(5,'2000-04-08 12:12:01','c'),
+(0,'1900-01-01 00:00:00','f'),(9,'2002-05-13 22:47:02','p'),
+(1,'2008-10-09 15:39:40','d'),(3,'2004-06-24 00:00:00','d'),
+(0,'2008-03-06 00:00:00','r'),(9,'2007-04-16 18:40:03','i'),
+(3,'2008-03-16 19:49:37','t'),(7,'2003-07-15 08:11:21','d'),
+(8,'2005-02-11 00:04:53','r'),(0,'2002-09-21 00:00:00','y'),
+(3,'2004-11-03 00:37:21','z'),(6,'2007-10-18 00:00:00','e'),
+(6,'2007-01-21 10:42:56','o'),(5,'2000-03-26 21:21:04','b'),
+(9,'2001-03-15 08:08:21','e'),(1,'2001-10-16 12:56:59','a'),
+(6,'2004-05-01 23:45:55','o'),(4,'2000-03-04 00:00:00','f'),
+(9,'2002-12-03 16:48:28','e'),(8,'2003-01-09 00:36:07','m'),
+(1,'2006-06-22 04:32:41','s'),(8,'2008-09-20 05:01:48','q'),
+(4,'2006-06-02 22:15:31','g'),(2,'2002-05-14 07:07:42','e'),
+(7,'2005-06-05 01:30:42','r'),(127,'2004-05-11 01:56:48','a'),
+(210,'2003-11-05 00:41:34','z'),(5,'1900-01-01 00:00:00','h'),
+(1,'2006-04-16 00:00:00','f'),(7,'2000-12-17 00:00:00','x'),
+(8,'2009-05-09 20:43:07','b'),(175,'2008-11-26 16:33:09','p'),
+(0,'2002-05-09 21:18:44','v'),(8,'2002-06-01 11:32:25','k'),
+(1,'2008-11-09 23:56:00','a'),(0,'2008-01-08 10:18:46','c'),
+(2,'2005-04-16 00:00:00','o'),(5,'2002-08-25 00:00:00','b'),
+(64,'2005-12-05 21:51:52','b'),(4,'2005-08-10 00:00:00','i'),
+(6,'2006-03-23 00:00:00','d'),(9,'2007-01-27 00:00:00','i'),
+(8,'2008-08-16 00:00:00','a'),(7,'2003-01-16 12:13:18','k'),
+(0,'2003-06-22 00:00:00','v'),(5,'2008-06-20 05:43:56','u'),
+(8,'2004-09-23 18:57:17','e'),(1,'2000-12-26 00:00:00','y'),
+(4,'2009-06-01 13:00:28','e'),(1,'2009-11-18 06:28:48','m'),
+(0,'2004-06-12 10:01:10','e'),(2,'2005-10-16 01:48:55','e'),
+(5,'2001-12-23 09:50:21','l'),(6,'1900-01-01 00:00:00','a'),
+(1,'2001-10-28 00:00:00','d'),(1,'2008-07-12 23:30:19','s'),
+(0,'2002-10-11 16:51:16','r'),(4,'2007-09-18 06:27:10','x'),
+(1,'2007-02-21 12:28:14','e'),(6,'2001-09-16 00:00:00','f'),
+(0,'2007-09-20 02:25:45','c'),(0,'2006-08-07 03:25:56','j'),
+(8,'2006-12-04 20:20:32','t'),(7,'2007-09-05 10:13:10','i'),
+(9,'2006-04-12 17:59:57','t'),(2,'2009-04-28 00:06:09','b'),
+(8,'2000-01-07 00:00:00','b'),(7,'2000-03-25 10:04:41','k'),
+(4,'2000-07-10 00:44:55','w'),(9,'2007-09-22 14:26:26','j'),
+(9,'2003-09-11 22:41:17','a'),(0,'2004-06-07 13:52:32','c'),
+(8,'2008-10-09 00:00:00','p'),(1,'2007-04-01 00:00:00','c'),
+(9,'2000-12-05 00:00:00','i'),(3,'1900-01-01 00:00:00','a'),
+(3,'2005-12-24 21:50:54','e'),(8,'2009-07-21 19:34:55','n'),
+(9,'2005-11-13 17:57:56','d'),(7,'2004-10-07 06:41:39','l'),
+(1,'2004-11-20 08:05:08','u'),(3,'2005-05-25 00:00:00','r'),
+(1,'2006-09-02 14:16:41','u'),(8,'2006-01-07 00:00:00','a'),
+(9,'2003-04-05 00:54:20','w'),(2,'2003-12-22 00:00:00','a'),
+(9,'2006-04-16 17:31:40','e'),(6,'2005-02-10 14:22:46','e'),
+(7,'2004-04-27 05:54:52','p'),(1,'2005-12-07 00:00:00','t'),
+(5,'2004-04-03 20:56:28','d'),(4,'2000-09-07 05:17:16','h'),
+(2,'2004-08-04 16:10:42','i'),(1,'2007-03-04 00:00:00','b'),
+(9,'1900-01-01 00:00:00','d'),(1,'2000-05-12 23:02:50','m'),
+(2,'1900-01-01 00:00:00','l'),(1,'1900-01-01 00:00:00','k'),
+(4,'2000-07-14 01:25:18','d'),(5,'2009-08-21 00:00:00','w'),
+(6,'2009-05-25 13:33:54','f'),(7,'2006-06-13 00:00:00','e'),
+(8,'1900-01-01 00:00:00','a'),(6,'2004-02-24 00:00:00','j'),
+(0,'2003-05-21 07:03:46','k'),(9,'1900-01-01 00:00:00','e'),
+(2,'1900-01-01 00:00:00','y'),(2,'2000-12-22 00:00:00','e'),
+(3,'2003-09-26 00:00:00','f'),(2,'2001-01-13 08:20:19','h'),
+(9,'2008-09-23 20:03:28','n'),(5,'2007-03-20 02:41:38','s'),
+(1,'2009-02-14 10:27:18','a'),(0,'2001-08-10 17:44:05','s'),
+(3,'2008-01-20 12:49:54','v'),(1,'2001-05-05 09:09:59','r');
+--enable_query_log
+CREATE TABLE t2 ( a INT ) ENGINE=MyISAM;
+INSERT INTO t2 VALUES
+ (7),(3),(7),(3);
+
+# 'con2' will be the connection that will run all the KILLable statements
+--connect (con2,127.0.0.1,root,,test)
+
+--let $run = 300
+--let $con_id = `SELECT CONNECTION_ID()`
+
+--echo # Now run a number of ICP queries while trying to kill them
+--disable_query_log
+--disable_result_log
+while ($run)
+{
+ --send
+ SELECT * FROM t1 AS alias1 STRAIGHT_JOIN t1 AS alias2
+ ON alias2.c = alias1.c
+ WHERE alias2.b >= 9;
+
+ --connect (con1,127.0.0.1,root,,test)
+ --eval KILL QUERY $con_id
+ --disconnect con1
+
+ --dec $run
+
+ --connection con2
+ --error 0,ER_QUERY_INTERRUPTED
+ --reap
+}
+--enable_result_log
+--enable_query_log
+--disconnect con2
+--connection default
+DROP TABLE t1,t2;
+
+set optimizer_switch=@myisam_icp_notembedded_tmp;
+
diff --git a/mysql-test/t/myisam_mrr.test b/mysql-test/t/myisam_mrr.test
new file mode 100644
index 00000000000..28385c61b0f
--- /dev/null
+++ b/mysql-test/t/myisam_mrr.test
@@ -0,0 +1,325 @@
+#
+# MRR/MyISAM tests.
+#
+
+--disable_warnings
+drop table if exists t0, t1, t2, t3;
+--enable_warnings
+
+set @myisam_mrr_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @mrr_buffer_size_save= @@mrr_buffer_size;
+set mrr_buffer_size=79;
+
+-- 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');
+INSERT INTO t1 VALUES
+ (110,8,'v','v'),(111,8,'f','f'), (112,5,'v','v'),
+ (113,8,'s','s'),(114,8,'a','a'),(115,6,'p','p'),
+ (116,7,'z','z'),(117,2,'a','a'),(118,5,'h','h'),
+ (119,7,'h','h'),(120,2,'v','v'),(121,9,'v','v'),
+ (122,142,'b','b'),(123,3,'y','y'),(124,0,'v','v'),
+ (125,3,'m','m'),(126,5,'z','z'),(127,9,'n','n'),
+ (128,1,'d','d'),(129,107,'a','a');
+
+SELECT COUNT(*)
+FROM
+ t1 AS table2, t1 AS table3
+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;
+
+
+--echo #
+--echo # BUG#730133: Wrong result with jkl = 7, BKA, ICP in maria-5.3 + compound index
+--echo #
+set @tmp_730133_jcl= @@join_cache_level;
+set join_cache_level = 7;
+
+set @tmp_730133_os= @@optimizer_switch;
+set optimizer_switch= 'join_cache_hashed=off,join_cache_bka=on,index_condition_pushdown=on,optimize_join_buffer_size=on';
+
+CREATE TABLE t1 (f1 int, f2 int, f3 int, f4 int, f5 int, KEY (f4,f3));
+INSERT IGNORE INTO t1 VALUES ('2','9','5','0','0'),('4','7','0','0','0'),
+ ('6','97','190','0','0'),('7','3','6','0','0'),('11','101','186','0','0'),
+ ('14','194','226','0','0'),('15','148','133','0','0'),
+ ('16','9','6','0','0'),('17','9','3','0','0'),('18','1','8','0','0'),
+ ('19','1','5','0','0'),('20','5','7','0','0');
+
+explain
+SELECT COUNT(alias2.f2)
+FROM
+ t1 STRAIGHT_JOIN
+ t1 AS alias3 STRAIGHT_JOIN
+ t1 AS alias2 FORCE KEY (f4)
+WHERE
+ alias2.f4=alias3.f5 AND
+ alias2.f3 > alias3.f1;
+
+SELECT COUNT(alias2.f2)
+FROM
+ t1 STRAIGHT_JOIN
+ t1 AS alias3 STRAIGHT_JOIN
+ t1 AS alias2 FORCE KEY (f4)
+WHERE
+ alias2.f4=alias3.f5 AND
+ alias2.f3 > alias3.f1;
+
+set @@join_cache_level= @tmp_730133_jcl;
+set @@optimizer_switch= @tmp_730133_os;
+drop table t1;
+
+--echo #
+--echo # Test of MRR handler counters
+--echo #
+flush status;
+show status like 'Handler_mrr%';
+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(200), key(a));
+insert into t1
+select A.a+10*B.a+100*C.a+1000*D.a, 123,'filler' from t0 A, t0 B, t0 C, t0 D;
+
+explain select sum(b) from t1 where a < 10;
+--echo # This should show one MRR scan and no re-fills:
+flush status;
+select sum(b) from t1 where a < 10;
+show status like 'handler_mrr%';
+
+set @mrr_buffer_size_save= @@mrr_buffer_size;
+--disable_warnings
+set mrr_buffer_size=128;
+--enable_warnings
+
+explain select sum(b) from t1 where a < 1600;
+--echo # This should show one MRR scan and one extra rowid sort:
+flush status;
+select sum(b) from t1 where a < 1600;
+show status like 'handler_mrr%';
+set @@mrr_buffer_size= @mrr_buffer_size_save;
+
+--echo #Now, let's check BKA:
+set @join_cache_level_save= @@join_cache_level;
+set @join_buffer_size_save= @@join_buffer_size;
+set join_cache_level=6;
+
+explain select sum(t1.b) from t0,t1 where t0.a=t1.a;
+flush status;
+select sum(t1.b) from t0,t1 where t0.a=t1.a;
+show status like 'handler_mrr%';
+
+--disable_warnings
+set join_buffer_size=10;
+--enable_warnings
+explain select sum(t1.b) from t0,t1 where t0.a=t1.a;
+flush status;
+select sum(t1.b) from t0,t1 where t0.a=t1.a;
+--replace_result 1 1or2 2 1or2
+show status like 'handler_mrr%';
+
+set join_cache_level= @join_cache_level_save;
+set join_buffer_size= @join_buffer_size_save;
+
+drop table t0, t1;
+
+## This must be last line in the file:
+set optimizer_switch= @myisam_mrr_tmp;
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index dc6c8cf9be7..2c6802b0ce5 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -6,7 +6,7 @@
#
--disable_warnings
-drop table if exists t1;
+drop table if exists t1,t2,t3;
--enable_warnings
#
@@ -124,6 +124,13 @@ drop table t1;
--exec echo "use" > $file
--exec $MYSQL < $file 2>&1
+# Test exceutable comments
+--exec echo "SELECT 1 /*! +1 */;" > $file
+--exec echo "SELECT 1 /*M! +1 */;" >> $file
+--exec echo "SELECT 1 /*!00000 +1 */;" >> $file
+--exec echo "SELECT 1 /*M!00000 +1 */" >> $file
+--exec $MYSQL < $file 2>&1
+
--remove_file $file
#
diff --git a/mysql-test/t/mysqlbinlog-master.opt b/mysql-test/t/mysqlbinlog-master.opt
index a9f4a6010d8..cef79bc8585 100644
--- a/mysql-test/t/mysqlbinlog-master.opt
+++ b/mysql-test/t/mysqlbinlog-master.opt
@@ -1,2 +1 @@
---max-binlog-size=4096
--force-restart
diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
index 98ee18b554e..6a73a170d12 100644
--- a/mysql-test/t/mysqlbinlog.test
+++ b/mysql-test/t/mysqlbinlog.test
@@ -3,10 +3,18 @@
-- source include/have_binlog_format_statement.inc
-- source include/have_log_bin.inc
+-- source include/binlog_start_pos.inc
# Deletes all the binary logs
reset master;
+# We need small binlog size to break the last LOAD DATA INFILE below so that
+# the corresponding Begin_load_query will be written to master-bin.000001
+# while the Execute_load_query will be written to master-bin.000002.
+
+SET @save_binlog_size= @@global.max_binlog_size;
+SET @@global.max_binlog_size= 4096;
+
# we need this for getting fixed timestamps inside of this test
set timestamp=1000000000;
@@ -26,13 +34,15 @@ insert into t2 values ();
# test for load data and load data distributed among the several
# files (we need to fill up first binlog)
-load data infile '../../std_data/words.dat' into table t1;
-load data infile '../../std_data/words.dat' into table t1;
-load data infile '../../std_data/words.dat' into table t1;
-load data infile '../../std_data/words.dat' into table t1;
-load data infile '../../std_data/words.dat' into table t1;
+load data infile '../../std_data/words3.dat' into table t1;
+load data infile '../../std_data/words3.dat' into table t1;
+load data infile '../../std_data/words3.dat' into table t1;
+load data infile '../../std_data/words3.dat' into table t1;
+load data infile '../../std_data/words3.dat' into table t1;
# simple query to show more in second binlog
insert into t1 values ("Alas");
+
+### Starting master-bin.000003
flush logs;
# delimiters are for easier debugging in future
@@ -46,7 +56,7 @@ select "--- Local --" as "";
#
let $MYSQLD_DATADIR= `select @@datadir`;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
+--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLD_DATADIR/master-bin.000001
# this should not fail but shouldn't produce any working statements
@@ -54,7 +64,7 @@ let $MYSQLD_DATADIR= `select @@datadir`;
select "--- Broken LOAD DATA --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
+--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLD_DATADIR/master-bin.000002 2> /dev/null
# this should show almost nothing
@@ -62,17 +72,17 @@ select "--- Broken LOAD DATA --" as "";
select "--- --database --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
+--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --database=nottest $MYSQLD_DATADIR/master-bin.000001 2> /dev/null
# this test for position option
--disable_query_log
select "--- --position --" as "";
--enable_query_log
+let $start_pos= `select @binlog_start_pos + 227`;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
---exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=332 $MYSQLD_DATADIR/master-bin.000002
-
+--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=$start_pos $MYSQLD_DATADIR/master-bin.000002
# These are tests for remote binlog.
# They should return the same as previous test.
@@ -83,7 +93,7 @@ select "--- Remote --" as "";
# This is broken now
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
+--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
# This is broken too
@@ -91,7 +101,7 @@ select "--- Remote --" as "";
select "--- Broken LOAD DATA --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
+--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 2> /dev/null
# And this too ! (altough it is documented)
@@ -99,34 +109,39 @@ select "--- Broken LOAD DATA --" as "";
select "--- --database --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
+--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --database=nottest master-bin.000001 2> /dev/null
# Strangely but this works
--disable_query_log
select "--- --position --" as "";
--enable_query_log
+let $start_pos= `select @binlog_start_pos + 227`;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
---exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --position=332 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
+--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --position=$start_pos --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
# Bug#7853 mysqlbinlog does not accept input from stdin
--disable_query_log
select "--- reading stdin --" as "";
--enable_query_log
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
+--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form - < $MYSQL_TEST_DIR/std_data/trunc_binlog.000001
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
+--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --position=79 - < $MYSQL_TEST_DIR/std_data/trunc_binlog.000001
drop table t1,t2;
+SET @@global.max_binlog_size= @save_binlog_size;
+
#
# Bug#14157 utf8 encoding in binlog without set character_set_client
#
+### Starting master-bin.000004
flush logs;
+
--write_file $MYSQLTEST_VARDIR/tmp/bug14157.sql
create table if not exists t5 (a int);
set names latin1;
@@ -140,6 +155,8 @@ EOF
# resulted binlog, parly consisting of multi-byte utf8 chars,
# must be digestable for both client and server. In 4.1 the client
# should use default-character-set same as the server.
+
+### Starting master-bin.000005
flush logs;
--exec $MYSQL_BINLOG --short-form $MYSQLD_DATADIR/master-bin.000004 | $MYSQL
select * from t5 /* must be (1),(1) */;
@@ -150,6 +167,8 @@ drop table t5;
# Check that a dump created by mysqlbinlog reproduces
# lc_time_names dependent values correctly
#
+
+### Starting master-bin.000006
flush logs;
create table t5 (c1 int, c2 varchar(128) character set latin1 not null);
insert into t5 values (1, date_format('2001-01-01','%W'));
@@ -158,7 +177,10 @@ insert into t5 values (2, date_format('2001-01-01','%W'));
set lc_time_names=en_US;
insert into t5 values (3, date_format('2001-01-01','%W'));
select * from t5 order by c1;
+
+### Starting master-bin.000007
flush logs;
+
drop table t5;
--exec $MYSQL_BINLOG --short-form $MYSQLD_DATADIR/master-bin.000006 | $MYSQL
select * from t5 order by c1;
@@ -170,7 +192,10 @@ drop table t5;
--disable_warnings
drop procedure if exists p1;
--enable_warnings
+
+### Starting master-bin.000008
flush logs;
+
delimiter //;
create procedure p1()
begin
@@ -178,12 +203,15 @@ select 1;
end;
//
delimiter ;//
+
+### Starting master-bin.000009
flush logs;
+
call p1();
drop procedure p1;
--error ER_SP_DOES_NOT_EXIST
call p1();
---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
+--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form $MYSQLD_DATADIR/master-bin.000008
--exec $MYSQL_BINLOG --short-form $MYSQLD_DATADIR/master-bin.000008 | $MYSQL
call p1();
@@ -202,7 +230,9 @@ drop procedure p1;
# (LOAD DATA INFILE need it)
#
+### Starting master-bin.000010
flush logs;
+
create table t1 (a varchar(64) character set utf8);
load data infile '../../std_data/loaddata6.dat' into table t1;
set character_set_database=koi8r;
@@ -217,9 +247,12 @@ load data infile '../../std_data/loaddata6.dat' into table t1;
load data infile '../../std_data/loaddata6.dat' into table t1 character set koi8r;
select hex(a) from t1;
drop table t1;
+
+### Starting master-bin.000011
flush logs;
+
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
+--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLD_DATADIR/master-bin.000010
#
@@ -229,9 +262,14 @@ flush logs;
CREATE TABLE t1 (c1 CHAR(10));
# we need this for getting fixed timestamps inside of this test
+### Starting master-bin.000012
FLUSH LOGS;
+
INSERT INTO t1 VALUES ('0123456789');
+
+### Starting master-bin.000013
FLUSH LOGS;
+
DROP TABLE t1;
# We create a table, patch, and load the output into it
@@ -257,11 +295,16 @@ DROP TABLE patch;
#
# Bug#29928 incorrect connection_id() restoring from mysqlbinlog out
#
+### Starting master-bin.000014
FLUSH LOGS;
+
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES(connection_id());
let $a= `SELECT a FROM t1`;
+
+### Starting master-bin.000015
FLUSH LOGS;
+
let $outfile= $MYSQLTEST_VARDIR/tmp/bug29928.sql;
--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000014 > $outfile
DROP TABLE t1;
@@ -281,11 +324,12 @@ error 1;
exec $MYSQL_BINLOG $MYSQL_TEST_DIR/std_data/corrupt-relay-bin.000624 > $MYSQLTEST_VARDIR/tmp/bug31793.sql;
--remove_file $MYSQLTEST_VARDIR/tmp/bug31793.sql
-
#
# Test --disable-force-if-open and --force-if-open
#
+### Starting master-bin.000016
FLUSH LOGS;
+
--error 1
--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000016 >/dev/null 2>/dev/null
--exec $MYSQL_BINLOG --force-if-open $MYSQLD_DATADIR/master-bin.000016 >/dev/null 2>/dev/null
@@ -300,9 +344,15 @@ GRANT SELECT ON mysqltest1.* TO untrusted@localhost;
SHOW GRANTS FOR untrusted@localhost;
USE mysqltest1;
CREATE TABLE t1 (a INT, b CHAR(64));
+
+### Starting master-bin.000017
flush logs;
+
INSERT INTO t1 VALUES (1,USER());
+
+### Starting master-bin.000018
flush logs;
+
echo mysqlbinlog var/log/master-bin.000017 > var/tmp/bug31611.sql;
exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000017 > $MYSQLTEST_VARDIR/tmp/bug31611.sql;
connect (unsecure,localhost,untrusted,,mysqltest1);
@@ -326,14 +376,20 @@ DROP USER untrusted@localhost;
connection default;
USE test;
SET BINLOG_FORMAT = STATEMENT;
+
+### Starting master-bin.000019
FLUSH LOGS;
+
CREATE TABLE t1 (a_real FLOAT, an_int INT, a_decimal DECIMAL(5,2), a_string CHAR(32));
SET @a_real = rand(20) * 1000;
SET @an_int = 1000;
SET @a_decimal = CAST(rand(19) * 999 AS DECIMAL(5,2));
SET @a_string = 'Just a test';
INSERT INTO t1 VALUES (@a_real, @an_int, @a_decimal, @a_string);
+
+### Starting master-bin.000020
FLUSH LOGS;
+
query_vertical SELECT * FROM t1;
DROP TABLE t1;
@@ -357,6 +413,7 @@ eval SET @@global.server_id= $s_id_max;
RESET MASTER;
FLUSH LOGS;
+
--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $binlog_file
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval SELECT
diff --git a/mysql-test/t/mysqldump-max.test b/mysql-test/t/mysqldump-max.test
index 1e8b9647503..27c1a3ce20c 100644
--- a/mysql-test/t/mysqldump-max.test
+++ b/mysql-test/t/mysqldump-max.test
@@ -2,6 +2,7 @@
--source include/not_embedded.inc
--source include/have_innodb.inc
--source include/have_archive.inc
+--source include/have_log_bin.inc
--disable_warnings
drop table if exists t1, t2, t3, t4, t5, t6;
@@ -1124,3 +1125,84 @@ DROP VIEW v1;
DROP TABLE t1;
SET GLOBAL storage_engine=@old_engine;
+
+# Test fully non-locking mysqldump with consistent binlog position (MWL#136).
+
+connect(c1,127.0.0.1,root,,test,$MASTER_MYPORT,);
+connect(c2,127.0.0.1,root,,test,$MASTER_MYPORT,);
+connect(c3,127.0.0.1,root,,test,$MASTER_MYPORT,);
+
+connection default;
+--echo # Connection default
+SET binlog_format= mixed;
+RESET MASTER;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1,0), (2,0);
+SELECT GET_LOCK("block_queries_1", 120);
+
+connection c3;
+--echo # Connection c3
+SELECT GET_LOCK("block_queries_2", 120);
+
+# Start two queries that will be running on the tables during mysqldump
+connection c1;
+--echo # Connection c1
+SET @c= 0;
+send SELECT IF(@c<1, @c:=@c+1, GET_LOCK("block_queries_1", 120)) FROM t1 ORDER BY a;
+
+connection c2;
+--echo # Connection c2
+SET binlog_format="row";
+SET @d= 10;
+send UPDATE t2 SET b=IF(@d<=10, @d:=@d+1, GET_LOCK("block_queries_2", 120)) ORDER BY a;
+
+connection default;
+--echo # Connection default
+--echo # Make sure other queries are running (and waiting).
+let $wait_condition=
+ SELECT COUNT(*) FROM information_schema.processlist
+ WHERE state = "User lock" AND info LIKE 'SELECT%block_queries_1%';
+--source include/wait_condition.inc
+let $wait_condition=
+ SELECT COUNT(*) FROM information_schema.processlist
+ WHERE state = "User lock" AND info LIKE 'UPDATE%block_queries_2%';
+--source include/wait_condition.inc
+
+--exec $MYSQL_DUMP --master-data=2 --single-transaction test t1 t2 > $MYSQLTEST_VARDIR/tmp/mwl136.sql
+
+SELECT RELEASE_LOCK("block_queries_1");
+
+connection c3;
+--echo # Connection c3
+SELECT RELEASE_LOCK("block_queries_2");
+
+connection c1;
+--echo # Connection c1
+reap;
+
+connection c2;
+--echo # Connection c2
+reap;
+
+connection default;
+--echo # Connection default
+SELECT * FROM t2 ORDER BY a;
+DROP TABLE t1;
+DROP TABLE t2;
+--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/mwl136.sql
+
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/
+SHOW BINLOG EVENTS LIMIT 6,3;
+--perl
+my $f= "$ENV{MYSQLTEST_VARDIR}/tmp/mwl136.sql";
+open F, '<', $f or die "Failed to open $f: $!\n";
+while (<F>) {
+ print if /CHANGE MASTER TO/;
+}
+EOF
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/negation_elimination.test b/mysql-test/t/negation_elimination.test
index 0e0d8891e1f..312be8ccdb4 100644
--- a/mysql-test/t/negation_elimination.test
+++ b/mysql-test/t/negation_elimination.test
@@ -65,6 +65,35 @@ select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17));
explain select * from t1 where ((a between 5 and 15) and (not(a like 10)));
select * from t1 where ((a between 5 and 15) and (not(a like 10)));
+--echo # XOR (Note: XOR is negated by negating one of the operands)
+
+--echo # Should return 6,7
+SELECT * FROM t1 WHERE ((a > 5) XOR (a > 7));
+
+--echo # Should return 0..5,8..19
+SELECT * FROM t1 WHERE ((NOT (a > 5)) XOR (a > 7));
+SELECT * FROM t1 WHERE ((a > 5) XOR (NOT (a > 7)));
+SELECT * FROM t1 WHERE NOT ((a > 5) XOR (a > 7));
+
+--echo # Should return 6,7
+SELECT * FROM t1 WHERE NOT ((NOT (a > 5)) XOR (a > 7));
+SELECT * FROM t1 WHERE NOT ((a > 5) XOR (NOT (a > 7)));
+
+--echo # Should return 0..5,8..19
+SELECT * FROM t1 WHERE NOT ((NOT (a > 5)) XOR (NOT (a > 7)));
+
+--echo # Should have empty result
+SELECT * FROM t1 WHERE (NULL XOR (a > 7));
+SELECT * FROM t1 WHERE NOT (NULL XOR (a > 7));
+
+--echo # Should be simplified to "...WHERE (a XOR a)
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT ((NOT a) XOR (a));
+
+--echo # Should be simplified to "...WHERE (a XOR a)
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT (a XOR (NOT a));
+
+--echo # End XOR
+
delete from t1 where a > 3;
select a, not(not(a)) from t1;
explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "1"), not (a not in (1,2)), not(a != 2) from t1 where not(not(a)) having not(not(a));
diff --git a/mysql-test/t/null_key.test b/mysql-test/t/null_key.test
index 1400c643203..695b2835610 100644
--- a/mysql-test/t/null_key.test
+++ b/mysql-test/t/null_key.test
@@ -263,3 +263,16 @@ SELECT * FROM t2 inner join t1 WHERE ( t1.a = 0 OR t1.a IS NULL) AND t2.a = 3 AN
drop table t1, t2;
-- echo End of 5.0 tests
+--echo #
+--echo # BUG#727667 Wrong result with OR + NOT NULL in maria-5.3
+--echo #
+
+CREATE TABLE t1 (
+ f3 int(11),
+ f10 varchar(1),
+ KEY (f3)
+);
+INSERT INTO t1 VALUES ('9','k'),(NULL,'r');
+SELECT * FROM t1 WHERE (f3 = 83) OR (f10 = 'z' AND f3 IS NULL);
+DROP TABLE t1;
+
diff --git a/mysql-test/t/old-mode.test b/mysql-test/t/old-mode.test
index 6d0fe64bbb8..cf2167c8027 100644
--- a/mysql-test/t/old-mode.test
+++ b/mysql-test/t/old-mode.test
@@ -15,3 +15,13 @@ checksum table t1, t2;
checksum table t1, t2 quick;
checksum table t1, t2 extended;
drop table t1,t2;
+
+#
+# Test that SHOW PROCESSLIST doesn't have the Progress column
+#
+
+--replace_column 1 <Id> 3 <Host> 6 <Time>
+# Embedded server is hardcoded to show "Writing to net" as STATE.
+--replace_result "Writing to net" "NULL"
+--replace_regex /localhost[:0-9]*/localhost/
+SHOW PROCESSLIST;
diff --git a/mysql-test/t/optimizer_switch.test b/mysql-test/t/optimizer_switch.test
new file mode 100644
index 00000000000..9675e4815e5
--- /dev/null
+++ b/mysql-test/t/optimizer_switch.test
@@ -0,0 +1,118 @@
+--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;
+
+#
+# Bug #695304: invalid default setting for optimizer_switch
+#
+
+--replace_regex /,table_elimination=on//
+select @@optimizer_switch;
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index add256a7451..1d81248b81e 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -1,11 +1,17 @@
#
-# Bug with order by
+# Testing ORDER BY
#
--disable_warnings
drop table if exists t1,t2,t3;
--enable_warnings
+call mtr.add_suppression("Out of sort memory; increase server sort buffer size");
+
+#
+# Test old ORDER BY bug
+#
+
CREATE TABLE t1 (
id int(6) DEFAULT '0' NOT NULL,
idservice int(5),
@@ -151,6 +157,9 @@ INSERT INTO t2 VALUES (2,25);
INSERT INTO t3 VALUES (1,'123 Park Place');
INSERT INTO t3 VALUES (2,'453 Boardwalk');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
SELECT a,b,if(b = 1,i,if(b = 2,v,''))
FROM t1
LEFT JOIN t2 USING(c)
@@ -173,6 +182,8 @@ LEFT JOIN t2 ON t1.c = t2.c
LEFT JOIN t3 ON t3.c = t1.c
ORDER BY a;
+SET optimizer_switch=@save_optimizer_switch;
+
drop table t1,t2,t3;
#
@@ -402,7 +413,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;
@@ -430,6 +445,7 @@ drop table t1;
create table t1(a int, b int, index(b));
insert into t1 values (2, 1), (1, 1), (4, NULL), (3, NULL), (6, 2), (5, 2);
+insert into t1 values (12, 11), (11, 11), (14, 3), (13, 5), (16, 12), (15, 12);
explain select * from t1 where b=1 or b is null order by a;
select * from t1 where b=1 or b is null order by a;
explain select * from t1 where b=2 or b is null order by a;
@@ -843,12 +859,12 @@ DROP TABLE t1;
--echo #
create table t1(a int, b tinytext);
insert into t1 values (1,2),(3,2);
-set session sort_buffer_size= 30000;
+set session sort_buffer_size= 1000;
set session max_sort_length= 2180;
--error 1038
select * from t1 order by b;
drop table t1;
-call mtr.add_suppression("Out of sort memory; increase server sort buffer size");
+
--echo #
--echo # Bug #39844: Query Crash Mysql Server 5.0.67
--echo #
@@ -1363,6 +1379,14 @@ SELECT d FROM t3 AS t1, t2 AS t2
WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
ORDER BY t2.c LIMIT 1;
+SELECT t1.*,t2.* 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 5;
+
+SELECT t1.*, t2.* FROM t3 AS t1, t2 AS t2
+WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
+ORDER BY t2.c LIMIT 5;
+
DROP TABLE t1,t2,t3;
@@ -1492,6 +1516,24 @@ LIMIT 2;
DROP TABLE t1, t2;
+--echo #
+--echo # Bug #707848: WHERE condition with OR + ORDER BY + field substitution
+--echo #
+
+CREATE TABLE t1 (a int PRIMARY KEY);
+INSERT INTO t1 VALUES
+ (9), (7), (11), (15), (2), (4), (1), (5), (14), (54), (3), (8);
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 r JOIN t1 s ON r.a = s.a
+ WHERE s.a IN (2,9) OR s.a < 100 AND s.a != 0
+ ORDER BY 1 LIMIT 10;
+
+SELECT * FROM t1 r JOIN t1 s ON r.a = s.a
+ WHERE s.a IN (2,9) OR s.a < 100 AND s.a != 0
+ ORDER BY 1 LIMIT 10;
+
+DROP TABLE t1;
--echo #
--echo # Bug #59110: Memory leak of QUICK_SELECT_I allocated memory
@@ -1547,3 +1589,42 @@ SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b;
drop table t1,t2;
--echo End of 5.2 tests
+
+--echo #
+--echo # Bug mdev-449: ORDER BY with small sort_buffer_size
+--echo #
+
+CREATE TABLE t1(f0 int auto_increment primary key, f1 int, f2 varchar(200));
+INSERT INTO t1(f1, f2) VALUES
+(0,"0"),(1,"1"),(2,"2"),(3,"3"),(4,"4"),(5,"5"),
+(6,"6"),(7,"7"),(8,"8"),(9,"9"),(10,"10"),
+(11,"11"),(12,"12"),(13,"13"),(14,"14"),(15,"15"),
+(16,"16"),(17,"17"),(18,"18"),(19,"19"),(20,"20"),
+(21,"21"),(22,"22"),(23,"23"),(24,"24"),(25,"25"),
+(26,"26"),(27,"27"),(28,"28"),(29,"29"),(30,"30"),
+(31,"31"),(32,"32"),(33,"33"),(34,"34"),(35,"35"),
+(36,"36"),(37,"37"),(38,"38"),(39,"39"),(40,"40"),
+(41,"41"),(42,"42"),(43,"43"),(44,"44"),(45,"45"),
+(46,"46"),(47,"47"),(48,"48"),(49,"49"),(50,"50"),
+(51,"51"),(52,"52"),(53,"53"),(54,"54"),(55,"55"),
+(56,"56"),(57,"57"),(58,"58"),(59,"59"),(60,"60"),
+(61,"61"),(62,"62"),(63,"63"),(64,"64"),(65,"65"),
+(66,"66"),(67,"67"),(68,"68"),(69,"69"),(70,"70"),
+(71,"71"),(72,"72"),(73,"73"),(74,"74"),(75,"75"),
+(76,"76"),(77,"77"),(78,"78"),(79,"79"),(80,"80"),
+(81,"81"),(82,"82"),(83,"83"),(84,"84"),(85,"85"),
+(86,"86"),(87,"87"),(88,"88"),(89,"89"),(90,"90"),
+(91,"91"),(92,"92"),(93,"93"),(94,"94"),(95,"95"),
+(96,"96"),(97,"97"),(98,"98"),(99,"99");
+
+set @save_sort_buffer_size= @@sort_buffer_size;
+set sort_buffer_size= 2000;
+
+SELECT * FROM t1 ORDER BY f1 DESC, f0;
+
+set sort_buffer_size= @save_sort_buffer_size;
+
+DROP TABLE t1;
+
+--echo End of 5.3 tests
+
diff --git a/mysql-test/t/parser_precedence.test b/mysql-test/t/parser_precedence.test
index 484c8759779..7b69bc9c6da 100644
--- a/mysql-test/t/parser_precedence.test
+++ b/mysql-test/t/parser_precedence.test
@@ -3,6 +3,8 @@
drop table if exists t1_30237_bool;
--enable_warnings
+set sql_mode=NO_UNSIGNED_SUBTRACTION;
+
create table t1_30237_bool(A boolean, B boolean, C boolean);
insert into t1_30237_bool values
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index 66dea7340b5..f035528444f 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -2276,3 +2276,22 @@ ALTER TABLE t1 ADD KEY (b);
drop table t1;
--echo End of 5.1 tests
+
+
+--echo #
+--echo # BUG#598247: partition.test produces valgrind errors in 5.3-based branches
+--echo #
+CREATE TABLE t1 (
+ a INT DEFAULT NULL,
+ b DOUBLE DEFAULT NULL,
+ c INT DEFAULT NULL,
+ KEY idx2(b,a)
+) engine=myisam PARTITION BY HASH(c) PARTITIONS 3;
+
+INSERT INTO t1 VALUES (6,8,9);
+INSERT INTO t1 VALUES (6,8,10);
+
+SELECT 1 FROM t1 JOIN t1 AS t2 USING (a);
+
+drop table t1;
+
diff --git a/mysql-test/t/partition_pruning.test b/mysql-test/t/partition_pruning.test
index db544d4643f..f12593d746f 100644
--- a/mysql-test/t/partition_pruning.test
+++ b/mysql-test/t/partition_pruning.test
@@ -872,6 +872,7 @@ drop table t1;
create table t1 (a int not null, b int not null, key(a), key(b))
partition by hash(a) partitions 4;
insert into t1 values (1,1),(2,2),(3,3),(4,4);
+insert into t1 values (5,5),(6,6),(7,7),(8,8);
explain partitions
select * from t1 X, t1 Y
@@ -1085,12 +1086,14 @@ show status like 'Handler_read_key';
flush status;
delete from t2 where b > 5;
show status like 'Handler_read_rnd_next';
+show status like 'Handler_read_rnd_deleted';
show status like 'Handler_read_key';
show status like 'Handler_read_prev';
show status like 'Handler_read_next';
flush status;
delete from t2 where b < 5 or b > 3;
show status like 'Handler_read_rnd_next';
+show status like 'Handler_read_rnd_deleted';
show status like 'Handler_read_key';
show status like 'Handler_read_prev';
show status like 'Handler_read_next';
diff --git a/mysql-test/t/pool_of_threads.test b/mysql-test/t/pool_of_threads.test
index 530038cee91..5cde9a9fb4b 100644
--- a/mysql-test/t/pool_of_threads.test
+++ b/mysql-test/t/pool_of_threads.test
@@ -2,11 +2,13 @@
# and run a number of tests
-- source include/have_pool_of_threads.inc
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
# Slow test, don't run during staging part
-- source include/not_staging.inc
-- source include/long_test.inc
-- source include/common-tests.inc
-
+SET optimizer_switch=@save_optimizer_switch;
# Test that we cannot have more simultaneous connections than
# --thread-pool-size on the standard port, but _can_ have additional
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index f31d2aea89f..f1941337874 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -163,14 +163,25 @@ 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 @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+
set @stmt= ' explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25 ' ;
prepare stmt1 from @stmt ;
execute stmt1 ;
execute stmt1 ;
explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
deallocate prepare stmt1;
+
+set optimizer_switch=@tmp_optimizer_switch;
+
drop tables t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
+
#
# parameters from variables (for field creation)
#
@@ -265,11 +276,11 @@ deallocate prepare Stmt1;
# also check that statement names are in right charset.
set names utf8;
-prepare `ü` from 'select 1234';
-execute `ü` ;
+prepare `ü` from 'select 1234';
+execute `ü` ;
set names latin1;
-execute `ü`;
-deallocate prepare `ü`;
+execute `ü`;
+deallocate prepare `ü`;
set names default;
@@ -3084,10 +3095,13 @@ DROP TABLE t1;
--echo #
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1),(2);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
PREPARE stmt FROM 'EXPLAIN EXTENDED SELECT 1 FROM t1 RIGHT JOIN t1 t2 ON 1';
EXECUTE stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
+SET optimizer_switch=@save_optimizer_switch;
DROP TABLE t1;
--echo #
@@ -3256,3 +3270,42 @@ EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2;
+
+#
+# restoring of the Item tree in BETWEEN with dates
+#
+prepare stmt from "select date('2010-10-10') between '2010-09-09' and ?";
+set @a='2010-11-11';
+execute stmt using @a;
+execute stmt using @a;
+set @a='2010-08-08';
+execute stmt using @a;
+execute stmt using @a;
+
+--echo #
+--echo # Bug #892725: look-up is changed for a full scan when executing PS
+--echo #
+
+create table t1 (a int primary key, b int);
+insert into t1 values
+ (7,70), (3,40), (4,40), (8,70), (1,70), (9,50), (2,70);
+
+prepare st from 'select * from t1 where a=8';
+
+flush status;
+execute st;
+show status like '%Handler_read%';
+flush status;
+execute st;
+show status like '%Handler_read%';
+flush status;
+select * from t1 use index() where a=3;
+show status like '%Handler_read%';
+flush status;
+execute st;
+show status like '%Handler_read%';
+
+deallocate prepare st;
+drop table t1;
+
+--echo # End of 5.3 tests
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index 24487db826a..dc403a30732 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -776,7 +776,19 @@ show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
+
+set global query_cache_strip_comments=1;
+(select a from t1) union (select a from t1);
+(select a from t1) /* */union (select a from t1);
+set global query_cache_strip_comments=0;
+(select a from t1) union (select a from t1);
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+
drop table t1;
+
+#
# SP cursors and selects with query cache (BUG#9715)
#
create table t1 (a int);
@@ -1255,6 +1267,7 @@ set GLOBAL query_cache_type=default;
set GLOBAL query_cache_limit=default;
set GLOBAL query_cache_min_res_unit=default;
set GLOBAL query_cache_size=default;
+set local query_cache_type=default;
#
# Bug#33756 - query cache with concurrent_insert=0 appears broken
@@ -1515,3 +1528,23 @@ SET GLOBAL query_cache_size= default;
--echo End of 5.1 tests
+--echo New query cache switching OFF mechanism test
+set global query_cache_size=1024*1024*20;
+set global query_cache_type=on;
+select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type;
+set global query_cache_size=0;
+select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type;
+set global query_cache_size=1024*1024*20;
+select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type;
+set global query_cache_type=off;
+select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type;
+set global query_cache_type=on;
+select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type;
+set local query_cache_type= on;
+select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type;
+
+
+--echo restore defaults
+SET GLOBAL query_cache_type= default;
+SET GLOBAL query_cache_size= default;
+SET LOCAL query_cache_type= default;
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/range.test b/mysql-test/t/range.test
index c3f6aad4638..6ac883ffcc1 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -3,7 +3,7 @@
#
--disable_warnings
-drop table if exists t1, t2, t3;
+drop table if exists t1, t2, t3, t10, t100;
--enable_warnings
CREATE TABLE t1 (
@@ -554,6 +554,18 @@ INSERT INTO t1 VALUES
'd8c4177d09f8b11f5.52725521'),
('d8c4177d24ccef970.14957924','d8c4177d09f8b11f5.52725521',10,11,
'd8c4177d09f8b11f5.52725521');
+INSERT INTO t1 VALUES
+('d8c4177d09f8b11f5.52725522','oxrootid',1,40,'d8c4177d09f8b11f5.52725522'),
+('d8c4177d151affab2.81582771','d8c4177d09f8b11f5.52725521',2,3,
+ 'd8c4177d09f8b11f5.52725522'),
+('d8c4177d206a333d2.74422678','d8c4177d09f8b11f5.52725521',4,5,
+ 'd8c4177d09f8b11f5.52725522'),
+('d8c4177d225791924.30714721','d8c4177d09f8b11f5.52725521',6,7,
+ 'd8c4177d09f8b11f5.52725522'),
+('d8c4177d2380fc201.39666694','d8c4177d09f8b11f5.52725521',8,9,
+ 'd8c4177d09f8b11f5.52725522'),
+('d8c4177d24ccef970.14957925','d8c4177d09f8b11f5.52725521',10,11,
+ 'd8c4177d09f8b11f5.52725522');
EXPLAIN
SELECT s.oxid FROM t1 v, t1 s
@@ -1483,3 +1495,57 @@ select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1;
select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1;
drop table t1;
+
+#
+# lp:750117 Bogus warning with aggregate and datetime column
+#
+create table t1 (f1 datetime, key (f1));
+insert into t1 values ('2000-03-09 15:56:59'),('2000-05-05 23:24:28'),('2000-06-13 13:12:06');
+select min(f1) from t1 where f1 >= '2006-05-25 07:00:20' and f1 between '2003-11-23 10:00:09' and '2010-01-01 01:01:01' and f1 > '2001-01-01 01:01:01';
+drop table t1;
+
+--echo #
+--echo # BUG#11765831: 'RANGE ACCESS' MAY INCORRECTLY FILTER
+--echo # AWAY QUALIFYING ROWS
+--echo #
+
+CREATE TABLE t10(
+ K INT NOT NULL AUTO_INCREMENT,
+ I INT, J INT,
+ PRIMARY KEY(K),
+ KEY(I,J)
+);
+INSERT INTO t10(I,J) VALUES (6,1),(6,2),(6,3),(6,4),(6,5),
+ (6,6),(6,7),(6,8),(6,9),(6,0);
+
+CREATE TABLE t100 LIKE t10;
+INSERT INTO t100(I,J) SELECT X.I, X.K+(10*Y.K) FROM t10 AS X,t10 AS Y;
+
+# Insert offending value:
+INSERT INTO t100(I,J) VALUES(8,26);
+
+let $query= SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5);
+
+#Verify that 'range' access will be used
+--echo
+--eval EXPLAIN $query
+
+# Only row 101,8,26 should be returned
+--echo
+--eval $query
+
+DROP TABLE t10,t100;
+
+--echo #
+--echo # lp:817363: Wrong result with sort_union and multipart key in maria-5.3
+--echo #
+CREATE TABLE t1 (a int NOT NULL , b int, c int, d varchar(32), KEY (d,b), PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (7,7,NULL,'e'),(8,1,0,'p'),(9,7,1,'s'),(10,1,1,'j'),(12,2,0,'c'),(13,0,0,'a'),(14,1,1,'q');
+
+SELECT c FROM t1 WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
+SELECT c FROM t1 ignore index (d) WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
+
+SELECT * FROM t1 ignore index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
+SELECT * FROM t1 force index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
+
+DROP TABLE t1;
diff --git a/mysql-test/t/range_mrr_icp.test b/mysql-test/t/range_mrr_icp.test
new file mode 100644
index 00000000000..724da8aea3b
--- /dev/null
+++ b/mysql-test/t/range_mrr_icp.test
@@ -0,0 +1,7 @@
+set @mrr_icp_extra_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+--source t/range.test
+
+set optimizer_switch=@mrr_icp_extra_tmp;
+
diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test
new file mode 100755
index 00000000000..fb8fd778559
--- /dev/null
+++ b/mysql-test/t/range_vs_index_merge.test
@@ -0,0 +1,1208 @@
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2,t3,t4;
+DROP DATABASE IF EXISTS world;
+--enable_warnings
+
+set names utf8;
+
+CREATE DATABASE world;
+
+use world;
+
+--source include/world_schema.inc
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+--source include/world.inc
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+SELECT COUNT(*) FROM Country;
+SELECT COUNT(*) FROM City;
+SELECT COUNT(*) FROM CountryLanguage;
+
+CREATE INDEX Name ON City(Name);
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+ANALYZE TABLE City;
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+set session optimizer_switch='index_merge_sort_intersection=off';
+
+# The following 4 queries are added for code coverage
+
+#the exptected # of rows differ on 32-bit and 64-bit platforms for innodb
+--replace_column 9 4079
+EXPLAIN
+SELECT * FROM City
+ WHERE (Population >= 100000 OR Name LIKE 'P%' OR Population < 100000);
+
+EXPLAIN
+SELECT * FROM City
+ WHERE (Population >= 100000 OR Name LIKE 'P%') AND Country='CAN' OR
+ (Population < 100000 OR Name Like 'T%') AND Country='ARG';
+
+EXPLAIN
+SELECT * FROM City
+ WHERE Population < 200000 AND Name LIKE 'P%' AND
+ (Population > 300000 OR Name LIKE 'T%') AND
+ (Population < 100000 OR Name LIKE 'Pa%');
+
+EXPLAIN
+SELECT * FROM City
+ WHERE Population > 100000 AND Name LIKE 'Aba%' OR
+ Country IN ('CAN', 'ARG') AND ID < 3800 OR
+ Country < 'U' AND Name LIKE 'Zhu%' OR
+ ID BETWEEN 3800 AND 3810;
+
+# The output of the next 3 commands tells us about selectivities
+# of the conditions utilized in 2 queries following after them
+
+EXPLAIN
+SELECT * FROM City
+ WHERE (Population > 101000 AND Population < 115000);
+
+EXPLAIN
+SELECT * FROM City
+ WHERE (Population > 101000 AND Population < 102000);
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'));
+
+# The pattern of the WHERE condition used in the following 2 queries is
+# (range(key1) OR range(key2)) AND range(key3)
+# Varying values of the constants in the second conjunct of the condition
+# we can get either a plan with range index scan for key3 or a plan with
+# an index merge retrieval over key2 and key3
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+ AND (Population > 101000 AND Population < 115000);
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+ AND (Population > 101000 AND Population < 102000);
+
+# The following 4 queries check that the plans
+# for the previous 2 plans are valid
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+ AND (Population > 101000 AND Population < 115000);
+
+SELECT * FROM City
+ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+ AND (Population > 101000 AND Population < 115000);
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+ AND (Population > 101000 AND Population < 102000);
+
+SELECT * FROM City
+ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+ AND (Population > 101000 AND Population < 102000);
+
+# The output of the next 7 commands tells us about selectivities
+# of the conditions utilized in 4 queries following after them
+
+EXPLAIN
+SELECT * FROM City WHERE (Name < 'Ac');
+EXPLAIN
+SELECT * FROM City WHERE (Name < 'Bb');
+EXPLAIN
+SELECT * FROM City WHERE (Country > 'A' AND Country < 'B');
+EXPLAIN
+SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'Pb');
+EXPLAIN
+SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'S');
+EXPLAIN
+SELECT * FROM City WHERE (Population > 101000 AND Population < 110000);
+EXPLAIN
+SELECT * FROM City WHERE (Population > 103000 AND Population < 104000);
+
+# The pattern of the WHERE condition used in the following 4 queries is
+# (range1(key1) AND range(key2)) OR (range2(key1) AND range(key3)
+# Varying values of the constants in the range conjuncts of the condition
+# we can get:
+# 1. a plan with range index over key1
+# index merge retrievals over:
+# 2. key1 and key3
+# 3. key2 and key1
+# 4. key2 and key3
+
+EXPLAIN
+SELECT * FROM City
+ WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+ (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+
+EXPLAIN
+SELECT * FROM City
+ WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+ (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+
+EXPLAIN
+SELECT * FROM City
+ WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+ (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+
+EXPLAIN
+SELECT * FROM City
+ WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+ (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+
+# The following 8 queries check that the plans
+# for the previous 4 plans are valid
+
+SELECT * FROM City USE INDEX ()
+ WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+ (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+
+SELECT * FROM City
+ WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+ (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+
+SELECT * FROM City USE INDEX ()
+ WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+ (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+
+SELECT * FROM City
+ WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+ (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+
+SELECT * FROM City USE INDEX ()
+ WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+ (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+
+SELECT * FROM City
+ WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+ (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+
+SELECT * FROM City USE INDEX ()
+ WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+ (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+
+SELECT * FROM City
+ WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR
+ (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
+
+
+# The output of the next 6 commands tells us about selectivities
+# of the conditions utilized in 3 queries following after them
+
+EXPLAIN
+SELECT * FROM City WHERE (ID < 10) OR (ID BETWEEN 100 AND 110);
+EXPLAIN
+SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 100 AND 200);
+EXPLAIN
+SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1500);
+EXPLAIN
+SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG';
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'H%' OR Name LIKE 'P%' ;
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'Ha%' OR Name LIKE 'Pa%' ;
+
+# The pattern of the WHERE condition used in the following 3 queries is
+# (range1(key1) AND (range1(key2) OR range(key3)) OR
+# (range2(key1) AND (range2(key2) OR range(key4))
+# Varying values of the constants in the range predicates of the condition
+# we can get:
+# 1. a plan with range index over key1
+# 2. an index merge retrieval over key1, key2 and key3
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
+ OR ((ID BETWEEN 100 AND 110) AND
+ (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+ OR ((ID BETWEEN 900 AND 1500) AND
+ (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+ OR ((ID BETWEEN 100 AND 200) AND
+ (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+
+
+# The following 6 queries check that the plans
+# for the previous 3 plans are valid
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
+ OR ((ID BETWEEN 100 AND 110) AND
+ (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
+
+SELECT * FROM City
+ WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
+ OR ((ID BETWEEN 100 AND 110) AND
+ (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
+
+SELECT * FROM City USE INDEX()
+ WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+ OR ((ID BETWEEN 900 AND 1500) AND
+ (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+
+SELECT * FROM City
+ WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+ OR ((ID BETWEEN 900 AND 1500) AND
+ (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+ OR ((ID BETWEEN 100 AND 200) AND
+ (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+
+SELECT * FROM City
+ WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
+ OR ((ID BETWEEN 100 AND 200) AND
+ (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
+
+
+# The output of the next 8 commands tells us about selectivities
+# of the conditions utilized in 2 queries following after them
+
+EXPLAIN
+SELECT * FROM City WHERE Population > 101000 AND Population < 102000;
+EXPLAIN
+SELECT * FROM City WHERE Population > 101000 AND Population < 110000;
+EXPLAIN
+SELECT * FROM City WHERE Country < 'C';
+EXPLAIN
+SELECT * FROM City WHERE Country < 'AGO';
+EXPLAIN
+SELECT * FROM City WHERE Name BETWEEN 'P' AND 'S';
+EXPLAIN
+SELECT * FROM City WHERE Name BETWEEN 'P' AND 'Pb';
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 3400 AND 3800;
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800;
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'P%';
+
+# The pattern of the WHERE condition used in the following 2 queries is
+# (range(key1) AND (range1(key2) OR range1(key3)) OR
+# (range(key4) AND (range2(key2) OR range2(key3))
+# Varying values of the constants in the range predicates of the condition
+# we can get:
+# index merge retrievals over:
+# 1. key1, key2 and key3
+# 2. key4, key2 and key3
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 102000) AND
+ (Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR
+ ((ID BETWEEN 3400 AND 3800) AND
+ (Country < 'AGO' OR Name LIKE 'Pa%'));
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 110000) AND
+ (Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR
+ ((ID BETWEEN 3790 AND 3800) AND
+ (Country < 'C' OR Name LIKE 'P%'));
+
+# The following 4 queries check that the plans
+# for the previous 2 plans are valid
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((Population > 101000 AND Population < 102000) AND
+ (Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR
+ ((ID BETWEEN 3400 AND 3800) AND
+ (Country < 'AGO' OR Name LIKE 'Pa%'));
+
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 102000) AND
+ (Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR
+ ((ID BETWEEN 3400 AND 3800) AND
+ (Country < 'AGO' OR Name LIKE 'Pa%'));
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((Population > 101000 AND Population < 110000) AND
+ (Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR
+ ((ID BETWEEN 3790 AND 3800) AND
+ (Country < 'C' OR Name LIKE 'P%'));
+
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 110000) AND
+ (Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR
+ ((ID BETWEEN 3790 AND 3800) AND
+ (Country < 'C' OR Name LIKE 'P%'));
+
+
+CREATE INDEX CountryPopulation ON City(Country,Population);
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+ANALYZE TABLE City;
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+# The output of the next 5 commands tells us about selectivities
+# of the conditions utilized in 2 queries following after them
+
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'Pas%';
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'P%';
+EXPLAIN
+SELECT * FROM City WHERE (Population > 101000 AND Population < 103000);
+EXPLAIN
+SELECT * FROM City WHERE Country='USA';
+EXPLAIN
+SELECT * FROM City WHERE Country='FIN';
+
+# The pattern of the WHERE condition used in the following 3 queries is
+# (range(key1_p2) OR (range(key2)) AND key1_p1=c
+# Varying values of the constants in the range predicates of the condition
+# we can get:
+# 1. a plan with range index over key1_p1
+# 2. an index merge retrieval over: key1 and key2
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
+ AND Country='USA';
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
+ AND Country='FIN';
+
+# The following 4 queries check that the plans
+# for the previous 2 plans are valid
+
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
+ AND Country='USA';
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
+ AND Country='USA';
+
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
+ AND Country='FIN';
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
+ AND Country='FIN';
+
+
+CREATE INDEX CountryName ON City(Country,Name);
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+ANALYZE TABLE City;
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+# The output of the next 12 commands tells us about selectivities
+# of the conditions utilized in 3 queries following after them
+
+EXPLAIN
+SELECT * FROM City WHERE Country='USA';
+EXPLAIN
+SELECT * FROM City WHERE Country='FIN';
+EXPLAIN
+SELECT * FROM City WHERE Country='BRA';
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800;
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 4025 AND 4035;
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 4028 AND 4032;
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 3500 AND 3800;
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 4000 AND 4300;
+EXPLAIN
+SELECT * FROM City WHERE ID BETWEEN 250 and 260 ;
+EXPLAIN
+SELECT * FROM City WHERE (Population > 101000 AND Population < 102000);
+EXPLAIN
+SELECT * FROM City WHERE (Population > 101000 AND Population < 103000);
+EXPLAIN
+SELECT * FROM City WHERE Name LIKE 'Pa%';
+
+# The pattern of the WHERE condition used in the following 3 queries is
+# (range(key1_p2) OR range1(key3)) AND
+# range(key1|2_p1=c) AND
+# (range(key2_p2) OR range2(key3))
+# Varying values of the constants in the range conjuncts of the condition
+# we can get:
+# 1. a plan with range index over key1|2_p1
+# index merge retrievals over:
+# 2. key1 and key3
+# 3. key2 and key3
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 102000) OR
+ ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 103000) OR
+ ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032);
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 110000) OR
+ ID BETWEEN 3500 AND 3800) AND Country='FIN'
+ AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300);
+
+# The following 6 queries check that the plans
+# for the previous 3 plans are valid
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((Population > 101000 AND Population < 102000) OR
+ ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 102000) OR
+ ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((Population > 101000 AND Population < 102000) OR
+ ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032);
+
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 102000) OR
+ ID BETWEEN 3790 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032);
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((Population > 101000 AND Population < 102000) OR
+ ID BETWEEN 3790 AND 3800) AND Country='FIN'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 102000) OR
+ ID BETWEEN 3790 AND 3800) AND Country='FIN'
+ AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
+
+
+# The pattern of the WHERE condition used in the following query is
+# (range(key1_p2) OR range1(key3)) AND range(key1|2_p1=c1) AND
+# (range(key2_p2) OR range1(key3)) AND range(key1|2_p1=c2)
+# We get an index merge retrieval over key1, key2 and key3 for it
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Population > 101000 and Population < 102000) OR
+ ID BETWEEN 3790 AND 3800) AND Country='USA'
+ OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA';
+
+# The following 2 queries check that the plans
+# for the previous plan is valid
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((Population > 101000 and Population < 102000) OR
+ ID BETWEEN 3790 AND 3800) AND Country='USA'
+ OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA';
+
+SELECT * FROM City
+ WHERE ((Population > 101000 and Population < 102000) OR
+ ID BETWEEN 3790 AND 3800) AND Country='USA'
+ OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA';
+
+# The pattern of the WHERE condition used in the following query is
+# (impossible_range(key1_p2) OR range1(key3)) AND
+# range(key1|2_p1=c1) AND
+# (range(key2_p2) OR range2(key3))
+# where range1(key3) and range2(key3) are disjoint
+# Varying values of the constant in range predicates we get plans:
+# 1. with an index scan over key2
+# 2. with an index scan over key4=key2_p2
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 11000) OR
+ ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300);
+
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 11000) OR
+ ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300);
+
+# The following 4 queries check that the plans
+# for the previous 2 plans are valid
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((Population > 101000 AND Population < 11000) OR
+ ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300);
+
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 11000) OR
+ ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300);
+
+SELECT * FROM City USE INDEX ()
+ WHERE ((Population > 101000 AND Population < 11000) OR
+ ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300);
+
+SELECT * FROM City
+ WHERE ((Population > 101000 AND Population < 11000) OR
+ ID BETWEEN 3500 AND 3800) AND Country='USA'
+ AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300);
+
+
+DROP INDEX Population ON City;
+DROP INDEX Name ON City;
+
+# The pattern of the WHERE condition used in the following query is
+# (key1|2_p1=c AND range(key1_p2)) OR (key1|2_p1=c AND range(key2_p2))
+# We get an index merge retrieval over key1, key2 for it
+
+EXPLAIN
+SELECT * FROM City
+ WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR
+ Country='USA' AND Name LIKE 'Pa%';
+
+# The following 2 queries check that the plans
+# for the previous plan is valid
+
+SELECT * FROM City USE INDEX()
+ WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR
+ Country='USA' AND Name LIKE 'Pa%';
+
+SELECT * FROM City
+ WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR
+ Country='USA' AND Name LIKE 'Pa%';
+
+
+# The pattern of the WHERE condition used in the following query is
+# key1|2_p1=c AND (range(key1_p2) OR range(key2_p2))
+# We get an index merge retrieval over key1, key2 for it
+
+EXPLAIN
+SELECT * FROM City
+ WHERE Country='USA' AND
+ (Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%');
+
+# The following 2 queries check that the plans
+# for the previous plan is valid
+
+SELECT * FROM City
+ WHERE Country='USA' AND
+ (Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%');
+
+SELECT * FROM City
+ WHERE Country='USA' AND
+ (Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%');
+
+
+#
+# LP bug #954262: index merge oover long disjunction in WHERE
+#
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+CREATE INDEX CityName on City(Name);
+
+let $cond =
+(Name='Manila' AND Country='PHL') OR
+(Name='Addis Abeba' AND Country='ETH') OR
+(Name='Jakarta' AND Country='IDN') OR
+(Name='Bangalore' AND Country='IND') OR
+(Name='Teheran' AND Country='IRN') OR
+(Name='Roma' AND Country='ITA') OR
+(Name='Delhi' AND Country='IND') OR
+(Name='Venezia' AND Country='ITA') OR
+(Name='Tokyo' AND Country='JPN') OR
+(Name='Toronto' AND Country='CAN') OR
+(Name='Peking' AND Country='CHN') OR
+(Name='Lagos' AND Country='NGA') OR
+(Name='Tijuana' AND Country='MEX') OR
+(Name='Rabat' AND Country='MAR') OR
+(Name='Seoul' AND Country='KOR') OR
+(Name='Vancouver' AND Country='CAN') OR
+(Name='Kaunas' AND Country='LTU') OR
+(Name='Paris' AND Country='FRA') OR
+(Name='Dakar' AND Country='SEN') OR
+(Name='Basel' AND Country='CHE') OR
+(Name='Praha' AND Country='CZE') OR
+(Name='Ankara' AND Country='TUR') OR
+(Name='Dresden' AND Country='DEU') OR
+(Name='Lugansk' AND Country='UKR') OR
+(Name='Caracas' AND Country='VEN') OR
+(Name='Samara' AND Country='RUS') OR
+(Name='Seattle' AND Country='USA');
+
+eval
+EXPLAIN SELECT Name, Country, Population FROM City WHERE
+$cond;
+eval
+SELECT Name, Country, Population FROM City WHERE
+$cond;
+
+set optimizer_switch='index_merge=off';
+
+eval
+EXPLAIN SELECT Name, Country, Population FROM City WHERE
+$cond;
+eval
+SELECT Name, Country, Population FROM City WHERE
+$cond;
+
+set optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # Bug mdev-585: range vs index-merge with ORDER BY ... LIMIT n
+--echo # (LP bug #637962)
+--echo #
+
+DROP INDEX CountryPopulation ON City;
+DROP INDEX CountryName ON City;
+DROP INDEX CityName on City;
+
+CREATE INDEX Name ON City(Name);
+CREATE INDEX Population ON City(Population);
+
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+ AND (Population >= 100000 AND Population < 120000);
+FLUSH STATUS;
+SELECT * FROM City
+ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+ AND (Population >= 100000 AND Population < 120000);
+SHOW STATUS LIKE 'Handler_read_%';
+
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+ AND (Population >= 100000 AND Population < 120000)
+ORDER BY Population LIMIT 5;
+
+FLUSH STATUS;
+SELECT * FROM City
+ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+ AND (Population >= 100000 AND Population < 120000)
+ORDER BY Population LIMIT 5;
+SHOW STATUS LIKE 'Handler_read_%';
+
+
+set optimizer_switch='index_merge=off';
+
+--replace_column 9 #
+EXPLAIN
+SELECT * FROM City
+ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+ AND (Population >= 100000 AND Population < 120000)
+ORDER BY Population LIMIT 5;
+
+FLUSH STATUS;
+SELECT * FROM City
+ WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'H'))
+ AND (Population >= 100000 AND Population < 120000)
+ORDER BY Population LIMIT 5;
+SHOW STATUS LIKE 'Handler_read_%';
+
+set optimizer_switch=@save_optimizer_switch;
+
+
+DROP DATABASE world;
+
+use test;
+
+#
+# Bug #17259: a bad range scan and a good index merge plan
+#
+
+CREATE TABLE t1 (
+ id int(10) unsigned NOT NULL auto_increment,
+ account_id int(10) unsigned NOT NULL,
+ first_name varchar(50) default NULL,
+ middle_name varchar(50) default NULL,
+ last_name varchar(100) default NULL,
+ home_address_1 varchar(150) default NULL,
+ home_city varchar(75) default NULL,
+ home_state char(2) default NULL,
+ home_postal_code varchar(50) default NULL,
+ home_county varchar(75) default NULL,
+ home_country char(3) default NULL,
+ work_address_1 varchar(150) default NULL,
+ work_city varchar(75) default NULL,
+ work_state char(2) default NULL,
+ work_postal_code varchar(50) default NULL,
+ work_county varchar(75) default NULL,
+ work_country char(3) default NULL,
+ login varchar(50) NOT NULL,
+ PRIMARY KEY (id),
+ KEY login (login,account_id),
+ KEY account_id (account_id),
+ KEY user_home_country_indx (home_country),
+ KEY user_work_country_indx (work_country),
+ KEY user_home_state_indx (home_state),
+ KEY user_work_state_indx (work_state),
+ KEY user_home_city_indx (home_city),
+ KEY user_work_city_indx (work_city),
+ KEY user_first_name_indx (first_name),
+ KEY user_last_name_indx (last_name)
+);
+
+insert into t1(account_id, login, home_state, work_state) values
+ (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'),
+ (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia');
+insert into t1(account_id, login, home_state, work_state)
+ select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+ select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+ select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+ select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+ select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+ select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+ select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+ select 1, 'pw', 'ak', 'ak' from t1;
+insert into t1(account_id, login, home_state, work_state)
+ select 1, 'pw', 'ak', 'ak' from t1;
+
+analyze table t1;
+
+select count(*) from t1 where account_id = 1;
+
+select * from t1
+ where (home_state = 'ia' or work_state='ia') and account_id = 1;
+
+explain
+select * from t1
+ where (home_state = 'ia' or work_state='ia') and account_id = 1;
+
+drop table t1;
+
+#
+# Bug #17673: no index merge plan if the condition for the last used
+# index component is factored out of the or formula
+#
+
+CREATE TABLE t1 (
+ c1 int(11) NOT NULL auto_increment,
+ c2 decimal(10,0) default NULL,
+ c3 decimal(10,0) default NULL,
+ c4 decimal(10,0) default NULL,
+ c5 decimal(10,0) default NULL,
+ cp decimal(1,0) default NULL,
+ ce decimal(10,0) default NULL,
+ cdata char(20),
+ PRIMARY KEY (c1),
+ KEY k1 (c2,c3,cp,ce),
+ KEY k2 (c4,c5,cp,ce)
+);
+
+insert into t1 (c2, c3, c4, c5, cp) values(1,1,1,1,1);
+insert into t1 (c2, c3, c4, c5, cp) values(2,1,1,1,4);
+insert into t1 (c2, c3, c4, c5, cp) values(2,1,2,1,1);
+insert into t1 (c2, c3, c4, c5, cp) values(2,1,3,1,4);
+insert into t1 (c2, c3, c4, c5, cp) values(3,1,4,1,4);
+
+insert into t1 (c2, c3, c4, c5, cp)
+ select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+ select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+ select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+ select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+ select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+ select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+ select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+ select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+ select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+ select c2, c3, c4, c5, cp from t1 where cp = 4;
+insert into t1 (c2, c3, c4, c5, cp)
+ select c2, c3, c4, c5, cp from t1 where cp = 4;
+
+analyze table t1;
+
+explain
+ select * from t1 where (c2=1 and c3=1) or (c4=2 and c5=1);
+
+explain
+ select * from t1
+ where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1);
+
+explain
+ select * from t1
+ where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1;
+
+select * from t1
+ where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1);
+
+select * from t1
+ where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1;
+
+drop table t1;
+
+#
+# Bug #23322: a bad range scan and a good index merge plan
+#
+
+create table t1 (
+ c1 int auto_increment primary key,
+ c2 char(20),
+ c3 char (20),
+ c4 int
+);
+alter table t1 add key k1 (c2);
+alter table t1 add key k2 (c3);
+alter table t1 add key k3 (c4);
+
+insert into t1 values(null, 'a', 'b', 0);
+insert into t1 values(null, 'c', 'b', 0);
+insert into t1 values(null, 'a', 'd', 0);
+insert into t1 values(null, 'ccc', 'qqq', 0);
+
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a';
+
+insert into t1 (c2,c3,c4) select c2,c3,1 from t1 where c2 != 'a';
+insert into t1 (c2,c3,c4) select c2,c3,2 from t1 where c2 != 'a';
+insert into t1 (c2,c3,c4) select c2,c3,3 from t1 where c2 != 'a';
+insert into t1 (c2,c3,c4) select c2,c3,4 from t1 where c2 != 'a';
+
+analyze table t1;
+
+select count(*) from t1 where (c2='e' OR c3='q');
+select count(*) from t1 where c4 != 0;
+
+explain
+ select distinct c1 from t1 where (c2='e' OR c3='q');
+
+explain
+ select distinct c1 from t1 where (c4!= 0) AND (c2='e' OR c3='q');
+
+drop table t1;
+
+#
+# Bug #30151: a bad range scan and a good index merge plan
+#
+
+create table t1 (
+ id int unsigned auto_increment primary key,
+ c1 char(12),
+ c2 char(15),
+ c3 char(1)
+);
+
+insert into t1 (c3) values ('1'), ('2');
+
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+insert into t1 (c3) select c3 from t1;
+
+update t1 set c1=lpad(id+1000, 12, ' '), c2=lpad(id+10000, 15, ' ');
+
+alter table t1 add unique index (c1), add unique index (c2), add index (c3);
+
+analyze table t1;
+
+explain
+ select * from t1 where (c1=' 100000' or c2=' 2000000');
+explain
+ select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2';
+
+select * from t1 where (c1=' 100000' or c2=' 2000000');
+select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2';
+
+drop table t1;
+
+#
+# Bug #637978: invalid index merge access plan causes to wrong results
+#
+
+CREATE TABLE t1 (
+ a smallint DEFAULT NULL,
+ pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ b varchar(10) DEFAULT NULL,
+ c varchar(64) DEFAULT NULL,
+ INDEX idx1 (a),
+ INDEX idx2 (b),
+ INDEX idx3 (c)
+);
+--disable_query_log
+--disable_result_log
+INSERT INTO t1 VALUES
+(30371,99001,'dl','e'),(3,99002,'Ohio','t'),(9,99003,'Delaware','xb'),
+(0,99004,'Pennsylvan','i'),(-199,99005,'y','d'),(0,99006,'with','Rhode Island'),
+(3,99007,'km','qkmiimdxbdljsejtsfrvwlrgacinbmfuosflnenlpomkmvbig'),
+(22860,99008,'ovqkmiimdx','uovqkmiimdxbdljsejtsfrvwlrgacinbmfuosflnenlpomkmvbig'),
+(212,99009,'f','p'),(NULL,99010,'i','k'),(20426,99011,'Vermont','New York'),
+(0,99012,'Oregon','w'),(31831,99013,'s','isrcijpuovqkmiimdxbdljsejtsfrvwl'),
+(123,99014,'t','p'),(32767,99015,'q','Maine'),
+(NULL,99016,'know','qqqpisrcijpuovqkmiimdxbdljsejtsfrvwlrgacinbmfuosflnenlpo'),
+(1,99017,'going','North Carolina'),(-717,99018,'ad','Indiana'),
+(32767,99019,'Maryland','aa'),(31280,99020,'Nebraska','Colorado'),
+(0,99021,'q','Ohio'),
+(5989,99022,'rovaadtqqq','lrovaadtqqqpisrcijpuovqkmiimdxbdljsejtsfrvwlrgacinb'),
+(89,99023,'n','Pennsylvania'),(0,99024,'Florida','c'),(97,99025,'Maine','y'),
+(149,99026,'xaemnl','Idaho'),(NULL,99027,'h','y'),(26276,99028,'going','New York'),
+(242,99029,'bdhxaemnlr','sbdhxaemnlrovaadtqqqpisrcijpuovqkmiimdxb'),
+(32767,99030,'if','a'),(26581,99031,'Arizona','q'),(45,99032,'ysazsbdhxa','f'),
+(0,99033,'qv','s'),(NULL,99034,'Louisiana','lqvfysazsbdhxaemnlrovaadtqqqpisrc'),
+(160,99035,'Connecticu','x'),(23241,99036,'lx','q'),(0,99037,'u','Colorado'),
+(-19141,99038,'w','h'),(218,99039,'s','uo'),(4,99040,'Montana','Oklahoma'),
+(97,99041,'r','ls'),(32767,99042,'q','v'),(7,99043,'mlsuownlnl','did'),
+(NULL,99044,'ui','i'),(2,99045,'to','I\'ll'),(0,99046,'Nevada','g'),
+(3251,99047,'y','New York'),(0,99048,'wyttuimlsu','you\'re'),
+(7,99049,'he','South Carolina'),(32767,99050,'s','right'),
+(172,99051,'Arizona','e'),(0,99052,'x','lxmvwyttuimlsuownlnlxklq'),
+(NULL,99053,'f','wfjlxmvwyttuimlsuownlnlxklqvfysazs'),(44,99054,'s','n'),
+(-17561,99055,'me','wm'),(88,99056,'y','my'),(7313,99057,'jx','New Hampshire'),
+(63,99058,'zl','South Carolina'),(9,99059,'ma','Illinois'),
+(6,99060,'lamazljxpg','like'),(17021,99061,'x','v'),(0,99062,'New Mexico','j'),
+(179,99427,'fliq','because'),
+(107,99063,'Virginia','Mississippi'),
+(0,99064,'si','to'),(113,99065,'Illinois','Kansas'),(20808,99066,'tsi','d'),
+(-15372,99067,'d','vdftsidjtvulamazljxpgiwmbnmwfjlxmvwyttuimlsuownlnl'),
+(0,99068,'y','then'),(2,99069,'all','b'),(NULL,99070,'by','Wisconsin'),
+(4,99071,'about','right'),(5,99072,'m','s'),(0,99073,'e','Pennsylvania'),
+(-28284,99074,'x','f'),(1,99075,'Rhode Isla','Georgia'),(NULL,99076,'p','was'),
+(168,99077,'Tennessee','Minnesota'),(18349,99078,'x','Rhode Island'),
+(5,99079,'as','d'),(12217,99080,'c','i'),(0,99081,'rdvdxboydm','s'),
+(19132,99082,'her','jerdvdxboydmpefbiesqbyyvdftsidjtvulamazljxpgiwmbn'),
+(0,99083,'all','jhjerdvdxboydmpefbiesqbyyvdftsidjtvulamazljx'),
+(32767,99084,'s','flj'),(-4947,99085,'something','Vermont'),
+(0,99086,'cjfljhjerd','Washington');
+--enable_query_log
+--enable_result_log
+
+SELECT COUNT(*) FROM t1 IGNORE INDEX (idx2,idx3)
+ WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR
+ (pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ;
+SELECT COUNT(*) FROM t1
+ WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR
+ (pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ;
+EXPLAIN
+SELECT COUNT(*) FROM t1
+ WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR
+ (pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ;
+
+DROP TABLE t1;
+
+#
+# Bug #684117: ORing of two index merge that caused a crash
+#
+
+CREATE TABLE t1 (
+ f1 int, f2 int, f3 int, f4 int, f5 int,
+ PRIMARY KEY (f4), KEY (f1), KEY (f2), KEY (f3)
+) ;
+INSERT INTO t1 VALUES (0,0,NULL,9,5), (0,0,1,9425,NULL);
+
+SELECT f5 FROM t1
+ WHERE f2 != 1 OR f1 IS NULL OR f4 = 4 OR
+ f2 AND (f4 BETWEEN 6 AND 255 OR f3 IS NULL);
+
+DROP TABLE t1;
+
+#
+# Bug #685952: An invalid index merge union plan
+#
+
+CREATE TABLE t1 (
+ f1 int, f2 int, f3 int, f4 int,
+ PRIMARY KEY (f1), KEY (f3), KEY (f4)
+);
+
+INSERT INTO t1 VALUES (9,0,2,6), (9930,0,0,NULL);
+
+SET SESSION optimizer_switch='index_merge_intersection=off';
+SET SESSION optimizer_switch='index_merge_sort_union=off';
+
+SET SESSION optimizer_switch='index_merge_union=off';
+
+EXPLAIN
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+ WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+ OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+ WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+ OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+
+SET SESSION optimizer_switch='index_merge_union=on';
+
+EXPLAIN
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+ WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+ OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+ WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+ OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+
+
+INSERT INTO t1 VALUES
+ (93,0,3,6), (9933,0,3,3), (94,0,4,6), (9934,0,4,4),
+ (95,0,5,6), (9935,0,5,5), (96,0,6,6), (9936,0,6,6),
+ (97,0,7,6), (9937,0,7,7), (98,0,8,6), (9938,0,8,8),
+ (99,0,9,6), (9939,0,9,9);
+
+SET SESSION optimizer_switch='index_merge_union=off';
+
+EXPLAIN
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+ WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+ OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+ WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+ OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+
+SET SESSION optimizer_switch='index_merge_union=on';
+
+EXPLAIN
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+ WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+ OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+
+SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
+ WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
+ OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
+
+SET SESSION optimizer_switch=DEFAULT;
+
+DROP TABLE t1;
+
+#
+# Bug #752353: valgrind complain on a jump depending
+# on an uninitialised value
+#
+
+CREATE TABLE t1 (f1 int) ;
+INSERT INTO t1 VALUES (0), (0);
+
+CREATE TABLE t2 (f1 int, f2 int, f3 int, f4 int, INDEX idx (f3,f2)) ;
+INSERT INTO t2 VALUES (5,6,0,0), (0,4,0,0);
+
+CREATE TABLE t3 (f1 int, f2 int, INDEX idx1 (f2,f1) , INDEX idx2 (f1)) ;
+INSERT INTO t3 VALUES (6,0),( 4,0);
+
+SELECT * FROM t1,t2,t3
+ WHERE (t2.f3 = 1 OR t3.f1=t2.f1) AND t3.f1 <> t2.f2 AND t3.f2 = t2.f4;
+
+DROP TABLE t1,t2,t3;
+
+#
+# LP bug #823301: index merge sort union with possible index scan
+#
+
+CREATE TABLE t1 (
+ a int, b int, c int, d int,
+ PRIMARY KEY(b), INDEX idx1(d), INDEX idx2(d,b,c)
+);
+INSERT INTO t1 VALUES
+ (0,58,7,7),(0,63,2,0),(0,64,186,8),(0,65,1,-2), (0,71,190,-3),
+ (0,72,321,-7),(0,73,0,3),(0,74,5,25),(0,75,5,3);
+
+SET SESSION optimizer_switch='index_merge_sort_union=off';
+EXPLAIN
+SELECT * FROM t1
+ WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+SELECT * FROM t1
+ WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+SET SESSION optimizer_switch='index_merge_sort_union=on';
+EXPLAIN
+SELECT * FROM t1
+ WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+SELECT * FROM t1
+ WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+SET SESSION optimizer_switch=DEFAULT;
+
+DROP TABLE t1;
+
+#
+# LP bug #800184: possible index merge sort union
+#
+
+CREATE TABLE t1 (a int NOT NULL PRIMARY KEY, b int, c int, INDEX idx(c,b));
+INSERT INTO t1 VALUES (19,1,NULL), (20,5,7);
+
+EXPLAIN
+SELECT * FROM t1
+ WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND
+ (t1.c=0 OR t1.a=500);
+SELECT * FROM t1
+ WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND
+ (t1.c=0 OR t1.a=500);
+
+DROP TABLE t1;
+
+#
+# LP bug #891953: always true OR
+#
+
+CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX idx(b));
+INSERT INTO t1 VALUES (167,9999), (168,10000);
+
+EXPLAIN
+SELECT * FROM t1
+ WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2;
+SELECT * FROM t1
+ WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2;
+
+DROP TABLE t1;
+
+#the following command must be the last one in the file
+set session optimizer_switch='index_merge_sort_intersection=default';
+
diff --git a/mysql-test/t/range_vs_index_merge_innodb.test b/mysql-test/t/range_vs_index_merge_innodb.test
new file mode 100755
index 00000000000..e85cd044ece
--- /dev/null
+++ b/mysql-test/t/range_vs_index_merge_innodb.test
@@ -0,0 +1,7 @@
+--source include/have_innodb.inc
+
+SET SESSION STORAGE_ENGINE='InnoDB';
+
+--source t/range_vs_index_merge.test
+
+SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/t/read_only_innodb.test b/mysql-test/t/read_only_innodb.test
index f8c25fdee1d..ec016c54f63 100644
--- a/mysql-test/t/read_only_innodb.test
+++ b/mysql-test/t/read_only_innodb.test
@@ -75,7 +75,36 @@ BEGIN;
SELECT * FROM t1;
COMMIT;
+#
+# Tests that LOCK TABLE doesn't block the SET READ_ONLY=1 for the InnoDB tables
+#
+
+connection default;
+UNLOCK TABLES;
+FLUSH STATUS;
+--echo # Expected 0 at the beginning of the test
+show status like 'Opened_tables';
+
+--echo connection con1;
+connection con1;
+lock table t1 write;
+
+--echo connection default;
connection default;
+set global read_only=1;
+--echo # Expected 1 as the slow_log was reopened
+show status like 'Opened_tables';
+
+--echo connection con1;
+connection con1;
+unlock tables;
+
+--echo connection default;
+connection default;
+SET GLOBAL read_only=0;
+--echo # Expected 2 as the slow_log was reopened
+show status like 'Opened_tables';
+
UNLOCK TABLES;
DROP TABLE t1;
DROP USER test@localhost;
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index ef1894a5405..890da70caad 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -13,6 +13,17 @@ drop table if exists t1_1,t1_2,t9_1,t9_2,t1aa,t2aa;
drop view if exists v1;
--enable_warnings
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch=ifnull(@optimizer_switch_for_select_test,'outer_join_with_cache=off');
+if (`select @join_cache_level_for_select_test is null`)
+{
+ set join_cache_level=1;
+}
+if (`select @join_cache_level_for_select_test is not null`)
+{
+ set join_cache_level=@join_cache_level_for_select_test;
+}
+
CREATE TABLE t1 (
Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
@@ -1961,6 +1972,7 @@ CREATE TABLE t2 ( a BLOB, INDEX (a(20)) );
INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five');
INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
+INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a;
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a;
@@ -3513,6 +3525,7 @@ 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';
select str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6';
+select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6';
select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6';
# We have all we need -- and trailing garbage:
@@ -3562,10 +3575,12 @@ select str_to_date('1','%Y-%m-%d') = '1';
select str_to_date('1','%Y-%m-%d') = '1';
select str_to_date('','%Y-%m-%d') = '';
-# these three should work!
-select str_to_date('1000-01-01','%Y-%m-%d') between '0000-00-00' and NULL;
-select str_to_date('1000-01-01','%Y-%m-%d') between NULL and '2000-00-00';
-select str_to_date('1000-01-01','%Y-%m-%d') between NULL and NULL;
+select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01';
+select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL;
+select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01';
+select str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL;
+select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01';
+select str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL;
#
# Bug #30666: Incorrect order when using range conditions on 2 tables or more
@@ -3893,9 +3908,9 @@ DROP TABLE t1;
# Field_varstring::store
#
-CREATE TABLE A (date_key date);
+CREATE TABLE t1 (date_key date);
-CREATE TABLE C (
+CREATE TABLE t2 (
pk int,
int_nokey int,
int_key int,
@@ -3904,20 +3919,20 @@ CREATE TABLE C (
varchar_key varchar(1)
);
-INSERT INTO C VALUES
+INSERT INTO t2 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);
+SELECT 1 FROM t2 WHERE pk > ANY (SELECT 1 FROM t2);
-SELECT COUNT(DISTINCT 1) FROM C
- WHERE date_key = (SELECT 1 FROM A WHERE C.date_key IS NULL) GROUP BY pk;
-SELECT date_nokey FROM C
- WHERE int_key IN (SELECT 1 FROM A)
+SELECT COUNT(DISTINCT 1) FROM t2
+ WHERE date_key = (SELECT 1 FROM t1 WHERE t2.date_key IS NULL) GROUP BY pk;
+SELECT date_nokey FROM t2
+ WHERE int_key IN (SELECT 1 FROM t1)
HAVING date_nokey = '10:41:7'
ORDER BY date_key;
-DROP TABLE A,C;
+DROP TABLE t1,t2;
#
# Bug #42957: no results from
@@ -4111,7 +4126,7 @@ INSERT INTO t5 VALUES (20),(5);
CREATE TABLE t6(f1 int);
INSERT INTO t6 VALUES (9),(7);
-SET SESSION join_buffer_size = 9000;
+SET SESSION join_buffer_size = 2176;
EXPLAIN
SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6;
@@ -4121,6 +4136,95 @@ SET SESSION join_buffer_size = DEFAULT;
DROP TABLE t1,t2,t3,t4,t5,t6;
+--echo #
+--echo # Bug #698882: best equality substitution not applied to ref
+--echo #
+
+CREATE TABLE t1 (a1 int NOT NULL, b1 char(10), INDEX idx (a1));
+CREATE TABLE t2 (a2 int NOT NULL, b2 char(10), INDEX idx (a2));
+CREATE TABLE t3 (a3 int NOT NULL, b3 char(10), INDEX idx (a3));
+INSERT INTO t1 VALUES (2,'xx'), (1,'xxx'), (11,'xxxxxxx');
+INSERT INTO t2 VALUES
+ (7,'yyyy'), (2,'y'), (3,'yyy'), (1,'yy'), (1,'yyyyy'),
+ (3,'yy'), (1,'y'), (4,'yyy'), (7,'y'), (4,'yyyyy'), (7,'yyy'),
+ (7,'yyyy'), (2,'yy'), (3,'yyy'), (1,'yyyyyyyy'), (1,'yyyyy'),
+ (3,'yy'), (1,'yyy'), (4,'yyy'), (7,'y'), (4,'yyyyy'), (7,'yyy');
+INSERT INTO t3 VALUES
+ (9,'zzzzzzz'), (2,'zzzzz'), (1,'z'), (9,'zz'), (1,'zz'), (5,'zzzzzzz'),
+ (4,'zz'), (3,'z'), (5,'zzzzzz'), (3,'zz'), (4,'zzzz'), (3,'z'),
+ (9,'zzzzzzzz'), (2,'zz'), (1,'zz'), (9,'zzz'), (1,'zzz'), (5,'zzzzzzzz'),
+ (4,'zzz'), (3,'zz'), (5,'zzzzzzz'), (3,'zzz'), (4,'zzzzz'), (3,'zz'),
+ (9,'zzzzzz'), (2,'zzzz'), (1,'zzz'), (9,'z'), (1,'z'), (5,'zzzzzz'),
+ (4,'z'), (3,'zzz'), (5,'zzzzz'), (3,'z'), (4,'zzz'), (3,'zzzz'),
+ (9,'zzzzz'), (2,'zzz'), (1,'zzzz'), (9,'zzz'), (1,'zzzz'), (5,'zzzzz'),
+ (4,'zzz'), (3,'zzzz'), (5,'zzzz'), (3,'zzz'), (4,'zz'), (3,'zzzzz');
+
+set @tmp= @@optimizer_switch;
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+
+EXPLAIN SELECT * from t1,t2,t3 WHERE t3.a3=t1.a1 AND t2.a2=t1.a1;
+EXPLAIN SELECT * FROM t1,t2,t3 WHERE t2.a2=t1.a1 AND t3.a3=t1.a1;
+EXPLAIN SELECT * FROM t1,t2,t3 WHERE t2.a2=t1.a1 AND t3.a3=t2.a2;
+
+--sorted_result
+SELECT * from t1,t2,t3
+ WHERE t3.a3=t1.a1 AND t2.a2=t1.a1 AND
+ LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7;
+--sorted_result
+SELECT * FROM t1,t2,t3
+ WHERE t2.a2=t1.a1 AND t3.a3=t1.a1 AND
+ LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7;
+--sorted_result
+SELECT * FROM t1,t2,t3
+ WHERE t2.a2=t1.a1 AND t3.a3=t2.a2 AND
+ LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7;
+
+SET SESSION optimizer_switch=@tmp;
+
+DROP TABLE t1,t2,t3;
+
+
+--echo #
+--echo # Bug #707555: crash with equality substitution in ref
+--echo #
+
+CREATE TABLE t1 (f11 int, f12 int, PRIMARY KEY (f11), KEY (f12)) ;
+INSERT INTO t1 VALUES (1,NULL), (8,NULL);
+
+CREATE TABLE t2 (f21 int, f22 int, f23 int, KEY (f22)) ;
+INSERT INTO t2 VALUES (1,NULL,3), (2,7,8);
+
+CREATE TABLE t3 (f31 int, f32 int(11), PRIMARY KEY (f31), KEY (f32)) ;
+INSERT INTO t3 VALUES (1,494862336);
+
+CREATE TABLE t4 (f41 int, f42 int, PRIMARY KEY (f41), KEY (f42)) ;
+INSERT INTO t4 VALUES (1,NULL), (8,NULL);
+
+CREATE TABLE t5 (f51 int, PRIMARY KEY (f51)) ;
+INSERT IGNORE INTO t5 VALUES (100);
+
+CREATE TABLE t6 (f61 int, f62 int, KEY (f61)) ;
+INSERT INTO t6 VALUES (NULL,1), (3,10);
+
+CREATE TABLE t7 (f71 int, f72 int, KEY (f72)) ;
+INSERT INTO t7 VALUES (1,NULL), (2,7);
+
+EXPLAIN
+SELECT t2.f23 FROM
+ (t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
+ LEFT JOIN
+ (((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
+ ON t3.f31 = t6.f61
+ WHERE t7.f71>0;
+
+SELECT t2.f23 FROM
+ (t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31)
+ LEFT JOIN
+ (((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0)
+ ON t3.f31 = t6.f61
+ WHERE t7.f71>0;
+
+DROP TABLE t1,t2,t3,t4,t5,t6,t7;
#
# Bug #780425: "sql_buffer_result=1 gives wrong result for GROUP BY with a
# constant expression"
@@ -4139,3 +4243,47 @@ SELECT 1 FROM t1 GROUP BY 1;
drop table t1;
--echo End of 5.1 tests
+
+--echo #
+--echo # BUG#776274: substitution of a single row table
+--echo #
+
+CREATE TABLE t1 (a int NOT NULL , b int);
+INSERT INTO t1 VALUES (2,2);
+
+SELECT * FROM t1 WHERE a = b;
+EXPLAIN
+SELECT * FROM t1 WHERE a = b;
+
+DROP TABLE t1;
+
+--echo #
+--echo # lp:822760 Wrong result with view + invalid dates
+--echo #
+CREATE TABLE t1 (f1 date);
+INSERT IGNORE INTO t1 VALUES ('0000-00-00');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t1 HAVING f1 = 'zz';
+SELECT * FROM t1 HAVING f1 <= 'aa' ;
+SELECT * FROM t1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+SELECT * FROM t1 WHERE f1 = 'zz' AND f1 <= 'aa' ;
+SELECT * FROM v1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+DROP TABLE t1;
+DROP VIEW v1;
+
+SET optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # LP bug#994275 Assertion `real->type() == Item::FIELD_ITEM' failed
+--echo # in add_not_null_conds(JOIN*) with JOIN, ZEROFILL column, PK
+--echo #
+
+CREATE TABLE t1 ( a INT(6) ZEROFILL );
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2 ( b INT PRIMARY KEY );
+INSERT INTO t2 VALUES (3),(4);
+SELECT * FROM t1, t2 WHERE a=3 AND a=b;
+drop table t1,t2;
+
+--echo End of 5.3 tests
diff --git a/mysql-test/t/select_debug.test b/mysql-test/t/select_debug.test
new file mode 100644
index 00000000000..16e8425efc4
--- /dev/null
+++ b/mysql-test/t/select_debug.test
@@ -0,0 +1,19 @@
+--source include/have_debug.inc
+
+--echo #
+--echo # Bug #725050: print keyuse info when hash join is used
+--echo #
+
+create table t1 (a int, b int);
+insert into t1 values (2,2), (1,1);
+create table t2 (a int);
+insert into t2 values (2), (3);
+
+set session join_cache_level=3;
+set @@debug = 'd:t:O,/tmp/trace.out';
+
+explain select t1.b from t1,t2 where t1.b=t2.a;
+select t1.b from t1,t2 where t1.b=t2.a;
+
+set session join_cache_level=default;
+drop table t1,t2;
diff --git a/mysql-test/t/select_jcl6.test b/mysql-test/t/select_jcl6.test
new file mode 100644
index 00000000000..f7c1aa988c7
--- /dev/null
+++ b/mysql-test/t/select_jcl6.test
@@ -0,0 +1,24 @@
+#
+# Run select.test with BKA enabled
+#
+
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set @@optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+set @optimizer_switch_for_select_test=@@optimizer_switch;
+set @join_cache_level_for_select_test=@@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;
+set @optimizer_switch_for_select_test=NULL;
+set @join_cache_level_for_select_test=NULL;
diff --git a/mysql-test/t/select_safe.test b/mysql-test/t/select_safe.test
index 481779e76d7..5691de956cb 100644
--- a/mysql-test/t/select_safe.test
+++ b/mysql-test/t/select_safe.test
@@ -58,6 +58,8 @@ SELECT * from t1;
#
analyze table t1;
insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a");
+insert into t1 values (null,"b"),(null,"b"),(null,"c"),(null,"c"),(null,"d"),(null,"d"),(null,"e"),(null,"e"),(null,"a"),(null,"e");
+insert into t1 values (null,"x"),(null,"x"),(null,"y"),(null,"y"),(null,"z"),(null,"z"),(null,"v"),(null,"v"),(null,"a"),(null,"v");
explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b;
set MAX_SEEKS_FOR_KEY=1;
explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 7dff5f3034d..0fce174ecb7 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -194,12 +194,15 @@ begin
insert into test.t1 values (x, z);
end|
+let $start_value= `SELECT @@max_join_size`|
call mixset("mixset", 19)|
show variables like 'max_join_size'|
select id,data,@z from t1|
delete from t1|
drop procedure mixset|
-
+--disable_query_log
+eval SET @@max_join_size= $start_value|
+--enable_query_log
# Multiple CALL statements, one with OUT parameter.
--disable_warnings
@@ -3748,15 +3751,25 @@ begin
return @x;
end|
-set @qcs1 = @@query_cache_size|
-set global query_cache_size = 100000|
+--disable_query_log
+--echo # Set query cache size, if we have query cache
+if (`select @@have_query_cache='YES'`) {
+ set @qcs1 = @@query_cache_size|
+ set global query_cache_size = 100000|
+}
+--enable_query_log
set @x = 1|
insert into t1 values ("qc", 42)|
select bug9902() from t1|
select bug9902() from t1|
select @x|
-set global query_cache_size = @qcs1|
+--echo # Restore the old query cache size
+--disable_query_log
+if (`select @@have_query_cache='YES'`) {
+ set global query_cache_size = @qcs1|
+}
+--enable_query_log
delete from t1|
drop function bug9902|
@@ -8465,3 +8478,22 @@ CALL p1(1);
DROP PROCEDURE p1;
+--echo
+--echo MDEV-3900 Optimizer difference between MySQL and MariaDB with stored functions in WHERE clause of UPDATE or DELETE statements
+--echo
+
+CREATE FUNCTION tdn() RETURNS int(7) DETERMINISTIC RETURN to_days(now());
+
+CREATE TABLE t1 (pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY, daynum INT, a CHAR(1), INDEX(daynum), INDEX(a)) ENGINE=MyISAM;
+INSERT INTO t1 (daynum) VALUES (1),(2),(3),(4),(5),(TO_DAYS(NOW())),(7),(8);
+INSERT INTO t1 (daynum) SELECT a1.daynum FROM t1 a1, t1 a2, t1 a3, t1 a4, t1 a5;
+
+FLUSH TABLES;
+FLUSH STATUS;
+
+SHOW STATUS LIKE '%Handler_read%';
+UPDATE t1 SET a = '+' WHERE daynum=tdn();
+SHOW STATUS LIKE '%Handler_read%';
+
+drop function tdn;
+drop table t1;
diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test
index 30e4899e3ba..e4c3351738e 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 d8458f69eef..2b5a44decf5 100644
--- a/mysql-test/t/sp_sync.test
+++ b/mysql-test/t/sp_sync.test
@@ -37,7 +37,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..8cc938c923e 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;
@@ -353,6 +353,33 @@ DROP FUNCTION f1;
# End of 5.1 tests
+#
+# Test of internal temporary table status variables
+#
+
+flush status;
+create table t1 (a int not null auto_increment primary key, g int, b blob);
+insert into t1 (g,b) values (1,'a'), (2, 'b'), (3, 'b'), (1, 'c');
+select * from t1;
+select b, count(*) from t1 group by b;
+select g, count(*) from t1 group by g;
+show status like 'Row%';
+show status like 'Handler%';
+show status like '%tmp%';
+drop table t1;
+
+#
+# Test of handler status counts
+#
+CREATE TABLE t1 (i int(11) DEFAULT NULL, KEY i (i) ) ENGINE=MyISAM;
+insert into t1 values (1),(2),(3),(4),(5);
+flush status;
+select * from t1 where i=5 union select * from t1 where i=5;
+show status like "handler%";
+drop table t1;
+
+# End of 5.3 tests
+
# Restore global concurrent_insert value. Keep in the end of the test file.
--connection default
set @@global.concurrent_insert= @old_concurrent_insert;
diff --git a/mysql-test/t/status_user.test b/mysql-test/t/status_user.test
index d42f81b20e5..802e2207d3d 100644
--- a/mysql-test/t/status_user.test
+++ b/mysql-test/t/status_user.test
@@ -85,5 +85,25 @@ select connected_time <> 0, busy_time <> 0, bytes_received <> 0,
bytes_sent <> 0, binlog_bytes_written <> 0
from information_schema.client_statistics;
+#
+# Test of in transaction
+#
+
+create table t1 (a int) engine=innodb;
+select @@in_transaction;
+begin;
+select @@in_transaction;
+insert into t1 values (1);
+select @@in_transaction;
+commit;
+select @@in_transaction;
+set @@autocommit=0;
+select @@in_transaction;
+insert into t1 values (2);
+select @@in_transaction;
+set @@autocommit=1;
+select @@in_transaction;
+drop table t1;
+
# Cleanup
set @@global.general_log=@save_general_log;
diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test
index 5779ea97bc2..e4a93453aee 100644
--- a/mysql-test/t/strict.test
+++ b/mysql-test/t/strict.test
@@ -367,6 +367,8 @@ INSERT INTO t1 (col1) VALUES(CONVERT('0000-10-31' , DATE));
INSERT INTO t1 (col1) VALUES(CONVERT('2004-10-0' , DATE));
--error 1292
INSERT INTO t1 (col1) VALUES(CONVERT('2004-0-10' , DATE));
+--error 1292
+INSERT INTO t1 (col1) VALUES('2004-0-10');
# deactivated because of Bug#8294
# Bug#8294 Traditional: Misleading error message for invalid CAST to DATE
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 3be57e993d5..eda78b1afe6 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1,8 +1,31 @@
+#
+# 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 @subselect_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test,
+ "semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+
+if (`select @join_cache_level_for_subselect_test is null`)
+{
+ set join_cache_level=1;
+}
+if (`select @join_cache_level_for_subselect_test is not null`)
+{
+ set join_cache_level=@join_cache_level_for_subselect_test;
+}
+ set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
select (select 2);
explain extended select (select 2);
SELECT (SELECT 1) UNION SELECT (SELECT 2);
@@ -80,8 +103,11 @@ explain extended (select * from t2 where t2.b=(select a from t3 order by 1 desc
select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
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;
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
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;
+set optimizer_switch=@tmp_optimizer_switch;
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);
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);
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);
@@ -248,6 +274,7 @@ 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 ER_SUBQUERY_NO_1_ROW
select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1);
+show warnings;
drop table t1;
create table t1 (a int);
@@ -277,8 +304,9 @@ SELECT (SELECT numeropost FROM t1 HAVING numreponse=a),numreponse FROM (SELECT *
SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=a) FROM (SELECT * FROM t1) as a;
SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT * FROM t1) as a;
INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
--- error ER_SUBQUERY_NO_1_ROW
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+-- error ER_SUBQUERY_NO_1_ROW
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
drop table t1;
@@ -310,7 +338,7 @@ insert into t2 values (1, 21),(2, 12),(3, 23);
select * from t1;
select * from t1 where b = (select b from t2 where t1.a = t2.a);
-- error ER_UPDATE_TABLE_USED
-delete from t1 where b = (select b from t1);
+delete from t1 where b in (select b from t1);
-- error ER_SUBQUERY_NO_1_ROW
delete from t1 where b = (select b from t2);
delete from t1 where b = (select b from t2 where t1.a = t2.a);
@@ -859,17 +887,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);
@@ -882,7 +905,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
@@ -1542,12 +1565,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
@@ -1854,6 +1878,9 @@ drop table t1;
# Bug#11867 queries with ROW(,elems>) IN (SELECT DISTINCT <cols> FROM ...)
#
+set @tmp11867_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin_with_cache=off';
+
CREATE TABLE t1 (one int, two int, flag char(1));
CREATE TABLE t2 (one int, two int, flag char(1));
INSERT INTO t1 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
@@ -1881,6 +1908,7 @@ explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FR
explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
DROP TABLE t1,t2;
+set optimizer_switch=@tmp11867_optimizer_switch;
#
# Bug#12392 where cond with IN predicate for rows and NULL values in table
@@ -2118,7 +2146,7 @@ SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2);
--error ER_SUBQUERY_NO_1_ROW
SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1);
-
+--sorted_result
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;
@@ -2126,7 +2154,7 @@ SELECT a FROM t1 GROUP BY a
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;
-
+--sorted_result
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;
@@ -2134,7 +2162,7 @@ SELECT a FROM t1 GROUP BY a
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;
-
+--sorted_result
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));
@@ -2142,7 +2170,7 @@ SELECT a FROM t1
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));
-
+--sorted_result
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));
@@ -2560,33 +2588,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;
#
@@ -2653,27 +2678,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(*)
@@ -2685,8 +2699,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
@@ -3142,6 +3155,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
#
@@ -3188,6 +3248,10 @@ DROP TABLE t1, t2, t3;
# Bug#30788 Inconsistent retrieval of char/varchar
#
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+SET optimizer_switch='materialization=off';
+
CREATE TABLE t1 (a CHAR(1), b VARCHAR(10));
INSERT INTO t1 VALUES ('a', 'aa');
INSERT INTO t1 VALUES ('a', 'aaa');
@@ -3209,6 +3273,7 @@ SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
DROP TABLE t1,t2;
+SET optimizer_switch= @save_optimizer_switch;
#
# Bug#32400 Complex SELECT query returns correct result only on some occasions
@@ -3243,52 +3308,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"
@@ -3365,8 +3423,11 @@ 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);
-EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a);
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 GROUP BY a);
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 WHERE a > 3 GROUP BY a);
+SET join_cache_level=@save_join_cache_level;
DROP TABLE t1;
--echo #
@@ -3541,6 +3602,183 @@ drop view v1;
--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
#
@@ -3644,6 +3882,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
@@ -3684,6 +4147,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));
@@ -3733,6 +4231,7 @@ SELECT 1 FROM t1 GROUP BY
(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
DROP TABLE t1;
+#Seems to be not needed here: set @@optimizer_switch=@subselect_tmp;
--echo #
--echo # Bug #49512 : subquery with aggregate function crash
--echo # subselect_single_select_engine::exec()
@@ -3913,6 +4412,117 @@ 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;
+
+--echo #
+--echo # Bug#52068: Optimizer generates invalid semijoin materialization plan
+--echo #
+--disable_warnings
+drop table if exists ot1, ot2, it1, it2;
+--enable_warnings
+CREATE TABLE ot1(a INTEGER);
+INSERT INTO ot1 VALUES(5), (8);
+CREATE TABLE it2(a INTEGER);
+INSERT INTO it2 VALUES(9), (5), (1), (8);
+CREATE TABLE it3(a INTEGER);
+INSERT INTO it3 VALUES(7), (1), (0), (5), (1), (4);
+CREATE TABLE ot4(a INTEGER);
+INSERT INTO ot4 VALUES(1), (3), (5), (7), (9), (7), (3), (1);
+
+let $query=
+SELECT * FROM ot1,ot4
+WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
+ FROM it2,it3);
+
+eval $query;
+eval explain $query;
+
+DROP TABLE IF EXISTS ot1, ot4, it2, it3;
+
+
+--echo #
+--echo # Bug#729039: NULL keys used to evaluate subquery
+--echo #
+
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (NULL), (1), (NULL), (2);
+
+CREATE TABLE t2 (a int, INDEX idx(a)) ;
+INSERT INTO t2 VALUES (NULL), (1), (NULL);
+
+SELECT * FROM t1
+ WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a);
+EXPLAIN
+SELECT * FROM t1
+ WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a);
+
+SELECT * FROM t1
+ WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+EXPLAIN
+SELECT * FROM t1
+ WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # BUG#752992: Wrong results for a subquery with 'semijoin=on'
+--echo #
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+
+
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=0;
+EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+SET join_cache_level=@save_join_cache_level;
+
+DROP table t1,t2;
+
+--echo #
+--echo # Bug#751350: crash with pushed condition for outer references when
+--echo # there should be none of such conditions
+--echo #
+
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0),(0,0);
+set @optimizer_switch_save=@@optimizer_switch;
+set @@optimizer_switch='semijoin=off,materialization=on,in_to_exists=on';
+EXPLAIN
+SELECT b FROM t1
+ WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+ GROUP BY b;
+
+SELECT b FROM t1
+ WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+ GROUP BY b;
+set @@optimizer_switch=@optimizer_switch_save;
+DROP TABLE t1;
+
+--echo #
--echo # Bug #11765713 58705:
--echo # OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES
--echo # CREATED BY OPT_SUM_QUERY
@@ -4222,3 +4832,491 @@ DROP TABLE t1,t2;
--echo End of 5.2 tests
+--echo #
+--echo # BUG#779885: Crash in eliminate_item_equal with materialization=on in
+--echo #
+
+CREATE TABLE t1 ( f1 int );
+INSERT INTO t1 VALUES (19), (20);
+
+CREATE TABLE t2 ( f10 varchar(32) );
+INSERT INTO t2 VALUES ('c'),('d');
+
+CREATE TABLE t3 ( f10 varchar(32) );
+INSERT INTO t3 VALUES ('a'),('b');
+
+SELECT *
+FROM t1
+WHERE
+( 't' ) IN (
+ SELECT t3.f10
+ FROM t3
+ JOIN t2
+ ON t2.f10 = t3.f10
+);
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # BUG LP:813473: Wrong result with outer join + NOT IN subquery
+--echo # This bug is a duplicate of Bug#11764086 whose test case is added below
+--echo #
+
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (5),(6);
+
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (20,9),(20,9);
+
+create table t3 (d int, e int);
+insert into t3 values (2, 9), (3,10);
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
+EXPLAIN
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b , t1.c) NOT IN (SELECT * from t3);
+
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b, t1.c) NOT IN (SELECT * from t3);
+
+SET optimizer_switch=@save_optimizer_switch;
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # Bug#11764086: Null left operand to NOT IN in WHERE clause
+--echo # behaves differently than real NULL
+--echo #
+
+CREATE TABLE parent (id int);
+INSERT INTO parent VALUES (1), (2);
+
+CREATE TABLE child (parent_id int, other int);
+INSERT INTO child VALUES (1,NULL);
+
+--echo # Offending query (c.parent_id is NULL for null-complemented rows only)
+
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id NOT IN (
+ SELECT parent_id
+ FROM child
+ WHERE parent_id = 3
+ );
+
+--echo # Some syntactic variations with IS FALSE and IS NOT TRUE
+
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+ SELECT parent_id
+ FROM child
+ WHERE parent_id = 3
+ ) IS NOT TRUE;
+
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+ SELECT parent_id
+ FROM child
+ WHERE parent_id = 3
+ ) IS FALSE;
+
+DROP TABLE parent, child;
+
+--echo # End of test for bug#11764086.
+
+--echo #
+--echo # Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET ||
+--echo # BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX
+--echo #
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0), (1);
+
+CREATE TABLE t2(
+ b TEXT,
+ c INT,
+ PRIMARY KEY (b(1))
+);
+INSERT INTO t2 VALUES ('a', 2), ('b', 3);
+
+SELECT 1 FROM t1 WHERE a =
+ (SELECT 1 FROM t2 WHERE b =
+ (SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ ORDER BY b
+ );
+
+SELECT 1 FROM t1 WHERE a =
+ (SELECT 1 FROM t2 WHERE b =
+ (SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ GROUP BY b
+ );
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # LP bug #826279: assertion failure with GROUP BY a result of subquery
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0), (0);
+
+CREATE TABLE t2 (a int, b int, c int);
+INSERT INTO t2 VALUES (10,7,0), (0,7,0);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,7), (0,7);
+
+SELECT SUM(DISTINCT b),
+ (SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+ WHERE t.a != 0 AND t2.a != 0)
+ FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+
+SELECT SUM(DISTINCT b),
+ (SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+ FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug#12329653
+--echo # EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+--echo #
+
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+
+## First a simpler query, illustrating the transformation
+## '1 < some (...)' => '1 < max(...)'
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+
+## The query which made the server crash.
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+
+--error ER_SUBQUERY_NO_1_ROW
+EXECUTE stmt ;
+--error ER_SUBQUERY_NO_1_ROW
+EXECUTE stmt ;
+
+SET SESSION sql_mode=@old_sql_mode;
+
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
+--echo #
+--echo # LP BUG#833777 Performance regression with deeply nested subqueries
+--echo #
+
+create table t1 (a int not null, b char(10) not null);
+insert into t1 values (1, 'a');
+set @@optimizer_switch='in_to_exists=on,semijoin=off,materialization=off,subquery_cache=off';
+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)))))))))))))))))))))))))))));
+set @@optimizer_switch=@subselect_tmp;
+drop table t1;
+
+--echo #
+--echo # LP BUG#894397 Wrong result with in_to_exists, constant table , semijoin=OFF,materialization=OFF
+--echo #
+
+CREATE TABLE t1 (a varchar(3));
+INSERT INTO t1 VALUES ('AAA'),('BBB');
+CREATE TABLE t2 (a varchar(3));
+INSERT INTO t2 VALUES ('CCC');
+set @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquery_cache=off';
+SELECT * FROM t1 WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.a < 'ZZZ');
+set @@optimizer_switch=@subselect_tmp;
+drop table t1, t2;
+
+--echo #
+--echo # LP bug #859375: Assertion `0' failed in st_select_lex_unit::optimize
+--echo # with view , UNION and prepared statement (rewriting fake_select
+--echo # condition).
+--echo #
+
+CREATE TABLE t1 ( f1 int NOT NULL, f4 varchar(1) NOT NULL) ;
+INSERT INTO t1 VALUES (6,'d'),(7,'y');
+
+CREATE TABLE t2 ( f1 int NOT NULL, f2 int NOT NULL) ;
+INSERT INTO t2 VALUES (10,7);
+
+CREATE VIEW v2 AS SELECT * FROM t2;
+
+PREPARE st1 FROM "
+ SELECT *
+ FROM t1
+ LEFT JOIN v2 ON ( v2.f2 = t1.f1 )
+ WHERE v2.f1 NOT IN (
+ SELECT 1 UNION
+ SELECT 247
+ )
+";
+
+EXECUTE st1;
+deallocate prepare st1;
+
+DROP VIEW v2;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #887458 Crash in subselect_union_engine::no_rows with
+--echo # double UNION and join_cache_level=3,8
+--echo # (IN/ALL/ANY optimizations should not be applied to fake_select)
+
+CREATE TABLE t2 ( a int, b varchar(1)) ;
+INSERT IGNORE INTO t2 VALUES (8,'y'),(8,'y');
+
+CREATE TABLE t1 ( b varchar(1)) ;
+INSERT IGNORE INTO t1 VALUES (NULL),(NULL);
+
+set @save_join_cache_level=@@join_cache_level;
+SET SESSION join_cache_level=3;
+
+SELECT *
+FROM t1, t2
+WHERE t2.b IN (
+ SELECT 'm' UNION
+ SELECT 'm'
+) OR t1.b <> SOME (
+ SELECT 'v' UNION
+ SELECT 't'
+);
+
+set @@join_cache_level= @save_join_cache_level;
+drop table t1,t2;
+
+
+--echo #
+--echo # LP bug #885162 Got error 124 from storage engine with UNION inside
+--echo # subquery and join_cache_level=3..8
+--echo # (IN/ALL/ANY optimizations should not be applied to fake_select)
+--echo #
+
+CREATE TABLE t1 (
+ f1 varchar(1) DEFAULT NULL
+ );
+INSERT INTO t1 VALUES ('c');
+set @save_join_cache_level=@@join_cache_level;
+SET SESSION join_cache_level=8;
+SELECT * FROM t1 WHERE t1.f1 IN ( SELECT 'k' UNION SELECT 'e' );
+set @@join_cache_level= @save_join_cache_level;
+drop table t1;
+
+
+--echo #
+--echo # LP BUG#747278 incorrect values of the NULL (no rows) single
+--echo # row subquery requested via element_index() interface
+--echo #
+
+CREATE TABLE t1 (f1a int, f1b int) ;
+INSERT IGNORE INTO t1 VALUES (1,1),(2,2);
+CREATE TABLE t2 ( f2 int);
+INSERT IGNORE INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (f3a int default 1, f3b int default 2);
+INSERT INTO t3 VALUES (1,1),(2,2);
+
+# check different IN with switches where the bug was found
+set @old_optimizer_switch = @@session.optimizer_switch;
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,subquery_cache=off,semijoin=off';
+
+SELECT (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1) FROM t2;
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1) FROM t2;
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1) FROM t2;
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1);
+SELECT (SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1) FROM t2;
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1) FROM t2;
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1) FROM t2;
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1);
+
+set @@session.optimizer_switch=@old_optimizer_switch;
+
+# check different IN with default switches
+SELECT (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1) FROM t2;
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a,f1a FROM t1) FROM t2;
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1) FROM t2;
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) NOT IN (SELECT f1a, f1b FROM t1);
+SELECT (SELECT f3a FROM t3 where f3a > 3) IN (SELECT f1a FROM t1) FROM t2;
+SELECT (SELECT f3a,f3a FROM t3 where f3a > 3) IN (SELECT f1a,f1a FROM t1) FROM t2;
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1) FROM t2;
+SELECT (SELECT f3a, f3b FROM t3 where f3a > 3) IN (SELECT f1a, f1b FROM t1);
+
+# other row operation with NULL single row subquery also should work
+select (null, null) = (null, null);
+SELECT (SELECT f3a, f3a FROM t3 where f3a > 3) = (0, 0);
+
+drop tables t1,t2,t3;
+
+--echo #
+--echo # LP BUG#825051 Wrong result with date/datetime and subquery with GROUP BY and in_to_exists
+--echo #
+
+CREATE TABLE t1 (a date, KEY (a)) ;
+INSERT INTO t1 VALUES ('2009-01-01'),('2009-02-02');
+set @old_optimizer_switch = @@optimizer_switch;
+SET @@optimizer_switch='semijoin=off,materialization=off,in_to_exists=on,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+SET @@optimizer_switch='semijoin=off,materialization=on,in_to_exists=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1);
+set @@optimizer_switch=@old_optimizer_switch;
+drop table t1;
+
+--echo #
+--echo # LP BUG#908269 incorrect condition in case of subqueries depending
+--echo # on constant tables
+--echo #
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1),(5);
+
+# t2 must be MyISAM or Aria and contain 1 row
+CREATE TABLE t2 ( b INT ) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1);
+
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (4),(5);
+
+SET optimizer_switch='subquery_cache=off';
+
+SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1;
+
+# This query just for example, it should return the same as above (1 and NULL)
+SELECT ( SELECT b FROM t2 WHERE b = a OR b * 0) FROM t1;
+
+# example with "random"
+SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1;
+
+drop table t1,t2,t3;
+set optimizer_switch=@subselect_tmp;
+
+--echo #
+--echo # LP BUG#905353 Wrong non-empty result with a constant table,
+--echo # aggregate function in subquery, MyISAM or Aria
+--echo #
+
+CREATE TABLE t1 ( a INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1);
+
+SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 );
+
+drop table t1;
+
+--echo #
+--echo # LP BUG#985667 Wrong result with subquery in SELECT clause, and constant table in
+--echo # main query and implicit grouping
+--echo #
+
+CREATE TABLE t1 (f1 int) engine=MyISAM;
+INSERT INTO t1 VALUES (7),(8);
+
+CREATE TABLE t2 (f2 int, f3 varchar(1)) engine=MyISAM;
+INSERT INTO t2 VALUES (3,'f');
+
+EXPLAIN
+SELECT COUNT(f1), (SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+SELECT COUNT(f1), (SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+
+EXPLAIN
+SELECT COUNT(f1), exists(SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+SELECT COUNT(f1), exists(SELECT f1 FROM t1 WHERE f2 > 0 limit 1) AS f4 FROM t2, t1 WHERE 'v'= f3;
+
+EXPLAIN
+SELECT COUNT(f1), f2 > ALL (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+SELECT COUNT(f1), f2 > ALL (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+
+EXPLAIN
+SELECT COUNT(f1), f2 IN (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+SELECT COUNT(f1), f2 IN (SELECT f1 FROM t1 WHERE f2 > 0) AS f4 FROM t2, t1 WHERE 'v'= f3;
+
+drop table t1,t2;
+
+--echo #
+--echo # LP BUG#1002079 Server crashes in Item_singlerow_subselect::val_int with constant table,
+--echo # HAVING, UNION in subquery
+--echo #
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (7),(0);
+CREATE TABLE t2 (b INT);
+
+EXPLAIN
+SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
+
+SELECT SUM(a) AS f1, a AS f2 FROM (t1, t2) HAVING f2 >= ALL (SELECT 4 UNION SELECT 5) AND f1 = 7;
+
+drop table t1,t2;
+
+--echo #
+--echo # LP BUG#1008686 Server crashes in subselect_union_engine::no_rows on SELECT with impossible
+--echo # WHERE and UNION in HAVING
+--echo #
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(7);
+
+EXPLAIN
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 0 HAVING a NOT IN ( SELECT 2 UNION SELECT 5 ) OR min_a != 1;
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 0 HAVING a NOT IN ( SELECT 2 UNION SELECT 5 ) OR min_a != 1;
+
+EXPLAIN
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 1;
+SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 1;
+
+drop table t1;
+
+--echo #
+--echo # MDEV-367: Different results with and without subquery_cache on
+--echo # a query with a constant NOT IN condition
+--echo #
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2),(3);
+
+set @mdev367_optimizer_switch = @@optimizer_switch;
+
+set optimizer_switch = 'subquery_cache=on';
+SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
+SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
+set optimizer_switch=@mdev367_optimizer_switch;
+
+set optimizer_switch = 'subquery_cache=off';
+SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
+SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
+set optimizer_switch=@mdev367_optimizer_switch;
+
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-521 single value subselect transformation problem
+--echo #
+CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('u1'),('u2');
+
+SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) );
+FLUSH TABLES;
+SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) );
+
+# Cleanup
+DROP TABLE t1;
+
+--echo # return optimizer switch changed in the beginning of this test
+set optimizer_switch=@subselect_tmp;
diff --git a/mysql-test/t/subselect2.test b/mysql-test/t/subselect2.test
index 162bdd0d90a..75cf842fbdb 100644
--- a/mysql-test/t/subselect2.test
+++ b/mysql-test/t/subselect2.test
@@ -8,6 +8,9 @@
drop table if exists t1, t2, t3, t4;
--enable_warnings
+set @subselect2_test_tmp=@@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
CREATE TABLE t1
(
DOCID VARCHAR(32)BINARY NOT NULL
@@ -168,3 +171,56 @@ SELECT t1.* FROM t1 WHERE (SELECT COUNT(*) FROM t3,t2 WHERE t3.c=t2.a
and t2.a='1' AND t1.a=t3.b) > 0;
DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #902356: DISTINCT in materialized subquery
+--echo #
+
+CREATE TABLE t1 (pk int PRIMARY KEY, a int, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0, 4), (8, 6);
+
+CREATE TABLE t2 (pk int PRIMARY KEY, a int, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (0, 4), (8, 6);
+
+CREATE TABLE t3 (b INT, KEY(b));
+INSERT INTO t3 VALUES (7), (0), (4), (2);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SET @tmp_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='materialization=on,in_to_exists=on';
+
+EXPLAIN
+SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM t1) OR a = b;
+SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM t1) OR a = b;
+
+EXPLAIN
+SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM v1) OR a = b;
+SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM v1) OR a = b;
+
+SET optimizer_switch=@tmp_optimizer_switch;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # MDEV-567: Wrong result from a query with correlated subquery if ICP is allowed
+--echo #
+CREATE TABLE t1 (a int, b int, INDEX idx(a));
+INSERT INTO t1 VALUES (9,0), (7,1), (1,9), (7,3), (2,1);
+
+CREATE TABLE t2 (a int, b int, INDEX idx(a));
+INSERT INTO t2 VALUES (2,1), (6,4), (7,6), (9,4);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (1,0), (1,1), (1,3);
+
+SELECT * FROM t3
+ WHERE a = (SELECT COUNT(DISTINCT t2.b) FROM t1, t2
+ WHERE t1.a = t2.a AND t2.a BETWEEN 7 AND 9
+ AND t3.b = t1.b
+ GROUP BY t1.b);
+DROP TABLE t1, t2, t3;
+
+set optimizer_switch=@subselect2_test_tmp;
+
diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test
index 8d403279a48..ec6ceff8822 100644
--- a/mysql-test/t/subselect3.test
+++ b/mysql-test/t/subselect3.test
@@ -1,7 +1,18 @@
--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 @subselect3_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on';
+if (`select @join_cache_level_for_subselect3_test is null`)
+{
+ set join_cache_level=1;
+}
+if (`select @join_cache_level_for_subselect3_test is not null`)
+{
+ set join_cache_level=@join_cache_level_for_subselect3_test;
+}
+
#
# 1. Subquery with GROUP/HAVING
#
@@ -59,9 +70,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;
#
@@ -74,6 +89,7 @@ insert into t1 values
(2, 3),
(2, NULL),
(3, NULL);
+insert into t1 values (5, 7), (8, 9), (4, 1);
create table t2 (a int, oref int);
insert into t2 values (1, 1), (2,2), (NULL, 3), (NULL, 4);
@@ -94,10 +110,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 +547,8 @@ SELECT a, MAX(b),
DROP TABLE t1, t2;
+# The next three test cases must be executed with the IN=>EXISTS strategy
+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 +608,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 +641,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
#
@@ -656,7 +692,8 @@ SELECT a, ROW(11, 12) = (SELECT a, 12), ROW(11, 12) IN (SELECT a, 12) FROM t1;
# The x alias is used below to workaround bug #40674.
# Regression tests for sum function on outer column in subselect from dual:
SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 22), ROW(11, 12) IN (SELECT MAX(x), 22) FROM t1;
---echo # 2nd and 3rd columns should be same for x == 11 only
+--echo # 2nd and 3rd columns should be same
+EXPLAIN SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 12), ROW(11, 12) IN (SELECT MAX(x), 12) FROM t1;
SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 12), ROW(11, 12) IN (SELECT MAX(x), 12) FROM t1;
DROP TABLE t1;
@@ -692,6 +729,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 +808,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 +838,433 @@ 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;
+
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
+
+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;
+
+set @@optimizer_switch=@save_optimizer_switch;
+
+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,materialization=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=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
+explain select * from t1 where 2 in (select a from t0);
+select * from t1 where 2 in (select a from t0);
+set @@optimizer_switch=@save_optimizer_switch;
+
+
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
+
+#
+# FirstMatch referring to a derived table
+#
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+explain select * from (select a from t0) X where a in (select a from t1);
+drop table t0, t1;
+set optimizer_switch=@tmp_optimizer_switch;
+
+#
+# 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;
+
+set @@optimizer_switch=@save_optimizer_switch;
+
+#
+# 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 where a+1 < 10000 + A.a + B.a +C.a+D.a);
+flush status;
+select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a);
+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;
+
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
+
+#
+# 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;
+
+set @@optimizer_switch=@save_optimizer_switch;
+
+#
+# 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,materialization=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;
+
+set @@optimizer_switch='materialization=off';
+
+#
+# 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;
+
+set @@optimizer_switch=@save_optimizer_switch;
+
+--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:
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=off';
+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'
+ );
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1,t2,t3;
+
+--echo #
+--echo # BUG#47367 Crash in Name_resolution_context::process_error
+--echo #
+
+SET SESSION optimizer_switch = '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;
+
+
+--echo #
+--echo # fix of LP BUG#824425 (prohibiting subqueries in row in
+--echo # left part of IN/ALL/ANY)
+--echo #
+
+CREATE TABLE t1 ( a int) ;
+INSERT INTO t1 VALUES (20),(30);
+
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (3),(9);
+
+CREATE TABLE t3 ( a int, b int) ;
+INSERT INTO t3 VALUES (20,5),(30,6);
+
+set @optimizer_switch_save=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=OFF,in_to_exists=OFF,materialization=ON,partial_match_rowid_merge=ON,partial_match_table_scan=OFF';
+
+SELECT * FROM t1
+WHERE (
+ ( SELECT a FROM t2 WHERE a = 9 )
+) NOT IN (
+ SELECT b
+ FROM t3
+);
+explain extended
+SELECT * FROM t1
+WHERE (
+ ( SELECT a FROM t2 WHERE a = 9 )
+) NOT IN (
+ SELECT b
+ FROM t3
+);
+
+--error ER_NOT_SUPPORTED_YET
+SELECT * FROM t1
+WHERE (
+ ( SELECT a FROM t2 WHERE a = 9 ),
+ ( SELECT a FROM t2 WHERE a = 3 )
+) NOT IN (
+ SELECT b , a
+ FROM t3
+);
+set optimizer_switch=@optimizer_switch_save;
+
+drop table t1,t2,t3;
+
+# The following command must be the last one the file
+set @@optimizer_switch=@subselect3_tmp;
diff --git a/mysql-test/t/subselect3_jcl6.test b/mysql-test/t/subselect3_jcl6.test
new file mode 100644
index 00000000000..e4b1c144b93
--- /dev/null
+++ b/mysql-test/t/subselect3_jcl6.test
@@ -0,0 +1,22 @@
+#
+# Run subselect3.test with BKA enabled
+#
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+set @join_cache_level_for_subselect3_test=@@join_cache_level;
+
+--source t/subselect3.test
+
+set join_cache_level=default;
+show variables like 'join_cache_level';
+
+set @@optimizer_switch=@save_optimizer_switch;
+set @join_cache_level_for_subselect3_test=NULL;
diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test
index 3de2dfc394e..51247e2c3ea 100644
--- a/mysql-test/t/subselect4.test
+++ b/mysql-test/t/subselect4.test
@@ -1,5 +1,13 @@
# General purpose bug fix tests go here : subselect.test too large
+--disable_warnings
+drop table if exists t1,t2,t3,t4,t5,t6;
+--enable_warnings
+
+set @subselect4_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='semijoin_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
--echo #
--echo # Bug #46791: Assertion failed:(table->key_read==0),function unknown
@@ -117,6 +125,9 @@ INSERT INTO t4 VALUES (1), (2), (3);
CREATE TABLE t5 ( a INT );
INSERT INTO t5 VALUES (NULL), (2);
+SET @old_optimizer_switch = @@session.optimizer_switch;
+SET SESSION optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off';
+
--replace_column 1 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x
EXPLAIN
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 );
@@ -158,6 +169,8 @@ SELECT * FROM t1 WHERE b NOT IN ( SELECT c FROM t2 WHERE c = 1 );
SELECT * FROM t1 WHERE NULL NOT IN ( SELECT c FROM t2 WHERE c = 1 AND c <> 1 );
+SET SESSION optimizer_switch = @old_optimizer_switch;
+
DROP TABLE t1, t2, t3, t4, t5;
--echo #
@@ -217,3 +230,1687 @@ drop table t1, t2a, t2b, t2c;
--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_engine_condition_pushdown = @@session.engine_condition_pushdown;
+
+SET SESSION OPTIMIZER_SWITCH = 'materialization=off,semijoin=off,loosescan=off,firstmatch=off,mrr=on';
+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.engine_condition_pushdown = @old_engine_condition_pushdown;
+
+DROP TABLE t1;
+
+--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,in_to_exists=off,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;
+
+--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,in_to_exists=off,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#716293: "Range checked for each record" is not used if condition refers to outside of subquery
+--echo #
+
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, b int, `filler` char(200), key(a), key (b));
+insert into t2
+ select A.a + 10*B.a + 100 * C.a, A.a + 10*B.a + 100 * C.a, 'filler' from t1 A, t1 B, t1 C;
+
+--echo # The following must use "Range checked for each record" for table B
+explain
+select a,
+ (select sum(X.a+B.b) from t1 X, t2 B where B.a=A.a or B.b=A.a)
+from t1 A;
+drop table t1, t2;
+
+
+--echo #
+--echo # BUG#723822: Crash in get_constant_key_infix with EXISTS ( SELECT .. DISTINCT )
+--echo #
+CREATE TABLE t1 ( f1 int(11), f3 varchar(1)) ;
+INSERT INTO t1 VALUES ('8','c'),('5','f');
+
+ALTER TABLE t1 ADD KEY (f3,f1);
+
+CREATE TABLE t2 ( f4 varchar(1)) ;
+INSERT INTO t2 VALUES ('f'),('d');
+
+SELECT * FROM t2
+WHERE EXISTS (
+ SELECT DISTINCT f3
+ FROM t1
+ WHERE f3 <= t2.f4
+);
+
+drop table t1,t2;
+
+--echo #
+--echo # LP BUG#718763 Second crash in select_describe() and materialization
+--echo #
+
+CREATE TABLE t1 ( f1 int(11), f3 int(11), f10 varchar(1), KEY (f3)) ;
+INSERT INTO t1 VALUES ('28','6','m'),('29','4','c');
+
+CREATE TABLE t2 (f11 varchar(1)) ;
+INSERT INTO t2 VALUES ('f'),('d');
+
+SET @old_optimizer_switch = @@session.optimizer_switch;
+SET @@optimizer_switch = 'materialization=on,in_to_exists=off,semijoin=off';
+
+EXPLAIN
+SELECT * FROM t1
+WHERE f3 = (
+ SELECT t1.f3 FROM t1
+ WHERE ( t1.f10 ) IN ( SELECT max(f11) FROM t2 GROUP BY f11 ));
+SELECT * FROM t1
+WHERE f3 = (
+ SELECT t1.f3 FROM t1
+ WHERE ( t1.f10 ) IN ( SELECT max(f11) FROM t2 GROUP BY f11 ));
+
+EXPLAIN
+SELECT * FROM t1
+WHERE f3 = (
+ SELECT f3 FROM t1
+ WHERE ( f10, f10 ) IN ( SELECT max(f11), f11 FROM t2 GROUP BY f11 ));
+SELECT * FROM t1
+WHERE f3 = (
+ SELECT f3 FROM t1
+ WHERE ( f10, f10 ) IN ( SELECT max(f11), f11 FROM t2 GROUP BY f11 ));
+
+SET SESSION optimizer_switch = @old_optimizer_switch;
+drop table t1,t2;
+
+--echo #
+--echo # LP BUG#715738: Wrong result with implicit grouping and empty result set
+--echo #
+
+CREATE TABLE t1 (f1 int, f2 int);
+CREATE TABLE t2 (f3 int, f4 int not null, PRIMARY KEY (f3));
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+SET @@optimizer_switch = 'materialization=on,in_to_exists=off,semijoin=off';
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2);
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2) as not_in;
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2);
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) > 7) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) > 7) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) is null) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) is null) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2) as not_in;
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2) as not_in;
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2) as not_in;
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2);
+
+
+SET @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off';
+
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2);
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2) as not_in;
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2);
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) > 7) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) > 7) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) is null) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) is null) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2) as not_in;
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2) as not_in;
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2) as not_in;
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2);
+
+
+INSERT INTO t1 VALUES (1, 2);
+INSERT INTO t1 VALUES (3, 4);
+INSERT INTO t2 VALUES (5, 6);
+INSERT INTO t2 VALUES (7, 8);
+
+SET @@optimizer_switch = 'materialization=on,in_to_exists=off,semijoin=off';
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2 WHERE f3 > 10);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2 WHERE f3 > 10);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2 WHERE f3 > 10);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2 WHERE f3 > 10);
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10) as not_in;
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2 WHERE f3 > 10);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2 WHERE f3 > 10);
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) > 7) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) > 7) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) is null) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) is null) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2 WHERE f3 > 10) as not_in;
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2 WHERE f3 > 10) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2 WHERE f3 > 10) as not_in;
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2 WHERE f3 > 10) as not_in;
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10);
+
+SET @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off';
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2 WHERE f3 > 10);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2 WHERE f3 > 10);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2 WHERE f3 > 10);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2 WHERE f3 > 10);
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10) as not_in;
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2 WHERE f3 > 10);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2 WHERE f3 > 10);
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) > 7) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) > 7) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) is null) as not_in;
+SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) is null) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2 WHERE f3 > 10) as not_in;
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2 WHERE f3 > 10) as not_in;
+
+EXPLAIN
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2 WHERE f3 > 10) as not_in;
+SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2 WHERE f3 > 10) as not_in;
+
+EXPLAIN
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10);
+SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10);
+
+set @@optimizer_switch=@save_optimizer_switch;
+
+drop table t1,t2;
+
+--echo #
+--echo # LP BUG#613029 Wrong result with materialization and semijoin, and
+--echo # valgrind warnings in Protocol::net_store_data with materialization
+--echo # for implicit grouping
+--echo #
+
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ f2 int(11) NOT NULL,
+ f3 varchar(1) NOT NULL,
+ PRIMARY KEY (pk),
+ KEY f2 (f2));
+
+INSERT INTO t1 VALUES (1,9,'x');
+INSERT INTO t1 VALUES (2,5,'g');
+
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ f2 int(11) NOT NULL,
+ f3 varchar(1) NOT NULL,
+ PRIMARY KEY (pk),
+ KEY f2 (f2));
+
+INSERT INTO t2 VALUES (1,7,'p');
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off';
+
+EXPLAIN
+SELECT t1.f3, MAX(t1.f2)
+FROM t1, t2
+WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1);
+
+SELECT t1.f3, MAX(t1.f2)
+FROM t1, t2
+WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1);
+
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+
+EXPLAIN
+SELECT t1.f3, MAX(t1.f2)
+FROM t1, t2
+WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1);
+
+SELECT t1.f3, MAX(t1.f2)
+FROM t1, t2
+WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1);
+
+-- echo TODO: add a test case for semijoin when the wrong result is fixed
+-- echo set @@optimizer_switch='materialization=off,semijoin=on';
+
+
+set @@optimizer_switch=@save_optimizer_switch;
+
+drop table t1, t2;
+
+
+--echo #
+--echo # LP BUG#777691 Wrong result with subqery in select list and subquery cache=off in maria-5.3
+--echo #
+
+CREATE TABLE t1 ( f1 varchar(32)) ;
+INSERT INTO t1 VALUES ('b'),('x'),('c'),('x');
+
+CREATE TABLE t2 ( f2 int, f3 varchar(32)) ;
+INSERT INTO t2 VALUES (1,'x');
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off';
+
+EXPLAIN
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+
+set @@optimizer_switch='materialization=on,in_to_exists=off,subquery_cache=off';
+EXPLAIN
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+
+set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off';
+--echo Even when t2 is not constant table, the result must be the same.
+INSERT INTO t2 VALUES (2,'y');
+EXPLAIN
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+
+set @@optimizer_switch=@save_optimizer_switch;
+
+drop table t1, t2;
+
+--echo #
+--echo # LP BUG#641203 Query returns rows where no result is expected (impossible WHERE)
+--echo #
+
+CREATE TABLE t1 (c1 varchar(1) DEFAULT NULL);
+CREATE TABLE t2 (c1 varchar(1) DEFAULT NULL);
+INSERT INTO t2 VALUES ('k'), ('d');
+CREATE TABLE t3 (c1 varchar(1) DEFAULT NULL);
+INSERT INTO t3 VALUES ('a'), ('b'), ('c');
+CREATE TABLE t4 (c1 varchar(1) primary key);
+INSERT INTO t4 VALUES ('k'), ('d');
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+SET optimizer_switch='semijoin_with_cache=off';
+
+SET optimizer_switch='materialization=off';
+EXPLAIN
+SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
+SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
+EXPLAIN
+SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
+SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
+SET optimizer_switch='materialization=on';
+EXPLAIN
+SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2);
+SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2);
+EXPLAIN
+SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2);
+SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2);
+
+SET optimizer_switch=@save_optimizer_switch;
+
+drop table t1, t2, t3, t4;
+
+--echo #
+--echo # LP BUG#675981 Assertion `cache != __null' failed in sub_select_cache()
+--echo # on EXPLAIN
+--echo #
+
+CREATE TABLE t1 (f1 int,f2 int) ;
+INSERT IGNORE INTO t1 VALUES ('2','5'),('2',NULL);
+
+CREATE TABLE t2 (f1 int, f5 int) ;
+INSERT IGNORE INTO t2 VALUES (1,0);
+
+CREATE TABLE t3 (f4 int) ;
+INSERT IGNORE INTO t3 VALUES (0),(0);
+
+set @@optimizer_switch='in_to_exists=on,materialization=off,semijoin=off';
+EXPLAIN
+SELECT * FROM t2
+WHERE f1 IN (SELECT t1.f2 FROM t1 JOIN t3 ON t3.f4);
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # LP BUG#680005 Second assertion `cache != __null' failed in
+--echo # sub_select_cache() on EXPLAIN
+--echo #
+
+CREATE TABLE t1 (f1 int,f2 int,f4 int,f6 int,KEY (f4)) ;
+INSERT IGNORE INTO t1 VALUES
+('1','5','1','0'),('2','1','1','0'),('2','2','2','0'),('0',NULL,'0','0'),
+('2','1','2','0'),('2','0','0','0'),('2','2','2','0'),('2','8','2','0'),
+('2','7','2','0'),('2','5','2','0'),('2',NULL,'1','0');
+
+CREATE TABLE t2 (f3 int) ;
+INSERT IGNORE INTO t2 VALUES ('7');
+
+CREATE TABLE t3 (f3 int) ;
+INSERT IGNORE INTO t3 VALUES ('2');
+
+EXPLAIN
+SELECT t1.f4
+FROM t2 JOIN t1 ON t1.f6
+WHERE
+( t1.f2 ) IN (SELECT SUBQUERY2_t1.f3
+ FROM t3 AS SUBQUERY2_t1
+ JOIN
+ (t1 AS SUBQUERY2_t2
+ JOIN
+ t1 AS SUBQUERY2_t3 ON SUBQUERY2_t3.f1)
+ ON SUBQUERY2_t3.f2)
+GROUP BY t1.f4 ORDER BY t1.f1 LIMIT 10;
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # LP BUG#680038 bool close_thread_table(THD*, TABLE**):
+--echo # Assertion `table->key_read == 0' failed in EXPLAIN
+--echo #
+
+CREATE TABLE t1 (f1 int,f3 int,f4 int) ;
+INSERT IGNORE INTO t1 VALUES (NULL,1,0);
+
+CREATE TABLE t2 (f2 int,f4 int,f5 int) ;
+INSERT IGNORE INTO t2 VALUES (8,0,0),(5,0,0);
+
+CREATE TABLE t3 (f4 int,KEY (f4)) ;
+INSERT IGNORE INTO t3 VALUES (0),(0);
+
+set @@optimizer_switch='semijoin=off';
+
+EXPLAIN
+SELECT * FROM t1 WHERE
+(SELECT f2 FROM t2
+ WHERE f4 <= ALL
+ (SELECT max(SQ1_t1.f4)
+ FROM t3 AS SQ1_t1 JOIN t3 AS SQ1_t3 ON SQ1_t3.f4
+ GROUP BY SQ1_t1.f4));
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # BUG#52317: Assertion failing in Field_varstring::store()
+--echo # at field.cc:6833
+--echo #
+
+CREATE TABLE t1 (i INTEGER);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (i INTEGER, KEY k(i));
+INSERT INTO t2 VALUES (1), (2);
+
+EXPLAIN
+SELECT i FROM t1 WHERE (1) NOT IN (SELECT i FROM t2);
+
+DROP TABLE t2;
+DROP TABLE t1;
+
+--echo #
+--echo # LP BUG#680846: Crash in clear_tables() with subqueries
+--echo #
+
+CREATE TABLE t1 (f3 int) ;
+INSERT IGNORE INTO t1 VALUES (0),(0);
+
+CREATE TABLE t2 (f1 int,f3 int,f4 varchar(32)) ;
+INSERT IGNORE INTO t2 VALUES (1,0,'f');
+
+EXPLAIN
+SELECT COUNT(t2.f3),
+ (SELECT COUNT(f3) FROM t1 WHERE t2.f1) AS f9
+FROM t2 JOIN t1 ON t1.f3
+WHERE ('v') IN (SELECT f4 FROM t2)
+GROUP BY f9;
+
+SELECT COUNT(t2.f3),
+ (SELECT COUNT(f3) FROM t1 WHERE t2.f1) AS f9
+FROM t2 JOIN t1 ON t1.f3
+WHERE ('v') IN (SELECT f4 FROM t2)
+GROUP BY f9;
+
+EXPLAIN
+SELECT COUNT(t2.f3),
+ (SELECT COUNT(f3) FROM t1 WHERE t2.f1) AS f9
+FROM t2 JOIN t1 ON t1.f3
+WHERE ('v') IN (SELECT f4 FROM t2)
+ORDER BY f9;
+
+SELECT COUNT(t2.f3),
+ (SELECT COUNT(f3) FROM t1 WHERE t2.f1) AS f9
+FROM t2 JOIN t1 ON t1.f3
+WHERE ('v') IN (SELECT f4 FROM t2)
+ORDER BY f9;
+
+# these queries are like the ones above, but without the ON clause,
+# resulting in a different crash (failed assert)
+EXPLAIN
+SELECT COUNT(t2.f3),
+ (SELECT t2.f1 FROM t1 limit 1) AS f9
+FROM t2 JOIN t1
+WHERE ('v') IN (SELECT f4 FROM t2)
+GROUP BY f9;
+
+SELECT COUNT(t2.f3),
+ (SELECT t2.f1 FROM t1 limit 1) AS f9
+FROM t2 JOIN t1
+WHERE ('v') IN (SELECT f4 FROM t2)
+GROUP BY f9;
+
+EXPLAIN
+SELECT COUNT(t2.f3),
+ (SELECT t2.f1 FROM t1 limit 1) AS f9
+FROM t2 JOIN t1
+WHERE ('v') IN (SELECT f4 FROM t2)
+ORDER BY f9;
+
+SELECT COUNT(t2.f3),
+ (SELECT t2.f1 FROM t1 limit 1) AS f9
+FROM t2 JOIN t1
+WHERE ('v') IN (SELECT f4 FROM t2)
+ORDER BY f9;
+
+drop table t1,t2;
+
+--echo #
+--echo # LP BUG#682683 Crash in create_tmp_table called from
+--echo # JOIN::init_execution
+--echo #
+
+CREATE TABLE t2 (f1 int) ;
+INSERT INTO t2 VALUES (1),(2);
+
+CREATE TABLE t1 (f1 int) ;
+
+EXPLAIN
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
+EXPLAIN
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
+
+INSERT INTO t1 VALUES (1),(2);
+
+EXPLAIN
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
+--error ER_SUBQUERY_NO_1_ROW
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
+EXPLAIN
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
+--error ER_SUBQUERY_NO_1_ROW
+SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
+
+drop table t1,t2;
+
+--echo #
+--echo # LP BUG#680943 Assertion `!table || (!table->read_set ||
+--echo # bitmap_is_set(table->read_set, field_index))' failed with subquery
+--echo #
+
+CREATE TABLE t1 (f1 int,f3 int) ;
+INSERT IGNORE INTO t1 VALUES ('6','0'),('4','0');
+
+CREATE TABLE t2 (f1 int,f2 int,f3 int) ;
+INSERT IGNORE INTO t2 VALUES ('6','0','0'),('2','0','0');
+
+SELECT f2
+FROM (SELECT * FROM t2) AS alias1
+WHERE (SELECT SQ2_t2.f1
+ FROM t1 JOIN t1 AS SQ2_t2 ON SQ2_t2.f3
+ WHERE SQ2_t2.f3 AND alias1.f1)
+ORDER BY f3 ;
+
+drop table t1,t2;
+
+--echo #
+--echo # LP BUG#715062: Wrong result with VIEW + UNION + subquery in maria-5.3-mwl89
+--echo #
+
+create table t1 (f1 int);
+create table t2 (f2 int);
+create table t3 (f3 int);
+insert into t1 values (2);
+insert into t2 values (2);
+insert into t3 values (7);
+
+CREATE VIEW v1 AS SELECT 2 UNION SELECT 2 ;
+CREATE VIEW v2 AS SELECT * from t1 UNION SELECT * from t2 ;
+
+set @save_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch = 'in_to_exists=off,semijoin=off,materialization=on';
+
+EXPLAIN
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 );
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 );
+
+EXPLAIN
+SELECT ( 5 ) IN ( SELECT * FROM v1 );
+SELECT ( 5 ) IN ( SELECT * FROM v1 );
+
+EXPLAIN
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2);
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2);
+
+EXPLAIN
+SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2);
+SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2);
+
+EXPLAIN
+SELECT ( 5 ) IN ( SELECT * FROM v2 );
+SELECT ( 5 ) IN ( SELECT * FROM v2 );
+
+SET @@optimizer_switch = 'in_to_exists=on,semijoin=off,materialization=off';
+
+EXPLAIN
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 );
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 );
+
+EXPLAIN
+SELECT ( 5 ) IN ( SELECT * FROM v1 );
+SELECT ( 5 ) IN ( SELECT * FROM v1 );
+
+EXPLAIN
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2);
+SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2);
+
+EXPLAIN
+SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2);
+SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2);
+
+EXPLAIN
+SELECT ( 5 ) IN ( SELECT * FROM v2 );
+SELECT ( 5 ) IN ( SELECT * FROM v2 );
+
+set @@optimizer_switch=@save_optimizer_switch;
+
+drop table t1,t2,t3;
+drop view v1,v2;
+
+--echo #
+--echo # LP BUG#715069 Wrong result with GROUP BY inside subquery and materialization=off
+--echo #
+
+CREATE TABLE t0 ( f1 int(11), f2 int(11), f10 varchar(1), PRIMARY KEY (f1)) ;
+INSERT INTO t0 VALUES (8,8,'u'),(10,5,'o');
+
+CREATE TABLE t1 (f1a int, f2a int not null, f3a varchar(3) not null, PRIMARY KEY (f1a)) ;
+INSERT INTO t1 VALUES
+(8,8,'a1a'),
+(10,5,'b1b');
+
+CREATE TABLE t2 (f1b int, f2b int not null, f3b varchar(3) not null, PRIMARY KEY (f1b)) ;
+INSERT INTO t2 VALUES
+(10,5,'d1d');
+
+set @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
+set @@optimizer_switch = 'in_to_exists=on,materialization=off,semijoin=off';
+
+EXPLAIN
+SELECT alias2.f1 , alias2.f2
+FROM t0 AS alias1
+RIGHT JOIN t0 AS alias2 ON alias2.f10
+WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT max(f2) , f1 FROM t0 GROUP BY f2 , f1 );
+
+SELECT alias2.f1 , alias2.f2
+FROM t0 AS alias1
+RIGHT JOIN t0 AS alias2 ON alias2.f10
+WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT max(f2) , f1 FROM t0 GROUP BY f2 , f1 );
+
+EXPLAIN
+SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT max(f1a), f2a FROM t1 GROUP BY f1a, f2a);
+SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT max(f1a), f2a FROM t1 GROUP BY f1a, f2a);
+
+EXPLAIN
+SELECT * FROM t2 WHERE (f1b) IN (SELECT max(f1a) FROM t1 GROUP BY f1a, f2a);
+SELECT * FROM t2 WHERE (f1b) IN (SELECT max(f1a) FROM t1 GROUP BY f1a, f2a);
+
+set @@optimizer_switch = 'in_to_exists=off,materialization=on,semijoin=off';
+
+EXPLAIN
+SELECT alias2.f1 , alias2.f2
+FROM t0 AS alias1
+RIGHT JOIN t0 AS alias2 ON alias2.f10
+WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT max(f2) , f1 FROM t0 GROUP BY f2 , f1 );
+
+SELECT alias2.f1 , alias2.f2
+FROM t0 AS alias1
+RIGHT JOIN t0 AS alias2 ON alias2.f10
+WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT max(f2) , f1 FROM t0 GROUP BY f2 , f1 );
+
+EXPLAIN
+SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT max(f1a), f2a FROM t1 GROUP BY f1a, f2a);
+SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT max(f1a), f2a FROM t1 GROUP BY f1a, f2a);
+
+EXPLAIN
+SELECT * FROM t2 WHERE (f1b) IN (SELECT max(f1a) FROM t1 GROUP BY f1a, f2a);
+SELECT * FROM t2 WHERE (f1b) IN (SELECT max(f1a) FROM t1 GROUP BY f1a, f2a);
+
+set @@optimizer_switch=@save_optimizer_switch;
+
+drop table t0,t1,t2;
+
+
+--echo #
+--echo # LP BUG#715759 Wrong result with in_to_exists=on in maria-5.3-mwl89
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (a1 int, a2 int) ;
+INSERT INTO t1 VALUES (1, 2);
+INSERT INTO t1 VALUES (3, 4);
+
+CREATE TABLE t2 (b1 int, b2 int) ;
+INSERT INTO t2 VALUES (1, 2);
+
+SET @@optimizer_switch = 'in_to_exists=on,materialization=off,semijoin=off';
+
+EXPLAIN SELECT * FROM t1 WHERE a1 IN (SELECT b1 FROM t2 WHERE b1 = b2);
+SELECT * FROM t1 WHERE a1 IN (SELECT b1 FROM t2 WHERE b1 = b2);
+
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t2;
+
+--echo #
+--echo # LP BUG#772309 join_tab_cmp_straight(): Assertion `!jt2->emb_sj_nest' failed in maria-5.3-mwl89 with semijoin
+--echo #
+
+CREATE TABLE t1 ( f2 int) ;
+INSERT INTO t1 VALUES (0),(0);
+
+CREATE TABLE t2 ( f1 int NOT NULL ) ;
+INSERT INTO t2 VALUES (0),(0);
+
+CREATE TABLE t3 ( f1 int NOT NULL , f2 int) ;
+INSERT INTO t3 VALUES (0,0), (0,0);
+
+EXPLAIN SELECT STRAIGHT_JOIN (
+ SELECT f2 FROM t1 WHERE ( f2 ) IN ( SELECT t3.f2 FROM t3 JOIN t2 ON t2.f1 = 1 )
+);
+SELECT STRAIGHT_JOIN (
+ SELECT f2 FROM t1 WHERE ( f2 ) IN ( SELECT t3.f2 FROM t3 JOIN t2 ON t2.f1 = 1 )
+);
+
+drop table t1, t2, t3;
+
+
+--echo #
+--echo # LP BUG#777597 Wrong result with multipart keys, in_to_exists=on, NOT IN in MWL#89
+--echo #
+
+CREATE TABLE t1 ( f4 int);
+INSERT IGNORE INTO t1 VALUES (2),(2);
+
+CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3) );
+INSERT IGNORE INTO t2 VALUES (6, 1), (6, 1);
+
+CREATE TABLE t3 ( f10 int );
+INSERT IGNORE INTO t3 VALUES (1);
+
+SET SESSION optimizer_switch='in_to_exists=on,materialization=off';
+
+EXPLAIN
+SELECT * FROM t1 WHERE ( 6 ) NOT IN ( SELECT t2.f3 FROM t2 JOIN t3 ON t3.f10 = t2.f10);
+SELECT * FROM t1 WHERE ( 6 ) NOT IN ( SELECT t2.f3 FROM t2 JOIN t3 ON t3.f10 = t2.f10);
+
+drop table t1,t2,t3;
+
+
+--echo #
+--echo # LP BUG#778413 Third crash in select_describe() in maria-5.3-mwl89
+--echo #
+
+CREATE TABLE t1 ( f11 int) ;
+INSERT INTO t1 VALUES (1),(1);
+
+CREATE TABLE t2 ( f1 int NOT NULL) ;
+INSERT INTO t2 VALUES (20);
+
+CREATE TABLE t3 (f3 int) ;
+INSERT INTO t3 VALUES (2),(2);
+
+EXPLAIN SELECT * FROM t2
+WHERE t2.f1 = (
+ SELECT MAX( f3 ) FROM t3
+ WHERE EXISTS (
+ SELECT DISTINCT f11
+ FROM t1));
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # LP BUG#802979 Assertion `table->key_read == 0' in close_thread_table
+--echo #
+
+CREATE TABLE t1 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t1 VALUES (1,0),(5,0);
+CREATE TABLE t2 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t2 VALUES (1,0),(5,0);
+CREATE TABLE t3 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES (1,0),(5,0);
+CREATE TABLE t4 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t4 VALUES (1,0),(5,0);
+
+EXPLAIN
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+ WHERE EXISTS (SELECT DISTINCT f1 FROM t4))
+ AND t2.f2 = t1.f1;
+
+-- error ER_SUBQUERY_NO_1_ROW
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+ WHERE EXISTS (SELECT DISTINCT f1 FROM t4))
+ AND t2.f2 = t1.f1;
+
+EXPLAIN
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+ WHERE EXISTS (SELECT DISTINCT f1 FROM t4) LIMIT 1)
+ AND t2.f2 = t1.f1;
+
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+ WHERE EXISTS (SELECT DISTINCT f1 FROM t4) LIMIT 1)
+ AND t2.f2 = t1.f1;
+
+drop table t1,t2,t3,t4;
+
+--echo #
+--echo # LP BUG#611690 Crash in select_describe() with nested subqueries
+--echo #
+
+CREATE TABLE t1 (
+ col_int_key int(11) DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL,
+ KEY col_int_key (col_int_key),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (8,'v','v');
+INSERT INTO t1 VALUES (9,'r','r');
+
+CREATE TABLE t2 (
+ col_int_key int(11) DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL,
+ KEY col_int_key (col_int_key),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (2,'w','w');
+INSERT INTO t2 VALUES (9,'m','m');
+
+set @old_optimizer_switch = @@optimizer_switch;
+
+set @@optimizer_switch='subquery_cache=off,materialization=on,in_to_exists=off,semijoin=off';
+EXPLAIN
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+ FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ ON SUBQUERY2_t2.col_varchar_key
+ WHERE SUBQUERY2_t2.col_varchar_nokey IN
+ (SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+ FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ ON SUBQUERY2_t2.col_varchar_key
+ WHERE SUBQUERY2_t2.col_varchar_nokey IN
+ (SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+
+set @@optimizer_switch='subquery_cache=off,materialization=off,in_to_exists=on,semijoin=off';
+EXPLAIN
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+ FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ ON SUBQUERY2_t2.col_varchar_key
+ WHERE SUBQUERY2_t2.col_varchar_nokey IN
+ (SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+ FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ ON SUBQUERY2_t2.col_varchar_key
+ WHERE SUBQUERY2_t2.col_varchar_nokey IN
+ (SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+
+drop table t1, t2;
+
+set @@optimizer_switch = @old_optimizer_switch;
+
+
+--echo #
+--echo # LP BUG#612543 Crash in Item_field::used_tables() with view + subquery + prepared statements
+--echo #
+
+CREATE TABLE t1 ( f1 int(11), f2 varchar(1));
+CREATE TABLE t2 ( f3 varchar(1));
+insert into t1 values (2,'x'), (5,'y');
+insert into t2 values ('x'), ('z');
+CREATE VIEW v2 AS SELECT * FROM t2;
+
+set @old_optimizer_switch = @@optimizer_switch;
+
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 );
+PREPARE st1 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )";
+EXECUTE st1;
+EXECUTE st1;
+
+set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 );
+PREPARE st2 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )";
+EXECUTE st2;
+EXECUTE st2;
+
+set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 );
+PREPARE st3 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )";
+EXECUTE st3;
+EXECUTE st3;
+
+set @@optimizer_switch = @old_optimizer_switch;
+
+drop table t1, t2;
+drop view v2;
+
+
+--echo #
+--echo # LP BUG#611396 RQG: crash in Item_field::register_field_in_read_map with semijoin=off
+--echo # and prepared statements and materialization
+
+CREATE TABLE t1 ( f1 int(11), f2 int(11)) ;
+CREATE TABLE t2 ( f1 int(11), f4 varchar(1), PRIMARY KEY (f1)) ;
+INSERT INTO t2 VALUES ('23','j'),('24','e');
+CREATE TABLE t3 ( f1 int(11), f4 varchar(1)) ;
+INSERT INTO t3 VALUES ('8','j');
+
+set @old_optimizer_switch = @@optimizer_switch;
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+
+EXPLAIN
+SELECT t2.f1, (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1))
+FROM t2 JOIN t3 ON t3.f4 = t2.f4
+WHERE t3.f1 = 8
+GROUP BY 1, 2;
+
+PREPARE st1 FROM "
+SELECT t2.f1, (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1))
+FROM t2 JOIN t3 ON t3.f4 = t2.f4
+WHERE t3.f1 = 8
+GROUP BY 1, 2";
+
+EXECUTE st1;
+EXECUTE st1;
+
+set @@optimizer_switch = @old_optimizer_switch;
+
+drop table t1, t2, t3;
+
+
+--echo #
+--echo # LP BUG#611382 RQG: Query returns extra rows when executed with materialization=on
+--echo #
+
+CREATE TABLE t1 ( f4 varchar(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2 ( f2 date, f3 varchar(1), f4 varchar(1)) ;
+INSERT INTO t2 VALUES ('2005-05-03','c','c'),('1900-01-01','d','d');
+CREATE TABLE t3 ( f3 varchar(1)) ;
+INSERT INTO t3 VALUES ('c');
+
+set @old_optimizer_switch = @@optimizer_switch;
+
+set @@optimizer_switch = 'materialization=on,in_to_exists=off,semijoin=off';
+
+EXPLAIN SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+
+SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+
+set @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off';
+
+EXPLAIN SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+
+SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+
+set @@optimizer_switch = @old_optimizer_switch;
+
+drop table t1, t2, t3;
+
+
+--echo #
+--echo # LP BUG#782305: Wrong result/valgrind warning in Item_sum_hybrid::any_value()
+--echo #
+
+CREATE TABLE t1 ( f1 int) ;
+INSERT INTO t1 VALUES (2),(3);
+CREATE TABLE t2 (f2 int) ;
+INSERT INTO t2 VALUES (2),(3);
+
+PREPARE st1 FROM '
+SELECT * FROM t2
+WHERE f2 <= SOME ( SELECT f1 FROM t1 );
+';
+EXECUTE st1;
+EXECUTE st1;
+
+PREPARE st2 FROM '
+SELECT * FROM t2
+WHERE f2 <= SOME (SELECT f1-2 FROM t1 UNION SELECT f1-1 FROM t1);
+';
+EXECUTE st2;
+EXECUTE st2;
+
+drop table t1, t2;
+
+--echo #
+--echo # LP BUG#825018: Crash in check_and_do_in_subquery_rewrites() with corrlated subquery in select list
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (10,1),(11,7);
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (2),(3);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (1,1);
+
+CREATE PROCEDURE sp1 () LANGUAGE SQL
+SELECT (SELECT t1.a
+ FROM t1
+ WHERE t1.b = t3.b
+ AND t1.b IN ( SELECT a FROM t2 )) sq
+FROM t3
+GROUP BY 1;
+CALL sp1();
+CALL sp1();
+drop procedure sp1;
+
+prepare st1 from "
+SELECT (SELECT t1.a
+ FROM t1
+ WHERE t1.b = t3.b
+ AND t1.b IN ( SELECT a FROM t2 )) sq
+FROM t3
+GROUP BY 1";
+execute st1;
+execute st1;
+deallocate prepare st1;
+
+drop table t1, t2, t3;
+
+set optimizer_switch=@subselect4_tmp;
+
+--echo #
+--echo # LP BUG#833702 Wrong result with nested IN and singlerow subqueries and equality propagation
+--echo #
+
+CREATE TABLE t2 (c int , a int, b int);
+INSERT INTO t2 VALUES (10,7,0);
+
+CREATE TABLE t3 (a int, b int) ;
+INSERT INTO t3 VALUES (5,0),(7,0);
+
+CREATE TABLE t4 (a int);
+INSERT INTO t4 VALUES (2),(8);
+
+set @@optimizer_switch='semijoin=off,in_to_exists=on,materialization=off,subquery_cache=off';
+
+SELECT * FROM t2
+WHERE t2.b IN (SELECT b FROM t3 WHERE t3.a = t2.a AND a < SOME (SELECT * FROM t4))
+ OR ( t2.c > 242 );
+
+EXPLAIN SELECT * FROM t2
+WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.a < ANY (SELECT t4.a FROM t4) and t3.a = 7);
+SELECT * FROM t2
+WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.a < ANY (SELECT t4.a FROM t4) and t3.a = 7);
+
+drop table t2, t3, t4;
+
+--echo #
+--echo # BUG#934597: Assertion `! is_set()' failed in Diagnostics_area::set_ok_status(THD...
+--echo #
+CREATE TABLE t1 ( a VARCHAR(1) );
+INSERT INTO t1 VALUES ('u'),('k');
+--error ER_SUBQUERY_NO_1_ROW
+CREATE TABLE t2 AS
+ SELECT a AS field1 FROM t1
+ WHERE ( SELECT alias1.a
+ FROM t1 AS alias1
+ ) IS NOT NULL;
+--error ER_BAD_TABLE_ERROR
+DROP TABLE t2;
+DROP TABLE t1;
+
+--echo #
+--echo # LP BUG#1000649 EXPLAIN shows incorrectly a non-correlated constant IN subquery is correlated
+--echo #
+
+create table ten (a int);
+insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, c int);
+insert into t1 select a,a,a from ten;
+create table five (a int, b int, c int);
+insert into five select a,a,a from ten limit 5;
+
+set @@optimizer_switch='semijoin=on,in_to_exists=on,materialization=off';
+explain select * from t1 where 33 in (select b from five) or c > 11;
+
+drop table ten, t1, five;
+
+--echo #
+--echo # LP BUG#1008773 Wrong result (NULL instead of a value) with no matching rows, subquery in FROM and HAVING
+--echo #
+
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1);
+
+EXPLAIN
+SELECT MAX(a), ( SELECT 1 FROM t2 ) AS bb FROM t1;
+SELECT MAX(a), ( SELECT 1 FROM t2 ) AS bb FROM t1;
+
+EXPLAIN
+SELECT MAX(a), 1 in ( SELECT b FROM t2 ) AS bb FROM t1;
+SELECT MAX(a), 1 in ( SELECT b FROM t2 ) AS bb FROM t1;
+
+EXPLAIN
+SELECT MAX(a), 1 >= ALL ( SELECT b FROM t2 ) AS bb FROM t1;
+SELECT MAX(a), 1 >= ALL ( SELECT b FROM t2 ) AS bb FROM t1;
+
+
+EXPLAIN
+SELECT MAX(a), ( SELECT 1 FROM t2 where b = a) AS bb FROM t1;
+SELECT MAX(a), ( SELECT 1 FROM t2 where b = a) AS bb FROM t1;
+
+EXPLAIN
+SELECT MAX(a), a in ( SELECT b FROM t2 ) AS bb FROM t1;
+SELECT MAX(a), a in ( SELECT b FROM t2 ) AS bb FROM t1;
+
+EXPLAIN
+SELECT MAX(a), a >= ALL ( SELECT b FROM t2 ) AS bb FROM t1;
+SELECT MAX(a), a >= ALL ( SELECT b FROM t2 ) AS bb FROM t1;
+
+drop table t1, t2;
+
+set optimizer_switch=@subselect4_tmp;
+
+--echo #
+--echo # MDEV-3928 Assertion `example' failed in Item_cache::is_expensive_processor with a 2-level IN subquery
+--echo #
+
+CREATE TABLE t1 (a1 INT, b1 TIME) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4,'21:22:34'),(6,'10:50:38');
+
+CREATE TABLE t2 (a2 INT, b2 TIME) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (8, '06:17:39');
+
+CREATE TABLE t3 (a3 INT, b3 TIME) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (1,'00:00:01'),(7,'00:00:02');
+
+EXPLAIN
+SELECT * FROM t1 WHERE a1 IN (
+ SELECT a2 FROM t2 WHERE a2 IN (
+ SELECT a3 FROM t3 WHERE b2 = b1 AND b2 <= b1 ORDER BY b3
+ )
+);
+
+SELECT * FROM t1 WHERE a1 IN (
+ SELECT a2 FROM t2 WHERE a2 IN (
+ SELECT a3 FROM t3 WHERE b2 = b1 AND b2 <= b1 ORDER BY b3
+ )
+);
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # MDEV-4056:Server crashes in Item_func_trig_cond::val_int
+--echo # with FROM and NOT IN subqueries, LEFT JOIN, derived_merge+in_to_exists
+--echo #
+
+set @optimizer_switch_MDEV4056 = @@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on,in_to_exists=on';
+
+CREATE TABLE t1 (a VARCHAR(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('x'),('d');
+
+CREATE TABLE t2 (pk INT PRIMARY KEY, b INT, c VARCHAR(1)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,2,'v'),(2,150,'v');
+
+SELECT * FROM t1 LEFT JOIN (
+ SELECT * FROM t2 WHERE ( pk, pk ) NOT IN (
+ SELECT MIN(b), SUM(pk) FROM t1
+ )
+) AS alias1 ON (a = c)
+WHERE b IS NULL OR a < 'u';
+
+drop table t1,t2;
+set @@optimizer_switch = @optimizer_switch_MDEV4056;
+
+
+
+SET optimizer_switch= @@global.optimizer_switch;
+set @@tmp_table_size= @@global.tmp_table_size;
diff --git a/mysql-test/t/subselect_cache.test b/mysql-test/t/subselect_cache.test
new file mode 100644
index 00000000000..0abd20cc50e
--- /dev/null
+++ b/mysql-test/t/subselect_cache.test
@@ -0,0 +1,1707 @@
+
+--disable_warnings
+drop table if exists t1,t2,t3,t4,t5;
+drop view if exists v1;
+--enable_warnings
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+SET optimizer_switch='semijoin_with_cache=off';
+
+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;
+
+set optimizer_switch='subquery_cache=on';
+#
+--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;
+
+--echo #
+--echo # Test aggregate functions as parameters to subquery cache
+--echo #
+
+CREATE TABLE t1 ( a INT, b INT, c INT, KEY (a, b));
+
+INSERT INTO t1 VALUES
+ ( 1, 1, 1 ),
+ ( 1, 2, 2 ),
+ ( 1, 3, 3 ),
+ ( 1, 4, 6 ),
+ ( 1, 5, 5 ),
+ ( 1, 9, 13 ),
+
+ ( 2, 1, 6 ),
+ ( 2, 2, 7 ),
+ ( 2, 3, 8 );
+
+SELECT a, AVG(t1.b),
+(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c
+FROM t1 GROUP BY a;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Test of LP BUG#800696 (deleting list of Items (OR arguments)
+--echo # in optimization)
+--echo #
+
+set optimizer_switch='subquery_cache=on,in_to_exists=on';
+CREATE TABLE t1 ( f3 int) ;
+INSERT INTO t1 VALUES (0),(0);
+
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+
+CREATE TABLE t2 ( f1 int, f2 int, f3 int) ;
+INSERT INTO t2 VALUES (7,0,0);
+
+SELECT *
+FROM t2, t3
+WHERE t2.f2 OR t3.f3 IN
+(
+SELECT t2.f2
+FROM t1
+WHERE t2.f1 OR t2.f3 );
+drop tables t1, t2, t3;
+
+--echo #
+--echo # Test of LP BUG#872775 view with "outer references" bug
+--echo #
+set @@optimizer_switch= default;
+set optimizer_switch='subquery_cache=on';
+CREATE TABLE t1 (a int) ;
+
+CREATE TABLE t2 (b int, c varchar(1) NOT NULL ) ;
+INSERT INTO t2 VALUES (1,'x'),(2,'y');
+
+CREATE TABLE t3 (a int) ;
+
+CREATE TABLE t4 ( pk int(11) NOT NULL , b int(11) NOT NULL ) ;
+INSERT INTO t4 VALUES (26,9),(27,5),(28,0),(29,3);
+
+CREATE OR REPLACE VIEW v1 AS
+SELECT t2.b
+FROM t1
+JOIN t2
+WHERE t2 .c > (
+ SELECT t2.c FROM t3
+ );
+
+SELECT * FROM t4 WHERE b NOT IN ( SELECT * FROM v1 );
+
+drop view v1;
+drop table t1,t2,t3,t4;
+
+SET optimizer_switch=@save_optimizer_switch;
+
+--echo # restore default
+set @@optimizer_switch= default;
diff --git a/mysql-test/t/subselect_extra.test b/mysql-test/t/subselect_extra.test
new file mode 100644
index 00000000000..b76f3f70516
--- /dev/null
+++ b/mysql-test/t/subselect_extra.test
@@ -0,0 +1,395 @@
+#
+# This file is for tests for other features that happen to use
+# subqueries. The idea is that one should be able to run
+#
+# ./mysql-test-run t/subselect*.test
+#
+# and get as much subquery testing as possible.
+#
+
+--disable_warnings
+drop table if exists t1,t2,t3,t4;
+drop view if exists v1,v2,v3;
+--enable_warnings
+
+set @subselect_extra_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_extra_test,
+ "semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+
+--echo # From explain.test:
+--echo #
+--echo # Bug#37870: Usage of uninitialized value caused failed assertion.
+--echo #
+create table t1 (dt datetime not null, t time not null);
+create table t2 (dt datetime not null);
+insert into t1 values ('2001-01-01 1:1:1', '1:1:1'),
+('2001-01-01 1:1:1', '1:1:1');
+insert into t2 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1');
+flush tables;
+EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
+flush tables;
+SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
+flush tables;
+EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+flush tables;
+SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+drop tables t1, t2;
+
+--echo # From type_datetime.test:
+--echo #
+--echo # Bug #32694: NOT NULL table field in a subquery produces invalid results
+--echo #
+create table t1 (id int(10) not null, cur_date datetime not null);
+create table t2 (id int(10) not null, cur_date date not null);
+insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22');
+insert into t2 (id, cur_date) values (1, '2007-04-25');
+
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+
+insert into t1 (id, cur_date) values (2, '2007-04-26 18:30:22');
+insert into t2 (id, cur_date) values (2, '2007-04-26');
+
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+
+drop table t1,t2;
+
+--echo #
+--echo # From group_min_max.test
+--echo #
+create table t1 (
+ a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
+);
+
+insert into t1 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'),
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4');
+
+create index idx_t1_0 on t1 (a1);
+create index idx_t1_1 on t1 (a1,a2,b,c);
+create index idx_t1_2 on t1 (a1,a2,b);
+analyze table t1;
+
+# t2 is the same as t1, but with some NULLs in the MIN/MAX column, and
+# one more nullable attribute
+
+create table t2 (
+ a1 char(64), a2 char(64) not null, b char(16), c char(16), d char(16), dummy char(64) default ' '
+);
+insert into t2 select * from t1;
+# add few rows with NULL's in the MIN/MAX column
+insert into t2 (a1, a2, b, c, d) values
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz');
+
+create index idx_t2_0 on t2 (a1);
+create index idx_t2_1 on t2 (a1,a2,b,c);
+create index idx_t2_2 on t2 (a1,a2,b);
+analyze table t2;
+
+# Table t3 is the same as t1, but with smaller column lenghts.
+# This allows to test different branches of the cost computation procedure
+# when the number of keys per block are less than the number of keys in the
+# sub-groups formed by predicates over non-group attributes.
+
+create table t3 (
+ a1 char(1), a2 char(1), b char(1), c char(4) not null, d char(3), dummy char(1) default ' '
+);
+
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+
+create index idx_t3_0 on t3 (a1);
+create index idx_t3_1 on t3 (a1,a2,b,c);
+create index idx_t3_2 on t3 (a1,a2,b);
+analyze table t3;
+
+
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+ where t2.c in (select c from t3 where t3.c > t1.b) and
+ t2.c > 'b1' )
+group by a1,a2,b;
+
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+ where t2.c in (select c from t3 where t3.c > t1.b) and
+ t2.c > 'b1' )
+group by a1,a2,b;
+
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+ where t2.c in (select c from t3 where t3.c > t1.c) and
+ t2.c > 'b1' )
+group by a1,a2,b;
+
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+ where t2.c in (select c from t3 where t3.c > t1.c) and
+ t2.c > 'b1' )
+group by a1,a2,b;
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # From group_by.test
+--echo #
+
+--echo # Bug #21174: Index degrades sort performance and
+--echo # optimizer does not honor IGNORE INDEX.
+--echo # a.k.a WL3527.
+--echo #
+CREATE TABLE t1 (a INT, b INT,
+ PRIMARY KEY (a),
+ KEY i2(a,b));
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8);
+INSERT INTO t1 SELECT a + 8,b FROM t1;
+INSERT INTO t1 SELECT a + 16,b FROM t1;
+INSERT INTO t1 SELECT a + 32,b FROM t1;
+INSERT INTO t1 SELECT a + 64,b FROM t1;
+INSERT INTO t1 SELECT a + 128,b FROM t1 limit 16;
+ANALYZE TABLE t1;
+EXPLAIN SELECT 1 FROM t1 WHERE a IN
+ (SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+
+CREATE TABLE t2 (a INT, b INT, KEY(a));
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3,3), (4,4);
+EXPLAIN SELECT a, SUM(b) FROM t2 GROUP BY a LIMIT 2;
+EXPLAIN SELECT a, SUM(b) FROM t2 IGNORE INDEX (a) GROUP BY a LIMIT 2;
+
+EXPLAIN SELECT 1 FROM t2 WHERE a IN
+ (SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+DROP TABLE t1, t2;
+
+--echo #
+--echo # From derived_view.test
+--echo #
+set @tmp_subselect_extra_derived=@@optimizer_switch;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+
+--echo #
+--echo # LP bug #806504: right join over a view/derived table
+--echo #
+
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0);
+
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (0), (0);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #793448: materialized view accessed by two-component key
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (9,3), (2,5);
+
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (9,3), (3,7), (9,1), (2,5), (2,4), (3,8);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,3), (9,7), (9,1), (2,4);
+
+CREATE VIEW v1(a,b) AS SELECT a, MAX(b) FROM t2 GROUP BY a;
+CREATE VIEW v2(a,b) AS SELECT a,b FROM t2 UNION SELECT a,b FROM t3;
+
+SELECT * FROM v1;
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+
+SELECT * FROM v2;
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+
+DROP VIEW v1,v2;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #874006: materialized view used in IN subquery
+--echo #
+
+CREATE TABLE t3 (a int NOT NULL, b varchar(1), c varchar(1));
+INSERT INTO t3 VALUES (19,NULL,NULL), (20,'r','r');
+
+CREATE TABLE t1 (a int, b varchar(1) , c varchar(1));
+INSERT INTO t1 VALUES (1,NULL,NULL), (5,'r','r'), (7,'y','y');
+
+CREATE TABLE t2 (a int NOT NULL , b int, c varchar(1));
+INSERT INTO t2 VALUES (4,3,'r');
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #873263: materialized view used in correlated IN subquery
+--echo #
+
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (5,4), (9,8);
+
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (4,5), (5,1);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+
+DROP VIEW v2;
+DROP TABLE t1,t2;
+
+set optimizer_switch= @tmp_subselect_extra_derived;
diff --git a/mysql-test/t/subselect_extra_no_semijoin.test b/mysql-test/t/subselect_extra_no_semijoin.test
new file mode 100644
index 00000000000..8aba3dde72b
--- /dev/null
+++ b/mysql-test/t/subselect_extra_no_semijoin.test
@@ -0,0 +1,9 @@
+set @subselect_extra_no_sj_tmp=@@optimizer_switch;
+
+set @optimizer_switch_for_subselect_extra_test='semijoin=off,firstmatch=off,loosescan=off,semijoin_with_cache=off';
+
+--source t/subselect_extra.test
+
+set optimizer_switch= @subselect_extra_no_sj_tmp;
+
+set @optimizer_switch_for_subselect_extra_test=null; \ No newline at end of file
diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test
index ce070b454c3..f6ac5204c3e 100644
--- a/mysql-test/t/subselect_innodb.test
+++ b/mysql-test/t/subselect_innodb.test
@@ -1,5 +1,9 @@
-- source include/have_innodb.inc
+# Note: the tests uses only non-semijoin subqueries so semi-join switch
+# settings are not relevant.
+set @subselect_innodb_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
--disable_warnings
drop table if exists t1,t2,t3;
--enable_warnings
@@ -294,3 +298,88 @@ eval $query;
DROP TABLE t1,t2;
--echo End of 5.1 tests
+
+--echo #
+--echo # LP BUG#827416: Crash in select_describe() on EXPLAIN with DISTINCT in nested subqueries
+--echo #
+
+CREATE TABLE t3 ( b int) ENGINE=InnoDB;
+CREATE TABLE t2 ( c int) ENGINE=InnoDB;
+CREATE TABLE t1 ( a int NOT NULL , PRIMARY KEY (a)) ENGINE=InnoDB;
+
+EXPLAIN SELECT *
+FROM t1
+WHERE t1.a = (
+ SELECT SUM( c )
+ FROM t2
+ WHERE (SELECT DISTINCT b FROM t3) > 0);
+SELECT *
+FROM t1
+WHERE t1.a = (
+ SELECT SUM( c )
+ FROM t2
+ WHERE (SELECT DISTINCT b FROM t3) > 0);
+
+DROP TABLE t1, t2, t3;
+
+
+--echo #
+--echo # LP BUG#858148 Fourth crash in select_describe() with nested subqueries
+--echo #
+
+CREATE TABLE t1 ( f1 int(11)) ENGINE=InnoDB;
+CREATE TABLE t2 ( f1 int(11), f2 int(11), PRIMARY KEY (f1)) ;
+CREATE TABLE t3 ( f3 int(11)) ENGINE=InnoDB;
+
+EXPLAIN
+SELECT MAX( f1 ) FROM t2
+WHERE f2 >= (
+ SELECT SUM( f1 )
+ FROM t1
+ WHERE EXISTS (
+ SELECT f3
+ FROM t3
+ GROUP BY 1
+ )
+);
+
+SELECT MAX( f1 ) FROM t2
+WHERE f2 >= (
+ SELECT SUM( f1 )
+ FROM t1
+ WHERE EXISTS (
+ SELECT f3
+ FROM t3
+ GROUP BY 1
+ )
+);
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # LP BUG#1006231 crash in select_describe
+--echo #
+
+create table t1(a1 int) ENGINE=InnoDB;
+insert into t1 values (1);
+explain
+select 1 from t1 where 1 like (select 1 from t1 where 1 <=> (select 1 from t1 group by a1));
+select 1 from t1 where 1 like (select 1 from t1 where 1 <=> (select 1 from t1 group by a1));
+drop table t1;
+
+
+--echo #
+--echo # MDEV-3988 crash in create_tmp_table
+--echo #
+
+drop table if exists `t1`,`t2`;
+create table `t1`(`a` char(1) character set utf8)engine=innodb;
+create table `t2`(`b` char(1) character set utf8)engine=memory;
+select distinct (select 1 from `t2` where `a`) `d2` from `t1`;
+select distinct (select 1 from `t2` where `a`) `d2`, a from `t1`;
+select distinct a, (select 1 from `t2` where `a`) `d2` from `t1`;
+select distinct (1 + (select 1 from `t2` where `a`)) `d2` from `t1`;
+
+drop table t1,t2;
+
+set optimizer_switch=@subselect_innodb_tmp;
diff --git a/mysql-test/t/subselect_mat.test b/mysql-test/t/subselect_mat.test
new file mode 100644
index 00000000000..09c6b3e1747
--- /dev/null
+++ b/mysql-test/t/subselect_mat.test
@@ -0,0 +1,256 @@
+#
+# Hash semi-join regression tests
+# (WL#1110: Subquery optimization: materialization)
+#
+
+
+# force the use of materialization
+set @subselect_mat_test_optimizer_switch_value='materialization=on,in_to_exists=off,semijoin=off';
+
+--source t/subselect_sj_mat.test
+set @subselect_mat_test_optimizer_switch_value=null;
+
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+#
+# Test that the contents of the temp table of a materialized subquery is
+# cleaned up between PS re-executions.
+#
+
+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#611622/BUG#52344: Subquery materialization: Assertion
+--echo # if subquery in on-clause of outer join
+--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 t2 t3 ON (8, 4) IN (SELECT c1, c1 FROM t1)";
+
+EXECUTE st1;
+EXECUTE st1;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Testcase backport: BUG#46548 IN-subqueries return 0 rows with materialization=on
+--echo #
+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#724228: Wrong result with materialization=on and three aggregates in maria-5.3-mwl90
+-- echo #
+CREATE TABLE t1 ( f2 int(11)) ;
+INSERT IGNORE INTO t1 VALUES ('7'),('9'),('7'),('4'),('2'),('6'),('8'),('5'),('6'),('188'),('2'),('1'),('1'),('0'),('9'),('4');
+
+CREATE TABLE t2 ( f1 int(11), f2 int(11)) ENGINE=MyISAM;
+INSERT IGNORE INTO t2 VALUES ('1','1');
+
+CREATE TABLE t3 ( f1 int(11), f2 int(11), f3 int(11), PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES ('16','6','1'),('18','3','4'),('19',NULL,'9'),('20','0','6'),('41','2','0'),('42','2','5'),('43','9','6'),('44','7','4'),('45','1','4'),('46','222','238'),('47','3','6'),('48','6','6'),('49',NULL,'1'),('50','5','1');
+
+SET @_save_join_cache_level = @@join_cache_level;
+SET @_save_optimizer_switch = @@optimizer_switch;
+
+SET join_cache_level = 1;
+SET optimizer_switch='materialization=on';
+
+SELECT f1 FROM t3
+WHERE
+ f1 NOT IN (SELECT MAX(f2) FROM t1) AND
+ f3 IN (SELECT MIN(f1) FROM t2) AND
+ f1 IN (SELECT COUNT(f2) FROM t1);
+
+SET @@join_cache_level = @_save_join_cache_level;
+SET @@optimizer_switch = @_save_optimizer_switch;
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # LPBUG#719198 Ordered_key::cmp_key_with_search_key(rownum_t): Assertion `!compare_pred[i]->null_value'
+--echo # failed with subquery on both sides of NOT IN and materialization
+--echo #
+
+CREATE TABLE t1 (f1a int, f1b int) ;
+INSERT IGNORE INTO t1 VALUES (1,1),(2,2);
+CREATE TABLE t2 ( f2 int);
+INSERT IGNORE INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (f3a int, f3b int);
+
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+
+EXPLAIN
+SELECT * FROM t2 WHERE (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1);
+SELECT * FROM t2 WHERE (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1);
+
+EXPLAIN
+SELECT (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1);
+SELECT (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1);
+
+EXPLAIN
+SELECT * FROM t2 WHERE (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1);
+SELECT * FROM t2 WHERE (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1);
+
+EXPLAIN
+SELECT (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1);
+SELECT (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1);
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # LPBUG#730604 Assertion `bit < (map)->n_bits' failed in maria-5.3 with
+--echo # partial_match_rowid_merge
+--echo #
+
+CREATE TABLE t1 (f1 int NOT NULL, f2 int, f3 int) ;
+CREATE TABLE t2 (f1 int NOT NULL, f2 int, f3 int) ;
+
+INSERT INTO t1 VALUES (60, 3, null), (61, null, 77);
+INSERT INTO t2 VALUES (1000,6,2);
+
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+
+EXPLAIN
+SELECT (f1, f2, f3) NOT IN
+ (SELECT COUNT(DISTINCT f2), f1, f3 FROM t1 GROUP BY f1, f3)
+FROM t2;
+
+SELECT (f1, f2, f3) NOT IN
+ (SELECT COUNT(DISTINCT f2), f1, f3 FROM t1 GROUP BY f1, f3)
+FROM t2;
+
+drop table t1, t2;
+
+--echo #
+--echo # LPBUG#702301: MAX in select + always false WHERE with SQ
+--echo #
+
+CREATE TABLE t1 (a int, b int, KEY (b));
+INSERT INTO t1 VALUES (3,1), (4,2);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (7), (8);
+
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+EXPLAIN EXTENDED
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+
+set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off';
+
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+EXPLAIN EXTENDED
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LPBUG#825095: Wrong result with materialization and NOT IN with 2 expressions
+--echo #
+
+CREATE TABLE t1 (a int,b int);
+INSERT INTO t1 VALUES (4,4),(4,2);
+
+CREATE TABLE t2 (b int, a int);
+INSERT INTO t2 VALUES (4,3),(8,4);
+
+set @@optimizer_switch='semijoin=off,in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+
+EXPLAIN SELECT *
+FROM t1
+WHERE (a, b) NOT IN (SELECT a, b FROM t2);
+
+SELECT *
+FROM t1
+WHERE (a, b) NOT IN (SELECT a, b FROM t2);
+
+EXPLAIN
+SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
+FROM t1;
+
+SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
+FROM t1;
+
+drop table t1, t2;
diff --git a/mysql-test/t/subselect_mat_cost-master.opt b/mysql-test/t/subselect_mat_cost-master.opt
new file mode 100644
index 00000000000..dc7ac6cc205
--- /dev/null
+++ b/mysql-test/t/subselect_mat_cost-master.opt
@@ -0,0 +1 @@
+--log-output=TABLE,FILE --log --log-slow-queries --slow-query-log=1
diff --git a/mysql-test/t/subselect_mat_cost.test b/mysql-test/t/subselect_mat_cost.test
new file mode 100644
index 00000000000..a747b9a6c5e
--- /dev/null
+++ b/mysql-test/t/subselect_mat_cost.test
@@ -0,0 +1,429 @@
+#
+# Tests of cost-based choice between the materialization and in-to-exists
+# subquery execution strategies (MWL#89)
+#
+# The test file is divided into two groups of tests:
+# A. Typical cases when either of the two strategies is selected:
+# 1. Subquery in disjunctive WHERE clause of the outer query.
+# 2. NOT IN subqueries
+# 3. Subqueries with GROUP BY, HAVING, and aggregate functions
+# 4. Subqueries in the SELECT and HAVING clauses
+# 5. Subqueries with UNION
+# B. Reasonably exhaustive tests of the various combinations of optimizer
+# switches, data distribution, available indexes, and typical queries.
+#
+
+set @subselect_mat_cost=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+#
+# Test logging to slow log (there was some errors in the log files about
+# the slow log when running under valgrind, so better to get this tested)
+#
+set log_slow_time=0.1;
+
+
+-- echo TEST GROUP 1:
+-- echo Typical cases of in-to-exists and materialization subquery strategies
+-- echo =====================================================================
+
+--disable_warnings
+drop database if exists world;
+--enable_warnings
+
+set names utf8;
+
+create database world;
+use world;
+
+--source include/world_schema.inc
+--disable_query_log
+--disable_result_log
+--disable_warnings
+--source include/world.inc
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+-- echo Make the schema and data more diverse by adding more indexes, nullable
+-- echo columns, and NULL data.
+create index SurfaceArea on Country(SurfaceArea);
+create index Language on CountryLanguage(Language);
+create index CityName on City(Name);
+alter table City change population population int(11) null default 0;
+
+select max(id) from City into @max_city_id;
+insert into City values (@max_city_id + 1,'Kilifarevo','BGR',NULL);
+
+
+SELECT COUNT(*) FROM Country;
+SELECT COUNT(*) FROM City;
+SELECT COUNT(*) FROM CountryLanguage;
+
+set @@optimizer_switch = 'in_to_exists=on,semijoin=on,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on';
+
+-- echo
+-- echo 1. Subquery in a disjunctive WHERE clause of the outer query.
+-- echo
+
+-- echo
+-- echo Q1.1m:
+-- echo MATERIALIZATION: there are too many rows in the outer query
+-- echo to be looked up in the inner table.
+EXPLAIN
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+ Name LIKE 'L%') AND
+ surfacearea > 1000000;
+
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+ Name LIKE 'L%') AND
+ surfacearea > 1000000;
+
+-- echo Q1.1e:
+-- echo IN-EXISTS: the materialization cost is the same as above, but
+-- echo there are much fewer outer rows to be looked up, thus the
+-- echo materialization cost is too high to compensate for fast lookups.
+EXPLAIN
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+ Name LIKE 'L%') AND
+ surfacearea > 10*1000000;
+
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+ Name LIKE 'L%') AND
+ surfacearea > 10*1000000;
+
+-- echo
+-- echo Q1.2m:
+-- echo MATERIALIZATION: the IN predicate is pushed (attached) to the last table
+-- echo in the join order (Country, City), therefore there are too many row
+-- echo combinations to filter by re-executing the subquery for each combination.
+EXPLAIN
+SELECT *
+ FROM Country, City
+ WHERE City.Country = Country.Code AND
+ Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+ (City.Name IN
+ (select Language from CountryLanguage where Percentage > 50) OR
+ City.name LIKE '%Island%');
+
+SELECT *
+ FROM Country, City
+ WHERE City.Country = Country.Code AND
+ Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+ (City.Name IN
+ (select Language from CountryLanguage where Percentage > 50) OR
+ City.name LIKE '%Island%');
+
+-- echo Q1.2e:
+-- echo IN_EXISTS: join order is the same, but the left IN operand refers to
+-- echo only the first table in the join order (Country), so there are much
+-- echo fewer rows to filter by subquery re-execution.
+EXPLAIN
+SELECT *
+ FROM Country, City
+ WHERE City.Country = Country.Code AND
+ Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+ (Country.Name IN
+ (select Language from CountryLanguage where Percentage > 50) OR
+ Country.name LIKE '%Island%');
+
+SELECT *
+ FROM Country, City
+ WHERE City.Country = Country.Code AND
+ Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+ (Country.Name IN
+ (select Language from CountryLanguage where Percentage > 50) OR
+ Country.name LIKE '%Island%');
+
+
+-- echo
+-- echo Q1.3:
+-- echo For the same reasons as in Q2 IN-EXISTS and MATERIALIZATION chosen
+-- echo for each respective subquery.
+EXPLAIN
+SELECT City.Name, Country.Name
+ FROM City,Country
+ WHERE City.Country = Country.Code AND
+ Country.SurfaceArea < 30000 AND Country.SurfaceArea > 10 AND
+ ((Country.Code, Country.Name) IN
+ (select Country, Language from CountryLanguage where Percentage > 50) AND
+ Country.Population > 3000000
+ OR
+ (Country.Code, City.Name) IN
+ (select Country, Language from CountryLanguage));
+
+SELECT City.Name, Country.Name
+ FROM City,Country
+ WHERE City.Country = Country.Code AND
+ Country.SurfaceArea < 30000 AND Country.SurfaceArea > 10 AND
+ ((Country.Code, Country.Name) IN
+ (select Country, Language from CountryLanguage where Percentage > 50) AND
+ Country.Population > 3000000
+ OR
+ (Country.Code, City.Name) IN
+ (select Country, Language from CountryLanguage));
+
+
+-- echo
+-- echo 2. NOT IN subqueries
+-- echo
+
+-- echo
+-- echo Q2.1:
+-- echo Number of cities that are not capitals in countries with small population.
+-- echo MATERIALIZATION is 50 times faster because the cost of each subquery
+-- echo re-execution is much higher than the cost of index lookups into the
+-- echo materialized subquery.
+
+EXPLAIN
+select count(*) from City
+where City.id not in (select capital from Country
+ where capital is not null and population < 100000);
+
+-- echo
+-- echo Q2.2e:
+-- echo Countries that speak French, but do not speak English
+-- echo IN-EXISTS because the outer query filters many rows, thus
+-- echo there are few lookups to make.
+EXPLAIN
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+ AND CountryLanguage.Language = 'French'
+ AND Code = Country;
+
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+ AND CountryLanguage.Language = 'French'
+ AND Code = Country;
+
+-- echo Q2.2m:
+-- echo Countries that speak French OR Spanish, but do not speak English
+-- echo MATERIALIZATION because the outer query filters less rows than Q5-a,
+-- echo so there are more lookups.
+EXPLAIN
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+ AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish')
+ AND Code = Country;
+
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+ AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish')
+ AND Code = Country;
+
+-- echo
+-- echo Q2.3e:
+-- echo Not a very meaningful query that tests NOT IN.
+-- echo IN-EXISTS because the outer query is cheap enough to reexecute many times.
+EXPLAIN
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+ (SELECT City.Name, Country.Code
+ FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000))
+ AND Language IN ('English','Spanish');
+
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+ (SELECT City.Name, Country.Code
+ FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000))
+ AND Language IN ('English','Spanish');
+
+-- echo Q2.3m:
+-- echo MATERIALIZATION with the PARTIAL_MATCH_MERGE strategy, because the HAVING
+-- echo clause prevents the use of the index on City(Name), and in practice reduces
+-- echo radically the size of the temp table.
+EXPLAIN
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+ (SELECT City.Name, Country.Code
+ FROM City LEFT JOIN Country ON (Country = Code)
+ HAVING City.Name LIKE "Santa%");
+
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+ (SELECT City.Name, Country.Code
+ FROM City LEFT JOIN Country ON (Country = Code)
+ HAVING City.Name LIKE "Santa%");
+
+
+-- echo
+-- echo 3. Subqueries with GROUP BY, HAVING, and aggregate functions
+-- echo
+
+-- echo Q3.1:
+-- echo Languages that are spoken in countries with 10 or 11 languages
+-- echo MATERIALIZATION is about 100 times faster than IN-EXISTS.
+
+EXPLAIN
+select count(*)
+from CountryLanguage
+where
+(Country, 10) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+ WHERE Code = Country GROUP BY Code)
+OR
+(Country, 11) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+ WHERE Code = Country GROUP BY Code)
+order by Country;
+
+select count(*)
+from CountryLanguage
+where
+(Country, 10) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+ WHERE Code = Country GROUP BY Code)
+OR
+(Country, 11) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+ WHERE Code = Country GROUP BY Code)
+order by Country;
+
+
+-- echo
+-- echo Q3.2:
+-- echo Countries whose capital is a city name that names more than one
+-- echo cities.
+-- echo MATERIALIZATION because the cost of single subquery execution is
+-- echo close to that of materializing the subquery.
+
+EXPLAIN
+select * from Country, City
+where capital = id and
+ (City.name in (SELECT name FROM City
+ GROUP BY name HAVING Count(*) > 2) OR
+ capital is null);
+
+select * from Country, City
+where capital = id and
+ (City.name in (SELECT name FROM City
+ GROUP BY name HAVING Count(*) > 2) OR
+ capital is null);
+
+-- echo
+-- echo Q3.3: MATERIALIZATION is 25 times faster than IN-EXISTS
+
+EXPLAIN
+SELECT Name
+FROM Country
+WHERE Country.Code NOT IN
+ (SELECT Country FROM City GROUP BY Name HAVING COUNT(Name) = 1);
+
+SELECT Name
+FROM Country
+WHERE Country.Code NOT IN
+ (SELECT Country FROM City GROUP BY Name HAVING COUNT(Name) = 1);
+
+
+-- echo
+-- echo 4. Subqueries in the SELECT and HAVING clauses
+-- echo
+
+-- echo Q4.1m:
+-- echo Capital information about very big cities
+-- echo MATERIALIZATION
+EXPLAIN
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+
+-- echo Q4.1e:
+-- echo IN-TO-EXISTS after adding an index to make the subquery re-execution
+-- echo efficient.
+
+create index CountryCapital on Country(capital);
+
+EXPLAIN
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+
+drop index CountryCapital on Country;
+
+-- echo
+-- echo Q4.2:
+-- echo MATERIALIZATION
+# TODO: the cost estimates for subqueries in the HAVING clause need to be changed
+# to take into account that the subquery predicate is executed #times ~ to the
+# number of groups, not number of rows
+EXPLAIN
+SELECT City.Name, City.Population
+FROM City JOIN Country ON City.Country = Country.Code
+GROUP BY City.Name
+HAVING City.Name IN (select Name from Country where population < 1000000);
+
+SELECT City.Name, City.Population
+FROM City JOIN Country ON City.Country = Country.Code
+GROUP BY City.Name
+HAVING City.Name IN (select Name from Country where population < 1000000);
+
+
+-- echo
+-- echo 5. Subqueries with UNION
+-- echo
+
+-- echo Q5.1:
+EXPLAIN
+SELECT * from City where (Name, 91) in
+(SELECT Name, round(Population/1000)
+ FROM City
+ WHERE Country = "IND" AND Population > 2500000
+UNION
+ SELECT Name, round(Population/1000)
+ FROM City
+ WHERE Country = "IND" AND Population < 100000);
+
+SELECT * from City where (Name, 91) in
+(SELECT Name, round(Population/1000)
+ FROM City
+ WHERE Country = "IND" AND Population > 2500000
+UNION
+ SELECT Name, round(Population/1000)
+ FROM City
+ WHERE Country = "IND" AND Population < 100000);
+
+set @@optimizer_switch='default';
+drop database world;
+-- echo
+
+
+-- echo
+-- echo TEST GROUP 2:
+-- echo Tests of various combinations of optimizer switches, types of queries,
+-- echo available indexes, column nullability, constness of tables/predicates.
+-- echo =====================================================================
+
+
+#TODO From Igor's review:
+#
+#2.1 Please add a case when two subqueries are used in the where clause
+#(or in select) of a 2-way join.
+#The first subquery is accessed after the first table, while the second
+#is accessed after the second table.
+#
+#2.2. Please add a test case when one non-correlated subquery contains
+#another non-correlated subquery.
+#Consider 4 subcases:
+# both subqueries are materialized
+# IN_EXIST transformations are applied to both subqueries
+# outer subquery is materialized while the inner subquery is not
+#(IN_EXIST transformation is applied to it)
+# inner subqyery is materialized while the outer subquery is not (
+#IN_EXIST transformation is applied to it)
+
+set optimizer_switch=@subselect_mat_cost;
diff --git a/mysql-test/t/subselect_mat_cost_bugs.test b/mysql-test/t/subselect_mat_cost_bugs.test
new file mode 100644
index 00000000000..8205e94b203
--- /dev/null
+++ b/mysql-test/t/subselect_mat_cost_bugs.test
@@ -0,0 +1,426 @@
+#
+# Test cases for bugs related to the implementation of
+# MWL#89 cost-based choice between the materialization and in-to-exists
+#
+
+--echo #
+--echo # LP BUG#643424 valgrind warning in choose_subquery_plan()
+--echo #
+
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ c1 int(11) DEFAULT NULL,
+ c2 int(11) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY c2 (c2));
+
+INSERT INTO t1 VALUES (1,NULL,2);
+INSERT INTO t1 VALUES (2,7,9);
+INSERT INTO t1 VALUES (9,NULL,8);
+
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ c1 int(11) DEFAULT NULL,
+ c2 int(11) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY c2 (c2));
+
+INSERT INTO t2 VALUES (1,1,7);
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off';
+
+SELECT pk FROM t1 WHERE (c2, c1) IN (SELECT c2, c2 FROM t2);
+
+set session optimizer_switch=@save_optimizer_switch;
+
+drop table t1, t2;
+
+
+--echo #
+--echo # LP BUG#652727 Crash in create_ref_for_key()
+--echo #
+
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ c1 int(11) DEFAULT NULL,
+ PRIMARY KEY (pk));
+
+INSERT INTO t2 VALUES (10,7);
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (17,NULL);
+
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ c1 int(11) DEFAULT NULL,
+ PRIMARY KEY (pk));
+
+INSERT INTO t1 VALUES (15,1);
+INSERT INTO t1 VALUES (19,NULL);
+
+CREATE TABLE t3 (c2 int(11) DEFAULT NULL, KEY c2 (c2));
+INSERT INTO t3 VALUES (1);
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off';
+
+SELECT c2
+FROM t3
+WHERE (2, 6) IN (SELECT t1.c1, t1.c1 FROM t1 STRAIGHT_JOIN t2 ON t2.pk = t1.pk);
+
+set session optimizer_switch=@save_optimizer_switch;
+drop table t1, t2, t3;
+
+
+--echo #
+--echo # LP BUG#641245 Crash in Item_equal::contains
+--echo #
+
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ c1 int(11) DEFAULT NULL,
+ c2 int(11) DEFAULT NULL,
+ c3 varchar(1) DEFAULT NULL,
+ c4 varchar(1) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY c2 (c2),
+ KEY c3 (c3,c2));
+
+INSERT INTO t1 VALUES (10,7,8,'v','v');
+INSERT INTO t1 VALUES (11,1,9,'r','r');
+INSERT INTO t1 VALUES (12,5,9,'a','a');
+INSERT INTO t1 VALUES (13,7,18,'v','v');
+INSERT INTO t1 VALUES (14,1,19,'r','r');
+INSERT INTO t1 VALUES (15,5,29,'a','a');
+INSERT INTO t1 VALUES (17,7,38,'v','v');
+INSERT INTO t1 VALUES (18,1,39,'r','r');
+INSERT INTO t1 VALUES (19,5,49,'a','a');
+
+create table t1a like t1;
+insert into t1a select * from t1;
+
+create table t1b like t1;
+insert into t1b select * from t1;
+
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ c1 int(11) DEFAULT NULL,
+ c2 int(11) DEFAULT NULL,
+ c3 varchar(1) DEFAULT NULL,
+ c4 varchar(1) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY c2 (c2),
+ KEY c3 (c3,c2));
+
+INSERT INTO t2 VALUES (1,NULL,2,'w','w');
+INSERT INTO t2 VALUES (2,7,9,'m','m');
+
+set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off';
+
+let $query=
+SELECT pk
+FROM t1
+WHERE c1 IN
+ (SELECT t1a.c1
+ FROM (t1b JOIN t2 ON t2.c3 = t1b.c4) LEFT JOIN
+ t1a ON (t1a.c2 = t1b.pk AND 2)
+ WHERE t1.pk) ;
+eval EXPLAIN EXTENDED $query;
+eval $query;
+
+DROP TABLE t1, t1a, t1b, t2;
+
+--echo #
+--echo # LP BUG#714808 Assertion `outer_lookup_keys <= outer_record_count'
+--echo # failed with materialization
+
+CREATE TABLE t1 ( pk int(11), PRIMARY KEY (pk)) ;
+CREATE TABLE t2 ( f2 int(11)) ;
+CREATE TABLE t3 ( f1 int(11), f3 varchar(1), KEY (f1)) ;
+INSERT INTO t3 VALUES (7,'f');
+
+set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off';
+
+EXPLAIN
+SELECT t1.*
+FROM t3 RIGHT JOIN t1 ON t1.pk = t3.f1
+WHERE t3.f3 OR ( 3 ) IN ( SELECT f2 FROM t2 );
+
+SELECT t1.*
+FROM t3 RIGHT JOIN t1 ON t1.pk = t3.f1
+WHERE t3.f3 OR ( 3 ) IN ( SELECT f2 FROM t2 );
+
+drop table t1,t2,t3;
+
+--echo #
+--echo # LP BUG#714999 Second crash in select_describe() with nested subqueries
+--echo #
+
+CREATE TABLE t1 ( pk int(11)) ;
+INSERT INTO t1 VALUES (29);
+
+CREATE TABLE t2 ( f1 varchar(1)) ;
+INSERT INTO t2 VALUES ('f'),('d');
+
+CREATE TABLE t3 ( f2 varchar(1)) ;
+
+EXPLAIN SELECT f2 FROM t3 WHERE (
+ SELECT MAX( pk ) FROM t1
+ WHERE EXISTS (
+ SELECT max(f1)
+ FROM t2 GROUP BY f1
+ )
+) IS NULL ;
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # LP BUG#715034 Item_sum_distinct::clear(): Assertion `tree != 0' failed
+--echo #
+
+CREATE TABLE t2 ( f2 int(11)) ;
+
+CREATE TABLE t1 ( f3 int(11), KEY (f3)) ;
+INSERT INTO t1 VALUES (6),(4);
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+
+EXPLAIN
+SELECT * FROM (SELECT * FROM t2) AS a2
+WHERE (SELECT distinct SUM(distinct f3 ) FROM t1);
+
+insert into t2 values (1),(2);
+EXPLAIN
+SELECT * FROM (SELECT * FROM t2) AS a2
+WHERE (SELECT distinct SUM(distinct f3 ) FROM t1);
+
+set optimizer_switch=@tmp_optimizer_switch;
+drop table t1,t2;
+
+--echo #
+--echo # LP BUG#715027 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed
+--echo #
+
+CREATE TABLE t1 ( f1 int(11), PRIMARY KEY (f1)) ;
+INSERT INTO t1 VALUES (28),(29);
+
+CREATE TABLE t2 ( f2 int(11), f3 int(11), f10 varchar(1)) ;
+INSERT INTO t2 VALUES (NULL,6,'f'),(4,2,'d');
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+
+EXPLAIN
+SELECT alias2.f2 AS field1
+FROM t1 AS alias1 JOIN ( SELECT * FROM t2 ) AS alias2 ON alias2.f3 = alias1.f1
+WHERE (
+ SELECT t2.f2
+ FROM t2 JOIN t1 ON t1.f1
+ WHERE t1.f1 AND alias2.f10
+)
+ORDER BY field1 ;
+
+SELECT alias2.f2 AS field1
+FROM t1 AS alias1 JOIN ( SELECT * FROM t2 ) AS alias2 ON alias2.f3 = alias1.f1
+WHERE (
+ SELECT t2.f2
+ FROM t2 JOIN t1 ON t1.f1
+ WHERE t1.f1 AND alias2.f10
+)
+ORDER BY field1 ;
+
+set optimizer_switch=@tmp_optimizer_switch;
+drop table t1,t2;
+
+--echo #
+--echo # LP BUG#718578 Yet another Assertion `!table ||
+--echo # (!table->read_set || bitmap_is_set(table->read_set, field_index))'
+
+CREATE TABLE t1 ( f1 int(11), f2 int(11), f3 int(11)) ;
+INSERT IGNORE INTO t1 VALUES (28,5,6),(29,NULL,4);
+
+CREATE TABLE t2 ( f10 varchar(1) );
+INSERT IGNORE INTO t2 VALUES (NULL);
+
+SELECT f1 AS field1
+FROM ( SELECT * FROM t1 ) AS alias1
+WHERE (SELECT t1.f1
+ FROM t2 JOIN t1 ON t1.f2
+ WHERE alias1.f3 AND t1.f3) AND f2
+ORDER BY field1;
+
+drop table t1,t2;
+
+--echo #
+--echo # LP BUG#601124 Bug in eliminate_item_equal
+--echo # leads to crash in Item_func::Item_func
+
+CREATE TABLE t1 ( f1 int(11), f3 varchar(1)) ;
+INSERT INTO t1 VALUES (5,'m'),(NULL,'c');
+
+CREATE TABLE t2 ( f2 int(11), f3 varchar(1)) ;
+INSERT INTO t2 VALUES (6,'f'),(2,'d');
+
+CREATE TABLE t3 ( f2 int(11), f3 varchar(1)) ;
+INSERT INTO t3 VALUES (6,'f'),(2,'d');
+
+SELECT * FROM t3
+WHERE ( f2 ) IN (SELECT t1.f1
+ FROM t1 STRAIGHT_JOIN t2 ON t2.f3 = t1.f3
+ WHERE t2.f3 = 'c');
+drop table t1,t2,t3;
+
+
+--echo #
+--echo # LP BUG#718593 Crash in substitute_for_best_equal_field -> eliminate_item_equal ->
+--echo # Item_field::find_item_equal -> Item_equal::contains
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch = 'semijoin=off';
+
+CREATE TABLE t1 ( f3 int(11), f10 varchar(1), f11 varchar(1)) ;
+INSERT IGNORE INTO t1 VALUES (6,'f','f'),(2,'d','d');
+
+CREATE TABLE t2 ( f12 int(11), f13 int(11)) ;
+insert into t2 values (1,2), (3,4);
+
+EXPLAIN
+SELECT * FROM t2
+WHERE ( f12 ) IN (
+ SELECT alias2.f3
+ FROM t1 AS alias1 JOIN t1 AS alias2 ON alias2.f10 = alias1.f11
+ WHERE alias1.f11 OR alias1.f3 = 50 AND alias1.f10
+);
+SELECT * FROM t2
+WHERE ( f12 ) IN (
+ SELECT alias2.f3
+ FROM t1 AS alias1 JOIN t1 AS alias2 ON alias2.f10 = alias1.f11
+ WHERE alias1.f11 OR alias1.f3 = 50 AND alias1.f10
+);
+
+EXPLAIN
+SELECT * FROM t2
+WHERE ( f12 ) IN (
+ SELECT alias2.f3
+ FROM t1 AS alias1, t1 AS alias2
+ WHERE (alias2.f10 = alias1.f11) AND (alias1.f11 OR alias1.f3 = 50 AND alias1.f10));
+SELECT * FROM t2
+WHERE ( f12 ) IN (
+ SELECT alias2.f3
+ FROM t1 AS alias1, t1 AS alias2
+ WHERE (alias2.f10 = alias1.f11) AND (alias1.f11 OR alias1.f3 = 50 AND alias1.f10));
+
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t2;
+
+
+--echo #
+--echo # MWL#89: test introduced after Sergey Petrunia's review - test that
+--echo # keyparts wihtout index prefix are used with the IN-EXISTS strategy.
+--echo #
+
+create table t1 (c1 int);
+insert into t1 values (1), (2), (3);
+
+create table t2 (kp1 int, kp2 int, c2 int, filler char(100));
+insert into t2 values (0,0,0,'filler'),(0,1,1,'filler'),(0,2,2,'filler'),(0,3,3,'filler');
+
+create index key1 on t2 (kp1, kp2);
+create index key2 on t2 (kp1);
+create index key3 on t2 (kp2);
+
+SET @@optimizer_switch='materialization=off,semijoin=off,in_to_exists=on';
+
+analyze table t2;
+
+explain
+select c1 from t1 where c1 in (select kp1 from t2 where kp2 = 10 and c2 = 4) or c1 > 7;
+select c1 from t1 where c1 in (select kp1 from t2 where kp2 = 10 and c2 = 4) or c1 > 7;
+
+set @@optimizer_switch='default';
+
+drop table t1, t2;
+
+--echo #
+--echo # LP BUG#800679: Assertion `outer_join->table_count > 0' failed in
+--echo # JOIN::choose_subquery_plan() with materialization=on,semijoin=off
+--echo #
+
+CREATE TABLE t1 ( f1 int);
+insert into t1 values (1),(2);
+CREATE TABLE t2 ( f1 int);
+insert into t2 values (1),(2);
+
+SET @@optimizer_switch='materialization=on,semijoin=off';
+
+EXPLAIN
+SELECT * FROM t1
+WHERE (f1) IN (SELECT f1 FROM t2)
+LIMIT 0;
+
+SELECT * FROM t1
+WHERE (f1) IN (SELECT f1 FROM t2)
+LIMIT 0;
+
+set @@optimizer_switch='default';
+drop table t1, t2;
+
+--echo #
+--echo # LP BUG#834492: Crash in fix_semijoin_strategies_for_picked_join_order
+--echo # with nested subqueries and LooseScan=ON
+--echo #
+
+CREATE TABLE t3 (b int) ;
+INSERT INTO t3 VALUES (0),(0);
+
+CREATE TABLE t4 (a int, b int, c int, d int, PRIMARY KEY (a)) ;
+INSERT INTO t4 VALUES (28,0,0,0),(29,3,0,0);
+
+CREATE TABLE t5 (a int, b int, c int, d int, KEY (c,b)) ;
+INSERT INTO t5 VALUES (28,0,0,0),(29,3,0,0);
+
+SET @@optimizer_switch='semijoin=ON,loosescan=ON,firstmatch=OFF,materialization=OFF';
+
+EXPLAIN SELECT *
+FROM t3
+WHERE t3.b > ALL (
+ SELECT c
+ FROM t4
+ WHERE t4.a >= t3.b
+ AND a = SOME (SELECT b FROM t5));
+
+SELECT *
+FROM t3
+WHERE t3.b > ALL (
+ SELECT c
+ FROM t4
+ WHERE t4.a >= t3.b
+ AND a = SOME (SELECT b FROM t5));
+
+set @@optimizer_switch='default';
+drop table t3, t4, t5;
+
+--echo #
+--echo # LP BUG#858038 The result of a query with NOT IN subquery depends on the state of the optimizer switch
+--echo #
+
+create table t1 (c1 char(2) not null, c2 char(2));
+create table t2 (c3 char(2), c4 char(2));
+
+insert into t1 values ('a1', 'b1');
+insert into t1 values ('a2', 'b2');
+
+insert into t2 values ('x1', 'y1');
+insert into t2 values ('a2', null);
+
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=off,partial_match_table_scan=on';
+explain select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+explain select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+
+drop table t1, t2;
diff --git a/mysql-test/t/subselect_no_mat.test b/mysql-test/t/subselect_no_mat.test
new file mode 100644
index 00000000000..ccd93af64ce
--- /dev/null
+++ b/mysql-test/t/subselect_no_mat.test
@@ -0,0 +1,17 @@
+#
+# Run subselect.test without semi-join optimization (test materialize)
+#
+select @@optimizer_switch like '%materialization=on%';
+set optimizer_switch='materialization=off';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+set join_cache_level=1;
+set @join_cache_level_for_subselect_test=@@join_cache_level;
+
+--source t/subselect.test
+
+set optimizer_switch=default;
+select @@optimizer_switch like '%materialization=on%';
+set @join_cache_level_for_subselect_test=NULL;
+
+
diff --git a/mysql-test/t/subselect_no_opts.test b/mysql-test/t/subselect_no_opts.test
new file mode 100644
index 00000000000..8a699fefaf7
--- /dev/null
+++ b/mysql-test/t/subselect_no_opts.test
@@ -0,0 +1,14 @@
+#
+# Run subselect.test without semi-join and materialization optimizations
+# (test in-to-exists)
+
+
+set @optimizer_switch_for_subselect_test='materialization=off,semijoin=off,subquery_cache=off,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+set join_cache_level=1;
+set @join_cache_level_for_subselect_test=@@join_cache_level;
+
+--source t/subselect.test
+
+set @optimizer_switch_for_subselect_test=null;
+
diff --git a/mysql-test/t/subselect_no_scache.test b/mysql-test/t/subselect_no_scache.test
new file mode 100644
index 00000000000..a8ff559b82b
--- /dev/null
+++ b/mysql-test/t/subselect_no_scache.test
@@ -0,0 +1,15 @@
+#
+# Run subselect.test without semi-join optimization (test materialize)
+#
+select @@optimizer_switch like '%subquery_cache=on%';
+set optimizer_switch='subquery_cache=off';
+
+set join_cache_level=1;
+set @join_cache_level_for_subselect_test=@@join_cache_level;
+
+--source t/subselect.test
+
+set optimizer_switch=default;
+select @@optimizer_switch like '%subquery_cache=on%';
+set @join_cache_level_for_subselect_test=NULL;
+
diff --git a/mysql-test/t/subselect_no_semijoin.test b/mysql-test/t/subselect_no_semijoin.test
new file mode 100644
index 00000000000..46791667173
--- /dev/null
+++ b/mysql-test/t/subselect_no_semijoin.test
@@ -0,0 +1,12 @@
+#
+# Run subselect.test without semi-join optimization (test materialize)
+#
+set @optimizer_switch_for_subselect_test='semijoin=off,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+set join_cache_level=1;
+set @join_cache_level_for_subselect_test=@@join_cache_level;
+
+--source t/subselect.test
+
+set @optimizer_switch_for_subselect_test=null;
+set @join_cache_level_for_subselect_test=NULL;
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..4b08e773b17
--- /dev/null
+++ b/mysql-test/t/subselect_nulls.test
@@ -0,0 +1,99 @@
+# Initialize tables for the test
+
+--disable_warnings
+drop table if exists x1;
+drop table if exists x2;
+--enable_warnings
+
+set @tmp_subselect_nulls=@@optimizer_switch;
+set optimizer_switch='semijoin=off';
+
+create table x1(k int primary key, d1 int, d2 int);
+create table x2(k int primary key, d1 int, d2 int);
+
+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);
+
+set optimizer_switch= @tmp_subselect_nulls;
+
+drop table x1;
+drop table x2;
diff --git a/mysql-test/t/subselect_partial_match.test b/mysql-test/t/subselect_partial_match.test
new file mode 100644
index 00000000000..fd1e6de716c
--- /dev/null
+++ b/mysql-test/t/subselect_partial_match.test
@@ -0,0 +1,803 @@
+#
+# Tests for
+# MWL#68: Subquery optimization: Efficient NOT IN execution with NULLs
+#
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+--echo -------------------------------
+--echo Part 1: Feature tests.
+--echo -------------------------------
+
+--echo Default for all tests.
+set @@optimizer_switch = "materialization=on,in_to_exists=off,semijoin=off,subquery_cache=off";
+set @test_default_opt_switch = @@optimizer_switch;
+set @in_exists = "materialization=off,in_to_exists=on,semijoin=off,subquery_cache=off";
+
+--echo -------------------------------------------------------------------------
+--echo Schema requires partial matching, but data analysis discoveres there is
+--echo no need. This is possible only if all outer columns are not NULL.
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(8) not null, a2 char(8) not null);
+create table t2 (b1 char(8), b2 char(8));
+
+insert into t1 values ('1 - 00', '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+
+insert into t2 values ('1 - 00', '2 - 00');
+insert into t2 values ('1 - 01', NULL );
+insert into t2 values (NULL , '2 - 02');
+insert into t2 values (NULL , NULL );
+insert into t2 values ('1 - 02', '2 - 02');
+
+select * from t1
+where (a1, a2) not in (select * from t2 where b1 is not null and b2 is not null);
+
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo NULLs in the outer columns, no NULLs in the suqbuery
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(8), a2 char(8));
+create table t2 (b1 char(8) not null, b2 char(8) not null);
+
+insert into t1 values (NULL , '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+insert into t1 values (NULL , NULL );
+
+insert into t2 values ('1 - 00', '2 - 00');
+insert into t2 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 02', '2 - 00');
+
+select * from t1
+where (a1, a2) not in (select * from t2 where b1 is not null and b2 is not null);
+
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+
+select * from t1
+where (a1, a2) in (select * from t2 where b1 is not null and b2 is not null);
+
+select a1, a2, (a1, a2) in (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo NULLs in the outer column, NULLs in the subquery, there is
+--echo no value match in any column, but there is a partial match
+--echo such that some of the matching NULLs are in the outer columns,
+--echo the other NULLs are in the inner columns.
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(1), a2 char(1), a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+
+insert into t1 values ('c', NULL, 'a');
+insert into t2 values (NULL, 'x', NULL);
+insert into t2 values (NULL, 'y', NULL);
+insert into t2 values ('o', 'z', 'p');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch = @test_default_opt_switch;
+
+drop table t1, t2;
+
+create table t1 (a1 char(1), a2 char(1) not null, a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+
+insert into t1 values (NULL, 'y', NULL);
+insert into t2 values ('v', 'x', NULL);
+insert into t2 values (NULL, 'y', 'w');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch = @test_default_opt_switch;
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo There is only one column in the subquery to complement the NULLs in the
+--echo outer reference. It is a NULL column, so a match is guaranteed.
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(1), a2 char(1), a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+
+insert into t1 values (NULL, 'g', NULL);
+insert into t2 values ('z', NULL, 'y');
+insert into t2 values (NULL, 'z', 'y');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch = @test_default_opt_switch;
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo The intersection of the NULL bitmaps is empty because the ranges
+--echo of NULL bits do not overlap.
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(1), a2 char(1), a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+
+insert into t1 values ('b', 'g', NULL);
+insert into t2 values ('z', NULL, 'y');
+insert into t2 values (NULL, 'z', 'y');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo The intersection of the NULL bitmaps is non-empty, and there is a
+--echo non-NULL column.
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(1), a2 char(1), a3 char(1) not null, a4 char(10));
+create table t2 (b1 char(1), b2 char(1), b3 char(1), b4 char(1));
+
+insert into t1 values ('a', 'g', 'x', NULL);
+insert into t2 values ('z', NULL, 'y', 'x');
+insert into t2 values (NULL, NULL, 'x', 'y');
+insert into t2 values ('x', 'w', 'z', NULL);
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo Value match in one row, but the NULL complement match in another.
+--echo The result must be false.
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(2), a2 char(1), a3 char(1) not null, a4 char(10));
+create table t2 (b1 char(2), b2 char(1), b3 char(1), b4 char(1));
+
+insert into t1 values ('99', NULL, 'j', 'f');
+
+insert into t2 values ('01', NULL, 'y', NULL);
+insert into t2 values ('02', NULL, 'x', 'y');
+insert into t2 values ('03', 'q', 'y', 'x');
+insert into t2 values (NULL, 'q', 'm', 'p');
+insert into t2 values ('m', 'z', 'j', NULL);
+insert into t2 values (NULL, 'z', 'b', NULL);
+insert into t2 values (NULL, 'z', 'a', NULL);
+insert into t2 values ('34', 'q', 'y', 'x');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo Test the intersection of larger number of rows with NULL, such that
+--echo the number is at the boundary 32. This test is based on the implementation
+--echo of MY_BITMAP which uses 32 bit words, and the intersection operation works
+--echo by intersecting the bitmap word by word.
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(2), a2 char(2), a3 char(1), a4 char(10)) ENGINE=MyISAM;
+create table t2 (b1 char(2), b2 char(2), b3 char(1), b4 char(1)) ENGINE=MyISAM;
+
+insert into t1 values (NULL, '98', NULL, 'b');
+insert into t1 values (NULL, '99', NULL, 'c');
+
+insert into t2 values ('00', 'rr', 'y', NULL);
+insert into t2 values ('01', 'rr', 'y', NULL);
+insert into t2 values ('02', NULL, 'x', 'y');
+insert into t2 values ('03', 'qq', 'y', 'x');
+insert into t2 values ('04', 'qq', 'm', 'p');
+insert into t2 values ('05', 'rr', 'y', NULL);
+insert into t2 values ('06', NULL, 'x', 'y');
+insert into t2 values ('07', 'qq', 'y', 'x');
+insert into t2 values ('08', 'qq', 'm', 'q');
+insert into t2 values ('09', 'rr', 'y', NULL);
+insert into t2 values ('10', NULL, 'x', 'y');
+insert into t2 values ('11', 'qq', 'y', 'x');
+insert into t2 values ('12', 'qq', 'm', 'k');
+insert into t2 values ('13', 'rr', 'y', NULL);
+insert into t2 values ('14', NULL, 'x', 'y');
+insert into t2 values ('15', 'qq', 'y', 'x');
+insert into t2 values ('16', 'qq', 'm', 's');
+insert into t2 values ('17', 'rr', 'y', NULL);
+insert into t2 values ('18', NULL, 'x', 'y');
+insert into t2 values ('19', 'qq', 'y', 'x');
+insert into t2 values ('20', 'qq', 'm', 't');
+insert into t2 values ('21', 'rr', 'y', NULL);
+insert into t2 values ('22', NULL, 'x', 'y');
+insert into t2 values ('23', 'qq', 'y', 'x');
+insert into t2 values ('24', 'qq', 'm', 'u');
+insert into t2 values ('25', 'rr', 'y', NULL);
+insert into t2 values ('26', NULL, 'x', 'y');
+insert into t2 values ('27', 'qq', 'y', 'x');
+insert into t2 values ('28', 'qq', 'm', 'y');
+insert into t2 values ('29', 'rr', 'y', NULL);
+insert into t2 values ('30', NULL, 'x', 'z');
+insert into t2 values ('31', 'ss', 'h', NULL);
+insert into t2 values ('32', 'vv', 'i', NULL);
+--echo the only partial matching row
+insert into t2 values ('33', NULL, 'j', NULL);
+insert into t2 values ('34', 'qq', 'y', 'x');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+--echo change the mathcing row to be the last one in the first bitmap word
+update t2 set b2 = 'zz' where b1 = 33;
+update t2 set b2 = NULL where b1 = 31;
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+drop table t1, t2;
+
+
+--echo -------------------------------------------------------------------------
+--echo All columns require partial matching (no non-null columns)
+--echo -------------------------------------------------------------------------
+
+--echo TODO
+
+--echo -------------------------------------------------------------------------
+--echo Both non-NULL columns and columns with NULLs
+--echo -------------------------------------------------------------------------
+
+--echo TODO
+
+--echo -------------------------------------------------------------------------
+--echo Covering NULL rows
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(8), a2 char(8));
+create table t2 (b1 char(8), b2 char(8));
+
+insert into t1 values ('1 - 00', '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+
+insert into t2 values ('1 - 01', NULL );
+insert into t2 values (NULL , '2 - 02');
+insert into t2 values (NULL , NULL );
+insert into t2 values ('1 - 02', '2 - 02');
+
+select * from t1
+where (a1, a2) not in (select * from t2);
+
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+
+insert into t2 values ('1 - 01', '2 - 01');
+
+select * from t1
+where (a1, a2) not in (select * from t2);
+
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+
+select * from t1
+where (a1, a2) in (select * from t2);
+
+select a1, a2, (a1, a2) in (select * from t2) as in_res from t1;
+
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo Covering NULL columns
+--echo -------------------------------------------------------------------------
+
+--echo this case affects only the rowid-merge algorithm
+set @@optimizer_switch="partial_match_rowid_merge=on,partial_match_table_scan=off";
+
+create table t1 (a1 char(8) not null, a2 char(8), a3 char(8) not null);
+create table t2 (b1 char(8) not null, b2 char(8), b3 char(8) not null);
+
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+
+insert into t2 values ('1 - 01', NULL, '3 - x1');
+insert into t2 values ('1 - 02', NULL, '3 - 02');
+insert into t2 values ('1 - 00', NULL, '3 - 00');
+
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+create table t1 (a1 char(8), a2 char(8), a3 char(8) not null);
+create table t2 (b1 char(8), b2 char(8), b3 char(8) not null);
+
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+
+insert into t2 values (NULL, NULL, '3 - x1');
+insert into t2 values (NULL, NULL, '3 - 02');
+insert into t2 values (NULL, NULL, '3 - 00');
+
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo Covering NULL row, and a NULL column
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(8) not null, a2 char(8), a3 char(8));
+create table t2 (b1 char(8), b2 char(8), b3 char(8));
+
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+
+insert into t2 values ('1 - 01', NULL, '3 - x1');
+insert into t2 values (NULL , NULL, NULL );
+insert into t2 values ('1 - 00', NULL, '3 - 00');
+
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+
+--echo -------------------------------------------------------------------------
+--echo Covering NULL row, and covering NULL columns
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(8) not null, a2 char(8), a3 char(8));
+create table t2 (b1 char(8), b2 char(8), b3 char(8));
+
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+
+insert into t2 values (NULL, NULL, NULL);
+insert into t2 values (NULL, NULL, NULL);
+
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo Small buffer for the rowid_merge partial match algorithm that forces
+--echo reverting to table scan partial match.
+--echo -------------------------------------------------------------------------
+
+set @save_rowid_merge_buff_size = @@rowid_merge_buff_size;
+set @@rowid_merge_buff_size = 0;
+
+create table t1 (a1 char(2), a2 char(2), a3 char(1), a4 char(10));
+create table t2 (b1 char(2), b2 char(2), b3 char(1), b4 char(1));
+
+insert into t1 values (NULL, '98', NULL, 'b');
+insert into t1 values (NULL, '99', NULL, 'c');
+
+insert into t2 values ('00', 'rr', 'y', NULL);
+insert into t2 values ('01', 'rr', 'y', NULL);
+insert into t2 values ('02', NULL, 'x', 'y');
+insert into t2 values ('03', 'qq', 'y', 'x');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+set @@rowid_merge_buff_size = @save_rowid_merge_buff_size;
+
+
+--echo -------------------------------
+--echo Part 2: Test cases for bugs.
+--echo -------------------------------
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+--echo #
+--echo # LP BUG#608744
+--echo #
+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;
+
+
+--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 @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on';
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT * FROM t1 WHERE a1 NOT IN (SELECT b2 FROM t2)) table1;
+set optimizer_switch=@tmp_optimizer_switch;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # LP BUG#613009 Crash in Ordered_key::get_field_idx
+--echo #
+
+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;
+
+--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 @@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);
+drop table t1, t2;
+
+
+--echo #
+--echo # LP BUG#809245 Second assertion `bit < (map)->n_bits' with partial_match_merge
+--echo #
+
+CREATE TABLE t1 (d varchar(32)) ;
+INSERT INTO t1 VALUES ('r');
+
+CREATE TABLE t2 ( a int, c varchar(32)) ;
+INSERT INTO t2 VALUES (5,'r');
+
+CREATE TABLE t3 ( a int NOT NULL , d varchar(32)) ;
+INSERT INTO t3 VALUES (10,'g');
+
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+
+EXPLAIN SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+ SELECT t3.d , t2.c
+ FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+
+SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+ SELECT t3.d , t2.c
+ FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+
+EXPLAIN SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+ SELECT t3.d , t2.c
+ FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+
+SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+ SELECT t3.d , t2.c
+ FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # LP BUG#809266 Diverging results with partial_match_rowid_merge=on
+--echo #
+
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (0),(0);
+
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (6,3), (9,NULL);
+
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+
+drop table t1, t2;
+
+--echo #
+--echo # LP BUG#856152 Wrong result with NOT IN subquery and partial_match_rowid_merge
+--echo #
+
+CREATE TABLE t1 ( f1 integer NOT NULL , f2 integer) ;
+INSERT INTO t1 VALUES (3,3),(48,NULL),(49,1);
+
+CREATE TABLE t2 ( f3 int) ;
+INSERT INTO t2 VALUES (5);
+
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+
+set @@optimizer_switch='in_to_exists=on,materialization=off';
+EXPLAIN SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+
+drop table t1, t2;
+
+--echo #
+--echo # LP BUG#869036 Wrong result with in_to_exists=ON and NOT IN
+--echo #
+
+create table outer_sq (f1 char(1), f2 char(1));
+insert into outer_sq values (NULL, 'c'), ('g', 'c');
+
+create table inner_sq (f3 char(1), f4 char(1));
+insert into inner_sq values(null, 'i'), ('v', null);
+
+--echo All three strategies below must produce the same result.
+
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+SELECT outer_sq.*, (f1, f2) IN (select * from inner_sq) from outer_sq;
+SELECT * from outer_sq where (f1, f2) NOT IN (select * from inner_sq);
+
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=off,partial_match_table_scan=on';
+SELECT outer_sq.*, (f1, f2) IN (select * from inner_sq) from outer_sq;
+SELECT * from outer_sq where (f1, f2) NOT IN (select * from inner_sq);
+
+set @@optimizer_switch='in_to_exists=on,materialization=off';
+SELECT outer_sq.*, (f1, f2) IN (select * from inner_sq) from outer_sq;
+SELECT * from outer_sq where (f1, f2) NOT IN (select * from inner_sq);
+
+drop table outer_sq, inner_sq;
+
+--echo #
+--echo # LP BUG#893486 Wrong result with partial_match_rowid_merge , NOT IN , NULLs
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (0,NULL),(2,NULL);
+
+CREATE TABLE t2 (c int, d int);
+INSERT INTO t2 VALUES (2,3),(4,5),(6, NULL);
+
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+
+EXPLAIN SELECT * FROM t1 WHERE (a, b) NOT IN (SELECT c, d FROM t2);
+SELECT * FROM t1 WHERE (a, b) NOT IN (SELECT c, d FROM t2);
+SELECT a, b, (a, b) NOT IN (SELECT c, d FROM t2) subq_res FROM t1;
+
+EXPLAIN SELECT * FROM t1 WHERE (a, b) NOT IN (SELECT c, d FROM t2 WHERE d is not NULL);
+SELECT * FROM t1 WHERE (a, b) NOT IN (SELECT c, d FROM t2 WHERE d is not NULL);
+SELECT a, b, (a, b) NOT IN (SELECT c, d FROM t2 WHERE d is not NULL) subq_res FROM t1;
+
+drop table t1,t2;
+
+set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test
new file mode 100644
index 00000000000..650c9d73893
--- /dev/null
+++ b/mysql-test/t/subselect_sj.test
@@ -0,0 +1,2486 @@
+#
+# Nested Loops semi-join subquery evaluation tests
+#
+--disable_warnings
+drop table if exists t0, t1, t2, t3, t4, t5, t10, t11, t12;
+drop view if exists v1, v2, v3, v4;
+drop procedure if exists p1;
+--enable_warnings
+
+set @subselect_sj_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj_test,'outer_join_with_cache=off');
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj_test,'semijoin_with_cache=off');
+if (`select @join_cache_level_for_subselect_sj_test is null`)
+{
+ set join_cache_level=1;
+}
+if (`select @join_cache_level_for_subselect_sj_test is not null`)
+{
+ set join_cache_level=@join_cache_level_for_subselect_sj_test;
+}
+
+# The 'default' value within the scope of this test:
+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
+);
+--disable_parsing # wrong duplicate results - LP BUG#702374
+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
+);
+--enable_parsing
+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);
+--sorted_result
+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;
+
+--echo #
+--echo # Bug#46692 "Crash occurring on queries with nested FROM subqueries
+--echo # using materialization."
+--echo #
+CREATE TABLE t1 (
+ pk INTEGER PRIMARY KEY,
+ int_key INTEGER,
+ KEY int_key(int_key)
+);
+INSERT INTO t1 VALUES (10,186),(11,NULL),(12,2),(13,3),(14,0),(15,133),(16,1);
+
+CREATE TABLE t2 (
+ pk INTEGER PRIMARY KEY,
+ int_key INTEGER,
+ KEY int_key(int_key)
+);
+INSERT INTO t2 VALUES (1,7),(2,2);
+
+SELECT * FROM t1 WHERE (140, 4) IN
+ (SELECT t2.int_key, t2 .pk FROM t2 STRAIGHT_JOIN t1 ON t2.int_key);
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug#42353 "SELECT ... WHERE oe IN (SELECT w/ LEFT JOIN) query
+--echo # causes crash."
+--echo #
+CREATE TABLE t1 (
+ pk INTEGER PRIMARY KEY,
+ int_nokey INTEGER,
+ int_key INTEGER,
+ date_key DATE,
+ datetime_nokey DATETIME,
+ varchar_nokey VARCHAR(1)
+);
+
+CREATE TABLE t2 (
+ date_nokey DATE
+);
+
+CREATE TABLE t3 (
+ pk INTEGER PRIMARY KEY,
+ int_nokey INTEGER,
+ date_key date,
+ varchar_key VARCHAR(1),
+ varchar_nokey VARCHAR(1),
+ KEY date_key (date_key)
+);
+
+SELECT date_key FROM t1
+WHERE (int_key, int_nokey)
+ IN (SELECT t3.int_nokey, t3.pk
+ FROM t2 LEFT JOIN t3 ON (t2.date_nokey < t3.date_key)
+ WHERE t3.varchar_key <= t3.varchar_nokey OR t3.int_nokey <= t3.pk
+ )
+ AND (varchar_nokey <> 'f' OR NOT int_key < 7);
+
+
+--echo #
+--echo # Bug#45933 "Crash in optimize_semijoin_nests on JOIN in subquery
+--echo # + AND in outer query".
+--echo #
+INSERT INTO t1 VALUES (10,7,5,'2009-06-16','2002-04-10 14:25:30','w'),
+ (11,7,0,'0000-00-00','0000-00-00 00:00:00','s'),
+ (12,4,0,'2003-07-14','2006-09-14 04:01:02','y'),
+ (13,0,4,'2002-07-25','0000-00-00 00:00:00','c'),
+ (14,1,8,'2007-07-03','0000-00-00 00:00:00','q'),
+ (15,6,5,'2001-11-12','0000-00-00 00:00:00',''),
+ (16,2,9,'0000-00-00','0000-00-00 00:00:00','j'),
+ (29,9,1,'0000-00-00','2003-08-11 00:00:00','m');
+INSERT INTO t3 VALUES (1,9,'0000-00-00','b','b'),
+ (2,2,'2002-09-17','h','h');
+
+SELECT t1.varchar_nokey FROM t1 JOIN t3 ON t1.datetime_nokey
+WHERE t1.varchar_nokey
+ IN (SELECT varchar_nokey FROM t1
+ WHERE (pk)
+ IN (SELECT t3.int_nokey
+ FROM t3 LEFT JOIN t1 ON t1.varchar_nokey
+ WHERE t3.date_key BETWEEN '2008-06-07' AND '2006-06-26'
+ )
+ );
+
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # Bug#45219 "Crash on SELECT DISTINCT query containing a
+--echo # LEFT JOIN in subquery"
+--echo #
+
+CREATE TABLE t1 (
+ pk INTEGER NOT NULL,
+ int_nokey INTEGER 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)
+);
+INSERT INTO t1 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 t2 LIKE t1;
+INSERT INTO t2 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 t3 LIKE t1;
+INSERT INTO t3 VALUES
+(10,8,'2007-08-19 08:08:38','i'),(11,0,'2000-05-21 03:51:51','');
+
+SELECT DISTINCT datetime_key FROM t1
+WHERE (int_nokey, pk)
+ IN (SELECT t3.pk, t3.pk FROM t2 LEFT JOIN t3 ON t3.varchar_key)
+ AND pk = 9;
+
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # BUG#53060: LooseScan semijoin strategy does not return all rows
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=off';
+set optimizer_switch='firstmatch=off,loosescan=on';
+
+CREATE TABLE t1 (i INTEGER);
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
+CREATE TABLE t2 (i INTEGER, j INTEGER, KEY k(i, j));
+INSERT INTO t2 VALUES (1, 0), (1, 1), (2, 0), (2, 1);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0);
+SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0);
+
+DROP TABLE t1, t2;
+
+set optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # BUG#49453: re-execution of prepared statement with view
+--echo # and semijoin crashes
+--echo #
+
+CREATE TABLE t1 (city VARCHAR(50), country_id INT);
+CREATE TABLE t2 (country_id INT, country VARCHAR(50));
+
+INSERT INTO t1 VALUES
+ ('Batna',2),('Bchar',2),('Skikda',2),('Tafuna',3),('Algeria',2) ;
+INSERT INTO t2 VALUES (2,'Algeria'),(2,'AlgeriaDup'),(3,'XAmerican Samoa');
+
+CREATE VIEW v1 AS
+ SELECT country_id as vf_country_id
+ FROM t2
+ WHERE LEFT(country,1) = "A";
+
+PREPARE stmt FROM "
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (SELECT vf_country_id FROM v1);
+";
+
+--echo
+EXECUTE stmt;
+EXECUTE stmt;
+
+DROP TABLE t1,t2;
+DROP VIEW v1;
+
+--echo #
+--echo # Bug#54437 Extra rows with LEFT JOIN + semijoin
+--echo #
+
+create table t1 (a int);
+create table t2 (a int);
+create table t3 (a int);
+insert into t1 values(1),(1);
+insert into t2 values(1),(1),(1),(1);
+insert into t3 values(2),(2);
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+set optimizer_switch='materialization=off';
+
+set optimizer_switch='semijoin=off';
+explain
+select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a);
+select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a);
+
+set optimizer_switch='semijoin=on';
+explain
+select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a);
+select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a);
+
+set optimizer_switch=@save_optimizer_switch;
+
+drop table t1,t2,t3;
+
+--echo #
+--echo # Bug#55955: crash in MEMORY engine with IN(LEFT JOIN (JOIN))
+--echo #
+
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+CREATE TABLE t3 (a INT);
+INSERT INTO t1 VALUES(1),(1);
+INSERT INTO t2 VALUES(1),(1);
+INSERT INTO t3 VALUES(2),(2);
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+set optimizer_switch='semijoin=off,materialization=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+ FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+ FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+
+set optimizer_switch='semijoin=off,materialization=on';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+ FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+ FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+
+set optimizer_switch='semijoin=on,materialization=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+ FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+SELECT * FROM t1
+WHERE t1.a IN (SELECT t2.a
+ FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a);
+
+set optimizer_switch=@save_optimizer_switch;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # BUG#52329 - Wrong result: subquery materialization, IN,
+--echo # non-null field followed by nullable
+--echo #
+
+CREATE TABLE t1 (a1 CHAR(8) NOT NULL, a2 char(8) NOT NULL);
+
+CREATE TABLE t2a (b1 char(8), b2 char(8));
+CREATE TABLE t2b (b1 CHAR(8), b2 char(8) NOT NULL);
+CREATE TABLE t2c (b1 CHAR(8) NOT NULL, b2 char(8));
+
+INSERT INTO t1 VALUES ('1 - 12', '2 - 22');
+
+INSERT INTO t2a VALUES ('1 - 11', '2 - 21'),
+ ('1 - 11', '2 - 21'),
+ ('1 - 12', '2 - 22'),
+ ('1 - 12', '2 - 22'),
+ ('1 - 13', '2 - 23');
+
+INSERT INTO t2b SELECT * FROM t2a;
+INSERT INTO t2c SELECT * FROM t2a;
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+set optimizer_switch='semijoin=off,materialization=on';
+
+SELECT * FROM t1
+WHERE (a1, a2) IN (
+ SELECT b1, b2 FROM t2c WHERE b1 > '0' GROUP BY b1, b2);
+
+SELECT * FROM t1
+WHERE (a1, a2) IN (
+ SELECT b1, b2 FROM t2a WHERE b1 > '0');
+
+
+SELECT * FROM t1
+WHERE (a1, a2) IN (
+ SELECT b1, b2 FROM t2b WHERE b1 > '0');
+
+
+SELECT * FROM t1
+WHERE (a1, a2) IN (
+ SELECT b1, b2 FROM t2c WHERE b1 > '0');
+
+set optimizer_switch=@save_optimizer_switch;
+
+DROP TABLE t1,t2a,t2b,t2c;
+
+--echo #
+--echo # Bug#57623: subquery within before insert trigger causes crash (sj=on)
+--echo #
+
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+
+let $query=
+SELECT *
+FROM ot1
+ LEFT JOIN
+ (ot2 JOIN ot3 on ot2.a=ot3.a)
+ ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+set optimizer_switch='semijoin=on';
+
+set optimizer_switch='materialization=off';
+eval explain $query;
+eval $query;
+eval prepare s from '$query';
+execute s;
+execute s;
+deallocate prepare s;
+
+set optimizer_switch='materialization=on';
+eval explain $query;
+eval $query;
+eval prepare s from '$query';
+execute s;
+execute s;
+deallocate prepare s;
+
+set optimizer_switch=@save_optimizer_switch;
+
+DROP TABLE ot1, ot2, ot3, it1;
+
+--echo #
+--echo # Bug#59919/11766739: Crash in tmp_table_param::init() with semijoin=on
+--echo #
+
+CREATE TABLE t1 (f1 INTEGER) ENGINE=MyISAM;
+CREATE TABLE t2 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM;
+CREATE TABLE t3 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM;
+
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1,1), (2,1);
+INSERT INTO t3 VALUES
+ (1,1), (2,1), (5,4), (7,3), (8,2), (8,1), (7,3),
+ (9,5), (4,3), (7,2), (7,7), (3,1), (5,8), (9,7);
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+set optimizer_switch='semijoin=off,materialization=on';
+EXPLAIN
+SELECT * FROM t3
+WHERE f2 IN (SELECT t1.f1
+ FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE);
+SELECT * FROM t3
+WHERE f2 IN (SELECT t1.f1
+ FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE);
+
+set optimizer_switch='semijoin=on,materialization=on';
+EXPLAIN
+SELECT * FROM t3
+WHERE f2 IN (SELECT t1.f1
+ FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE);
+SELECT * FROM t3
+WHERE f2 IN (SELECT t1.f1
+ FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE);
+
+set optimizer_switch=@save_optimizer_switch;
+
+DROP TABLE t1, t2, t3 ;
+
+--echo #
+--echo #
+--echo # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3
+--echo #
+CREATE TABLE t1 ( t1field integer, primary key (t1field));
+CREATE TABLE t2 ( t2field integer, primary key (t2field));
+INSERT INTO t1 VALUES (1),(2),(3);
+INSERT INTO t2 VALUES (2),(3),(4);
+explain
+SELECT * FROM t1 A
+WHERE
+ A.t1field IN (SELECT A.t1field FROM t2 B) AND
+ A.t1field IN (SELECT C.t2field FROM t2 C
+ WHERE C.t2field IN (SELECT D.t2field FROM t2 D));
+SELECT * FROM t1 A
+WHERE
+ A.t1field IN (SELECT A.t1field FROM t2 B) AND
+ A.t1field IN (SELECT C.t2field FROM t2 C
+ WHERE C.t2field IN (SELECT D.t2field FROM t2 D));
+drop table t1,t2;
+
+--echo #
+--echo # BUG#787299: Valgrind complains on a join query with two IN subqueries
+--echo #
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+create table t2 as select * from t1;
+select * from t1 A, t1 B
+ where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D);
+explain
+select * from t1 A, t1 B
+ where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D);
+drop table t1, t2;
+
+--echo #
+--echo # BUG#784441: Abort on semijoin with a view as the inner table
+--echo #
+
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (1), (1);
+
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (1), (1);
+
+CREATE VIEW v1 AS SELECT 1;
+
+EXPLAIN
+SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
+SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # BUG#751439 Assertion `!table->file || table->file->inited == handler::NONE' failed with subquery
+--echo #
+CREATE TABLE t1 ( f10 int, f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0,0),(0,0);
+
+CREATE TABLE t2 ( f11 int);
+INSERT IGNORE INTO t2 VALUES (0),(0);
+
+CREATE TABLE t3 ( f11 int) ;
+INSERT IGNORE INTO t3 VALUES (0);
+
+SELECT alias1.f11 AS field2
+FROM ( t3 AS alias2 JOIN t1 AS alias3 ON alias3.f10 = 1)
+LEFT JOIN ( t2 AS alias1 ) ON alias3.f11 = 1
+WHERE alias2.f11 IN ( SELECT f11 FROM t2 )
+GROUP BY field2 ;
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # BUG#778406 Crash in hp_movelink with Aria engine and subqueries
+--echo #
+CREATE TABLE t4 (f10 varchar(32) , KEY (f10)) ENGINE=Aria;
+INSERT INTO t4 VALUES ('x'),('m'),('c');
+
+CREATE TABLE t1 (f11 int) ENGINE=Aria;
+INSERT INTO t1 VALUES (0),(0),(0);
+
+CREATE TABLE t2 ( f10 int) ENGINE=Aria;
+INSERT INTO t2 VALUES (0),(0),(0);
+
+CREATE TABLE t3 ( f10 int, f11 int) ENGINE=Aria;
+
+SELECT *
+FROM t4
+WHERE f10 IN
+( SELECT t1.f11
+FROM t1
+LEFT JOIN t2 JOIN t3 ON t3.f10 = t2.f10 ON t3.f11 != 0 );
+
+drop table t1,t2,t3,t4;
+
+--echo #
+--echo # BUG#751484: Valgrind warning / sporadic crash in evaluate_join_record sql_select.cc:14099 with semijoin
+--echo #
+
+CREATE TABLE t1 ( f10 int, f11 int, KEY (f10));
+INSERT IGNORE INTO t1 VALUES (0, 0),(0, 0);
+
+CREATE TABLE t3 ( f10 int);
+INSERT IGNORE INTO t3 VALUES (0);
+
+set @tmp_751484= @@optimizer_switch;
+set optimizer_switch='materialization=on';
+SELECT * FROM t1
+WHERE f11 IN (
+ SELECT C_SQ1_alias1.f11
+ FROM t1 AS C_SQ1_alias1
+ JOIN t3 AS C_SQ1_alias2
+ ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10
+);
+set optimizer_switch='materialization=off';
+SELECT * FROM t1
+WHERE f11 IN (
+ SELECT C_SQ1_alias1.f11
+ FROM t1 AS C_SQ1_alias1
+ JOIN t3 AS C_SQ1_alias2
+ ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10
+);
+set optimizer_switch=@tmp_751484;
+drop table t1, t3;
+
+#
+--echo # BUG#795530 Wrong result with subquery semijoin materialization and outer join
+--echo # Simplified testcase that uses DuplicateElimination
+--echo #
+create table t1 (a int);
+create table t2 (a int, b char(10));
+
+insert into t1 values (1),(2);
+insert into t2 values (1, 'one'), (3, 'three');
+
+create table t3 (b char(10));
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+explain select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
+select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
+drop table t1, t2, t3;
+
+--echo #
+--echo # BUG#600958 RQG: Crash in optimize_semijoin_nests
+--echo #
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_key int(11) DEFAULT NULL,
+ col_date_key date DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY col_int_key (col_int_key),
+ KEY col_date_key (col_date_key),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (10,8,'2002-02-21',NULL);
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_key int(11) DEFAULT NULL,
+ col_date_key date DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY col_int_key (col_int_key),
+ KEY col_date_key (col_date_key),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (1,7,'1900-01-01','f');
+
+SELECT col_date_key FROM t1
+WHERE 5 IN (
+ SELECT SUBQUERY3_t1 .col_int_key
+ FROM t2 SUBQUERY3_t1
+ LEFT JOIN t1 SUBQUERY3_t2 ON SUBQUERY3_t1 .col_varchar_key
+);
+drop table t2, t1;
+
+
+--echo #
+--echo # No BUG#: Duplicate weedout check is not done for outer joins
+--echo #
+create table t1 (a int);
+create table t2 (a int);
+
+insert into t1 values (1),(1),(2),(2);
+insert into t2 values (1);
+
+create table t0 (a int);
+insert into t0 values (1),(2);
+
+set @tmp_20110622= @@optimizer_switch;
+set optimizer_switch='firstmatch=off,loosescan=off,materialization=off';
+--echo # Check DuplicateWeedout + join buffer
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+
+--echo # Check DuplicateWeedout without join buffer
+set @tmp_jcl_20110622= @@join_cache_level;
+set join_cache_level= 0;
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+
+
+--echo # Check FirstMatch without join buffer:
+set optimizer_switch='firstmatch=on';
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+
+--echo #
+--echo # Now, check the same for multiple inner tables:
+alter table t2 add b int;
+update t2 set b=a;
+create table t3 as select * from t2;
+
+set optimizer_switch='firstmatch=off';
+set join_cache_level= 0;
+--echo # DuplicateWeedout without join buffer
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+
+set @@join_cache_level=@tmp_jcl_20110622;
+--echo # DuplicateWeedout + join buffer
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+
+--echo # Now, let the inner join side have a 'partial' match
+select * from t3;
+insert into t3 values(2,2);
+
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+
+set @@optimizer_switch=@tmp_20110622;
+
+drop table t0, t1, t2, t3;
+
+--echo #
+--echo # BUG#802965: Crash in do_copy_not_null with semijoin=on in maria-5.3
+--echo #
+set @save_802965= @@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=off,firstmatch=off,loosescan=off';
+
+CREATE TABLE t2 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t2 VALUES (19),(20);
+
+CREATE TABLE t1 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t1 VALUES (21),(22),(23),(24);
+
+SELECT *
+FROM t2 , t1
+WHERE t2.f1 IN
+(
+ SELECT SQ1_alias1.f1
+ FROM t1 AS SQ1_alias1 LEFT JOIN t2 AS SQ1_alias2 JOIN t2 AS SQ1_alias3 ON SQ1_alias3.f1 ON SQ1_alias3.f1
+)
+AND t1.f1 = t2.f1 ;
+
+DROP TABLE t1, t2;
+set optimizer_switch=@save_802965;
+
+--echo #
+--echo # BUG#803365: Crash in pull_out_semijoin_tables with outer join + semijoin + derived tables in maria-5.3 with WL#106
+--echo #
+CREATE TABLE t1 ( f1 int) ;
+INSERT INTO t1 VALUES (1),(1);
+
+CREATE TABLE t2 ( f2 int) ;
+INSERT INTO t2 VALUES (1),(1);
+
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (1),(1);
+
+SELECT *
+FROM t1
+WHERE t1.f1 IN (
+ SELECT t2.f2
+ FROM t2
+ LEFT JOIN (
+ SELECT *
+ FROM t3
+ ) AS alias1
+ ON alias1.f3 = t2.f2
+);
+
+DROP TABLE t1,t2,t3;
+
+
+--echo #
+--echo # BUG#611704: Crash in replace_where_subcondition with nested subquery and semijoin=on
+--echo #
+
+CREATE TABLE t1 ( f1 int) ;
+CREATE TABLE t2 ( f1 int) ;
+CREATE TABLE t3 ( f1 int) ;
+
+SELECT * FROM (
+ SELECT t3.*
+ FROM t2 STRAIGHT_JOIN t3
+ ON t3.f1
+ AND (t3.f1 ) IN (
+ SELECT t1.f1
+ FROM t1
+ )
+) AS alias1;
+DROP TABLE t1,t2,t3;
+
+--echo # BUG#611704: another testcase:
+CREATE TABLE t1 ( f1 int(11), f3 varchar(1), f4 varchar(1)) ;
+CREATE TABLE t2 ( f2 int(11), KEY (f2));
+CREATE TABLE t3 ( f4 varchar(1)) ;
+
+PREPARE st1 FROM '
+SELECT *
+FROM t1
+STRAIGHT_JOIN ( t2 STRAIGHT_JOIN t3 ON t2.f2 )
+ON (t1.f3) IN ( SELECT f4 FROM t1 )
+';
+EXECUTE st1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90
+--echo # (Original testcase)
+--echo #
+
+CREATE TABLE t1 (f1 int, f2 int );
+INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL);
+
+CREATE TABLE t2 (f2 int, f3 int );
+INSERT INTO t2 VALUES (NULL,NULL),(0,0);
+
+CREATE TABLE t3 ( f1 int, f3 int );
+INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0);
+
+CREATE TABLE t4 ( f2 int, KEY (f2) );
+INSERT INTO t4 VALUES (0),(NULL);
+
+CREATE VIEW v4 AS SELECT DISTINCT f2 FROM t4 ;
+
+--echo # The following must not have outer joins:
+explain extended
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
+
+drop view v4;
+drop table t1, t2, t3, t4;
+
+--echo #
+--echo # BUG#803303: Wrong result with semijoin=on, outer join in maria-5.3-subqueries-mwl90
+--echo #
+
+--echo # Testcase#1:
+set @tmp803303= @@optimizer_switch;
+set optimizer_switch = 'semijoin=on,materialization=off,firstmatch=off,loosescan=off';
+CREATE TABLE t2 ( f1 int) ;
+INSERT IGNORE INTO t2 VALUES (6),(8);
+CREATE TABLE t1 ( f1 int, f2 int, f3 int) ;
+INSERT IGNORE INTO t1 VALUES (8,0,0),(7,0,0),(9,0,0);
+SELECT alias2.f1
+FROM t2 AS alias1
+LEFT JOIN ( t1 AS alias2 JOIN t1 AS alias3 ON alias3.f2 = alias2.f3 )
+ON alias3.f2 = alias2.f2
+WHERE alias2.f1 IN ( SELECT f1 FROM t2 AS alias4 ) ;
+drop table t1,t2;
+set optimizer_switch= @tmp803303;
+
+--echo # Testcase #2:
+CREATE TABLE t1 ( f10 int) ;
+INSERT INTO t1 VALUES (0),(0);
+
+CREATE TABLE t2 ( f10 int, f11 varchar(1)) ;
+INSERT INTO t2 VALUES (0,'a'),(0,'b');
+
+CREATE TABLE t3 ( f10 int) ;
+INSERT INTO t3 VALUES (0),(0),(0),(0),(0);
+
+CREATE TABLE t4 ( f10 varchar(1), f11 int) ;
+INSERT INTO t4 VALUES ('a',0),('b',0);
+
+SELECT * FROM t1
+LEFT JOIN ( t2 JOIN t3 ON t3.f10 = t2.f10 ) ON t1.f10 = t2.f10
+WHERE t2.f10 IN (
+ SELECT t4.f11
+ FROM t4
+ WHERE t4.f10 != t2.f11
+);
+
+drop table t1,t2,t3,t4;
+
+--echo #
+--echo # BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90
+--echo #
+set @tmp803457=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+CREATE TABLE t1 (f1 int, f2 int );
+INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL);
+
+CREATE TABLE t2 (f2 int, f3 int );
+INSERT INTO t2 VALUES (NULL,NULL),(0,0);
+
+CREATE TABLE t3 ( f1 int, f3 int );
+INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0);
+
+CREATE TABLE t4 ( f2 int);
+INSERT INTO t4 VALUES (0),(NULL);
+
+--echo # The following uses Duplicate Weedout, and "End temporary" must not be
+--echo # in the middle of the inner side of an outer join:
+explain
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3 ) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
+
+DROP TABLE t1, t2, t3, t4;
+set @tmp803457=@@optimizer_switch;
+
+--echo #
+--echo # BUG#818280: crash in do_copy_not_null() in maria-5.3 with semijoin
+--echo #
+CREATE TABLE t1 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ;
+INSERT IGNORE INTO t1 VALUES (2,7),(1,3),(5,6);
+
+CREATE TABLE t3 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ;
+INSERT IGNORE INTO t3 VALUES (2,7),(1,3),(5,6);
+
+CREATE TABLE t2 ( c1 int NOT NULL , c5 int NOT NULL );
+INSERT IGNORE INTO t2 VALUES (2,2),(2,2),(5,6);
+
+SELECT * FROM t1 WHERE c1 IN ( SELECT t3.c1 FROM t3 LEFT JOIN t2 ON t2 .c1 = t3 .c1 WHERE t2.c5 != 0 );
+
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # BUG#834534: Assertion `0' failed in replace_where_subcondition with semijoin subquery in HAVING
+--echo #
+CREATE TABLE t1 ( d int );
+INSERT INTO t1 VALUES (2),(2),(0),(2),(2);
+
+CREATE TABLE t2 ( b int );
+INSERT INTO t2 VALUES (4),(3),(3);
+
+CREATE TABLE t3 ( a int );
+
+SELECT *
+FROM t3
+WHERE (t3.a) IN (
+ SELECT t1.d
+ FROM t1
+ HAVING ( 4 ) IN (
+ SELECT t2.b
+ FROM t2
+ )
+);
+drop table t1, t2,t3;
+
+--echo #
+--echo # BUG#834758: Wrong result with innner join, LooseScan, two-column IN() predicate
+--echo #
+
+set @tmp835758=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
+
+CREATE TABLE t1 (b int) ;
+INSERT INTO t1 VALUES (1),(5);
+
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (6),(10);
+
+CREATE TABLE t3 (a int, b int, KEY (b)) ;
+INSERT INTO t3 VALUES (6,5),(6,2),(8,0),(9,1),(6,5);
+
+--echo # This used to incorrectly pick a join order of (t1, LooseScan(t3), t2):
+explain
+SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
+SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
+
+DROP TABLE t1, t2, t3;
+set @@optimizer_switch= @tmp835758;
+
+--echo #
+--echo # BUG#834739: Wrong result with 3-way inner join, LooseScan,multipart keys
+--echo #
+set @tmp834739=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
+CREATE TABLE t2 ( b int, c int, KEY (b)) ;
+INSERT INTO t2 VALUES (1,0),(1,0),(9,0),(1,0),(5,0);
+INSERT INTO t2 VALUES (2,0),(3,0),(8,0),(6,0),(5,0);
+
+CREATE TABLE t3 ( a int);
+INSERT INTO t3 VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+
+CREATE TABLE t4 ( a int);
+INSERT INTO t4 VALUES (0),(0),(0);
+
+CREATE TABLE t5 ( b int, a int , KEY (a,b)) ;
+INSERT INTO t5 VALUES (7,0),(9,0);
+
+explain
+SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
+SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
+
+DROP TABLE t2, t3, t4, t5;
+set @@optimizer_switch=@tmp834739;
+
+--echo #
+--echo # BUG#830993: Crash in end_read_record with derived table
+--echo #
+set @tmp_830993=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=off,materialization=off,firstmatch=off';
+set @tmp_830993_jbs= @@join_buffer_size;
+--disable_warnings
+set join_buffer_size=160;
+--enable_warnings
+CREATE TABLE t1 (
+ a int(11) NOT NULL AUTO_INCREMENT,
+ b int(11) DEFAULT NULL,
+ c int(11) DEFAULT NULL,
+ d time DEFAULT NULL,
+ e varchar(1) DEFAULT NULL,
+ f varchar(1) DEFAULT NULL,
+ PRIMARY KEY (a),
+ KEY c (c),
+ KEY d (d),
+ KEY e (e,c)
+);
+INSERT INTO t1 VALUES (10,NULL,8,'22:55:23','x','x'),
+ (11,8,7,'10:19:31','d','d'),(12,1,1,'14:40:36','r','r'),
+ (13,9,7,'04:37:47','f','f'),(14,4,9,'19:34:06','y','y'),
+ (15,3,NULL,'20:35:33','u','u'),(16,2,1,NULL,'m','m'),
+ (17,NULL,9,'14:43:37',NULL,NULL),(18,2,2,'02:23:09','o','o'),
+ (19,NULL,9,'01:22:45','w','w'),(20,6,2,'00:00:00','m','m'),
+ (21,7,4,'00:13:25','q','q'),(22,2,0,'03:47:16',NULL,NULL),
+ (23,5,4,'01:41:48','d','d'),(24,7,8,'00:00:00','g','g'),
+ (25,6,NULL,'22:32:04','x','x'),(26,6,NULL,'16:44:14','f','f'),
+ (27,2,0,'17:38:37','p','p'),(28,9,NULL,'08:46:48','j','j'),
+ (29,6,8,'14:11:27','c','c');
+
+CREATE TABLE t2 like t1;
+INSERT INTO t2 VALUES (1,2,4,'22:34:09','v','v'),
+ (2,150,62,'14:26:02','v','v'),(3,NULL,7,'14:03:03','c','c'),
+ (4,2,1,'01:46:09',NULL,NULL),(5,5,0,'16:21:18','x','x'),
+ (6,3,7,'18:56:33','i','i'),(7,1,7,NULL,'e','e'),
+ (8,4,1,'09:29:08','p','p'),(9,NULL,7,'19:11:10','s','s'),
+ (10,2,1,'11:57:26','j','j'),(11,6,5,'00:39:46','z','z'),
+ (12,6,2,'03:28:15','c','c'),(13,8,0,'06:44:18','a','a'),
+ (14,2,1,'14:36:39','q','q'),(15,6,8,'18:42:45','y','y'),
+ (16,8,1,'02:57:29',NULL,NULL),(17,3,1,'16:46:13','r','r'),
+ (18,3,9,'19:39:02','v','v'),(19,9,1,NULL,NULL,NULL),
+ (20,6,5,'20:58:33','r','r');
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+
+explain
+SELECT
+ alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
+ alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
+ alias2.e as a2_e, alias2.f as a2_f,
+ t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
+FROM
+ (SELECT * FROM t2) AS alias1,
+ t1 AS alias2,
+ t2
+WHERE
+ alias1.c IN (SELECT SQ3_alias1.b
+ FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
+LIMIT 100;
+
+create table t3 as
+SELECT
+ alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
+ alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
+ alias2.e as a2_e, alias2.f as a2_f,
+ t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
+FROM
+ (SELECT * FROM t2) AS alias1,
+ t1 AS alias2,
+ t2
+WHERE
+ alias1.c IN (SELECT SQ3_alias1.b
+ FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
+LIMIT 100;
+
+set optimizer_switch=@tmp_optimizer_switch;
+
+drop table t1,t2, t3;
+set optimizer_switch=@tmp_830993;
+set join_buffer_size= @tmp_830993_jbs;
+
+--echo #
+--echo # BUG##849717: Crash in Item_func::fix_fields on second execution of a prepared statement with semijoin
+--echo #
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int, b int) ;
+
+PREPARE st1 FROM "SELECT * FROM t2 LEFT JOIN t1 ON t2.a != 0 AND ('j','r') IN ( SELECT b,a FROM t3)";
+EXECUTE st1;
+EXECUTE st1;
+
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # BUG#849776: Wrong result with semijoin + "Impossible where"
+--echo #
+CREATE TABLE t1 ( b varchar(1), a integer) ;
+INSERT INTO t1 VALUES ('z',8);
+
+CREATE TABLE t2 ( a integer, b varchar(1)) ;
+
+CREATE TABLE t4 ( a integer, b varchar(1)) ;
+
+CREATE TABLE t5 ( a integer) ;
+INSERT INTO t5 VALUES (8);
+
+select * from t5 where (a) in (
+ SELECT t1.a
+ FROM t1 LEFT JOIN t2 ON t1.a = t2.a
+ WHERE t2.b NOT IN (SELECT t4.b FROM t4 WHERE t4.b < t1.b)
+);
+
+DROP TABLE t1, t2, t4, t5;
+
+--echo #
+--echo # BUG#861147: Assertion `fixed == 1' failed in Item_func_eq::val_int() with semijoin + materialization + max_join_size
+--echo #
+#CREATE TABLE t1 ( f2 int) ;
+#CREATE TABLE t2 ( f1 int, f3 int, f4 varchar(3), f5 varchar(35)) ;
+#INSERT INTO t2 VALUES (4057,9,'USA','Visalia'),(3993,11,'USA','Waco'),
+# (3948,14,'USA','Warren'),(3813,57,'USA','Washington'),
+# (4010,11,'USA','Waterbury'),(4017,11,'USA','West Covina'),
+# (4004,11,'USA','West Valley City'),(4033,10,'USA','Westminster'),
+# (3842,34,'USA','Wichita'),(4018,10,'USA','Wichita Falls'),
+# (3899,19,'USA','Winston-Salem'),(3914,17,'USA','Worcester'),
+# (3888,20,'USA','Yonkers');
+
+#CREATE TABLE t3 ( f3 int, f4 varchar(3)) ;
+#INSERT INTO t3 VALUES (86,'USA');
+
+#CREATE TABLE t4 ( f3 int, f4 varchar(3), f5 varchar(52)) ;
+#INSERT INTO t4 VALUES (0,'RUS','Belorussian'),(0,'USA','Portuguese');
+
+#CREATE TABLE t5 ( f2 int) ;
+
+#CREATE TABLE t6 ( f4 varchar(3));
+#INSERT INTO t6 VALUES ('RUS'),('USA');
+
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+set @tmp_mjs_861147= @@max_join_size;
+SET max_join_size=10;
+set @tmp_os_861147= @@optimizer_switch;
+set @@optimizer_switch='semijoin=on,materialization=on';
+
+--error ER_TOO_BIG_SELECT
+explain
+select * from t1 where a in (select max(A.a + B.a + C.a) from t1 A, t1 B, t1 C);
+
+set max_join_size= @tmp_mjs_861147;
+set optimizer_switch= @tmp_os_861147;
+
+#DROP TABLE t1,t2,t3,t4,t5,t6;
+drop table t1;
+
+--echo #
+--echo # BUG#877288: Wrong result with semijoin + materialization + multipart key
+--echo #
+set @tmp_877288=@@optimizer_switch;
+set optimizer_switch='semijoin=ON,materialization=ON';
+CREATE TABLE t1 ( a int) ;
+INSERT INTO t1 VALUES (19),(19),(19),(20),(20),(20),(20),(20),(20);
+
+CREATE TABLE t2 ( b int NOT NULL , c int NOT NULL , KEY (b,c)) ;
+INSERT INTO t2 VALUES (14,1),(15,1),(16,1),(17,1),(18,1),(19,1),(20,1);
+
+CREATE TABLE t3 ( a int, d int) ;
+INSERT INTO t3 VALUES (19,1),(7,1),(3,1),(3,1),(20,1),(3,1),(16,1),(17,1),(9,1),(4,1),(6,1),(15,1),(17,1);
+
+explain
+SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
+SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@tmp_877288;
+
+--echo #
+--echo # BUG#878753: Assertion '0' failed in replace_where_subcondition with derived_merge
+--echo #
+set @tmp878753= @@optimizer_switch;
+set optimizer_switch= 'semijoin=on,derived_merge=on';
+CREATE TABLE t1 (b int(11)) ;
+CREATE TABLE t2 (c int, b int, d varchar(52) NOT NULL) ;
+CREATE TABLE t3 (b int(11)) ;
+
+PREPARE st1 FROM '
+ SELECT * FROM t1
+ JOIN (
+ SELECT t2.* FROM t2
+ WHERE t2.d <> "a"
+ AND t2.c IN (
+ SELECT t3.b
+ FROM t3
+ )
+ ) AS alias2
+ ON ( alias2.b = t1.b );
+';
+EXECUTE st1;
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@tmp878753;
+
+--echo #
+--echo # Bug #889750: semijoin=on + firstmatch=off + semijoin_with_cache=off
+--echo #
+
+create table t1 (a int);
+insert into t1 values (7), (1), (5), (3);
+create table t2 (a int);
+insert into t2 values (4), (1), (8), (3), (9), (2);
+
+set @tmp_otimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=on';
+set optimizer_switch='firstmatch=off';
+
+set optimizer_switch='semijoin_with_cache=on';
+explain
+select * from t1 where t1.a in (select t2.a from t2);
+select * from t1 where t1.a in (select t2.a from t2);
+
+set optimizer_switch='semijoin_with_cache=off';
+explain
+select * from t1 where t1.a in (select t2.a from t2);
+select * from t1 where t1.a in (select t2.a from t2);
+
+set optimizer_switch= @tmp_otimizer_switch;
+
+drop table t1,t2;
+
+--echo #
+--echo # Bug #887496: semijoin with IN equality for the second part of an index
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (9), (0), (8), (5);
+
+CREATE TABLE t2 (a int, b varchar(1), INDEX idx (b,a));
+INSERT INTO t2 VALUES (5,'r'), (5,'z');
+
+CREATE TABLE t3 (a int, b varchar(1), INDEX idx (b,a));
+INSERT INTO t3 VALUES (5,'r'), (5,'z');
+
+set @tmp_otimizer_switch= @@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on,firstmatch=on';
+
+SET SESSION optimizer_switch='loosescan=off';
+EXPLAIN
+SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
+SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
+
+SET SESSION optimizer_switch='loosescan=on';
+EXPLAIN
+SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
+SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
+
+set optimizer_switch= @tmp_otimizer_switch;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #901312: materialized semijoin + right join
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (4), (1);
+CREATE TABLE t2 (b int);
+INSERT INTO t2 VALUES (4), (1);
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (4), (1);
+
+set @tmp_otimizer_switch= @@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on,materialization=on';
+
+EXPLAIN
+SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3);
+SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3);
+
+set optimizer_switch= @tmp_otimizer_switch;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #901709: assertion failure with record count == 0
+--echo #
+
+CREATE TABLE t1 (a int, KEY (a));
+INSERT INTO t1 VALUES (4), (6);
+CREATE TABLE t2 (a int, KEY (a));
+INSERT INTO t2 VALUES (4), (6);
+CREATE TABLE t3 (b int);
+INSERT INTO t3 VALUES (4);
+CREATE TABLE t4 (c int);
+
+SET @tmp_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch='semijoin=on';
+SET @@optimizer_switch='materialization=on';
+SET @@optimizer_switch='firstmatch=on';
+SET optimizer_switch='semijoin_with_cache=on';
+SET optimizer_prune_level=0;
+
+EXPLAIN
+SELECT * FROM t1, t2
+ WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4);
+SELECT * FROM t1, t2
+ WHERE t1.a = t2.a AND t2.a IN (SELECT b FROM t3 STRAIGHT_JOIN t4);
+
+SET optimizer_prune_level=DEFAULT;
+SET optimizer_switch=@tmp_optimizer_switch;
+
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # BUG#901399: Wrong result (extra row) with semijoin=ON, materialization=OFF, optimizer_prune_level=0
+--echo #
+set @opl_901399= @@optimizer_prune_level;
+set @os_091399= @@optimizer_switch;
+SET optimizer_prune_level=0;
+SET optimizer_switch = 'materialization=off';
+
+CREATE TABLE t1 ( c INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+ (0),(1),(2),(3),(4),(5),
+ (6),(7),(8),(9),(10),(11),(12);
+CREATE TABLE t2 ( a INT, b INT, KEY(a)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (3,20),(2,21),(3,22);
+
+SELECT *
+FROM t1 AS alias1, t1 AS alias2
+WHERE ( alias1.c, alias2.c )
+ IN (
+ SELECT alias3.a, alias3.a
+ FROM t2 AS alias3, t2 alias4
+ WHERE alias3.b = alias4.b
+ );
+set optimizer_prune_level= @opl_901399;
+set optimizer_switch= @os_091399;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # BUG#912510: Crash in do_copy_not_null with semijoin=ON, firstmatch=ON, aggregate ...
+--echo #
+CREATE TABLE t1 ( a VARCHAR(1) NOT NULL );
+INSERT INTO t1 VALUES ('k'),('l');
+
+CREATE TABLE t2 ( b VARCHAR(1) NOT NULL, KEY(b) );
+INSERT INTO t2 VALUES ('k'),('l');
+
+CREATE TABLE t3 ( c VARCHAR(1) NOT NULL, KEY(c) );
+INSERT INTO t3 VALUES ('m'),('n');
+
+SELECT a, COUNT(*) FROM t1
+ WHERE a IN (
+ SELECT b FROM t2 force index(b), t3 force index(c)
+ WHERE c = b AND b = a
+ );
+
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # BUG#920255: Wrong result (extra rows) with loosescan and IN subquery
+--echo #
+CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, KEY(b) );
+INSERT INTO t1 VALUES
+ (1,2),(2,1),(3,3),(4,2),(5,5),
+ (6,3),(7,1),(8,4),(9,3),(10,2);
+
+CREATE TABLE t2 ( c INT, d INT, UNIQUE KEY(c) );
+INSERT INTO t2 VALUES
+ (1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1);
+
+SELECT a, b, d FROM t1, t2
+WHERE ( b, d ) IN
+ ( SELECT b, d FROM t1, t2 WHERE b = c );
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#920713: Wrong result (missing rows) with firstmatch+BNL, IN subquery, ...
+--echo #
+# t1 should be MyISAM or InnoDB
+CREATE TABLE t1 ( a VARCHAR(1) ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('e'),('w'),('a'),('h'),('x'),('k'),('g');
+CREATE TABLE t2 ( b INT, c VARCHAR(1) );
+INSERT INTO t2 VALUES (0,'j'),(8,'v');
+
+#SET debug_optimizer_prefer_join_prefix= 'alias2,alias4,alias1,alias3';
+
+SELECT * FROM t1 alias1, t2 alias2
+WHERE alias2.c IN (
+ SELECT alias4.c FROM t1 alias3, t2 alias4
+);
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#923246: Loosescan reports different result than other semijoin methods
+--echo #
+set @tmp_923246= @@optimizer_switch;
+set optimizer_switch='mrr=on,materialization=off';
+
+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;
+
+select * from t3 where a in (select kp1 from t1 where kp1<20);
+explain select * from t3 where a in (select kp1 from t1 where kp1<20);
+
+drop table t0,t1,t3;
+set optimizer_switch= @tmp_923246;
+
+--echo #
+--echo # BUG#952583: Server crashes in Item_field::fix_after_pullout on INSERT .. SELECT
+--echo #
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 ( b INT );
+INSERT INTO t2 VALUES (3),(4);
+
+INSERT INTO t1
+SELECT * FROM ( SELECT * FROM t1 ) AS alias
+WHERE a IN ( SELECT b FROM t2 );
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#952372: Server crashes on 2nd execution of PS in find_field_in_tables with semijoin+materialization
+--echo #
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (2),(3);
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+CREATE TABLE t2 ( b VARCHAR(1) );
+INSERT INTO t2 VALUES ('v'),('v');
+
+PREPARE pstmt FROM
+ 'SELECT DISTINCT a FROM v1, t2
+ WHERE b IN ( SELECT MIN(b) FROM t2 )';
+
+EXECUTE pstmt;
+EXECUTE pstmt;
+
+DEALLOCATE PREPARE pstmt;
+DROP VIEW v1;
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#978479: Wrong result (extra rows) with derived_with_keys+loosescan+semijoin=ON, materialization=OFF
+--echo #
+
+set @tmp_jcl_978479= @@join_cache_level;
+set join_cache_level=0;
+
+set @tmp_os_978479= @@optimizer_switch;
+set optimizer_switch = 'derived_with_keys=on,loosescan=on,semijoin=on,materialization=off';
+
+--echo # Part#1: make sure EXPLAIN is using LooseScan:
+CREATE TABLE t1 ( a INT, b INT );
+INSERT INTO t1 VALUES
+ (4,0),(6,8),(3,1),(5,8),(3,9),(2,4),
+ (2,6),(9,1),(5,4),(7,7),(5,4);
+
+CREATE ALGORITHM=TEMPTABLE
+ VIEW v1 AS SELECT * FROM t1;
+
+--echo # This will use LooseScan:
+EXPLAIN
+SELECT * FROM t1 AS t1_1, t1 AS t1_2
+ WHERE (t1_1.a, t1_2.a) IN ( SELECT a, b FROM v1 );
+
+SELECT * FROM t1 AS t1_1, t1 AS t1_2
+ WHERE (t1_1.a, t1_2.a) IN ( SELECT a, b FROM v1 );
+
+DROP VIEW v1;
+DROP TABLE t1;
+set @@join_cache_level= @tmp_jcl_978479;
+set @@optimizer_switch= @tmp_os_978479;
+
+--echo #
+--echo # BUG#998236: Assertion failure or valgrind errors at best_access_path ...
+--echo #
+CREATE TABLE t1 (a1 VARCHAR(3), a2 VARCHAR(35), KEY(a1,a2)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+('USA','Arvada'),('USA','Athens'),('USA','Atlanta'),('USA','Augusta'),
+('USA','Aurora'),('USA','Aurora'),('USA','Austin'),('USA','Bakersfield'),
+('USA','Baltimore'),('USA','Baton'),('USA','Beaumont'),('USA','Bellevue'),
+('USA','Berkeley'),('USA','Billings'),('USA','Birmingham'),('USA','Boise'),
+('USA','Boston'),('USA','Boulder'),('USA','Bridgeport'),('USA','Brockton'),
+('USA','Brownsville'),('USA','Buffalo'),('USA','Burbank'),('USA','Cambridge'),
+('USA','Cape'),('USA','Carrollton'),('USA','Carson'),('USA','Cary'),
+('USA','Cedar'),('USA','Chandler'),('USA','Charleston'),('USA','Charlotte'),
+('USA','Chattanooga'),('USA','Chesapeake'),('USA','Chicago'),('USA','Chula'),
+('USA','Cincinnati'),('USA','Citrus'),('USA','Clarksville'),('USA','Clearwater'),
+('USA','Cleveland'),('USA','Colorado'),('USA','Columbia'),('USA','Columbus'),
+('USA','Columbus'),('USA','Compton'),('USA','Concord'),('USA','Coral'),
+('USA','Corona'),('USA','Corpus'),('USA','Costa'),('USA','Dallas'),('USA','Daly'),
+('USA','Davenport'),('USA','Dayton'),('USA','Denver'),('USA','DesMoines'),
+('USA','Detroit'),('USA','Downey'),('USA','Durham'),('USA','East'),('USA','ElCajon'),
+('USA','ElMonte'),('USA','ElPaso'),('USA','Elgin'),('USA','Elizabeth'),
+('USA','Erie'),('USA','Escondido'),('USA','Eugene'),('USA','Evansville'),
+('USA','Fairfield'),('USA','Fall'),('USA','Fayetteville'),('USA','Flint'),
+('USA','Fontana'),('USA','FortCollins'),('USA','FortLauderdale'),('USA','FortWayne'),
+('USA','FortWorth'),('USA','Fremont'),('USA','Fresno'),('USA','Fullerton'),
+('USA','Gainesville'),('USA','GardenGrove'),('USA','Garland'),('USA','Gary'),
+('USA','Gilbert'),('USA','Glendale'),('USA','Glendale'),('USA','GrandPrairie'),
+('USA','GrandRapids'),('USA','Green Bay'),('USA','Greensboro'),('USA','Hampton'),
+('USA','Hartford'),('USA','Hayward'),('USA','Henderson'),('USA','Hialeah'),
+('USA','Inglewood'),('USA','Livonia');
+
+CREATE TABLE t3 (c1 VARCHAR(3), c2 VARCHAR(16), PRIMARY KEY (c1,c2)) ENGINE=MyISAM;
+INSERT INTO t3 VALUES ('USA','Chinese'), ('USA','English');
+
+# Not reproducible with 2 rows
+CREATE TABLE t2 (b1 INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1);
+
+SELECT alias1.a1 AS field1
+FROM t1 AS alias1, t1 AS alias2
+WHERE alias1.a2 IN ( SELECT a1 FROM t1, t2 )
+AND alias1.a1 IS NULL
+AND ( alias1.a1, alias2.a1 ) IN ( SELECT c1, c1 FROM t3 )
+GROUP BY field1;
+
+DROP TABLE t1,t3,t2;
+
+--echo #
+--echo # BUG#1002630: Valgrind warnings 'Invalid read' in subselect_engine::calc_const_tables with SELECT
+--echo #
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(7);
+
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (4),(6);
+
+SELECT ( SELECT SUM(a) FROM t1 ) AS t1sum, b
+FROM t2
+WHERE (1,1) IN ( SELECT MAX(a), MIN(a) FROM t1 )
+GROUP BY b
+HAVING t1sum <> 1;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # MDEV-3911: Assertion `fixed == 0' failed in Item_field::fix_fields
+--echo # on 2nd execution of PS with semijoin=on and IN subquery
+--echo #
+
+CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (0,4),(8,6);
+
+CREATE TABLE t2 (c INT, d INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (7,1),(0,7);
+
+eval PREPARE stmt FROM ' SELECT * FROM t1 WHERE ( a, b ) IN ( SELECT c, d FROM t2 ) ';
+
+execute stmt;
+execute stmt;
+
+deallocate prepare stmt;
+drop table t1,t2;
+
+
+# The following command must be the last one the file
+set optimizer_switch=@subselect_sj_tmp;
diff --git a/mysql-test/t/subselect_sj2.test b/mysql-test/t/subselect_sj2.test
new file mode 100644
index 00000000000..1afc39264ea
--- /dev/null
+++ b/mysql-test/t/subselect_sj2.test
@@ -0,0 +1,1233 @@
+#
+# DuplicateElimination strategy test
+#
+--source include/have_innodb.inc
+
+set @subselect_sj2_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj2_test,'outer_join_with_cache=off');
+SET optimizer_switch=ifnull(@optimizer_switch_for_subselect_sj2_test,'semijoin_with_cache=off');
+if (`select @join_cache_level_for_subselect_sj2_test is null`)
+{
+ set join_cache_level=1;
+}
+if (`select @join_cache_level_for_subselect_sj2_test is not null`)
+{
+ set join_cache_level=@join_cache_level_for_subselect_sj2_test;
+}
+
+--disable_warnings
+drop table if exists t0, t1, t2, t3, t4, t5;
+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;
+insert into t2 select a+10, a+10/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;
+insert into t3 select a,a, a+100,a+100,a+100 from t0;
+
+explain select * from t3 where b in (select a from t1);
+select * from t3 where b in (select a from t1);
+
+# 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;
+
+--replace_column 9 #
+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
+
+# Disable materialization to avoid races between query plans
+set @bug35674_save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+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);
+set optimizer_switch=@bug35674_save_optimizer_switch;
+
+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
+#
+
+--disable_warnings
+drop procedure if exists p1;
+drop procedure if exists p2;
+drop procedure if exists p3;
+drop procedure if exists p4;
+--enable_warnings
+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;
+insert into t1 select a+5,a from t0;
+
+create table t2 (a int, b int, primary key(a));
+insert into t2 select * from t1;
+
+# Table t2 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;
+
+
+--echo #
+--echo # BUG#761598: InnoDB: Error: row_search_for_mysql() is called without ha_innobase::external_lock() in maria-5.3
+--echo #
+
+CREATE TABLE t1 ( f1 int NOT NULL , f10 int) ;
+INSERT IGNORE INTO t1 VALUES (25,0),(29,0);
+
+CREATE TABLE t2 ( f10 int) ENGINE=InnoDB;
+
+CREATE TABLE t3 ( f11 int) ;
+INSERT IGNORE INTO t3 VALUES (0);
+
+SELECT alias1.f10 AS field2
+FROM t2 AS alias1
+JOIN (
+ t3 AS alias2
+ JOIN t1 AS alias3
+ ON alias3.f10
+) ON alias3.f1
+WHERE alias2.f11 IN (
+ SELECT SQ4_alias1.f10
+ FROM t1 AS SQ4_alias1
+ LEFT JOIN t2 AS SQ4_alias3 ON SQ4_alias3.f10
+)
+GROUP BY field2;
+drop table t1, t2, t3;
+
+--echo #
+--echo # BUG#849763: Wrong result with second execution of prepared statement with semijoin + view
+--echo #
+CREATE TABLE t1 ( c varchar(1)) engine=innodb;
+INSERT INTO t1 VALUES ('r');
+
+CREATE TABLE t2 ( a integer, b varchar(1), c varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES (1,'r','r');
+
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+
+PREPARE st1 FROM 'SELECT * FROM t2 WHERE a = SOME (SELECT a FROM v1 WHERE v1.c = t2.c)';
+EXECUTE st1;
+EXECUTE st1;
+
+DROP VIEW v1;
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#858732: Wrong result with semijoin + loosescan + comma join
+--echo #
+CREATE TABLE t1 (f13 int(11) NOT NULL , PRIMARY KEY (f13)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (16),(24);
+
+CREATE TABLE t2 (f14 int(11) NOT NULL, f12 varchar(1) NOT NULL, KEY (f12,f14)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (6,'y');
+
+CREATE TABLE t3 (f12 varchar(1) NOT NULL) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('r'),('s'),('t'),('v'),('w'),('x'),('y');
+
+--echo # The following must use LooseScan but not join buffering
+explain
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # BUG#869012: Wrong result with semijoin + materialization + AND in WHERE
+--echo #
+CREATE TABLE t1 (f3 varchar(1) , f4 varchar(1) ) engine=InnoDB;
+INSERT IGNORE INTO t1 VALUES ('x','x'),('x','x');
+CREATE TABLE t2 ( f4 varchar(1) ) ;
+INSERT IGNORE INTO t2 VALUES ('g');
+CREATE TABLE t3 (f4 varchar(1) ) Engine=InnoDB;
+INSERT IGNORE INTO t3 VALUES ('x');
+
+set @tmp_869012=@@optimizer_switch;
+SET optimizer_switch='semijoin=on,materialization=on';
+SELECT *
+FROM t1 , t2
+WHERE ( t1.f4 ) IN ( SELECT f4 FROM t3 )
+AND t2.f4 != t1.f3 ;
+set optimizer_switch= @tmp_869012;
+
+DROP TABLE t1,t2,t3;
+
+
+--echo #
+--echo # BUG#869001: Wrong result with semijoin + materialization + firstmatch + multipart key
+--echo #
+set @tmp869001_jcl= @@join_cache_level;
+set @tmp869001_os= @@optimizer_switch;
+SET join_cache_level=0;
+SET optimizer_switch='materialization=on,semijoin=on,firstmatch=on,loosescan=off';
+
+CREATE TABLE t1 ( f2 int, f3 varchar(1), KEY (f3,f2)) engine=innodb;
+INSERT INTO t1 VALUES (8,'x'),(NULL,'x'),(8,'c');
+
+CREATE TABLE t2 ( f4 varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES ('x');
+
+CREATE TABLE t3 ( f1 int) engine=innodb;
+INSERT INTO t3 VALUES (8),(6),(2),(9),(6);
+
+CREATE TABLE t4 ( f3 varchar(1)) engine=innodb;
+INSERT INTO t4 VALUES ('p'),('j'),('c');
+
+SELECT *
+FROM t1 JOIN t2 ON (t2.f4 = t1.f3 )
+WHERE ( 8 ) IN (
+ SELECT t3.f1 FROM t3 , t4
+);
+
+DROP TABLE t1, t2, t3, t4;
+set join_cache_level= @tmp869001_jcl;
+set optimizer_switch= @tmp869001_os;
+
+--echo #
+--echo # Bug #881318: join cache + duplicate elimination + left join
+--echo # with empty materialized derived inner table
+--echo #
+
+CREATE TABLE t1 (b varchar(1)) ENGINE=InnoDB;
+
+CREATE TABLE t2 (a varchar(1)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('a');
+
+CREATE TABLE t3 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('c','c');
+
+CREATE TABLE t4 (b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t4 VALUES ('c'), ('b');
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+
+EXPLAIN
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+ WHERE t3.b IN (SELECT b FROM t4);
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+ WHERE t3.b IN (SELECT b FROM t4);
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # BUG#912538: Wrong result (missing rows) with semijoin=on, firstmatch=on, ...
+--echo #
+CREATE TABLE t1 ( a INT NOT NULL, UNIQUE KEY(a) );
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+
+# t2 needs to be InnoDB
+CREATE TABLE t2 ( b INT, c INT ) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1,1);
+
+SELECT * FROM t1, t2 WHERE c IN (SELECT c FROM t1, t2 WHERE a = b);
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # BUG#962667: Assertion `0' failed in QUICK_INDEX_SORT_SELECT::need_sorted_output()
+--echo # with index_merge+index_merge_sort_union+loosescan+semijoin
+--echo #
+CREATE TABLE t1 (
+ a INT, b VARCHAR(1), c INT,
+ KEY(a), KEY(b)
+) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES
+(1,'v',9),(2,'v',8),(3,'c',7),(4,'m',6),(5,'x',5),
+(6,'i',4),(7,'e',3),(8,'p',2),(9,'s',1),(10,'j',9),
+(11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4),
+(16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0);
+
+CREATE TABLE t2 (
+ pk INT, d VARCHAR(1), e INT,
+ PRIMARY KEY(pk), KEY(d,e)
+) ENGINE=InnoDB;
+
+INSERT INTO t2 VALUES
+(1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5),
+(6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1),
+(11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5),
+(15,'g',6),(16,'x',7),(17,'f',8);
+
+explain
+SELECT * FROM t1 WHERE b IN (
+ SELECT d FROM t2, t1
+ WHERE a = d AND ( pk < 2 OR d = 'z' )
+);
+SELECT * FROM t1 WHERE b IN (
+ SELECT d FROM t2, t1
+ WHERE a = d AND ( pk < 2 OR d = 'z' )
+);
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view
+--echo #
+CREATE TABLE t1 (
+ a VARCHAR(1),
+ b VARCHAR(1) NOT NULL,
+ KEY(a)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+('j','j'),('v','v'),('c','c'),('m','m'),('d','d'),
+('y','y'),('t','t'),('d','d'),('s','s'),('r','r'),
+('m','m'),('b','b'),('x','x'),('g','g'),('p','p'),
+('q','q'),('w','w'),('d','d'),('e','e');
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+
+--echo # This query returned 6 rows instead of 19
+--sorted_result
+SELECT * FROM v1
+WHERE ( a, a ) IN (
+ SELECT alias2.b, alias2.a
+ FROM t1 AS alias1, t1 AS alias2
+ WHERE alias2.b = alias1.a
+ AND ( alias1.b >= alias1.a OR alias2.b = 'z' )
+);
+
+--echo # Another testcase, without the VIEW:
+CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(1) NOT NULL, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t2 SELECT * FROM t1;
+INSERT INTO t2 SELECT * FROM t1;
+EXPLAIN
+SELECT * FROM t2
+ WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
+ WHERE
+ alias2.b = alias1.a AND
+ (alias1.b >= alias1.a OR alias2.b = 'z'));
+
+--sorted_result
+SELECT * FROM t2
+ WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
+ WHERE
+ alias2.b = alias1.a AND
+ (alias1.b >= alias1.a OR alias2.b = 'z'));
+
+DROP VIEW v1;
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#965872: Server crashes in embedding_sjm on a simple 1-table select with AND and OR
+--echo # (this is a regression caused by the fix for BUG#951937)
+CREATE TABLE t1 ( a INT, b INT, c INT, d INT );
+INSERT INTO t1 VALUES (4,2,8,9),(4,2,7,8);
+
+SELECT * FROM t1
+WHERE a = d AND ( b = 50 AND b = d OR a = c );
+DROP TABLE t1;
+
+--echo #
+--echo # BUG#951283: Wrong result (missing rows) with semijoin+firstmatch, IN/ANY subquery
+--echo #
+set @tmp_951283=@@optimizer_prune_level;
+SET optimizer_prune_level=0;
+
+CREATE TABLE t1 ( a INT ) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+ (10),(11),(12),(13),(14),(15),(16),
+ (17),(18),(19),(20),(21),(22),(23);
+
+CREATE TABLE t2 (
+ b INT PRIMARY KEY,
+ c VARCHAR(1),
+ d VARCHAR(1),
+ KEY(c)
+) ENGINE=InnoDB;
+
+INSERT INTO t2 VALUES
+ (1,'j','j'),(2,'v','v'),(3,'c','c'),(4,'m','m'),
+ (5,'d','d'),(6,'d','d'),(7,'y','y'),(8,'t','t'),
+ (9,'d','d'),(10,'s','s'),(11,'r','r'),(12,'m','m'),
+ (13,'b','b'),(14,'x','x'),(15,'g','g'),(16,'p','p'),
+ (17,'q','q'),(18,'w','w'),(19,'d','d');
+
+EXPLAIN
+SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
+WHERE alias3.d IN (
+ SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
+ WHERE alias5.b = alias4.b
+ AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
+);
+
+SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
+WHERE alias3.d IN (
+ SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
+ WHERE alias5.b = alias4.b
+ AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
+);
+
+set optimizer_prune_level=@tmp_951283;
+DROP TABLE t1,t2;
+
+--echo # This must be the last in the file:
+set optimizer_switch=@subselect_sj2_tmp;
diff --git a/mysql-test/t/subselect_sj2_jcl6.test b/mysql-test/t/subselect_sj2_jcl6.test
new file mode 100644
index 00000000000..fbc474f7067
--- /dev/null
+++ b/mysql-test/t/subselect_sj2_jcl6.test
@@ -0,0 +1,113 @@
+#
+# Run subselect_sj2.test with BKA enabled
+#
+
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+set @optimizer_switch_for_subselect_sj2_test=@@optimizer_switch;
+set @join_cache_level_for_subselect_sj2_test=@@join_cache_level;
+
+--source t/subselect_sj2.test
+
+--echo #
+--echo # Bug #898073: potential incremental join cache for semijoin
+--echo #
+
+CREATE TABLE t1 (a int, b varchar(1), KEY (b,a));
+INSERT INTO t1 VALUES (0,'x'), (5,'r');
+
+CREATE TABLE t2 (a int) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (8);
+
+CREATE TABLE t3 (b varchar(1), c varchar(1)) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('x','x');
+
+CREATE TABLE t4 (a int NOT NULL, b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t4 VALUES (20,'r'), (10,'x');
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+
+SET SESSION optimizer_switch='semijoin_with_cache=on';
+
+SET SESSION join_cache_level=2;
+EXPLAIN
+SELECT t3.* FROM t1 JOIN t3 ON t3.b = t1.b
+ WHERE c IN (SELECT t4.b FROM t4 JOIN t2);
+SELECT t3.* FROM t1 JOIN t3 ON t3.b = t1.b
+ WHERE c IN (SELECT t4.b FROM t4 JOIN t2);
+
+set optimizer_switch=@tmp_optimizer_switch;
+set join_cache_level=default;
+
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # Bug #899696: potential incremental join cache for semijoin
+--echo #
+
+CREATE TABLE t1 (pk int PRIMARY KEY, a int);
+INSERT INTO t1 VALUES (1, 6), (2, 8);
+CREATE TABLE t2 (b int) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (8);
+CREATE TABLE t3 (pk int PRIMARY KEY, a int);
+INSERT INTO t3 VALUES (1, 6), (2, 8);
+CREATE TABLE t4 (b int) ENGINE=InnoDB;
+INSERT INTO t4 VALUES (2);
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+
+SET optimizer_switch = 'semijoin_with_cache=on';
+SET join_cache_level = 2;
+
+EXPLAIN
+SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk);
+SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk);
+
+set optimizer_switch=@tmp_optimizer_switch;
+set join_cache_level=default;
+
+DROP TABLE t1,t2,t3,t4;
+
+
+--echo #
+--echo # Bug #899962: materialized subquery with join_cache_level=3
+--echo #
+
+CREATE TABLE t1 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('v','v');
+CREATE TABLE t2 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('v','v');
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+
+SET optimizer_switch = 'semijoin_with_cache=on';
+SET join_cache_level = 3;
+
+EXPLAIN
+SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a);
+SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a);
+
+EXPLAIN
+SELECT * FROM t1 WHERE b IN (SELECT max(a) FROM t2 GROUP BY a);
+SELECT * FROM t1 WHERE b IN (SELECT max(a) FROM t2 GROUP BY a);
+
+set optimizer_switch=@tmp_optimizer_switch;
+set join_cache_level=default;
+
+DROP TABLE t1,t2;
+
+
+set join_cache_level=default;
+show variables like 'join_cache_level';
+
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
+set @optimizer_switch_for_subselect_sj2_test=NULL;
+set @join_cache_level_subselect_sj2_test=NULL;
+
diff --git a/mysql-test/t/subselect_sj2_mat.test b/mysql-test/t/subselect_sj2_mat.test
new file mode 100644
index 00000000000..61d9b09edff
--- /dev/null
+++ b/mysql-test/t/subselect_sj2_mat.test
@@ -0,0 +1,265 @@
+#
+# Run subselect_sj2.test with subquery materialization.
+#
+set optimizer_switch='materialization=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+--source t/subselect_sj2.test
+
+set optimizer_switch=default;
+select @@optimizer_switch like '%materialization=on%';
+
+--echo #
+--echo # BUG#906385: EXPLAIN EXTENDED crashes in TABLE_LIST::print with limited max_join_size
+--echo #
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( b INT );
+
+INSERT INTO t1 VALUES (1),(2);
+INSERT INTO t2 VALUES
+ (1),(2),(3),(4),(5),
+ (6),(7),(8),(9),(10),
+ (11),(12),(13),(14),(15),
+ (16),(17),(18),(19),(20);
+
+set @tmp_906385=@@max_join_size;
+SET max_join_size = 80;
+
+--error ER_TOO_BIG_SELECT
+EXPLAIN EXTENDED
+SELECT COUNT(*) FROM t1
+WHERE a IN
+ ( SELECT b FROM t2 GROUP BY b )
+ AND ( 6 ) IN
+ ( SELECT MIN( t2.b ) FROM t2 alias1, t2 );
+
+DROP TABLE t1, t2;
+set max_join_size= @tmp_906385;
+
+--echo #
+--echo # mdev-3995: Wrong result for semijoin with materialization
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+CREATE TABLE t1 (
+ cat_id int(10) unsigned NOT NULL,
+ PRIMARY KEY (cat_id)
+) ENGINE=MyISAM;
+
+INSERT INTO t1 VALUES
+(709411),(709412),(709413),(709414),(709416),(709417),(709418),(709419),(709421),(709422),
+(709424),(709425),(709427),(709428),(709429),(709431),(709432),(709433),(709434),(709435),
+(709438),(709439),(709441),(709442),(709443),(709444),(709445),(709446),(709447),(709450),
+(709451),(709454),(709455),(709456),(709457),(709459),(709460),(709461),(709462),(709463),
+(709464),(709465),(709467),(709469),(709470),(709471),(709472),(709473),(709474),(709475),
+(709476),(709477),(709478),(709479),(709480),(709481),(709483),(709484),(709485),(709487),
+(709490),(709491),(709492),(709493),(709494),(709495),(709496),(709497),(709498),(709499),
+(709500),(709501),(709502),(709503),(709504),(709505),(709506),(709507),(709509),(709510),
+(709511),(709512),(709513),(709514),(709515),(709516),(709517),(709518),(709519),(709520),
+(709521),(709522),(709523),(709524),(709525),(709526),(709527),(709528),(709529),(709530),
+(709531),(709532),(709533),(709534),(709535),(709536),(709537),(709538),(709539),(709540),
+(709541),(709542),(709543),(709544),(709545),(709546),(709548),(709549),(709551),(709552),
+(709553),(709555),(709556),(709557),(709558),(709559),(709560),(709561),(709562),(709563),
+(709564),(709565),(709566),(709567),(709568),(709569),(709570),(709571),(709572),(709573),
+(709574),(709575),(709576),(709577),(709578),(709579),(709580),(709581),(709582),(709583),
+(709584),(709585),(709586),(709587),(709588),(709590),(709591),(709592),(709593),(709594),
+(709595),(709596),(709597),(709598),(709600),(709601),(709602),(709603),(709604),(709605),
+(709606),(709608),(709609),(709610),(709611),(709612),(709613),(709614),(709615),(709616),
+(709617),(709618),(709619),(709620),(709621),(709622),(709623),(709624),(709625),(709626),
+(709627),(709628),(709629),(709630),(709631),(709632),(709633),(709634),(709635),(709637),
+(709638),(709639),(709640),(709641),(709642),(709643),(709644),(709645),(709646),(709649),
+(709650),(709651),(709652),(709653),(709654),(709655),(709656),(709657),(709658),(709659);
+
+CREATE TABLE t2 (
+ cat_id int(10) NOT NULL,
+ KEY cat_id (cat_id)
+) ENGINE=MyISAM;
+
+INSERT INTO t2 VALUES
+(708742),(708755),(708759),(708761),(708766),(708769),(708796),(708798),(708824),(708825),
+(708838),(708844),(708861),(708882),(708887),(708889),(708890),(709586),(709626);
+
+CREATE TABLE t3 (
+ sack_id int(10) unsigned NOT NULL,
+ kit_id tinyint(3) unsigned NOT NULL DEFAULT '0',
+ cat_id int(10) unsigned NOT NULL,
+ PRIMARY KEY (sack_id,kit_id,cat_id)
+) ENGINE=MyISAM;
+
+INSERT INTO t3 VALUES
+(33479,6,708523),(33479,6,708632),(33479,6,709085),(33479,6,709586),(33479,6,709626);
+
+CREATE TABLE t4 (
+ cat_id int(10) unsigned NOT NULL,
+ KEY cat_id (cat_id)
+) ENGINE=MyISAM;
+
+INSERT INTO t4 (cat_id) SELECT cat_id from t2;
+
+set optimizer_switch='materialization=off';
+
+EXPLAIN
+SELECT count(*) FROM t1, t3
+ WHERE t1.cat_id = t3.cat_id AND
+ t3.cat_id IN (SELECT cat_id FROM t2) AND
+ t3.sack_id = 33479 AND t3.kit_id = 6;
+
+SELECT count(*) FROM t1, t3
+ WHERE t1.cat_id = t3.cat_id AND
+ t3.cat_id IN (SELECT cat_id FROM t2) AND
+ t3.sack_id = 33479 AND t3.kit_id = 6;
+
+set optimizer_switch='materialization=on';
+
+EXPLAIN
+SELECT count(*) FROM t1, t3
+ WHERE t1.cat_id = t3.cat_id AND
+ t3.cat_id IN (SELECT cat_id FROM t4) AND
+ t3.sack_id = 33479 AND t3.kit_id = 6;
+
+SELECT count(*) FROM t1, t3
+ WHERE t1.cat_id = t3.cat_id AND
+ t3.cat_id IN (SELECT cat_id FROM t4) AND
+ t3.sack_id = 33479 AND t3.kit_id = 6;
+
+EXPLAIN
+SELECT count(*) FROM t1, t3
+ WHERE t1.cat_id = t3.cat_id AND
+ t3.cat_id IN (SELECT cat_id FROM t2) AND
+ t3.sack_id = 33479 AND t3.kit_id = 6;
+
+SELECT count(*) FROM t1, t3
+ WHERE t1.cat_id = t3.cat_id AND
+ t3.cat_id IN (SELECT cat_id FROM t2) AND
+ t3.sack_id = 33479 AND t3.kit_id = 6;
+
+
+DROP TABLE t1,t2,t3,t4;
+
+set optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # mdev-3913: LEFT JOIN with materialized multi-table IN subquery in WHERE
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+CREATE TABLE t1 (a1 char(1), b1 char(1), index idx(b1,a1));
+INSERT INTO t1 VALUES ('f','c'),('d','m'),('g','y');
+INSERT INTO t1 VALUES ('f','c'),('d','m'),('g','y');
+
+CREATE TABLE t2 (a2 char(1), b2 char(1));
+INSERT INTO t2 VALUES ('y','y'),('y','y'),('w','w');
+
+CREATE TABLE t3 (a3 int);
+INSERT INTO t3 VALUES (8),(6);
+
+CREATE TABLE t4 (a4 char(1), b4 char(1));
+INSERT INTO t4 VALUES ('y','y'),('y','y'),('w','w');
+
+set optimizer_switch='materialization=off';
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+ WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+ WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+
+set optimizer_switch='materialization=on';
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+ WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+ WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+
+DROP TABLE t1,t2,t3,t4;
+
+set optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # mdev-4172: LEFT JOIN with materialized multi-table IN subquery in WHERE
+--echo # and OR in ON condition
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+CREATE TABLE t1 (a1 int, c1 varchar(1));
+INSERT t1 VALUES (7,'v'), (3,'y');
+
+CREATE TABLE t2 (c2 varchar(1));
+INSERT INTO t2 VALUES ('y'), ('y');
+
+CREATE TABLE t3 (c3 varchar(1));
+INSERT INTO t3 VALUES
+ ('j'), ('v'), ('c'), ('m'), ('d'),
+ ('d'), ('y'), ('t'), ('d'), ('s');
+
+CREATE TABLE t4 (a4 int, c4 varchar(1));
+INSERT INTO t4 SELECT * FROM t1;
+
+set optimizer_switch='materialization=off';
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+ WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+ WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+
+set optimizer_switch='materialization=on';
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+ WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+ WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+
+DROP TABLE t1,t2,t3,t4;
+
+set optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # mdev-4177: materialization of a subquery whose WHERE condition is OR
+--echo # formula with two disjucts such that the second one is always false
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @save_join_cache_level=@@join_cache_level;
+
+CREATE TABLE t1 (i1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1), (7), (4), (8), (4);
+
+CREATE TABLE t2 (i2 int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (7), (5);
+
+CREATE TABLE t3 (i3 int) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (7), (2), (9);
+
+set join_cache_level=3;
+
+set optimizer_switch='materialization=off,semijoin=off';
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+
+set optimizer_switch='materialization=on,semijoin=on';
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+
+EXPLAIN EXTENDED
+SELECT * FROM t1
+ WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 0 AND i3 = i2 OR 1=2);
+SELECT * FROM t1
+ WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 0 AND i3 = i2 OR 1=2);
+SELECT * FROM t1
+ WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 7 AND i3 = i2 OR 1=2);
+
+DROP TABLE t1,t2,t3;
+
+set join_cache_level= @save_join_cache_level;
+set optimizer_switch=@save_optimizer_switch;
+
diff --git a/mysql-test/t/subselect_sj_aria.test b/mysql-test/t/subselect_sj_aria.test
new file mode 100644
index 00000000000..806688b3f87
--- /dev/null
+++ b/mysql-test/t/subselect_sj_aria.test
@@ -0,0 +1,76 @@
+#
+# Semi-join tests that require Aria
+#
+--disable_warnings
+drop table if exists t1,t2,t3,t4;
+--enable_warnings
+
+
+--echo #
+--echo # BUG#887468: Second assertion `keypart_map' failed in maria_rkey with semijoin
+--echo #
+
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_key int(11) DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ dummy char(30),
+ PRIMARY KEY (pk),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=Aria AUTO_INCREMENT=30 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1;
+
+INSERT INTO t1 (pk, col_varchar_key, col_int_key) VALUES
+(10,NULL,0), (11,'d',4), (12,'g',8), (13,'x',NULL), (14,'f',NULL),
+(15,'p',0), (16,'j',NULL), (17,'c',8), (18,'z',8), (19,'j',6), (20,NULL,2),
+(21,'p',3), (22,'w',1), (23,'c',NULL), (24,'j',1), (25,'f',10), (26,'v',2),
+(27,'f',103), (28,'q',3), (29,'y',6);
+
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_key int(11) DEFAULT NULL,
+ dummy char(36),
+ PRIMARY KEY (pk),
+ KEY col_int_key (col_int_key)
+) ENGINE=Aria AUTO_INCREMENT=101 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1;
+
+INSERT INTO t2 ( pk, col_int_key) VALUES
+(1,8), (2,2), (3,9), (4,6), (5,NULL), (6,NULL), (7,48), (8,228), (9,3), (10,5),
+(11,39), (12,6), (13,8), (14,3), (15,NULL), (16,2), (17,6), (18,3), (19,1), (20,4),
+(21,3), (22,1), (23,NULL), (24,97), (25,0), (26,0), (27,9), (28,5), (29,9), (30,0),
+(31,2), (32,172), (33,NULL), (34,5), (35,119), (36,1), (37,4), (38,8), (39,NULL), (40,6),
+(41,5), (42,5), (43,1), (44,7), (45,2), (46,8), (47,9), (48,NULL), (49,NULL), (50,3),
+(51,172), (52,NULL), (53,6), (54,6), (55,5), (56,4), (57,3), (58,2), (59,7), (60,4),
+(61,6), (62,0), (63,8), (64,5), (65,8), (66,2), (67,9), (68,7), (69,5), (70,7),
+(71,0), (72,4), (73,3), (74,1), (75,0), (76,6), (77,2), (78,NULL), (79,8), (80,NULL),
+(81,NULL), (82,NULL), (83,3), (84,7), (85,3), (86,5), (87,5), (88,1), (89,2), (90,1),
+(91,7), (92,1), (93,9), (94,9), (95,8), (96,3), (97,7), (98,4), (99,9), (100,0);
+
+CREATE TABLE t3 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ dummy char(34),
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_int_key int(11) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=Aria AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1;
+
+INSERT INTO t3 (pk, col_varchar_key) VALUES (1,'v'), (2,'c'), (3,NULL);
+
+CREATE TABLE t4 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ dummy char (38),
+ PRIMARY KEY (pk)
+) ENGINE=Aria AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1;
+
+INSERT INTO t4 (pk) VALUES (1), (2), (3);
+
+SELECT *
+FROM t1
+JOIN t2
+ON ( t2.col_int_key = t1.pk )
+WHERE t1.col_varchar_key IN (
+ SELECT t3.col_varchar_key FROM t3, t4
+);
+
+drop table t1, t2, t3, t4;
+
diff --git a/mysql-test/t/subselect_sj_jcl6.test b/mysql-test/t/subselect_sj_jcl6.test
new file mode 100644
index 00000000000..e86ed017951
--- /dev/null
+++ b/mysql-test/t/subselect_sj_jcl6.test
@@ -0,0 +1,216 @@
+#
+# Run subselect_sj.test with BKA enabled
+#
+
+set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set @@optimizer_switch='semijoin_with_cache=on';
+set @@optimizer_switch='outer_join_with_cache=on';
+set @@optimizer_switch='join_cache_hashed=off';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+set @optimizer_switch_for_subselect_sj_test=@@optimizer_switch;
+set @join_cache_level_for_subselect_sj_test=@@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;
+INSERT INTO t1 SELECT a+5, a from t0;
+INSERT INTO t1 SELECT a+10, a from t0;
+CREATE TABLE t2 (a INT, b INT, PRIMARY KEY(a));
+INSERT INTO t2 SELECT * FROM t1;
+UPDATE t1 SET a=3, b=11 WHERE a=4;
+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 #
+--echo # Bug #891995: IN subquery with join_cache_level >= 3
+--echo #
+
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('w'),('q');
+
+CREATE TABLE t2 (a int NOT NULL, b time, PRIMARY KEY (a));
+INSERT INTO t2 VALUES
+ (2,'18:56:33'), (5,'19:11:10'), (3,'18:56:33'), (7,'19:11:10');
+
+CREATE TABLE t3 (
+ a int NOT NULL, b int, c int, d varchar(1), PRIMARY KEY (a), KEY (d,c)
+);
+INSERT INTO t3 VALUES
+ (25,158,10,'f'), (26,5,2,'v'), (27,163,103,'f'), (28,2,3,'q'), (29,8,6,'y');
+
+set @save_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on';
+
+SET SESSION optimizer_switch='join_cache_hashed=on';
+SET SESSION join_cache_level=3;
+EXPLAIN
+SELECT * FROM t1, t2
+ WHERE t2.a IN (SELECT b FROM t3 WHERE t3.d <= t1.a);
+SELECT * FROM t1, t2
+ WHERE t2.a IN (SELECT b FROM t3 WHERE t3.d <= t1.a);
+
+
+SET SESSION optimizer_switch='mrr=on';
+SET SESSION join_cache_level=6;
+EXPLAIN
+SELECT * FROM t1, t2
+ WHERE t2.a IN (SELECT b FROM t3 WHERE t3.d <= t1.a);
+SELECT * FROM t1, t2
+ WHERE t2.a IN (SELECT b FROM t3 WHERE t3.d <= t1.a);
+
+set optimizer_switch=@save_optimizer_switch;
+set join_cache_level=default;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # BUG#912513: Wrong result (missing rows) with join_cache_hashed+materialization+semijoin=on
+--echo #
+set @os_912513= @@optimizer_switch;
+set @jcl_912513= @@join_cache_level;
+SET optimizer_switch = 'semijoin=on,materialization=on,join_cache_hashed=on';
+SET join_cache_level = 3;
+
+CREATE TABLE t1 ( a INT, b INT, KEY(a) );
+INSERT INTO t1 VALUES
+ (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7);
+
+CREATE TABLE t2 ( c INT );
+INSERT INTO t2 VALUES (1),(2),(3),(4),(5),(6),(7);
+
+SELECT alias1.* FROM
+ t1 AS alias1 INNER JOIN t1 AS alias2
+ ON alias2.a = alias1.b
+WHERE alias1.b IN (
+ SELECT a FROM t1, t2
+ );
+
+DROP table t1, t2;
+set @@optimizer_switch= @os_912513;
+set @@join_cache_level= @jcl_912513;
+
+--echo # End
+
+--echo #
+--echo # BUG#934342: outer join + semijoin materialization
+--echo # + join_cache_level > 2
+--echo #
+
+CREATE TABLE t1 (a varchar(1), b varchar(1), INDEX idx_a(a) );
+INSERT INTO t1 VALUES ('v','v'), ('w','w'), ('t','t');
+
+CREATE TABLE t2 (c varchar(1), INDEX idx_c(c) );
+INSERT INTO t2 VALUES ('v'), ('v'), ('s'), ('j');
+
+CREATE TABLE t3 (c varchar(1), d varchar(1), INDEX idx_c(c) );
+INSERT INTO t3 VALUES ('v','v'), ('v','v'), ('s','s'), ('j','j');
+INSERT INTO t3 VALUES ('m','m'), ('d','d'), ('k','k'), ('m','m');
+
+set @tmp_otimizer_switch= @@optimizer_switch;
+set @tmp_join_cache_level=@@join_cache_level;
+set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on';
+
+set join_cache_level=0;
+
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 ON (c = b)
+ WHERE (a, b) IN (SELECT a, b FROM t1 t);
+SELECT * FROM t1 LEFT JOIN t2 ON (c = b)
+ WHERE (a, b) IN (SELECT a, b FROM t1 t);
+
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t3 ON (c = b)
+ WHERE (a, b) IN (SELECT a, b FROM t1 t);
+SELECT * FROM t1 LEFT JOIN t3 ON (c = b)
+ WHERE (a, b) IN (SELECT a, b FROM t1 t);
+
+set join_cache_level=6;
+
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2 ON (c = b)
+ WHERE (a, b) IN (SELECT a, b FROM t1 t);
+SELECT * FROM t1 LEFT JOIN t2 ON (c = b)
+ WHERE (a, b) IN (SELECT a, b FROM t1 t);
+
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t3 ON (c = b)
+ WHERE (a, b) IN (SELECT a, b FROM t1 t);
+SELECT * FROM t1 LEFT JOIN t3 ON (c = b)
+ WHERE (a, b) IN (SELECT a, b FROM t1 t);
+
+set optimizer_switch=@tmp_optimizer_switch;
+set join_cache_level=@tmp_join_cache_level;
+
+DROP TABLE t1,t2,t3;
+
+--echo # End
+
+--echo #
+--echo # BUG#934348: GROUP BY with HAVING + semijoin materialization
+--echo # + join_cache_level > 2
+--echo #
+
+CREATE TABLE t1 (a varchar(1), INDEX idx_a(a));
+INSERT INTO t1 VALUES ('c'), ('v'), ('c');
+
+CREATE TABLE t2 (b varchar(1));
+INSERT INTO t2 VALUES ('v'), ('c');
+
+set @tmp_otimizer_switch= @@optimizer_switch;
+set @tmp_join_cache_level=@@join_cache_level;
+set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on';
+
+set join_cache_level=0;
+
+EXPLAIN
+SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a)
+ GROUP BY a HAVING a != 'z';
+SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a)
+ GROUP BY a HAVING a != 'z';
+
+set join_cache_level=6;
+
+EXPLAIN
+SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a)
+ GROUP BY a HAVING a != 'z';
+SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a)
+ GROUP BY a HAVING a != 'z';
+
+set optimizer_switch=@tmp_optimizer_switch;
+set join_cache_level=@tmp_join_cache_level;
+
+DROP TABLE t1,t2;
+
+--echo # End
+
+set join_cache_level=default;
+show variables like 'join_cache_level';
+
+set @@optimizer_switch=@save_optimizer_switch_jcl6;
+set @optimizer_switch_for_subselect_sj_test=NULL;
+set @join_cache_level_subselect_sj_test=NULL;
diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test
new file mode 100644
index 00000000000..4c40b2b5487
--- /dev/null
+++ b/mysql-test/t/subselect_sj_mat.test
@@ -0,0 +1,1683 @@
+#
+# Hash semi-join regression tests
+# (WL#1110: Subquery optimization: materialization)
+#
+
+set @subselect_sj_mat_tmp= @@optimizer_switch;
+set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on');
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @optimizer_switch_local_default= @@optimizer_switch;
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
+
+--disable_warnings
+drop table if exists t1, t2, t3, t4, t5, t1i, t2i, t3i;
+drop table if exists columns;
+drop table if exists t1_16, t2_16, t3_16;
+drop view if exists v1, v2, v1m, v2m;
+--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='materialization=on,in_to_exists=off,firstmatch=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
+--replace_column 7 #
+--replace_regex /it1.*/_it1_idx/ /test.t2i.*/_ref_/ /Using index$// /Using where$//
+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');
+
+--replace_column 6 # 8 # 11 #
+explain extended
+select * from t1i where a1 in (select max(b1) from t2i where b1 > '0' group by b1);
+select * from t1i where a1 in (select max(b1) from t2i where b1 > '0' group by b1);
+
+--replace_column 7 #
+--replace_regex /it1.*/_it1_idx/ /test.t2i.*/_ref_/ /Using index$// /Using where$//
+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');
+
+--replace_column 6 # 7 # 8 # 11 #
+explain extended
+select * from t1i where (a1, a2) in (select b1, max(b2) from t2i where b1 > '0' group by b1);
+select * from t1i where (a1, a2) in (select b1, max(b2) from t2i where b1 > '0' group by b1);
+
+--replace_column 6 # 7 # 8 # 11 #
+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 @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+prepare st1 from
+"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+execute st1;
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+execute st1;
+
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+prepare st1 from
+"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+execute st1;
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+execute st1;
+set @@optimizer_switch=@save_optimizer_switch;
+
+# 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'));
+
+--replace_column 6 # 7 # 8 # 11 #
+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
+--replace_column 6 # 7 # 8 # 11 #
+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 @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');
+
+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.
+******************************************************************************/
+
+# 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 max(b1) from t2 group by b1);
+select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+# Query with group by, executed via IN=>EXISTS
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+explain select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+
+# Executed with materialization
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+select min(a1) from t1 where 7 in (select b1 from t2);
+# Executed with semi-join. Notice, this time we get a different result (NULL).
+# This is the only correct result of all four queries. This difference is
+# filed as BUG#40037.
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+-- echo # with MariaDB and MWL#90, this particular case is solved:
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+select min(a1) from t1 where 7 in (select b1 from t2);
+-- echo # but when we go around MWL#90 code, the problem still shows up:
+explain select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
+select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
+set @@optimizer_switch= @save_optimizer_switch;
+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');
+
+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;
+
+--echo #
+--echo # BUG#49630: Segfault in select_describe() with double
+--echo # nested subquery and materialization
+--echo #
+
+CREATE TABLE t1 (t1i int);
+CREATE TABLE t2 (t2i int);
+CREATE TABLE t3 (t3i int);
+CREATE TABLE t4 (t4i int);
+
+INSERT INTO t1 VALUES (1); # Note: t1 must be const table
+INSERT INTO t2 VALUES (1),(2);
+INSERT INTO t3 VALUES (1),(2);
+INSERT INTO t4 VALUES (1),(2);
+
+--echo
+EXPLAIN
+SELECT t1i
+FROM t1 JOIN t4 ON t1i=t4i
+WHERE (t1i) IN (
+ SELECT t2i
+ FROM t2
+ WHERE (t2i) IN (
+ SELECT max(t3i)
+ FROM t3
+ GROUP BY t3i
+ )
+ );
+
+DROP TABLE t1,t2,t3,t4;
+
+
+#
+# Bug #52538 Valgrind bug: Item_in_subselect::init_left_expr_cache()
+#
+CREATE TABLE t1 (
+ pk INTEGER AUTO_INCREMENT,
+ col_int_nokey INTEGER,
+ col_int_key INTEGER,
+
+ col_varchar_key VARCHAR(1),
+
+ PRIMARY KEY (pk),
+ KEY (col_int_key),
+ KEY (col_varchar_key, col_int_key)
+)
+;
+
+INSERT INTO t1 (
+ col_int_key, col_int_nokey, col_varchar_key
+)
+VALUES
+(2, NULL, 'w'),
+(9, 7, 'm'),
+(3, 9, 'm'),
+(9, 7, 'k'),
+(NULL, 4, 'r'),
+(9, 2, 't'),
+(3, 6, 'j'),
+(8, 8, 'u'),
+(8, NULL, 'h'),
+(53, 5, 'o'),
+(0, NULL, NULL),
+(5, 6, 'k'),
+(166, 188, 'e'),
+(3, 2, 'n'),
+(0, 1, 't'),
+(1, 1, 'c'),
+(9, 0, 'm'),
+(5, 9, 'y'),
+(6, NULL, 'f'),
+(2, 4, 'd')
+;
+
+SELECT table2.col_varchar_key AS field1,
+ table2.col_int_nokey AS field2
+FROM ( t1 AS table1 LEFT OUTER JOIN t1 AS table2
+ ON (table2.col_varchar_key = table1.col_varchar_key ) )
+WHERE table1.pk = 6
+HAVING ( field2 ) IN
+( SELECT SUBQUERY2_t2.col_int_nokey AS SUBQUERY2_field2
+ FROM ( t1 AS SUBQUERY2_t1 JOIN t1 AS SUBQUERY2_t2
+ ON (SUBQUERY2_t2.col_varchar_key = SUBQUERY2_t1.col_varchar_key ) ) )
+ORDER BY field2
+;
+
+drop table t1;
+
+
+--echo #
+--echo # BUG#53103: MTR test ps crashes in optimize_cond()
+--echo # when running with --debug
+--echo #
+
+CREATE TABLE t1(track varchar(15));
+
+INSERT INTO t1 VALUES ('CAD'), ('CAD');
+
+PREPARE STMT FROM
+"SELECT 1 FROM t1
+ WHERE
+ track IN (SELECT track FROM t1
+ GROUP BY track
+ HAVING track>='CAD')";
+EXECUTE STMT ;
+EXECUTE STMT ;
+
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
+
+--echo # End of BUG#53103
+
+--echo #
+--echo # BUG#54511 - Assertion failed: cache != 0L in file
+--echo # sql_select.cc::sub_select_cache on HAVING
+--echo #
+
+CREATE TABLE t1 (i int(11));
+CREATE TABLE t2 (c char(1));
+CREATE TABLE t3 (c char(1));
+
+# These records are needed for the test to fail with MyISAM. The test
+# fails with InnoDB without these (difference due to optimization of
+# aggregates available only in MyISAM)
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES ('a'), ('b');
+INSERT INTO t3 VALUES ('x'), ('y');
+
+SELECT COUNT( i ),i
+FROM t1
+HAVING ('c')
+ IN (SELECT t2.c FROM (t2 JOIN t3));
+
+DROP TABLE t1,t2,t3;
+
+--echo # End BUG#54511
+
+--echo #
+--echo # BUG#56367 - Assertion exec_method != EXEC_MATERIALIZATION...
+--echo # on subquery in FROM
+--echo #
+
+CREATE TABLE t1 (a INTEGER);
+
+CREATE TABLE t2 (b INTEGER);
+INSERT INTO t2 VALUES (1);
+
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+let $query =
+SELECT a FROM (
+ SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+eval explain $query;
+eval $query;
+set optimizer_switch=@tmp_optimizer_switch;
+
+DROP TABLE t1, t2;
+
+--echo # End BUG#56367
+
+--echo #
+--echo # Bug#59833 - materialization=on/off leads to different result set
+--echo # when using IN
+--echo #
+
+CREATE TABLE t1 (
+ pk int NOT NULL,
+ f1 int DEFAULT NULL,
+ PRIMARY KEY (pk)
+) ENGINE=MyISAM;
+
+CREATE TABLE t2 (
+ pk int NOT NULL,
+ f1 int DEFAULT NULL,
+ PRIMARY KEY (pk)
+) ENGINE=MyISAM;
+
+INSERT INTO t1 VALUES (10,0);
+INSERT INTO t2 VALUES (10,0),(11,0);
+
+let $query=
+SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+
+eval explain $query;
+eval $query;
+
+DROP TABLE t1, t2;
+
+--echo # End Bug#59833
+
+--echo #
+--echo # Bug#11852644 - CRASH IN ITEM_REF::SAVE_IN_FIELD ON SELECT DISTINCT
+--echo #
+
+CREATE TABLE t1 (
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL,
+ KEY col_varchar_key (col_varchar_key))
+;
+
+INSERT INTO t1 VALUES
+('v','v'),('r','r');
+
+CREATE TABLE t2 (
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL,
+ KEY col_varchar_key(col_varchar_key))
+;
+
+INSERT INTO t2 VALUES
+('r','r'),('c','c');
+
+CREATE VIEW v3 AS SELECT * FROM t2;
+
+SELECT DISTINCT alias2.col_varchar_key
+FROM t1 AS alias1 JOIN v3 AS alias2
+ON alias2.col_varchar_key = alias1.col_varchar_key
+HAVING col_varchar_key IN (SELECT col_varchar_nokey FROM t2)
+;
+
+DROP TABLE t1, t2;
+DROP VIEW v3;
+
+--echo # End Bug#11852644
+
+--echo
+--echo # Bug#12668294 - GROUP BY ON EMPTY RESULT GIVES EMPTY ROW
+--echo # INSTEAD OF NULL WHEN MATERIALIZATION ON
+--echo
+
+CREATE TABLE t1 (col_int_nokey INT) ENGINE=MEMORY;
+CREATE TABLE t2 (col_int_nokey INT) ENGINE=MEMORY;
+INSERT INTO t2 VALUES (8),(7);
+CREATE TABLE t3 (col_int_nokey INT) ENGINE=MEMORY;
+INSERT INTO t3 VALUES (7);
+
+SELECT MIN(t3.col_int_nokey),t1.col_int_nokey AS field3
+FROM t3
+ LEFT JOIN t1
+ ON t1.col_int_nokey
+WHERE (194, 200) IN (
+ SELECT SQ4_alias1.col_int_nokey,
+ SQ4_alias2.col_int_nokey
+ FROM t2 AS SQ4_alias1
+ JOIN
+ t2 AS SQ4_alias2
+ ON SQ4_alias2.col_int_nokey = 5
+ )
+GROUP BY field3 ;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+
+#
+# Bug #44303 Assertion failures in Field_new_decimal::store_decimal
+# when executing materialized InsideOut semijoin
+#
+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 @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch=@optimizer_switch_local_default;
+SET @@optimizer_switch='semijoin=on,materialization=on';
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+set @@optimizer_switch= @save_optimizer_switch;
+
+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 @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch=@optimizer_switch_local_default;
+SET @@optimizer_switch='semijoin=on,materialization=on';
+EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0);
+DROP TABLE t1, t2;
+set optimizer_switch=@save_optimizer_switch;
+
+--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,in_to_exists=on';
+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;
+set optimizer_switch='firstmatch=on';
+
+--echo #
+--echo # MWL#90, review feedback: check what happens when the subquery
+--echo # looks like candidate for MWL#90 checking at the first glance
+--echo # but then subselect_hash_sj_engine::init_permanent() discovers
+--echo # that it's not possible to perform duplicate removal for the
+--echo # selected datatypes, and so materialization isn't applicable after
+--echo # all.
+--echo #
+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));
+
+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)));
+
+explain select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0');
+select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0');
+
+drop table t1_1024, t2_1024;
+
+--echo #
+--echo # BUG##836491: Crash in Item_field::Item_field from add_ref_to_table_cond() with semijoin+materialization
+--echo #
+
+CREATE TABLE t1 (c int, d varchar(1), KEY(d)) ;
+INSERT INTO t1 VALUES (2,'x'),(2,'x'),(2,'j'),(2,'c');
+
+CREATE TABLE t2 (a int, d varchar(1)) ;
+INSERT INTO t2 VALUES (1,'x');
+
+CREATE TABLE t3 (d varchar(1)) ;
+INSERT INTO t3 VALUES ('x'),('x'),('j'),('c');
+
+SELECT t2.a, t1.c
+FROM t1, t2
+WHERE t2.d IN ( SELECT d FROM t3 )
+AND t1.d = t2.d
+GROUP BY 1 , 2;
+
+drop table t1,t2,t3;
+
+--echo #
+--echo # BUG#836523: Crash in JOIN::get_partial_cost_and_fanout with semijoin+materialization
+--echo #
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('a'),('a');
+
+CREATE TABLE t2 (a varchar(1));
+
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (1),(2);
+
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('a'),('a');
+
+SELECT t1.a
+FROM t1
+WHERE t1.a IN (
+ SELECT t2.a
+ FROM t2, t3
+)
+HAVING a IN (
+ SELECT a
+ FROM t4
+);
+DROP TABLE t1, t2, t3, t4;
+
+--echo #
+--echo # BUG#836507: Crash in setup_sj_materialization_part1() with semijoin+materialization
+--echo #
+CREATE TABLE t1 (a int) ;
+INSERT IGNORE INTO t1 VALUES (1),(1);
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1);
+
+CREATE TABLE t3 (a int);
+
+CREATE TABLE t4 (a int);
+INSERT INTO t4 VALUES (2),(2);
+
+CREATE TABLE t5 (a int);
+INSERT INTO t5 VALUES (1);
+
+SELECT * FROM t1
+WHERE (a) IN (
+ SELECT t5.a
+ FROM (
+ t2
+ LEFT JOIN ( t3 , t4 )
+ ON 1 = 1
+ )
+ JOIN t5
+);
+
+DROP TABLE t1,t2,t3,t4,t5;
+
+--echo #
+--echo # BUG#836532: Crash in Item_equal_fields_iterator::get_curr_field with semijoin+materialization
+--echo #
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES ('a'),('a');
+
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('m'),('o');
+
+CREATE TABLE t3 (a varchar(1) , b varchar(1) ) ;
+INSERT INTO t3 VALUES ('b','b');
+
+CREATE TABLE t5 (a varchar(1), KEY (a)) ;
+INSERT INTO t5 VALUES ('d'),('e');
+
+SELECT *
+FROM t2
+WHERE t2.a = ALL (
+ SELECT t4.a
+ FROM t4
+ WHERE t4.a IN (
+ SELECT t3.a
+ FROM t3 , t5
+ WHERE ( t5.a = t3.b )
+ )
+);
+
+DROP TABLE t2,t3,t4,t5;
+
+--echo #
+--echo # BUG#860300: Second crash with get_fanout_with_deps() with semijoin + materialization
+--echo #
+set @tmp_860300=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f2 int);
+INSERT INTO t1 VALUES (9),(6);
+CREATE TABLE t3 (f4 int);
+CREATE TABLE t4 (f6 varchar(1));
+
+SELECT *
+FROM t3
+WHERE 'h' IN (SELECT f6
+ FROM t4
+ WHERE 5 IN (SELECT f2 FROM t1)
+ GROUP BY t4.f6);
+DROP TABLE t1,t3,t4;
+set optimizer_switch=@tmp_860300;
+
+--echo #
+--echo # BUG#860535: Assertion `keypart_map' failed in mi_rkey with semijoin
+--echo #
+set @tmp_860535=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f3 int) ;
+INSERT INTO t1 VALUES (1),(7);
+
+CREATE TABLE t2 (f3 int , f5 varchar(1), KEY (f3)) ;
+INSERT INTO t2 VALUES (7,'b');
+
+CREATE TABLE t3 (f3 int , f4 varchar(1) , KEY(f3), KEY (f4,f3)) ;
+INSERT INTO t3 VALUES (1,'t'),(7,'g');
+
+CREATE TABLE t4
+SELECT f3
+FROM t1 WHERE ( f3 ) NOT IN (
+ SELECT f3
+ FROM t2
+ WHERE f5 IN (
+ SELECT f4
+ FROM t3
+ WHERE t3.f3 < 3
+ )
+);
+SELECT * FROM t4;
+DROP TABLE t1, t2, t3, t4;
+set optimizer_switch=@tmp_860535;
+
+--echo #
+--echo # BUG#860553: Crash in create_ref_for_key with semijoin + materialization
+--echo #
+CREATE TABLE t1 (f1 int) ;
+CREATE TABLE t2 (f5 varchar(52) NOT NULL) ;
+
+CREATE TABLE t3 (f1 varchar(3), f4 varchar(52) , KEY (f4), PRIMARY KEY (f1));
+
+CREATE TABLE t4 (f3 int, KEY (f3));
+INSERT INTO t4 VALUES (17),(20);
+
+CREATE TABLE t5 (f2 int);
+INSERT INTO t5 VALUES (0),(0);
+
+SELECT *
+FROM t1
+JOIN t2
+ON ( t2.f5 ) IN (
+ SELECT t3.f4
+ FROM t3
+ WHERE ( 1 ) IN (
+ SELECT t4.f3
+ FROM t4 , t5
+ )
+);
+
+DROP TABLE t1, t2, t3, t4, t5;
+--echo #
+--echo # BUG#868908: Crash in check_simple_equality() with semijoin + materialization + prepared statement
+--echo #
+
+CREATE TABLE t1 ( a int );
+CREATE TABLE t3 ( b int, c int) ;
+CREATE TABLE t2 ( a int ) ;
+CREATE TABLE t4 ( a int , c int) ;
+
+PREPARE st1 FROM "
+SELECT STRAIGHT_JOIN *
+FROM t1
+WHERE ( 3 ) IN (
+ SELECT t3.b
+ FROM t3
+ LEFT JOIN (
+ t2 STRAIGHT_JOIN t4 ON ( t4.c = t2.a )
+ ) ON ( t4.a = t3.c )
+);
+";
+EXECUTE st1;
+EXECUTE st1;
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # BUG#901032: Wrong result for MIN/MAX on an indexed column with materialization and semijoin
+--echo #
+CREATE TABLE t1 ( a INT, KEY(a) );
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 ( b INT );
+INSERT INTO t2 VALUES (2);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (2);
+
+SELECT MIN(a) FROM t1, t2 WHERE b IN (SELECT c FROM t3 GROUP BY c);
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo #
+--echo # BUG#902632: Crash or invalid read at st_join_table::cleanup, st_table::disable_keyread
+--echo #
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 ( b INT );
+INSERT INTO t2 VALUES (3), (4);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (5), (6);
+
+SELECT * FROM t1 WHERE EXISTS (
+ SELECT DISTINCT b FROM t2
+ WHERE b <= a
+ AND b IN ( SELECT c FROM t3 GROUP BY c )
+ );
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # BUG#901506: Crash in TABLE_LIST::print on EXPLAIN EXTENDED
+--echo #
+CREATE TABLE t1 ( a INT, KEY(a) );
+INSERT INTO t1 VALUES (8);
+
+EXPLAIN EXTENDED
+ SELECT * FROM t1
+ WHERE a IN ( SELECT MIN(a) FROM t1 );
+
+DROP TABLE t1;
+
+--echo #
+--echo # BUG#904432: Wrong result with LEFT JOIN, constant table, semijoin=ON,materialization=ON
+--echo #
+CREATE TABLE t1 ( a INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4);
+CREATE TABLE t2 ( b INT NOT NULL, c INT );
+INSERT INTO t2 VALUES (4,2),(4,2),(4,4),(1,1);
+
+SELECT * FROM t1 LEFT JOIN t2 ON ( a = b )
+ WHERE a IN ( SELECT c FROM t2 );
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # BUG#922254: Assertion `0' failed at item_cmpfunc.cc:5899: Item* Item_equal::get_first(JOIN_TAB*, Item*)
+--echo #
+CREATE TABLE t1 ( a VARCHAR(3) );
+CREATE TABLE t2 ( b VARCHAR(3), c VARCHAR(8), KEY(c) );
+INSERT INTO t2 VALUES ('USA','Abilene'),('USA','Akron');
+
+EXPLAIN
+SELECT * FROM
+ ( SELECT * FROM t1 ) AS alias1,
+ t2 AS alias2
+WHERE b = a AND a IN (
+ SELECT alias3.c
+ FROM t2 AS alias3, t2 AS alias4
+ WHERE alias4.c = alias3.b
+);
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # BUG#928048: Query containing IN subquery with OR in the where clause returns a wrong result
+--echo #
+create table t1 (a int, b int);
+insert into t1 values (7,5), (3,3), (5,4), (9,3);
+
+create table t2 (a int, b int, index i_a(a));
+
+insert into t2 values
+ (4,2), (7,9), (7,4), (3,1), (5,3), (3,1), (9,4), (8,1);
+
+explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1);
+select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1);
+
+drop table t1,t2;
+
+--echo #
+--echo # BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE
+--echo #
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(8);
+
+SELECT STRAIGHT_JOIN MIN(a) FROM t1
+WHERE a IN (
+ SELECT a FROM t1
+ WHERE 'condition'='impossible'
+ );
+
+DROP TABLE t1;
+
+--echo #
+--echo # BUG#938131: Subquery materialization is not used in CREATE TABLE SELECT
+--echo #
+CREATE TABLE t1(a int);
+INSERT INTO t1 values(1),(2);
+CREATE TABLE t2(a int);
+INSERT INTO t2 values(1),(2);
+--echo # Should use Materialization:
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
+flush status;
+CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
+SHOW STATUS LIKE 'Created_tmp_tables';
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # BUG#939009: Crash with aggregate function in IN subquery
+--echo #
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='materialization=on,semijoin=on';
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (7,1), (4,2), (7,7);
+
+CREATE TABLE t2 ( c INT );
+INSERT INTO t2 VALUES (4), (7), (6);
+
+EXPLAIN EXTENDED
+SELECT * FROM t1
+ WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
+SELECT * FROM t1
+ WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
+
+EXPLAIN
+SELECT * FROM t1
+ WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
+SELECT * FROM t1
+ WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
+
+SET optimizer_switch=@save_optimizer_switch;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # BUG#946055: Crash with semijoin IN subquery when hash join is used
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (7);
+
+CREATE TABLE t2 (b int, c int, d varchar(1), e varchar(1), KEY (c), KEY (d, c));
+
+INSERT INTO t2 VALUES
+ (4,2,'v','v'), (6,1,'v','v'), (0,5,'x','x'), (7,1,'x','x'),
+ (7,3,'i','i'), (7,1,'e','e'), (1,4,'p','p'), (1,2,'j','j');
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET @save_join_cache_level=@@join_cache_level;
+
+SET join_cache_level=2;
+EXPLAIN
+SELECT a, c FROM t1, t2
+ WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+ WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+SELECT a, c FROM t1, t2
+ WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+ WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+
+SET optimizer_switch='join_cache_hashed=on';
+SET join_cache_level=4;
+EXPLAIN
+SELECT a, c FROM t1, t2
+ WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+ WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+SELECT a, c FROM t1, t2
+ WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+ WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+
+SET optimizer_switch=@save_optimizer_switch;
+SET join_cache_level=@save_join_cache_level;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # BUG#952297: Server crashes on 2nd execution of PS in Field::is_null with semijoin+materialization
+--echo #
+CREATE TABLE t1 ( a VARCHAR(1) );
+INSERT INTO t1 VALUES ('y'),('z');
+
+CREATE TABLE t2 ( b VARCHAR(1), c VARCHAR(1) );
+INSERT INTO t2 VALUES ('v','v'),('v','v');
+
+CREATE VIEW v2 AS SELECT * FROM t2;
+
+PREPARE ps FROM '
+SELECT a FROM t1, v2
+WHERE ( c, b ) IN ( SELECT b, b FROM t2 )
+GROUP BY a ';
+
+EXECUTE ps;
+EXECUTE ps;
+
+DROP VIEW v2;
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#1000269: Wrong result (extra rows) with semijoin+materialization, IN subqueries, join_cache_level>0
+--echo #
+CREATE TABLE t1 (a1 VARCHAR(1), a2 VARCHAR(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('b','b'),('e','e');
+
+CREATE TABLE t2 (b1 VARCHAR(1), b2 VARCHAR(1), KEY(b1)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('v','v'),('s','s'),('l','l'), ('y','y'),('c','c'),('i','i');
+
+SELECT * FROM t1, t2 WHERE b1 IN ( SELECT b2 FROM t2 WHERE b1 > 'o' ) AND ( b1 < 'l' OR a1 IN ('b','c') );
+
+DROP TABLE t1,t2;
+
+--echo # This must be at the end:
+set optimizer_switch=@subselect_sj_mat_tmp;
+set join_cache_level=@save_join_cache_level;
+
diff --git a/mysql-test/t/subselect_sj_nonmerged.test b/mysql-test/t/subselect_sj_nonmerged.test
new file mode 100644
index 00000000000..e47e72ffe97
--- /dev/null
+++ b/mysql-test/t/subselect_sj_nonmerged.test
@@ -0,0 +1,121 @@
+#
+# Tests for non-merged semi-joins
+#
+--disable_warnings
+drop table if exists t0, t1, t2, t3, t4;
+--enable_warnings
+
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+
+# Check the case of subquery having agggregates but not having grouping
+
+create table t1 as select * from t0;
+--echo # The following should use full scan on <subquery2> and it must scan 1 row:
+explain select * from t0 where a in (select max(a) from t1);
+select * from t0 where a in (select max(a) from t1);
+
+# Ok, now check the trivial match/no-match/NULL on the left/NULL on the right cases
+insert into t1 values (11);
+select * from t0 where a in (select max(a) from t1);
+delete from t1 where a=11;
+
+insert into t0 values (NULL);
+select * from t0 where a in (select max(a) from t1);
+delete from t0 where a is NULL;
+
+delete from t1;
+select * from t0 where a in (select max(a) from t1);
+
+insert into t0 values (NULL);
+select * from t0 where a in (select max(a) from t1);
+delete from t0 where a is NULL;
+
+drop table t1;
+
+#
+# Try with join subqueries
+#
+
+create table t1 (a int, b int);
+insert into t1 select a,a from t0; # 10 rows
+create table t2 as select * from t1 where a<5; # 5 rows
+create table t3 as select (A.a + 10*B.a) as a from t0 A, t0 B; # 100 rows
+alter table t3 add primary key(a);
+
+--echo # The following should have do a full scan on <subquery2> and scan 5 rows
+--echo # (despite that subquery's join output estimate is 50 rows)
+explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b);
+
+--echo # Compare to this which really will have 50 record combinations:
+explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b, t1.b);
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
+--echo # Outer joins also work:
+explain select * from t3
+where a in (select max(t2.a) from t1 left join t2 on t1.a=t2.a group by t2.b, t1.b);
+
+SET optimizer_switch=@save_optimizer_switch;
+
+#
+# Check if joins on the outer side also work
+#
+
+create table t4 (a int, b int, filler char(20), unique key(a,b));
+insert into t4 select A.a + 10*B.a, A.a + 10*B.a, 'filler' from t0 A, t0 B; # 100 rows
+explain select * from t0, t4 where
+ t4.b=t0.a and t4.a in (select max(t2.a) from t1, t2 group by t2.b);
+
+insert into t4 select 100 + (B.a *100 + A.a), 100 + (B.a*100 + A.a), 'filler' from t4 A, t0 B;
+explain select * from t4 where
+ t4.a in (select max(t2.a) from t1, t2 group by t2.b) and
+ t4.b in (select max(t2.a) from t1, t2 group by t2.b);
+
+drop table t1,t2,t3,t4;
+
+drop table t0;
+
+--echo #
+--echo # BUG#780359: Crash with get_fanout_with_deps in maria-5.3-mwl90
+--echo #
+CREATE TABLE t1 (f1 int);
+INSERT INTO t1 VALUES (2),(2);
+
+CREATE TABLE t2 (f3 int);
+INSERT INTO t2 VALUES (2),(2);
+
+SELECT *
+FROM t1
+WHERE ( f1 ) IN (
+ SELECT t2.f3
+ FROM t2
+ WHERE t2.f3 = 97
+ AND t2.f3 = 50
+ GROUP BY 1
+);
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#727183: WL#90 does not trigger with non-comma joins
+--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 A.a + 10*B.a + 100*C.a from t0 A, t0 B, t0 C;
+
+--echo # The following must use non-merged SJ-Materialization:
+explain select * from t1 X join t0 Y on X.a < Y.a where X.a in (select max(a) from t0);
+
+drop table t0, t1;
+
+set optimizer_switch=@save_optimizer_switch;
+
diff --git a/mysql-test/t/system_mysql_db_fix40123.test b/mysql-test/t/system_mysql_db_fix40123.test
index 440fcc8aa8a..08d40bdae0f 100644
--- a/mysql-test/t/system_mysql_db_fix40123.test
+++ b/mysql-test/t/system_mysql_db_fix40123.test
@@ -41,8 +41,8 @@ INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','
CREATE TABLE func ( name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL, PRIMARY KEY (name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User defined functions';
-CREATE TABLE tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges';
-CREATE TABLE columns_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges';
+CREATE TABLE tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp, Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges';
+CREATE TABLE columns_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges';
CREATE TABLE help_topic ( help_topic_id int unsigned not null, name varchar(64) not null, help_category_id smallint unsigned not null, description text not null, example text not null, url varchar(128) not null, primary key (help_topic_id), unique index (name) ) engine=MyISAM CHARACTER SET utf8 comment='help topics';
CREATE TABLE help_category ( help_category_id smallint unsigned not null, name varchar(64) not null, parent_category_id smallint unsigned null, url varchar(128) not null, primary key (help_category_id), unique index (name) ) engine=MyISAM CHARACTER SET utf8 comment='help categories';
diff --git a/mysql-test/t/system_mysql_db_fix50030.test b/mysql-test/t/system_mysql_db_fix50030.test
index 4924c625d57..41e85661fe8 100644
--- a/mysql-test/t/system_mysql_db_fix50030.test
+++ b/mysql-test/t/system_mysql_db_fix50030.test
@@ -39,9 +39,9 @@ INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','
CREATE TABLE func ( name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL, PRIMARY KEY (name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User defined functions';
-CREATE TABLE tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges';
+CREATE TABLE tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp, Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges';
-CREATE TABLE columns_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges';
+CREATE TABLE columns_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges';
CREATE TABLE help_topic ( help_topic_id int unsigned not null, name char(64) not null, help_category_id smallint unsigned not null, description text not null, example text not null, url char(128) not null, primary key (help_topic_id), unique index (name) ) engine=MyISAM CHARACTER SET utf8 comment='help topics';
CREATE TABLE help_category ( help_category_id smallint unsigned not null, name char(64) not null, parent_category_id smallint unsigned null, url char(128) not null, primary key (help_category_id), unique index (name) ) engine=MyISAM CHARACTER SET utf8 comment='help categories';
@@ -60,7 +60,7 @@ CREATE TABLE time_zone_leap_second ( Transition_time bigint signed NOT NULL,
CREATE TABLE proc ( db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum('CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA' ) DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob DEFAULT '' NOT NULL, returns char(64) DEFAULT '' NOT NULL, body longblob DEFAULT '' NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE' ) DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, PRIMARY KEY (db,name,type) ) engine=MyISAM character set utf8 comment='Stored Procedures';
-CREATE TABLE procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
+CREATE TABLE procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp, PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
CREATE TABLE servers ( Server_name char(64) NOT NULL DEFAULT '', Host char(64) NOT NULL DEFAULT '', Db char(64) NOT NULL DEFAULT '', Username char(64) NOT NULL DEFAULT '', Password char(64) NOT NULL DEFAULT '', Port INT(4) NOT NULL DEFAULT '0', Socket char(64) NOT NULL DEFAULT '', Wrapper char(64) NOT NULL DEFAULT '', Owner char(64) NOT NULL DEFAULT '', PRIMARY KEY (Server_name)) CHARACTER SET utf8 comment='MySQL Foreign Servers table';
diff --git a/mysql-test/t/system_mysql_db_fix50117.test b/mysql-test/t/system_mysql_db_fix50117.test
index d88c4edba93..bed00239081 100644
--- a/mysql-test/t/system_mysql_db_fix50117.test
+++ b/mysql-test/t/system_mysql_db_fix50117.test
@@ -44,9 +44,9 @@ CREATE TABLE IF NOT EXISTS plugin ( name char(64) binary DEFAULT '' NOT NULL, dl
CREATE TABLE IF NOT EXISTS servers ( Server_name char(64) NOT NULL DEFAULT '', Host char(64) NOT NULL DEFAULT '', Db char(64) NOT NULL DEFAULT '', Username char(64) NOT NULL DEFAULT '', Password char(64) NOT NULL DEFAULT '', Port INT(4) NOT NULL DEFAULT '0', Socket char(64) NOT NULL DEFAULT '', Wrapper char(64) NOT NULL DEFAULT '', Owner char(64) NOT NULL DEFAULT '', PRIMARY KEY (Server_name)) CHARACTER SET utf8 comment='MySQL Foreign Servers table';
-CREATE TABLE IF NOT EXISTS tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges';
+CREATE TABLE IF NOT EXISTS tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp, Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges';
-CREATE TABLE IF NOT EXISTS columns_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges';
+CREATE TABLE IF NOT EXISTS columns_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges';
CREATE TABLE IF NOT EXISTS help_topic ( help_topic_id int unsigned not null, name char(64) not null, help_category_id smallint unsigned not null, description text not null, example text not null, url char(128) not null, primary key (help_topic_id), unique index (name) ) engine=MyISAM CHARACTER SET utf8 comment='help topics';
@@ -79,7 +79,7 @@ CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint sign
CREATE TABLE IF NOT EXISTS proc ( db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum('CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA' ) DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns char(64) DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE' ) DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, PRIMARY KEY (db,name,type) ) engine=MyISAM character set utf8 comment='Stored Procedures';
-CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
+CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp, PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
diff --git a/mysql-test/t/table_elim.test b/mysql-test/t/table_elim.test
index a52e003066b..a957e24e393 100644
--- a/mysql-test/t/table_elim.test
+++ b/mysql-test/t/table_elim.test
@@ -6,6 +6,9 @@ drop table if exists t0, t1, t2, t3, t4, t5, t6;
drop view if exists v1, v2;
--enable_warnings
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
create table t1 (a int);
insert into t1 values (0),(1),(2),(3);
create table t0 as select * from t1;
@@ -223,7 +226,8 @@ create table t1 (a char(10) primary key);
insert into t1 values ('foo'),('bar');
create table t2 (a char(10), unique key(a(2)));
-insert into t2 values ('foo'),('bar');
+insert into t2 values
+ ('foo'),('bar'),('boo'),('car'),('coo'),('par'),('doo'),('tar');
explain select t1.* from t1 left join t2 on t2.a=t1.a;
@@ -541,3 +545,4 @@ DROP TABLE t1,t2,t3;
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/table_elim_debug.test b/mysql-test/t/table_elim_debug.test
index 9f793169e4f..6400f798195 100644
--- a/mysql-test/t/table_elim_debug.test
+++ b/mysql-test/t/table_elim_debug.test
@@ -1,7 +1,8 @@
#
# Table elimination (MWL#17) tests that need debug build
#
---source include/have_debug.inc
+# In MariaDB 5.3, one can switch table_elimination on/off without debug, too:
+## --source include/have_debug.inc
--disable_warnings
drop table if exists t1, t2;
diff --git a/mysql-test/t/timezone.test b/mysql-test/t/timezone.test
index 157b18f57fa..a41e806a40e 100644
--- a/mysql-test/t/timezone.test
+++ b/mysql-test/t/timezone.test
@@ -60,4 +60,6 @@ select unix_timestamp('1970-01-01 01:00:00'),
unix_timestamp('2038-01-19 04:14:07'),
unix_timestamp('2038-01-19 04:14:08');
+select unix_timestamp('1969-12-31 23:59:59'), unix_timestamp('1970-01-01 00:00:00'), unix_timestamp('1970-01-01 00:59:59');
+
# End of 4.1 tests
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index 8d84330ec44..4b261c9f023 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -2434,3 +2434,43 @@ select * from t2;
drop table t1,t2;
--echo End of 5.2 tests.
+
+--echo #
+--echo # BUG #910083: materialized subquery in a trigger
+--echo #
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='materialization=on';
+
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (b int);
+
+CREATE TRIGGER tr AFTER UPDATE ON t1 FOR EACH ROW
+ UPDATE t2 SET b = (SELECT COUNT(a) FROM t1);
+
+INSERT INTO t1
+ VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+INSERT INTO t2
+ VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0);
+
+send
+ UPDATE t1 SET a = 3;
+
+connect(con1,localhost,root,,);
+ SELECT COUNT(*) FROM t1;
+disconnect con1;
+
+connection default;
+reap;
+SELECT * FROM t2;
+UPDATE t1 SET a = 2;
+SELECT * FROM t2;
+
+SET optimizer_switch=@save_optimizer_switch;
+
+DROP TRIGGER tr;
+DROP TABLE t1, t2;
+
+--echo End of 5.3 tests.
+
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/type_blob.test b/mysql-test/t/type_blob.test
index 4e097edf73d..c5862699524 100644
--- a/mysql-test/t/type_blob.test
+++ b/mysql-test/t/type_blob.test
@@ -535,10 +535,10 @@ DROP TABLE b15776;
CREATE TABLE b15776 (a year(-2));
## For timestamp, we silently rewrite widths to 14 or 19.
+--error ER_TOO_BIG_PRECISION
CREATE TABLE b15776 (a timestamp(4294967294));
-DROP TABLE b15776;
+--error ER_TOO_BIG_PRECISION
CREATE TABLE b15776 (a timestamp(4294967295));
-DROP TABLE b15776;
--error ER_TOO_BIG_DISPLAYWIDTH
CREATE TABLE b15776 (a timestamp(4294967296));
--error ER_PARSE_ERROR
@@ -628,3 +628,11 @@ DROP TABLE t1;
--echo End of 5.1 tests
+#
+# Problem when comparing blobs #778901
+#
+
+CREATE TABLE t1 ( f1 blob, f2 blob );
+INSERT INTO t1 VALUES ('','');
+SELECT f1,f2,"found row" FROM t1 WHERE f1 = f2 ;
+DROP TABLE t1;
diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test
index a3fe1eaf73c..76da6402154 100644
--- a/mysql-test/t/type_date.test
+++ b/mysql-test/t/type_date.test
@@ -274,3 +274,11 @@ DROP TABLE t1;
DROP VIEW v1;
--echo End of 5.1 tests
+
+#
+# lp:737496 Field_temporal::store_TIME_with_warning() in 5.1-micro
+#
+create table t1 (f1 date, key (f1));
+insert t1 values ('2010-10-10 15:foobar');
+drop table t1;
+
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index 43dafc371dc..f9ee8dfd5d3 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -137,9 +137,9 @@ DROP TABLE t1;
# Bug 19491 (CAST DATE AS DECIMAL returns incorrect result
#
SELECT CAST(CAST('2006-08-10' AS DATE) AS DECIMAL(20,6));
-SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME) AS DECIMAL(20,6));
-SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME) + INTERVAL 14 MICROSECOND AS DECIMAL(20,6));
-SELECT CAST(CAST('10:11:12.098700' AS TIME) AS DECIMAL(20,6));
+SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME(6)) AS DECIMAL(20,6));
+SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME(6)) + INTERVAL 14 MICROSECOND AS DECIMAL(20,6));
+SELECT CAST(CAST('10:11:12.098700' AS TIME(6)) AS DECIMAL(20,6));
#
@@ -359,6 +359,9 @@ create table t2 (id int(10) not null, cur_date date not null);
insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22');
insert into t2 (id, cur_date) values (1, '2007-04-25');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='semijoin_with_cache=off';
+
explain extended
select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));
@@ -386,6 +389,8 @@ where id in (select id from t2 as x1 where (t2.cur_date is null));
select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));
+SET optimizer_switch=@save_optimizer_switch;
+
drop table t1,t2;
@@ -432,18 +437,18 @@ set @@sql_mode= @org_mode;
# Bug #42146 - DATETIME fractional seconds parse error
#
# show we trucate microseconds from the right -- special case: leftmost is 0
-SELECT CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME) AS DECIMAL(30,7));
+SELECT CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME(6)) AS DECIMAL(30,7));
# show that we ignore leading zeroes for all other fields
-SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME) AS DECIMAL(30,7));
+SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME(6)) AS DECIMAL(30,7));
# once more with feeling (but no warnings)
-SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME) AS DECIMAL(30,7));
+SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME(6)) AS DECIMAL(30,7));
#
# Bug #38435 - LONG Microseconds cause MySQL to fail a CAST to DATETIME or DATE
#
# show we truncate microseconds from the right
-SELECT CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7));
+SELECT CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime(6)) AS DECIMAL(30,7));
--echo #
--echo # Bug#59173: Failure to handle DATE(TIME) values where Year, Month or
diff --git a/mysql-test/t/type_datetime_hires.test b/mysql-test/t/type_datetime_hires.test
new file mode 100644
index 00000000000..74f686d4157
--- /dev/null
+++ b/mysql-test/t/type_datetime_hires.test
@@ -0,0 +1,71 @@
+
+--source include/have_partition.inc
+
+let type=datetime;
+--source include/type_hrtime.inc
+
+#
+# partitioning
+#
+eval CREATE TABLE t1 (
+ taken $type(5) NOT NULL DEFAULT '0000-00-00 00:00:00',
+ id int(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (id,taken),
+ KEY taken (taken)
+)
+PARTITION BY RANGE (to_days(taken))
+(
+PARTITION p01 VALUES LESS THAN (732920),
+PARTITION p02 VALUES LESS THAN (732950),
+PARTITION p03 VALUES LESS THAN MAXVALUE);
+
+INSERT INTO t1 VALUES
+('2006-09-27 21:50:01.123456',0),
+('2006-09-27 21:50:01.123456',1),
+('2006-09-27 21:50:01.123456',2),
+('2006-09-28 21:50:01.123456',3),
+('2006-09-29 21:50:01.123456',4),
+('2006-09-29 21:50:01.123456',5),
+('2006-09-30 21:50:01.123456',6),
+('2006-10-01 21:50:01.123456',7),
+('2006-10-02 21:50:01.123456',8),
+('2006-10-02 21:50:01.123456',9);
+
+SELECT id,to_days(taken) FROM t1 order by 2;
+
+eval CREATE TABLE t2 (
+ taken $type(5) NOT NULL DEFAULT '0000-00-00 00:00:00',
+ id int(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (id,taken),
+ KEY taken (taken)
+)
+PARTITION BY RANGE (extract(microsecond from taken))
+(
+PARTITION p01 VALUES LESS THAN (123000),
+PARTITION p02 VALUES LESS THAN (500000),
+PARTITION p03 VALUES LESS THAN MAXVALUE);
+
+INSERT INTO t2 VALUES
+('2006-09-27 21:50:01',0),
+('2006-09-27 21:50:01.1',1),
+('2006-09-27 21:50:01.12',2),
+('2006-09-28 21:50:01.123',3),
+('2006-09-29 21:50:01.1234',4),
+('2006-09-29 21:50:01.12345',5),
+('2006-09-30 21:50:01.123456',6),
+('2006-10-01 21:50:01.56',7),
+('2006-10-02 21:50:01.567',8),
+('2006-10-02 21:50:01.5678',9);
+
+select table_name,partition_name,partition_method,partition_expression,partition_description,table_rows from information_schema.partitions where table_name in ('t1', 't2');
+
+drop table t1, t2;
+
+create table t1 (a datetime, b datetime(6));
+insert t1 values ('2010-01-02 03:04:05.678912', '2010-01-02 03:04:05.678912');
+update t1 set b=a;
+select * from t1;
+alter table t1 modify b datetime, modify a datetime(6);
+select * from t1;
+drop table t1;
+
diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test
index 34331b72688..a456f2b9eea 100644
--- a/mysql-test/t/type_time.test
+++ b/mysql-test/t/type_time.test
@@ -100,3 +100,26 @@ SELECT TIMESTAMP(f1,'1') FROM t1;
DROP TABLE t1;
--echo End of 5.1 tests
+
+create table t1 (a time);
+insert t1 values (-131415);
+select * from t1;
+drop table t1;
+
+#
+# lp:731229 Different results depending on table access method with TIME column and CURDATE()
+#
+create table t1 (f1 time , f2 varchar(5), key(f1));
+insert into t1 values ('00:20:01','a'),('00:20:03','b');
+select * from t1 force key (f1) where f1 < curdate();
+select * from t1 ignore key (f1) where f1 < curdate();
+drop table t1;
+
+#
+# comparison of time and datetime:
+#
+create table t1(f1 time);
+insert into t1 values ('23:38:57');
+select f1, f1 = '2010-10-11 23:38:57' from t1;
+drop table t1;
+
diff --git a/mysql-test/t/type_time_hires.test b/mysql-test/t/type_time_hires.test
new file mode 100644
index 00000000000..3785a23f1eb
--- /dev/null
+++ b/mysql-test/t/type_time_hires.test
@@ -0,0 +1,12 @@
+
+let type=time;
+--source include/type_hrtime.inc
+
+create table t1 (a time(4) not null, key(a));
+insert into t1 values ('1:2:3.001'),('1:2:3'), ('-00:00:00.6'),('-00:00:00.7'),('-00:00:00.8'),('-00:00:00.9'),('-00:00:01.0'),('-00:00:01.1'),('-00:00:01.000000'),('-00:00:01.100001'),('-00:00:01.000002'),('-00:00:01.090000');
+select * from t1 order by a;
+select * from t1 order by a desc;
+select min(a - interval 1 hour), max(a - interval 1 hour) from t1 where a < 0;
+drop table t1;
+
+select cast(1e-6 as time(6));
diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test
index 53b45fc6732..674f22cd1c2 100644
--- a/mysql-test/t/type_timestamp.test
+++ b/mysql-test/t/type_timestamp.test
@@ -67,17 +67,6 @@ INSERT INTO t1 VALUES ("2030-01-01","2030-01-01 00:00:00",20300101000000);
SELECT * FROM t1;
drop table t1;
-create table t1 (t2 timestamp(2), t4 timestamp(4), t6 timestamp(6),
- t8 timestamp(8), t10 timestamp(10), t12 timestamp(12),
- t14 timestamp(14));
-insert t1 values (0,0,0,0,0,0,0),
-("1997-12-31 23:47:59", "1997-12-31 23:47:59", "1997-12-31 23:47:59",
-"1997-12-31 23:47:59", "1997-12-31 23:47:59", "1997-12-31 23:47:59",
-"1997-12-31 23:47:59");
-select * from t1;
-select * from t1;
-drop table t1;
-
#
# Let us check if we properly treat wrong datetimes and produce proper warnings
# (for both strings and numbers)
@@ -298,7 +287,7 @@ drop table t1;
# mode regardless of whether a display width is given.
#
set sql_mode='maxdb';
-create table t1 (a timestamp, b timestamp(19));
+create table t1 (a timestamp, b timestamp(5));
show create table t1;
# restore default mode
set sql_mode='';
@@ -421,3 +410,10 @@ SHOW STATUS LIKE 'Handler_read_next';
DROP TABLE t1, t2;
--echo End of 5.1 tests
+
+--echo #
+--echo # lp:923429 Crash in decimal_cmp on using UNIX_TIMESTAMP with a wrongly formatted timestamp
+--echo #
+SELECT UNIX_TIMESTAMP('abc') > 0;
+SELECT UNIX_TIMESTAMP('abc');
+
diff --git a/mysql-test/t/type_timestamp_hires.test b/mysql-test/t/type_timestamp_hires.test
new file mode 100644
index 00000000000..8e1f8586956
--- /dev/null
+++ b/mysql-test/t/type_timestamp_hires.test
@@ -0,0 +1,16 @@
+
+let type=timestamp;
+--source include/type_hrtime.inc
+
+set time_zone='+03:00';
+set timestamp=unix_timestamp('2011-01-01 01:01:01') + 0.123456;
+
+create table t1 (a timestamp(5));
+#
+# CREATE ... DEFAULT NOW(X)
+#
+
+insert t1 values ();
+select * from t1;
+drop table t1;
+
diff --git a/mysql-test/t/type_year.test b/mysql-test/t/type_year.test
index 8ba8260cfc4..d542bfaebfa 100644
--- a/mysql-test/t/type_year.test
+++ b/mysql-test/t/type_year.test
@@ -157,6 +157,7 @@ CREATE TABLE t1(c1 YEAR(4));
INSERT INTO t1 VALUES (1901),(2155),(0000);
SELECT * FROM t1;
SELECT COUNT(*) AS total_rows, MIN(c1) AS min_value, MAX(c1) FROM t1;
+SELECT COUNT(*) AS total_rows, MIN(c1+0) AS min_value, MAX(c1+0) FROM t1;
DROP TABLE t1;
--echo #
@@ -170,3 +171,20 @@ DROP TABLE t1;
--echo #
--echo End of 5.1 tests
+#
+# fun with convert_const_to_int
+# in some cases 00 is equal to 2000, in others it is not.
+#
+create function y2k() returns int deterministic return 2000;
+create table t1 (a year(2), b int);
+insert t1 values (0,2000);
+select a from t1 where a=2000; # constant.
+select a from t1 where a=1000+1000; # still a constant.
+select a from t1 where a=(select 2000); # even this is a constant
+select a from t1 where a=(select 2000 from dual where 1); # constant, but "expensive"
+select a from t1 where a=y2k(); # constant, but "expensive"
+select a from t1 where a=b; # not a constant
+drop table t1;
+drop function y2k;
+
+
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index 507f0ffa09f..fefd67fd2f7 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -563,7 +563,10 @@ drop table t1;
#
create table t1 ( RID int(11) not null default '0', IID int(11) not null default '0', nada varchar(50) not null,NAME varchar(50) not null,PHONE varchar(50) not null) engine=MyISAM;
insert into t1 ( RID,IID,nada,NAME,PHONE) values (1, 1, 'main', 'a', '111'), (2, 1, 'main', 'b', '222'), (3, 1, 'main', 'c', '333'), (4, 1, 'main', 'd', '444'), (5, 1, 'main', 'e', '555'), (6, 2, 'main', 'c', '333'), (7, 2, 'main', 'd', '454'), (8, 2, 'main', 'e', '555'), (9, 2, 'main', 'f', '666'), (10, 2, 'main', 'g', '777');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
select A.NAME, A.PHONE, B.NAME, B.PHONE from t1 A left join t1 B on A.NAME = B.NAME and B.IID = 2 where A.IID = 1 and (A.PHONE <> B.PHONE or B.NAME is null) union select A.NAME, A.PHONE, B.NAME, B.PHONE from t1 B left join t1 A on B.NAME = A.NAME and A.IID = 1 where B.IID = 2 and (A.PHONE <> B.PHONE or A.NAME is null);
+SET optimizer_switch=@save_optimizer_switch;
drop table t1;
#
@@ -1134,6 +1137,7 @@ SELECT * FROM t1 UNION SELECT * FROM t1
ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
--echo # Should not crash
+--sorted_result
(SELECT * FROM t1) UNION (SELECT * FROM t1)
ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
diff --git a/mysql-test/t/update_ignore_216.test b/mysql-test/t/update_ignore_216.test
new file mode 100644
index 00000000000..bae3930e1a7
--- /dev/null
+++ b/mysql-test/t/update_ignore_216.test
@@ -0,0 +1,13 @@
+#
+# MDEV-216 lp:976104 - Assertion `0' failed in my_message_sql on UPDATE IGNORE, or unknown error on release build
+#
+
+CREATE TABLE t1 ( a INT, b CHAR(3) );
+INSERT INTO t1 VALUES ( 1, 'foo' );
+CREATE TABLE t2 ( c CHAR(3), d INT );
+INSERT INTO t2 VALUES ( 'foo', 1 );
+
+UPDATE IGNORE t1, t2 SET b = 'bar', c = 'bar'
+ WHERE a != ( SELECT 1 UNION SELECT 2 );
+
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/user_limits-2.test b/mysql-test/t/user_limits-2.test
new file mode 100644
index 00000000000..a376c78a09b
--- /dev/null
+++ b/mysql-test/t/user_limits-2.test
@@ -0,0 +1,11 @@
+#
+# Test behavior of various per-account limits (aka quotas)
+#
+--source include/not_embedded.inc
+
+#
+# We will get an error as it was set to 0 at startup
+#
+--error ER_OPTION_PREVENTS_STATEMENT
+set global max_user_connections=100;
+
diff --git a/mysql-test/t/user_limits-master.opt b/mysql-test/t/user_limits-master.opt
new file mode 100644
index 00000000000..107b2e4a27f
--- /dev/null
+++ b/mysql-test/t/user_limits-master.opt
@@ -0,0 +1 @@
+--max-user-connections=1000
diff --git a/mysql-test/t/user_limits.test b/mysql-test/t/user_limits.test
index 41af032b97e..becaa0963cc 100644
--- a/mysql-test/t/user_limits.test
+++ b/mysql-test/t/user_limits.test
@@ -8,6 +8,8 @@
# Save the initial number of concurrent sessions
--source include/count_sessions.inc
+set @my_max_user_connections= @@global.max_user_connections;
+
# Prepare play-ground
--disable_warnings
drop table if exists t1;
@@ -120,8 +122,18 @@ select * from t1;
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
--error ER_USER_LIMIT_REACHED
connect (muc5, localhost, mysqltest_1,,);
-# Clean up
+
connection default;
+# Test with negative max_user_connections
+grant usage on *.* to mysqltest_1@localhost with max_user_connections -1;
+show grants for mysqltest_1@localhost;
+flush user_resources;
+show grants for mysqltest_1@localhost;
+--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
+--error ER_USER_LIMIT_REACHED
+connect (muc5, localhost, mysqltest_1,,);
+
+# Clean up
disconnect muc2;
disconnect muc3;
disconnect muc4;
@@ -165,12 +177,37 @@ disconnect muca1;
disconnect muca2;
disconnect muca3;
set global max_user_connections= 0;
-drop user mysqltest_1@localhost;
--enable_ps_protocol
+#
+# Test setting negative values of max_user_connections
+#
+grant usage on *.* to mysqltest_1@localhost with max_user_connections 0;
+set global max_user_connections=-1;
+show variables like "max_user_user_connections";
+select @@max_user_connections;
+select @@global.max_user_connections;
+# Check that we can't connect anymore except as root
+--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
+--error ER_TOO_MANY_USER_CONNECTIONS
+connect (muca2, localhost, mysqltest_1,,);
+connect (muca2, localhost, root,,);
+disconnect muca2;
+connection default;
+set global max_user_connections=1;
+# Check that we can connect one time, not two
+connect (muca2, localhost, mysqltest_1,,);
+--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
+--error ER_TOO_MANY_USER_CONNECTIONS
+connect (muca3, localhost, mysqltest_1,,);
+disconnect muca2;
+connection default;
+drop user mysqltest_1@localhost;
+
# Final cleanup
drop table t1;
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
+set global max_user_connections= @my_max_user_connections;
diff --git a/mysql-test/t/variables-big.test b/mysql-test/t/variables-big.test
index 85121fd8f6d..2c0f55032a5 100644
--- a/mysql-test/t/variables-big.test
+++ b/mysql-test/t/variables-big.test
@@ -44,18 +44,22 @@ SET SESSION transaction_prealloc_size=1024*1024*1024*1;
--replace_column 1 <Id> 3 <Host> 6 <Time>
# Embedded server is hardcoded to show "Writing to net" as STATE.
--replace_result "Writing to net" "NULL"
+--replace_regex /localhost[:0-9]*/localhost/
SHOW PROCESSLIST;
SET SESSION transaction_prealloc_size=1024*1024*1024*2;
--replace_column 1 <Id> 3 <Host> 6 <Time>
--replace_result "Writing to net" "NULL"
+--replace_regex /localhost[:0-9]*/localhost/
SHOW PROCESSLIST;
SET SESSION transaction_prealloc_size=1024*1024*1024*3;
--replace_column 1 <Id> 3 <Host> 6 <Time>
--replace_result "Writing to net" "NULL"
+--replace_regex /localhost[:0-9]*/localhost/
SHOW PROCESSLIST;
SET SESSION transaction_prealloc_size=1024*1024*1024*4;
--replace_column 1 <Id> 3 <Host> 6 <Time>
--replace_result "Writing to net" "NULL"
+--replace_regex /localhost[:0-9]*/localhost/
SHOW PROCESSLIST;
SET SESSION transaction_prealloc_size=1024*1024*1024*5;
--replace_column 1 <Id> 3 <Host> 6 <Time>
diff --git a/mysql-test/t/variables-master.opt b/mysql-test/t/variables-master.opt
new file mode 100644
index 00000000000..e4b213a0323
--- /dev/null
+++ b/mysql-test/t/variables-master.opt
@@ -0,0 +1 @@
+--max-user-connections=1
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index 2e1ecf9835a..6a9d0372c0a 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -23,6 +23,7 @@ set @my_max_delayed_threads =@@global.max_delayed_threads;
set @my_max_heap_table_size =@@global.max_heap_table_size;
set @my_max_insert_delayed_threads=@@global.max_insert_delayed_threads;
set @my_max_join_size =@@global.max_join_size;
+set @my_max_user_connections =@@global.max_user_connections;
set @my_myisam_data_pointer_size =@@global.myisam_data_pointer_size;
set @my_myisam_max_sort_file_size =@@global.myisam_max_sort_file_size;
set @my_net_buffer_length =@@global.net_buffer_length;
@@ -737,6 +738,7 @@ select * from information_schema.session_variables where variable_name like 'tmp
# Bug #19606: make ssl settings available via SHOW VARIABLES and @@variables
#
# Don't actually output, since it depends on the system
+set sort_buffer_size=1024*8;
--replace_column 1 # 2 # 3 # 4 # 5 #
select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key;
--replace_column 2 #
@@ -829,7 +831,7 @@ set global max_delayed_threads =@my_max_delayed_threads;
set global max_heap_table_size =@my_max_heap_table_size;
set global max_insert_delayed_threads=@my_max_insert_delayed_threads;
set global max_join_size =@my_max_join_size;
-set global max_user_connections =default;
+set global max_user_connections =@my_max_user_connections;
set global max_write_lock_count =default;
set global myisam_data_pointer_size =@my_myisam_data_pointer_size;
set global myisam_max_sort_file_size =@my_myisam_max_sort_file_size;
@@ -1287,29 +1289,49 @@ SET @@global.max_join_size=0;
SET @@global.key_buffer_size=0;
SET @@global.key_cache_block_size=0;
+# Restore variables
+SET @@global.max_binlog_cache_size=DEFAULT;
+SET @@global.max_join_size=DEFAULT;
+SET @@global.key_buffer_size=@kbs;
+SET @@global.key_cache_block_size=@kcbs;
+
#
# Bug#56976: added new start-up parameter
#
select @@max_long_data_size;
--echo #
---echo # Bug#11766424 59527: DECIMAL_BIN_SIZE: ASSERTION `SCALE >= 0 && PRECISION > 0 && SCALE <= PRE
+--echo # Bug#11766424 59527:
+--echo # Assert in DECIMAL_BIN_SIZE:
+--echo # `SCALE >= 0 && PRECISION > 0 && SCALE <= PRE
+--echo # This test also exposed a bug with sql_buffer_result
--echo #
CREATE TABLE t1(f1 DECIMAL(1,1) UNSIGNED);
INSERT INTO t1 VALUES (0.2),(0.1);
-SELECT 1 FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE @a=f1);
+set @a=NULL;
+set sql_buffer_result=0;
+SELECT 1 as 'one' FROM t1 GROUP BY @a:= ROUND(f1);
+
+explain SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0);
+SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0);
+SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE @a=f1);
+
+set sql_buffer_result=1;
+explain SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0);
+SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0);
+SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE @a=f1);
+
DROP TABLE t1;
+set sql_buffer_result=0;
+
+#
+# Test of CREATE ... CAST
+#
+
CREATE TABLE t1 AS SELECT @a:= CAST(1 AS UNSIGNED) AS a;
SHOW CREATE TABLE t1;
DROP TABLE t1;
-# cleanup
-SET @@global.max_binlog_cache_size=DEFAULT;
-SET @@global.max_join_size=DEFAULT;
-SET @@global.key_buffer_size=@kbs;
-SET @@global.key_cache_block_size=@kcbs;
-
-
--echo End of 5.1 tests
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 762c3121615..2a230e65493 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -5,6 +5,9 @@ drop database if exists mysqltest;
--enable_warnings
use test;
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
#
# some basic test of views and its functionality
#
@@ -2782,6 +2785,7 @@ DROP VIEW IF EXISTS v1;
#
# Bug#21261 Wrong access rights was required for an insert to a view
#
+
CREATE DATABASE bug21261DB;
USE bug21261DB;
connect (root,localhost,root,,bug21261DB);
@@ -3976,7 +3980,6 @@ drop table t1,t2;
--echo # -----------------------------------------------------------------
--echo # -- End of 5.1 tests.
--echo # -----------------------------------------------------------------
-
--echo #
--echo # Bug #794005: crash in st_table::mark_virtual_columns_for_write
--echo #
@@ -4030,3 +4033,571 @@ DROP TABLE t1,t2;
--echo # -----------------------------------------------------------------
--echo # -- End of 5.2 tests.
--echo # -----------------------------------------------------------------
+
+--echo #
+--echo # Bug #59696 Optimizer does not use equalities for conditions over view
+--echo #
+
+CREATE TABLE t1 (a int NOT NULL);
+INSERT INTO t1 VALUES
+ (9), (2), (8), (1), (3), (4), (2), (5),
+ (9), (2), (8), (1), (3), (4), (2), (5);
+
+CREATE TABLE t2 (pk int PRIMARY KEY, c int NOT NULL);
+INSERT INTO t2 VALUES
+ (9,90), (16, 160), (11,110), (1,10), (18,180), (2,20),
+ (14,140), (15, 150), (12,120), (3,30), (17,170), (19,190);
+
+EXPLAIN EXTENDED
+SELECT t1.a,t2.c FROM t1,t2 WHERE t2.pk = t1.a AND t2.pk > 8;
+FLUSH STATUS;
+SELECT t1.a,t2.c FROM t1,t2 WHERE t2.pk = t1.a AND t2.pk > 8;
+SHOW STATUS LIKE 'Handler_read_%';
+
+CREATE VIEW v AS SELECT * FROM t2;
+EXPLAIN EXTENDED
+SELECT t1.a,v.c FROM t1,v WHERE v.pk = t1.a AND v.pk > 8;
+FLUSH STATUS;
+SELECT t1.a,v.c FROM t1,v WHERE v.pk = t1.a AND v.pk > 8;
+SHOW STATUS LIKE 'Handler_read_%';
+DROP VIEW v;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug#702403: crash with multiple equalities and a view
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (10);
+
+CREATE TABLE t2 (pk int PRIMARY KEY, b int, INDEX idx (b));
+INSERT INTO t2 VALUES (1,2), (3,4);
+CREATE TABLE t3 (pk int PRIMARY KEY, b int, INDEX idx (b));
+INSERT INTO t3 VALUES (1,2), (3,4);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+EXPLAIN
+SELECT * FROM v1, t2, t3
+ WHERE t3.pk = v1.a AND t2.b = 1 AND t2.b = t3.pk AND v1.a BETWEEN 2 AND 5;
+
+SELECT * FROM v1, t2, t3
+ WHERE t3.pk = v1.a AND t2.b = 1 AND t2.b = t3.pk AND v1.a BETWEEN 2 AND 5;
+
+DROP VIEW v1;
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # Bug#717577: substitution for best field in a query over a view and
+--echo # with OR in the WHERE condition
+--echo #
+
+create table t1 (a int, b int);
+insert into t1 values (2,4), (1,3);
+create table t2 (c int);
+insert into t2 values (6), (4), (1), (3), (8), (3), (4), (2);
+
+select * from t1,t2 where t2.c=t1.a and t2.c < 3 or t2.c=t1.b and t2.c >=4;
+explain extended
+select * from t1,t2 where t2.c=t1.a and t2.c < 3 or t2.c=t1.b and t2.c >=4;
+
+create view v1 as select * from t2;
+select * from t1,v1 where v1.c=t1.a and v1.c < 3 or v1.c=t1.b and v1.c >=4;
+explain extended
+select * from t1,v1 where v1.c=t1.a and v1.c < 3 or v1.c=t1.b and v1.c >=4;
+
+create view v2 as select * from v1;
+select * from t1,v2 where v2.c=t1.a and v2.c < 3 or v2.c=t1.b and v2.c >=4;
+explain extended
+select * from t1,v2 where v2.c=t1.a and v2.c < 3 or v2.c=t1.b and v2.c >=4;
+
+create view v3 as select * from t1;
+select * from v3,v2 where v2.c=v3.a and v2.c < 3 or v2.c=v3.b and v2.c >=4;
+explain extended
+select * from v3,v2 where v2.c=v3.a and v2.c < 3 or v2.c=v3.b and v2.c >=4;
+
+drop view v1,v2,v3;
+drop table t1,t2;
+
+--echo #
+--echo # Bug#724942: substitution of the constant into a view field
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2), (9), (9), (6), (5), (4), (7);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT * FROM v1 WHERE a > -1 OR a > 6 AND a = 3;
+EXPLAIN EXTENDED
+SELECT * FROM v1 WHERE a > -1 OR a > 6 AND a = 3;
+
+SELECT * FROM v1 WHERE a > -1 OR a AND a = 0;
+EXPLAIN EXTENDED
+SELECT * FROM v1 WHERE a > -1 OR a AND a = 0;
+
+CREATE VIEW v2 AS SELECT * FROM v1;
+
+SELECT * FROM v2 WHERE a > -1 OR a AND a = 0;
+EXPLAIN EXTENDED
+SELECT * FROM v2 WHERE a > -1 OR a AND a = 0;
+
+DROP VIEW v1,v2;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a varchar(10), KEY (a)) ;
+INSERT INTO t1 VALUES
+ ('DD'), ('ZZ'), ('ZZ'), ('KK'), ('FF'), ('HH'),('MM');
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT * FROM v1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV';
+EXPLAIN EXTENDED
+SELECT * FROM v1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV';
+
+SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV';
+EXPLAIN EXTENDED
+SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV';
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#777745: crash with equality propagation
+--echo # over view fields
+--echo #
+
+CREATE TABLE t1 (a int NOT NULL ) ;
+INSERT INTO t1 VALUES (2), (1);
+
+CREATE TABLE t2 (a int NOT NULL , b int NOT NULL) ;
+INSERT INTO t2 VALUES (2,20),(2,30);
+
+CREATE VIEW v2 AS SELECT * FROM t2;
+
+EXPLAIN
+SELECT * FROM t1,v2
+ WHERE v2.a = t1.a AND v2.a = 2 AND v2.a IS NULL AND t1.a != 0;
+SELECT * FROM t1,v2
+ WHERE v2.a = t1.a AND v2.a = 2 AND v2.a IS NULL AND t1.a != 0;
+
+EXPLAIN
+SELECT * FROM t1,v2
+ WHERE v2.a = t1.a AND v2.a = 2 AND v2.a+1 > 2 AND t1.a != 0;
+SELECT * FROM t1,v2
+ WHERE v2.a = t1.a AND v2.a = 2 AND v2.a+1 > 2 AND t1.a != 0;
+
+DROP VIEW v2;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug#794038: crash with INSERT/UPDATE/DELETE
+--echo # over a non-updatable view
+--echo #
+
+CREATE TABLE t1 (a int);
+CREATE ALGORITHM = TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+CREATE ALGORITHM = MERGE VIEW v2 AS SELECT * FROM v1;
+CREATE ALGORITHM = TEMPTABLE VIEW v3 AS SELECT * FROM v2;
+
+-- error ER_NON_INSERTABLE_TABLE
+INSERT INTO v3 VALUES (1);
+-- error ER_NON_UPDATABLE_TABLE
+UPDATE v3 SET a=0;
+-- error ER_NON_UPDATABLE_TABLE
+DELETE FROM v3;
+
+DROP VIEW v1,v2,v3;
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#798621: crash with a view string field equal
+--echo # to a constant
+--echo #
+
+CREATE TABLE t1 (a varchar(32), b int) ;
+INSERT INTO t1 VALUES ('j', NULL), ('c', 8), ('c', 1);
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+CREATE TABLE t2 (a varchar(32)) ;
+INSERT INTO t2 VALUES ('j'), ('c');
+
+SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a
+ WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b;
+EXPLAIN EXTENDED
+SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a
+ WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo # Bug#798625: duplicate of the previous one, but without crash
+
+CREATE TABLE t1 (f1 int NOT NULL, f2 int, f3 int, f4 varchar(32), f5 int) ;
+INSERT INTO t1 VALUES (20,5,2,'r', 0);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT v1.f4 FROM v1
+ WHERE f1<>0 OR f2<>0 AND f4='v' AND (f2<>0 OR f3<>0 AND f5<>0 OR f4 LIKE '%b%');
+EXPLAIN EXTENDED
+SELECT v1.f4 FROM v1
+ WHERE f1<>0 OR f2<>0 AND f4='v' AND (f2<>0 OR f3<>0 AND f5<>0 OR f4 LIKE '%b%');
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#798576: abort on a GROUP BY query over a view with left join
+--echo # that can be converted to inner join
+--echo #
+
+CREATE TABLE t1 (a int NOT NULL , b int NOT NULL) ;
+INSERT INTO t1 VALUES (214,0), (6,6), (6,0), (7,0);
+
+CREATE TABLE t2 (b int) ;
+INSERT INTO t2 VALUES (88), (78), (6);
+
+CREATE ALGORITHM=MERGE VIEW v1 AS
+ SELECT t1.a, t2.b FROM (t2 LEFT JOIN t1 ON t2.b > t1.a) WHERE t1.b <= 0;
+
+SELECT * FROM v1;
+SELECT a, MIN(b) FROM v1 GROUP BY a;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #793386: unexpected 'Duplicate column name ''' error
+--echo # at the second execution of a PS using a view
+--echo #
+
+CREATE TABLE t1 (f1 int, f2 int, f3 int, f4 int);
+
+CREATE VIEW v1 AS
+ SELECT t.f1, t.f2, s.f3, s.f4 FROM t1 t, t1 s
+ WHERE t.f4 >= s.f2 AND s.f3 < 0;
+
+PREPARE stmt1 FROM
+ "SELECT s.f1 AS f1, s.f2 AS f2, s.f3 AS f3, t.f4 AS f4
+ FROM v1 AS t LEFT JOIN v1 AS s ON t.f4=s.f4 WHERE t.f2 <> 1225";
+EXECUTE stmt1;
+EXECUTE stmt1;
+
+DEALLOCATE PREPARE stmt1;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo #
+--echo # LP BUG#806071 (2 views with ORDER BY)
+--echo #
+
+CREATE TABLE t1 (f1 int);
+INSERT INTO t1 VALUES (1),(1);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT f1 FROM t1;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT f1 FROM v1 ORDER BY f1;
+
+SELECT * FROM v2 AS a1, v2 AS a2;
+EXPLAIN EXTENDED SELECT * FROM v2 AS a1, v2 AS a2;
+
+DROP VIEW v1, v2;
+DROP TABLE t1;
+
+--echo #
+--echo # LP bug #823189: dependent subquery with RIGHT JOIN
+--echo # referencing view in WHERE
+--echo #
+
+CREATE TABLE t1 (a varchar(32));
+INSERT INTO t1 VALUES ('y'), ('w');
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (10);
+
+CREATE TABLE t3 (a varchar(32), b int);
+
+CREATE TABLE t4 (a varchar(32));
+INSERT INTO t4 VALUES ('y'), ('w');
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+EXPLAIN EXTENDED
+SELECT * FROM t1, t2
+ WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+ WHERE t4.a >= t1.a);
+SELECT * FROM t1, t2
+ WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+ WHERE t4.a >= t1.a);
+
+EXPLAIN EXTENDED
+SELECT * FROM v1, t2
+ WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+ WHERE t4.a >= v1.a);
+SELECT * FROM v1, t2
+ WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+ WHERE t4.a >= v1.a);
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3,t4;
+
+
+--echo #
+--echo # LP bug #823237: dependent subquery with LEFT JOIN
+--echo # referencing view in WHERE
+--echo # (duplicate of LP bug #823189)
+--echo #
+
+CREATE TABLE t1 (a int);
+
+CREATE TABLE t2 ( b int, d int, e int);
+INSERT INTO t2 VALUES (7,8,0);
+
+CREATE TABLE t3 ( c int);
+INSERT INTO t3 VALUES (0);
+
+CREATE TABLE t4 (a int, b int, c int);
+INSERT INTO t4 VALUES (93,1,0), (95,NULL,0);
+
+CREATE VIEW v4 AS SELECT * FROM t4;
+
+EXPLAIN EXTENDED
+SELECT * FROM t3 , t4
+ WHERE t4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d )
+ WHERE t2.b > t4.b);
+SELECT * FROM t3 , t4
+ WHERE t4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d )
+ WHERE t2.b > t4.b);
+
+
+EXPLAIN EXTENDED
+SELECT * FROM t3, v4
+ WHERE v4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d )
+ WHERE t2.b > v4.b);
+
+SELECT * FROM t3, v4
+ WHERE v4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d )
+ WHERE t2.b > v4.b);
+
+DROP VIEW v4;
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # BUG#833600: Wrong result with view + outer join + uncorrelated subquery (non-semijoin)
+--echo #
+
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (0,0),(0,0);
+
+CREATE TABLE t2 ( a int, b int );
+INSERT IGNORE INTO t2 VALUES (1,0),(1,0);
+
+CREATE TABLE t3 ( b int );
+INSERT IGNORE INTO t3 VALUES (0),(0);
+
+CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2;
+SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM t3 ) AND t1.b IS NULL ;
+
+SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM t3 ) AND t1.b IS NULL ;
+
+DROP VIEW v2;
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # BUG#915222: Valgrind complains or crashes with INSERT SELECT
+--echo # within a trigger that uses a view
+--echo #
+
+CREATE TABLE t1 (a char(1));
+
+CREATE TABLE t2 (d int, e char(1));
+
+INSERT INTO t2 VALUES (13,'z');
+
+CREATE TRIGGER tr AFTER UPDATE ON t2
+ FOR EACH ROW
+ REPLACE INTO t3
+ SELECT f, a AS alias FROM t3, v;
+
+CREATE TABLE t3 (f int, g char(8));
+
+CREATE VIEW v AS SELECT a, e FROM t2, t1;
+
+UPDATE t2 SET d=7;
+UPDATE t2 SET d=7;
+UPDATE t2 SET d=7;
+UPDATE t2 SET d=7;
+
+DROP TRIGGER tr;
+DROP VIEW v;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # BUG#972943: Assertion failure with INSERT SELECT within a trigger
+--echo # that uses derived table and materialized view
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (1,0), (2,8);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1
+ AS SELECT * FROM t1;
+
+CREATE TABLE t2 (c int);
+CREATE TABLE t3 (d int, e int);
+
+CREATE TRIGGER tr BEFORE INSERT ON t2 FOR EACH ROW
+ INSERT INTO t3
+ SELECT t1.*
+ FROM (SELECT * FROM t1 WHERE b IN (SELECT b FROM v1)) AS alias1, t1
+ WHERE t1.a = 3 OR t1.a > 5;
+
+INSERT INTO t2 VALUES (1);
+
+DROP TRIGGER tr;
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug#1007622 Server crashes in handler::increment_statistics on
+--echo # inserting into a view over a view
+--echo #
+
+CREATE TABLE t1 (a INT);
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT a1.* FROM t1 AS a1, t1 AS a2;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM v1;
+INSERT INTO v2 (a) VALUES (1) ;
+select * from t1;
+drop view v2,v1;
+drop table t1;
+
+--echo #
+--echo # MDEV-486 LP BUG#1010116 Incorrect query results in
+--echo # view and derived tables
+--echo #
+
+SELECT
+`Derived1`.`id`,
+`Derived2`.`Val1`
+FROM (select 30631 as `id`) AS `Derived1` LEFT OUTER JOIN (SELECT
+2 as `id`,
+1 AS `Val1`
+FROM (select 30631 as `id`) AS `Derived3`) AS `Derived2` ON `Derived1`.`id` = `Derived2`.`id`;
+
+create table t1 ( id int );
+insert into t1 values (30631);
+create table t2 ( id int );
+insert into t2 values (30631);
+create algorithm=MERGE view v2 as select 2 as id, 1 as val1 from t2;
+select t1.*, v2.* from t1 left join v2 on t1.id = v2.id;
+drop view v2;
+drop table t1,t2;
+
+create table t1 ( id int );
+insert into t1 values (30631);
+create table t2 ( id int );
+insert into t2 values (30631);
+create algorithm=MERGE view v2 as select 2 as id, id is null as bbb, id as iddqd, 1 as val1 from t2;
+select t1.*, v2.* from t1 left join v2 on t1.id = v2.id;
+drop view v2;
+drop table t1,t2;
+
+--echo #
+--echo # MDEV-3914: Wrong result (NULLs instead of real values)
+--echo # with INNER and RIGHT JOIN in a FROM subquery, derived_merge=on
+--echo # (fix of above MDEV-486 fix)
+--echo #
+SET @save_optimizer_switch_MDEV_3914=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on';
+
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (3),(4);
+
+CREATE TABLE t3 (c INT) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (5),(6);
+
+SELECT * FROM ( SELECT c FROM ( t1 INNER JOIN t2 ) RIGHT JOIN t3 ON a = c ) AS alias;
+
+SET optimizer_switch = 'derived_merge=off';
+
+SELECT * FROM ( SELECT c FROM ( t1 INNER JOIN t2 ) RIGHT JOIN t3 ON a = c ) AS alias;
+
+SET optimizer_switch=@save_optimizer_switch_MDEV_3914;
+drop table t1,t2,t3;
+
+--echo #
+--echo # MDEV-589 (LP BUG#1007647) :
+--echo # Assertion `vcol_table == 0 || vcol_table == table' failed in
+--echo # fill_record(THD*, List<Item>&, List<Item>&, bool)
+--echo #
+CREATE TABLE t1 (f1 INT, f2 INT);
+CREATE TABLE t2 (f1 INT, f2 INT);
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT a1.f1, a2.f2 FROM t1 AS a1, t1 AS a2;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM v1;
+CREATE ALGORITHM=MERGE VIEW v3 AS SELECT a1.f1, a2.f2 FROM t1 AS a1, t2 AS a2;
+CREATE ALGORITHM=MERGE VIEW v4 AS SELECT * FROM v3;
+--error ER_VIEW_MULTIUPDATE
+INSERT INTO v3 (f1, f2) VALUES (1, 2);
+--error ER_VIEW_MULTIUPDATE
+INSERT INTO v1 (f1, f2) VALUES (1, 2);
+--error ER_VIEW_MULTIUPDATE
+INSERT INTO v4 (f1, f2) VALUES (1, 2);
+--error ER_VIEW_MULTIUPDATE
+INSERT INTO v2 (f1, f2) VALUES (1, 2);
+drop view v4,v3,v2,v1;
+drop table t1,t2;
+
+--echo #
+--echo # MDEV-3799 fix of above bugfix (MDEV-589)
+--echo # Wrong result (NULLs instead of real values) with RIGHT JOIN
+--echo # in a FROM subquery and derived_merge=on
+--echo #
+
+CREATE TABLE t1 (f1 INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4),(6);
+
+CREATE TABLE t2 (f2 INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (7),(8);
+
+SELECT * FROM (
+ SELECT * FROM t1 RIGHT JOIN t2 ON f1 = f2
+) AS alias;
+
+SELECT * FROM (
+ SELECT * FROM t2 LEFT JOIN t1 ON f1 = f2
+) AS alias;
+
+drop tables t1,t2;
+
+
+--echo #
+--echo # MDEV-3876 Wrong result (extra rows) with ALL subquery
+--echo # from a MERGE view (duplicate of MDEV-3873)
+--echo #
+
+CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2 (b INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1),(3);
+
+CREATE OR REPLACE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t2;
+
+SELECT a FROM t1 AS alias
+WHERE a >= ALL (
+SELECT b FROM t1 LEFT JOIN v1 ON (a = b)
+WHERE a = alias.a );
+
+drop view v1;
+drop table t1,t2;
+
+--echo # -----------------------------------------------------------------
+--echo # -- End of 5.3 tests.
+--echo # -----------------------------------------------------------------
+
+SET optimizer_switch=@save_optimizer_switch;
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/mysql-test/t/xa_binlog.test b/mysql-test/t/xa_binlog.test
new file mode 100644
index 00000000000..48f1dc6dfaa
--- /dev/null
+++ b/mysql-test/t/xa_binlog.test
@@ -0,0 +1,32 @@
+--source include/have_innodb.inc
+--source include/have_log_bin.inc
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+
+# Fix binlog format (otherwise SHOW BINLOG EVENTS will fluctuate).
+SET binlog_format= mixed;
+
+RESET MASTER;
+
+XA START 'xatest';
+INSERT INTO t1 VALUES (1);
+XA END 'xatest';
+XA PREPARE 'xatest';
+XA COMMIT 'xatest';
+
+XA START 'xatest';
+INSERT INTO t1 VALUES (2);
+XA END 'xatest';
+XA COMMIT 'xatest' ONE PHASE;
+
+BEGIN;
+INSERT INTO t1 VALUES (3);
+COMMIT;
+
+SELECT * FROM t1 ORDER BY a;
+
+--replace_column 2 # 5 #
+--replace_regex /xid=[0-9]+/xid=XX/
+SHOW BINLOG EVENTS LIMIT 1,9;
+
+DROP TABLE t1;
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index 30d77fa3e72..0c75b4facab 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -273,6 +273,15 @@
fun:do_flush
}
+{
+ libz inflatereset2
+ Memcheck:Cond
+ fun:inflateReset2
+ fun:inflateInit2_
+ fun:uncompress
+}
+
+
#
# Warning from my_thread_init becasue mysqld dies before kill thread exists
#
@@ -386,6 +395,7 @@
fun:__libc_start_main
}
+
#
# dlclose can allocate memory for error message, the memory will be
# freed by dlerror or other dl* function.
@@ -400,6 +410,16 @@
{
+ dlclose memory loss from plugin variant 10
+ Memcheck:Leak
+ fun:calloc
+ obj:/lib*/libdl-*.so
+ fun:dlclose
+ fun:*free_plugin_mem*
+ fun:*plugin_dl_del*
+}
+
+{
dlsym memory loss from plugin on SuSE 11.1 x64
Memcheck:Leak
fun:*alloc
@@ -489,7 +509,7 @@
}
{
- dlsym memory loss from plugin
+ dlsym memory loss from plugin version 2
Memcheck:Leak
obj:/lib*/ld-*.so
obj:/lib*/ld-*.so
@@ -501,6 +521,20 @@
fun:dlsym
}
+{
+ dlsym memory loss from plugin version 3
+ Memcheck:Leak
+ fun:malloc
+ obj:/lib*/ld-*.so
+ obj:/lib*/ld-*.so
+ obj:/lib*/ld-*.so
+ obj:/lib*/libc-*.so)
+ obj:/lib*/libdl-*.so)
+ obj:/lib*/ld-*.so)
+ obj:/lib*/libdl-*.so)
+ fun:dlsym
+}
+
#
# Reading wrong addresses on SuSe Linux 10.3 32 bit
#
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index bff418370cc..9e35a98faac 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -38,9 +38,9 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_
my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c
my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c
my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
- my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c stacktrace.c
+ my_winerr.c my_winfile.c my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c stacktrace.c
rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
- thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c
+ thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c ma_dyncol.c
lf_alloc-pin.c lf_dynarray.c lf_hash.c
my_atomic.c my_getncpus.c my_rnd.c
my_uuid.c wqueue.c waiting_threads.c
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index f618f5d88e3..eb263ee34c6 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -27,7 +27,7 @@ libmysys_la_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
mf_path.c mf_loadpath.c my_file.c \
my_open.c my_create.c my_dup.c my_seek.c my_read.c \
my_pread.c my_write.c my_getpagesize.c \
- my_crc32.c \
+ my_crc32.c ma_dyncol.c \
mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \
mf_tempdir.c my_lock.c mf_brkhant.c my_alarm.c \
my_malloc.c my_realloc.c my_once.c mulalloc.c \
@@ -74,7 +74,7 @@ endif
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c waiting_threads.c \
CMakeLists.txt mf_soundex.c \
- my_conio.c my_wincond.c my_winthread.c
+ my_conio.c my_wincond.c my_winthread.c my_winfile.c my_winerr.c
# test_dir_DEPENDENCIES= $(LIBRARIES)
# testhash_DEPENDENCIES= $(LIBRARIES)
# test_charset_DEPENDENCIES= $(LIBRARIES)
diff --git a/mysys/charset.c b/mysys/charset.c
index 6a6f25e34b4..fe8eff5af2b 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -99,6 +99,9 @@ static my_bool init_state_maps(struct charset_info_st *cs)
state_map[(uchar)'@']= (uchar) MY_LEX_USER_END;
state_map[(uchar) '`']= (uchar) MY_LEX_USER_VARIABLE_DELIMITER;
state_map[(uchar)'"']= (uchar) MY_LEX_STRING_OR_DELIMITER;
+ state_map[(uchar)'-']= (uchar) MY_LEX_MINUS_OR_COMMENT;
+ state_map[(uchar)',']= (uchar) MY_LEX_COMMA;
+ state_map[(uchar)'?']= (uchar) MY_LEX_PLACEHOLDER;
/*
Create a second map to make it faster to find identifiers
diff --git a/mysys/default_modify.c b/mysys/default_modify.c
index 88df0122da2..ccbf47176a6 100644
--- a/mysys/default_modify.c
+++ b/mysys/default_modify.c
@@ -21,7 +21,7 @@
#define BUFF_SIZE 1024
#define RESERVE 1024 /* Extend buffer with this extent */
-#ifdef __WIN__
+#ifdef _WIN32
#define NEWLINE "\r\n"
#define NEWLINE_LEN 2
#else
@@ -78,7 +78,7 @@ int modify_defaults_file(const char *file_location, const char *option,
DBUG_RETURN(2);
/* my_fstat doesn't use the flag parameter */
- if (my_fstat(fileno(cnf_file), &file_stat, MYF(0)))
+ if (my_fstat(my_fileno(cnf_file), &file_stat, MYF(0)))
goto malloc_err;
if (option && option_value)
@@ -96,7 +96,7 @@ int modify_defaults_file(const char *file_location, const char *option,
NEWLINE_LEN + /* Space for newline */
RESERVE); /* Some additional space */
- buffer_size= (file_stat.st_size +
+ buffer_size= (uint)(file_stat.st_size +
1); /* The ending zero */
/*
@@ -213,7 +213,7 @@ int modify_defaults_file(const char *file_location, const char *option,
if (opt_applied)
{
/* Don't write the file if there are no changes to be made */
- if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0,
+ if (my_chsize(my_fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0,
MYF(MY_WME)) ||
my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) ||
my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer),
diff --git a/mysys/hash.c b/mysys/hash.c
index c2964b58b1a..f60092391fa 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -185,8 +185,9 @@ my_hash_key(const HASH *hash, const uchar *record, size_t *length,
static uint my_hash_mask(size_t hashnr, size_t buffmax, size_t maxlength)
{
- if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
- return (hashnr & ((buffmax >> 1) -1));
+ if ((hashnr & (buffmax-1)) < maxlength)
+ return (uint) (hashnr & (buffmax-1));
+ return (uint) (hashnr & ((buffmax >> 1) -1));
}
static uint my_hash_rec_mask(const HASH *hash, HASH_LINK *pos,
@@ -487,7 +488,8 @@ my_bool my_hash_insert(HASH *info, const uchar *record)
my_bool my_hash_delete(HASH *hash, uchar *record)
{
- uint blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
+ uint pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
+ size_t blength;
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
DBUG_ENTER("my_hash_delete");
if (!hash->records)
@@ -576,8 +578,8 @@ exit:
my_bool my_hash_update(HASH *hash, uchar *record, uchar *old_key,
size_t old_key_length)
{
- uint new_index,new_pos_index,blength,records;
- size_t idx,empty;
+ uint new_index,new_pos_index,records;
+ size_t idx, empty, blength;
HASH_LINK org_link,*data,*previous,*pos;
DBUG_ENTER("my_hash_update");
@@ -659,7 +661,7 @@ my_bool my_hash_update(HASH *hash, uchar *record, uchar *old_key,
if (new_index != new_pos_index)
{ /* Other record in wrong position */
data[empty] = *pos;
- movelink(data,new_index,new_pos_index,empty);
+ movelink(data,new_index,new_pos_index, (uint) empty);
org_link.next=NO_RECORD;
data[new_index]= org_link;
}
@@ -667,7 +669,7 @@ my_bool my_hash_update(HASH *hash, uchar *record, uchar *old_key,
{ /* Link in chain at right position */
org_link.next=data[new_index].next;
data[empty]=org_link;
- data[new_index].next=empty;
+ data[new_index].next= (uint) empty;
}
DBUG_RETURN(0);
}
@@ -731,7 +733,8 @@ my_bool my_hash_check(HASH *hash)
{
int error;
uint i,rec_link,found,max_links,seek,links,idx;
- uint records,blength;
+ uint records;
+ size_t blength;
HASH_LINK *data,*hash_info;
records=hash->records; blength=hash->blength;
diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c
new file mode 100644
index 00000000000..03d9007c7cb
--- /dev/null
+++ b/mysys/ma_dyncol.c
@@ -0,0 +1,2111 @@
+/* Copyright (c) 2011, Monty Program Ab
+ Copyright (c) 2011, Oleksandr Byelkin
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``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> OR
+ CONTRIBUTORS 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.
+*/
+
+#include "mysys_priv.h"
+#include <m_string.h>
+#include <ma_dyncol.h>
+
+/*
+ Flag byte bits
+
+ 2 bits which determinate size of offset in the header -1
+*/
+/* mask to get above bits */
+#define DYNCOL_FLG_OFFSET 3
+/* All known flags mask */
+#define DYNCOL_FLG_KNOWN 3
+
+/* dynamic column size reserve */
+#define DYNCOL_SYZERESERVE 80
+
+/* length of fixed string header 1 byte - flags, 2 bytes - columns counter */
+#define FIXED_HEADER_SIZE 3
+
+#define COLUMN_NUMBER_SIZE 2
+
+#define MAX_OFFSET_LENGTH 5
+
+static enum enum_dyncol_func_result
+dynamic_column_time_store(DYNAMIC_COLUMN *str,
+ MYSQL_TIME *value);
+static enum enum_dyncol_func_result
+dynamic_column_date_store(DYNAMIC_COLUMN *str,
+ MYSQL_TIME *value);
+static enum enum_dyncol_func_result
+dynamic_column_time_read_internal(DYNAMIC_COLUMN_VALUE *store_it_here,
+ uchar *data, size_t length);
+static enum enum_dyncol_func_result
+dynamic_column_date_read_internal(DYNAMIC_COLUMN_VALUE *store_it_here,
+ uchar *data, size_t length);
+
+/**
+ Initialize dynamic column string with (make it empty but correct format)
+
+ @param str The string to initialize
+ @param size Amount of preallocated memory for the string.
+
+ @retval FALSE OK
+ @retval TRUE error
+*/
+
+static my_bool dynamic_column_init_str(DYNAMIC_COLUMN *str, size_t size)
+{
+ DBUG_ASSERT(size != 0);
+
+ /*
+ Make string with no fields (empty header)
+ - First \0 is flags
+ - other 2 \0 is number of fields
+ */
+ if (init_dynamic_string(str, NULL,
+ size + FIXED_HEADER_SIZE, DYNCOL_SYZERESERVE))
+ return TRUE;
+ bzero(str->str, FIXED_HEADER_SIZE);
+ str->length= FIXED_HEADER_SIZE;
+ return FALSE;
+}
+
+
+/**
+ Calculate how many bytes needed to store val as variable length integer
+ where first bit indicate continuation of the sequence.
+
+ @param val The value for which we are calculating length
+
+ @return number of bytes
+*/
+
+static size_t dynamic_column_var_uint_bytes(ulonglong val)
+{
+ size_t len= 0;
+ do
+ {
+ len++;
+ val>>= 7;
+ } while (val);
+ return len;
+}
+
+
+/**
+ Stores variable length unsigned integer value to a string
+
+ @param str The string where to append the value
+ @param val The value to put in the string
+
+ @return ER_DYNCOL_* return code
+
+ @notes
+ This is used to store a number together with other data in the same
+ object. (Like decimals, length of string etc)
+ (As we don't know the length of this object, we can't store 0 in 0 bytes)
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_var_uint_store(DYNAMIC_COLUMN *str, ulonglong val)
+{
+ if (dynstr_realloc(str, 10)) /* max what we can use */
+ return ER_DYNCOL_RESOURCE;
+
+ do
+ {
+ ulonglong rest= val >> 7;
+ str->str[str->length++]= ((val & 0x7f) | (rest ? 0x80 : 0x00));
+ val= rest;
+ } while (val);
+ return ER_DYNCOL_OK;
+}
+
+
+/**
+ Reads variable length unsigned integer value from a string
+
+ @param data The string from which the int should be read
+ @param data_length Max length of data
+ @param len Where to put length of the string read in bytes
+
+ @return value of the unsigned integer read from the string
+
+ In case of error, *len is set to 0
+*/
+
+static ulonglong
+dynamic_column_var_uint_get(uchar *data, size_t data_length,
+ size_t *len)
+{
+ ulonglong val= 0;
+ uint length;
+ uchar *end= data + data_length;
+
+ for (length=0; data < end ; data++)
+ {
+ val+= (((ulonglong)((*data) & 0x7f)) << (length * 7));
+ length++;
+ if (!((*data) & 0x80))
+ {
+ /* End of data */
+ *len= length;
+ return val;
+ }
+ }
+ /* Something was wrong with data */
+ *len= 0; /* Mark error */
+ return 0;
+}
+
+
+/**
+ Calculate how many bytes needed to store val as unsigned.
+
+ @param val The value for which we are calculating length
+
+ @return number of bytes (0-8)
+*/
+
+static size_t dynamic_column_uint_bytes(ulonglong val)
+{
+ size_t len;
+
+ for (len= 0; val ; val>>= 8, len++)
+ ;
+ return len;
+}
+
+
+/**
+ Append the string with given unsigned int value.
+
+ @param str The string where to put the value
+ @param val The value to put in the string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_uint_store(DYNAMIC_COLUMN *str, ulonglong val)
+{
+ if (dynstr_realloc(str, 8)) /* max what we can use */
+ return ER_DYNCOL_RESOURCE;
+
+ for (; val; val>>= 8)
+ str->str[str->length++]= (char) (val & 0xff);
+ return ER_DYNCOL_OK;
+}
+
+
+/**
+ Read unsigned int value of given length from the string
+
+ @param store_it_here The structure to store the value
+ @param data The string which should be read
+ @param length The length (in bytes) of the value in nthe string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_uint_read(DYNAMIC_COLUMN_VALUE *store_it_here,
+ uchar *data, size_t length)
+{
+ ulonglong value= 0;
+ size_t i;
+
+ for (i= 0; i < length; i++)
+ value+= ((ulonglong)data[i]) << (i*8);
+
+ store_it_here->x.ulong_value= value;
+ return ER_DYNCOL_OK;
+}
+
+/**
+ Calculate how many bytes needed to store val as signed in following encoding:
+ 0 -> 0
+ -1 -> 1
+ 1 -> 2
+ -2 -> 3
+ 2 -> 4
+ ...
+
+ @param val The value for which we are calculating length
+
+ @return number of bytes
+*/
+
+static size_t dynamic_column_sint_bytes(longlong val)
+{
+ return dynamic_column_uint_bytes((val << 1) ^
+ (val < 0 ? ULL(0xffffffffffffffff) : 0));
+}
+
+
+/**
+ Append the string with given signed int value.
+
+ @param str the string where to put the value
+ @param val the value to put in the string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_sint_store(DYNAMIC_COLUMN *str, longlong val)
+{
+ return dynamic_column_uint_store(str,
+ (val << 1) ^
+ (val < 0 ? ULL(0xffffffffffffffff) : 0));
+}
+
+
+/**
+ Read signed int value of given length from the string
+
+ @param store_it_here The structure to store the value
+ @param data The string which should be read
+ @param length The length (in bytes) of the value in the string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_sint_read(DYNAMIC_COLUMN_VALUE *store_it_here,
+ uchar *data, size_t length)
+{
+ ulonglong val;
+ dynamic_column_uint_read(store_it_here, data, length);
+ val= store_it_here->x.ulong_value;
+ if (val & 1)
+ val= (val >> 1) ^ ULL(0xffffffffffffffff);
+ else
+ val>>= 1;
+ store_it_here->x.long_value= (longlong) val;
+ return ER_DYNCOL_OK;
+}
+
+
+/**
+ Calculate how many bytes needed to store the value.
+
+ @param value The value for which we are calculating length
+
+ @return
+ Error: (size_t) ~0
+ ok number of bytes
+*/
+
+static size_t
+dynamic_column_value_len(DYNAMIC_COLUMN_VALUE *value)
+{
+ switch (value->type) {
+ case DYN_COL_NULL:
+ return 0;
+ case DYN_COL_INT:
+ return dynamic_column_sint_bytes(value->x.long_value);
+ case DYN_COL_UINT:
+ return dynamic_column_uint_bytes(value->x.ulong_value);
+ case DYN_COL_DOUBLE:
+ return 8;
+ case DYN_COL_STRING:
+ return (dynamic_column_var_uint_bytes(value->x.string.charset->number) +
+ value->x.string.value.length);
+ case DYN_COL_DECIMAL:
+ {
+ int precision= value->x.decimal.value.intg + value->x.decimal.value.frac;
+ int scale= value->x.decimal.value.frac;
+
+ if (precision == 0 || decimal_is_zero(&value->x.decimal.value))
+ {
+ /* This is here to simplify dynamic_column_decimal_store() */
+ value->x.decimal.value.intg= value->x.decimal.value.frac= 0;
+ return 0;
+ }
+ /*
+ Check if legal decimal; This is needed to not get an assert in
+ decimal_bin_size(). However this should be impossible as all
+ decimals entered here should be valid and we have the special check
+ above to handle the unlikely but possible case that decimal.value.intg
+ and decimal.frac is 0.
+ */
+ if (scale < 0 || precision <= 0)
+ {
+ DBUG_ASSERT(0); /* Impossible */
+ return (size_t) ~0;
+ }
+ return (dynamic_column_var_uint_bytes(value->x.decimal.value.intg) +
+ dynamic_column_var_uint_bytes(value->x.decimal.value.frac) +
+ decimal_bin_size(precision, scale));
+ }
+ case DYN_COL_DATETIME:
+ /* date+time in bits: 14 + 4 + 5 + 10 + 6 + 6 + 20 + 1 66bits ~= 9 bytes */
+ return 9;
+ case DYN_COL_DATE:
+ /* date in dits: 14 + 4 + 5 = 23bits ~= 3bytes*/
+ return 3;
+ case DYN_COL_TIME:
+ /* time in bits: 10 + 6 + 6 + 20 + 1 = 43bits ~= 6bytes*/
+ return 6;
+ }
+ DBUG_ASSERT(0);
+ return 0;
+}
+
+
+/**
+ Append double value to a string
+
+ @param str the string where to put the value
+ @param val the value to put in the string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_double_store(DYNAMIC_COLUMN *str, double val)
+{
+ if (dynstr_realloc(str, 8))
+ return ER_DYNCOL_RESOURCE;
+ float8store(str->str + str->length, val);
+ str->length+= 8;
+ return ER_DYNCOL_OK;
+}
+
+
+/**
+ Read double value of given length from the string
+
+ @param store_it_here The structure to store the value
+ @param data The string which should be read
+ @param length The length (in bytes) of the value in nthe string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_double_read(DYNAMIC_COLUMN_VALUE *store_it_here,
+ uchar *data, size_t length)
+{
+ if (length != 8)
+ return ER_DYNCOL_FORMAT;
+ float8get(store_it_here->x.double_value, data);
+ return ER_DYNCOL_OK;
+}
+
+
+/**
+ Append the string with given string value.
+
+ @param str the string where to put the value
+ @param val the value to put in the string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_string_store(DYNAMIC_COLUMN *str, LEX_STRING *string,
+ CHARSET_INFO *charset)
+{
+ enum enum_dyncol_func_result rc;
+ if ((rc= dynamic_column_var_uint_store(str, charset->number)))
+ return rc;
+ if (dynstr_append_mem(str, string->str, string->length))
+ return ER_DYNCOL_RESOURCE;
+ return ER_DYNCOL_OK;
+}
+
+
+/**
+ Read string value of given length from the packed string
+
+ @param store_it_here The structure to store the value
+ @param data The packed string which should be read
+ @param length The length (in bytes) of the value in nthe string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_string_read(DYNAMIC_COLUMN_VALUE *store_it_here,
+ uchar *data, size_t length)
+{
+ size_t len;
+ uint charset_nr= (uint)dynamic_column_var_uint_get(data, length, &len);
+ if (len == 0) /* Wrong packed number */
+ return ER_DYNCOL_FORMAT;
+ store_it_here->x.string.charset= get_charset(charset_nr, MYF(MY_WME));
+ if (store_it_here->x.string.charset == NULL)
+ return ER_DYNCOL_UNKNOWN_CHARSET;
+ data+= len;
+ store_it_here->x.string.value.length= (length-= len);
+ store_it_here->x.string.value.str= (char*) data;
+ return ER_DYNCOL_OK;
+}
+
+
+/**
+ Append the string with given decimal value.
+
+ @param str the string where to put the value
+ @param val the value to put in the string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_decimal_store(DYNAMIC_COLUMN *str,
+ decimal_t *value)
+{
+ uint bin_size;
+ int precision= value->intg + value->frac;
+
+ /* Store decimal zero as empty string */
+ if (precision == 0)
+ return ER_DYNCOL_OK;
+
+ bin_size= decimal_bin_size(precision, value->frac);
+ if (dynstr_realloc(str, bin_size + 20))
+ return ER_DYNCOL_RESOURCE;
+
+ /* The following can't fail as memory is already allocated */
+ (void) dynamic_column_var_uint_store(str, value->intg);
+ (void) dynamic_column_var_uint_store(str, value->frac);
+
+ decimal2bin(value, (uchar *) str->str + str->length,
+ precision, value->frac);
+ str->length+= bin_size;
+ return ER_DYNCOL_OK;
+}
+
+
+/**
+ Prepare the value to be used as decimal.
+
+ @param value The value structure which sould be setup.
+*/
+
+void dynamic_column_prepare_decimal(DYNAMIC_COLUMN_VALUE *value)
+{
+ value->x.decimal.value.buf= value->x.decimal.buffer;
+ value->x.decimal.value.len= DECIMAL_BUFF_LENGTH;
+ /* just to be safe */
+ value->type= DYN_COL_DECIMAL;
+ decimal_make_zero(&value->x.decimal.value);
+}
+
+
+/**
+ Read decimal value of given length from the string
+
+ @param store_it_here The structure to store the value
+ @param data The string which should be read
+ @param length The length (in bytes) of the value in nthe string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_decimal_read(DYNAMIC_COLUMN_VALUE *store_it_here,
+ uchar *data, size_t length)
+{
+ size_t intg_len, frac_len;
+ int intg, frac, precision, scale;
+
+ dynamic_column_prepare_decimal(store_it_here);
+ /* Decimals 0.0 is stored as a zero length string */
+ if (length == 0)
+ return ER_DYNCOL_OK; /* value contains zero */
+
+ intg= (int)dynamic_column_var_uint_get(data, length, &intg_len);
+ data+= intg_len;
+ frac= (int)dynamic_column_var_uint_get(data, length - intg_len, &frac_len);
+ data+= frac_len;
+
+ /* Check the size of data is correct */
+ precision= intg + frac;
+ scale= frac;
+ if (scale < 0 || precision <= 0 || scale > precision ||
+ (length - intg_len - frac_len) >
+ (size_t) (DECIMAL_BUFF_LENGTH*sizeof(decimal_digit_t)) ||
+ decimal_bin_size(intg + frac, frac) !=
+ (int) (length - intg_len - frac_len))
+ return ER_DYNCOL_FORMAT;
+
+ if (bin2decimal(data, &store_it_here->x.decimal.value, precision, scale) !=
+ E_DEC_OK)
+ return ER_DYNCOL_FORMAT;
+ return ER_DYNCOL_OK;
+}
+
+
+/**
+ Append the string with given datetime value.
+
+ @param str the string where to put the value
+ @param value the value to put in the string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_date_time_store(DYNAMIC_COLUMN *str, MYSQL_TIME *value)
+{
+ enum enum_dyncol_func_result rc;
+ /*
+ 0<----year----><mn><day>00000!<-hours--><min-><sec-><---microseconds--->
+ 12345678901234123412345 1123456789012345612345612345678901234567890
+ <123456><123456><123456><123456><123456><123456><123456><123456><123456>
+ */
+ if ((rc= dynamic_column_date_store(str, value)) ||
+ (rc= dynamic_column_time_store(str, value)))
+ return rc;
+ return ER_DYNCOL_OK;
+}
+
+
+/**
+ Read datetime value of given length from the packed string
+
+ @param store_it_here The structure to store the value
+ @param data The packed string which should be read
+ @param length The length (in bytes) of the value in nthe string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_date_time_read(DYNAMIC_COLUMN_VALUE *store_it_here,
+ uchar *data, size_t length)
+{
+ enum enum_dyncol_func_result rc= ER_DYNCOL_FORMAT;
+ /*
+ 0<----year----><mn><day>00000!<-hours--><min-><sec-><---microseconds--->
+ 12345678901234123412345 1123456789012345612345612345678901234567890
+ <123456><123456><123456><123456><123456><123456><123456><123456><123456>
+ */
+ if (length != 9)
+ goto err;
+ store_it_here->x.time_value.time_type= MYSQL_TIMESTAMP_DATETIME;
+ if ((rc= dynamic_column_date_read_internal(store_it_here, data, 3)) ||
+ (rc= dynamic_column_time_read_internal(store_it_here, data + 3, 6)))
+ goto err;
+ return ER_DYNCOL_OK;
+
+err:
+ store_it_here->x.time_value.time_type= MYSQL_TIMESTAMP_ERROR;
+ return rc;
+}
+
+
+/**
+ Append the string with given time value.
+
+ @param str the string where to put the value
+ @param value the value to put in the string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_time_store(DYNAMIC_COLUMN *str, MYSQL_TIME *value)
+{
+ uchar *buf;
+ if (dynstr_realloc(str, 6))
+ return ER_DYNCOL_RESOURCE;
+
+ buf= ((uchar *)str->str) + str->length;
+
+ if (value->time_type == MYSQL_TIMESTAMP_NONE ||
+ value->time_type == MYSQL_TIMESTAMP_ERROR ||
+ value->time_type == MYSQL_TIMESTAMP_DATE)
+ {
+ value->neg= 0;
+ value->second_part= 0;
+ value->hour= 0;
+ value->minute= 0;
+ value->second= 0;
+ }
+ DBUG_ASSERT(value->hour <= 838);
+ DBUG_ASSERT(value->minute <= 59);
+ DBUG_ASSERT(value->second <= 59);
+ DBUG_ASSERT(value->second_part <= 999999);
+ /*
+ 00000!<-hours--><min-><sec-><---microseconds--->
+ 1123456789012345612345612345678901234567890
+ <123456><123456><123456><123456><123456><123456>
+ */
+ buf[0]= (value->second_part & 0xff);
+ buf[1]= ((value->second_part & 0xff00) >> 8);
+ buf[2]= (uchar)(((value->second & 0xf) << 4) |
+ ((value->second_part & 0xf0000) >> 16));
+ buf[3]= ((value->minute << 2) | ((value->second & 0x30) >> 4));
+ buf[4]= (value->hour & 0xff);
+ buf[5]= ((value->neg ? 0x4 : 0) | (value->hour >> 8));
+ str->length+= 6;
+ return ER_DYNCOL_OK;
+}
+
+
+/**
+ Read time value of given length from the packed string
+
+ @param store_it_here The structure to store the value
+ @param data The packed string which should be read
+ @param length The length (in bytes) of the value in nthe string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_time_read(DYNAMIC_COLUMN_VALUE *store_it_here,
+ uchar *data, size_t length)
+{
+ store_it_here->x.time_value.year= store_it_here->x.time_value.month=
+ store_it_here->x.time_value.day= 0;
+ store_it_here->x.time_value.time_type= MYSQL_TIMESTAMP_TIME;
+ return dynamic_column_time_read_internal(store_it_here, data, length);
+}
+
+/**
+ Internal function for reading time part from the string.
+
+ @param store_it_here The structure to store the value
+ @param data The packed string which should be read
+ @param length The length (in bytes) of the value in nthe string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_time_read_internal(DYNAMIC_COLUMN_VALUE *store_it_here,
+ uchar *data, size_t length)
+{
+ if (length != 6)
+ goto err;
+ /*
+ 00000!<-hours--><min-><sec-><---microseconds--->
+ 1123456789012345612345612345678901234567890
+ <123456><123456><123456><123456><123456><123456>
+ */
+ store_it_here->x.time_value.second_part= (data[0] |
+ (data[1] << 8) |
+ ((data[2] & 0xf) << 16));
+ store_it_here->x.time_value.second= ((data[2] >> 4) |
+ ((data[3] & 0x3) << 4));
+ store_it_here->x.time_value.minute= (data[3] >> 2);
+ store_it_here->x.time_value.hour= (((((uint)data[5]) & 0x3 ) << 8) | data[4]);
+ store_it_here->x.time_value.neg= ((data[5] & 0x4) ? 1 : 0);
+ if (store_it_here->x.time_value.second > 59 ||
+ store_it_here->x.time_value.minute > 59 ||
+ store_it_here->x.time_value.hour > 838 ||
+ store_it_here->x.time_value.second_part > 999999)
+ goto err;
+ return ER_DYNCOL_OK;
+
+err:
+ store_it_here->x.time_value.time_type= MYSQL_TIMESTAMP_ERROR;
+ return ER_DYNCOL_FORMAT;
+}
+
+
+/**
+ Append the string with given date value.
+
+ @param str the string where to put the value
+ @param value the value to put in the string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_date_store(DYNAMIC_COLUMN *str, MYSQL_TIME *value)
+{
+ uchar *buf;
+ if (dynstr_realloc(str, 3))
+ return ER_DYNCOL_RESOURCE;
+
+ buf= ((uchar *)str->str) + str->length;
+ if (value->time_type == MYSQL_TIMESTAMP_NONE ||
+ value->time_type == MYSQL_TIMESTAMP_ERROR ||
+ value->time_type == MYSQL_TIMESTAMP_TIME)
+ value->year= value->month= value->day = 0;
+ DBUG_ASSERT(value->year <= 9999);
+ DBUG_ASSERT(value->month <= 12);
+ DBUG_ASSERT(value->day <= 31);
+ /*
+ 0<----year----><mn><day>
+ 012345678901234123412345
+ <123456><123456><123456>
+ */
+ buf[0]= (value->day |
+ ((value->month & 0x7) << 5));
+ buf[1]= ((value->month >> 3) | ((value->year & 0x7F) << 1));
+ buf[2]= (value->year >> 7);
+ str->length+= 3;
+ return ER_DYNCOL_OK;
+}
+
+
+
+/**
+ Read date value of given length from the packed string
+
+ @param store_it_here The structure to store the value
+ @param data The packed string which should be read
+ @param length The length (in bytes) of the value in nthe string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_date_read(DYNAMIC_COLUMN_VALUE *store_it_here,
+ uchar *data, size_t length)
+{
+ store_it_here->x.time_value.neg= 0;
+ store_it_here->x.time_value.second_part= 0;
+ store_it_here->x.time_value.hour= 0;
+ store_it_here->x.time_value.minute= 0;
+ store_it_here->x.time_value.second= 0;
+ store_it_here->x.time_value.time_type= MYSQL_TIMESTAMP_DATE;
+ return dynamic_column_date_read_internal(store_it_here, data, length);
+}
+
+/**
+ Internal function for reading date part from the string.
+
+ @param store_it_here The structure to store the value
+ @param data The packed string which should be read
+ @param length The length (in bytes) of the value in nthe string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_date_read_internal(DYNAMIC_COLUMN_VALUE *store_it_here,
+ uchar *data,
+ size_t length)
+{
+ if (length != 3)
+ goto err;
+ /*
+ 0<----year----><mn><day>
+ 12345678901234123412345
+ <123456><123456><123456>
+ */
+ store_it_here->x.time_value.day= (data[0] & 0x1f);
+ store_it_here->x.time_value.month= (((data[1] & 0x1) << 3) |
+ (data[0] >> 5));
+ store_it_here->x.time_value.year= ((((uint)data[2]) << 7) |
+ (data[1] >> 1));
+ if (store_it_here->x.time_value.day > 31 ||
+ store_it_here->x.time_value.month > 12 ||
+ store_it_here->x.time_value.year > 9999)
+ goto err;
+ return ER_DYNCOL_OK;
+
+err:
+ store_it_here->x.time_value.time_type= MYSQL_TIMESTAMP_ERROR;
+ return ER_DYNCOL_FORMAT;
+}
+
+
+/**
+ Append the string with given value.
+
+ @param str the string where to put the value
+ @param value the value to put in the string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+data_store(DYNAMIC_COLUMN *str, DYNAMIC_COLUMN_VALUE *value)
+{
+ switch (value->type) {
+ case DYN_COL_INT:
+ return dynamic_column_sint_store(str, value->x.long_value);
+ case DYN_COL_UINT:
+ return dynamic_column_uint_store(str, value->x.ulong_value);
+ case DYN_COL_DOUBLE:
+ return dynamic_column_double_store(str, value->x.double_value);
+ case DYN_COL_STRING:
+ return dynamic_column_string_store(str, &value->x.string.value,
+ value->x.string.charset);
+ case DYN_COL_DECIMAL:
+ return dynamic_column_decimal_store(str, &value->x.decimal.value);
+ case DYN_COL_DATETIME:
+ /* date+time in bits: 14 + 4 + 5 + 5 + 6 + 6 40bits = 5 bytes */
+ return dynamic_column_date_time_store(str, &value->x.time_value);
+ case DYN_COL_DATE:
+ /* date in dits: 14 + 4 + 5 = 23bits ~= 3bytes*/
+ return dynamic_column_date_store(str, &value->x.time_value);
+ case DYN_COL_TIME:
+ /* time in bits: 5 + 6 + 6 = 17bits ~= 3bytes*/
+ return dynamic_column_time_store(str, &value->x.time_value);
+ case DYN_COL_NULL:
+ break; /* Impossible */
+ }
+ DBUG_ASSERT(0);
+ return ER_DYNCOL_OK; /* Impossible */
+}
+
+
+/**
+ Calculate length of offset field for given data length
+
+ @param data_length Length of the data segment
+
+ @return number of bytes
+*/
+
+static size_t dynamic_column_offset_bytes(size_t data_length)
+{
+ if (data_length < 0x1f) /* all 1 value is reserved */
+ return 1;
+ if (data_length < 0x1fff) /* all 1 value is reserved */
+ return 2;
+ if (data_length < 0x1fffff) /* all 1 value is reserved */
+ return 3;
+ if (data_length < 0x1fffffff) /* all 1 value is reserved */
+ return 4;
+ return MAX_OFFSET_LENGTH; /* For future */
+}
+
+/**
+ Store offset and type information in the given place
+
+ @param place Beginning of the index entry
+ @param offset_size Size of offset field in bytes
+ @param type Type to be written
+ @param offset Offset to be written
+*/
+
+static void type_and_offset_store(uchar *place, size_t offset_size,
+ DYNAMIC_COLUMN_TYPE type,
+ size_t offset)
+{
+ ulong val = (((ulong) offset) << 3) | (type - 1);
+ DBUG_ASSERT(type != DYN_COL_NULL);
+ DBUG_ASSERT(((type - 1) & (~7)) == 0); /* fit in 3 bits */
+
+ /* Index entry starts with column number; Jump over it */
+ place+= COLUMN_NUMBER_SIZE;
+
+ switch (offset_size) {
+ case 1:
+ DBUG_ASSERT(offset < 0x1f); /* all 1 value is reserved */
+ place[0]= (uchar)val;
+ break;
+ case 2:
+ DBUG_ASSERT(offset < 0x1fff); /* all 1 value is reserved */
+ int2store(place, val);
+ break;
+ case 3:
+ DBUG_ASSERT(offset < 0x1fffff); /* all 1 value is reserved */
+ int3store(place, val);
+ break;
+ case 4:
+ DBUG_ASSERT(offset < 0x1fffffff); /* all 1 value is reserved */
+ int4store(place, val);
+ break;
+ default:
+ DBUG_ASSERT(0); /* impossible */
+ }
+}
+
+
+/**
+ Read offset and type information from index entry
+
+ @param type Where to put type info
+ @param offset Where to put offset info
+ @param place Beginning of the index entry
+ @param offset_size Size of offset field in bytes
+*/
+
+static void type_and_offset_read(DYNAMIC_COLUMN_TYPE *type,
+ size_t *offset,
+ uchar *place, size_t offset_size)
+{
+ ulong val;
+ LINT_INIT(val);
+
+ place+= COLUMN_NUMBER_SIZE; /* skip column number */
+ switch (offset_size) {
+ case 1:
+ val= (ulong)place[0];
+ break;
+ case 2:
+ val= uint2korr(place);
+ break;
+ case 3:
+ val= uint3korr(place);
+ break;
+ case 4:
+ val= uint4korr(place);
+ break;
+ default:
+ DBUG_ASSERT(0); /* impossible */
+ }
+ *type= (val & 0x7) + 1;
+ *offset= val >> 3;
+}
+
+
+/**
+ Comparator function for references on column numbers for qsort
+*/
+
+static int column_sort(const void *a, const void *b)
+{
+ return **((uint **)a) - **((uint **)b);
+}
+
+
+/**
+ Write information to the fixed header
+
+ @param str String where to write the header
+ @param offset_size Size of offset field in bytes
+ @param column_count Number of columns
+*/
+
+static void set_fixed_header(DYNAMIC_COLUMN *str,
+ uint offset_size,
+ uint column_count)
+{
+ DBUG_ASSERT(column_count <= 0xffff);
+ DBUG_ASSERT(offset_size <= 4);
+ str->str[0]= ((str->str[0] & ~DYNCOL_FLG_OFFSET) |
+ (offset_size - 1)); /* size of offset */
+ int2store(str->str + 1, column_count); /* columns number */
+ DBUG_ASSERT((str->str[0] & (~DYNCOL_FLG_KNOWN)) == 0);
+}
+
+/*
+ Calculate entry size (E) and header size (H) by offset size (O) and column
+ count (C).
+*/
+
+#define calc_param(E,H,O,C) do { \
+ (*(E))= (O) + COLUMN_NUMBER_SIZE; \
+ (*(H))= (*(E)) * (C); \
+}while(0);
+
+
+/**
+ Adds columns into the empty string
+
+ @param str String where to write the data
+ @param header_size Size of the header without fixed part
+ @param offset_size Size of offset field in bytes
+ @param column_count Number of columns in the arrays
+ @parem not_null_count Number of non-null columns in the arrays
+ @param data_size Size of the data segment
+ @param column_numbers Array of columns numbers
+ @param values Array of columns values
+ @param new_str True if we need to allocate new string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_new_column_store(DYNAMIC_COLUMN *str,
+ size_t header_size,
+ size_t offset_size,
+ uint column_count,
+ uint not_null_count,
+ size_t data_size,
+ uint *column_numbers,
+ DYNAMIC_COLUMN_VALUE *values,
+ my_bool new_str)
+{
+ uchar *header_end;
+ uint **columns_order;
+ uint i;
+ uint entry_size= COLUMN_NUMBER_SIZE + offset_size;
+ enum enum_dyncol_func_result rc= ER_DYNCOL_RESOURCE;
+
+ if (!(columns_order= malloc(sizeof(uint*)*column_count)))
+ return ER_DYNCOL_RESOURCE;
+ if (new_str)
+ {
+ if (dynamic_column_init_str(str,
+ data_size + header_size + DYNCOL_SYZERESERVE))
+ goto err;
+ }
+ else
+ {
+ str->length= 0;
+ if (dynstr_realloc(str, data_size + header_size + DYNCOL_SYZERESERVE))
+ goto err;
+ bzero(str->str, FIXED_HEADER_SIZE);
+ str->length= FIXED_HEADER_SIZE;
+ }
+
+ /* sort columns for the header */
+ for (i= 0; i < column_count; i++)
+ columns_order[i]= column_numbers + i;
+ qsort(columns_order, (size_t)column_count, sizeof(uint*), &column_sort);
+
+ /*
+ For now we don't allow creating two columns with the same number
+ at the time of create. This can be fixed later to just use the later
+ by comparing the pointers.
+ */
+ for (i= 0; i < column_count - 1; i++)
+ {
+ if (columns_order[i][0] > UINT_MAX16 ||
+ columns_order[i][0] == columns_order[i + 1][0])
+ {
+ rc= ER_DYNCOL_DATA;
+ goto err;
+ }
+ }
+ if (columns_order[i][0] > UINT_MAX16)
+ {
+ rc= ER_DYNCOL_DATA;
+ goto err;
+ }
+
+ DBUG_ASSERT(str->max_length >= str->length + header_size);
+ set_fixed_header(str, offset_size, not_null_count);
+ str->length+= header_size; /* reserve place for header */
+ header_end= (uchar *)str->str + FIXED_HEADER_SIZE;
+ for (i= 0; i < column_count; i++)
+ {
+ uint ord= columns_order[i] - column_numbers;
+ if (values[ord].type != DYN_COL_NULL)
+ {
+ /* Store header first in the str */
+ int2store(header_end, column_numbers[ord]);
+ type_and_offset_store(header_end, offset_size,
+ values[ord].type,
+ str->length - header_size - FIXED_HEADER_SIZE);
+
+ /* Store value in 'str + str->length' and increase str->length */
+ if ((rc= data_store(str, values + ord)))
+ goto err;
+ header_end+= entry_size;
+ }
+ }
+ rc= ER_DYNCOL_OK;
+err:
+ free(columns_order);
+ return rc;
+}
+
+/**
+ Create packed string which contains given columns (internal)
+
+ @param str String where to write the data
+ @param column_count Number of columns in the arrays
+ @param column_numbers Array of columns numbers
+ @param values Array of columns values
+ @param new_str True if we need allocate new string
+
+ @return ER_DYNCOL_* return code
+*/
+
+static enum enum_dyncol_func_result
+dynamic_column_create_many_internal(DYNAMIC_COLUMN *str,
+ uint column_count,
+ uint *column_numbers,
+ DYNAMIC_COLUMN_VALUE *values,
+ my_bool new_str)
+{
+ size_t data_size= 0;
+ size_t header_size, offset_size;
+ uint i;
+ int not_null_column_count= 0;
+
+ if (new_str)
+ {
+ /* to make dynstr_free() working in case of errors */
+ bzero(str, sizeof(DYNAMIC_COLUMN));
+ }
+
+ for (i= 0; i < column_count; i++)
+ {
+ if (values[i].type != DYN_COL_NULL)
+ {
+ size_t tmp;
+ not_null_column_count++;
+ data_size+= (tmp=dynamic_column_value_len(values + i));
+ if (tmp == (size_t) ~0)
+ return ER_DYNCOL_DATA;
+ }
+ }
+
+ /* We can handle data up to 1fffffff = 536870911 bytes now */
+ if ((offset_size= dynamic_column_offset_bytes(data_size)) >=
+ MAX_OFFSET_LENGTH)
+ return ER_DYNCOL_LIMIT;
+
+ /* header entry is column number + offset & type */
+ header_size= not_null_column_count * (offset_size + 2);
+
+ return dynamic_new_column_store(str,
+ header_size, offset_size,
+ column_count,
+ not_null_column_count,
+ data_size,
+ column_numbers, values,
+ new_str);
+}
+
+
+/**
+ Create packed string which contains given columns
+
+ @param str String where to write the data
+ @param column_count Number of columns in the arrays
+ @param column_numbers Array of columns numbers
+ @param values Array of columns values
+
+ @return ER_DYNCOL_* return code
+*/
+
+enum enum_dyncol_func_result
+dynamic_column_create_many(DYNAMIC_COLUMN *str,
+ uint column_count,
+ uint *column_numbers,
+ DYNAMIC_COLUMN_VALUE *values)
+{
+ DBUG_ENTER("dynamic_column_create_many");
+ DBUG_RETURN(dynamic_column_create_many_internal(str, column_count,
+ column_numbers, values,
+ TRUE));
+}
+
+
+/**
+ Create packed string which contains given column
+
+ @param str String where to write the data
+ @param column_number Column number
+ @param value The columns value
+
+ @return ER_DYNCOL_* return code
+*/
+
+enum enum_dyncol_func_result
+dynamic_column_create(DYNAMIC_COLUMN *str, uint column_nr,
+ DYNAMIC_COLUMN_VALUE *value)
+{
+ DBUG_ENTER("dynamic_column_create");
+ DBUG_RETURN(dynamic_column_create_many(str, 1, &column_nr, value));
+}
+
+
+/**
+ Calculate length of data between given two header entries
+
+ @param entry Pointer to the first entry
+ @param entry_next Pointer to the last entry
+ @param header_end Pointer to the header end
+ @param offset_size Size of offset field in bytes
+ @param last_offset Size of the data segment
+
+ @return number of bytes
+*/
+
+static size_t get_length_interval(uchar *entry, uchar *entry_next,
+ uchar *header_end, size_t offset_size,
+ size_t last_offset)
+{
+ size_t offset, offset_next;
+ DYNAMIC_COLUMN_TYPE type, type_next;
+ DBUG_ASSERT(entry < entry_next);
+
+ type_and_offset_read(&type, &offset, entry, offset_size);
+ if (entry_next >= header_end)
+ return (last_offset - offset);
+ type_and_offset_read(&type_next, &offset_next, entry_next, offset_size);
+ return (offset_next - offset);
+}
+
+/*
+ Calculate length of data of one column
+
+
+ @param entry Pointer to the first entry
+ @param header_end Pointer to the header end
+ @param offset_size Size of offset field in bytes
+ @param last_offset Size of the data segment
+
+ @return number of bytes
+*/
+
+static size_t get_length(uchar *entry, uchar *header_end,
+ size_t offset_size,
+ size_t last_offset)
+{
+ return get_length_interval(entry,
+ entry + offset_size + COLUMN_NUMBER_SIZE,
+ header_end, offset_size, last_offset);
+}
+
+
+/**
+ Comparator function for references to header entries for qsort
+*/
+
+static int header_compar(const void *a, const void *b)
+{
+ uint va= uint2korr((uchar*)a), vb= uint2korr((uchar*)b);
+ return (va > vb ? 1 : (va < vb ? -1 : 0));
+}
+
+
+/**
+ Find column and fill information about it
+
+ @param type Returns type of the column
+ @param data Returns a pointer to the data
+ @param length Returns length of the data
+ @param offset_size Size of offset field in bytes
+ @param column_count Number of column in the packed string
+ @param data_end Pointer to the data end
+ @param num Number of the column we want to fetch
+ @param entry_pos NULL or place where to put reference to the entry
+
+ @return 0 ok
+ @return 1 error in data
+*/
+
+static my_bool
+find_column(DYNAMIC_COLUMN_TYPE *type, uchar **data, size_t *length,
+ uchar *header, size_t offset_size, uint column_count,
+ uchar *data_end, uint num, uchar **entry_pos)
+{
+ uchar *entry;
+ size_t offset, total_data, header_size, entry_size;
+ uchar key[2+4];
+
+ if (!entry_pos)
+ entry_pos= &entry;
+
+ calc_param(&entry_size, &header_size, offset_size, column_count);
+
+ if (header + header_size > data_end)
+ return 1;
+
+ int2store(key, num);
+ entry= bsearch(key, header, (size_t)column_count, entry_size,
+ &header_compar);
+ if (!entry)
+ {
+ /* Column not found */
+ *type= DYN_COL_NULL;
+ *entry_pos= NULL;
+ return 0;
+ }
+ type_and_offset_read(type, &offset, entry, offset_size);
+ total_data= data_end - (header + header_size);
+ if (offset > total_data)
+ return 1;
+ *data= header + header_size + offset;
+ *length= get_length(entry, header + header_size, offset_size,
+ total_data);
+ /*
+ Check that the found data is withing the ranges. This can happen if
+ we get data with wrong offsets.
+ */
+ if ((long) *length < 0 || offset + *length > total_data)
+ return 1;
+
+ *entry_pos= entry;
+ return 0;
+}
+
+
+/**
+ Read and check the header of the dynamic string
+
+ @param str Dynamic string
+
+ @retval FALSE OK
+ @retval TRUE error
+
+ Note
+ We don't check for str->length == 0 as all code that calls this
+ already have handled this case.
+*/
+
+static inline my_bool read_fixed_header(DYNAMIC_COLUMN *str,
+ size_t *offset_size,
+ uint *column_count)
+{
+ DBUG_ASSERT(str != NULL && str->length != 0);
+ if ((str->length < FIXED_HEADER_SIZE) ||
+ (str->str[0] & (~DYNCOL_FLG_KNOWN)))
+ return 1; /* Wrong header */
+ *offset_size= (str->str[0] & DYNCOL_FLG_OFFSET) + 1;
+ *column_count= uint2korr(str->str + 1);
+ return 0;
+}
+
+
+/**
+ Get dynamic column value
+
+ @param str The packed string to extract the column
+ @param column_nr Number of column to fetch
+ @param store_it_here Where to store the extracted value
+
+ @return ER_DYNCOL_* return code
+*/
+
+int dynamic_column_get(DYNAMIC_COLUMN *str, uint column_nr,
+ DYNAMIC_COLUMN_VALUE *store_it_here)
+{
+ uchar *data;
+ size_t offset_size, length;
+ uint column_count;
+ enum enum_dyncol_func_result rc= ER_DYNCOL_FORMAT;
+
+ if (str->length == 0)
+ goto null;
+
+ if (read_fixed_header(str, &offset_size, &column_count))
+ goto err;
+
+ if (column_count == 0)
+ goto null;
+
+ if (find_column(&store_it_here->type, &data, &length,
+ (uchar*)str->str + FIXED_HEADER_SIZE,
+ offset_size, column_count, (uchar*)str->str + str->length,
+ column_nr, NULL))
+ goto err;
+
+ switch (store_it_here->type) {
+ case DYN_COL_INT:
+ rc= dynamic_column_sint_read(store_it_here, data, length);
+ break;
+ case DYN_COL_UINT:
+ rc= dynamic_column_uint_read(store_it_here, data, length);
+ break;
+ case DYN_COL_DOUBLE:
+ rc= dynamic_column_double_read(store_it_here, data, length);
+ break;
+ case DYN_COL_STRING:
+ rc= dynamic_column_string_read(store_it_here, data, length);
+ break;
+ case DYN_COL_DECIMAL:
+ rc= dynamic_column_decimal_read(store_it_here, data, length);
+ break;
+ case DYN_COL_DATETIME:
+ rc= dynamic_column_date_time_read(store_it_here, data, length);
+ break;
+ case DYN_COL_DATE:
+ rc= dynamic_column_date_read(store_it_here, data, length);
+ break;
+ case DYN_COL_TIME:
+ rc= dynamic_column_time_read(store_it_here, data, length);
+ break;
+ case DYN_COL_NULL:
+ rc= ER_DYNCOL_OK;
+ break;
+ default:
+ goto err;
+ }
+ return rc;
+
+null:
+ rc= ER_DYNCOL_OK;
+err:
+ store_it_here->type= DYN_COL_NULL;
+ return rc;
+}
+
+/**
+ Delete column with given number from the packed string
+
+ @param str The packed string to delete the column
+ @param column_nr Number of column to delete
+
+ @return ER_DYNCOL_* return code
+*/
+
+int dynamic_column_delete(DYNAMIC_COLUMN *str, uint column_nr)
+{
+ uchar *data, *header_entry, *read, *write;
+ size_t offset_size, new_offset_size, length, entry_size, new_entry_size,
+ header_size, new_header_size, data_size, new_data_size,
+ deleted_entry_offset;
+ uint column_count, i;
+ DYNAMIC_COLUMN_TYPE type;
+
+ if (str->length == 0)
+ return ER_DYNCOL_OK; /* no columns */
+
+ if (read_fixed_header(str, &offset_size, &column_count))
+ return ER_DYNCOL_FORMAT;
+
+ if (column_count == 0)
+ {
+ str->length= 0;
+ return ER_DYNCOL_OK; /* no columns */
+ }
+
+ if (find_column(&type, &data, &length, (uchar*)str->str + FIXED_HEADER_SIZE,
+ offset_size, column_count, (uchar*)str->str + str->length,
+ column_nr, &header_entry))
+ return ER_DYNCOL_FORMAT;
+
+ if (type == DYN_COL_NULL)
+ return ER_DYNCOL_OK; /* no such column */
+
+ if (column_count == 1)
+ {
+ /* delete the only column; Return empty string */
+ str->length= 0;
+ return ER_DYNCOL_OK;
+ }
+
+ /* Calculate entry_size and header_size */
+ calc_param(&entry_size, &header_size, offset_size, column_count);
+ data_size= str->length - FIXED_HEADER_SIZE - header_size;
+
+ new_data_size= data_size - length;
+ if ((new_offset_size= dynamic_column_offset_bytes(new_data_size)) >=
+ MAX_OFFSET_LENGTH)
+ return ER_DYNCOL_LIMIT;
+ DBUG_ASSERT(new_offset_size <= offset_size);
+
+ calc_param(&new_entry_size, &new_header_size,
+ new_offset_size, column_count - 1);
+
+ deleted_entry_offset= ((data - (uchar*) str->str) -
+ header_size - FIXED_HEADER_SIZE);
+
+ /* rewrite header*/
+ set_fixed_header(str, new_offset_size, column_count - 1);
+ for (i= 0, write= read= (uchar *)str->str + FIXED_HEADER_SIZE;
+ i < column_count;
+ i++, read+= entry_size, write+= new_entry_size)
+ {
+ size_t offs;
+ uint nm;
+ DYNAMIC_COLUMN_TYPE tp;
+ if (read == header_entry)
+ {
+#ifndef DBUG_OFF
+ nm= uint2korr(read);
+ type_and_offset_read(&tp, &offs, read,
+ offset_size);
+ DBUG_ASSERT(nm == column_nr);
+ DBUG_ASSERT(offs == deleted_entry_offset);
+#endif
+ write-= new_entry_size; /* do not move writer */
+ continue; /* skip removed field */
+ }
+
+ nm= uint2korr(read),
+ type_and_offset_read(&tp, &offs, read,
+ offset_size);
+
+ if (offs > deleted_entry_offset)
+ offs-= length; /* data stored after removed data */
+
+ int2store(write, nm);
+ type_and_offset_store(write, new_offset_size, tp, offs);
+ }
+
+ /* move data */
+ {
+ size_t first_chunk_len= ((data - (uchar *)str->str) -
+ FIXED_HEADER_SIZE - header_size);
+ size_t second_chunk_len= new_data_size - first_chunk_len;
+ if (first_chunk_len)
+ memmove(str->str + FIXED_HEADER_SIZE + new_header_size,
+ str->str + FIXED_HEADER_SIZE + header_size,
+ first_chunk_len);
+ if (second_chunk_len)
+ memmove(str->str +
+ FIXED_HEADER_SIZE + new_header_size + first_chunk_len,
+ str->str +
+ FIXED_HEADER_SIZE + header_size + first_chunk_len + length,
+ second_chunk_len);
+ }
+
+ /* fix str length */
+ DBUG_ASSERT(str->length >=
+ FIXED_HEADER_SIZE + new_header_size + new_data_size);
+ str->length= FIXED_HEADER_SIZE + new_header_size + new_data_size;
+
+ return ER_DYNCOL_OK;
+}
+
+
+/**
+ Check existence of the column in the packed string
+
+ @param str The packed string to check the column
+ @param column_nr Number of column to check
+
+ @return ER_DYNCOL_* return code
+*/
+
+enum enum_dyncol_func_result
+dynamic_column_exists(DYNAMIC_COLUMN *str, uint column_nr)
+{
+ uchar *data;
+ size_t offset_size, length;
+ uint column_count;
+ DYNAMIC_COLUMN_TYPE type;
+
+ if (str->length == 0)
+ return ER_DYNCOL_NO; /* no columns */
+
+ if (read_fixed_header(str, &offset_size, &column_count))
+ return ER_DYNCOL_FORMAT;
+
+ if (column_count == 0)
+ return ER_DYNCOL_NO; /* no columns */
+
+ if (find_column(&type, &data, &length, (uchar*)str->str + FIXED_HEADER_SIZE,
+ offset_size, column_count, (uchar*)str->str + str->length,
+ column_nr, NULL))
+ return ER_DYNCOL_FORMAT;
+
+ return (type != DYN_COL_NULL ? ER_DYNCOL_YES : ER_DYNCOL_NO);
+}
+
+
+/**
+ List not-null columns in the packed string
+
+ @param str The packed string
+ @param array_of_uint Where to put reference on created array
+
+ @return ER_DYNCOL_* return code
+*/
+
+enum enum_dyncol_func_result
+dynamic_column_list(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_uint)
+{
+ uchar *read;
+ size_t offset_size, entry_size;
+ uint column_count, i;
+
+ bzero(array_of_uint, sizeof(*array_of_uint)); /* In case of errors */
+ if (str->length == 0)
+ return ER_DYNCOL_OK; /* no columns */
+
+ if (read_fixed_header(str, &offset_size, &column_count))
+ return ER_DYNCOL_FORMAT;
+
+ entry_size= COLUMN_NUMBER_SIZE + offset_size;
+
+ if (entry_size * column_count + FIXED_HEADER_SIZE > str->length)
+ return ER_DYNCOL_FORMAT;
+
+ if (init_dynamic_array(array_of_uint, sizeof(uint),
+ column_count, 0 CALLER_INFO))
+ return ER_DYNCOL_RESOURCE;
+
+ for (i= 0, read= (uchar *)str->str + FIXED_HEADER_SIZE;
+ i < column_count;
+ i++, read+= entry_size)
+ {
+ uint nm= uint2korr(read);
+ /* Insert can't never fail as it's pre-allocated above */
+ (void) insert_dynamic(array_of_uint, (uchar *)&nm);
+ }
+ return ER_DYNCOL_OK;
+}
+
+
+/**
+ Find the place of the column in the header or place where it should be put
+
+ @param num Number of the column
+ @param header Pointer to the header
+ @param entry_size Size of a header entry
+ @param column_count Number of columns in the packed string
+ @param entry Return pointer to the entry or next entry
+
+ @retval TRUE found
+ @retval FALSE pointer set to the next row
+*/
+
+static my_bool
+find_place(uint num, uchar *header, size_t entry_size,
+ uint column_count, uchar **entry)
+{
+ uint mid, start, end, val;
+ int flag;
+ LINT_INIT(flag); /* 100 % safe */
+
+ start= 0;
+ end= column_count -1;
+ mid= 1;
+ while (start != end)
+ {
+ uint val;
+ mid= (start + end) / 2;
+ val= uint2korr(header + mid * entry_size);
+ if ((flag= CMP_NUM(num, val)) <= 0)
+ end= mid;
+ else
+ start= mid + 1;
+ }
+ if (start != mid)
+ {
+ val= uint2korr(header + start * entry_size);
+ flag= CMP_NUM(num, val);
+ }
+ *entry= header + start * entry_size;
+ if (flag > 0)
+ *entry+= entry_size; /* Point at next bigger key */
+ return flag == 0;
+}
+
+
+/*
+ Description of plan of adding/removing/updating a packed string
+*/
+
+typedef enum {PLAN_REPLACE, PLAN_ADD, PLAN_DELETE, PLAN_NOP} PLAN_ACT;
+
+struct st_plan {
+ DYNAMIC_COLUMN_VALUE *val;
+ uint *num;
+ uchar *place;
+ size_t length;
+ int hdelta, ddelta;
+ PLAN_ACT act;
+};
+typedef struct st_plan PLAN;
+
+
+static int plan_sort(const void *a, const void *b)
+{
+ return ((PLAN *)a)->num[0] - ((PLAN *)b)->num[0];
+}
+
+#define DELTA_CHECK(S, D, C) \
+ if ((S) == 0) \
+ (S)= (D); \
+ else if (((S) > 0 && (D) < 0) || \
+ ((S) < 0 && (D) > 0)) \
+ { \
+ (C)= TRUE; \
+ break; \
+ } \
+
+
+/**
+ Update the packed string with the given columns
+
+ @param str String where to write the data
+ @param add_column_count Number of columns in the arrays
+ @param column_numbers Array of columns numbers
+ @param values Array of columns values
+
+ @return ER_DYNCOL_* return code
+*/
+
+enum enum_dyncol_func_result
+dynamic_column_update_many(DYNAMIC_COLUMN *str,
+ uint add_column_count,
+ uint *column_numbers,
+ DYNAMIC_COLUMN_VALUE *values)
+{
+ PLAN *plan;
+ uchar *header_end;
+ long data_delta= 0;
+ uint i, j, k;
+ uint new_column_count, column_count, not_null;
+ enum enum_dyncol_func_result rc;
+ int header_delta;
+ size_t offset_size, entry_size, header_size, data_size;
+ size_t new_offset_size, new_entry_size, new_header_size, new_data_size;
+ size_t max_offset;
+
+ if (add_column_count == 0)
+ return ER_DYNCOL_OK;
+
+ /*
+ Get columns in column order. As the data in 'str' is already
+ in column order this allows to replace all columns in one loop.
+ */
+
+ if (!(plan= my_malloc(sizeof(PLAN) * (add_column_count + 1), MYF(0))))
+ return ER_DYNCOL_RESOURCE;
+
+ not_null= add_column_count;
+ for (i= 0; i < add_column_count; i++)
+ {
+ if (column_numbers[i] > UINT_MAX16)
+ {
+ rc= ER_DYNCOL_DATA;
+ goto end;
+ }
+
+ plan[i].val= values + i;
+ plan[i].num= column_numbers + i;
+ if (values[i].type == DYN_COL_NULL)
+ not_null--;
+
+ }
+
+ if (str->length == 0)
+ {
+ /*
+ Just add new columns. If there was no columns to add we return
+ an empty string.
+ */
+ goto create_new_string;
+ }
+
+ /* Check that header is ok */
+ if (read_fixed_header(str, &offset_size, &column_count))
+ {
+ rc= ER_DYNCOL_FORMAT;
+ goto end;
+ }
+ if (column_count == 0)
+ goto create_new_string;
+
+ qsort(plan, (size_t)add_column_count, sizeof(PLAN), &plan_sort);
+
+ new_column_count= column_count;
+ calc_param(&entry_size, &header_size, offset_size, column_count);
+ max_offset= str->length - (FIXED_HEADER_SIZE + header_size);
+ header_end= (uchar*) str->str + FIXED_HEADER_SIZE + header_size;
+
+ if (header_size + FIXED_HEADER_SIZE > str->length)
+ {
+ rc= ER_DYNCOL_FORMAT;
+ goto end;
+ }
+
+ /*
+ Calculate how many columns and data is added/deleted and make a 'plan'
+ for each of them.
+ */
+ header_delta= 0;
+ for (i= 0; i < add_column_count; i++)
+ {
+ uchar *entry;
+
+ /*
+ For now we don't allow creating two columns with the same number
+ at the time of create. This can be fixed later to just use the later
+ by comparing the pointers.
+ */
+ if (i < add_column_count - 1 && plan[i].num[0] == plan[i + 1].num[0])
+ {
+ rc= ER_DYNCOL_DATA;
+ goto end;
+ }
+
+ /* Set common variables for all plans */
+ plan[i].ddelta= data_delta;
+ /* get header delta in entries */
+ plan[i].hdelta= header_delta;
+ plan[i].length= 0; /* Length if NULL */
+
+ if (find_place(plan[i].num[0],
+ (uchar *)str->str + FIXED_HEADER_SIZE,
+ entry_size, column_count, &entry))
+ {
+ size_t entry_data_size;
+
+ /* Data existed; We have to replace or delete it */
+
+ entry_data_size= get_length(entry, header_end,
+ offset_size, max_offset);
+ if ((long) entry_data_size < 0)
+ {
+ rc= ER_DYNCOL_FORMAT;
+ goto end;
+ }
+
+ if (plan[i].val->type == DYN_COL_NULL)
+ {
+ /* Inserting a NULL means delete the old data */
+
+ plan[i].act= PLAN_DELETE; /* Remove old value */
+ header_delta--; /* One row less in header */
+ data_delta-= entry_data_size; /* Less data to store */
+ }
+ else
+ {
+ /* Replace the value */
+
+ plan[i].act= PLAN_REPLACE;
+ /* get data delta in bytes */
+ if ((plan[i].length= dynamic_column_value_len(plan[i].val)) ==
+ (size_t) ~0)
+ {
+ rc= ER_DYNCOL_DATA;
+ goto end;
+ }
+ data_delta+= plan[i].length - entry_data_size;
+ }
+ }
+ else
+ {
+ /* Data did not exists. Add if it it's not NULL */
+
+ if (plan[i].val->type == DYN_COL_NULL)
+ {
+ plan[i].act= PLAN_NOP; /* Mark entry to be skiped */
+ }
+ else
+ {
+ /* Add new value */
+
+ plan[i].act= PLAN_ADD;
+ header_delta++; /* One more row in header */
+ /* get data delta in bytes */
+ if ((plan[i].length= dynamic_column_value_len(plan[i].val)) ==
+ (size_t) ~0)
+ {
+ rc= ER_DYNCOL_DATA;
+ goto end;
+ }
+ data_delta+= plan[i].length;
+ }
+ }
+ plan[i].place= entry;
+ }
+ plan[add_column_count].hdelta= header_delta;
+ plan[add_column_count].ddelta= data_delta;
+ new_column_count= column_count + header_delta;
+
+ /*
+ Check if it is only "increasing" or only "decreasing" plan for (header
+ and data separately).
+ */
+ data_size= str->length - header_size - FIXED_HEADER_SIZE;
+ new_data_size= data_size + data_delta;
+ if ((new_offset_size= dynamic_column_offset_bytes(new_data_size)) >=
+ MAX_OFFSET_LENGTH)
+ {
+ rc= ER_DYNCOL_LIMIT;
+ goto end;
+ }
+
+#ifdef NOT_IMPLEMENTED
+ /* if (new_offset_size != offset_size) then we have to rewrite header */
+ header_delta_sign= new_offset_size - offset_size;
+ data_delta_sign= 0;
+ for (i= 0; i < add_column_count; i++)
+ {
+ /* This is the check for increasing/decreasing */
+ DELTA_CHECK(header_delta_sign, plan[i].hdelta, copy);
+ DELTA_CHECK(data_delta_sign, plan[i].ddelta, copy);
+ }
+#endif
+ calc_param(&new_entry_size, &new_header_size,
+ new_offset_size, new_column_count);
+
+ /*
+ The following code always make a copy. In future we can do a more
+ optimized version when data is only increasing / decreasing.
+ */
+
+ /*if (copy) */
+ {
+ DYNAMIC_COLUMN tmp;
+ uchar *header_base= (uchar *)str->str + FIXED_HEADER_SIZE,
+ *write;
+ if (dynamic_column_init_str(&tmp,
+ (FIXED_HEADER_SIZE + new_header_size +
+ new_data_size + DYNCOL_SYZERESERVE)))
+ {
+ rc= ER_DYNCOL_RESOURCE;
+ goto end;
+ }
+ write= (uchar *)tmp.str + FIXED_HEADER_SIZE;
+ /* Adjust tmp to contain whole the future header */
+ tmp.length= FIXED_HEADER_SIZE + new_header_size;
+ set_fixed_header(&tmp, new_offset_size, new_column_count);
+ data_delta= 0;
+
+ /*
+ Copy data to the new string
+ i= index in array of changes
+ j= index in packed string header index
+ */
+
+ for (i= 0, j= 0; i < add_column_count || j < column_count; i++)
+ {
+ size_t first_offset;
+ uint start= j, end;
+ LINT_INIT(first_offset);
+
+ /*
+ Search in i and j for the next column to add from i and where to
+ add.
+ */
+
+ while (i < add_column_count && plan[i].act == PLAN_NOP)
+ i++; /* skip NOP */
+ if (i == add_column_count)
+ j= end= column_count;
+ else
+ {
+ /*
+ old data portion. We don't need to check that j < column_count
+ as plan[i].place is guaranteed to have a pointer inside the
+ data.
+ */
+ while (header_base + j * entry_size < plan[i].place)
+ j++;
+ end= j;
+ if ((plan[i].act == PLAN_REPLACE || plan[i].act == PLAN_DELETE))
+ j++; /* data at 'j' will be removed */
+ }
+
+ if (plan[i].ddelta == 0 && offset_size == new_offset_size)
+ {
+ uchar *read= header_base + start * entry_size;
+ DYNAMIC_COLUMN_TYPE tp;
+ /*
+ It's safe to copy the header unchanged. This is usually the
+ case for the first header block before any changed data.
+ */
+ if (start < end) /* Avoid memcpy with 0 */
+ {
+ size_t length= entry_size * (end - start);
+ memcpy(write, read, length);
+ write+= length;
+ }
+ /* Read first_offset */
+ type_and_offset_read(&tp, &first_offset, read, offset_size);
+ }
+ else
+ {
+ /*
+ Adjust all headers since last loop.
+ We have to do this as the offset for data has moved
+ */
+ for (k= start; k < end; k++)
+ {
+ uchar *read= header_base + k * entry_size;
+ size_t offs;
+ uint nm;
+ DYNAMIC_COLUMN_TYPE tp;
+
+ nm= uint2korr(read); /* Column nummber */
+ type_and_offset_read(&tp, &offs, read, offset_size);
+ if (k == start)
+ first_offset= offs;
+ else if (offs < first_offset)
+ {
+ dynamic_column_column_free(&tmp);
+ rc= ER_DYNCOL_FORMAT;
+ goto end;
+ }
+
+ offs+= plan[i].ddelta;
+ int2store(write, nm);
+ /* write rest of data at write + COLUMN_NUMBER_SIZE */
+ type_and_offset_store(write, new_offset_size, tp, offs);
+ write+= new_entry_size;
+ }
+ }
+
+ /* copy first the data that was not replaced in original packed data */
+ if (start < end)
+ {
+ /* Add old data last in 'tmp' */
+ size_t data_size=
+ get_length_interval(header_base + start * entry_size,
+ header_base + end * entry_size,
+ header_end, offset_size, max_offset);
+ if ((long) data_size < 0 ||
+ data_size > max_offset - first_offset)
+ {
+ dynamic_column_column_free(&tmp);
+ rc= ER_DYNCOL_FORMAT;
+ goto end;
+ }
+
+ memcpy(tmp.str + tmp.length, (char *)header_end + first_offset,
+ data_size);
+ tmp.length+= data_size;
+ }
+
+ /* new data adding */
+ if (i < add_column_count)
+ {
+ if( plan[i].act == PLAN_ADD || plan[i].act == PLAN_REPLACE)
+ {
+ int2store(write, plan[i].num[0]);
+ type_and_offset_store(write, new_offset_size,
+ plan[i].val[0].type,
+ tmp.length -
+ (FIXED_HEADER_SIZE + new_header_size));
+ write+= new_entry_size;
+ data_store(&tmp, plan[i].val); /* Append new data */
+ }
+ data_delta= plan[i].ddelta;
+ }
+ }
+ dynamic_column_column_free(str);
+ *str= tmp;
+ }
+
+ rc= ER_DYNCOL_OK;
+
+end:
+ my_free(plan, MYF(0));
+ return rc;
+
+create_new_string:
+ /* There is no columns from before, so let's just add the new ones */
+ rc= ER_DYNCOL_OK;
+ if (not_null != 0)
+ rc= dynamic_column_create_many_internal(str, add_column_count,
+ column_numbers, values,
+ str->str == NULL);
+ goto end;
+}
+
+
+/**
+ Update the packed string with the given column
+
+ @param str String where to write the data
+ @param column_number Array of columns number
+ @param values Array of columns values
+
+ @return ER_DYNCOL_* return code
+*/
+
+
+int dynamic_column_update(DYNAMIC_COLUMN *str, uint column_nr,
+ DYNAMIC_COLUMN_VALUE *value)
+{
+ return dynamic_column_update_many(str, 1, &column_nr, value);
+}
diff --git a/mysys/mf_getdate.c b/mysys/mf_getdate.c
index f517fcae70d..e09dd0603dc 100644
--- a/mysys/mf_getdate.c
+++ b/mysys/mf_getdate.c
@@ -45,7 +45,7 @@ void get_date(register char * to, int flag, time_t date)
struct tm tm_tmp;
#endif
- skr=date ? (time_t) date : my_time(0);
+ skr=date ? date : (time_t) my_time(0);
#if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT)
if (flag & GETDATE_GMT)
gmtime_r(&skr,&tm_tmp);
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index e29b6415d42..8caca5d438b 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -1659,9 +1659,6 @@ int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count,
Buffer+=length;
pos+= length;
Count-= length;
-#ifndef HAVE_PREAD
- info->seek_not_done=1;
-#endif
}
/* Check if we want to write inside the used part of the buffer.*/
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index 04d1c30f6a3..fe5faff47bc 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -101,6 +101,44 @@ void create_last_word_mask(MY_BITMAP *map)
}
+static inline my_bitmap_map last_word_mask(uint bit)
+{
+ my_bitmap_map last_word_mask;
+ uint n_bits= bit + 1;
+ unsigned char const mask= invers_last_byte_mask(n_bits);
+
+ /*
+ The first bytes are to be set to zero since they represent real bits
+ in the bitvector. The last bytes are set to 0xFF since they represent
+ bytes not used by the bitvector. Finally the last byte contains bits
+ as set by the mask above.
+ */
+ unsigned char *ptr= (unsigned char*)&last_word_mask;
+
+ switch ((n_bits + 7)/8 & 3) {
+ case 1:
+ last_word_mask= ~0U;
+ ptr[0]= mask;
+ break;
+ case 2:
+ last_word_mask= ~0U;
+ ptr[0]= 0;
+ ptr[1]= mask;
+ break;
+ case 3:
+ last_word_mask= 0U;
+ ptr[2]= mask;
+ ptr[3]= 0xFFU;
+ break;
+ case 0:
+ last_word_mask= 0U;
+ ptr[3]= mask;
+ break;
+ }
+ return last_word_mask;
+}
+
+
static inline void bitmap_lock(MY_BITMAP *map __attribute__((unused)))
{
#ifdef THREAD
@@ -411,6 +449,58 @@ void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
}
}
+
+/*
+ Check if there is some bit index between start_bit and end_bit, such that
+ this is bit is set for all bitmaps in bitmap_list.
+
+ SYNOPSIS
+ bitmap_exists_intersection()
+ bitmpap_array [in] a set of MY_BITMAPs
+ bitmap_count [in] number of elements in bitmpap_array
+ start_bit [in] beginning (inclusive) of the range of bits to search
+ end_bit [in] end (inclusive) of the range of bits to search, must be
+ no bigger than the bits of the shortest bitmap.
+
+ NOTES
+ This function assumes that for at least one of the bitmaps in bitmap_array all
+ bits outside the range [start_bit, end_bit] are 0. As a result is not
+ necessary to take care of the bits outside the range [start_bit, end_bit].
+
+ RETURN
+ TRUE if an intersecion exists
+ FALSE no intersection
+*/
+
+my_bool bitmap_exists_intersection(const MY_BITMAP **bitmap_array,
+ uint bitmap_count,
+ uint start_bit, uint end_bit)
+{
+ uint i, j, start_idx, end_idx;
+ my_bitmap_map cur_res;
+
+ DBUG_ASSERT(bitmap_count && end_bit >= start_bit);
+ for (j= 0; j < bitmap_count; j++)
+ DBUG_ASSERT(end_bit < bitmap_array[j]->n_bits);
+
+ start_idx= start_bit/8/sizeof(my_bitmap_map);
+ end_idx= end_bit/8/sizeof(my_bitmap_map);
+
+ for (i= start_idx; i < end_idx; i++)
+ {
+ cur_res= ~0;
+ for (j= 0; cur_res && j < bitmap_count; j++)
+ cur_res &= bitmap_array[j]->bitmap[i];
+ if (cur_res)
+ return TRUE;
+ }
+ cur_res= ~last_word_mask(end_bit);
+ for (j= 0; cur_res && j < bitmap_count; j++)
+ cur_res &= bitmap_array[j]->bitmap[end_idx];
+ return cur_res != 0;
+}
+
+
/* True if union of bitmaps have all bits set */
my_bool bitmap_union_is_set_all(const MY_BITMAP *map1, const MY_BITMAP *map2)
diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c
index b1dbb22c687..b9013811b34 100644
--- a/mysys/my_chsize.c
+++ b/mysys/my_chsize.c
@@ -52,20 +52,13 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
if (oldsize > newlength)
{
-#if defined(HAVE_SETFILEPOINTER)
- /* This is for the moment only true on windows */
- long is_success;
- HANDLE win_file= (HANDLE) _get_osfhandle(fd);
- long length_low, length_high;
- length_low= (long) (ulong) newlength;
- length_high= (long) ((ulonglong) newlength >> 32);
- is_success= SetFilePointer(win_file, length_low, &length_high, FILE_BEGIN);
- if (is_success == -1 && (my_errno= GetLastError()) != NO_ERROR)
+#ifdef _WIN32
+ if (my_win_chsize(fd, newlength))
+ {
+ my_errno= errno;
goto err;
- if (SetEndOfFile(win_file))
- DBUG_RETURN(0);
- my_errno= GetLastError();
- goto err;
+ }
+ DBUG_RETURN(0);
#elif defined(HAVE_FTRUNCATE)
if (ftruncate(fd, (off_t) newlength))
{
diff --git a/mysys/my_compare.c b/mysys/my_compare.c
index 936e10c1433..3a60faae727 100644
--- a/mysys/my_compare.c
+++ b/mysys/my_compare.c
@@ -657,7 +657,7 @@ void my_handler_error_register(void)
/*
If you got compilation error here about compile_time_assert array, check
that every HA_ERR_xxx constant has a corresponding error message in
- handler_error_messages[] list (check mysys/ma_handler_errors.h and
+ handler_error_messages[] list (check mysys/my_handler_errors.h and
include/my_base.h).
*/
compile_time_assert(HA_ERR_FIRST + array_elements(handler_error_messages) ==
diff --git a/mysys/my_create.c b/mysys/my_create.c
index 5c9a1e027d2..d0436276d03 100644
--- a/mysys/my_create.c
+++ b/mysys/my_create.c
@@ -18,7 +18,7 @@
#include "mysys_err.h"
#include <errno.h>
#include <my_sys.h>
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <share.h>
#endif
@@ -41,16 +41,12 @@ File my_create(const char *FileName, int CreateFlags, int access_flags,
FileName, CreateFlags, access_flags, MyFlags));
#if !defined(NO_OPEN_3)
- fd = open((char *) FileName, access_flags | O_CREAT,
+ fd= open((char *) FileName, access_flags | O_CREAT,
CreateFlags ? CreateFlags : my_umask);
-#elif defined(VMS)
- fd = open((char *) FileName, access_flags | O_CREAT, 0,
- "ctx=stm","ctx=bin");
-#elif defined(__WIN__)
- fd= my_sopen((char *) FileName, access_flags | O_CREAT | O_BINARY,
- SH_DENYNO, MY_S_IREAD | MY_S_IWRITE);
+#elif defined(_WIN32)
+ fd= my_win_open(FileName, access_flags | O_CREAT);
#else
- fd = open(FileName, access_flags);
+ fd= open(FileName, access_flags);
#endif
if ((MyFlags & MY_SYNC_DIR) && (fd >=0) &&
@@ -71,6 +67,7 @@ File my_create(const char *FileName, int CreateFlags, int access_flags,
if (unlikely(fd >= 0 && rc < 0))
{
int tmp= my_errno;
+ my_close(fd, MyFlags);
my_delete(FileName, MyFlags);
my_errno= tmp;
}
diff --git a/mysys/my_dup.c b/mysys/my_dup.c
index 55f5e0c0099..5fdd6e9f364 100644
--- a/mysys/my_dup.c
+++ b/mysys/my_dup.c
@@ -29,7 +29,11 @@ File my_dup(File file, myf MyFlags)
const char *filename;
DBUG_ENTER("my_dup");
DBUG_PRINT("my",("file: %d MyFlags: %d", file, MyFlags));
- fd = dup(file);
+#ifdef _WIN32
+ fd= my_win_dup(file);
+#else
+ fd= dup(file);
+#endif
filename= (((uint) file < my_file_limit) ?
my_file_info[(int) file].name : "Unknown");
DBUG_RETURN(my_register_filename(fd, filename, FILE_BY_DUP,
diff --git a/mysys/my_file.c b/mysys/my_file.c
index 19900559f64..f0dd51bdcd5 100644
--- a/mysys/my_file.c
+++ b/mysys/my_file.c
@@ -99,6 +99,7 @@ uint my_set_max_open_files(uint files)
DBUG_ENTER("my_set_max_open_files");
DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
+ files+= MY_FILE_MIN;
files= set_max_open_files(min(files, OS_FILE_LIMIT));
if (files <= MY_NFILE)
DBUG_RETURN(files);
diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c
index a4b0c9f895d..ae631a59353 100644
--- a/mysys/my_fopen.c
+++ b/mysys/my_fopen.c
@@ -46,24 +46,14 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags)
DBUG_ENTER("my_fopen");
DBUG_PRINT("my",("Name: '%s' flags: %d MyFlags: %d",
filename, flags, MyFlags));
- /*
- if we are not creating, then we need to use my_access to make sure
- the file exists since Windows doesn't handle files like "com1.sym"
- very well
- */
-#ifdef __WIN__
- if (check_if_legal_filename(filename))
- {
- errno= EACCES;
- fd= 0;
- }
- else
+
+ make_ftype(type,flags);
+
+#ifdef _WIN32
+ fd= my_win_fopen(filename, type);
+#else
+ fd= fopen(filename, type);
#endif
- {
- make_ftype(type,flags);
- fd = fopen(filename, type);
- }
-
if (fd != 0)
{
/*
@@ -71,18 +61,20 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags)
on some OS (SUNOS). Actually the filename save isn't that important
so we can ignore if this doesn't work.
*/
- if ((uint) fileno(fd) >= my_file_limit)
+
+ int filedesc= my_fileno(fd);
+ if ((uint)filedesc >= my_file_limit)
{
thread_safe_increment(my_stream_opened,&THR_LOCK_open);
DBUG_RETURN(fd); /* safeguard */
}
pthread_mutex_lock(&THR_LOCK_open);
- if ((my_file_info[fileno(fd)].name = (char*)
+ if ((my_file_info[filedesc].name= (char*)
my_strdup(filename,MyFlags)))
{
my_stream_opened++;
my_file_total_opened++;
- my_file_info[fileno(fd)].type = STREAM_BY_FOPEN;
+ my_file_info[filedesc].type= STREAM_BY_FOPEN;
pthread_mutex_unlock(&THR_LOCK_open);
DBUG_PRINT("exit",("stream: 0x%lx", (long) fd));
DBUG_RETURN(fd);
@@ -240,8 +232,13 @@ int my_fclose(FILE *fd, myf MyFlags)
DBUG_PRINT("my",("stream: 0x%lx MyFlags: %d", (long) fd, MyFlags));
pthread_mutex_lock(&THR_LOCK_open);
- file=fileno(fd);
- if ((err = fclose(fd)) < 0)
+ file= my_fileno(fd);
+#ifndef _WIN32
+ err= fclose(fd);
+#else
+ err= my_win_fclose(fd);
+#endif
+ if(err < 0)
{
my_errno=errno;
if (MyFlags & (MY_FAE | MY_WME))
@@ -272,7 +269,12 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
Filedes, Flags, MyFlags));
make_ftype(type,Flags);
- if ((fd = fdopen(Filedes, type)) == 0)
+#ifdef _WIN32
+ fd= my_win_fdopen(Filedes, type);
+#else
+ fd= fdopen(Filedes, type);
+#endif
+ if (!fd)
{
my_errno=errno;
if (MyFlags & (MY_FAE | MY_WME))
diff --git a/mysys/my_fstream.c b/mysys/my_fstream.c
index 929a59db9cd..8cee4819ed2 100644
--- a/mysys/my_fstream.c
+++ b/mysys/my_fstream.c
@@ -59,11 +59,11 @@ size_t my_fread(FILE *stream, uchar *Buffer, size_t Count, myf MyFlags)
{
if (ferror(stream))
my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
- my_filename(fileno(stream)),errno);
+ my_filename(my_fileno(stream)),errno);
else
if (MyFlags & (MY_NABP | MY_FNABP))
my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
- my_filename(fileno(stream)),errno);
+ my_filename(my_fileno(stream)),errno);
}
my_errno=errno ? errno : -1;
if (ferror(stream) || MyFlags & (MY_NABP | MY_FNABP))
@@ -145,7 +145,7 @@ size_t my_fwrite(FILE *stream, const uchar *Buffer, size_t Count, myf MyFlags)
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
{
my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG),
- my_filename(fileno(stream)),errno);
+ my_filename(my_fileno(stream)),errno);
}
writtenbytes= (size_t) -1; /* Return that we got error */
break;
@@ -185,3 +185,14 @@ my_off_t my_ftell(FILE *stream, myf MyFlags __attribute__((unused)))
DBUG_PRINT("exit",("ftell: %lu",(ulong) pos));
DBUG_RETURN((my_off_t) pos);
} /* my_ftell */
+
+
+/* Get a File corresponding to the stream*/
+int my_fileno(FILE *f)
+{
+#ifdef _WIN32
+ return my_win_fileno(f);
+#else
+ return fileno(f);
+#endif
+}
diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c
index 6bffcd65d30..8a3e97cffa7 100644
--- a/mysys/my_getsystime.c
+++ b/mysys/my_getsystime.c
@@ -14,224 +14,107 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* get time since epoc in 100 nanosec units */
-/* thus to get the current time we should use the system function
- with the highest possible resolution */
-
-/*
- TODO: in functions my_micro_time() and my_micro_time_and_time() there
- exists some common code that should be merged into a function.
-*/
#include "mysys_priv.h"
#include "my_static.h"
#ifdef __NETWARE__
#include <nks/time.h>
+#elif defined(__WIN__)
+#define OFFSET_TO_EPOC 116444736000000000LL
+static ulonglong query_performance_frequency;
#endif
#ifdef HAVE_LINUX_UNISTD_H
#include <linux/unistd.h>
#endif
+/* For CYGWIN */
+#if !defined(CLOCK_THREAD_CPUTIME_ID) && defined(CLOCK_THREAD_CPUTIME)
+#define CLOCK_THREAD_CPUTIME_ID CLOCK_THREAD_CPUTIME
+#endif
+
+/*
+ return number of nanoseconds since unspecified (but always the same)
+ point in the past
+
+ NOTE:
+ Thus to get the current time we should use the system function
+ with the highest possible resolution
-ulonglong my_getsystime()
+ The value is not anchored to any specific point in time (e.g. epoch) nor
+ is it subject to resetting or drifting by way of adjtime() or settimeofday(),
+ and thus it is *NOT* appropriate for getting the current timestamp. It can be
+ used for calculating time intervals, though.
+*/
+
+ulonglong my_interval_timer()
{
#ifdef HAVE_CLOCK_GETTIME
struct timespec tp;
- clock_gettime(CLOCK_REALTIME, &tp);
- return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100;
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ return tp.tv_sec*1000000000ULL+tp.tv_nsec;
+#elif defined(HAVE_GETHRTIME)
+ return gethrtime();
#elif defined(__WIN__)
LARGE_INTEGER t_cnt;
if (query_performance_frequency)
{
QueryPerformanceCounter(&t_cnt);
- return ((t_cnt.QuadPart / query_performance_frequency * 10000000) +
- ((t_cnt.QuadPart % query_performance_frequency) * 10000000 /
- query_performance_frequency) + query_performance_offset);
+ return (t_cnt.QuadPart / query_performance_frequency * 1000000000ULL) +
+ ((t_cnt.QuadPart % query_performance_frequency) * 1000000000ULL /
+ query_performance_frequency);
+ }
+ else
+ {
+ ulonglong newtime;
+ GetSystemTimeAsFileTime((FILETIME*)&newtime);
+ return newtime*100ULL;
}
- return 0;
#elif defined(__NETWARE__)
NXTime_t tm;
NXGetTime(NX_SINCE_1970, NX_NSECONDS, &tm);
- return (ulonglong)tm/100;
+ return (ulonglong)tm;
#else
/* TODO: check for other possibilities for hi-res timestamping */
struct timeval tv;
gettimeofday(&tv,NULL);
- return (ulonglong)tv.tv_sec*10000000+(ulonglong)tv.tv_usec*10;
+ return tv.tv_sec*1000000000ULL+tv.tv_usec*1000ULL;
#endif
}
-/*
- Return current time
-
- SYNOPSIS
- my_time()
- flags If MY_WME is set, write error if time call fails
-
-*/
+/* Return current time in HRTIME_RESOLUTION (microseconds) since epoch */
-time_t my_time(myf flags __attribute__((unused)))
-{
- time_t t;
-#ifdef HAVE_GETHRTIME
- (void) my_micro_time_and_time(&t);
- return t;
-#else
- /* The following loop is here beacuse time() may fail on some systems */
- while ((t= time(0)) == (time_t) -1)
- {
- if (flags & MY_WME)
- fprintf(stderr, "%s: Warning: time() call failed\n", my_progname);
- }
- return t;
-#endif
-}
-
-
-/*
- Return time in micro seconds
-
- SYNOPSIS
- my_micro_time()
-
- NOTES
- This function is to be used to measure performance in micro seconds.
- As it's not defined whats the start time for the clock, this function
- us only useful to measure time between two moments.
-
- For windows platforms we need the frequency value of the CUP. This is
- initalized in my_init.c through QueryPerformanceFrequency().
-
- If Windows platform doesn't support QueryPerformanceFrequency() we will
- obtain the time via GetClockCount, which only supports milliseconds.
-
- RETURN
- Value in microseconds from some undefined point in time
-*/
-
-ulonglong my_micro_time()
+my_hrtime_t my_hrtime()
{
+ my_hrtime_t hrtime;
#if defined(__WIN__)
ulonglong newtime;
GetSystemTimeAsFileTime((FILETIME*)&newtime);
- return (newtime/10);
-#elif defined(HAVE_GETHRTIME)
- return gethrtime()/1000;
-#else
- ulonglong newtime;
- struct timeval t;
- /*
- The following loop is here because gettimeofday may fail on some systems
- */
- while (gettimeofday(&t, NULL) != 0)
- {}
- newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec;
- return newtime;
-#endif /* defined(__WIN__) */
-}
-
-
-/*
- Return time in seconds and timer in microseconds (not different start!)
-
- SYNOPSIS
- my_micro_time_and_time()
- time_arg Will be set to seconds since epoch (00:00:00 UTC,
- January 1, 1970)
-
- NOTES
- This function is to be useful when we need both the time and microtime.
- For example in MySQL this is used to get the query time start of a query
- and to measure the time of a query (for the slow query log)
-
- IMPLEMENTATION
- Value of time is as in time() call.
- Value of microtime is same as my_micro_time(), which may be totally
- unrealated to time()
-
- RETURN
- Value in microseconds from some undefined point in time
-*/
-
-#define DELTA_FOR_SECONDS LL(500000000) /* Half a second */
-
-ulonglong my_micro_time_and_time(time_t *time_arg)
-{
-#if defined(__WIN__)
- ulonglong newtime;
- GetSystemTimeAsFileTime((FILETIME*)&newtime);
- *time_arg= (time_t) ((newtime - OFFSET_TO_EPOCH) / 10000000);
- return (newtime/10);
-#elif defined(HAVE_GETHRTIME)
- /*
- Solaris has a very slow time() call. We optimize this by using the very
- fast gethrtime() call and only calling time() every 1/2 second
- */
- static hrtime_t prev_gethrtime= 0;
- static time_t cur_time= 0;
- hrtime_t cur_gethrtime;
-
- pthread_mutex_lock(&THR_LOCK_time);
- cur_gethrtime= gethrtime();
- /*
- Due to bugs in the Solaris (x86) implementation of gethrtime(),
- the time returned by it might not be monotonic. Don't use the
- cached time(2) value if this is a case.
- */
- if ((prev_gethrtime > cur_gethrtime) ||
- ((cur_gethrtime - prev_gethrtime) > DELTA_FOR_SECONDS))
- {
- cur_time= time(0);
- prev_gethrtime= cur_gethrtime;
- }
- *time_arg= cur_time;
- pthread_mutex_unlock(&THR_LOCK_time);
- return cur_gethrtime/1000;
+ newtime -= OFFSET_TO_EPOC;
+ hrtime.val= newtime/10;
+#elif defined(HAVE_CLOCK_GETTIME)
+ struct timespec tp;
+ clock_gettime(CLOCK_REALTIME, &tp);
+ hrtime.val= tp.tv_sec*1000000ULL+tp.tv_nsec/1000ULL;
#else
- ulonglong newtime;
struct timeval t;
- /*
- The following loop is here because gettimeofday may fail on some systems
- */
- while (gettimeofday(&t, NULL) != 0)
- {}
- *time_arg= t.tv_sec;
- newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec;
- return newtime;
-#endif /* defined(__WIN__) */
+ /* The following loop is here because gettimeofday may fail */
+ while (gettimeofday(&t, NULL) != 0) {}
+ hrtime.val= t.tv_sec*1000000ULL + t.tv_usec;
+#endif
+ return hrtime;
}
-/*
- Returns current time
-
- SYNOPSIS
- my_time_possible_from_micro()
- microtime Value from very recent my_micro_time()
-
- NOTES
- This function returns the current time. The microtime argument is only used
- if my_micro_time() uses a function that can safely be converted to the
- current time.
-
- RETURN
- current time
-*/
-
-time_t my_time_possible_from_micro(ulonglong microtime __attribute__((unused)))
+void my_time_init()
{
-#if defined(__WIN__)
- time_t t;
- while ((t= time(0)) == (time_t) -1)
- {}
- return t;
-#elif defined(HAVE_GETHRTIME)
- return my_time(0); /* Cached time */
-#else
- return (time_t) (microtime / 1000000);
-#endif /* defined(__WIN__) */
+#ifdef __WIN__
+ compile_time_assert(sizeof(LARGE_INTEGER) ==
+ sizeof(query_performance_frequency));
+ if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0)
+ query_performance_frequency= 0;
+#endif
}
@@ -241,7 +124,7 @@ time_t my_time_possible_from_micro(ulonglong microtime __attribute__((unused)))
ulonglong my_getcputime()
{
-#ifdef HAVE_CLOCK_GETTIME
+#ifdef CLOCK_THREAD_CPUTIME_ID
struct timespec tp;
if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp))
return 0;
diff --git a/mysys/my_handler_errors.h b/mysys/my_handler_errors.h
index e6514536735..92d9266ae73 100644
--- a/mysys/my_handler_errors.h
+++ b/mysys/my_handler_errors.h
@@ -79,8 +79,8 @@ static const char *handler_error_messages[]=
"File too short; Expected more data in file",
"Read page with wrong checksum",
"Too many active concurrent transactions",
- "",
- "",
+ "Operation was interrupted by end user (probably kill command?)",
+ "Disk full",
"Row is not visible by the current transaction",
"Table is being used in foreign key check" /* HA_ERR_TABLE_IN_FK_CHECK */
};
diff --git a/mysys/my_init.c b/mysys/my_init.c
index 23567947adb..89ac2f322cf 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -106,6 +106,7 @@ my_bool my_init(void)
DBUG_PROCESS((char*) (my_progname ? my_progname : "unknown"));
if (!home_dir)
{ /* Don't initialize twice */
+ my_time_init();
my_win_init();
if ((home_dir=getenv("HOME")) != 0)
home_dir=intern_filename(home_dir_buff,home_dir);
@@ -262,7 +263,6 @@ void my_debug_put_break_here(void)
#ifdef __WIN__
-
/*
my_parameter_handler
@@ -278,6 +278,7 @@ void my_parameter_handler(const wchar_t * expression, const wchar_t * function,
{
DBUG_PRINT("my",("Expression: %s function: %s file: %s, line: %d",
expression, function, file, line));
+ __debugbreak();
}
@@ -302,7 +303,7 @@ int handle_rtc_failure(int err_type, const char *file, int line,
fprintf(stderr, " At %s:%d\n", file, line);
va_end(args);
(void) fflush(stderr);
-
+ __debugbreak();
return 0; /* Error is handled */
}
#pragma runtime_checks("", restore)
@@ -336,54 +337,6 @@ static void my_win_init(void)
_tzset();
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* The following is used by time functions */
-#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10)
-#define MS 10000000
- {
- FILETIME ft;
- LARGE_INTEGER li, t_cnt;
- DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency));
- if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0)
- query_performance_frequency= 0;
- else
- {
- GetSystemTimeAsFileTime(&ft);
- li.LowPart= ft.dwLowDateTime;
- li.HighPart= ft.dwHighDateTime;
- query_performance_offset= li.QuadPart-OFFSET_TO_EPOC;
- QueryPerformanceCounter(&t_cnt);
- query_performance_offset-= (t_cnt.QuadPart /
- query_performance_frequency * MS +
- t_cnt.QuadPart %
- query_performance_frequency * MS /
- query_performance_frequency);
- }
- }
-
{
/*
Open HKEY_LOCAL_MACHINE\SOFTWARE\MySQL and set any strings found
diff --git a/mysys/my_lib.c b/mysys/my_lib.c
index 8bd9a289176..864c1e96d27 100644
--- a/mysys/my_lib.c
+++ b/mysys/my_lib.c
@@ -36,8 +36,7 @@
# if defined(HAVE_NDIR_H)
# include <ndir.h>
# endif
-# if defined(__WIN__)
-# include <dos.h>
+# if defined(_WIN32)
# ifdef __BORLANDC__
# include <dir.h>
# endif
@@ -93,7 +92,7 @@ static int comp_names(struct fileinfo *a, struct fileinfo *b)
} /* comp_names */
-#if !defined(__WIN__)
+#if !defined(_WIN32)
MY_DIR *my_dir(const char *path, myf MyFlags)
{
@@ -509,19 +508,24 @@ error:
DBUG_RETURN((MY_DIR *) NULL);
} /* my_dir */
-#endif /* __WIN__ */
+#endif /* _WIN32 */
/****************************************************************************
** File status
** Note that MY_STAT is assumed to be same as struct stat
****************************************************************************/
-int my_fstat(int Filedes, MY_STAT *stat_area,
+
+int my_fstat(File Filedes, MY_STAT *stat_area,
myf MyFlags __attribute__((unused)))
{
DBUG_ENTER("my_fstat");
DBUG_PRINT("my",("fd: %d MyFlags: %d", Filedes, MyFlags));
+#ifdef _WIN32
+ DBUG_RETURN(my_win_fstat(Filedes, stat_area));
+#else
DBUG_RETURN(fstat(Filedes, (struct stat *) stat_area));
+#endif
}
@@ -533,11 +537,15 @@ MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags)
(long) stat_area, my_flags));
if ((m_used= (stat_area == NULL)))
- if (!(stat_area = (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags)))
+ if (!(stat_area= (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags)))
goto error;
- if (! stat((char *) path, (struct stat *) stat_area) )
- DBUG_RETURN(stat_area);
-
+#ifndef _WIN32
+ if (! stat((char *) path, (struct stat *) stat_area) )
+ DBUG_RETURN(stat_area);
+#else
+ if (! my_win_stat(path, stat_area) )
+ DBUG_RETURN(stat_area);
+#endif
DBUG_PRINT("error",("Got errno: %d from stat", errno));
my_errno= errno;
if (m_used) /* Free if new area */
diff --git a/mysys/my_lock.c b/mysys/my_lock.c
index 8450fcfc30a..6bbb177e4b6 100644
--- a/mysys/my_lock.c
+++ b/mysys/my_lock.c
@@ -22,13 +22,113 @@
#undef NO_ALARM_LOOP
#endif
#include <my_alarm.h>
-#ifdef __WIN__
-#include <sys/locking.h>
-#endif
#ifdef __NETWARE__
#include <nks/fsio.h>
#endif
+#ifdef _WIN32
+#define WIN_LOCK_INFINITE -1
+#define WIN_LOCK_SLEEP_MILLIS 100
+
+static int win_lock(File fd, int locktype, my_off_t start, my_off_t length,
+ int timeout_sec)
+{
+ LARGE_INTEGER liOffset,liLength;
+ DWORD dwFlags;
+ OVERLAPPED ov= {0};
+ HANDLE hFile= (HANDLE)my_get_osfhandle(fd);
+ DWORD lastError= 0;
+ int i;
+ int timeout_millis= timeout_sec * 1000;
+
+ DBUG_ENTER("win_lock");
+
+ liOffset.QuadPart= start;
+ liLength.QuadPart= length;
+
+ ov.Offset= liOffset.LowPart;
+ ov.OffsetHigh= liOffset.HighPart;
+
+ if (locktype == F_UNLCK)
+ {
+ if (UnlockFileEx(hFile, 0, liLength.LowPart, liLength.HighPart, &ov))
+ DBUG_RETURN(0);
+ /*
+ For compatibility with fcntl implementation, ignore error,
+ if region was not locked
+ */
+ if (GetLastError() == ERROR_NOT_LOCKED)
+ {
+ SetLastError(0);
+ DBUG_RETURN(0);
+ }
+ goto error;
+ }
+ else if (locktype == F_RDLCK)
+ /* read lock is mapped to a shared lock. */
+ dwFlags= 0;
+ else
+ /* write lock is mapped to an exclusive lock. */
+ dwFlags= LOCKFILE_EXCLUSIVE_LOCK;
+
+ /*
+ Drop old lock first to avoid double locking.
+ During analyze of Bug#38133 (Myisamlog test fails on Windows)
+ I met the situation that the program myisamlog locked the file
+ exclusively, then additionally shared, then did one unlock, and
+ then blocked on an attempt to lock it exclusively again.
+ Unlocking before every lock fixed the problem.
+ Note that this introduces a race condition. When the application
+ wants to convert an exclusive lock into a shared one, it will now
+ first unlock the file and then lock it shared. A waiting exclusive
+ lock could step in here. For reasons described in Bug#38133 and
+ Bug#41124 (Server hangs on Windows with --external-locking after
+ INSERT...SELECT) and in the review thread at
+ http://lists.mysql.com/commits/60721 it seems to be the better
+ option than not to unlock here.
+ If one day someone notices a way how to do file lock type changes
+ on Windows without unlocking before taking the new lock, please
+ change this code accordingly to fix the race condition.
+ */
+ if (!UnlockFileEx(hFile, 0, liLength.LowPart, liLength.HighPart, &ov) &&
+ (GetLastError() != ERROR_NOT_LOCKED))
+ goto error;
+
+ if (timeout_sec == WIN_LOCK_INFINITE)
+ {
+ if (LockFileEx(hFile, dwFlags, 0, liLength.LowPart, liLength.HighPart, &ov))
+ DBUG_RETURN(0);
+ goto error;
+ }
+
+ dwFlags|= LOCKFILE_FAIL_IMMEDIATELY;
+ timeout_millis= timeout_sec * 1000;
+ /* Try lock in a loop, until the lock is acquired or timeout happens */
+ for(i= 0; ;i+= WIN_LOCK_SLEEP_MILLIS)
+ {
+ if (LockFileEx(hFile, dwFlags, 0, liLength.LowPart, liLength.HighPart, &ov))
+ DBUG_RETURN(0);
+
+ if (GetLastError() != ERROR_LOCK_VIOLATION)
+ goto error;
+
+ if (i >= timeout_millis)
+ break;
+ Sleep(WIN_LOCK_SLEEP_MILLIS);
+ }
+
+ /* timeout */
+ errno= EAGAIN;
+ DBUG_RETURN(-1);
+
+error:
+ my_osmaperr(GetLastError());
+ DBUG_RETURN(-1);
+}
+#endif
+
+
+
/*
Lock a part of a file
@@ -97,29 +197,16 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
DBUG_RETURN(0);
}
}
-#elif defined(HAVE_LOCKING)
- /* Windows */
+#elif defined(_WIN32)
{
- my_bool error= FALSE;
- pthread_mutex_lock(&my_file_info[fd].mutex);
- if (MyFlags & MY_SEEK_NOT_DONE)
- {
- if( my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE))
- == MY_FILEPOS_ERROR )
- {
- /*
- If my_seek fails my_errno will already contain an error code;
- just unlock and return error code.
- */
- DBUG_PRINT("error",("my_errno: %d (%d)",my_errno,errno));
- pthread_mutex_unlock(&my_file_info[fd].mutex);
- DBUG_RETURN(-1);
- }
- }
- error= locking(fd,locktype,(ulong) length) && errno != EINVAL;
- pthread_mutex_unlock(&my_file_info[fd].mutex);
- if (!error)
- DBUG_RETURN(0);
+ int timeout_sec;
+ if (MyFlags & MY_NO_WAIT)
+ timeout_sec= 0;
+ else
+ timeout_sec= WIN_LOCK_INFINITE;
+
+ if(win_lock(fd, locktype, start, length, timeout_sec) == 0)
+ DBUG_RETURN(0);
}
#else
#if defined(HAVE_FCNTL)
diff --git a/mysys/my_mmap.c b/mysys/my_mmap.c
index 023a06fd896..303d8efaf30 100644
--- a/mysys/my_mmap.c
+++ b/mysys/my_mmap.c
@@ -27,17 +27,17 @@ int my_msync(int fd, void *addr, size_t len, int flags)
return my_sync(fd, MYF(0));
}
-#elif defined(__WIN__)
+#elif defined(_WIN32)
static SECURITY_ATTRIBUTES mmap_security_attributes=
{sizeof(SECURITY_ATTRIBUTES), 0, TRUE};
void *my_mmap(void *addr, size_t len, int prot,
- int flags, int fd, my_off_t offset)
+ int flags, File fd, my_off_t offset)
{
HANDLE hFileMap;
LPVOID ptr;
- HANDLE hFile= (HANDLE)_get_osfhandle(fd);
+ HANDLE hFile= (HANDLE)my_get_osfhandle(fd);
if (hFile == INVALID_HANDLE_VALUE)
return MAP_FAILED;
diff --git a/mysys/my_open.c b/mysys/my_open.c
index 3980e3a9a77..dc2fcaf04c6 100644
--- a/mysys/my_open.c
+++ b/mysys/my_open.c
@@ -17,9 +17,7 @@
#include "mysys_err.h"
#include <my_dir.h>
#include <errno.h>
-#if defined(__WIN__)
-#include <share.h>
-#endif
+
/*
Open a file
@@ -45,30 +43,8 @@ File my_open(const char *FileName, int Flags, myf MyFlags)
FileName, Flags, MyFlags));
if (!(MyFlags & (MY_WME | MY_FAE | MY_FFNF)))
MyFlags|= my_global_flags;
-
-#if defined(__WIN__)
- /*
- Check that we don't try to open or create a file name that may
- cause problems for us in the future (like PRN)
- */
- if (check_if_legal_filename(FileName))
- {
- errno= EACCES;
- DBUG_RETURN(my_register_filename(-1, FileName, FILE_BY_OPEN,
- EE_FILENOTFOUND, MyFlags));
- }
-#ifndef __WIN__
- if (Flags & O_SHARE)
- fd = sopen((char *) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO,
- MY_S_IREAD | MY_S_IWRITE);
- else
- fd = open((char *) FileName, Flags | O_BINARY,
- MY_S_IREAD | MY_S_IWRITE);
-#else
- fd= my_sopen((char *) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO,
- MY_S_IREAD | MY_S_IWRITE);
-#endif
-
+#if defined(_WIN32)
+ fd= my_win_open(FileName, Flags);
#elif !defined(NO_OPEN_3)
fd = open(FileName, Flags, my_umask); /* Normal unix */
#else
@@ -99,11 +75,14 @@ int my_close(File fd, myf MyFlags)
MyFlags|= my_global_flags;
pthread_mutex_lock(&THR_LOCK_open);
+#ifndef _WIN32
do
{
err= close(fd);
} while (err == -1 && errno == EINTR);
-
+#else
+ err= my_win_close(fd);
+#endif
if (err)
{
DBUG_PRINT("error",("Got error %d on close",err));
@@ -115,9 +94,6 @@ int my_close(File fd, myf MyFlags)
if ((uint) fd < my_file_limit && my_file_info[fd].type != UNOPEN)
{
my_free(my_file_info[fd].name, MYF(0));
-#if defined(THREAD) && !defined(HAVE_PREAD)
- pthread_mutex_destroy(&my_file_info[fd].mutex);
-#endif
my_file_info[fd].type = UNOPEN;
}
my_file_opened--;
@@ -147,16 +123,12 @@ File my_register_filename(File fd, const char *FileName, enum file_type
type_of_file, uint error_message_number, myf MyFlags)
{
DBUG_ENTER("my_register_filename");
- if ((int) fd >= 0)
+ if ((int) fd >= MY_FILE_MIN)
{
if ((uint) fd >= my_file_limit)
{
-#if defined(THREAD) && !defined(HAVE_PREAD)
- my_errno= EMFILE;
-#else
thread_safe_increment(my_file_opened,&THR_LOCK_open);
DBUG_RETURN(fd); /* safeguard */
-#endif
}
else
{
@@ -166,9 +138,6 @@ File my_register_filename(File fd, const char *FileName, enum file_type
my_file_opened++;
my_file_total_opened++;
my_file_info[fd].type = type_of_file;
-#if defined(THREAD) && !defined(HAVE_PREAD)
- pthread_mutex_init(&my_file_info[fd].mutex,MY_MUTEX_INIT_FAST);
-#endif
pthread_mutex_unlock(&THR_LOCK_open);
DBUG_PRINT("exit",("fd: %d",fd));
DBUG_RETURN(fd);
@@ -193,188 +162,7 @@ File my_register_filename(File fd, const char *FileName, enum file_type
DBUG_RETURN(-1);
}
-#ifdef __WIN__
-
-extern void __cdecl _dosmaperr(unsigned long);
-
-/*
- Open a file with sharing. Similar to _sopen() from libc, but allows managing
- share delete on win32
-
- SYNOPSIS
- my_sopen()
- path fully qualified file name
- oflag operation flags
- shflag share flag
- pmode permission flags
-
- RETURN VALUE
- File descriptor of opened file if success
- -1 and sets errno if fails.
-*/
-
-File my_sopen(const char *path, int oflag, int shflag, int pmode)
-{
- int fh; /* handle of opened file */
- int mask;
- HANDLE osfh; /* OS handle of opened file */
- DWORD fileaccess; /* OS file access (requested) */
- DWORD fileshare; /* OS file sharing mode */
- DWORD filecreate; /* OS method of opening/creating */
- DWORD fileattrib; /* OS file attribute flags */
- SECURITY_ATTRIBUTES SecurityAttributes;
-
- SecurityAttributes.nLength= sizeof(SecurityAttributes);
- SecurityAttributes.lpSecurityDescriptor= NULL;
- SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT);
- /*
- * decode the access flags
- */
- switch (oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
- case _O_RDONLY: /* read access */
- fileaccess= GENERIC_READ;
- break;
- case _O_WRONLY: /* write access */
- fileaccess= GENERIC_WRITE;
- break;
- case _O_RDWR: /* read and write access */
- fileaccess= GENERIC_READ | GENERIC_WRITE;
- break;
- default: /* error, bad oflag */
- errno= EINVAL;
- _doserrno= 0L; /* not an OS error */
- return -1;
- }
-
- /*
- * decode sharing flags
- */
- switch (shflag) {
- case _SH_DENYRW: /* exclusive access except delete */
- fileshare= FILE_SHARE_DELETE;
- break;
- case _SH_DENYWR: /* share read and delete access */
- fileshare= FILE_SHARE_READ | FILE_SHARE_DELETE;
- break;
- case _SH_DENYRD: /* share write and delete access */
- fileshare= FILE_SHARE_WRITE | FILE_SHARE_DELETE;
- break;
- case _SH_DENYNO: /* share read, write and delete access */
- fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
- break;
- case _SH_DENYRWD: /* exclusive access */
- fileshare= 0L;
- break;
- case _SH_DENYWRD: /* share read access */
- fileshare= FILE_SHARE_READ;
- break;
- case _SH_DENYRDD: /* share write access */
- fileshare= FILE_SHARE_WRITE;
- break;
- case _SH_DENYDEL: /* share read and write access */
- fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE;
- break;
- default: /* error, bad shflag */
- errno= EINVAL;
- _doserrno= 0L; /* not an OS error */
- return -1;
- }
-
- /*
- * decode open/create method flags
- */
- switch (oflag & (_O_CREAT | _O_EXCL | _O_TRUNC)) {
- case 0:
- case _O_EXCL: /* ignore EXCL w/o CREAT */
- filecreate= OPEN_EXISTING;
- break;
-
- case _O_CREAT:
- filecreate= OPEN_ALWAYS;
- break;
-
- case _O_CREAT | _O_EXCL:
- case _O_CREAT | _O_TRUNC | _O_EXCL:
- filecreate= CREATE_NEW;
- break;
-
- case _O_TRUNC:
- case _O_TRUNC | _O_EXCL: /* ignore EXCL w/o CREAT */
- filecreate= TRUNCATE_EXISTING;
- break;
-
- case _O_CREAT | _O_TRUNC:
- filecreate= CREATE_ALWAYS;
- break;
-
- default:
- /* this can't happen ... all cases are covered */
- errno= EINVAL;
- _doserrno= 0L;
- return -1;
- }
-
- /*
- * decode file attribute flags if _O_CREAT was specified
- */
- fileattrib= FILE_ATTRIBUTE_NORMAL; /* default */
- if (oflag & _O_CREAT)
- {
- _umask((mask= _umask(0)));
-
- if (!((pmode & ~mask) & _S_IWRITE))
- fileattrib= FILE_ATTRIBUTE_READONLY;
- }
-
- /*
- * Set temporary file (delete-on-close) attribute if requested.
- */
- if (oflag & _O_TEMPORARY)
- {
- fileattrib|= FILE_FLAG_DELETE_ON_CLOSE;
- fileaccess|= DELETE;
- }
-
- /*
- * Set temporary file (delay-flush-to-disk) attribute if requested.
- */
- if (oflag & _O_SHORT_LIVED)
- fileattrib|= FILE_ATTRIBUTE_TEMPORARY;
-
- /*
- * Set sequential or random access attribute if requested.
- */
- if (oflag & _O_SEQUENTIAL)
- fileattrib|= FILE_FLAG_SEQUENTIAL_SCAN;
- else if (oflag & _O_RANDOM)
- fileattrib|= FILE_FLAG_RANDOM_ACCESS;
-
- /*
- * try to open/create the file
- */
- if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes,
- filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE)
- {
- /*
- * OS call to open/create file failed! map the error, release
- * the lock, and return -1. note that it's not necessary to
- * call _free_osfhnd (it hasn't been used yet).
- */
- _dosmaperr(GetLastError()); /* map error */
- return -1; /* return error to caller */
- }
-
- if ((fh= _open_osfhandle((intptr_t)osfh,
- oflag & (_O_APPEND | _O_RDONLY | _O_TEXT))) == -1)
- {
- _dosmaperr(GetLastError()); /* map error */
- CloseHandle(osfh);
- }
-
- return fh; /* return handle */
-}
-#endif /* __WIN__ */
#ifdef EXTRA_DEBUG
diff --git a/mysys/my_pread.c b/mysys/my_pread.c
index 5fd60f6ef8a..dad346264bb 100644
--- a/mysys/my_pread.c
+++ b/mysys/my_pread.c
@@ -21,7 +21,7 @@
#include "my_base.h"
#include <m_string.h>
#include <errno.h>
-#ifdef HAVE_PREAD
+#ifndef _WIN32
#include <unistd.h>
#endif
@@ -51,9 +51,7 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
{
size_t readbytes;
int error= 0;
-#ifndef HAVE_PREAD
- int save_errno;
-#endif
+
#ifndef DBUG_OFF
char llbuf[22];
DBUG_ENTER("my_pread");
@@ -67,20 +65,15 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
for (;;)
{
errno= 0; /* Linux, Windows don't reset this on EOF/success */
-#ifndef HAVE_PREAD
- pthread_mutex_lock(&my_file_info[Filedes].mutex);
- readbytes= (uint) -1;
- error= (lseek(Filedes, offset, MY_SEEK_SET) == (my_off_t) -1 ||
- (readbytes= read(Filedes, Buffer, (uint) Count)) != Count);
- save_errno= errno;
- pthread_mutex_unlock(&my_file_info[Filedes].mutex);
- if (error)
- {
- errno= save_errno;
+#ifdef _WIN32
+ readbytes= my_win_pread(Filedes, Buffer, Count, offset);
#else
- if ((error= ((readbytes= pread(Filedes, Buffer, Count, offset)) != Count)))
- {
+ readbytes= pread(Filedes, Buffer, Count, offset);
#endif
+ error = (readbytes != Count);
+
+ if (error)
+ {
my_errno= errno ? errno : -1;
if (errno == 0 || (readbytes != (size_t) -1 &&
(MyFlags & (MY_NABP | MY_FNABP))))
@@ -107,11 +100,11 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
my_filename(Filedes),my_errno);
}
if (readbytes == (size_t) -1 || (MyFlags & (MY_FNABP | MY_NABP)))
- DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
+ DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
}
if (MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN(0); /* Read went ok; Return 0 */
- DBUG_RETURN(readbytes); /* purecov: inspected */
+ DBUG_RETURN(0); /* Read went ok; Return 0 */
+ DBUG_RETURN(readbytes); /* purecov: inspected */
}
} /* my_pread */
@@ -140,7 +133,7 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
my_off_t offset, myf MyFlags)
{
- size_t writenbytes, written;
+ size_t writtenbytes, written;
uint errors;
#ifndef DBUG_OFF
char llbuf[22];
@@ -156,28 +149,22 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
for (;;)
{
-#ifndef HAVE_PREAD
- int error;
- writenbytes= (size_t) -1;
- pthread_mutex_lock(&my_file_info[Filedes].mutex);
- error= (lseek(Filedes, offset, MY_SEEK_SET) != (my_off_t) -1 &&
- (writenbytes = write(Filedes, Buffer, (uint) Count)) == Count);
- pthread_mutex_unlock(&my_file_info[Filedes].mutex);
- if (error)
- break;
+#ifdef _WIN32
+ writtenbytes= my_win_pwrite(Filedes, Buffer, Count,offset);
#else
- if ((writenbytes= pwrite(Filedes, Buffer, Count,offset)) == Count)
+ writtenbytes= pwrite(Filedes, Buffer, Count, offset);
+#endif
+ if (writtenbytes == Count)
break;
my_errno= errno;
-#endif
- if (writenbytes != (size_t) -1)
+ if (writtenbytes != (size_t) -1)
{ /* Safegueard */
- written+=writenbytes;
- Buffer+=writenbytes;
- Count-=writenbytes;
- offset+=writenbytes;
+ written+=writtenbytes;
+ Buffer+=writtenbytes;
+ Count-=writtenbytes;
+ offset+=writtenbytes;
}
- DBUG_PRINT("error",("Write only %u bytes", (uint) writenbytes));
+ DBUG_PRINT("error",("Write only %u bytes", (uint) writtenbytes));
#ifndef NO_BACKGROUND
#ifdef THREAD
if (my_thread_var->abort)
@@ -190,7 +177,7 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
errors++;
continue;
}
- if ((writenbytes && writenbytes != (size_t) -1) || my_errno == EINTR)
+ if ((writtenbytes && writtenbytes != (size_t) -1) || my_errno == EINTR)
continue; /* Retry */
#endif
@@ -207,5 +194,5 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
DBUG_EXECUTE_IF("check", my_seek(Filedes, -1, SEEK_SET, MYF(0)););
if (MyFlags & (MY_NABP | MY_FNABP))
DBUG_RETURN(0); /* Want only errors */
- DBUG_RETURN(writenbytes+written); /* purecov: inspected */
+ DBUG_RETURN(writtenbytes+written); /* purecov: inspected */
} /* my_pwrite */
diff --git a/mysys/my_quick.c b/mysys/my_quick.c
index 0ba20a5bdee..b93e7e17224 100644
--- a/mysys/my_quick.c
+++ b/mysys/my_quick.c
@@ -19,11 +19,19 @@
#include "my_nosys.h"
+#ifdef _WIN32
+extern size_t my_win_read(File Filedes,uchar *Buffer,size_t Count);
+#endif
+
size_t my_quick_read(File Filedes,uchar *Buffer,size_t Count,myf MyFlags)
{
size_t readbytes;
-
- if ((readbytes = read(Filedes, Buffer, (uint) Count)) != Count)
+#ifdef _WIN32
+ readbytes= my_win_read(Filedes, Buffer, Count);
+#else
+ readbytes= read(Filedes, Buffer, Count);
+#endif
+ if(readbytes != Count)
{
#ifndef DBUG_OFF
if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR)
@@ -40,8 +48,13 @@ size_t my_quick_read(File Filedes,uchar *Buffer,size_t Count,myf MyFlags)
}
-size_t my_quick_write(File Filedes,const uchar *Buffer,size_t Count)
+
+size_t my_quick_write(File Filedes, const uchar *Buffer, size_t Count)
{
+#ifdef _WIN32
+ return my_win_write(Filedes, Buffer, Count);
+#else
+
#ifndef DBUG_OFF
size_t writtenbytes;
#endif
@@ -50,7 +63,7 @@ size_t my_quick_write(File Filedes,const uchar *Buffer,size_t Count)
#ifndef DBUG_OFF
writtenbytes =
#endif
- (size_t) write(Filedes,Buffer, (uint) Count)) != Count)
+ (size_t) write(Filedes,Buffer,Count)) != Count)
{
#ifndef DBUG_OFF
if ((writtenbytes == 0 || writtenbytes == (size_t) -1) && errno == EINTR)
@@ -64,4 +77,5 @@ size_t my_quick_write(File Filedes,const uchar *Buffer,size_t Count)
return (size_t) -1;
}
return 0;
+#endif
}
diff --git a/mysys/my_read.c b/mysys/my_read.c
index e2023b14337..8ababb31324 100644
--- a/mysys/my_read.c
+++ b/mysys/my_read.c
@@ -46,7 +46,12 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
for (;;)
{
errno= 0; /* Linux, Windows don't reset this on EOF/success */
- if ((readbytes= read(Filedes, Buffer, (uint) Count)) != Count)
+#ifdef _WIN32
+ readbytes= my_win_read(Filedes, Buffer, Count);
+#else
+ readbytes= read(Filedes, Buffer, Count);
+#endif
+ if (readbytes != Count)
{
my_errno= errno;
if (errno == 0 || (readbytes != (size_t) -1 &&
diff --git a/mysys/my_seek.c b/mysys/my_seek.c
index 61c4bbd3f73..bdaf91ccc5a 100644
--- a/mysys/my_seek.c
+++ b/mysys/my_seek.c
@@ -58,16 +58,11 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags)
Make sure we are using a valid file descriptor!
*/
DBUG_ASSERT(fd != -1);
-#if defined(THREAD) && !defined(HAVE_PREAD)
- if (MyFlags & MY_THREADSAFE)
- {
- pthread_mutex_lock(&my_file_info[fd].mutex);
- newpos= lseek(fd, pos, whence);
- pthread_mutex_unlock(&my_file_info[fd].mutex);
- }
- else
+#ifdef _WIN32
+ newpos= my_win_lseek(fd, pos, whence);
+#else
+ newpos= lseek(fd, pos, whence);
#endif
- newpos= lseek(fd, pos, whence);
if (newpos == (os_off_t) -1)
{
my_errno= errno;
@@ -93,7 +88,9 @@ my_off_t my_tell(File fd, myf MyFlags)
DBUG_ENTER("my_tell");
DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags));
DBUG_ASSERT(fd >= 0);
-#ifdef HAVE_TELL
+#ifdef _WIN32
+ pos= my_seek(fd, 0, MY_SEEK_CUR,0);
+#elif defined(HAVE_TELL)
pos=tell(fd);
#else
pos=lseek(fd, 0L, MY_SEEK_CUR);
diff --git a/mysys/my_static.c b/mysys/my_static.c
index 404ed477cb9..dd4e4f225c3 100644
--- a/mysys/my_static.c
+++ b/mysys/my_static.c
@@ -40,7 +40,7 @@ my_bool my_assert_on_error= 0;
#ifndef THREAD
int NEAR my_errno=0;
#endif
-struct st_my_file_info my_file_info_default[MY_NFILE]= {{0,UNOPEN}};
+struct st_my_file_info my_file_info_default[MY_NFILE];
uint my_file_limit= MY_NFILE;
struct st_my_file_info *my_file_info= my_file_info_default;
@@ -117,11 +117,6 @@ const char *(*proc_info_hook)(void *, const char *, const char *, const char *,
void (*debug_sync_C_callback_ptr)(const char *, size_t);
#endif /* defined(ENABLED_DEBUG_SYNC) */
-#ifdef __WIN__
-/* from my_getsystime.c */
-ulonglong query_performance_frequency, query_performance_offset;
-#endif
-
/* How to disable options */
my_bool NEAR my_disable_locking=0;
my_bool NEAR my_disable_sync=0;
diff --git a/mysys/my_static.h b/mysys/my_static.h
index 90168b099a8..5e853c2a559 100644
--- a/mysys/my_static.h
+++ b/mysys/my_static.h
@@ -66,8 +66,6 @@ extern struct st_irem *sf_malloc_root;
extern struct st_my_file_info my_file_info_default[MY_NFILE];
-extern ulonglong query_performance_frequency, query_performance_offset;
-
#if defined(THREAD) && !defined(__WIN__)
extern sigset_t my_signals; /* signals blocked by mf_brkhant */
#endif
diff --git a/mysys/my_sync.c b/mysys/my_sync.c
index 700574cd5dd..33033ff1045 100644
--- a/mysys/my_sync.c
+++ b/mysys/my_sync.c
@@ -39,6 +39,13 @@ ulong my_sync_count; /* Count number of sync calls */
(which is correct behaviour, if we know that the other thread synced the
file before closing)
+ MY_SYNC_FILESIZE is useful when syncing a file after it has been extended.
+ On Linux, fdatasync() on ext3/ext4 file systems does not properly flush
+ to disk the inode data required to preserve the added data across a crash
+ (this looks to be a bug). But when a file is extended, inode data will most
+ likely need flushing in any case, so passing MY_SYNC_FILESIZE as flags
+ is not likely to be any slower, and will be crash safe on Linux ext3/ext4.
+
RETURN
0 ok
-1 error
@@ -67,17 +74,24 @@ int my_sync(File fd, myf my_flags)
DBUG_PRINT("info",("fcntl(F_FULLFSYNC) failed, falling back"));
#endif
#if defined(HAVE_FDATASYNC) && HAVE_DECL_FDATASYNC
- res= fdatasync(fd);
-#elif defined(HAVE_FSYNC)
+ if (!(my_flags & MY_SYNC_FILESIZE))
+ res= fdatasync(fd);
+ else
+ {
+#endif
+#if defined(HAVE_FSYNC)
res= fsync(fd);
if (res == -1 && errno == ENOLCK)
res= 0; /* Result Bug in Old FreeBSD */
#elif defined(__WIN__)
- res= _commit(fd);
+ res= my_win_fsync(fd);
#else
#error Cannot find a way to sync a file, durability in danger
res= 0; /* No sync (strange OS) */
#endif
+#if defined(HAVE_FDATASYNC) && HAVE_DECL_FDATASYNC
+ }
+#endif
} while (res == -1 && errno == EINTR);
if (res)
diff --git a/mysys/my_uuid.c b/mysys/my_uuid.c
index e2372391b06..3df2dda2af5 100644
--- a/mysys/my_uuid.c
+++ b/mysys/my_uuid.c
@@ -47,6 +47,7 @@ static my_bool my_uuid_inited= 0;
static struct my_rnd_struct uuid_rand;
static uint nanoseq;
static ulonglong uuid_time= 0;
+static longlong interval_timer_offset;
static uchar uuid_suffix[2+6]; /* clock_seq and node */
#ifdef THREAD
@@ -70,6 +71,8 @@ static void set_clock_seq()
{
uint16 clock_seq= ((uint)(my_rnd(&uuid_rand)*16383)) | UUID_VARIANT;
mi_int2store(uuid_suffix, clock_seq);
+ interval_timer_offset= (my_hrtime().val * 10 - my_interval_timer()/100 +
+ UUID_TIME_OFFSET);
}
@@ -93,7 +96,7 @@ void my_uuid_init(ulong seed1, ulong seed2)
if (my_uuid_inited)
return;
my_uuid_inited= 1;
- now= my_getsystime();
+ now= my_interval_timer()/100 + interval_timer_offset;
nanoseq= 0;
if (my_gethwaddr(mac))
@@ -134,7 +137,7 @@ void my_uuid(uchar *to)
DBUG_ASSERT(my_uuid_inited);
pthread_mutex_lock(&LOCK_uuid_generator);
- tv= my_getsystime() + UUID_TIME_OFFSET + nanoseq;
+ tv= my_interval_timer()/100 + interval_timer_offset + nanoseq;
if (likely(tv > uuid_time))
{
@@ -187,7 +190,7 @@ void my_uuid(uchar *to)
irrelevant in the new numberspace.
*/
set_clock_seq();
- tv= my_getsystime() + UUID_TIME_OFFSET;
+ tv= my_interval_timer()/100 + interval_timer_offset;
nanoseq= 0;
DBUG_PRINT("uuid",("making new numberspace"));
}
@@ -228,7 +231,8 @@ void my_uuid2str(const uchar *guid, char *s)
{
*s++= _dig_vec_lower[guid[i] >>4];
*s++= _dig_vec_lower[guid[i] & 15];
- if(i == 3 || i == 5 || i == 7 || i == 9)
+ /* Set '-' at intervals 3, 5, 7 and 9 */
+ if ((1 << i) & ((1 << 3) | (1 << 5) | (1 << 7) | (1 << 9)))
*s++= '-';
}
}
diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c
index abe339d63b1..64cd67bf8d9 100644
--- a/mysys/my_wincond.c
+++ b/mysys/my_wincond.c
@@ -29,7 +29,92 @@
#include <process.h>
#include <sys/timeb.h>
-int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
+
+/*
+ Windows native condition variables. We use runtime loading / function
+ pointers, because they are not available on XP
+*/
+
+/* Prototypes and function pointers for condition variable functions */
+typedef void (WINAPI * InitializeConditionVariableProc)
+ (PCONDITION_VARIABLE ConditionVariable);
+
+typedef BOOL (WINAPI * SleepConditionVariableCSProc)
+ (PCONDITION_VARIABLE ConditionVariable,
+ PCRITICAL_SECTION CriticalSection,
+ DWORD dwMilliseconds);
+
+typedef void (WINAPI * WakeAllConditionVariableProc)
+ (PCONDITION_VARIABLE ConditionVariable);
+
+typedef void (WINAPI * WakeConditionVariableProc)
+ (PCONDITION_VARIABLE ConditionVariable);
+
+static InitializeConditionVariableProc my_InitializeConditionVariable;
+static SleepConditionVariableCSProc my_SleepConditionVariableCS;
+static WakeAllConditionVariableProc my_WakeAllConditionVariable;
+static WakeConditionVariableProc my_WakeConditionVariable;
+
+
+/**
+ Indicates if we have native condition variables,
+ initialized first time pthread_cond_init is called.
+*/
+
+static BOOL have_native_conditions= FALSE;
+
+
+/**
+ Check if native conditions can be used, load function pointers
+*/
+
+static void check_native_cond_availability(void)
+{
+ HMODULE module= GetModuleHandle("kernel32");
+
+ my_InitializeConditionVariable= (InitializeConditionVariableProc)
+ GetProcAddress(module, "InitializeConditionVariable");
+ my_SleepConditionVariableCS= (SleepConditionVariableCSProc)
+ GetProcAddress(module, "SleepConditionVariableCS");
+ my_WakeAllConditionVariable= (WakeAllConditionVariableProc)
+ GetProcAddress(module, "WakeAllConditionVariable");
+ my_WakeConditionVariable= (WakeConditionVariableProc)
+ GetProcAddress(module, "WakeConditionVariable");
+
+ if (my_InitializeConditionVariable)
+ have_native_conditions= TRUE;
+}
+
+
+
+/**
+ Convert abstime to milliseconds
+*/
+
+static DWORD get_milliseconds(const struct timespec *abstime)
+{
+ struct timespec current_time;
+ long long ms;
+
+ if (abstime == NULL)
+ return INFINITE;
+
+ set_timespec_nsec(current_time, 0);
+ ms= (abstime->tv_sec - current_time.tv_sec)*1000LL +
+ (abstime->tv_nsec - current_time.tv_nsec)/1000000LL;
+ if(ms < 0 )
+ ms= 0;
+ if(ms > UINT_MAX)
+ ms= INFINITE;
+ return (DWORD)ms;
+}
+
+
+/*
+ Old (pre-vista) implementation using events
+*/
+
+static int legacy_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
{
cond->waiting= 0;
InitializeCriticalSection(&cond->lock_waiting);
@@ -58,7 +143,8 @@ int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
return 0;
}
-int pthread_cond_destroy(pthread_cond_t *cond)
+
+static int legacy_cond_destroy(pthread_cond_t *cond)
{
DeleteCriticalSection(&cond->lock_waiting);
@@ -70,41 +156,26 @@ int pthread_cond_destroy(pthread_cond_t *cond)
}
-int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
-{
- return pthread_cond_timedwait(cond,mutex,NULL);
-}
-
-
-int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
+static int legacy_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
struct timespec *abstime)
{
int result;
- long timeout;
- union ft64 now;
-
+ DWORD timeout;
+ long long timeout_us;
+ my_hrtime_t now;
+ my_hrtime_t then;
if( abstime != NULL )
{
- GetSystemTimeAsFileTime(&now.ft);
-
- /*
- Calculate time left to abstime
- - subtract start time from current time(values are in 100ns units)
- - convert to millisec by dividing with 10000
- */
- timeout= (long)((abstime->tv.i64 - now.i64) / 10000);
-
- /* Don't allow the timeout to be negative */
- if (timeout < 0)
- timeout= 0L;
-
- /*
- Make sure the calucated timeout does not exceed original timeout
- value which could cause "wait for ever" if system time changes
- */
- if (timeout > abstime->max_timeout_msec)
- timeout= abstime->max_timeout_msec;
-
+ now= my_hrtime();
+ then.val= 1000000ULL*abstime->tv_sec + abstime->tv_nsec/1000;
+ timeout_us= then.val - now.val;
+
+ if (timeout_us < 0)
+ timeout= 0;
+ else if (timeout_us > 1000ULL*INFINITE)
+ timeout= INFINITE;
+ else
+ timeout= (DWORD)(timeout_us/1000);
}
else
{
@@ -147,7 +218,7 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
return result == WAIT_TIMEOUT ? ETIMEDOUT : 0;
}
-int pthread_cond_signal(pthread_cond_t *cond)
+static int legacy_cond_signal(pthread_cond_t *cond)
{
EnterCriticalSection(&cond->lock_waiting);
@@ -160,7 +231,7 @@ int pthread_cond_signal(pthread_cond_t *cond)
}
-int pthread_cond_broadcast(pthread_cond_t *cond)
+static int legacy_cond_broadcast(pthread_cond_t *cond)
{
EnterCriticalSection(&cond->lock_waiting);
/*
@@ -182,6 +253,87 @@ int pthread_cond_broadcast(pthread_cond_t *cond)
}
+/*
+ Posix API functions. Just choose between native and legacy implementation.
+*/
+
+int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
+{
+ /*
+ Once initialization is used here rather than in my_init(), to
+ 1) avoid my_init() pitfalls- undefined order in which initialization should
+ run
+ 2) be potentially useful C++ (in static constructors that run before main())
+ 3) just to simplify the API.
+ Also, the overhead of my_pthread_once is very small.
+ */
+ static my_pthread_once_t once_control= MY_PTHREAD_ONCE_INIT;
+ my_pthread_once(&once_control, check_native_cond_availability);
+
+ if (have_native_conditions)
+ {
+ my_InitializeConditionVariable(&cond->native_cond);
+ return 0;
+ }
+ else
+ return legacy_cond_init(cond, attr);
+}
+
+
+int pthread_cond_destroy(pthread_cond_t *cond)
+{
+ if (have_native_conditions)
+ return 0; /* no destroy function */
+ else
+ return legacy_cond_destroy(cond);
+}
+
+
+int pthread_cond_broadcast(pthread_cond_t *cond)
+{
+ if (have_native_conditions)
+ {
+ my_WakeAllConditionVariable(&cond->native_cond);
+ return 0;
+ }
+ else
+ return legacy_cond_broadcast(cond);
+}
+
+
+int pthread_cond_signal(pthread_cond_t *cond)
+{
+ if (have_native_conditions)
+ {
+ my_WakeConditionVariable(&cond->native_cond);
+ return 0;
+ }
+ else
+ return legacy_cond_signal(cond);
+}
+
+
+int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
+ struct timespec *abstime)
+{
+ if (have_native_conditions)
+ {
+ DWORD timeout= get_milliseconds(abstime);
+ if (!my_SleepConditionVariableCS(&cond->native_cond, mutex, timeout))
+ return ETIMEDOUT;
+ return 0;
+ }
+ else
+ return legacy_cond_timedwait(cond, mutex, abstime);
+}
+
+
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+ return pthread_cond_timedwait(cond, mutex, NULL);
+}
+
+
int pthread_attr_init(pthread_attr_t *connect_att)
{
connect_att->dwStackSize = 0;
diff --git a/mysys/my_winerr.c b/mysys/my_winerr.c
new file mode 100644
index 00000000000..534078b6737
--- /dev/null
+++ b/mysys/my_winerr.c
@@ -0,0 +1,123 @@
+/* Copyright (C) 2008 MySQL AB
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Convert Windows API error (GetLastError() to Posix equivalent (errno)
+ The exported function my_osmaperr() is modelled after and borrows
+ heavily from undocumented _dosmaperr()(found of the static Microsoft C runtime).
+*/
+
+#include <my_global.h>
+#include <my_sys.h>
+
+
+struct errentry
+{
+ unsigned long oscode; /* OS return value */
+ int sysv_errno; /* System V error code */
+};
+
+static struct errentry errtable[]= {
+ { ERROR_INVALID_FUNCTION, EINVAL }, /* 1 */
+ { ERROR_FILE_NOT_FOUND, ENOENT }, /* 2 */
+ { ERROR_PATH_NOT_FOUND, ENOENT }, /* 3 */
+ { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, /* 4 */
+ { ERROR_ACCESS_DENIED, EACCES }, /* 5 */
+ { ERROR_INVALID_HANDLE, EBADF }, /* 6 */
+ { ERROR_ARENA_TRASHED, ENOMEM }, /* 7 */
+ { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, /* 8 */
+ { ERROR_INVALID_BLOCK, ENOMEM }, /* 9 */
+ { ERROR_BAD_ENVIRONMENT, E2BIG }, /* 10 */
+ { ERROR_BAD_FORMAT, ENOEXEC }, /* 11 */
+ { ERROR_INVALID_ACCESS, EINVAL }, /* 12 */
+ { ERROR_INVALID_DATA, EINVAL }, /* 13 */
+ { ERROR_INVALID_DRIVE, ENOENT }, /* 15 */
+ { ERROR_CURRENT_DIRECTORY, EACCES }, /* 16 */
+ { ERROR_NOT_SAME_DEVICE, EXDEV }, /* 17 */
+ { ERROR_NO_MORE_FILES, ENOENT }, /* 18 */
+ { ERROR_LOCK_VIOLATION, EACCES }, /* 33 */
+ { ERROR_BAD_NETPATH, ENOENT }, /* 53 */
+ { ERROR_NETWORK_ACCESS_DENIED, EACCES }, /* 65 */
+ { ERROR_BAD_NET_NAME, ENOENT }, /* 67 */
+ { ERROR_FILE_EXISTS, EEXIST }, /* 80 */
+ { ERROR_CANNOT_MAKE, EACCES }, /* 82 */
+ { ERROR_FAIL_I24, EACCES }, /* 83 */
+ { ERROR_INVALID_PARAMETER, EINVAL }, /* 87 */
+ { ERROR_NO_PROC_SLOTS, EAGAIN }, /* 89 */
+ { ERROR_DRIVE_LOCKED, EACCES }, /* 108 */
+ { ERROR_BROKEN_PIPE, EPIPE }, /* 109 */
+ { ERROR_DISK_FULL, ENOSPC }, /* 112 */
+ { ERROR_INVALID_TARGET_HANDLE, EBADF }, /* 114 */
+ { ERROR_INVALID_HANDLE, EINVAL }, /* 124 */
+ { ERROR_WAIT_NO_CHILDREN, ECHILD }, /* 128 */
+ { ERROR_CHILD_NOT_COMPLETE, ECHILD }, /* 129 */
+ { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, /* 130 */
+ { ERROR_NEGATIVE_SEEK, EINVAL }, /* 131 */
+ { ERROR_SEEK_ON_DEVICE, EACCES }, /* 132 */
+ { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, /* 145 */
+ { ERROR_NOT_LOCKED, EACCES }, /* 158 */
+ { ERROR_BAD_PATHNAME, ENOENT }, /* 161 */
+ { ERROR_MAX_THRDS_REACHED, EAGAIN }, /* 164 */
+ { ERROR_LOCK_FAILED, EACCES }, /* 167 */
+ { ERROR_ALREADY_EXISTS, EEXIST }, /* 183 */
+ { ERROR_FILENAME_EXCED_RANGE, ENOENT }, /* 206 */
+ { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, /* 215 */
+ { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } /* 1816 */
+};
+
+/* size of the table */
+#define ERRTABLESIZE (sizeof(errtable)/sizeof(errtable[0]))
+
+/* The following two constants must be the minimum and maximum
+values in the (contiguous) range of Exec Failure errors. */
+#define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
+#define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
+
+/* These are the low and high value in the range of errors that are
+access violations */
+#define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
+#define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
+
+
+static int get_errno_from_oserr(unsigned long oserrno)
+{
+ int i;
+
+ /* check the table for the OS error code */
+ for (i= 0; i < ERRTABLESIZE; ++i)
+ {
+ if (oserrno == errtable[i].oscode)
+ {
+ return errtable[i].sysv_errno;
+ }
+ }
+
+ /* The error code wasn't in the table. We check for a range of */
+ /* EACCES errors or exec failure errors (ENOEXEC). Otherwise */
+ /* EINVAL is returned. */
+
+ if (oserrno >= MIN_EACCES_RANGE && oserrno <= MAX_EACCES_RANGE)
+ return EACCES;
+ else if (oserrno >= MIN_EXEC_ERROR && oserrno <= MAX_EXEC_ERROR)
+ return ENOEXEC;
+ else
+ return EINVAL;
+}
+
+/* Set errno corresponsing to GetLastError() value */
+void my_osmaperr ( unsigned long oserrno)
+{
+ errno= get_errno_from_oserr(oserrno);
+}
diff --git a/mysys/my_winfile.c b/mysys/my_winfile.c
new file mode 100644
index 00000000000..f63c35ba47b
--- /dev/null
+++ b/mysys/my_winfile.c
@@ -0,0 +1,681 @@
+/* Copyright (C) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ The purpose of this file is to provide implementation of file IO routines on
+ Windows that can be thought as drop-in replacement for corresponding C runtime
+ functionality.
+
+ Compared to Windows CRT, this one
+ - does not have the same file descriptor
+ limitation (default is 16384 and can be increased further, whereas CRT poses
+ a hard limit of 2048 file descriptors)
+ - the file operations are not serialized
+ - positional IO pread/pwrite is ported here.
+ - no text mode for files, all IO is "binary"
+
+ Naming convention:
+ All routines are prefixed with my_win_, e.g Posix open() is implemented with
+ my_win_open()
+
+ Implemented are
+ - POSIX routines(e.g open, read, lseek ...)
+ - Some ANSI C stream routines (fopen, fdopen, fileno, fclose)
+ - Windows CRT equvalients (my_get_osfhandle, open_osfhandle)
+
+ Worth to note:
+ - File descriptors used here are located in a range that is not compatible
+ with CRT on purpose. Attempt to use a file descriptor from Windows CRT library
+ range in my_win_* function will be punished with DBUG_ASSERT()
+
+ - File streams (FILE *) are actually from the C runtime. The routines provided
+ here are useful only in scernarios that use low-level IO with my_win_fileno()
+*/
+
+#ifdef _WIN32
+
+#include "mysys_priv.h"
+#include <share.h>
+#include <sys/stat.h>
+
+/* Associates a file descriptor with an existing operating-system file handle.*/
+File my_open_osfhandle(HANDLE handle, int oflag)
+{
+ int offset= -1;
+ uint i;
+ DBUG_ENTER("my_open_osfhandle");
+
+ pthread_mutex_lock(&THR_LOCK_open);
+ for(i= MY_FILE_MIN; i < my_file_limit;i++)
+ {
+ if(my_file_info[i].fhandle == 0)
+ {
+ struct st_my_file_info *finfo= &(my_file_info[i]);
+ finfo->type= FILE_BY_OPEN;
+ finfo->fhandle= handle;
+ finfo->oflag= oflag;
+ offset= i;
+ break;
+ }
+ }
+ pthread_mutex_unlock(&THR_LOCK_open);
+ if(offset == -1)
+ errno= EMFILE; /* to many file handles open */
+ DBUG_RETURN(offset);
+}
+
+
+static void invalidate_fd(File fd)
+{
+ DBUG_ENTER("invalidate_fd");
+ DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit);
+ my_file_info[fd].fhandle= 0;
+ DBUG_VOID_RETURN;
+}
+
+
+/* Get Windows handle for a file descriptor */
+HANDLE my_get_osfhandle(File fd)
+{
+ DBUG_ENTER("my_get_osfhandle");
+ DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit);
+ DBUG_RETURN(my_file_info[fd].fhandle);
+}
+
+
+static int my_get_open_flags(File fd)
+{
+ DBUG_ENTER("my_get_open_flags");
+ DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit);
+ DBUG_RETURN(my_file_info[fd].oflag);
+}
+
+
+/*
+ Open a file with sharing. Similar to _sopen() from libc, but allows managing
+ share delete on win32
+
+ SYNOPSIS
+ my_win_sopen()
+ path file name
+ oflag operation flags
+ shflag share flag
+ pmode permission flags
+
+ RETURN VALUE
+ File descriptor of opened file if success
+ -1 and sets errno if fails.
+*/
+
+File my_win_sopen(const char *path, int oflag, int shflag, int pmode)
+{
+ int fh; /* handle of opened file */
+ int mask;
+ HANDLE osfh; /* OS handle of opened file */
+ DWORD fileaccess; /* OS file access (requested) */
+ DWORD fileshare; /* OS file sharing mode */
+ DWORD filecreate; /* OS method of opening/creating */
+ DWORD fileattrib; /* OS file attribute flags */
+ SECURITY_ATTRIBUTES SecurityAttributes;
+
+ DBUG_ENTER("my_win_sopen");
+
+ if (check_if_legal_filename(path))
+ {
+ errno= EACCES;
+ DBUG_RETURN(-1);
+ }
+ SecurityAttributes.nLength= sizeof(SecurityAttributes);
+ SecurityAttributes.lpSecurityDescriptor= NULL;
+ SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT);
+
+ /* decode the access flags */
+ switch (oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
+ case _O_RDONLY: /* read access */
+ fileaccess= GENERIC_READ;
+ break;
+ case _O_WRONLY: /* write access */
+ fileaccess= GENERIC_WRITE;
+ break;
+ case _O_RDWR: /* read and write access */
+ fileaccess= GENERIC_READ | GENERIC_WRITE;
+ break;
+ default: /* error, bad oflag */
+ errno= EINVAL;
+ DBUG_RETURN(-1);
+ }
+
+ /* decode sharing flags */
+ switch (shflag) {
+ case _SH_DENYRW: /* exclusive access except delete */
+ fileshare= FILE_SHARE_DELETE;
+ break;
+ case _SH_DENYWR: /* share read and delete access */
+ fileshare= FILE_SHARE_READ | FILE_SHARE_DELETE;
+ break;
+ case _SH_DENYRD: /* share write and delete access */
+ fileshare= FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+ break;
+ case _SH_DENYNO: /* share read, write and delete access */
+ fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+ break;
+ case _SH_DENYRWD: /* exclusive access */
+ fileshare= 0L;
+ break;
+ case _SH_DENYWRD: /* share read access */
+ fileshare= FILE_SHARE_READ;
+ break;
+ case _SH_DENYRDD: /* share write access */
+ fileshare= FILE_SHARE_WRITE;
+ break;
+ case _SH_DENYDEL: /* share read and write access */
+ fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE;
+ break;
+ default: /* error, bad shflag */
+ errno= EINVAL;
+ DBUG_RETURN(-1);
+ }
+
+ /* decode open/create method flags */
+ switch (oflag & (_O_CREAT | _O_EXCL | _O_TRUNC)) {
+ case 0:
+ case _O_EXCL: /* ignore EXCL w/o CREAT */
+ filecreate= OPEN_EXISTING;
+ break;
+
+ case _O_CREAT:
+ filecreate= OPEN_ALWAYS;
+ break;
+
+ case _O_CREAT | _O_EXCL:
+ case _O_CREAT | _O_TRUNC | _O_EXCL:
+ filecreate= CREATE_NEW;
+ break;
+
+ case _O_TRUNC:
+ case _O_TRUNC | _O_EXCL: /* ignore EXCL w/o CREAT */
+ filecreate= TRUNCATE_EXISTING;
+ break;
+
+ case _O_CREAT | _O_TRUNC:
+ filecreate= CREATE_ALWAYS;
+ break;
+
+ default:
+ /* this can't happen ... all cases are covered */
+ errno= EINVAL;
+ DBUG_RETURN(-1);
+ }
+
+ /* decode file attribute flags if _O_CREAT was specified */
+ fileattrib= FILE_ATTRIBUTE_NORMAL; /* default */
+ if (oflag & _O_CREAT)
+ {
+ _umask((mask= _umask(0)));
+
+ if (!((pmode & ~mask) & _S_IWRITE))
+ fileattrib= FILE_ATTRIBUTE_READONLY;
+ }
+
+ /* Set temporary file (delete-on-close) attribute if requested. */
+ if (oflag & _O_TEMPORARY)
+ {
+ fileattrib|= FILE_FLAG_DELETE_ON_CLOSE;
+ fileaccess|= DELETE;
+ }
+
+ /* Set temporary file (delay-flush-to-disk) attribute if requested.*/
+ if (oflag & _O_SHORT_LIVED)
+ fileattrib|= FILE_ATTRIBUTE_TEMPORARY;
+
+ /* Set sequential or random access attribute if requested. */
+ if (oflag & _O_SEQUENTIAL)
+ fileattrib|= FILE_FLAG_SEQUENTIAL_SCAN;
+ else if (oflag & _O_RANDOM)
+ fileattrib|= FILE_FLAG_RANDOM_ACCESS;
+
+ /* try to open/create the file */
+ if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes,
+ filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE)
+ {
+ /*
+ OS call to open/create file failed! map the error, release
+ the lock, and return -1. note that it's not necessary to
+ call _free_osfhnd (it hasn't been used yet).
+ */
+ my_osmaperr(GetLastError()); /* map error */
+ DBUG_RETURN(-1); /* return error to caller */
+ }
+
+ if ((fh= my_open_osfhandle(osfh,
+ oflag & (_O_APPEND | _O_RDONLY | _O_TEXT))) == -1)
+ {
+ CloseHandle(osfh);
+ }
+
+ DBUG_RETURN(fh); /* return handle */
+}
+
+
+File my_win_open(const char *path, int flags)
+{
+ DBUG_ENTER("my_win_open");
+ DBUG_RETURN(my_win_sopen((char *) path, flags | _O_BINARY, _SH_DENYNO,
+ _S_IREAD | S_IWRITE));
+}
+
+
+int my_win_close(File fd)
+{
+ DBUG_ENTER("my_win_close");
+ if(CloseHandle(my_get_osfhandle(fd)))
+ {
+ invalidate_fd(fd);
+ DBUG_RETURN(0);
+ }
+ my_osmaperr(GetLastError());
+ DBUG_RETURN(-1);
+}
+
+
+size_t my_win_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset)
+{
+ DWORD nBytesRead;
+ HANDLE hFile;
+ OVERLAPPED ov= {0};
+ LARGE_INTEGER li;
+
+ DBUG_ENTER("my_win_pread");
+
+ if(!Count)
+ DBUG_RETURN(0);
+#ifdef _WIN64
+ if(Count > UINT_MAX)
+ Count= UINT_MAX;
+#endif
+
+ hFile= (HANDLE)my_get_osfhandle(Filedes);
+ li.QuadPart= offset;
+ ov.Offset= li.LowPart;
+ ov.OffsetHigh= li.HighPart;
+
+ if(!ReadFile(hFile, Buffer, (DWORD)Count, &nBytesRead, &ov))
+ {
+ DWORD lastError= GetLastError();
+ /*
+ ERROR_BROKEN_PIPE is returned when no more data coming
+ through e.g. a command pipe in windows : see MSDN on ReadFile.
+ */
+ if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE)
+ DBUG_RETURN(0); /*return 0 at EOF*/
+ my_osmaperr(lastError);
+ DBUG_RETURN((size_t)-1);
+ }
+ DBUG_RETURN(nBytesRead);
+}
+
+
+size_t my_win_read(File Filedes, uchar *Buffer, size_t Count)
+{
+ DWORD nBytesRead;
+ HANDLE hFile;
+
+ DBUG_ENTER("my_win_read");
+ if(!Count)
+ DBUG_RETURN(0);
+#ifdef _WIN64
+ if(Count > UINT_MAX)
+ Count= UINT_MAX;
+#endif
+
+ hFile= (HANDLE)my_get_osfhandle(Filedes);
+
+ if(!ReadFile(hFile, Buffer, (DWORD)Count, &nBytesRead, NULL))
+ {
+ DWORD lastError= GetLastError();
+ /*
+ ERROR_BROKEN_PIPE is returned when no more data coming
+ through e.g. a command pipe in windows : see MSDN on ReadFile.
+ */
+ if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE)
+ DBUG_RETURN(0); /*return 0 at EOF*/
+ my_osmaperr(lastError);
+ DBUG_RETURN((size_t)-1);
+ }
+ DBUG_RETURN(nBytesRead);
+}
+
+
+size_t my_win_pwrite(File Filedes, const uchar *Buffer, size_t Count,
+ my_off_t offset)
+{
+ DWORD nBytesWritten;
+ HANDLE hFile;
+ OVERLAPPED ov= {0};
+ LARGE_INTEGER li;
+
+ DBUG_ENTER("my_win_pwrite");
+ DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count: %llu, offset: %llu",
+ Filedes, Buffer, (ulonglong)Count, (ulonglong)offset));
+
+ if(!Count)
+ DBUG_RETURN(0);
+
+#ifdef _WIN64
+ if(Count > UINT_MAX)
+ Count= UINT_MAX;
+#endif
+
+ hFile= (HANDLE)my_get_osfhandle(Filedes);
+ li.QuadPart= offset;
+ ov.Offset= li.LowPart;
+ ov.OffsetHigh= li.HighPart;
+
+ if(!WriteFile(hFile, Buffer, (DWORD)Count, &nBytesWritten, &ov))
+ {
+ my_osmaperr(GetLastError());
+ DBUG_RETURN((size_t)-1);
+ }
+ else
+ DBUG_RETURN(nBytesWritten);
+}
+
+
+my_off_t my_win_lseek(File fd, my_off_t pos, int whence)
+{
+ LARGE_INTEGER offset;
+ LARGE_INTEGER newpos;
+
+ DBUG_ENTER("my_win_lseek");
+
+ /* Check compatibility of Windows and Posix seek constants */
+ compile_time_assert(FILE_BEGIN == SEEK_SET && FILE_CURRENT == SEEK_CUR
+ && FILE_END == SEEK_END);
+
+ offset.QuadPart= pos;
+ if(!SetFilePointerEx(my_get_osfhandle(fd), offset, &newpos, whence))
+ {
+ my_osmaperr(GetLastError());
+ newpos.QuadPart= -1;
+ }
+ DBUG_RETURN(newpos.QuadPart);
+}
+
+
+#ifndef FILE_WRITE_TO_END_OF_FILE
+#define FILE_WRITE_TO_END_OF_FILE 0xffffffff
+#endif
+size_t my_win_write(File fd, const uchar *Buffer, size_t Count)
+{
+ DWORD nWritten;
+ OVERLAPPED ov;
+ OVERLAPPED *pov= NULL;
+ HANDLE hFile;
+
+ DBUG_ENTER("my_win_write");
+ DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count %llu", fd, Buffer,
+ (ulonglong)Count));
+
+ if(!Count)
+ DBUG_RETURN(0);
+
+#ifdef _WIN64
+ if(Count > UINT_MAX)
+ Count= UINT_MAX;
+#endif
+
+ if(my_get_open_flags(fd) & _O_APPEND)
+ {
+ /*
+ Atomic append to the end of file is is done by special initialization of
+ the OVERLAPPED structure. See MSDN WriteFile documentation for more info.
+ */
+ memset(&ov, 0, sizeof(ov));
+ ov.Offset= FILE_WRITE_TO_END_OF_FILE;
+ ov.OffsetHigh= -1;
+ pov= &ov;
+ }
+
+ hFile= my_get_osfhandle(fd);
+ if(!WriteFile(hFile, Buffer, (DWORD)Count, &nWritten, pov))
+ {
+ my_osmaperr(GetLastError());
+ DBUG_RETURN((size_t)-1);
+ }
+ DBUG_RETURN(nWritten);
+}
+
+
+int my_win_chsize(File fd, my_off_t newlength)
+{
+ HANDLE hFile;
+ LARGE_INTEGER length;
+ DBUG_ENTER("my_win_chsize");
+
+ hFile= (HANDLE) my_get_osfhandle(fd);
+ length.QuadPart= newlength;
+ if (!SetFilePointerEx(hFile, length , NULL , FILE_BEGIN))
+ goto err;
+ if (!SetEndOfFile(hFile))
+ goto err;
+ DBUG_RETURN(0);
+err:
+ my_osmaperr(GetLastError());
+ my_errno= errno;
+ DBUG_RETURN(-1);
+}
+
+
+/* Get the file descriptor for stdin,stdout or stderr */
+static File my_get_stdfile_descriptor(FILE *stream)
+{
+ HANDLE hFile;
+ DWORD nStdHandle;
+ DBUG_ENTER("my_get_stdfile_descriptor");
+
+ if(stream == stdin)
+ nStdHandle= STD_INPUT_HANDLE;
+ else if(stream == stdout)
+ nStdHandle= STD_OUTPUT_HANDLE;
+ else if(stream == stderr)
+ nStdHandle= STD_ERROR_HANDLE;
+ else
+ DBUG_RETURN(-1);
+
+ hFile= GetStdHandle(nStdHandle);
+ if(hFile != INVALID_HANDLE_VALUE)
+ DBUG_RETURN(my_open_osfhandle(hFile, 0));
+ DBUG_RETURN(-1);
+}
+
+
+File my_win_fileno(FILE *file)
+{
+ HANDLE hFile= (HANDLE)_get_osfhandle(fileno(file));
+ int retval= -1;
+ uint i;
+
+ DBUG_ENTER("my_win_fileno");
+
+ for(i= MY_FILE_MIN; i < my_file_limit; i++)
+ {
+ if(my_file_info[i].fhandle == hFile)
+ {
+ retval= i;
+ break;
+ }
+ }
+ if(retval == -1)
+ /* try std stream */
+ DBUG_RETURN(my_get_stdfile_descriptor(file));
+ DBUG_RETURN(retval);
+}
+
+
+FILE *my_win_fopen(const char *filename, const char *type)
+{
+ FILE *file;
+ int flags= 0;
+ DBUG_ENTER("my_win_open");
+
+ /*
+ If we are not creating, then we need to use my_access to make sure
+ the file exists since Windows doesn't handle files like "com1.sym"
+ very well
+ */
+ if (check_if_legal_filename(filename))
+ {
+ errno= EACCES;
+ DBUG_RETURN(NULL);
+ }
+
+ file= fopen(filename, type);
+ if(!file)
+ DBUG_RETURN(NULL);
+
+ if(strchr(type,'a') != NULL)
+ flags= O_APPEND;
+
+ /*
+ Register file handle in my_table_info.
+ Necessary for my_fileno()
+ */
+ if(my_open_osfhandle((HANDLE)_get_osfhandle(fileno(file)), flags) < 0)
+ {
+ fclose(file);
+ DBUG_RETURN(NULL);
+ }
+ DBUG_RETURN(file);
+}
+
+
+FILE * my_win_fdopen(File fd, const char *type)
+{
+ FILE *file;
+ int crt_fd;
+ int flags= 0;
+
+ DBUG_ENTER("my_win_fdopen");
+
+ if(strchr(type,'a') != NULL)
+ flags= O_APPEND;
+ /* Convert OS file handle to CRT file descriptor and then call fdopen*/
+ crt_fd= _open_osfhandle((intptr_t)my_get_osfhandle(fd), flags);
+ if(crt_fd < 0)
+ file= NULL;
+ else
+ file= fdopen(crt_fd, type);
+ DBUG_RETURN(file);
+}
+
+
+int my_win_fclose(FILE *file)
+{
+ File fd;
+
+ DBUG_ENTER("my_win_close");
+ fd= my_fileno(file);
+ if(fd < 0)
+ DBUG_RETURN(-1);
+ if(fclose(file) < 0)
+ DBUG_RETURN(-1);
+ invalidate_fd(fd);
+ DBUG_RETURN(0);
+}
+
+
+
+/*
+ Quick and dirty my_fstat() implementation for Windows.
+ Use CRT fstat on temporarily allocated file descriptor.
+ Patch file size, because size that fstat returns is not
+ reliable (may be outdated)
+*/
+int my_win_fstat(File fd, struct _stati64 *buf)
+{
+ int crt_fd;
+ int retval;
+ HANDLE hFile, hDup;
+
+ DBUG_ENTER("my_win_fstat");
+
+ hFile= my_get_osfhandle(fd);
+ if(!DuplicateHandle( GetCurrentProcess(), hFile, GetCurrentProcess(),
+ &hDup ,0,FALSE,DUPLICATE_SAME_ACCESS))
+ {
+ my_osmaperr(GetLastError());
+ DBUG_RETURN(-1);
+ }
+ if ((crt_fd= _open_osfhandle((intptr_t)hDup,0)) < 0)
+ DBUG_RETURN(-1);
+
+ retval= _fstati64(crt_fd, buf);
+ if(retval == 0)
+ {
+ /* File size returned by stat is not accurate (may be outdated), fix it*/
+ GetFileSizeEx(hDup, (PLARGE_INTEGER) (&(buf->st_size)));
+ }
+ _close(crt_fd);
+ DBUG_RETURN(retval);
+}
+
+
+
+int my_win_stat( const char *path, struct _stati64 *buf)
+{
+ DBUG_ENTER("my_win_stat");
+ if(_stati64( path, buf) == 0)
+ {
+ /* File size returned by stat is not accurate (may be outdated), fix it*/
+ WIN32_FILE_ATTRIBUTE_DATA data;
+ if (GetFileAttributesEx(path, GetFileExInfoStandard, &data))
+ {
+ LARGE_INTEGER li;
+ li.LowPart= data.nFileSizeLow;
+ li.HighPart= data.nFileSizeHigh;
+ buf->st_size= li.QuadPart;
+ }
+ DBUG_RETURN(0);
+ }
+ DBUG_RETURN(-1);
+}
+
+
+
+int my_win_fsync(File fd)
+{
+ DBUG_ENTER("my_win_fsync");
+ if(FlushFileBuffers(my_get_osfhandle(fd)))
+ DBUG_RETURN(0);
+ my_osmaperr(GetLastError());
+ DBUG_RETURN(-1);
+}
+
+
+
+int my_win_dup(File fd)
+{
+ HANDLE hDup;
+ DBUG_ENTER("my_win_dup");
+ if (DuplicateHandle(GetCurrentProcess(), my_get_osfhandle(fd),
+ GetCurrentProcess(), &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
+ {
+ DBUG_RETURN(my_open_osfhandle(hDup, my_get_open_flags(fd)));
+ }
+ my_osmaperr(GetLastError());
+ DBUG_RETURN(-1);
+}
+
+#endif /*_WIN32*/
diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c
index 2632f575a7b..7a22027d6a5 100644
--- a/mysys/my_winthread.c
+++ b/mysys/my_winthread.c
@@ -159,8 +159,19 @@ int win_pthread_setspecific(void *a,void *b,uint length)
int my_pthread_once(my_pthread_once_t *once_control,
void (*init_routine)(void))
{
- LONG state= InterlockedCompareExchange(once_control, MY_PTHREAD_ONCE_INPROGRESS,
- MY_PTHREAD_ONCE_INIT);
+ LONG state;
+
+ /*
+ Do "dirty" read to find out if initialization is already done, to
+ save an interlocked operation in common case. Memory barriers are ensured by
+ Visual C++ volatile implementation.
+ */
+ if (*once_control == MY_PTHREAD_ONCE_DONE)
+ return 0;
+
+ state= InterlockedCompareExchange(once_control, MY_PTHREAD_ONCE_INPROGRESS,
+ MY_PTHREAD_ONCE_INIT);
+
switch(state)
{
case MY_PTHREAD_ONCE_INIT:
diff --git a/mysys/my_write.c b/mysys/my_write.c
index e1237e62bee..67fe04a69d7 100644
--- a/mysys/my_write.c
+++ b/mysys/my_write.c
@@ -25,7 +25,7 @@
size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
{
- size_t writenbytes, written;
+ size_t writtenbytes, written;
uint errors;
DBUG_ENTER("my_write");
DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
@@ -40,7 +40,17 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
for (;;)
{
- writenbytes= write(Filedes, Buffer, Count);
+#ifdef _WIN32
+ if(Filedes < 0)
+ {
+ my_errno= errno= EBADF;
+ DBUG_RETURN((size_t)-1);
+ }
+ writtenbytes= my_win_write(Filedes, Buffer, Count);
+#else
+ writtenbytes= write(Filedes, Buffer, Count);
+#endif
+
/**
To simulate the write error set the errno = error code
and the number pf written bytes to -1.
@@ -48,19 +58,20 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
DBUG_EXECUTE_IF ("simulate_file_write_error",
if (!errors) {
errno= ENOSPC;
- writenbytes= (size_t) -1;
+ writtenbytes= (size_t) -1;
});
- if (writenbytes == Count)
+
+ if (writtenbytes == Count)
break;
- if (writenbytes != (size_t) -1)
+ if (writtenbytes != (size_t) -1)
{ /* Safeguard */
- written+=writenbytes;
- Buffer+=writenbytes;
- Count-=writenbytes;
+ written+= writtenbytes;
+ Buffer+= writtenbytes;
+ Count-= writtenbytes;
}
- my_errno=errno;
+ my_errno= errno;
DBUG_PRINT("error",("Write only %ld bytes, error: %d",
- (long) writenbytes, my_errno));
+ (long) writtenbytes, my_errno));
#ifndef NO_BACKGROUND
#ifdef THREAD
if (my_thread_var->abort)
@@ -74,19 +85,19 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
continue;
}
- if ((writenbytes == 0 || writenbytes == (size_t) -1))
+ if ((writtenbytes == 0 || writtenbytes == (size_t) -1))
{
if (my_errno == EINTR)
{
DBUG_PRINT("debug", ("my_write() was interrupted and returned %ld",
- (long) writenbytes));
+ (long) writtenbytes));
continue; /* Interrupted */
}
- if (!writenbytes && !errors++) /* Retry once */
+ if (!writtenbytes && !errors++) /* Retry once */
{
/* We may come here if the file quota is exeeded */
- errno=EFBIG; /* Assume this is the error */
+ errno= EFBIG; /* Assume this is the error */
continue;
}
}
@@ -108,5 +119,5 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
}
if (MyFlags & (MY_NABP | MY_FNABP))
DBUG_RETURN(0); /* Want only errors */
- DBUG_RETURN(writenbytes+written);
+ DBUG_RETURN(writtenbytes+written);
} /* my_write */
diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h
index 113b64005f2..6d39999aa86 100644
--- a/mysys/mysys_priv.h
+++ b/mysys/mysys_priv.h
@@ -45,3 +45,27 @@ extern pthread_mutex_t THR_LOCK_charset, THR_LOCK_time;
void my_error_unregister_all(void);
void my_thread_destroy_mutex(void);
my_bool my_wait_for_other_threads_to_die(uint number_of_threads);
+
+#ifdef _WIN32
+/* my_winfile.c exports, should not be used outside mysys */
+extern File my_win_open(const char *path, int oflag);
+extern int my_win_close(File fd);
+extern size_t my_win_read(File fd, uchar *buffer, size_t count);
+extern size_t my_win_write(File fd, const uchar *buffer, size_t count);
+extern size_t my_win_pread(File fd, uchar *buffer, size_t count,
+ my_off_t offset);
+extern size_t my_win_pwrite(File fd, const uchar *buffer, size_t count,
+ my_off_t offset);
+extern my_off_t my_win_lseek(File fd, my_off_t pos, int whence);
+extern int my_win_chsize(File fd, my_off_t newlength);
+extern FILE* my_win_fopen(const char *filename, const char *type);
+extern File my_win_fclose(FILE *file);
+extern File my_win_fileno(FILE *file);
+extern FILE* my_win_fdopen(File Filedes, const char *type);
+extern int my_win_stat(const char *path, struct _stat64 *buf);
+extern int my_win_fstat(File fd, struct _stat64 *buf);
+extern int my_win_fsync(File fd);
+extern File my_win_dup(File fd);
+extern File my_win_sopen(const char *path, int oflag, int shflag, int perm);
+extern File my_open_osfhandle(HANDLE handle, int oflag);
+#endif
diff --git a/mysys/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/string.c b/mysys/string.c
index e3a99580c29..1cbce7ca4e1 100644
--- a/mysys/string.c
+++ b/mysys/string.c
@@ -186,3 +186,15 @@ void dynstr_free(DYNAMIC_STRING *str)
str->str=0;
}
}
+
+
+/* Give over the control of the dynamic string to caller */
+
+void dynstr_reassociate(DYNAMIC_STRING *str, char **ptr, size_t *length,
+ size_t *alloc_length)
+{
+ *ptr= str->str;
+ *length= str->length;
+ *alloc_length= str->max_length;
+ str->str=0;
+}
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index 99e82a65a25..b6d2ce46ccc 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -38,11 +38,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;
@@ -74,8 +87,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);
@@ -153,7 +166,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
@@ -162,80 +175,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);
}
@@ -249,41 +259,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;
}
@@ -346,12 +335,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 */
@@ -362,6 +352,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 */
@@ -373,8 +364,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 */
@@ -384,15 +375,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
@@ -485,21 +477,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;
}
@@ -510,7 +508,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);
@@ -558,7 +556,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
@@ -794,19 +792,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 de21e79458c..b1722e0bfdf 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -100,8 +100,8 @@ ulong table_lock_wait_timeout;
enum thr_lock_type thr_upgraded_concurrent_insert_lock = TL_WRITE;
/* The following constants are only for debug output */
-#define MAX_THREADS 100
-#define MAX_LOCKS 100
+#define MAX_THREADS 1000
+#define MAX_LOCKS 1000
LIST *thr_lock_thread_list; /* List of threads in use */
@@ -168,7 +168,8 @@ thr_lock_owner_equal(THR_LOCK_OWNER *rhs, THR_LOCK_OWNER *lhs)
static uint found_errors=0;
static int check_lock(struct st_lock_list *list, const char* lock_type,
- const char *where, my_bool same_owner, my_bool no_cond)
+ const char *where, my_bool same_owner, my_bool no_cond,
+ my_bool read_lock)
{
THR_LOCK_DATA *data,**prev;
uint count=0;
@@ -181,6 +182,23 @@ static int check_lock(struct st_lock_list *list, const char* lock_type,
for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next)
{
+ if (data->type == TL_UNLOCK)
+ {
+ fprintf(stderr,
+ "Warning: Found unlocked lock at %s: %s\n",
+ lock_type, where);
+ return 1;
+ }
+ if ((read_lock && data->type > TL_READ_NO_INSERT) ||
+ (!read_lock && data->type <= TL_READ_NO_INSERT))
+ {
+ fprintf(stderr,
+ "Warning: Found %s lock in %s queue at %s: %s\n",
+ read_lock ? "write" : "read",
+ read_lock ? "read" : "write",
+ lock_type, where);
+ return 1;
+ }
if (data->type != last_lock_type)
last_lock_type=TL_IGNORE;
if (data->prev != prev)
@@ -237,22 +255,27 @@ static void check_locks(THR_LOCK *lock, const char *where,
if (found_errors < MAX_FOUND_ERRORS)
{
- if (check_lock(&lock->write,"write",where,1,1) |
- check_lock(&lock->write_wait,"write_wait",where,0,0) |
- check_lock(&lock->read,"read",where,0,1) |
- check_lock(&lock->read_wait,"read_wait",where,0,0))
+ if (check_lock(&lock->write,"write",where,1,1,0) |
+ check_lock(&lock->write_wait,"write_wait",where,0,0,0) |
+ check_lock(&lock->read,"read",where,0,1,1) |
+ check_lock(&lock->read_wait,"read_wait",where,0,0,1))
+ {
+ DBUG_ASSERT(my_assert_on_error == 0);
found_errors++;
+ }
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)
{
@@ -304,7 +327,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)
{
@@ -587,18 +613,17 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
static enum enum_thr_lock_result
-thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner,
- enum thr_lock_type lock_type)
+thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner)
{
THR_LOCK *lock=data->lock;
enum enum_thr_lock_result result= THR_LOCK_SUCCESS;
struct st_lock_list *wait_queue;
THR_LOCK_DATA *lock_owner;
+ enum thr_lock_type lock_type= data->type;
DBUG_ENTER("thr_lock");
data->next=0;
data->cond=0; /* safety */
- data->type=lock_type;
data->owner= owner; /* Must be reset ! */
data->priority&= ~THR_LOCK_LATE_PRIV;
VOID(pthread_mutex_lock(&lock->mutex));
@@ -907,9 +932,7 @@ void thr_unlock(THR_LOCK_DATA *data, uint unlock_flags)
if (lock_type == TL_READ_NO_INSERT)
lock->read_no_write_count--;
data->type=TL_UNLOCK; /* Mark unlocked */
- check_locks(lock,"after releasing lock", lock_type, 1);
wake_up_waiters(lock);
- check_locks(lock,"end of thr_unlock", lock_type, 1);
pthread_mutex_unlock(&lock->mutex);
DBUG_VOID_RETURN;
}
@@ -929,6 +952,7 @@ static void wake_up_waiters(THR_LOCK *lock)
enum thr_lock_type lock_type;
DBUG_ENTER("wake_up_waiters");
+ check_locks(lock, "before waking up waiters", TL_UNLOCK, 1);
if (!lock->write.data) /* If no active write locks */
{
data=lock->write_wait.data;
@@ -1082,10 +1106,13 @@ thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_OWNER *owner)
/* lock everything */
for (pos=data,end=data+count; pos < end ; pos++)
{
- enum enum_thr_lock_result result= thr_lock(*pos, owner, (*pos)->type);
+ enum enum_thr_lock_result result= thr_lock(*pos, owner);
if (result != THR_LOCK_SUCCESS)
{ /* Aborted */
thr_multi_unlock(data,(uint) (pos-data), 0);
+ /* Mark all requested locks as TL_UNLOCK (to simplify lock checking) */
+ for ( ; pos < end ; pos++)
+ (*pos)->type= TL_UNLOCK;
DBUG_RETURN(result);
}
#ifdef MAIN
diff --git a/mysys/thr_rwlock.c b/mysys/thr_rwlock.c
index ea98a854a4d..2978d91090d 100644
--- a/mysys/thr_rwlock.c
+++ b/mysys/thr_rwlock.c
@@ -19,6 +19,119 @@
#if defined(THREAD) && !defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && !defined(HAVE_RWLOCK_INIT)
#include <errno.h>
+#ifdef _WIN32
+
+static BOOL have_srwlock= FALSE;
+/* Prototypes and function pointers for windows functions */
+typedef VOID (WINAPI* srw_func) (PSRWLOCK SRWLock);
+typedef BOOL (WINAPI* srw_bool_func) (PSRWLOCK SRWLock);
+
+static srw_func my_InitializeSRWLock;
+static srw_func my_AcquireSRWLockExclusive;
+static srw_func my_ReleaseSRWLockExclusive;
+static srw_func my_AcquireSRWLockShared;
+static srw_func my_ReleaseSRWLockShared;
+
+static srw_bool_func my_TryAcquireSRWLockExclusive;
+static srw_bool_func my_TryAcquireSRWLockShared;
+
+/**
+ Check for presence of Windows slim reader writer lock function.
+ Load function pointers.
+*/
+
+static void check_srwlock_availability(void)
+{
+ HMODULE module= GetModuleHandle("kernel32");
+
+ my_InitializeSRWLock= (srw_func) GetProcAddress(module,
+ "InitializeSRWLock");
+ my_AcquireSRWLockExclusive= (srw_func) GetProcAddress(module,
+ "AcquireSRWLockExclusive");
+ my_AcquireSRWLockShared= (srw_func) GetProcAddress(module,
+ "AcquireSRWLockShared");
+ my_ReleaseSRWLockExclusive= (srw_func) GetProcAddress(module,
+ "ReleaseSRWLockExclusive");
+ my_ReleaseSRWLockShared= (srw_func) GetProcAddress(module,
+ "ReleaseSRWLockShared");
+ my_TryAcquireSRWLockExclusive= (srw_bool_func) GetProcAddress(module,
+ "TryAcquireSRWLockExclusive");
+ my_TryAcquireSRWLockShared= (srw_bool_func) GetProcAddress(module,
+ "TryAcquireSRWLockShared");
+
+ /*
+ We currently require TryAcquireSRWLockExclusive. This API is missing on
+ Vista, this means SRWLock are only used starting with Win7.
+
+ If "trylock" usage for rwlocks is eliminated from server codebase (it is used
+ in a single place currently, in query cache), then SRWLock can be enabled on
+ Vista too. In this case condition below needs to be changed to e.g check
+ for my_InitializeSRWLock.
+ */
+
+ if (my_TryAcquireSRWLockExclusive)
+ have_srwlock= TRUE;
+
+}
+
+
+static int srw_init(my_rw_lock_t *rwp)
+{
+ my_InitializeSRWLock(&rwp->srwlock);
+ rwp->have_exclusive_srwlock = FALSE;
+ return 0;
+}
+
+
+static int srw_rdlock(my_rw_lock_t *rwp)
+{
+ my_AcquireSRWLockShared(&rwp->srwlock);
+ return 0;
+}
+
+
+static int srw_tryrdlock(my_rw_lock_t *rwp)
+{
+
+ if (!my_TryAcquireSRWLockShared(&rwp->srwlock))
+ return EBUSY;
+ return 0;
+}
+
+
+static int srw_wrlock(my_rw_lock_t *rwp)
+{
+ my_AcquireSRWLockExclusive(&rwp->srwlock);
+ rwp->have_exclusive_srwlock= TRUE;
+ return 0;
+}
+
+
+static int srw_trywrlock(my_rw_lock_t *rwp)
+{
+ if (!my_TryAcquireSRWLockExclusive(&rwp->srwlock))
+ return EBUSY;
+ rwp->have_exclusive_srwlock= TRUE;
+ return 0;
+}
+
+
+static int srw_unlock(my_rw_lock_t *rwp)
+{
+ if (rwp->have_exclusive_srwlock)
+ {
+ rwp->have_exclusive_srwlock= FALSE;
+ my_ReleaseSRWLockExclusive(&rwp->srwlock);
+ }
+ else
+ {
+ my_ReleaseSRWLockShared(&rwp->srwlock);
+ }
+ return 0;
+}
+
+#endif /*_WIN32 */
+
/*
Source base from Sun Microsystems SPILT, simplified for MySQL use
-- Joshua Chamas
@@ -62,6 +175,22 @@ int my_rwlock_init(rw_lock_t *rwp, void *arg __attribute__((unused)))
{
pthread_condattr_t cond_attr;
+#ifdef _WIN32
+ /*
+ Once initialization is used here rather than in my_init(), in order to
+ - avoid my_init() pitfalls- (undefined order in which initialization should
+ run)
+ - be potentially useful C++ (static constructors)
+ - just to simplify the API.
+ Also, the overhead is of my_pthread_once is very small.
+ */
+ static my_pthread_once_t once_control= MY_PTHREAD_ONCE_INIT;
+ my_pthread_once(&once_control, check_srwlock_availability);
+
+ if (have_srwlock)
+ return srw_init(rwp);
+#endif
+
pthread_mutex_init( &rwp->lock, MY_MUTEX_INIT_FAST);
pthread_condattr_init( &cond_attr );
pthread_cond_init( &rwp->readers, &cond_attr );
@@ -77,6 +206,10 @@ int my_rwlock_init(rw_lock_t *rwp, void *arg __attribute__((unused)))
int my_rwlock_destroy(rw_lock_t *rwp)
{
+#ifdef _WIN32
+ if (have_srwlock)
+ return 0; /* no destroy function */
+#endif
pthread_mutex_destroy( &rwp->lock );
pthread_cond_destroy( &rwp->readers );
pthread_cond_destroy( &rwp->writers );
@@ -86,6 +219,11 @@ int my_rwlock_destroy(rw_lock_t *rwp)
int my_rw_rdlock(rw_lock_t *rwp)
{
+#ifdef _WIN32
+ if (have_srwlock)
+ return srw_rdlock(rwp);
+#endif
+
pthread_mutex_lock(&rwp->lock);
/* active or queued writers */
@@ -100,6 +238,12 @@ int my_rw_rdlock(rw_lock_t *rwp)
int my_rw_tryrdlock(rw_lock_t *rwp)
{
int res;
+
+#ifdef _WIN32
+ if (have_srwlock)
+ return srw_tryrdlock(rwp);
+#endif
+
pthread_mutex_lock(&rwp->lock);
if ((rwp->state < 0 ) || rwp->waiters)
res= EBUSY; /* Can't get lock */
@@ -115,6 +259,11 @@ int my_rw_tryrdlock(rw_lock_t *rwp)
int my_rw_wrlock(rw_lock_t *rwp)
{
+#ifdef _WIN32
+ if (have_srwlock)
+ return srw_wrlock(rwp);
+#endif
+
pthread_mutex_lock(&rwp->lock);
rwp->waiters++; /* another writer queued */
@@ -130,6 +279,12 @@ int my_rw_wrlock(rw_lock_t *rwp)
int my_rw_trywrlock(rw_lock_t *rwp)
{
int res;
+
+#ifdef _WIN32
+ if (have_srwlock)
+ return srw_trywrlock(rwp);
+#endif
+
pthread_mutex_lock(&rwp->lock);
if (rwp->state)
res= EBUSY; /* Can't get lock */
@@ -145,6 +300,11 @@ int my_rw_trywrlock(rw_lock_t *rwp)
int my_rw_unlock(rw_lock_t *rwp)
{
+#ifdef _WIN32
+ if (have_srwlock)
+ return srw_unlock(rwp);
+#endif
+
DBUG_PRINT("rw_unlock",
("state: %d waiters: %d", rwp->state, rwp->waiters));
pthread_mutex_lock(&rwp->lock);
diff --git a/mysys/tree.c b/mysys/tree.c
index 68eaecbb27b..eba058b22f8 100644
--- a/mysys/tree.c
+++ b/mysys/tree.c
@@ -221,7 +221,10 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size,
}
if (element == &tree->null_element)
{
- uint alloc_size=sizeof(TREE_ELEMENT)+key_size+tree->size_of_element;
+ uint alloc_size;
+ if (tree->flag & TREE_ONLY_DUPS)
+ return((TREE_ELEMENT *) 1);
+ alloc_size=sizeof(TREE_ELEMENT)+key_size+tree->size_of_element;
tree->allocated+=alloc_size;
if (tree->memory_limit && tree->elements_in_tree
diff --git a/mysys/waiting_threads.c b/mysys/waiting_threads.c
index 732929f6d99..6ee79cb8e87 100644
--- a/mysys/waiting_threads.c
+++ b/mysys/waiting_threads.c
@@ -479,9 +479,9 @@ void wt_end()
(or even most) of them will never be used for deadlock detection.
@param ds a pointer to deadlock search depth short value
- @param ts a pointer to deadlock timeout short value
+ @param ts a pointer to deadlock timeout short value (microseconds)
@param dl a pointer to deadlock search depth long value
- @param tl a pointer to deadlock timeout long value
+ @param tl a pointer to deadlock timeout long value (microseconds)
@note these are pointers to values, and WT_THD stores them as pointers.
It allows one later to change search depths and timeouts for existing
@@ -1037,8 +1037,9 @@ int wt_thd_cond_timedwait(WT_THD *thd, pthread_mutex_t *mutex)
{
int ret= WT_TIMEOUT;
struct timespec timeout;
- ulonglong before, after, starttime;
+ my_hrtime_t before, after, starttime;
WT_RESOURCE *rc= thd->waiting_for;
+ ulonglong end_wait_time;
DBUG_ENTER("wt_thd_cond_timedwait");
DBUG_PRINT("wt", ("enter: thd=%s, rc=%p", thd->name, rc));
@@ -1050,29 +1051,15 @@ int wt_thd_cond_timedwait(WT_THD *thd, pthread_mutex_t *mutex)
safe_mutex_assert_owner(mutex);
#endif
- before= starttime= my_getsystime();
-
-#ifdef __WIN__
- /*
- only for the sake of Windows we distinguish between
- 'before' and 'starttime':
-
- my_getsystime() returns high-resolution value, that cannot be used for
- waiting (it doesn't follow system clock changes), but is good for time
- intervals.
-
- GetSystemTimeAsFileTime() follows system clock, but is low-resolution
- and will result in lousy intervals.
- */
- GetSystemTimeAsFileTime((PFILETIME)&starttime);
-#endif
+ before= starttime= my_hrtime();
rc_wrlock(rc);
if (rc->owners.elements == 0)
ret= WT_OK;
rc_unlock(rc);
- set_timespec_time_nsec(timeout, starttime, (*thd->timeout_short)*ULL(1000));
+ end_wait_time= starttime.val *1000 + (*thd->timeout_short)*ULL(1000000);
+ set_timespec_time_nsec(timeout, end_wait_time);
if (ret == WT_TIMEOUT && !thd->killed)
ret= pthread_cond_timedwait(&rc->cond, mutex, &timeout);
if (ret == WT_TIMEOUT && !thd->killed)
@@ -1084,15 +1071,16 @@ int wt_thd_cond_timedwait(WT_THD *thd, pthread_mutex_t *mutex)
ret= WT_DEADLOCK;
else if (*thd->timeout_long > *thd->timeout_short)
{
- set_timespec_time_nsec(timeout, starttime, (*thd->timeout_long)*ULL(1000));
+ end_wait_time= starttime.val *1000 + (*thd->timeout_long)*ULL(1000000);
+ set_timespec_time_nsec(timeout, end_wait_time);
if (!thd->killed)
ret= pthread_cond_timedwait(&rc->cond, mutex, &timeout);
}
}
- after= my_getsystime();
+ after= my_hrtime();
if (stop_waiting(thd) == WT_DEADLOCK) /* if we're killed */
ret= WT_DEADLOCK;
- increment_wait_stats(after-before, ret);
+ increment_wait_stats(after.val-before.val, ret);
if (ret == WT_OK)
increment_success_stats();
DBUG_RETURN(ret);
diff --git a/netware/Makefile.am b/netware/Makefile.am
index f537022495b..0eb7fe65f25 100644
--- a/netware/Makefile.am
+++ b/netware/Makefile.am
@@ -108,6 +108,7 @@ init_db.sql: $(top_srcdir)/scripts/mysql_system_tables.sql \
@echo "CREATE DATABASE test;" >> $@;
@echo "use mysql;" >> $@;
@cat $(top_srcdir)/scripts/mysql_system_tables.sql >> $@;
+ @cat $(top_srcdir)/scripts/mysql_system_tables_data.sql | grep -v '@current_hostname' >> $@;
# Build test_db.sql from init_db.sql plus
# some test data
diff --git a/netware/my_manage.c b/netware/my_manage.c
index d5032da2208..4b149afe5c2 100644
--- a/netware/my_manage.c
+++ b/netware/my_manage.c
@@ -24,8 +24,10 @@
#include <proc.h>
#include <ctype.h>
#include <sys/stat.h>
+#include <sys/wait.h>
#include <fcntl.h>
#include <assert.h>
+#include <nks/vm.h>
#include "my_manage.h"
@@ -356,17 +358,17 @@ pid_t get_server_pid(char *pid_file)
// terminate string
if ((p = strchr(buf, '\n')) != NULL)
{
- *p = NULL;
+ *p = 0;
// check for a '\r'
if ((p = strchr(buf, '\r')) != NULL)
{
- *p = NULL;
+ *p = 0;
}
}
else
{
- buf[err] = NULL;
+ buf[err] = 0;
}
id = strtol(buf, NULL, 0);
@@ -471,7 +473,7 @@ void get_basedir(char *argv0, char *basedir)
if ((p = strindex(temp, "/bin/")) != NULL)
{
- *p = NULL;
+ *p = 0;
strcpy(basedir, temp);
}
}
diff --git a/netware/mysql_install_db.c b/netware/mysql_install_db.c
index 98852c89825..09960eacb59 100644
--- a/netware/mysql_install_db.c
+++ b/netware/mysql_install_db.c
@@ -34,7 +34,7 @@
global variables
******************************************************************************/
-char autoclose;
+int autoclose;
char basedir[PATH_MAX];
char datadir[PATH_MAX];
char err_log[PATH_MAX];
@@ -99,7 +99,7 @@ void start_defaults(int argc, char *argv[])
}
// default option
- default_option[0] = NULL;
+ default_option[0] = 0;
for (i=0; (argc > 1) && default_options[i]; i++)
{
if(!strnicmp(argv[1], default_options[i], strlen(default_options[i])))
@@ -110,11 +110,11 @@ void start_defaults(int argc, char *argv[])
}
// set after basedir is established
- datadir[0] = NULL;
- err_log[0] = NULL;
- out_log[0] = NULL;
- mysqld[0] = NULL;
- sql_file[0] = NULL;
+ datadir[0] = 0;
+ err_log[0] = 0;
+ out_log[0] = 0;
+ mysqld[0] = 0;
+ sql_file[0] = 0;
}
/******************************************************************************
diff --git a/netware/mysql_tzinfo_to_sql.def b/netware/mysql_tzinfo_to_sql.def
new file mode 100644
index 00000000000..ff9d35a07fa
--- /dev/null
+++ b/netware/mysql_tzinfo_to_sql.def
@@ -0,0 +1,11 @@
+#------------------------------------------------------------------------------
+# MySQL TzInfo To SQL
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Tool - Create Time Zone Info to SQL"
+VERSION 5, 0
+STACKSIZE 131072
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/mysqld_safe.c b/netware/mysqld_safe.c
index 6ed04c9ff0d..228c7c23fa4 100644
--- a/netware/mysqld_safe.c
+++ b/netware/mysqld_safe.c
@@ -1,6 +1,6 @@
-/*
+/*
Copyright (c) 2003 Novell, Inc. 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; either version 2 of the License, or
@@ -10,74 +10,74 @@
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
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <netdb.h>
-#include <sys/stat.h>
-#include <monitor.h>
-#include <strings.h>
-#include <getopt.h>
-#include <screen.h>
-#include <dirent.h>
-
-#include "my_config.h"
-#include "my_manage.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <sys/stat.h>
+#include <monitor.h>
+#include <strings.h>
+#include <getopt.h>
+#include <screen.h>
+#include <dirent.h>
+
+#include "my_config.h"
+#include "my_manage.h"
#include "mysql_version.h"
-
-/******************************************************************************
-
- global variables
-
-******************************************************************************/
-char autoclose;
-char basedir[PATH_MAX];
+
+/******************************************************************************
+
+ global variables
+
+******************************************************************************/
+char autoclose;
+char basedir[PATH_MAX];
char checktables;
-char datadir[PATH_MAX];
-char pid_file[PATH_MAX];
-char address[PATH_MAX];
-char port[PATH_MAX];
-char err_log[PATH_MAX];
-char safe_log[PATH_MAX];
-char mysqld[PATH_MAX];
-char hostname[PATH_MAX];
-char default_option[PATH_MAX];
-
+char datadir[PATH_MAX];
+char pid_file[PATH_MAX];
+char address[PATH_MAX];
+char port[PATH_MAX];
+char err_log[PATH_MAX];
+char safe_log[PATH_MAX];
+char mysqld[PATH_MAX];
+char hostname[PATH_MAX];
+char default_option[PATH_MAX];
+
FILE *log_fd= NULL;
-
-/******************************************************************************
-
- prototypes
-******************************************************************************/
-
+/******************************************************************************
+
+ prototypes
+
+******************************************************************************/
+
void usage(void);
-void vlog(char *, va_list);
-void log(char *, ...);
+void vlog(char *, va_list);
+void log(char *, ...);
void start_defaults(int, char *[]);
-void finish_defaults();
+void finish_defaults();
void read_defaults(arg_list_t *);
void parse_args(int, char *[]);
void get_options(int, char *[]);
-void check_data_vol();
-void check_setup();
-void check_tables();
+void check_data_vol();
+void check_setup();
+void check_tables();
void mysql_start(int, char *[]);
void parse_setvar(char *arg);
-
-/******************************************************************************
-
- functions
-
-******************************************************************************/
-
-/******************************************************************************
-
+
+/******************************************************************************
+
+ functions
+
+******************************************************************************/
+
+/******************************************************************************
+
usage()
Show usage.
@@ -114,86 +114,86 @@ options:\n\
/******************************************************************************
- vlog()
-
- Log the message.
-
-******************************************************************************/
-void vlog(char *format, va_list ap)
-{
- vfprintf(stdout, format, ap);
- fflush(stdout);
-
- if (log_fd)
- {
- vfprintf(log_fd, format, ap);
- fflush(log_fd);
- }
-}
-
-/******************************************************************************
-
- log()
-
- Log the message.
-
-******************************************************************************/
-void log(char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
-
- vlog(format, ap);
-
- va_end(ap);
-}
-
-/******************************************************************************
-
- start_defaults()
-
- Start setting the defaults.
-
-******************************************************************************/
-void start_defaults(int argc, char *argv[])
-{
- struct stat buf;
- int i;
-
- // default options
+ vlog()
+
+ Log the message.
+
+******************************************************************************/
+void vlog(char *format, va_list ap)
+{
+ vfprintf(stdout, format, ap);
+ fflush(stdout);
+
+ if (log_fd)
+ {
+ vfprintf(log_fd, format, ap);
+ fflush(log_fd);
+ }
+}
+
+/******************************************************************************
+
+ log()
+
+ Log the message.
+
+******************************************************************************/
+void log(char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ vlog(format, ap);
+
+ va_end(ap);
+}
+
+/******************************************************************************
+
+ start_defaults()
+
+ Start setting the defaults.
+
+******************************************************************************/
+void start_defaults(int argc, char *argv[])
+{
+ struct stat buf;
+ int i;
+
+ // default options
static char *default_options[]=
- {
+ {
"--no-defaults",
"--defaults-file=",
"--defaults-extra-file=",
NULL
- };
+ };
- // autoclose
+ // autoclose
autoclose= FALSE;
- // basedir
- get_basedir(argv[0], basedir);
+ // basedir
+ get_basedir(argv[0], basedir);
// check-tables
checktables= FALSE;
- // hostname
+ // hostname
if (gethostname(hostname, PATH_MAX) < 0)
- {
- // default
+ {
+ // default
strcpy(hostname, "mysql");
- }
-
- // address
- snprintf(address, PATH_MAX, "0.0.0.0");
-
- // port
+ }
+
+ // address
+ snprintf(address, PATH_MAX, "0.0.0.0");
+
+ // port
snprintf(port, PATH_MAX, "%d", MYSQL_PORT);
- // default option
- default_option[0]= NULL;
+ // default option
+ default_option[0]= 0;
for (i= 0; (argc > 1) && default_options[i]; i++)
{
if (!strnicmp(argv[1], default_options[i], strlen(default_options[i])))
@@ -203,73 +203,73 @@ void start_defaults(int argc, char *argv[])
}
}
- // set after basedir is established
- datadir[0]= NULL;
- pid_file[0]= NULL;
- err_log[0]= NULL;
- safe_log[0]= NULL;
- mysqld[0]= NULL;
-}
-
-/******************************************************************************
-
- finish_defaults()
-
- Finish settig the defaults.
-
-******************************************************************************/
-void finish_defaults()
-{
- struct stat buf;
- int i;
-
- // datadir
+ // set after basedir is established
+ datadir[0]= 0;
+ pid_file[0]= 0;
+ err_log[0]= 0;
+ safe_log[0]= 0;
+ mysqld[0]= 0;
+}
+
+/******************************************************************************
+
+ finish_defaults()
+
+ Finish settig the defaults.
+
+******************************************************************************/
+void finish_defaults()
+{
+ struct stat buf;
+ int i;
+
+ // datadir
if (!datadir[0])
snprintf(datadir, PATH_MAX, "%s/data", basedir);
- // pid-file
+ // pid-file
if (!pid_file[0])
snprintf(pid_file, PATH_MAX, "%s/%s.pid", datadir, hostname);
- // err-log
+ // err-log
if (!err_log[0])
snprintf(err_log, PATH_MAX, "%s/%s.err", datadir, hostname);
-
- // safe-log
+
+ // safe-log
if (!safe_log[0])
snprintf(safe_log, PATH_MAX, "%s/%s.safe", datadir, hostname);
-
- // mysqld
+
+ // mysqld
if (!mysqld[0])
snprintf(mysqld, PATH_MAX, "%s/bin/mysqld-max", basedir);
- if (stat(mysqld, &buf))
- {
- snprintf(mysqld, PATH_MAX, "%s/bin/mysqld", basedir);
- }
-}
-
-/******************************************************************************
-
- read_defaults()
-
- Read the defaults.
-
-******************************************************************************/
+ if (stat(mysqld, &buf))
+ {
+ snprintf(mysqld, PATH_MAX, "%s/bin/mysqld", basedir);
+ }
+}
+
+/******************************************************************************
+
+ read_defaults()
+
+ Read the defaults.
+
+******************************************************************************/
void read_defaults(arg_list_t *pal)
-{
+{
arg_list_t al;
char defaults_file[PATH_MAX];
- char mydefaults[PATH_MAX];
- char line[PATH_MAX];
- FILE *fp;
+ char mydefaults[PATH_MAX];
+ char line[PATH_MAX];
+ FILE *fp;
// defaults output file
snprintf(defaults_file, PATH_MAX, "%s/bin/defaults.out", basedir);
remove(defaults_file);
// mysqladmin file
- snprintf(mydefaults, PATH_MAX, "%s/bin/my_print_defaults", basedir);
+ snprintf(mydefaults, PATH_MAX, "%s/bin/my_print_defaults", basedir);
// args
init_args(&al);
@@ -290,13 +290,13 @@ void read_defaults(arg_list_t *pal)
{
while (fgets(line, PATH_MAX, fp))
{
- char *p;
+ char *p;
- // remove end-of-line character
+ // remove end-of-line character
if ((p= strrchr(line, '\n')) != NULL)
*p= '\0';
- // add the option as an argument
+ // add the option as an argument
add_arg(pal, line);
}
@@ -305,37 +305,37 @@ void read_defaults(arg_list_t *pal)
// remove file
remove(defaults_file);
-}
-
-/******************************************************************************
-
- parse_args()
-
- Get the options.
-
-******************************************************************************/
-void parse_args(int argc, char *argv[])
-{
+}
+
+/******************************************************************************
+
+ parse_args()
+
+ Get the options.
+
+******************************************************************************/
+void parse_args(int argc, char *argv[])
+{
int index= 0;
- int c;
+ int c;
- // parse options
- enum opts
- {
+ // parse options
+ enum opts
+ {
OPT_BASEDIR= 0xFF,
- OPT_DATADIR,
- OPT_PID_FILE,
- OPT_BIND_ADDRESS,
- OPT_PORT,
- OPT_ERR_LOG,
- OPT_SAFE_LOG,
+ OPT_DATADIR,
+ OPT_PID_FILE,
+ OPT_BIND_ADDRESS,
+ OPT_PORT,
+ OPT_ERR_LOG,
+ OPT_SAFE_LOG,
OPT_MYSQLD,
OPT_HELP,
OPT_SETVAR
- };
+ };
static struct option options[]=
- {
+ {
{"autoclose", no_argument, &autoclose, TRUE},
{"basedir", required_argument, 0, OPT_BASEDIR},
{"check-tables", no_argument, &checktables, TRUE},
@@ -349,51 +349,51 @@ void parse_args(int argc, char *argv[])
{"help", no_argument, 0, OPT_HELP},
{"set-variable", required_argument, 0, OPT_SETVAR},
{0, 0, 0, 0}
- };
+ };
- // we have to reset getopt_long because we use it multiple times
+ // we have to reset getopt_long because we use it multiple times
optind= 1;
- // turn off error reporting
+ // turn off error reporting
opterr= 0;
while ((c= getopt_long(argc, argv, "b:h:P:", options, &index)) >= 0)
- {
+ {
switch (c) {
- case OPT_BASEDIR:
- case 'b':
- strcpy(basedir, optarg);
- break;
+ case OPT_BASEDIR:
+ case 'b':
+ strcpy(basedir, optarg);
+ break;
- case OPT_DATADIR:
- case 'h':
- strcpy(datadir, optarg);
- break;
+ case OPT_DATADIR:
+ case 'h':
+ strcpy(datadir, optarg);
+ break;
- case OPT_PID_FILE:
- strcpy(pid_file, optarg);
- break;
+ case OPT_PID_FILE:
+ strcpy(pid_file, optarg);
+ break;
- case OPT_BIND_ADDRESS:
- strcpy(address, optarg);
- break;
+ case OPT_BIND_ADDRESS:
+ strcpy(address, optarg);
+ break;
- case OPT_PORT:
- case 'P':
- strcpy(port, optarg);
- break;
+ case OPT_PORT:
+ case 'P':
+ strcpy(port, optarg);
+ break;
- case OPT_ERR_LOG:
- strcpy(err_log, optarg);
- break;
+ case OPT_ERR_LOG:
+ strcpy(err_log, optarg);
+ break;
- case OPT_SAFE_LOG:
- strcpy(safe_log, optarg);
- break;
+ case OPT_SAFE_LOG:
+ strcpy(safe_log, optarg);
+ break;
- case OPT_MYSQLD:
- strcpy(mysqld, optarg);
- break;
+ case OPT_MYSQLD:
+ strcpy(mysqld, optarg);
+ break;
case OPT_SETVAR:
parse_setvar(optarg);
@@ -403,13 +403,13 @@ void parse_args(int argc, char *argv[])
usage();
break;
- default:
- // ignore
- break;
- }
- }
-}
-
+ default:
+ // ignore
+ break;
+ }
+ }
+}
+
/*
parse_setvar(char *arg)
Pasrsing for port just to display the port num on the mysqld_safe screen
@@ -430,148 +430,148 @@ void parse_setvar(char *arg)
-/******************************************************************************
-
- get_options()
+/******************************************************************************
+
+ get_options()
+
+ Get the options.
- Get the options.
-
-******************************************************************************/
-void get_options(int argc, char *argv[])
-{
+******************************************************************************/
+void get_options(int argc, char *argv[])
+{
arg_list_t al;
- // start defaults
- start_defaults(argc, argv);
-
- // default file arguments
+ // start defaults
+ start_defaults(argc, argv);
+
+ // default file arguments
init_args(&al);
add_arg(&al, "ignore");
read_defaults(&al);
parse_args(al.argc, al.argv);
free_args(&al);
- // command-line arguments
- parse_args(argc, argv);
-
- // finish defaults
- finish_defaults();
-}
-
-/******************************************************************************
-
- check_data_vol()
-
- Check the database volume.
-
-******************************************************************************/
-void check_data_vol()
-{
- // warn if the data is on a Traditional volume
- struct volume_info vol;
- char buff[PATH_MAX];
- char *p;
-
- // clear struct
- memset(&vol, 0, sizeof(vol));
-
- // find volume name
- strcpy(buff, datadir);
+ // command-line arguments
+ parse_args(argc, argv);
+
+ // finish defaults
+ finish_defaults();
+}
+
+/******************************************************************************
+
+ check_data_vol()
+
+ Check the database volume.
+
+******************************************************************************/
+void check_data_vol()
+{
+ // warn if the data is on a Traditional volume
+ struct volume_info vol;
+ char buff[PATH_MAX];
+ char *p;
+
+ // clear struct
+ memset(&vol, 0, sizeof(vol));
+
+ // find volume name
+ strcpy(buff, datadir);
if (p= strchr(buff, ':'))
- {
- // terminate after volume name
+ {
+ // terminate after volume name
*p= 0;
- }
- else
- {
- // assume SYS volume
- strcpy(buff, "SYS");
- }
-
- // retrieve information
- netware_vol_info_from_name(&vol, buff);
-
- if ((vol.flags & VOL_NSS_PRESENT) == 0)
- {
+ }
+ else
+ {
+ // assume SYS volume
+ strcpy(buff, "SYS");
+ }
+
+ // retrieve information
+ netware_vol_info_from_name(&vol, buff);
+
+ if ((vol.flags & VOL_NSS_PRESENT) == 0)
+ {
log("Error: Either the data directory does not exist or is not on an NSS volume!\n\n");
- exit(-1);
- }
-}
-
-/******************************************************************************
-
- check_setup()
-
- Check the current setup.
-
-******************************************************************************/
-void check_setup()
-{
+ exit(-1);
+ }
+}
+
+/******************************************************************************
+
+ check_setup()
+
+ Check the current setup.
+
+******************************************************************************/
+void check_setup()
+{
struct stat info;
- char temp[PATH_MAX];
+ char temp[PATH_MAX];
- // remove any current pid_file
+ // remove any current pid_file
if (!stat(pid_file, &info) && (remove(pid_file) < 0))
{
- log("ERROR: Unable to remove current pid file!\n\n");
- exit(-1);
+ log("ERROR: Unable to remove current pid file!\n\n");
+ exit(-1);
}
// check the data volume
- check_data_vol();
-
- // check for a database
- snprintf(temp, PATH_MAX, "%s/mysql/host.frm", datadir);
- if (stat(temp, &info))
- {
- log("ERROR: No database found in the data directory!\n\n");
- exit(-1);
- }
-}
-
-/******************************************************************************
-
- check_tables()
-
- Check the database tables.
-
-******************************************************************************/
-void check_tables()
-{
+ check_data_vol();
+
+ // check for a database
+ snprintf(temp, PATH_MAX, "%s/mysql/host.frm", datadir);
+ if (stat(temp, &info))
+ {
+ log("ERROR: No database found in the data directory!\n\n");
+ exit(-1);
+ }
+}
+
+/******************************************************************************
+
+ check_tables()
+
+ Check the database tables.
+
+******************************************************************************/
+void check_tables()
+{
arg_list_t al;
- char mycheck[PATH_MAX];
+ char mycheck[PATH_MAX];
char table[PATH_MAX];
char db[PATH_MAX];
DIR *datadir_entry, *db_entry, *table_entry;
// status
- log("checking tables...\n");
+ log("checking tables...\n");
- // list databases
+ // list databases
if ((datadir_entry= opendir(datadir)) == NULL)
{
return;
}
-
+
while ((db_entry= readdir(datadir_entry)) != NULL)
{
- if (db_entry->d_name[0] == '.')
- {
- // Skip
- }
- else if (S_ISDIR(db_entry->d_type))
- {
- // create long db name
- snprintf(db, PATH_MAX, "%s/%s", datadir, db_entry->d_name);
-
- // list tables
+ if (db_entry->d_name[0] == '.')
+ {
+ // Skip
+ }
+ else if (S_ISDIR(db_entry->d_type))
+ {
+ // create long db name
+ snprintf(db, PATH_MAX, "%s/%s", datadir, db_entry->d_name);
+
+ // list tables
if ((db_entry= opendir(db)) == NULL)
- {
+ {
continue;
- }
+ }
while ((table_entry= readdir(db_entry)) != NULL)
- {
+ {
// create long table name
snprintf(table, PATH_MAX, "%s/%s", db, strlwr(table_entry->d_name));
@@ -581,7 +581,7 @@ void check_tables()
// mysqladmin file
snprintf(mycheck, PATH_MAX, "%s/bin/myisamchk", basedir);
-
+
// args
init_args(&al);
add_arg(&al, mycheck);
@@ -594,7 +594,7 @@ void check_tables()
add_arg(&al, "-O");
add_arg(&al, "sort_buffer=64M");
add_arg(&al, table);
-
+
spawn(mycheck, &al, TRUE, NULL, NULL, NULL);
free_args(&al);
@@ -619,20 +619,20 @@ void check_tables()
free_args(&al);
}
- }
- }
+ }
+ }
}
-}
-
-/******************************************************************************
-
- mysql_start()
-
- Start the mysql server.
-
-******************************************************************************/
-void mysql_start(int argc, char *argv[])
-{
+}
+
+/******************************************************************************
+
+ mysql_start()
+
+ Start the mysql server.
+
+******************************************************************************/
+void mysql_start(int argc, char *argv[])
+{
arg_list_t al;
int i, j, err;
struct stat info;
@@ -641,16 +641,16 @@ void mysql_start(int argc, char *argv[])
char stamp[PATH_MAX];
char skip;
- // private options
+ // private options
static char *private_options[]=
- {
+ {
"--autoclose",
"--check-tables",
"--help",
"--err-log=",
"--mysqld=",
NULL
- };
+ };
// args
init_args(&al);
@@ -661,22 +661,22 @@ void mysql_start(int argc, char *argv[])
{
skip= FALSE;
- // skip private arguments
+ // skip private arguments
for (j= 0; private_options[j]; j++)
- {
+ {
if (!strnicmp(argv[i], private_options[j], strlen(private_options[j])))
- {
+ {
skip= TRUE;
break;
- }
- }
+ }
+ }
if (!skip)
{
add_arg(&al, "%s", argv[i]);
}
}
- // spawn
+ // spawn
do
{
// check the database tables
@@ -684,10 +684,10 @@ void mysql_start(int argc, char *argv[])
check_tables();
// status
- time(&cal);
- localtime_r(&cal, &lt);
- strftime(stamp, PATH_MAX, "%d %b %Y %H:%M:%S", &lt);
- log("mysql started : %s\n", stamp);
+ time(&cal);
+ localtime_r(&cal, &lt);
+ strftime(stamp, PATH_MAX, "%d %b %Y %H:%M:%S", &lt);
+ log("mysql started : %s\n", stamp);
// spawn mysqld
spawn(mysqld, &al, TRUE, NULL, NULL, err_log);
@@ -695,57 +695,57 @@ void mysql_start(int argc, char *argv[])
while (!stat(pid_file, &info));
// status
- time(&cal);
- localtime_r(&cal, &lt);
- strftime(stamp, PATH_MAX, "%d %b %Y %H:%M:%S", &lt);
- log("mysql stopped : %s\n\n", stamp);
+ time(&cal);
+ localtime_r(&cal, &lt);
+ strftime(stamp, PATH_MAX, "%d %b %Y %H:%M:%S", &lt);
+ log("mysql stopped : %s\n\n", stamp);
// free args
free_args(&al);
-}
-
-/******************************************************************************
-
- main()
-
-******************************************************************************/
-int main(int argc, char **argv)
-{
+}
+
+/******************************************************************************
+
+ main()
+
+******************************************************************************/
+int main(int argc, char **argv)
+{
char temp[PATH_MAX];
- // get the options
+ // get the options
get_options(argc, argv);
-
- // keep the screen up
+
+ // keep the screen up
if (!autoclose)
setscreenmode(SCR_NO_MODE);
- // create log file
+ // create log file
log_fd= fopen(safe_log, "w+");
- // header
- log("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE);
+ // header
+ log("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE);
// status
log("address : %s\n", address);
log("port : %s\n", port);
- log("daemon : %s\n", mysqld);
+ log("daemon : %s\n", mysqld);
log("base directory : %s\n", basedir);
log("data directory : %s\n", datadir);
log("pid file : %s\n", pid_file);
log("error file : %s\n", err_log);
log("log file : %s\n", safe_log);
- log("\n");
+ log("\n");
- // check setup
- check_setup();
+ // check setup
+ check_setup();
- // start the MySQL server
+ // start the MySQL server
mysql_start(argc, argv);
// close log file
if (log_fd)
fclose(log_fd);
- return 0;
-}
+ return 0;
+}
diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c
index ee13b37f793..de62ebf8dbd 100644
--- a/plugin/auth_pam/auth_pam.c
+++ b/plugin/auth_pam/auth_pam.c
@@ -1,3 +1,7 @@
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE /* For strndup() */
+#endif
+
#include <mysql/plugin_auth.h>
#include <string.h>
#include <my_config.h>
diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc
index 617ca0213dc..bcfb0348e11 100644
--- a/plugin/feedback/sender_thread.cc
+++ b/plugin/feedback/sender_thread.cc
@@ -257,7 +257,7 @@ ret:
pthread_mutex_lock(&LOCK_thread_count);
bzero(&thd->status_var, sizeof(thd->status_var));
thread_count--;
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_CONNECTION;
pthread_cond_broadcast(&COND_thread_count);
pthread_mutex_unlock(&LOCK_thread_count);
delete thd;
diff --git a/plugin/handler_socket/AUTHORS b/plugin/handler_socket/AUTHORS
new file mode 100644
index 00000000000..b60fb015eaa
--- /dev/null
+++ b/plugin/handler_socket/AUTHORS
@@ -0,0 +1,22 @@
+Akira Higuchi (https://github.com/ahiguti)
+ - developed HanderSocket plugin, libhsclient, and perl-Net-HandlerSocket
+
+Yoshinori Matsunobu (https://github.com/yoshinorim)
+ - introduced autotools, added support for MySQL 5.5.6, added statistics
+ variables
+
+Jeff Hodges (https://github.com/jmhodges)
+ - fixed some autotools scripts
+
+Toru Yamaguchi (https://github.com/zigorou)
+ - ported to MacOS X
+
+Moriyoshi Koizumi (https://github.com/moriyoshi)
+ - fixed some autotools scripts
+
+takeda-at (https://github.com/takada-at)
+ - added simple authorization function
+
+WheresWardy (https://github.com/WheresWardy)
+ - added authentication functions to libhsclient
+
diff --git a/plugin/handler_socket/ChangeLog b/plugin/handler_socket/ChangeLog
new file mode 100644
index 00000000000..793a39937e5
--- /dev/null
+++ b/plugin/handler_socket/ChangeLog
@@ -0,0 +1,19 @@
+1.0.6 - For MariaDB
+ * Modifications to Makefiles to be part of plugin directory
+ * Compiled by default in max builds
+ * Some minor changes in database.cpp to use the new MariaDB handler
+ interface
+o * Fixed compiler warnings
+
+1.0.6 - 2010-10-29
+ * Changed build instruction (autoreconf/configure/make), removed auto-generated files (Contributed by jmhodges)
+ *
+
+1.0.5 - 2010-10-18
+ * Changed build procedures (using typical configure/make)
+ * Supported 5.5.6
+ * Added status variables
+
+1.0.4 - 2010-08-15
+ * Initial public release
+
diff --git a/plugin/handler_socket/Makefile.am b/plugin/handler_socket/Makefile.am
new file mode 100644
index 00000000000..7dff19820ce
--- /dev/null
+++ b/plugin/handler_socket/Makefile.am
@@ -0,0 +1,88 @@
+
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = @HANDLERSOCKET_SUBDIRS@
+EXTRA_DIST= plug.in
+
+perl:
+ cd perl-Net-HandlerSocket && perl Makefile.PL && make
+
+install_perl:
+ cd perl-Net-HandlerSocket && make install
+
+rpms: rpm_cli rpm_perl rpm_c
+
+rpm_dir:
+ - mkdir dist
+ - mkdir dist/BUILD dist/RPMS dist/SOURCES dist/SPECS dist/SRPMS
+
+rpm_cli: clean_cli rpm_dir
+ sed -e "s/HANDLERSOCKET_VERSION/$(VERSION)/" \
+ libhsclient/libhsclient.spec.template \
+ > libhsclient/libhsclient.spec
+ tar cvfz dist/libhsclient.tar.gz libhsclient
+ rpmbuild --define "_topdir `pwd`/dist" -ta \
+ dist/libhsclient.tar.gz
+
+rpm_perl: clean_perl rpm_dir
+ sed -e "s/HANDLERSOCKET_VERSION/$(VERSION)/" \
+ perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec.template \
+ > perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec
+ cd perl-Net-HandlerSocket && perl Makefile.PL && make clean && \
+ rm -f Makefile.old
+ tar cvfz dist/perl-Net-HandlerSocket.tar.gz perl-Net-HandlerSocket
+ rpmbuild --define "_topdir `pwd`/dist" -ta \
+ dist/perl-Net-HandlerSocket.tar.gz
+
+rpm_c: clean_c rpm_dir
+ sed -e "s/HANDLERSOCKET_VERSION/$(VERSION)/" \
+ handlersocket/handlersocket.spec.template \
+ > handlersocket/handlersocket.spec
+ sed -e "s|HANDLERSOCKET_MYSQL_INC|$(MYSQL_CFLAGS) $(MYSQL_INC)|" \
+ -e "s|HANDLERSOCKET_MYSQL_LIB|$(MYSQL_LIB)|" \
+ handlersocket/Makefile.plain.template \
+ > handlersocket/Makefile.plain
+ tar cvfz dist/handlersocket.tar.gz handlersocket
+ rpmbuild --define "_topdir `pwd`/dist" -ta \
+ dist/handlersocket.tar.gz
+
+install_rpm_pl:
+ - sudo rpm -e perl-Net-HandlerSocket
+ - sudo rpm -e perl-Net-HandlerSocket-debuginfo
+ make clean
+ make rpm_perl
+ - sudo rpm -U dist/RPMS/*/perl*.rpm
+
+installrpms:
+ - sudo rpm -e handlersocket
+ - sudo rpm -e handlersocket-debuginfo
+ - sudo rpm -e perl-Net-HandlerSocket
+ - sudo rpm -e perl-Net-HandlerSocket-debuginfo
+ - sudo rpm -e libhsclient
+ - sudo rpm -e libhsclient-debuginfo
+ make clean
+ make rpm_cli
+ - sudo rpm -U dist/RPMS/*/libhsclient*.rpm
+ make clean
+ make rpm_perl
+ - sudo rpm -U dist/RPMS/*/perl*.rpm
+ make clean
+ make rpm_c
+ - sudo rpm -U dist/RPMS/*/handlersocket*.rpm
+
+clean_cli:
+ cd libhsclient && make clean
+ cd client && make clean
+
+clean_perl:
+ cd perl-Net-HandlerSocket && perl Makefile.PL && make clean && \
+ rm -f Makefile.old
+
+clean_c:
+ cd handlersocket && make clean
+
+clean_all: clean_cli clean_perl clean_c
+ cd regtest && make clean
+ rm -rf dist/*/*
+ rm -f dist/*.tar.gz
+
diff --git a/plugin/handler_socket/README b/plugin/handler_socket/README
new file mode 100644
index 00000000000..9a3bed7ae65
--- /dev/null
+++ b/plugin/handler_socket/README
@@ -0,0 +1,82 @@
+Notes added by Monty:
+
+This is HandlerSocket version 1.0.6 (See ChangeLog file)
+The original code can be found at:
+
+https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL
+
+-----------------------------------------------------------------------------
+HandlerSocket plugin for MySQL
+
+Copyright (c) 2010 DeNA Co.,Ltd.
+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 above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of DeNA Co.,Ltd. nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY DeNA Co.,Ltd. "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 DeNA Co.,Ltd. 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.
+
+
+-----------------------------------------------------------------------------
+About HandlerSocket
+
+HandlerSocket is a NoSQL plugin for MySQL. It works as a daemon inside the
+mysqld process, accept tcp connections, and execute requests from clients.
+HandlerSocket does not support SQL queries. Instead, it supports simple CRUD
+operations on tables.
+
+Because of the following reasons, HandlerSocket is much faster than the
+mysqld/libmysql pair in some circumstances:
+
+ - HandlerSocket manipulates data without parsing SQL, which causes less
+ CPU usage.
+ - HandlerSocket reads many requests from clients and executes their
+ requests in bulk, which causes less CPU and disk usage.
+ - HandlerSocket client/server protocol is more compact than the
+ mysql/libmysql pair, which causes less network usage.
+
+The current version of HandlerSocket only works with GNU/Linux. The source
+archive of HandlerSocket includes a C++ and a Perl client libraries.
+Here is a list of client libraries for other languages:
+
+ - PHP
+ http://openpear.org/package/Net_HandlerSocket
+ http://github.com/tz-lom/HSPHP
+ http://code.google.com/p/php-handlersocket/
+ - Java
+ http://code.google.com/p/hs4j/
+ http://code.google.com/p/handlersocketforjava/
+ - Python
+ http://pypi.python.org/pypi/python-handler-socket
+ https://code.launchpad.net/~songofacandy/+junk/pyhandlersocket
+ - Ruby
+ https://github.com/winebarrel/ruby-handlersocket
+ https://github.com/miyucy/handlersocket
+ - JavaScript
+ https://github.com/koichik/node-handlersocket
+ - Scala
+ https://github.com/fujohnwang/hs2client
+
+The home of HandlerSocket is here:
+ https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL
+
+More documents are available in docs-en/ and docs-ja/ directories.
+
diff --git a/plugin/handler_socket/autogen.sh b/plugin/handler_socket/autogen.sh
new file mode 100755
index 00000000000..3b80afd1cb8
--- /dev/null
+++ b/plugin/handler_socket/autogen.sh
@@ -0,0 +1,117 @@
+#!/bin/sh
+
+warn() {
+echo -e "\tWARNING: $@" 1>&2
+}
+
+# init
+
+LIBTOOLIZE=libtoolize
+ACLOCAL=aclocal
+AUTOCONF=autoconf
+AUTOHEADER=autoheader
+AUTOMAKE=automake
+
+case `uname -s` in
+Darwin)
+LIBTOOLIZE=glibtoolize
+;;
+FreeBSD)
+ACLOCAL_ARGS="$ACLOCAL_ARGS -I /usr/local/share/aclocal/"
+;;
+esac
+
+
+# libtoolize
+echo "Searching libtoolize..."
+if [ `which $LIBTOOLIZE` ] ; then
+echo -e "\tFOUND: libtoolize -> $LIBTOOLIZE"
+else
+warn "Cannot Found libtoolize... input libtool command"
+ read LIBTOOLIZE
+ LIBTOOLIZE=`which $LIBTOOLIZE`
+ if [ `which $LIBTOOLIZE` ] ; then
+echo -e "\tSET: libtoolize -> $LIBTOOLIZE"
+ else
+warn "$LIBTOOLIZE: Command not found."
+ exit 1;
+ fi
+fi
+
+# aclocal
+echo "Searching aclocal..."
+if [ `which $ACLOCAL` ] ; then
+echo -e "\tFOUND: aclocal -> $ACLOCAL"
+else
+warn "Cannot Found aclocal... input aclocal command"
+ read ACLOCAL
+ ACLOCAL=`which $ACLOCAL`
+ if [ `which $ACLOCAL` ] ; then
+echo -e "\tSET: aclocal -> $ACLOCAL"
+ else
+warn "$ACLOCAL: Command not found."
+ exit 1;
+ fi
+fi
+
+# automake
+echo "Searching automake..."
+if [ `which $AUTOMAKE` ] ; then
+echo -e "\tFOUND: automake -> $AUTOMAKE"
+else
+warn "Cannot Found automake... input automake command"
+ read AUTOMAKE
+ ACLOCAL=`which $AUTOMAKE`
+ if [ `which $AUTOMAKE` ] ; then
+echo -e "\tSET: automake -> $AUTOMAKE"
+ else
+warn "$AUTOMAKE: Command not found."
+ exit 1;
+ fi
+fi
+
+# autoheader
+echo "Searching autoheader..."
+if [ `which $AUTOHEADER` ] ; then
+echo -e "\tFOUND: autoheader -> $AUTOHEADER"
+else
+warn "Cannot Found autoheader... input autoheader command"
+ read AUTOHEADER
+ ACLOCAL=`which $AUTOHEADER`
+ if [ `which $AUTOHEADER` ] ; then
+echo -e "\tSET: autoheader -> $AUTOHEADER"
+ else
+warn "$AUTOHEADER: Command not found."
+ exit 1;
+ fi
+fi
+
+# autoconf
+echo "Searching autoconf..."
+if [ `which $AUTOCONF` ] ; then
+echo -e "\tFOUND: autoconf -> $AUTOCONF"
+else
+warn "Cannot Found autoconf... input autoconf command"
+ read AUTOCONF
+ ACLOCAL=`which $AUTOCONF`
+ if [ `which $AUTOCONF` ] ; then
+echo -e "\tSET: autoconf -> $AUTOCONF"
+ else
+warn "$AUTOCONF: Command not found."
+ exit 1;
+ fi
+fi
+
+echo "Running libtoolize ..."
+$LIBTOOLIZE --force --copy
+echo "Running aclocal ..."
+$ACLOCAL ${ACLOCAL_ARGS} -I .
+echo "Running autoheader..."
+$AUTOHEADER
+echo "Running automake ..."
+$AUTOMAKE --add-missing --copy
+echo "Running autoconf ..."
+$AUTOCONF
+
+mkdir m4 2> /dev/null
+
diff --git a/plugin/handler_socket/client/Makefile.am b/plugin/handler_socket/client/Makefile.am
new file mode 100644
index 00000000000..e89727a7023
--- /dev/null
+++ b/plugin/handler_socket/client/Makefile.am
@@ -0,0 +1,24 @@
+CXXFLAGS += -fimplicit-templates
+AM_INCLUDES= -I$(srcdir)/../libhsclient
+bin_PROGRAMS=hsclient
+hsclient_SOURCES= hsclient.cpp
+hsclient_LDFLAGS= -static -L../libhsclient -lhsclient
+hsclient_CXXFLAGS= $(AM_INCLUDES)
+
+hstest: hstest.o
+ $(CXX) $(CXXFLAGS) $(MY_CXXFLAGS) $(LFLAGS) hstest.o \
+ -L../libhsclient/.libs -lhsclient $(MYSQL_LIB) \
+ -o hstest
+
+hstest.o: hstest.cpp
+ $(CXX) $(CXXFLAGS) $(MY_CXXFLAGS) $(MYSQL_INC) $(AM_INCLUDES) \
+ -c hstest.cpp
+
+hslongrun: hslongrun.o
+ $(CXX) $(CXXFLAGS) $(MY_CXXFLAGS) $(LFLAGS) hslongrun.o \
+ -L../libhsclient/.libs -lhsclient $(MYSQL_LIB) \
+ -o hslongrun
+
+hslongrun.o: hslongrun.cpp
+ $(CXX) $(CXXFLAGS) $(MY_CXXFLAGS) $(MYSQL_INC) $(AM_INCLUDES) \
+ -c hslongrun.cpp
diff --git a/plugin/handler_socket/client/hsclient.cpp b/plugin/handler_socket/client/hsclient.cpp
new file mode 100644
index 00000000000..0dd8332e345
--- /dev/null
+++ b/plugin/handler_socket/client/hsclient.cpp
@@ -0,0 +1,88 @@
+
+// vim:sw=2:ai
+
+#include "hstcpcli.hpp"
+#include "string_util.hpp"
+
+namespace dena {
+
+int
+hstcpcli_main(int argc, char **argv)
+{
+ config conf;
+ parse_args(argc, argv, conf);
+ socket_args sockargs;
+ sockargs.set(conf);
+ hstcpcli_ptr cli = hstcpcli_i::create(sockargs);
+ const std::string dbname = conf.get_str("dbname", "hstest");
+ const std::string table = conf.get_str("table", "hstest_table1");
+ const std::string index = conf.get_str("index", "PRIMARY");
+ const std::string fields = conf.get_str("fields", "k,v");
+ const int limit = conf.get_int("limit", 0);
+ const int skip = conf.get_int("skip", 0);
+ std::vector<std::string> keys;
+ std::vector<string_ref> keyrefs;
+ size_t num_keys = 0;
+ while (true) {
+ const std::string conf_key = std::string("k") + to_stdstring(num_keys);
+ const std::string k = conf.get_str(conf_key, "");
+ const std::string kx = conf.get_str(conf_key, "x");
+ if (k.empty() && kx == "x") {
+ break;
+ }
+ ++num_keys;
+ keys.push_back(k);
+ }
+ for (size_t i = 0; i < keys.size(); ++i) {
+ const string_ref ref(keys[i].data(), keys[i].size());
+ keyrefs.push_back(ref);
+ }
+ const std::string op = conf.get_str("op", "=");
+ const string_ref op_ref(op.data(), op.size());
+ cli->request_buf_open_index(0, dbname.c_str(), table.c_str(),
+ index.c_str(), fields.c_str());
+ cli->request_buf_exec_generic(0, op_ref, num_keys == 0 ? 0 : &keyrefs[0],
+ num_keys, limit, skip, string_ref(), 0, 0);
+ int code = 0;
+ size_t numflds = 0;
+ do {
+ if (cli->request_send() != 0) {
+ fprintf(stderr, "request_send: %s\n", cli->get_error().c_str());
+ break;
+ }
+ if ((code = cli->response_recv(numflds)) != 0) {
+ fprintf(stderr, "response_recv: %s\n", cli->get_error().c_str());
+ break;
+ }
+ } while (false);
+ cli->response_buf_remove();
+ do {
+ if ((code = cli->response_recv(numflds)) != 0) {
+ fprintf(stderr, "response_recv: %s\n", cli->get_error().c_str());
+ break;
+ }
+ while (true) {
+ const string_ref *const row = cli->get_next_row();
+ if (row == 0) {
+ break;
+ }
+ printf("REC:");
+ for (size_t i = 0; i < numflds; ++i) {
+ const std::string val(row[i].begin(), row[i].size());
+ printf(" %s", val.c_str());
+ }
+ printf("\n");
+ }
+ } while (false);
+ cli->response_buf_remove();
+ return 0;
+}
+
+};
+
+int
+main(int argc, char **argv)
+{
+ return dena::hstcpcli_main(argc, argv);
+}
+
diff --git a/plugin/handler_socket/client/hslongrun.cpp b/plugin/handler_socket/client/hslongrun.cpp
new file mode 100644
index 00000000000..e82c12b166b
--- /dev/null
+++ b/plugin/handler_socket/client/hslongrun.cpp
@@ -0,0 +1,1041 @@
+
+// vim:sw=2:ai
+
+#include <signal.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <string.h>
+#include <vector>
+#include <map>
+#include <stdlib.h>
+#include <memory>
+#include <errno.h>
+#include <mysql.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "util.hpp"
+#include "auto_ptrcontainer.hpp"
+#include "socket.hpp"
+#include "hstcpcli.hpp"
+#include "string_util.hpp"
+#include "mutex.hpp"
+
+namespace dena {
+
+struct auto_mysql : private noncopyable {
+ auto_mysql() : db(0) {
+ reset();
+ }
+ ~auto_mysql() {
+ if (db) {
+ mysql_close(db);
+ }
+ }
+ void reset() {
+ if (db) {
+ mysql_close(db);
+ }
+ if ((db = mysql_init(0)) == 0) {
+ fatal_exit("failed to initialize mysql client");
+ }
+ }
+ operator MYSQL *() const { return db; }
+ private:
+ MYSQL *db;
+};
+
+struct auto_mysql_res : private noncopyable {
+ auto_mysql_res(MYSQL *db) {
+ res = mysql_store_result(db);
+ }
+ ~auto_mysql_res() {
+ if (res) {
+ mysql_free_result(res);
+ }
+ }
+ operator MYSQL_RES *() const { return res; }
+ private:
+ MYSQL_RES *res;
+};
+
+struct auto_mysql_stmt : private noncopyable {
+ auto_mysql_stmt(MYSQL *db) {
+ stmt = mysql_stmt_init(db);
+ }
+ ~auto_mysql_stmt() {
+ if (stmt) {
+ mysql_stmt_close(stmt);
+ }
+ }
+ operator MYSQL_STMT *() const { return stmt; }
+ private:
+ MYSQL_STMT *stmt;
+};
+
+double
+gettimeofday_double()
+{
+ struct timeval tv = { };
+ if (gettimeofday(&tv, 0) != 0) {
+ fatal_abort("gettimeofday");
+ }
+ return static_cast<double>(tv.tv_usec) / 1000000 + tv.tv_sec;
+}
+
+struct record_value {
+ mutex lock;
+ bool deleted;
+ bool unknown_state;
+ std::string key;
+ std::vector<std::string> values;
+ record_value() : deleted(true), unknown_state(false) { }
+};
+
+struct hs_longrun_shared {
+ config conf;
+ socket_args arg;
+ int verbose;
+ long num_threads;
+ int usleep;
+ volatile mutable int running;
+ auto_ptrcontainer< std::vector<record_value *> > records;
+ hs_longrun_shared() : verbose(0), num_threads(0), usleep(0), running(1) { }
+};
+
+struct thread_base {
+ thread_base() : need_join(false), stack_size(256 * 1024) { }
+ virtual ~thread_base() {
+ join();
+ }
+ virtual void run() = 0;
+ void start() {
+ if (!start_nothrow()) {
+ fatal_abort("thread::start");
+ }
+ }
+ bool start_nothrow() {
+ if (need_join) {
+ return need_join; /* true */
+ }
+ void *const arg = this;
+ pthread_attr_t attr;
+ if (pthread_attr_init(&attr) != 0) {
+ fatal_abort("pthread_attr_init");
+ }
+ if (pthread_attr_setstacksize(&attr, stack_size) != 0) {
+ fatal_abort("pthread_attr_setstacksize");
+ }
+ const int r = pthread_create(&thr, &attr, thread_main, arg);
+ if (pthread_attr_destroy(&attr) != 0) {
+ fatal_abort("pthread_attr_destroy");
+ }
+ if (r != 0) {
+ return need_join; /* false */
+ }
+ need_join = true;
+ return need_join; /* true */
+ }
+ void join() {
+ if (!need_join) {
+ return;
+ }
+ int e = 0;
+ if ((e = pthread_join(thr, 0)) != 0) {
+ fatal_abort("pthread_join");
+ }
+ need_join = false;
+ }
+ private:
+ static void *thread_main(void *arg) {
+ thread_base *p = static_cast<thread_base *>(arg);
+ p->run();
+ return 0;
+ }
+ private:
+ pthread_t thr;
+ bool need_join;
+ size_t stack_size;
+};
+
+struct hs_longrun_stat {
+ unsigned long long verify_error_count;
+ unsigned long long runtime_error_count;
+ unsigned long long unknown_count;
+ unsigned long long success_count;
+ hs_longrun_stat()
+ : verify_error_count(0), runtime_error_count(0),
+ unknown_count(0), success_count(0) { }
+ void add(const hs_longrun_stat& x) {
+ verify_error_count += x.verify_error_count;
+ runtime_error_count += x.runtime_error_count;
+ unknown_count += x.unknown_count;
+ success_count += x.success_count;
+ }
+};
+
+struct hs_longrun_thread_base : public thread_base {
+ struct arg_type {
+ int id;
+ std::string worker_type;
+ char op;
+ int lock_flag;
+ const hs_longrun_shared& sh;
+ arg_type(int id, const std::string& worker_type, char op, int lock_flag,
+ const hs_longrun_shared& sh)
+ : id(id), worker_type(worker_type), op(op), lock_flag(lock_flag),
+ sh(sh) { }
+ };
+ arg_type arg;
+ hs_longrun_stat stat;
+ drand48_data randbuf;
+ unsigned int seed;
+ hs_longrun_thread_base(const arg_type& arg)
+ : arg(arg), seed(0) {
+ seed = time(0) + arg.id + 1;
+ srand48_r(seed, &randbuf);
+ }
+ virtual ~hs_longrun_thread_base() { }
+ virtual void run() = 0;
+ size_t rand_record() {
+ double v = 0;
+ drand48_r(&randbuf, &v);
+ const size_t sz = arg.sh.records.size();
+ size_t r = size_t(v * sz);
+ if (r >= sz) {
+ r = 0;
+ }
+ return r;
+ }
+ int verify_update(const std::string& k, const std::string& v1,
+ const std::string& v2, const std::string& v3, record_value& rec,
+ uint32_t num_rows, bool cur_unknown_state);
+ int verify_read(const std::string& k, uint32_t num_rows, uint32_t num_flds,
+ const std::string rrec[4], record_value& rec);
+ int verify_readnolock(const std::string& k, uint32_t num_rows,
+ uint32_t num_flds, const std::string rrec[4]);
+};
+
+int
+hs_longrun_thread_base::verify_update(const std::string& k,
+ const std::string& v1, const std::string& v2, const std::string& v3,
+ record_value& rec, uint32_t num_rows, bool cur_unknown_state)
+{
+ const bool op_success = num_rows == 1;
+ int ret = 0;
+ if (!rec.unknown_state) {
+ if (!rec.deleted && !op_success) {
+ ++stat.verify_error_count;
+ if (arg.sh.verbose > 0) {
+ fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s "
+ "unexpected_update_failure\n",
+ arg.worker_type.c_str(), arg.id, k.c_str());
+ }
+ ret = 1;
+ } else if (rec.deleted && op_success) {
+ ++stat.verify_error_count;
+ if (arg.sh.verbose > 0) {
+ fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s "
+ "unexpected_update_success\n",
+ arg.worker_type.c_str(), arg.id, k.c_str());
+ }
+ ret = 1;
+ }
+ }
+ if (op_success) {
+ rec.values.resize(4);
+ rec.values[0] = k;
+ rec.values[1] = v1;
+ rec.values[2] = v2;
+ rec.values[3] = v3;
+ if (ret == 0 && !rec.unknown_state) {
+ ++stat.success_count;
+ }
+ }
+ rec.unknown_state = cur_unknown_state;
+ if (arg.sh.verbose >= 100 && ret == 0) {
+ fprintf(stderr, "%s %s %s %s %s\n", arg.worker_type.c_str(),
+ k.c_str(), v1.c_str(), v2.c_str(), v3.c_str());
+ }
+ return ret;
+}
+
+int
+hs_longrun_thread_base::verify_read(const std::string& k,
+ uint32_t num_rows, uint32_t num_flds, const std::string rrec[4],
+ record_value& rec)
+{
+ const bool op_success = num_rows != 0;
+ int ret = 0;
+ if (!rec.unknown_state) {
+ if (!rec.deleted && !op_success) {
+ ++stat.verify_error_count;
+ if (arg.sh.verbose > 0) {
+ fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s "
+ "unexpected_read_failure\n",
+ arg.worker_type.c_str(), arg.id, k.c_str());
+ }
+ ret = 1;
+ } else if (rec.deleted && op_success) {
+ ++stat.verify_error_count;
+ if (arg.sh.verbose > 0) {
+ fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s "
+ "unexpected_read_success\n",
+ arg.worker_type.c_str(), arg.id, k.c_str());
+ }
+ ret = 1;
+ } else if (num_flds != 4) {
+ ++stat.verify_error_count;
+ if (arg.sh.verbose > 0) {
+ fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s "
+ "unexpected_read_fldnum %d\n",
+ arg.worker_type.c_str(), arg.id, k.c_str(),
+ static_cast<int>(num_flds));
+ }
+ ret = 1;
+ } else if (rec.deleted) {
+ /* nothing to verify */
+ } else {
+ int diff = 0;
+ for (size_t i = 0; i < 4; ++i) {
+ if (rec.values[i] == rrec[i]) {
+ /* ok */
+ } else {
+ diff = 1;
+ }
+ }
+ if (diff) {
+ std::string mess;
+ for (size_t i = 0; i < 4; ++i) {
+ const std::string& expected = rec.values[i];
+ const std::string& val = rrec[i];
+ mess += " " + val + "/" + expected;
+ }
+ if (arg.sh.verbose > 0) {
+ fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s "
+ "unexpected_read_value %s\n",
+ arg.worker_type.c_str(), arg.id, k.c_str(), mess.c_str());
+ }
+ ret = 1;
+ }
+ }
+ }
+ if (arg.sh.verbose >= 100 && ret == 0) {
+ fprintf(stderr, "%s %s\n", arg.worker_type.c_str(), k.c_str());
+ }
+ if (ret == 0 && !rec.unknown_state) {
+ ++stat.success_count;
+ }
+ return ret;
+}
+
+int
+hs_longrun_thread_base::verify_readnolock(const std::string& k,
+ uint32_t num_rows, uint32_t num_flds, const std::string rrec[4])
+{
+ int ret = 0;
+ if (num_rows != 1 || num_flds != 4) {
+ ++stat.verify_error_count;
+ if (arg.sh.verbose > 0) {
+ fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s "
+ "unexpected_read_failure\n",
+ arg.worker_type.c_str(), arg.id, k.c_str());
+ }
+ ret = 1;
+ }
+ if (arg.sh.verbose >= 100 && ret == 0) {
+ fprintf(stderr, "%s -> %s %s %s %s %s\n", arg.worker_type.c_str(),
+ k.c_str(), rrec[0].c_str(), rrec[1].c_str(), rrec[2].c_str(),
+ rrec[3].c_str());
+ }
+ if (ret == 0) {
+ ++stat.success_count;
+ }
+ return ret;
+}
+
+struct hs_longrun_thread_hs : public hs_longrun_thread_base {
+ hs_longrun_thread_hs(const arg_type& arg)
+ : hs_longrun_thread_base(arg) { }
+ void run();
+ int check_hs_error(const char *mess, record_value *rec);
+ int op_insert(record_value& rec);
+ int op_delete(record_value& rec);
+ int op_update(record_value& rec);
+ int op_read(record_value& rec);
+ int op_readnolock(int k);
+ hstcpcli_ptr cli;
+ socket_args sockargs;
+};
+
+struct lock_guard : noncopyable {
+ lock_guard(mutex& mtx) : mtx(mtx) {
+ mtx.lock();
+ }
+ ~lock_guard() {
+ mtx.unlock();
+ }
+ mutex& mtx;
+};
+
+string_ref
+to_string_ref(const std::string& s)
+{
+ return string_ref(s.data(), s.size());
+}
+
+std::string
+to_string(const string_ref& s)
+{
+ return std::string(s.begin(), s.size());
+}
+
+void
+hs_longrun_thread_hs::run()
+{
+ config c = arg.sh.conf;
+ if (arg.op == 'R' || arg.op == 'N') {
+ c["port"] = to_stdstring(arg.sh.conf.get_int("hsport", 9998));
+ } else {
+ c["port"] = to_stdstring(arg.sh.conf.get_int("hsport_wr", 9999));
+ }
+ sockargs.set(c);
+
+ while (arg.sh.running) {
+ if (cli.get() == 0 || !cli->stable_point()) {
+ cli = hstcpcli_i::create(sockargs);
+ if (check_hs_error("connect", 0) != 0) {
+ cli.reset();
+ continue;
+ }
+ cli->request_buf_open_index(0, "hstestdb", "hstesttbl", "PRIMARY",
+ "k,v1,v2,v3", "k,v1,v2,v3");
+ cli->request_send();
+ if (check_hs_error("openindex_send", 0) != 0) {
+ cli.reset();
+ continue;
+ }
+ size_t num_flds = 0;
+ cli->response_recv(num_flds);
+ if (check_hs_error("openindex_recv", 0) != 0) {
+ cli.reset();
+ continue;
+ }
+ cli->response_buf_remove();
+ }
+ const size_t rec_id = rand_record();
+ if (arg.lock_flag) {
+ record_value& rec = *arg.sh.records[rec_id];
+ lock_guard g(rec.lock);
+ int e = 0;
+ switch (arg.op) {
+ case 'I':
+ e = op_insert(rec);
+ break;
+ case 'D':
+ e = op_delete(rec);
+ break;
+ case 'U':
+ e = op_update(rec);
+ break;
+ case 'R':
+ e = op_read(rec);
+ break;
+ default:
+ break;
+ }
+ } else {
+ int e = 0;
+ switch (arg.op) {
+ case 'N':
+ e = op_readnolock(rec_id);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+int
+hs_longrun_thread_hs::op_insert(record_value& rec)
+{
+ const std::string k = rec.key;
+ const std::string v1 = "iv1_" + k + "_" + to_stdstring(arg.id);
+ const std::string v2 = "iv2_" + k + "_" + to_stdstring(arg.id);
+ const std::string v3 = "iv3_" + k + "_" + to_stdstring(arg.id);
+ const string_ref op_ref("+", 1);
+ const string_ref op_args[4] = {
+ to_string_ref(k),
+ to_string_ref(v1),
+ to_string_ref(v2),
+ to_string_ref(v3)
+ };
+ cli->request_buf_exec_generic(0, op_ref, op_args, 4, 1, 0,
+ string_ref(), 0, 0, 0, 0);
+ cli->request_send();
+ if (check_hs_error("op_insert_send", &rec) != 0) { return 1; }
+ size_t numflds = 0;
+ cli->response_recv(numflds);
+ if (arg.sh.verbose > 10) {
+ const string_ref *row = cli->get_next_row();
+ fprintf(stderr, "HS op=+ errrcode=%d errmess=[%s]\n", cli->get_error_code(),
+ row ? to_string(row[0]).c_str() : "");
+ }
+ const bool op_success = cli->get_error_code() == 0;
+ int ret = 0;
+ if (!rec.unknown_state) {
+ if (rec.deleted && !op_success) {
+ ++stat.verify_error_count;
+ if (arg.sh.verbose > 0) {
+ fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s "
+ "unexpected_insert_failure\n",
+ arg.worker_type.c_str(), arg.id, k.c_str());
+ }
+ ret = 1;
+ } else if (!rec.deleted && op_success) {
+ ++stat.verify_error_count;
+ if (arg.sh.verbose > 0) {
+ fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s "
+ "unexpected_insert_success\n",
+ arg.worker_type.c_str(), arg.id, k.c_str());
+ }
+ ret = 1;
+ }
+ } else {
+ ++stat.unknown_count;
+ }
+ if (op_success) {
+ rec.values.resize(4);
+ rec.values[0] = k;
+ rec.values[1] = v1;
+ rec.values[2] = v2;
+ rec.values[3] = v3;
+ rec.deleted = false;
+ if (arg.sh.verbose >= 100 && ret == 0) {
+ fprintf(stderr, "HS_INSERT %s %s %s %s\n", k.c_str(), v1.c_str(),
+ v2.c_str(), v3.c_str());
+ }
+ if (ret == 0 && !rec.unknown_state) {
+ ++stat.success_count;
+ }
+ rec.unknown_state = false;
+ }
+ cli->response_buf_remove();
+ return ret;
+}
+
+int
+hs_longrun_thread_hs::op_delete(record_value& rec)
+{
+ const std::string k = rec.key;
+ const string_ref op_ref("=", 1);
+ const string_ref op_args[1] = {
+ to_string_ref(k),
+ };
+ const string_ref modop_ref("D", 1);
+ cli->request_buf_exec_generic(0, op_ref, op_args, 1, 1, 0,
+ modop_ref, 0, 0, 0, 0);
+ cli->request_send();
+ if (check_hs_error("op_delete_send", &rec) != 0) { return 1; }
+ size_t numflds = 0;
+ cli->response_recv(numflds);
+ if (check_hs_error("op_delete_recv", &rec) != 0) { return 1; }
+ const string_ref *row = cli->get_next_row();
+ const bool op_success = (numflds > 0 && row != 0 &&
+ to_string(row[0]) == "1");
+ int ret = 0;
+ if (!rec.unknown_state) {
+ if (!rec.deleted && !op_success) {
+ ++stat.verify_error_count;
+ if (arg.sh.verbose > 0) {
+ fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s "
+ "unexpected_delete_failure\n",
+ arg.worker_type.c_str(), arg.id, k.c_str());
+ }
+ ret = 1;
+ } else if (rec.deleted && op_success) {
+ ++stat.verify_error_count;
+ if (arg.sh.verbose > 0) {
+ fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s "
+ "unexpected_delete_success\n",
+ arg.worker_type.c_str(), arg.id, k.c_str());
+ }
+ ret = 1;
+ }
+ }
+ cli->response_buf_remove();
+ if (op_success) {
+ rec.deleted = true;
+ if (ret == 0 && !rec.unknown_state) {
+ ++stat.success_count;
+ }
+ rec.unknown_state = false;
+ }
+ if (arg.sh.verbose >= 100 && ret == 0) {
+ fprintf(stderr, "HS_DELETE %s\n", k.c_str());
+ }
+ return ret;
+}
+
+int
+hs_longrun_thread_hs::op_update(record_value& rec)
+{
+ const std::string k = rec.key;
+ const std::string v1 = "uv1_" + k + "_" + to_stdstring(arg.id);
+ const std::string v2 = "uv2_" + k + "_" + to_stdstring(arg.id);
+ const std::string v3 = "uv3_" + k + "_" + to_stdstring(arg.id);
+ const string_ref op_ref("=", 1);
+ const string_ref op_args[1] = {
+ to_string_ref(k),
+ };
+ const string_ref modop_ref("U", 1);
+ const string_ref modop_args[4] = {
+ to_string_ref(k),
+ to_string_ref(v1),
+ to_string_ref(v2),
+ to_string_ref(v3)
+ };
+ cli->request_buf_exec_generic(0, op_ref, op_args, 1, 1, 0,
+ modop_ref, modop_args, 4, 0, 0);
+ cli->request_send();
+ if (check_hs_error("op_update_send", &rec) != 0) { return 1; }
+ size_t numflds = 0;
+ cli->response_recv(numflds);
+ if (check_hs_error("op_update_recv", &rec) != 0) { return 1; }
+ const string_ref *row = cli->get_next_row();
+ uint32_t num_rows = row
+ ? atoi_uint32_nocheck(row[0].begin(), row[0].end()) : 0;
+ cli->response_buf_remove();
+ const bool cur_unknown_state = (num_rows == 1);
+ return verify_update(k, v1, v2, v3, rec, num_rows, cur_unknown_state);
+}
+
+int
+hs_longrun_thread_hs::op_read(record_value& rec)
+{
+ const std::string k = rec.key;
+ const string_ref op_ref("=", 1);
+ const string_ref op_args[1] = {
+ to_string_ref(k),
+ };
+ cli->request_buf_exec_generic(0, op_ref, op_args, 1, 1, 0,
+ string_ref(), 0, 0, 0, 0);
+ cli->request_send();
+ if (check_hs_error("op_read_send", 0) != 0) { return 1; }
+ size_t num_flds = 0;
+ size_t num_rows = 0;
+ cli->response_recv(num_flds);
+ if (check_hs_error("op_read_recv", 0) != 0) { return 1; }
+ const string_ref *row = cli->get_next_row();
+ std::string rrec[4];
+ if (row != 0 && num_flds == 4) {
+ for (int i = 0; i < 4; ++i) {
+ rrec[i] = to_string(row[i]);
+ }
+ ++num_rows;
+ }
+ row = cli->get_next_row();
+ if (row != 0) {
+ ++num_rows;
+ }
+ cli->response_buf_remove();
+ return verify_read(k, num_rows, num_flds, rrec, rec);
+}
+
+int
+hs_longrun_thread_hs::op_readnolock(int key)
+{
+ const std::string k = to_stdstring(key);
+ const string_ref op_ref("=", 1);
+ const string_ref op_args[1] = {
+ to_string_ref(k),
+ };
+ cli->request_buf_exec_generic(0, op_ref, op_args, 1, 1, 0,
+ string_ref(), 0, 0, 0, 0);
+ cli->request_send();
+ if (check_hs_error("op_read_send", 0) != 0) { return 1; }
+ size_t num_flds = 0;
+ size_t num_rows = 0;
+ cli->response_recv(num_flds);
+ if (check_hs_error("op_read_recv", 0) != 0) { return 1; }
+ const string_ref *row = cli->get_next_row();
+ std::string rrec[4];
+ if (row != 0 && num_flds == 4) {
+ for (int i = 0; i < 4; ++i) {
+ rrec[i] = to_string(row[i]);
+ }
+ ++num_rows;
+ }
+ row = cli->get_next_row();
+ if (row != 0) {
+ ++num_rows;
+ }
+ cli->response_buf_remove();
+ return verify_readnolock(k, num_rows, num_flds, rrec);
+}
+
+int
+hs_longrun_thread_hs::check_hs_error(const char *mess, record_value *rec)
+{
+ const int err = cli->get_error_code();
+ if (err == 0) {
+ return 0;
+ }
+ ++stat.runtime_error_count;
+ if (arg.sh.verbose > 0) {
+ const std::string estr = cli->get_error();
+ fprintf(stderr, "RUNTIME_ERROR: op=%c wid=%d %s: %d %s\n",
+ arg.op, arg.id, mess, err, estr.c_str());
+ }
+ if (rec) {
+ rec->unknown_state = true;
+ }
+ return 1;
+}
+
+struct hs_longrun_thread_my : public hs_longrun_thread_base {
+ hs_longrun_thread_my(const arg_type& arg)
+ : hs_longrun_thread_base(arg), connected(false) { }
+ void run();
+ void show_mysql_error(const char *mess, record_value *rec);
+ int op_insert(record_value& rec);
+ int op_delete(record_value& rec);
+ int op_update(record_value& rec);
+ int op_delins(record_value& rec);
+ int op_read(record_value& rec);
+ auto_mysql db;
+ bool connected;
+};
+
+void
+hs_longrun_thread_my::run()
+{
+ const std::string mysql_host = arg.sh.conf.get_str("host", "localhost");
+ const std::string mysql_user = arg.sh.conf.get_str("mysqluser", "root");
+ const std::string mysql_passwd = arg.sh.conf.get_str("mysqlpass", "");
+ const std::string mysql_dbname = "hstestdb";
+
+ while (arg.sh.running) {
+ if (!connected) {
+ if (!mysql_real_connect(db, mysql_host.c_str(), mysql_user.c_str(),
+ mysql_passwd.c_str(), mysql_dbname.c_str(), mysql_port, 0, 0)) {
+ show_mysql_error("mysql_real_connect", 0);
+ continue;
+ }
+ }
+ connected = true;
+ const size_t rec_id = rand_record();
+ record_value& rec = *arg.sh.records[rec_id];
+ lock_guard g(rec.lock);
+ int e = 0;
+ switch (arg.op) {
+ #if 0
+ case 'I':
+ e = op_insert(rec);
+ break;
+ case 'D':
+ e = op_delete(rec);
+ break;
+ case 'U':
+ e = op_update(rec);
+ break;
+ #endif
+ case 'T':
+ e = op_delins(rec);
+ break;
+ case 'R':
+ e = op_read(rec);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+int
+hs_longrun_thread_my::op_delins(record_value& rec)
+{
+ const std::string k = rec.key;
+ const std::string v1 = "div1_" + k + "_" + to_stdstring(arg.id);
+ const std::string v2 = "div2_" + k + "_" + to_stdstring(arg.id);
+ const std::string v3 = "div3_" + k + "_" + to_stdstring(arg.id);
+ int success = 0;
+ bool cur_unknown_state = false;
+ do {
+ char query[1024];
+ #if 1
+ if (mysql_query(db, "begin") != 0) {
+ if (arg.sh.verbose >= 20) {
+ fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), "begin");
+ }
+ break;
+ }
+ #endif
+ cur_unknown_state = true;
+ snprintf(query, 1024,
+ "delete from hstesttbl where k = '%s'", k.c_str());
+ if (mysql_query(db, query) != 0) {
+ if (arg.sh.verbose >= 20) {
+ fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), query);
+ }
+ break;
+ }
+ if (mysql_affected_rows(db) != 1) {
+ if (arg.sh.verbose >= 20) {
+ fprintf(stderr, "mysql: notfound: [%s]\n", query);
+ }
+ break;
+ }
+ snprintf(query, 1024,
+ "insert into hstesttbl values ('%s', '%s', '%s', '%s')",
+ k.c_str(), v1.c_str(), v2.c_str(), v3.c_str());
+ if (mysql_query(db, query) != 0) {
+ if (arg.sh.verbose >= 20) {
+ fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), query);
+ }
+ break;
+ }
+ #if 1
+ if (mysql_query(db, "commit") != 0) {
+ if (arg.sh.verbose >= 20) {
+ fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), "commit");
+ }
+ break;
+ }
+ #endif
+ success = true;
+ cur_unknown_state = false;
+ } while (false);
+ return verify_update(k, v1, v2, v3, rec, (success != 0), cur_unknown_state);
+}
+
+int
+hs_longrun_thread_my::op_read(record_value& rec)
+{
+ const std::string k = rec.key;
+ char query[1024] = { 0 };
+ const int len = snprintf(query, 1024,
+ "select k,v1,v2,v3 from hstesttbl where k='%s'", k.c_str());
+ const int r = mysql_real_query(db, query, len > 0 ? len : 0);
+ if (r != 0) {
+ show_mysql_error(query, 0);
+ return 1;
+ }
+ MYSQL_ROW row = 0;
+ unsigned long *lengths = 0;
+ unsigned int num_rows = 0;
+ unsigned int num_flds = 0;
+ auto_mysql_res res(db);
+ std::string rrec[4];
+ if (res != 0) {
+ num_flds = mysql_num_fields(res);
+ row = mysql_fetch_row(res);
+ if (row != 0) {
+ lengths = mysql_fetch_lengths(res);
+ if (num_flds == 4) {
+ for (int i = 0; i < 4; ++i) {
+ rrec[i] = std::string(row[i], lengths[i]);
+ }
+ }
+ ++num_rows;
+ row = mysql_fetch_row(res);
+ if (row != 0) {
+ ++num_rows;
+ }
+ }
+ }
+ return verify_read(k, num_rows, num_flds, rrec, rec);
+}
+
+void
+hs_longrun_thread_my::show_mysql_error(const char *mess, record_value *rec)
+{
+ ++stat.runtime_error_count;
+ if (arg.sh.verbose > 0) {
+ fprintf(stderr, "RUNTIME_ERROR: op=%c wid=%d [%s]: %s\n",
+ arg.op, arg.id, mess, mysql_error(db));
+ }
+ if (rec) {
+ rec->unknown_state = true;
+ }
+ db.reset();
+ connected = false;
+}
+
+void
+mysql_do(MYSQL *db, const char *query)
+{
+ if (mysql_real_query(db, query, strlen(query)) != 0) {
+ fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), query);
+ fatal_exit("mysql_do");
+ }
+}
+
+void
+hs_longrun_init_table(const config& conf, int num_prepare,
+ hs_longrun_shared& shared)
+{
+ const std::string mysql_host = conf.get_str("host", "localhost");
+ const std::string mysql_user = conf.get_str("mysqluser", "root");
+ const std::string mysql_passwd = conf.get_str("mysqlpass", "");
+ const std::string mysql_dbname = "";
+ auto_mysql db;
+ if (!mysql_real_connect(db, mysql_host.c_str(), mysql_user.c_str(),
+ mysql_passwd.c_str(), mysql_dbname.c_str(), mysql_port, 0, 0)) {
+ fprintf(stderr, "mysql: error=[%s]\n", mysql_error(db));
+ fatal_exit("hs_longrun_init_table");
+ }
+ mysql_do(db, "drop database if exists hstestdb");
+ mysql_do(db, "create database hstestdb");
+ mysql_do(db, "use hstestdb");
+ mysql_do(db,
+ "create table hstesttbl ("
+ "k int primary key,"
+ "v1 varchar(32) not null,"
+ "v2 varchar(32) not null,"
+ "v3 varchar(32) not null"
+ ") character set utf8 collate utf8_bin engine = innodb");
+ for (int i = 0; i < num_prepare; ++i) {
+ const std::string i_str = to_stdstring(i);
+ const std::string v1 = "pv1_" + i_str;
+ const std::string v2 = "pv2_" + i_str;
+ const std::string v3 = "pv3_" + i_str;
+ char buf[1024];
+ snprintf(buf, 1024, "insert into hstesttbl(k, v1, v2, v3) values"
+ "(%d, '%s', '%s', '%s')", i, v1.c_str(), v2.c_str(), v3.c_str());
+ mysql_do(db, buf);
+ record_value *rec = shared.records[i];
+ rec->key = i_str;
+ rec->values.resize(4);
+ rec->values[0] = i_str;
+ rec->values[1] = v1;
+ rec->values[2] = v2;
+ rec->values[3] = v3;
+ rec->deleted = false;
+ }
+}
+
+int
+hs_longrun_main(int argc, char **argv)
+{
+ hs_longrun_shared shared;
+ parse_args(argc, argv, shared.conf);
+ shared.conf["host"] = shared.conf.get_str("host", "localhost");
+ shared.verbose = shared.conf.get_int("verbose", 1);
+ const int table_size = shared.conf.get_int("table_size", 10000);
+ for (int i = 0; i < table_size; ++i) {
+ std::auto_ptr<record_value> rec(new record_value());
+ rec->key = to_stdstring(i);
+ shared.records.push_back_ptr(rec);
+ }
+ mysql_library_init(0, 0, 0);
+ const int duration = shared.conf.get_int("duration", 10);
+ const int num_hsinsert = shared.conf.get_int("num_hsinsert", 10);
+ const int num_hsdelete = shared.conf.get_int("num_hsdelete", 10);
+ const int num_hsupdate = shared.conf.get_int("num_hsupdate", 10);
+ const int num_hsread = shared.conf.get_int("num_hsread", 10);
+ const int num_myread = shared.conf.get_int("num_myread", 10);
+ const int num_mydelins = shared.conf.get_int("num_mydelins", 10);
+ int num_hsreadnolock = shared.conf.get_int("num_hsreadnolock", 10);
+ const bool always_filled = (num_hsinsert == 0 && num_hsdelete == 0);
+ if (!always_filled) {
+ num_hsreadnolock = 0;
+ }
+ hs_longrun_init_table(shared.conf, always_filled ? table_size : 0,
+ shared);
+ /* create worker threads */
+ static const struct thrtmpl_type {
+ const char *type; char op; int num; int hs; int lock;
+ } thrtmpl[] = {
+ { "hsinsert", 'I', num_hsinsert, 1, 1 },
+ { "hsdelete", 'D', num_hsdelete, 1, 1 },
+ { "hsupdate", 'U', num_hsupdate, 1, 1 },
+ { "hsread", 'R', num_hsread, 1, 1 },
+ { "hsreadnolock", 'N', num_hsreadnolock, 1, 0 },
+ { "myread", 'R', num_myread, 0, 1 },
+ { "mydelins", 'T', num_mydelins, 0, 1 },
+ };
+ typedef auto_ptrcontainer< std::vector<hs_longrun_thread_base *> > thrs_type;
+ thrs_type thrs;
+ for (size_t i = 0; i < sizeof(thrtmpl)/sizeof(thrtmpl[0]); ++i) {
+ const thrtmpl_type& e = thrtmpl[i];
+ for (int j = 0; j < e.num; ++j) {
+ int id = thrs.size();
+ const hs_longrun_thread_hs::arg_type arg(id, e.type, e.op, e.lock,
+ shared);
+ std::auto_ptr<hs_longrun_thread_base> thr;
+ if (e.hs) {
+ thr.reset(new hs_longrun_thread_hs(arg));
+ } else {
+ thr.reset(new hs_longrun_thread_my(arg));
+ }
+ thrs.push_back_ptr(thr);
+ }
+ }
+ shared.num_threads = thrs.size();
+ /* start threads */
+ fprintf(stderr, "START\n");
+ shared.running = 1;
+ for (size_t i = 0; i < thrs.size(); ++i) {
+ thrs[i]->start();
+ }
+ /* wait */
+ sleep(duration);
+ /* stop thread */
+ shared.running = 0;
+ for (size_t i = 0; i < thrs.size(); ++i) {
+ thrs[i]->join();
+ }
+ fprintf(stderr, "DONE\n");
+ /* summary */
+ typedef std::map<std::string, hs_longrun_stat> stat_map;
+ stat_map sm;
+ for (size_t i = 0; i < thrs.size(); ++i) {
+ hs_longrun_thread_base *const thr = thrs[i];
+ const std::string wt = thr->arg.worker_type;
+ hs_longrun_stat& v = sm[wt];
+ v.add(thr->stat);
+ }
+ hs_longrun_stat total;
+ for (stat_map::const_iterator i = sm.begin(); i != sm.end(); ++i) {
+ if (i->second.verify_error_count != 0) {
+ fprintf(stderr, "%s verify_error %llu\n", i->first.c_str(),
+ i->second.verify_error_count);
+ }
+ if (i->second.runtime_error_count) {
+ fprintf(stderr, "%s runtime_error %llu\n", i->first.c_str(),
+ i->second.runtime_error_count);
+ }
+ if (i->second.unknown_count) {
+ fprintf(stderr, "%s unknown %llu\n", i->first.c_str(),
+ i->second.unknown_count);
+ }
+ fprintf(stderr, "%s success %llu\n", i->first.c_str(),
+ i->second.success_count);
+ total.add(i->second);
+ }
+ if (total.verify_error_count != 0) {
+ fprintf(stderr, "TOTAL verify_error %llu\n", total.verify_error_count);
+ }
+ if (total.runtime_error_count != 0) {
+ fprintf(stderr, "TOTAL runtime_error %llu\n", total.runtime_error_count);
+ }
+ if (total.unknown_count != 0) {
+ fprintf(stderr, "TOTAL unknown %llu\n", total.unknown_count);
+ }
+ fprintf(stderr, "TOTAL success %llu\n", total.success_count);
+ mysql_library_end();
+ return 0;
+}
+
+};
+
+int
+main(int argc, char **argv)
+{
+ return dena::hs_longrun_main(argc, argv);
+}
+
diff --git a/plugin/handler_socket/client/hspool_test.pl b/plugin/handler_socket/client/hspool_test.pl
new file mode 100755
index 00000000000..7fe073301b1
--- /dev/null
+++ b/plugin/handler_socket/client/hspool_test.pl
@@ -0,0 +1,224 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use DB::HandlerSocket::Pool;
+use DBI;
+
+my %conf = ();
+for my $i (@ARGV) {
+ my ($k, $v) = split(/=/, $i);
+ $conf{$k} = $v;
+}
+
+my $verbose = get_conf("verbose", 0);
+my $actions_str = get_conf("actions",
+ "create,insert,verify,verify2,verify3,verify4,clean");
+my $tablesize = get_conf("tablesize", 1000);
+my $db = get_conf("db", "hstestdb");
+my $table = get_conf("table", "testtbl");
+my $table_schema = get_conf("table_schema", undef);
+my $engine = get_conf("engine", "innodb");
+my $host = get_conf("host", "localhost");
+my $mysqlport = get_conf("mysqlport", 3306);
+my $hsport_rd = get_conf("hsport_rd", 9998);
+my $hsport_wr = get_conf("hsport_wr", 9999);
+my $loop = get_conf("loop", 10000);
+my $op = get_conf("op", "=");
+my $ssps = get_conf("ssps", 0);
+my $num_moreflds = get_conf("moreflds", 0);
+my $moreflds_prefix = get_conf("moreflds_prefix", "f");
+my $mysql_user = 'root';
+my $mysql_password = '';
+
+my $dsn = "DBI:mysql:database=;host=$host;port=$mysqlport"
+ . ";mysql_server_prepare=$ssps";
+my $dbh = DBI->connect($dsn, $mysql_user, $mysql_password,
+ { RaiseError => 1 });
+my $hsargs = { 'host' => $host, 'port' => $hsport_rd };
+my $hspool = new DB::HandlerSocket::Pool({
+ hostmap => {
+ "$db.$table" => {
+ host => $host,
+ port => $hsport_rd,
+ },
+ },
+ resolve => undef,
+ error => undef,
+});
+$table_schema = "(k int primary key, fc30 varchar(30), ft text)"
+ if (!defined($table_schema));
+
+my @actions = split(/,/, $actions_str);
+for my $action (@actions) {
+ print "ACTION: $action\n";
+ eval "hstest_$action()";
+ if ($@) {
+ die $@;
+ }
+ print "ACTION: $action DONE\n";
+}
+
+sub get_conf {
+ my ($key, $def) = @_;
+ my $val = $conf{$key};
+ if ($val) {
+ print "$key=$val\n";
+ } else {
+ $val = $def;
+ my $defstr = $def || "(undef)";
+ print "$key=$defstr(default)\n";
+ }
+ return $val;
+}
+
+sub hstest_create {
+ $dbh->do("drop database if exists $db");
+ $dbh->do("create database $db");
+ $dbh->do("use $db");
+ $dbh->do("create table $table $table_schema engine=$engine");
+}
+
+sub hstest_dump {
+ $dbh->do("use $db");
+ my $sth = $dbh->prepare("select * from $table");
+ $sth->execute();
+ my $arr = $sth->fetchall_arrayref();
+ for my $rec (@$arr) {
+ print "REC:";
+ for my $row (@$rec) {
+ print " $row";
+ }
+ print "\n";
+ }
+}
+
+sub hstest_insert {
+ $dbh->do("use $db");
+ my $sth = $dbh->prepare("insert into $table values (?, ?, ?)");
+ for (my $k = 0; $k < $tablesize; ++$k) {
+ my $fc30 = "fc30_$k";
+ my $ft = "ft_$k";
+ $sth->execute($k, $fc30, $ft);
+ }
+}
+
+sub hstest_verify {
+ $dbh->do("use $db");
+ my $sth = $dbh->prepare("select * from $table order by k");
+ $sth->execute();
+ my $arr = $sth->fetchall_arrayref();
+ my $hsres = $hspool->index_find($db, $table, "PRIMARY", "k,fc30,ft",
+ ">=", [ 0 ], $tablesize, 0);
+ for (my $i = 0; $i < $tablesize; ++$i) {
+ my $rec = $arr->[$i];
+ my $differ = 0;
+ print "REC:" if $verbose;
+ for (my $j = 0; $j < 3; ++$j) {
+ my $fld = $rec->[$j];
+ my $hsidx = $i * 3 + $j;
+ my $hsfld = $hsres->[$hsidx];
+ if ($hsfld ne $fld) {
+ $differ = 1;
+ }
+ if ($differ) {
+ print " $fld:$hsfld" if $verbose;
+ } else {
+ print " $hsfld" if $verbose;
+ }
+ }
+ print "\n" if $verbose;
+ if ($differ) {
+ die "verification failed";
+ }
+ }
+}
+
+sub hstest_verify2 {
+ $dbh->do("use $db");
+ my $sth = $dbh->prepare("select * from $table order by k");
+ $sth->execute();
+ my $arr = $sth->fetchall_arrayref();
+ my $hsresa = $hspool->index_find_multi($db, $table, "PRIMARY",
+ "k,fc30,ft", [ [ -1, ">=", [ 0 ], $tablesize, 0 ] ]);
+ my $hsres = $hsresa->[0];
+ for (my $i = 0; $i < $tablesize; ++$i) {
+ my $rec = $arr->[$i];
+ my $differ = 0;
+ print "REC:" if $verbose;
+ for (my $j = 0; $j < 3; ++$j) {
+ my $fld = $rec->[$j];
+ my $hsidx = $i * 3 + $j;
+ my $hsfld = $hsres->[$hsidx];
+ if ($hsfld ne $fld) {
+ $differ = 1;
+ }
+ if ($differ) {
+ print " $fld:$hsfld" if $verbose;
+ } else {
+ print " $hsfld" if $verbose;
+ }
+ }
+ print "\n" if $verbose;
+ if ($differ) {
+ die "verification failed";
+ }
+ }
+}
+
+sub hashref_to_str {
+ my $href = $_[0];
+ my $r = '';
+ for my $k (sort keys %$href) {
+ my $v = $href->{$k};
+ $r .= "($k=>$v)";
+ }
+ return $r;
+}
+
+sub hstest_verify3 {
+ $dbh->do("use $db");
+ my $sth = $dbh->prepare("select * from $table order by k");
+ $sth->execute();
+ my $hsres_t = $hspool->index_find($db, $table, "PRIMARY", "k,fc30,ft",
+ ">=", [ 0 ], $tablesize, 0);
+ my $hsres = DB::HandlerSocket::Pool::result_single_to_hasharr(
+ [ 'k', 'fc30', 'ft' ], $hsres_t);
+ for (my $i = 0; $i < $tablesize; ++$i) {
+ my $mystr = hashref_to_str($sth->fetchrow_hashref());
+ my $hsstr = hashref_to_str($hsres->[$i]);
+ if ($mystr ne $hsstr) {
+ print "DIFF my=[$mystr] hs=[$hsstr]\n" if $verbose;
+ die "verification failed";
+ } else {
+ print "OK $hsstr\n" if $verbose;
+ }
+ }
+}
+
+sub hstest_verify4 {
+ $dbh->do("use $db");
+ my $sth = $dbh->prepare("select * from $table order by k");
+ $sth->execute();
+ my $hsres_t = $hspool->index_find($db, $table, "PRIMARY", "k,fc30,ft",
+ ">=", [ 0 ], $tablesize, 0);
+ my $hsres = DB::HandlerSocket::Pool::result_single_to_hashhash(
+ [ 'k', 'fc30', 'ft' ], 'k', $hsres_t);
+ my $rechash = $sth->fetchall_hashref('k');
+ while (my ($k, $href) = each (%$rechash)) {
+ my $mystr = hashref_to_str($href);
+ my $hsstr = hashref_to_str($hsres->{$k});
+ if ($mystr ne $hsstr) {
+ print "DIFF my=[$mystr] hs=[$hsstr]\n" if $verbose;
+ die "verification failed";
+ } else {
+ print "OK $hsstr\n" if $verbose;
+ }
+ }
+}
+
+sub hstest_clean {
+ $hspool->clear_pool();
+ $dbh->do("drop database if exists $db");
+}
+
diff --git a/plugin/handler_socket/client/hstest.cpp b/plugin/handler_socket/client/hstest.cpp
new file mode 100644
index 00000000000..b5551fed81c
--- /dev/null
+++ b/plugin/handler_socket/client/hstest.cpp
@@ -0,0 +1,1532 @@
+
+// vim:sw=2:ai
+
+#include <signal.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <string.h>
+#include <vector>
+#include <stdlib.h>
+#include <memory>
+#include <errno.h>
+#include <mysql.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "util.hpp"
+#include "auto_ptrcontainer.hpp"
+#include "socket.hpp"
+#include "thread.hpp"
+#include "hstcpcli.hpp"
+
+#if __GNUC__ >= 4
+long atomic_exchange_and_add(volatile long *valp, long c)
+{
+ return __sync_fetch_and_add(valp, c);
+}
+#else
+#include <bits/atomicity.h>
+using namespace __gnu_cxx;
+long atomic_exchange_and_add(volatile long *valp, long c)
+{
+ return __exchange_and_add((volatile _Atomic_word *)valp, c);
+}
+#endif
+
+namespace dena {
+
+struct auto_mysql : private noncopyable {
+ auto_mysql() : db(0) {
+ reset();
+ }
+ ~auto_mysql() {
+ if (db) {
+ mysql_close(db);
+ }
+ }
+ void reset() {
+ if (db) {
+ mysql_close(db);
+ }
+ if ((db = mysql_init(0)) == 0) {
+ fatal_abort("failed to initialize mysql client");
+ }
+ }
+ operator MYSQL *() const { return db; }
+ private:
+ MYSQL *db;
+};
+
+struct auto_mysql_res : private noncopyable {
+ auto_mysql_res(MYSQL *db) {
+ res = mysql_store_result(db);
+ }
+ ~auto_mysql_res() {
+ if (res) {
+ mysql_free_result(res);
+ }
+ }
+ operator MYSQL_RES *() const { return res; }
+ private:
+ MYSQL_RES *res;
+};
+
+struct auto_mysql_stmt : private noncopyable {
+ auto_mysql_stmt(MYSQL *db) {
+ stmt = mysql_stmt_init(db);
+ }
+ ~auto_mysql_stmt() {
+ if (stmt) {
+ mysql_stmt_close(stmt);
+ }
+ }
+ operator MYSQL_STMT *() const { return stmt; }
+ private:
+ MYSQL_STMT *stmt;
+};
+
+namespace {
+
+double
+gettimeofday_double()
+{
+ struct timeval tv;
+ if (gettimeofday(&tv, 0) != 0) {
+ fatal_abort("gettimeofday");
+ }
+ return static_cast<double>(tv.tv_usec) / 1000000 + tv.tv_sec;
+}
+
+// unused
+void
+wait_close(int fd)
+{
+ char buf[1024];
+ while (true) {
+ int r = read(fd, buf, sizeof(buf));
+ if (r <= 0) {
+ break;
+ }
+ }
+}
+
+// unused
+void
+gentle_close(int fd)
+{
+ int r = shutdown(fd, SHUT_WR);
+ if (r != 0) {
+ return;
+ }
+ wait_close(fd);
+}
+
+};
+
+struct hstest_shared {
+ config conf;
+ socket_args arg;
+ int verbose;
+ size_t loop;
+ size_t pipe;
+ char op;
+ long num_threads;
+ mutable volatile long count;
+ mutable volatile long conn_count;
+ long wait_conn;
+ volatile char *keygen;
+ long keygen_size;
+ mutable volatile int enable_timing;
+ int usleep;
+ int dump;
+ hstest_shared() : verbose(0), loop(0), pipe(0), op('G'), num_threads(0),
+ count(0), conn_count(0), wait_conn(0), keygen(0), keygen_size(0),
+ enable_timing(0), usleep(0), dump(0) { }
+ void increment_count(unsigned int c = 1) const volatile {
+ atomic_exchange_and_add(&count, c);
+ }
+ void increment_conn(unsigned int c) const volatile {
+ atomic_exchange_and_add(&conn_count, c);
+ while (wait_conn != 0 && conn_count < wait_conn) {
+ sleep(1);
+ }
+ // fprintf(stderr, "wait_conn=%ld done\n", wait_conn);
+ }
+};
+
+struct hstest_thread {
+ struct arg_type {
+ size_t id;
+ const hstest_shared& sh;
+ bool watch_flag;
+ arg_type(size_t i, const hstest_shared& s, bool w)
+ : id(i), sh(s), watch_flag(w) { }
+ };
+ hstest_thread(const arg_type& a) : arg(a), io_success_count(0),
+ op_success_count(0), response_min(99999), response_max(0),
+ response_sum(0), response_avg(0) { }
+ void operator ()();
+ void test_1();
+ void test_2_3(int test_num);
+ void test_4_5(int test_num);
+ void test_6(int test_num);
+ void test_7(int test_num);
+ void test_8(int test_num);
+ void test_9(int test_num);
+ void test_10(int test_num);
+ void test_11(int test_num);
+ void test_12(int test_num);
+ void test_21(int test_num);
+ void test_22(int test_num);
+ void test_watch();
+ void sleep_if();
+ void set_timing(double time_spent);
+ arg_type arg;
+ auto_file fd;
+ size_t io_success_count;
+ size_t op_success_count;
+ double response_min, response_max, response_sum, response_avg;
+};
+
+void
+hstest_thread::test_1()
+{
+ char buf[1024];
+ unsigned int seed = arg.id;
+ seed ^= arg.sh.conf.get_int("seed_xor", 0);
+ std::string err;
+ if (socket_connect(fd, arg.sh.arg, err) != 0) {
+ fprintf(stderr, "connect: %d %s\n", errno, strerror(errno));
+ return;
+ }
+ const char op = arg.sh.op;
+ const int tablesize = arg.sh.conf.get_int("tablesize", 0);
+ for (size_t i = 0; i < arg.sh.loop; ++i) {
+ for (size_t j = 0; j < arg.sh.pipe; ++j) {
+ int k = 0, v = 0, len = 0;
+ if (op == 'G') {
+ k = rand_r(&seed);
+ v = rand_r(&seed); /* unused */
+ if (tablesize != 0) {
+ k &= tablesize;
+ }
+ len = snprintf(buf, sizeof(buf), "%c\tk%d\n", op, k);
+ } else {
+ k = rand_r(&seed);
+ v = rand_r(&seed);
+ if (tablesize != 0) {
+ k &= tablesize;
+ }
+ len = snprintf(buf, sizeof(buf), "%c\tk%d\tv%d\n", op, k, v);
+ }
+ const int wlen = write(fd.get(), buf, len);
+ if (wlen != len) {
+ return;
+ }
+ }
+ size_t read_cnt = 0;
+ size_t read_pos = 0;
+ while (read_cnt < arg.sh.pipe) {
+ const int rlen = read(fd.get(), buf + read_pos, sizeof(buf) - read_pos);
+ if (rlen <= 0) {
+ return;
+ }
+ read_pos += rlen;
+ while (true) {
+ const char *const p = static_cast<const char *>(memchr(buf, '\n',
+ read_pos));
+ if (p == 0) {
+ break;
+ }
+ ++read_cnt;
+ ++io_success_count;
+ arg.sh.increment_count();
+ if (p != buf && buf[0] == '=') {
+ ++op_success_count;
+ }
+ const size_t rest_size = buf + read_pos - (p + 1);
+ if (rest_size != 0) {
+ memmove(buf, p + 1, rest_size);
+ }
+ read_pos = rest_size;
+ }
+ }
+ }
+}
+
+void
+hstest_thread::test_2_3(int test_num)
+{
+#if 0
+ char buf_k[128], buf_v[128];
+ unsigned int seed = arg.id;
+ op_base_t op = static_cast<op_base_t>(arg.sh.op);
+ micli_ptr hnd;
+ if (test_num == 2) {
+ hnd = micli_i::create_remote(arg.sh.conf);
+ } else if (test_num == 3) {
+ // hnd = micli_i::create_inproc(arg.sh.localdb);
+ }
+ if (hnd.get() == 0) {
+ return;
+ }
+ for (size_t i = 0; i < arg.sh.loop; ++i) {
+ for (size_t j = 0; j < arg.sh.pipe; ++j) {
+ int k = 0, v = 0, klen = 0, vlen = 0;
+ k = rand_r(&seed);
+ klen = snprintf(buf_k, sizeof(buf_k), "k%d", k);
+ v = rand_r(&seed); /* unused */
+ vlen = snprintf(buf_v, sizeof(buf_v), "v%d", v);
+ string_ref arr[2];
+ arr[0] = string_ref(buf_k, klen);
+ arr[1] = string_ref(buf_v, vlen);
+ pstrarr_ptr rec(arr, 2);
+ if (hnd->execute(op, 0, 0, rec.get_const())) {
+ ++io_success_count;
+ arg.sh.increment_count();
+ const dataset& res = hnd->get_result_ref();
+ if (res.size() == 1) {
+ ++op_success_count;
+ }
+ }
+ }
+ }
+#endif
+}
+
+void
+hstest_thread::test_4_5(int test_num)
+{
+#if 0
+ char buf_k[128], buf_v[8192];
+ memset(buf_v, ' ', sizeof(buf_v));
+ unsigned int seed = arg.id;
+ op_base_t op = static_cast<op_base_t>(arg.sh.op);
+ micli_ptr hnd;
+ if (test_num == 4) {
+ hnd = micli_i::create_remote(arg.sh.conf);
+ } else if (test_num == 5) {
+ hnd = micli_i::create_inproc(arg.sh.localdb);
+ }
+ if (hnd.get() == 0) {
+ return;
+ }
+ for (size_t i = 0; i < arg.sh.loop; ++i) {
+ for (size_t j = 0; j < arg.sh.pipe; ++j) {
+ int k = 0, klen = 0, vlen = 0;
+ k = i & 0x0000ffffUL;
+ if (k == 0) {
+ fprintf(stderr, "k=0\n");
+ }
+ klen = snprintf(buf_k, sizeof(buf_k), "k%d", k);
+ vlen = rand_r(&seed) % 8192;
+ string_ref arr[2];
+ arr[0] = string_ref(buf_k, klen);
+ arr[1] = string_ref(buf_v, vlen);
+ pstrarr_ptr rec(arr, 2);
+ if (hnd->execute(op, 0, 0, rec.get_const())) {
+ ++io_success_count;
+ const dataset& res = hnd->get_result_ref();
+ if (res.size() == 1) {
+ ++op_success_count;
+ }
+ }
+ }
+ }
+#endif
+}
+
+void
+hstest_thread::test_6(int test_num)
+{
+ int count = arg.sh.conf.get_int("count", 1);
+ auto_file fds[count];
+ for (int i = 0; i < count; ++i) {
+ const double t1 = gettimeofday_double();
+ std::string err;
+ if (socket_connect(fds[i], arg.sh.arg, err) != 0) {
+ fprintf(stderr, "id=%zu i=%d err=%s\n", arg.id, i, err.c_str());
+ }
+ const double t2 = gettimeofday_double();
+ if (t2 - t1 > 1) {
+ fprintf(stderr, "id=%zu i=%d time %f\n", arg.id, i, t2 - t1);
+ }
+ }
+}
+
+void
+hstest_thread::test_7(int num)
+{
+ /*
+ set foo 0 0 10
+ 0123456789
+ STORED
+ get foo
+ VALUE foo 0 10
+ 0123456789
+ END
+ get var
+ END
+ */
+ char buf[1024];
+ const int keep_connection = arg.sh.conf.get_int("keep_connection", 1);
+ unsigned int seed = arg.id;
+ seed ^= arg.sh.conf.get_int("seed_xor", 0);
+ const int tablesize = arg.sh.conf.get_int("tablesize", 0);
+ const char op = arg.sh.op;
+ for (size_t i = 0; i < arg.sh.loop; ++i) {
+ const double tm1 = gettimeofday_double();
+ std::string err;
+ if (fd.get() < 0 && socket_connect(fd, arg.sh.arg, err) != 0) {
+ fprintf(stderr, "connect: %d %s\n", errno, strerror(errno));
+ return;
+ }
+ for (size_t j = 0; j < arg.sh.pipe; ++j) {
+ int k = 0, v = 0, len = 0;
+ if (op == 'G') {
+ k = rand_r(&seed);
+ v = rand_r(&seed); /* unused */
+ if (tablesize != 0) {
+ k &= tablesize;
+ }
+ len = snprintf(buf, sizeof(buf), "get k%d\r\n", k);
+ } else {
+ k = rand_r(&seed);
+ v = rand_r(&seed);
+ if (tablesize != 0) {
+ k &= tablesize;
+ }
+ char vbuf[1024];
+ int vlen = snprintf(vbuf, sizeof(vbuf),
+ "v%d"
+ // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ , v);
+ len = snprintf(buf, sizeof(buf), "set k%d 0 0 %d\r\n%s\r\n",
+ k, vlen, vbuf);
+ }
+ const int wlen = write(fd.get(), buf, len);
+ if (wlen != len) {
+ return;
+ }
+ }
+ size_t read_cnt = 0;
+ size_t read_pos = 0;
+ bool read_response_done = false;
+ bool expect_value = false;
+ while (!read_response_done) {
+ const int rlen = read(fd.get(), buf + read_pos, sizeof(buf) - read_pos);
+ if (rlen <= 0) {
+ return;
+ }
+ read_pos += rlen;
+ while (true) {
+ const char *const p = static_cast<const char *>(memchr(buf, '\n',
+ read_pos));
+ if (p == 0) {
+ break;
+ }
+ ++read_cnt;
+ if (expect_value) {
+ expect_value = false;
+ } else if (p >= buf + 6 && memcmp(buf, "VALUE ", 6) == 0) {
+ expect_value = true;
+ ++op_success_count;
+ } else {
+ if (p == buf + 7 && memcmp(buf, "STORED\r", 7) == 0) {
+ ++op_success_count;
+ }
+ read_response_done = true;
+ }
+ const size_t rest_size = buf + read_pos - (p + 1);
+ if (rest_size != 0) {
+ memmove(buf, p + 1, rest_size);
+ }
+ read_pos = rest_size;
+ }
+ ++io_success_count;
+ }
+ arg.sh.increment_count();
+ if (!keep_connection) {
+ fd.close();
+ }
+ const double tm2 = gettimeofday_double();
+ set_timing(tm2 - tm1);
+ sleep_if();
+ }
+}
+
+struct rec {
+ std::string key;
+ std::string value;
+};
+
+void
+hstest_thread::test_8(int test_num)
+{
+#if 0
+ char buf_k[128], buf_v[128];
+ unsigned int seed = arg.id;
+ // op_base_t op = static_cast<op_base_t>(arg.sh.op);
+ using namespace boost::multi_index;
+ typedef member<rec, std::string, &rec::key> rec_get_key;
+ typedef ordered_unique<rec_get_key> oui;
+ typedef multi_index_container< rec, indexed_by<oui> > mic;
+ #if 0
+ typedef std::map<std::string, std::string> m_type;
+ m_type m;
+ #endif
+ mic m;
+ for (size_t i = 0; i < arg.sh.loop; ++i) {
+ for (size_t j = 0; j < arg.sh.pipe; ++j) {
+ int k = 0, v = 0, klen = 0, vlen = 0;
+ k = rand_r(&seed);
+ klen = snprintf(buf_k, sizeof(buf_k), "k%d", k);
+ v = rand_r(&seed); /* unused */
+ vlen = snprintf(buf_v, sizeof(buf_v), "v%d", v);
+ const std::string ks(buf_k, klen);
+ const std::string vs(buf_v, vlen);
+ rec r;
+ r.key = ks;
+ r.value = vs;
+ m.insert(r);
+ // m.insert(std::make_pair(ks, vs));
+ ++io_success_count;
+ ++op_success_count;
+ arg.sh.increment_count();
+ }
+ }
+#endif
+}
+
+struct mysqltest_thread_initobj : private noncopyable {
+ mysqltest_thread_initobj() {
+ mysql_thread_init();
+ }
+ ~mysqltest_thread_initobj() {
+ mysql_thread_end();
+ }
+};
+
+void
+hstest_thread::test_9(int test_num)
+{
+ /* create table hstest
+ * ( k varchar(255) not null, v varchar(255) not null, primary key(k))
+ * engine = innodb; */
+ auto_mysql db;
+ // mysqltest_thread_initobj initobj;
+ std::string err;
+ const char op = arg.sh.op;
+ const std::string suffix = arg.sh.conf.get_str("value_suffix", "upd");
+ unsigned long long err_cnt = 0;
+ unsigned long long query_cnt = 0;
+ #if 0
+ my_bool reconnect = 0;
+ if (mysql_options(db, MYSQL_OPT_RECONNECT, &reconnect) != 0) {
+ err = "mysql_options() failed";
+ ++err_cnt;
+ return;
+ }
+ #endif
+ unsigned int seed = time(0) + arg.id + 1;
+ seed ^= arg.sh.conf.get_int("seed_xor", 0);
+ drand48_data randbuf;
+ srand48_r(seed, &randbuf);
+ const std::string mysql_host = arg.sh.conf.get_str("host", "localhost");
+ const int mysql_port = arg.sh.conf.get_int("mysqlport", 3306);
+ const int num = arg.sh.loop;
+ const std::string mysql_user = arg.sh.conf.get_str("mysqluser", "root");
+ const std::string mysql_passwd = arg.sh.conf.get_str("mysqlpass", "");
+ const std::string mysql_dbname = arg.sh.conf.get_str("dbname", "hstest");
+ const int keep_connection = arg.sh.conf.get_int("keep_connection", 1);
+ const int verbose = arg.sh.conf.get_int("verbose", 1);
+ const int tablesize = arg.sh.conf.get_int("tablesize", 10000);
+ const int moreflds = arg.sh.conf.get_int("moreflds", 0);
+ const std::string moreflds_prefix = arg.sh.conf.get_str(
+ "moreflds_prefix", "column0123456789_");
+ const int use_handler = arg.sh.conf.get_int("handler", 0);
+ const int sched_flag = arg.sh.conf.get_int("sched", 0);
+ const int use_in = arg.sh.conf.get_int("in", 0);
+ const int ssps = use_in ? 0 : arg.sh.conf.get_int("ssps", 0);
+ std::string flds = "v";
+ for (int i = 0; i < moreflds; ++i) {
+ char buf[1024];
+ snprintf(buf, sizeof(buf), ",%s%d", moreflds_prefix.c_str(), i);
+ flds += std::string(buf);
+ }
+ int connected = 0;
+ std::auto_ptr<auto_mysql_stmt> stmt;
+ string_buffer wbuf;
+ for (int i = 0; i < num; ++i) {
+ const double tm1 = gettimeofday_double();
+ const int flags = 0;
+ if (connected == 0) {
+ if (!mysql_real_connect(db, mysql_host.c_str(),
+ mysql_user.c_str(), mysql_user.empty() ? 0 : mysql_passwd.c_str(),
+ mysql_dbname.c_str(), mysql_port, 0, flags)) {
+ err = "failed to connect: " + std::string(mysql_error(db));
+ if (verbose >= 1) {
+ fprintf(stderr, "e=[%s]\n", err.c_str());
+ }
+ ++err_cnt;
+ return;
+ }
+ arg.sh.increment_conn(1);
+ }
+ int r = 0;
+ if (connected == 0 && use_handler) {
+ const char *const q = "handler hstest_table1 open";
+ r = mysql_real_query(db, q, strlen(q));
+ if (r != 0) {
+ err = 1;
+ }
+ }
+ if (connected == 0 && ssps) {
+ stmt.reset(new auto_mysql_stmt(db));
+ const char *const q = "select v from hstest_table1 where k = ?";
+ r = mysql_stmt_prepare(*stmt, q, strlen(q));
+ if (r != 0) {
+ fprintf(stderr, "ssps err\n");
+ ++err_cnt;
+ return;
+ }
+ }
+ connected = 1;
+ std::string result_str;
+ unsigned int err = 0;
+ unsigned int num_flds = 0, num_affected_rows = 0;
+ int got_data = 0;
+ char buf_query[16384];
+ int buf_query_len = 0;
+ int k = 0, v = 0;
+ {
+ double kf = 0, vf = 0;
+ drand48_r(&randbuf, &kf);
+ drand48_r(&randbuf, &vf);
+ k = int(kf * tablesize);
+ v = int(vf * tablesize);
+ #if 0
+ k = rand_r(&seed);
+ v = rand_r(&seed);
+ if (tablesize != 0) {
+ k %= tablesize;
+ }
+ #endif
+ if (op == 'G') {
+ if (use_handler) {
+ buf_query_len = snprintf(buf_query, sizeof(buf_query),
+ "handler hstest_table1 read `primary` = ( '%d' )", k);
+ // TODO: moreflds
+ } else if (ssps) {
+ //
+ } else if (use_in) {
+ wbuf.clear();
+ char *p = wbuf.make_space(1024);
+ int len = snprintf(p, 1024, "select %s from hstest_table1 where k in ('%d'", flds.c_str(), k);
+ wbuf.space_wrote(len);
+ for (int j = 1; j < use_in; ++j) {
+ /* generate more key */
+ drand48_r(&randbuf, &kf);
+ k = int(kf * tablesize);
+ p = wbuf.make_space(1024);
+ int len = snprintf(p, 1024, ", '%d'", k);
+ wbuf.space_wrote(len);
+ }
+ wbuf.append_literal(")");
+ } else {
+ buf_query_len = snprintf(buf_query, sizeof(buf_query),
+ "select %s from hstest_table1 where k = '%d'", flds.c_str(), k);
+ }
+ } else if (op == 'U') {
+ buf_query_len = snprintf(buf_query, sizeof(buf_query),
+ "update hstest_table1 set v = '%d_%d%s' where k = '%d'",
+ v, k, suffix.c_str(), k);
+ } else if (op == 'R') {
+ buf_query_len = snprintf(buf_query, sizeof(buf_query),
+ "replace into hstest_table1 values ('%d', 'v%d')", k, v);
+ // TODO: moreflds
+ }
+ }
+ if (r == 0) {
+ if (ssps) {
+ MYSQL_BIND bind[1] = { };
+ bind[0].buffer_type = MYSQL_TYPE_LONG;
+ bind[0].buffer = (char *)&k;
+ bind[0].is_null = 0;
+ bind[0].length = 0;
+ if (mysql_stmt_bind_param(*stmt, bind)) {
+ fprintf(stderr, "err: %s\n", mysql_stmt_error(*stmt));
+ ++err_cnt;
+ return;
+ }
+ r = mysql_stmt_execute(*stmt);
+ // fprintf(stderr, "stmt exec\n");
+ } else if (use_in) {
+ r = mysql_real_query(db, wbuf.begin(), wbuf.size());
+ } else {
+ r = mysql_real_query(db, buf_query, buf_query_len);
+ // fprintf(stderr, "real query\n");
+ }
+ ++query_cnt;
+ }
+ if (r != 0) {
+ err = 1;
+ } else if (ssps) {
+ if (verbose >= 0) {
+ char resbuf[1024];
+ unsigned long res_len = 0;
+ MYSQL_BIND bind[1] = { };
+ bind[0].buffer_type = MYSQL_TYPE_STRING;
+ bind[0].buffer = resbuf;
+ bind[0].buffer_length = sizeof(resbuf);
+ bind[0].length = &res_len;
+ if (mysql_stmt_bind_result(*stmt, bind)) {
+ fprintf(stderr, "err: %s\n", mysql_stmt_error(*stmt));
+ ++err_cnt;
+ return;
+ }
+ if (mysql_stmt_fetch(*stmt)) {
+ fprintf(stderr, "err: %s\n", mysql_stmt_error(*stmt));
+ ++err_cnt;
+ return;
+ }
+ if (!result_str.empty()) {
+ result_str += " ";
+ }
+ result_str += std::string(resbuf, res_len);
+ // fprintf(stderr, "SSPS RES: %s\n", result_str.c_str());
+ got_data = 1;
+ } else {
+ got_data = 1;
+ }
+ } else {
+ auto_mysql_res res(db);
+ if (res != 0) {
+ if (verbose >= 0) {
+ num_flds = mysql_num_fields(res);
+ MYSQL_ROW row = 0;
+ while ((row = mysql_fetch_row(res)) != 0) {
+ got_data += 1;
+ unsigned long *const lengths = mysql_fetch_lengths(res);
+ if (verbose >= 2) {
+ for (unsigned int i = 0; i < num_flds; ++i) {
+ if (!result_str.empty()) {
+ result_str += " ";
+ }
+ result_str += std::string(row[i], lengths[i]);
+ }
+ }
+ }
+ } else {
+ MYSQL_ROW row = 0;
+ while ((row = mysql_fetch_row(res)) != 0) {
+ got_data += 1;
+ }
+ }
+ } else {
+ if (mysql_field_count(db) == 0) {
+ num_affected_rows = mysql_affected_rows(db);
+ } else {
+ err = 1;
+ }
+ }
+ }
+ if (verbose >= 2 || (verbose >= 1 && err != 0)) {
+ if (err) {
+ ++err_cnt;
+ const char *const errstr = mysql_error(db);
+ fprintf(stderr, "e=[%s] a=%u q=[%s]\n", errstr,
+ num_affected_rows, buf_query);
+ } else {
+ fprintf(stderr, "a=%u q=[%s] r=[%s]\n", num_affected_rows, buf_query,
+ result_str.c_str());
+ }
+ }
+ if (err == 0) {
+ ++io_success_count;
+ if (num_affected_rows > 0 || got_data > 0) {
+ op_success_count += got_data;
+ } else {
+ if (verbose >= 1) {
+ fprintf(stderr, "k=%d numaff=%u gotdata=%d\n",
+ k, num_affected_rows, got_data);
+ }
+ }
+ arg.sh.increment_count();
+ }
+ if (!keep_connection) {
+ if (stmt.get() != 0) {
+ stmt.reset();
+ }
+ db.reset();
+ connected = 0;
+ }
+ const double tm2 = gettimeofday_double();
+ set_timing(tm2 - tm1);
+ sleep_if();
+ if (sched_flag) {
+ sched_yield();
+ }
+ }
+ if (verbose >= 1) {
+ fprintf(stderr, "thread finished (error_count=%llu)\n", err_cnt);
+ }
+}
+
+void
+hstest_thread::test_10(int test_num)
+{
+ const int keep_connection = arg.sh.conf.get_int("keep_connection", 1);
+ unsigned int seed = time(0) + arg.id + 1;
+ seed ^= arg.sh.conf.get_int("seed_xor", 0);
+ drand48_data randbuf;
+ srand48_r(seed, &randbuf);
+ std::string err;
+ int keepconn_count = 0;
+ const char op = arg.sh.op;
+ const int verbose = arg.sh.conf.get_int("verbose", 1);
+ const std::string suffix = arg.sh.conf.get_str("value_suffix", "upd");
+ const int tablesize = arg.sh.conf.get_int("tablesize", 10000);
+ const int firstkey = arg.sh.conf.get_int("firstkey", 0);
+ const int sched_flag = arg.sh.conf.get_int("sched", 0);
+ const int moreflds = arg.sh.conf.get_int("moreflds", 0);
+ const std::string dbname = arg.sh.conf.get_str("dbname", "hstest");
+ const std::string table = arg.sh.conf.get_str("table", "hstest_table1");
+ const std::string index = arg.sh.conf.get_str("index", "PRIMARY");
+ const std::string field = arg.sh.conf.get_str("field", "v");
+ const int use_in = arg.sh.conf.get_int("in", 0);
+ const std::string moreflds_prefix = arg.sh.conf.get_str(
+ "moreflds_prefix", "column0123456789_");
+ const int dump = arg.sh.dump;
+ const int nodup = arg.sh.conf.get_int("nodup", 0);
+ std::string moreflds_str;
+ for (int i = 0; i < moreflds; ++i) {
+ char sbuf[1024];
+ snprintf(sbuf, sizeof(sbuf), ",%s%d", moreflds_prefix.c_str(), i);
+ moreflds_str += std::string(sbuf);
+ }
+ string_buffer wbuf;
+ char rbuf[16384];
+ for (size_t i = 0; i < arg.sh.loop; ++i) {
+ int len = 0, rlen = 0, wlen = 0;
+ #if 0
+ const double tm1 = gettimeofday_double();
+ #endif
+ if (fd.get() < 0) {
+ if (socket_connect(fd, arg.sh.arg, err) != 0) {
+ fprintf(stderr, "connect: %d %s\n", errno, strerror(errno));
+ return;
+ }
+ char *wp = wbuf.make_space(1024);
+ len = snprintf(wp, 1024,
+ "P\t1\t%s\t%s\tPRIMARY\t%s%s\n", dbname.c_str(), table.c_str(),
+ field.c_str(), moreflds_str.c_str());
+ /* pst_num, db, table, index, retflds */
+ wbuf.space_wrote(len);
+ wlen = write(fd.get(), wbuf.begin(), len);
+ if (len != wlen) {
+ fprintf(stderr, "write: %d %d\n", len, wlen);
+ return;
+ }
+ wbuf.clear();
+ rlen = read(fd.get(), rbuf, sizeof(rbuf));
+ if (rlen <= 0 || rbuf[rlen - 1] != '\n') {
+ fprintf(stderr, "read: rlen=%d errno=%d\n", rlen, errno);
+ return;
+ }
+ if (rbuf[0] != '0') {
+ fprintf(stderr, "failed to open table\n");
+ return;
+ }
+ arg.sh.increment_conn(1);
+ }
+ const double tm1 = gettimeofday_double();
+ for (size_t j = 0; j < arg.sh.pipe; ++j) {
+ int k = 0, v = 0;
+ {
+ while (true) {
+ double kf = 0, vf = 0;
+ drand48_r(&randbuf, &kf);
+ drand48_r(&randbuf, &vf);
+ k = int(kf * tablesize) + firstkey;
+ v = int(vf * tablesize) + firstkey;
+ if (k - firstkey < arg.sh.keygen_size) {
+ volatile char *const ptr = arg.sh.keygen + (k - firstkey);
+ // int oldv = __sync_fetch_and_or(ptr, 1);
+ int oldv = *ptr;
+ *ptr += 1;
+ if (nodup && oldv != 0) {
+ if (dump) {
+ fprintf(stderr, "retry\n");
+ }
+ continue;
+ }
+ } else {
+ if (nodup) {
+ if (dump) {
+ fprintf(stderr, "retry2\n");
+ }
+ continue;
+ }
+ }
+ size_t len = 0;
+ if (op == 'G') {
+ if (use_in) {
+ char *wp = wbuf.make_space(1024);
+ len = snprintf(wp, 1024, "1\t=\t1\t\t%d\t0\t@\t0\t%d\t%d",
+ use_in, use_in, k);
+ wbuf.space_wrote(len);
+ for (int j = 1; j < use_in; ++j) {
+ drand48_r(&randbuf, &kf);
+ k = int(kf * tablesize) + firstkey;
+ char *wp = wbuf.make_space(1024);
+ len = snprintf(wp, 1024, "\t%d", k);
+ wbuf.space_wrote(len);
+ }
+ wbuf.append_literal("\n");
+ } else {
+ char *wp = wbuf.make_space(1024);
+ len = snprintf(wp, 1024, "1\t=\t1\t%d\n", k);
+ wbuf.space_wrote(len);
+ }
+ } else if (op == 'U') {
+ char *wp = wbuf.make_space(1024);
+ len = snprintf(wp, 1024,
+ "1\t=\t1\t%d\t1\t0\tU\t%d_%d%s\n", k, v, k, suffix.c_str());
+ wbuf.space_wrote(len);
+ }
+ break;
+ }
+ }
+ }
+ wlen = write(fd.get(), wbuf.begin(), wbuf.size());
+ if ((size_t) wlen != wbuf.size()) {
+ fprintf(stderr, "write: %d %d\n", (int)wbuf.size(), wlen);
+ return;
+ }
+ wbuf.clear();
+ size_t read_cnt = 0;
+ size_t read_pos = 0;
+ while (read_cnt < arg.sh.pipe) {
+ rlen = read(fd.get(), rbuf + read_pos, sizeof(rbuf) - read_pos);
+ if (rlen <= 0) {
+ fprintf(stderr, "read: %d\n", rlen);
+ return;
+ }
+ read_pos += rlen;
+ while (true) {
+ const char *const nl = static_cast<const char *>(memchr(rbuf, '\n',
+ read_pos));
+ if (nl == 0) {
+ break;
+ }
+ ++read_cnt;
+ ++io_success_count;
+ const char *t1 = static_cast<const char *>(memchr(rbuf, '\t',
+ nl - rbuf));
+ if (t1 == 0) {
+ fprintf(stderr, "error \n");
+ break;
+ }
+ ++t1;
+ const char *t2 = static_cast<const char *>(memchr(t1, '\t',
+ nl - t1));
+ if (t2 == 0) {
+ if (verbose > 1) {
+ fprintf(stderr, "key: notfound \n");
+ }
+ break;
+ }
+ ++t2;
+ if (t1 == rbuf + 2 && rbuf[0] == '0') {
+ if (op == 'G') {
+ ++op_success_count;
+ arg.sh.increment_count();
+ } else if (op == 'U') {
+ const char *t3 = t2;
+ while (t3 != nl && t3[0] >= 0x10) {
+ ++t3;
+ }
+ if (t3 != t2 + 1 || t2[0] != '1') {
+ const std::string mess(t2, t3);
+ fprintf(stderr, "mod: %s\n", mess.c_str());
+ } else {
+ ++op_success_count;
+ arg.sh.increment_count();
+ if (arg.sh.dump && arg.sh.pipe == 1) {
+ fwrite(wbuf.begin(), wbuf.size(), 1, stderr);
+ }
+ }
+ }
+ } else {
+ const char *t3 = t2;
+ while (t3 != nl && t3[0] >= 0x10) {
+ ++t3;
+ }
+ const std::string mess(t2, t3);
+ fprintf(stderr, "err: %s\n", mess.c_str());
+ }
+ const size_t rest_size = rbuf + read_pos - (nl + 1);
+ if (rest_size != 0) {
+ memmove(rbuf, nl + 1, rest_size);
+ }
+ read_pos = rest_size;
+ }
+ }
+ if (!keep_connection) {
+ fd.reset();
+ arg.sh.increment_conn(-1);
+ } else if (keep_connection > 1 && ++keepconn_count > keep_connection) {
+ keepconn_count = 0;
+ fd.reset();
+ arg.sh.increment_conn(-1);
+ }
+ const double tm2 = gettimeofday_double();
+ set_timing(tm2 - tm1);
+ sleep_if();
+ if (sched_flag) {
+ sched_yield();
+ }
+ }
+ if (dump) {
+ fprintf(stderr, "done\n");
+ }
+}
+
+void
+hstest_thread::sleep_if()
+{
+ if (arg.sh.usleep) {
+ struct timespec ts = {
+ arg.sh.usleep / 1000000,
+ (arg.sh.usleep % 1000000) * 1000
+ };
+ nanosleep(&ts, 0);
+ }
+}
+
+void
+hstest_thread::set_timing(double time_spent)
+{
+ response_min = std::min(response_min, time_spent);
+ response_max = std::max(response_max, time_spent);
+ response_sum += time_spent;
+ if (op_success_count != 0) {
+ response_avg = response_sum / op_success_count;
+ }
+}
+
+void
+hstest_thread::test_11(int test_num)
+{
+ const int keep_connection = arg.sh.conf.get_int("keep_connection", 1);
+ const int tablesize = arg.sh.conf.get_int("tablesize", 0);
+ unsigned int seed = arg.id;
+ seed ^= arg.sh.conf.get_int("seed_xor", 0);
+ std::string err;
+ hstcpcli_ptr cli;
+ for (size_t i = 0; i < arg.sh.loop; ++i) {
+ if (cli.get() == 0) {
+ cli = hstcpcli_i::create(arg.sh.arg);
+ cli->request_buf_open_index(0, "hstest", "hstest_table1", "", "v");
+ /* pst_num, db, table, index, retflds */
+ if (cli->request_send() != 0) {
+ fprintf(stderr, "reuqest_send: %s\n", cli->get_error().c_str());
+ return;
+ }
+ size_t num_flds = 0;
+ if (cli->response_recv(num_flds) != 0) {
+ fprintf(stderr, "reuqest_recv: %s\n", cli->get_error().c_str());
+ return;
+ }
+ cli->response_buf_remove();
+ }
+ for (size_t j = 0; j < arg.sh.pipe; ++j) {
+ char buf[256];
+ int k = 0, v = 0, len = 0;
+ {
+ k = rand_r(&seed);
+ v = rand_r(&seed); /* unused */
+ if (tablesize != 0) {
+ k &= tablesize;
+ }
+ len = snprintf(buf, sizeof(buf), "%d", k);
+ }
+ const string_ref key(buf, len);
+ const string_ref op("=", 1);
+ cli->request_buf_exec_generic(0, op, &key, 1, 1, 0, string_ref(), 0, 0);
+ }
+ if (cli->request_send() != 0) {
+ fprintf(stderr, "reuqest_send: %s\n", cli->get_error().c_str());
+ return;
+ }
+ size_t read_cnt = 0;
+ for (size_t j = 0; j < arg.sh.pipe; ++j) {
+ size_t num_flds = 0;
+ if (cli->response_recv(num_flds) != 0) {
+ fprintf(stderr, "reuqest_recv: %s\n", cli->get_error().c_str());
+ return;
+ }
+ {
+ ++read_cnt;
+ ++io_success_count;
+ arg.sh.increment_count();
+ {
+ ++op_success_count;
+ }
+ }
+ cli->response_buf_remove();
+ }
+ if (!keep_connection) {
+ cli.reset();
+ }
+ }
+}
+
+void
+hstest_thread::test_watch()
+{
+ const int timelimit = arg.sh.conf.get_int("timelimit", 0);
+ const int timelimit_offset = timelimit / 2;
+ int loop = 0;
+ double t1 = 0, t2 = 0;
+ size_t cnt_t1 = 0, cnt_t2 = 0;
+ size_t prev_cnt = 0;
+ double now_f = 0;
+ while (true) {
+ sleep(1);
+ const size_t cnt = arg.sh.count;
+ const size_t df = cnt - prev_cnt;
+ prev_cnt = cnt;
+ const double now_prev = now_f;
+ now_f = gettimeofday_double();
+ if (now_prev != 0) {
+ const double rps = static_cast<double>(df) / (now_f - now_prev);
+ fprintf(stderr, "now: %zu cntdiff: %zu tdiff: %f rps: %f\n",
+ static_cast<size_t>(now_f), df, now_f - now_prev, rps);
+ }
+ if (timelimit != 0) {
+ if (arg.sh.wait_conn == 0 || arg.sh.conn_count >= arg.sh.wait_conn) {
+ ++loop;
+ }
+ if (loop == timelimit_offset) {
+ t1 = gettimeofday_double();
+ cnt_t1 = cnt;
+ arg.sh.enable_timing = 1;
+ fprintf(stderr, "start timing\n");
+ } else if (loop == timelimit_offset + timelimit) {
+ t2 = gettimeofday_double();
+ cnt_t2 = cnt;
+ const size_t cnt_diff = cnt_t2 - cnt_t1;
+ const double tdiff = t2 - t1;
+ const double qps = cnt_diff / (tdiff != 0 ? tdiff : 1);
+ fprintf(stderr, "(%f: %zu, %f: %zu), %10.5f qps\n",
+ t1, cnt_t1, t2, cnt_t2, qps);
+ size_t keycnt = 0;
+ for (int i = 0; i < arg.sh.keygen_size; ++i) {
+ if (arg.sh.keygen[i]) {
+ ++keycnt;
+ }
+ }
+ fprintf(stderr, "keygen=%zu\n", keycnt);
+ break;
+ }
+ }
+ }
+#if 0
+ int loop = 0;
+ double t1 = 0, t2 = 0;
+ size_t cnt_t1 = 0, cnt_t2 = 0;
+ size_t prev_cnt = 0;
+ while (true) {
+ sleep(1);
+ const size_t cnt = arg.sh.count;
+ const size_t df = cnt - prev_cnt;
+ prev_cnt = cnt;
+ const size_t now = time(0);
+ fprintf(stderr, "%zu %zu\n", now, df);
+ if (timelimit != 0) {
+ ++loop;
+ if (loop == timelimit_offset) {
+ t1 = gettimeofday_double();
+ cnt_t1 = cnt;
+ } else if (loop == timelimit_offset + timelimit) {
+ t2 = gettimeofday_double();
+ cnt_t2 = cnt;
+ const size_t cnt_diff = cnt_t2 - cnt_t1;
+ const double tdiff = t2 - t1;
+ const double qps = cnt_diff / (tdiff != 0 ? tdiff : 1);
+ fprintf(stderr, "(%f: %zu, %f: %zu), %10.5f qps\n",
+ t1, cnt_t1, t2, cnt_t2, qps);
+ size_t keycnt = 0;
+ for (int i = 0; i < arg.sh.keygen_size; ++i) {
+ if (arg.sh.keygen[i]) {
+ ++keycnt;
+ }
+ }
+ fprintf(stderr, "keygen=%zu\n", keycnt);
+ _exit(0);
+ }
+ }
+ }
+#endif
+}
+
+void
+hstest_thread::test_12(int test_num)
+{
+ /* NOTE: num_threads should be 1 */
+ /* create table hstest
+ * ( k varchar(255) not null, v varchar(255) not null, primary key(k))
+ * engine = innodb; */
+ mysqltest_thread_initobj initobj;
+ auto_mysql db;
+ std::string err;
+ unsigned long long err_cnt = 0;
+ unsigned long long query_cnt = 0;
+ #if 0
+ my_bool reconnect = 0;
+ if (mysql_options(db, MYSQL_OPT_RECONNECT, &reconnect) != 0) {
+ err = "mysql_options() failed";
+ ++err_cnt;
+ return;
+ }
+ #endif
+ const std::string mysql_host = arg.sh.conf.get_str("host", "localhost");
+ const int mysql_port = arg.sh.conf.get_int("mysqlport", 3306);
+ const unsigned int num = arg.sh.loop;
+ const size_t pipe = arg.sh.pipe;
+ const std::string mysql_user = arg.sh.conf.get_str("mysqluser", "root");
+ const std::string mysql_passwd = arg.sh.conf.get_str("mysqlpass", "");
+ const std::string mysql_dbname = arg.sh.conf.get_str("db", "hstest");
+ const int keep_connection = arg.sh.conf.get_int("keep_connection", 1);
+ const int verbose = arg.sh.conf.get_int("verbose", 1);
+ const int use_handler = arg.sh.conf.get_int("handler", 0);
+ int connected = 0;
+ unsigned int k = 0;
+ string_buffer buf;
+ for (unsigned int i = 0; i < num; ++i) {
+ const int flags = 0;
+ if (connected == 0 && !mysql_real_connect(db, mysql_host.c_str(),
+ mysql_user.c_str(), mysql_user.empty() ? 0 : mysql_passwd.c_str(),
+ mysql_dbname.c_str(), mysql_port, 0, flags)) {
+ err = "failed to connect: " + std::string(mysql_error(db));
+ if (verbose >= 1) {
+ fprintf(stderr, "e=[%s]\n", err.c_str());
+ }
+ ++err_cnt;
+ return;
+ }
+ int r = 0;
+ if (connected == 0 && use_handler) {
+ const char *const q = "handler hstest open";
+ r = mysql_real_query(db, q, strlen(q));
+ if (r != 0) {
+ err = 1;
+ }
+ }
+ connected = 1;
+ std::string result_str;
+ unsigned int err = 0;
+ unsigned int num_flds = 0, num_affected_rows = 0;
+ int got_data = 0;
+ buf.clear();
+ buf.append_literal("insert into hstest values ");
+ for (size_t j = 0; j < pipe; ++j) {
+ const unsigned int v = ~k;
+ if (j != 0) {
+ buf.append_literal(",");
+ }
+ char *wp = buf.make_space(64);
+ int buf_query_len = snprintf(wp, 64, "('k%u', 'v%u')", k, v);
+ buf.space_wrote(buf_query_len);
+ ++k;
+ }
+ if (r == 0) {
+ r = mysql_real_query(db, buf.begin(), buf.size());
+ ++query_cnt;
+ }
+ if (r != 0) {
+ err = 1;
+ } else {
+ auto_mysql_res res(db);
+ if (res != 0) {
+ if (verbose >= 0) {
+ num_flds = mysql_num_fields(res);
+ MYSQL_ROW row = 0;
+ while ((row = mysql_fetch_row(res)) != 0) {
+ got_data = 1;
+ unsigned long *const lengths = mysql_fetch_lengths(res);
+ if (verbose >= 2) {
+ for (unsigned int i = 0; i < num_flds; ++i) {
+ if (!result_str.empty()) {
+ result_str += " ";
+ }
+ result_str += std::string(row[i], lengths[i]);
+ }
+ }
+ }
+ }
+ } else {
+ if (mysql_field_count(db) == 0) {
+ num_affected_rows = mysql_affected_rows(db);
+ } else {
+ err = 1;
+ }
+ }
+ }
+ if (verbose >= 2 || (verbose >= 1 && err != 0)) {
+ if (err) {
+ ++err_cnt;
+ const char *const errstr = mysql_error(db);
+ fprintf(stderr, "e=[%s] a=%u q=[%s]\n", errstr,
+ num_affected_rows, std::string(buf.begin(), buf.size()).c_str());
+ } else {
+ fprintf(stderr, "a=%u q=[%s] r=[%s]\n", num_affected_rows,
+ std::string(buf.begin(), buf.size()).c_str(),
+ result_str.c_str());
+ }
+ }
+ if (err == 0) {
+ ++io_success_count;
+ if (num_affected_rows > 0 || got_data > 0) {
+ ++op_success_count;
+ }
+ arg.sh.increment_count(pipe);
+ }
+ if (!keep_connection) {
+ db.reset();
+ connected = 0;
+ }
+ }
+ if (verbose >= 1) {
+ fprintf(stderr, "thread finished (error_count=%llu)\n", err_cnt);
+ }
+}
+
+void
+hstest_thread::test_21(int num)
+{
+ /* fsync test */
+ unsigned int id = arg.id;
+ std::string err;
+ #if 0
+ if (socket_connect(fd, arg.sh.arg, err) != 0) {
+ fprintf(stderr, "connect: %d %s\n", errno, strerror(errno));
+ return;
+ }
+ #endif
+ auto_file logfd;
+ char fname[1024];
+ snprintf(fname, sizeof(fname), "synctest_%u", id);
+ int open_flags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND;
+ logfd.reset(open(fname, open_flags, 0644));
+ if (logfd.get() < 0) {
+ fprintf(stderr, "open: %s: %d %s\n", fname, errno, strerror(errno));
+ return;
+ }
+ char buf[1024];
+ unsigned long long count = 0;
+ while (true) {
+ snprintf(buf, sizeof(buf), "%u %llu\n", id, count);
+ const size_t len = strlen(buf);
+ if (write(logfd.get(), buf, len) != (ssize_t)len) {
+ fprintf(stderr, "write: %s: %d %s\n", fname, errno, strerror(errno));
+ return;
+ }
+ #if 0
+ if (write(fd.get(), buf, len) != (ssize_t)len) {
+ fprintf(stderr, "write(sock): %d %s\n", errno, strerror(errno));
+ return;
+ }
+ #endif
+ if (fdatasync(logfd.get()) != 0) {
+ fprintf(stderr, "fsync: %s: %d %s\n", fname, errno, strerror(errno));
+ return;
+ }
+ ++count;
+ ++op_success_count;
+ arg.sh.increment_count();
+ }
+}
+
+void
+hstest_thread::test_22(int num)
+{
+ /* dd if=/dev/zero of=dummy.dat bs=1024M count=100 */
+ unsigned int id = arg.id;
+ std::string err;
+ auto_file filefd;
+ char fname[1024];
+ snprintf(fname, sizeof(fname), "dummy.dat");
+ int open_flags = O_RDONLY | O_DIRECT;
+ filefd.reset(open(fname, open_flags, 0644));
+ if (filefd.get() < 0) {
+ fprintf(stderr, "open: %s: %d %s\n", fname, errno, strerror(errno));
+ return;
+ }
+ char buf_x[4096 * 2];
+ char *const buf = (char *)(size_t(buf_x + 4096) / 4096 * 4096);
+ unsigned long long count = 0;
+ drand48_data randbuf;
+ unsigned long long seed = time(0);
+ seed *= 10;
+ seed += id;
+ srand48_r(seed, &randbuf);
+ for (unsigned int i = 0; i < arg.sh.loop; ++i) {
+ double kf = 0;
+ drand48_r(&randbuf, &kf);
+ kf *= (209715200 / 1);
+ // fprintf(stderr, "v=%f\n", kf);
+ off_t v = static_cast<off_t>(kf);
+ v %= (209715200 / 1);
+ v *= (512 * 1);
+ const double tm1 = gettimeofday_double();
+ const ssize_t r = pread(filefd.get(), buf, (512 * 1), v);
+ const double tm2 = gettimeofday_double();
+ if (r < 0) {
+ fprintf(stderr, "pread: %s: %d %s\n", fname, errno, strerror(errno));
+ return;
+ }
+ ++count;
+ ++op_success_count;
+ arg.sh.increment_count();
+ set_timing(tm2 - tm1);
+ }
+}
+
+void
+hstest_thread::operator ()()
+{
+ if (arg.watch_flag) {
+ return test_watch();
+ }
+ int test_num = arg.sh.conf.get_int("test", 1);
+ if (test_num == 1) {
+ test_1();
+ } else if (test_num == 2 || test_num == 3) {
+ test_2_3(test_num);
+ } else if (test_num == 4 || test_num == 5) {
+ test_4_5(test_num);
+ } else if (test_num == 6) {
+ test_6(test_num);
+ } else if (test_num == 7) {
+ test_7(test_num);
+ } else if (test_num == 8) {
+ test_8(test_num);
+ } else if (test_num == 9) {
+ test_9(test_num);
+ } else if (test_num == 10) {
+ test_10(test_num);
+ } else if (test_num == 11) {
+ test_11(test_num);
+ } else if (test_num == 12) {
+ test_12(test_num);
+ } else if (test_num == 21) {
+ test_21(test_num);
+ } else if (test_num == 22) {
+ test_22(test_num);
+ }
+ const int halt = arg.sh.conf.get_int("halt", 0);
+ if (halt) {
+ fprintf(stderr, "thread halted\n");
+ while (true) {
+ sleep(100000);
+ }
+ }
+ fprintf(stderr, "thread finished\n");
+}
+
+int
+hstest_main(int argc, char **argv)
+{
+ ignore_sigpipe();
+ hstest_shared shared;
+ parse_args(argc, argv, shared.conf);
+ shared.conf["port"] = shared.conf["hsport"];
+ shared.arg.set(shared.conf);
+ shared.loop = shared.conf.get_int("num", 1000);
+ shared.pipe = shared.conf.get_int("pipe", 1);
+ shared.verbose = shared.conf.get_int("verbose", 1);
+ const int tablesize = shared.conf.get_int("tablesize", 0);
+ std::vector<char> keygen(tablesize);
+ shared.keygen = &keygen[0];
+ shared.keygen_size = tablesize;
+ shared.usleep = shared.conf.get_int("usleep", 0);
+ shared.dump = shared.conf.get_int("dump", 0);
+ shared.num_threads = shared.conf.get_int("num_threads", 10);
+ shared.wait_conn = shared.conf.get_int("wait_conn", 0);
+ const std::string op = shared.conf.get_str("op", "G");
+ if (op.size() > 0) {
+ shared.op = op[0];
+ }
+ #if 0
+ const int localdb_flag = shared.conf.get_int("local", 0);
+ if (localdb_flag) {
+ shared.localdb = database_i::create(shared.conf);
+ }
+ #endif
+ const int num_thrs = shared.num_threads;
+ typedef thread<hstest_thread> thread_type;
+ typedef std::auto_ptr<thread_type> thread_ptr;
+ typedef auto_ptrcontainer< std::vector<thread_type *> > thrs_type;
+ thrs_type thrs;
+ for (int i = 0; i < num_thrs; ++i) {
+ const hstest_thread::arg_type arg(i, shared, false);
+ thread_ptr thr(new thread<hstest_thread>(arg));
+ thrs.push_back_ptr(thr);
+ }
+ for (size_t i = 0; i < thrs.size(); ++i) {
+ thrs[i]->start();
+ }
+ thread_ptr watch_thread;
+ const int timelimit = shared.conf.get_int("timelimit", 0);
+ {
+ const hstest_thread::arg_type arg(0, shared, true);
+ watch_thread = thread_ptr(new thread<hstest_thread>(arg));
+ watch_thread->start();
+ }
+ size_t iocnt = 0, opcnt = 0;
+ double respmin = 999999, respmax = 0;
+ double respsum = 0;
+ if (timelimit != 0) {
+ watch_thread->join();
+ }
+ for (size_t i = 0; i < thrs.size(); ++i) {
+ if (timelimit == 0) {
+ thrs[i]->join();
+ }
+ iocnt += (*thrs[i])->io_success_count;
+ opcnt += (*thrs[i])->op_success_count;
+ respmin = std::min(respmin, (*thrs[i])->response_min);
+ respmax = std::max(respmax, (*thrs[i])->response_max);
+ respsum += (*thrs[i])->response_sum;
+ }
+ fprintf(stderr, "io_success_count=%zu op_success_count=%zu\n", iocnt, opcnt);
+ fprintf(stderr, "respmin=%f respmax=%f respsum=%f respavg=%f\n",
+ respmin, respmax, respsum, respsum / opcnt);
+ size_t keycnt = 0;
+ for (size_t i = 0; i < keygen.size(); ++i) {
+ if (keygen[i]) {
+ ++keycnt;
+ }
+ }
+ fprintf(stderr, "keycnt=%zu\n", keycnt);
+ _exit(0);
+ return 0;
+}
+
+};
+
+int
+main(int argc, char **argv)
+{
+ return dena::hstest_main(argc, argv);
+}
+
diff --git a/plugin/handler_socket/client/hstest.pl b/plugin/handler_socket/client/hstest.pl
new file mode 100755
index 00000000000..4d177b6cdc8
--- /dev/null
+++ b/plugin/handler_socket/client/hstest.pl
@@ -0,0 +1,228 @@
+#!/usr/bin/perl
+
+# vim:sw=8:ai:ts=8
+
+use strict;
+use warnings;
+
+use DBI;
+use Net::HandlerSocket;
+
+my %conf = ();
+for my $i (@ARGV) {
+ my ($k, $v) = split(/=/, $i);
+ $conf{$k} = $v;
+}
+
+my $verbose = get_conf("verbose", 0);
+my $actions_str = get_conf("actions", "hsread");
+my $tablesize = get_conf("tablesize", 10000);
+my $db = get_conf("db", "hstest");
+my $table = get_conf("table", "hstest_table1");
+my $engine = get_conf("engine", "innodb");
+my $host = get_conf("host", "localhost");
+my $mysqlport = get_conf("mysqlport", 3306);
+my $mysqluser = get_conf("mysqluser", "root");
+my $mysqlpass = get_conf("mysqlpass", "");
+my $hsport = get_conf("hsport", 9999);
+my $loop = get_conf("loop", 10000);
+my $op = get_conf("op", "=");
+my $ssps = get_conf("ssps", 0);
+my $num_moreflds = get_conf("moreflds", 0);
+my $moreflds_prefix = get_conf("moreflds_prefix", "column0123456789_");
+my $keytype = get_conf("keytype", "varchar(32)");
+my $file = get_conf("file", undef);
+
+my $dsn = "DBI:mysql:database=;host=$host;port=$mysqlport"
+ . ";mysql_server_prepare=$ssps";
+my $dbh = DBI->connect($dsn, $mysqluser, $mysqlpass, { RaiseError => 1 });
+my $hsargs = { 'host' => $host, 'port' => $hsport };
+my $cli = new Net::HandlerSocket($hsargs);
+
+my @actions = split(/,/, $actions_str);
+for my $action (@actions) {
+ if ($action eq "table") {
+ print("TABLE $db.$table\n");
+ $dbh->do("drop database if exists $db");
+ $dbh->do("create database $db");
+ $dbh->do("use $db");
+ my $moreflds = get_createtbl_moreflds_str();
+ $dbh->do(
+ "create table $table (" .
+ "k $keytype primary key" .
+ ",v varchar(32) not null" .
+ $moreflds .
+ ") character set utf8 collate utf8_bin " .
+ "engine = $engine");
+ } elsif ($action eq "insert") {
+ print("INSERT $db.$table tablesize=$tablesize\n");
+ $dbh->do("use $db");
+ my $moreflds = get_insert_moreflds_str();
+ for (my $i = 0; $i < $tablesize; $i += 100) {
+ my $qstr = "insert into $db.$table values";
+ for (my $j = 0; $j < 100; ++$j) {
+ if ($j != 0) {
+ $qstr .= ",";
+ }
+ my $k = "" . ($i + $j);
+ my $v = "v" . int(rand(1000)) . ($i + $j);
+ $qstr .= "('$k', '$v'";
+ for (my $j = 0; $j < $num_moreflds; ++$j) {
+ $qstr .= ",'$j'";
+ }
+ $qstr .= ")";
+ }
+ $dbh->do($qstr);
+ print "$i/$tablesize\n" if $i % 1000 == 0;
+ }
+ } elsif ($action eq "read") {
+ print("READ $db.$table op=$op loop=$loop\n");
+ $dbh->do("use $db");
+ my $moreflds = get_select_moreflds_str();
+ my $sth = $dbh->prepare(
+ "select k,v$moreflds from $db.$table where k = ?");
+ for (my $i = 0; $i < $loop; ++$i) {
+ my $k = "" . int(rand($tablesize));
+ # print "k=$k\n";
+ $sth->execute($k);
+ if ($verbose >= 10) {
+ print "RET:";
+ while (my $ref = $sth->fetchrow_arrayref()) {
+ my $rk = $ref->[0];
+ my $rv = $ref->[1];
+ print " $rk $rv";
+ }
+ print "\n";
+ }
+ print "$i/$loop\n" if $i % 1000 == 0;
+ }
+ } elsif ($action eq "hsinsert") {
+ print("HSINSERT $db.$table tablesize=$tablesize\n");
+ $cli->open_index(1, $db, $table, '', 'k,v');
+ for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "" . $i;
+ my $v = "v" . int(rand(1000)) . $i;
+ my $r = $cli->execute_insert(1, [ $k, $v ]);
+ if ($r->[0] != 0) {
+ die;
+ }
+ print "$i/$tablesize\n" if $i % 1000 == 0;
+ }
+ } elsif ($action eq "hsread") {
+ print("HSREAD $db.$table op=$op loop=$loop\n");
+ my $moreflds = get_select_moreflds_str();
+ $cli->open_index(1, $db, $table, '', "k,v$moreflds");
+ for (my $i = 0; $i < $loop; ++$i) {
+ my $k = "" . int(rand($tablesize));
+ # print "k=$k\n";
+ my $r = $cli->execute_find(1, $op, [ $k ], 1, 0);
+ if ($verbose >= 10) {
+ my $len = scalar(@{$r});
+ print "LEN=$len";
+ for my $e (@{$r}) {
+ print " [$e]";
+ }
+ print "\n";
+ }
+ print "$i/$loop\n" if $i % 1000 == 0;
+ }
+ } elsif ($action eq "hsupdate") {
+ my $vbase = "v" . int(rand(1000));
+ print("HSUPDATE $db.$table op=$op loop=$loop vbase=$vbase\n");
+ $cli->open_index(1, $db, $table, '', 'v');
+ for (my $i = 0; $i < $loop; ++$i) {
+ my $k = "" . int(rand($tablesize));
+ my $v = $vbase . $i;
+ print "k=$k v=$v\n";
+ my $r = $cli->execute_update(1, $op, [ $k ], 1, 0,
+ [ $v ]);
+ if ($verbose >= 10) {
+ print "UP k=$k v=$v\n";
+ }
+ print "$i/$loop\n" if $i % 1000 == 0;
+ }
+ } elsif ($action eq "hsdelete") {
+ print("HSDELETE $db.$table op=$op loop=$loop\n");
+ $cli->open_index(1, $db, $table, '', '');
+ for (my $i = 0; $i < $loop; ++$i) {
+ my $k = "" . int(rand($tablesize));
+ print "k=$k\n";
+ my $r = $cli->execute_delete(1, $op, [ $k ], 1, 0);
+ if ($verbose >= 10) {
+ print "DEL k=$k\n";
+ }
+ print "$i/$loop\n" if $i % 1000 == 0;
+ }
+ } elsif ($action eq "verify") {
+ verify_do();
+ }
+}
+
+sub verify_do {
+ my ($fail_cnt, $ok_cnt) = (0, 0);
+ my $sth = $dbh->prepare("select v from $db.$table where k = ?");
+ use FileHandle;
+ my $fh = new FileHandle($file, "r");
+ while (my $line = <$fh>) {
+ chomp($line);
+ my @vec = split(/\t/, $line);
+ my $k = $vec[3];
+ my $v = $vec[7];
+ next if (!defined($k) || !defined($v));
+ # print "$k $v\n";
+ $sth->execute($k);
+ my $aref = $sth->fetchrow_arrayref();
+ if (!defined($aref)) {
+ print "FAILED: $k notfound\n";
+ ++$fail_cnt;
+ } else {
+ my $gv = $aref->[0];
+ if ($gv ne $v) {
+ print "FAILED: $k got=$gv expected=$v\n";
+ ++$fail_cnt;
+ } else {
+ print "OK: $k $v $gv\n" if $verbose >= 10;
+ ++$ok_cnt;
+ }
+ }
+ }
+ print "OK=$ok_cnt FAIL=$fail_cnt\n";
+}
+
+sub get_conf {
+ my ($key, $def) = @_;
+ my $val = $conf{$key};
+ if ($val) {
+ print "$key=$val\n";
+ } else {
+ $val = $def;
+ $def ||= '';
+ print "$key=$def(default)\n";
+ }
+ return $val;
+}
+
+sub get_createtbl_moreflds_str {
+ my $s = "";
+ for (my $j = 0; $j < $num_moreflds; ++$j) {
+ $s .= ",$moreflds_prefix$j varchar(30)";
+ }
+ return $s;
+}
+
+sub get_select_moreflds_str {
+ my $s = "";
+ for (my $i = 0; $i < $num_moreflds; ++$i) {
+ $s .= ",$moreflds_prefix$i";
+ }
+ return $s;
+}
+
+sub get_insert_moreflds_str {
+ my $s = "";
+ for (my $i = 0; $i < $num_moreflds; ++$i) {
+ $s .= ",?";
+ }
+ return $s;
+}
+
diff --git a/plugin/handler_socket/client/hstest_hs.sh b/plugin/handler_socket/client/hstest_hs.sh
new file mode 100755
index 00000000000..1b9eee188ec
--- /dev/null
+++ b/plugin/handler_socket/client/hstest_hs.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+exec ./hstest test=10 tablesize=10000 host=localhost hsport=9998 num=10000000 \
+ num_threads=100 timelimit=10 $@
diff --git a/plugin/handler_socket/client/hstest_hs_more50.sh b/plugin/handler_socket/client/hstest_hs_more50.sh
new file mode 100755
index 00000000000..b7539c52921
--- /dev/null
+++ b/plugin/handler_socket/client/hstest_hs_more50.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+exec ./hstest test=10 key_mask=9999 host=localhost port=9998 num=10000000 \
+ num_threads=100 timelimit=10 moreflds=50 $@
diff --git a/plugin/handler_socket/client/hstest_md.sh b/plugin/handler_socket/client/hstest_md.sh
new file mode 100755
index 00000000000..8129f884d24
--- /dev/null
+++ b/plugin/handler_socket/client/hstest_md.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+./hstest test=7 key_mask=9999 host=localhost port=11211 num=10000 \
+ num_threads=10 timelimit=10 op=R $@
+./hstest test=7 key_mask=9999 host=localhost port=11211 num=1000000 \
+ num_threads=100 timelimit=10 op=G $@
+
diff --git a/plugin/handler_socket/client/hstest_my.sh b/plugin/handler_socket/client/hstest_my.sh
new file mode 100755
index 00000000000..cf917cf48b8
--- /dev/null
+++ b/plugin/handler_socket/client/hstest_my.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+exec ./hstest test=9 tablesize=9999 host=localhost mysqlport=3306 num=1000000 \
+ num_threads=100 verbose=1 timelimit=10 $@
diff --git a/plugin/handler_socket/client/hstest_my_more50.sh b/plugin/handler_socket/client/hstest_my_more50.sh
new file mode 100755
index 00000000000..6782b5e8ed6
--- /dev/null
+++ b/plugin/handler_socket/client/hstest_my_more50.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+exec ./hstest test=9 key_mask=9999 host=localhost port=3306 num=1000000 \
+ num_threads=100 verbose=1 timelimit=10 moreflds=50 $@
diff --git a/plugin/handler_socket/configure.ac b/plugin/handler_socket/configure.ac
new file mode 100644
index 00000000000..4395fcf1994
--- /dev/null
+++ b/plugin/handler_socket/configure.ac
@@ -0,0 +1,144 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+#AC_PREREQ([2.63b])
+AC_INIT([handlersocket-plugin], [1.0.6], [https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL/issues])
+AC_CONFIG_HEADERS([config.h])
+AM_INIT_AUTOMAKE([-Wall -Werror foreign])
+AC_CONFIG_SRCDIR([libhsclient/fatal.cpp])
+AC_CONFIG_MACRO_DIR([m4])
+
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_CPP
+AC_PROG_LIBTOOL
+
+ac_mysql_debug=
+AC_ARG_ENABLE(mysql-debug,
+ [AS_HELP_STRING([--enable-mysql-debug], [specify whether MySQL is build with DBUG_ON])],[ac_mysql_debug="$enableval"],[ac_mysql_debug=no])
+AC_MSG_CHECKING([if --enable-mysql-debug is specified])
+AC_MSG_RESULT($ac_mysql_debug)
+
+AC_DEFUN([CONFIG_OPTION_MYSQL],[
+ AC_MSG_CHECKING([mysql source])
+
+ MYSQL_SOURCE_VERSION=
+ MYSQL_INC=
+ ac_mysql_source_dir=
+ AC_ARG_WITH([mysql-source],
+ [AS_HELP_STRING([--with-mysql-source=PATH], [MySQL source directory PATH])],
+ [
+ ac_mysql_source_dir=`cd $withval && pwd`
+ if test -f "$ac_mysql_source_dir/sql/handler.h" ; then
+ MYSQL_INC="-I$ac_mysql_source_dir/sql"
+ MYSQL_INC="$MYSQL_INC -I$ac_mysql_source_dir/include"
+ MYSQL_INC="$MYSQL_INC -I$ac_mysql_source_dir/regex"
+ MYSQL_INC="$MYSQL_INC -I$ac_mysql_source_dir"
+ AC_SUBST(MYSQL_INC)
+ if test -f "$ac_mysql_source_dir/VERSION"; then
+ source "$ac_mysql_source_dir/VERSION"
+ MYSQL_SOURCE_VERSION="$MYSQL_VERSION_MAJOR.$MYSQL_VERSION_MINOR.$MYSQL_VERSION_PATCH"
+ else
+ if test -f "$ac_mysql_source_dir/configure.in"; then
+ MYSQL_SOURCE_VERSION=`cat $ac_mysql_source_dir/configure.in | grep "\[[MySQL Server\]]" | sed -e "s|.*\([[0-9]]\+\.[[0-9]]\+\.[[0-9]]\+[[0-9a-zA-Z\_\-]]*\).*|\1|"`
+ else
+ AC_MSG_ERROR([invalid MySQL source directory: $ac_mysql_source_dir])
+ fi
+ fi
+ AC_MSG_RESULT([yes: Using $ac_mysql_source_dir, version $MYSQL_SOURCE_VERSION])
+ else
+ AC_MSG_ERROR([invalid MySQL source directory: $ac_mysql_source_dir])
+ fi
+ ],
+ [AC_MSG_ERROR([--with-mysql-source=PATH is required for standalone build])]
+ )
+
+ MYSQL_BIN_VERSION=
+ ac_mysql_config=
+ AC_ARG_WITH([mysql-bindir],
+ [AS_HELP_STRING([--with-mysql-bindir=PATH], [MySQL binary directory PATH. This should be the directory where mysql_config is located.])],
+ [
+ mysql_bin_dir=`cd $withval 2> /dev/null && pwd || echo ""`
+ ac_mysql_config="$mysql_bin_dir/mysql_config"
+ ],
+ [
+ AC_PATH_PROG([ac_mysql_config], [mysql_config])
+ ]
+ )
+
+ AC_MSG_CHECKING([mysql binary])
+ if test ! -x "$ac_mysql_config" ; then
+ AC_MSG_ERROR([mysql_config not found! You have to specify the directory where mysql_config resides to --with-mysql-bindir=PATH.])
+ fi
+
+ MYSQL_CFLAGS_ADD=`"$ac_mysql_config" --cflags`
+ MYSQL_CFLAGS="$MYSQL_CFLAGS $MYSQL_CFLAGS_ADD"
+ if test "$ac_mysql_debug" = "yes"; then
+ MYSQL_CFLAGS="$MYSQL_CFLAGS -DDBUG_ON -DENABLED_DEBUG_SYNC"
+ else
+ MYSQL_CFLAGS="$MYSQL_CFLAGS -DDBUG_OFF"
+ fi
+ AC_SUBST(MYSQL_CFLAGS)
+
+ MYSQL_BIN_VERSION=`"$ac_mysql_config" --version`
+ AC_MSG_RESULT([yes: Using $ac_mysql_config, version $MYSQL_BIN_VERSION])
+
+ MYSQL_LIB=`"$ac_mysql_config" --libs_r`
+ LIB_DIR=`echo $MYSQL_LIB | sed -e "s|.*-L/|/|" | sed -e "s| .*||"`
+ # FIXME
+ if test a`basename "$LIB_DIR"` = amysql ; then
+ MYSQL_LIB="-L`dirname $LIB_DIR` $MYSQL_LIB"
+ # FIXME
+ fi
+ AC_SUBST(MYSQL_LIB)
+
+ if test a$MYSQL_SOURCE_VERSION != a$MYSQL_BIN_VERSION ; then
+ AC_MSG_ERROR([MySQL source version does not match MySQL binary version])
+ fi
+
+ AC_MSG_CHECKING([mysql plugin dir])
+ ac_mysql_plugin_dir=
+ AC_ARG_WITH([mysql-plugindir],
+ [AS_HELP_STRING([--with-mysql-plugindir=PATH], [MySQL plugin directory where handlersocket.so to be copied])],
+ [
+ ac_mysql_plugin_dir=`cd $withval && pwd`
+ if test -d "$ac_mysql_plugin_dir/" ; then
+ PLUGIN_DIR="$ac_mysql_plugin_dir"
+ AC_SUBST(PLUGIN_DIR)
+ AC_MSG_RESULT([yes: Using $ac_mysql_plugin_dir])
+ else
+ AC_MSG_ERROR([invalid MySQL plugin directory : $ac_mysql_plugin_dir])
+ fi
+ ],
+ [
+ LIB_DIR_TMP=`"$ac_mysql_config" --plugindir`
+ if test ! -d "$LIB_DIR_TMP"; then
+ LIB_DIR_TMP=`"$ac_mysql_config" --libs_r | sed -e "s|.*-L/|/|" | sed -e "s| .*||"`/plugin
+ # FIXME
+ fi
+ ac_mysql_plugin_dir=$LIB_DIR_TMP
+ PLUGIN_DIR="$ac_mysql_plugin_dir"
+ AC_SUBST(PLUGIN_DIR)
+ AC_MSG_RESULT([--with-mysql-plugindir was not set. Using $ac_mysql_plugin_dir])
+ ]
+ )
+])
+
+HANDLERSOCKET_SUBDIRS="libhsclient"
+AC_ARG_ENABLE(handlersocket_server,
+ [ --enable-handlersocket-server build HandlerSocket plugin (defalut=yes)])
+if test "$enable_handlersocket_server" != "no"; then
+ CONFIG_OPTION_MYSQL
+ HANDLERSOCKET_SUBDIRS="libhsclient handlersocket client"
+fi
+AC_SUBST(HANDLERSOCKET_SUBDIRS)
+
+CFLAGS="$CFLAGS -Werror"
+CXXFLAGS="$CXXFLAGS -Wall -g -fno-rtti -fno-exceptions -fPIC -DPIC"
+
+AC_CONFIG_FILES([Makefile
+ handlersocket/Makefile
+ libhsclient/Makefile
+ client/Makefile])
+
+AC_OUTPUT
diff --git a/plugin/handler_socket/docs-en/about-handlersocket.en.txt b/plugin/handler_socket/docs-en/about-handlersocket.en.txt
new file mode 100644
index 00000000000..0a13a2713d6
--- /dev/null
+++ b/plugin/handler_socket/docs-en/about-handlersocket.en.txt
@@ -0,0 +1,72 @@
+
+-----------------------------------------------------------------------------
+HandlerSocket plugin for MySQL
+
+Copyright (c) 2010 DeNA Co.,Ltd.
+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 above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of DeNA Co.,Ltd. nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY DeNA Co.,Ltd. "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 DeNA Co.,Ltd. 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.
+
+
+-----------------------------------------------------------------------------
+About HandlerSocket
+
+HandlerSocket is a NoSQL plugin for MySQL. It works as a daemon inside the
+mysqld process, accept tcp connections, and execute requests from clients.
+HandlerSocket does not support SQL queries. Instead, it supports simple CRUD
+operations on tables.
+
+Because of the following reasons, HandlerSocket is much faster than the
+mysqld/libmysql pair in some circumstances:
+
+ - HandlerSocket manipulates data without parsing SQL, which causes less
+ CPU usage.
+ - HandlerSocket reads many requests from clients and executes their
+ requests in bulk, which causes less CPU and disk usage.
+ - HandlerSocket client/server protocol is more compact than the
+ mysql/libmysql pair, which causes less network usage.
+
+The current version of HandlerSocket only works with GNU/Linux. The source
+archive of HandlerSocket includes a C++ and a Perl client libraries.
+Here is a list of other language bindings:
+
+ - PHP
+ http://openpear.org/package/Net_HandlerSocket
+ http://github.com/tz-lom/HSPHP
+ http://code.google.com/p/php-handlersocket/
+ - Java
+ http://code.google.com/p/handlersocketforjava/
+ - Python
+ https://code.launchpad.net/~songofacandy/+junk/pyhandlersocket
+ - Ruby
+ https://github.com/winebarrel/ruby-handlersocket
+ https://github.com/miyucy/handlersocket
+ - JavaScript(Node.js)
+ https://github.com/koichik/node-handlersocket
+
+The home of HandlerSocket is here:
+ https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL
+
+More documents are available in docs-en/ and docs-ja/ directories.
+
diff --git a/plugin/handler_socket/docs-en/configuration-options.en.txt b/plugin/handler_socket/docs-en/configuration-options.en.txt
new file mode 100644
index 00000000000..60fb6d85f3c
--- /dev/null
+++ b/plugin/handler_socket/docs-en/configuration-options.en.txt
@@ -0,0 +1,99 @@
+
+-----------------------------------------------------------------
+handlersocket_verbose (default = 10, min = 0, max = 10000)
+
+ Specify the logging verboseness.
+
+-----------------------------------------------------------------
+handlersocket_address (default = '')
+
+ Specify the address to bind. If empty, it binds to 0.0.0.0.
+
+-----------------------------------------------------------------
+handlersocket_port (default = '9998')
+
+ Specify the port to bind. This option is for the listener for
+ read requests. If empty, the listener is disabled.
+
+-----------------------------------------------------------------
+handlersocket_port_wr (default = '9999')
+
+ Specify the port to bind. This option is for the listener for
+ write requests. If empty, the listener is disabled.
+
+-----------------------------------------------------------------
+handlersocket_epoll (default = 1, min = 0, max = 1)
+
+ Specify whether handlersocket uses epoll for I/O multiplexing.
+
+-----------------------------------------------------------------
+handlersocket_threads (default = 16, min = 1, max = 3000)
+
+ Specify the number of handlersocket worker threads. This option
+ is for the listener for read requests. Recommended value is
+ (the number of CPU cores * 2).
+
+-----------------------------------------------------------------
+handlersocket_threads_wr (default = 1, min = 1, max = 3000)
+
+ Specify the number of handlersocket worker threads. This option
+ is for the listener for write requests. Recommended value is 1.
+
+-----------------------------------------------------------------
+handlersocket_timeout (default = 300, min = 30, max = 3600)
+
+ Specify the socket timeout in seconds.
+
+-----------------------------------------------------------------
+handlersocket_backlog (default = 32768, min = 5, max = 1000000)
+
+ Specify the length of the listen backlog.
+
+-----------------------------------------------------------------
+handlersocket_sndbuf (default = 0, min = 0, max = 1677216)
+
+ Specify the maximum socket send buffer in bytes. If 0, the
+ system-wide default value is set.
+
+-----------------------------------------------------------------
+handlersocket_rcvbuf (default = 0, min = 0, max = 1677216)
+
+ Specify the maximum socket receive buffer in bytes. If 0, the
+ system-wide default value is set.
+
+-----------------------------------------------------------------
+handlersocket_readsize (default = 0, min = 0, max = 1677216)
+
+ Specify the minimum length of the handlersocket request buffer.
+ Larger value can make handlersocket faster for large requests,
+ but can consume memory. The default value is possibly 4096.
+
+-----------------------------------------------------------------
+handlersocket_accept_balance (default = 0, min = 0, max = 10000)
+
+ When this option is set to non-zero, handlersocket tries to
+ balance accepted connections among threads. Non-zero is
+ recommended if you use persistent connections (i.e., connection
+ pooling on the client side).
+
+-----------------------------------------------------------------
+handlersocket_wrlock_timeout (default = 12, min = 0, max = 3600)
+
+ Specify the lock timeout in seconds. When a write request is
+ performed, handlersocket acquires an advisory lock named
+ 'handlersocket_wr'. This option sets the timeout for the
+ locking.
+
+-----------------------------------------------------------------
+handlersocket_plain_secret (default = '')
+
+ When this option is specified, a plain-text authentication is
+ enabled for the listener for read requests. This option
+ specifies the secret key for the authentication.
+
+-----------------------------------------------------------------
+handlersocket_plain_secret_wr (default = '')
+
+ This option specifies the secret key for the listener for write
+ requests.
+
diff --git a/plugin/handler_socket/docs-en/installation.en.txt b/plugin/handler_socket/docs-en/installation.en.txt
new file mode 100644
index 00000000000..8e680ed35f1
--- /dev/null
+++ b/plugin/handler_socket/docs-en/installation.en.txt
@@ -0,0 +1,91 @@
+1. Building Handlersocket
+
+ Handlersocket mainly consists of libhsclient, handlersocket, and C++/Perl clients. libhsclient is a common library shared from both client and server(plugin). handlersocket is a MySQL daemon plugin.
+ To build Handlersocket, you need both MySQL source code and MySQL binary. It is not required to pre-build MySQL source code, but source itself is needed because Handlersocket depends on MySQL header files that only MySQL source distribution contains. MySQL binary is just a normal MySQL binary distribution. You can use official MySQL binaries provided by Oracle.
+ Since Handlersocket uses daemon plugin interface supported from MySQL 5.1,
+MySQL 5.1 or higher version is required.
+ Please make sure that you use identical MySQL version between MySQL source
+and MySQL binary. Otherwise you might encounter serious problems (i.e. server
+crash, etc).
+ Here are steps to build Handlersocket.
+
+* Get MySQL source code
+
+* Get MySQL binary
+
+* Build Handlersocket
+ $ ./autogen.sh
+ $ ./configure --with-mysql-source=/work/mysql-5.1.50 --with-mysql-bindir=/work/mysql-5.1.50-linux-x86_64-glibc23/bin --with-mysql-plugindir=/work/mysql-5.1.50-linux-x86_64-glibc23/lib/plugin
+
+ --with-mysql-source refers to the top of MySQL source directory,
+--with-mysql-bindir refers to where MySQL binary executables (i.e.
+mysql_config) are located, and --with-mysql-plugindir refers to a plugin
+directory where plugin libraries (*.so) are installed.
+
+ $ make
+ $ sudo make install
+
+ Both libhsclient and the handlersocket plugin will be installed.
+
+
+2. Using Handlersocket
+
+Append configuration options for handlersocket to my.cnf.
+
+ [mysqld]
+ loose_handlersocket_port = 9998
+ # the port number to bind to (for read requests)
+ loose_handlersocket_port_wr = 9999
+ # the port number to bind to (for write requests)
+ loose_handlersocket_threads = 16
+ # the number of worker threads (for read requests)
+ loose_handlersocket_threads_wr = 1
+ # the number of worker threads (for write requests)
+ open_files_limit = 65535
+ # to allow handlersocket accept many concurrent
+ # connections, make open_files_limit as large as
+ # possible.
+
+Log in to mysql as root, and execute the following query.
+
+ mysql> install plugin handlersocket soname 'handlersocket.so';
+
+If handlersocket.so is successfully installed, it starts
+accepting connections on port 9998 and 9999. Running
+'show processlist' should show handlersocket worker threads.
+
+-----------------------------------------------------------------
+On the client side, you need to install libhsclient for c++ apps
+and perl-Net-HandlerSocket for perl apps. They do not require
+MySQL to compile.
+
+ $ ./autogen.sh
+ $ ./configure --disable-handlersocket-server
+ $ make
+ $ sudo make install
+ $ cd perl-Net-HandlerSocket
+ $ perl Makefile.PL
+ $ make
+ $ sudo make install
+
+-----------------------------------------------------------------
+Alternatively, you can use the rpm installation. If your OS
+supports rpms, you can use the following commands to build and
+install handlersocket rpm packages.
+
+(Server side, installs HandlerSocket plugin)
+ $ ./autogen.sh
+ $ ./configure --with-mysql-source=/work/mysql-5.1.50 --with-mysql-bindir=/work/mysql-5.1.50-linux-x86_64-glibc23/bin --with-mysql-plugindir=/work/mysql-5.1.50-linux-x86_64-glibc23/lib/plugin
+ $ make rpm_cli
+ $ sudo rpm -U dist/RPMS/*/libhsclient*.rpm
+ $ make rpm_c
+ $ sudo rpm -U dist/RPMS/*/handlersocket*.rpm
+
+(Client side, installs client libraries)
+ $ ./autogen.sh
+ $ ./configure --disable-handlersocket-server
+ $ make rpm_cli
+ $ sudo rpm -U dist/RPMS/*/libhsclient*.rpm
+ $ make rpm_perl
+ $ sudo rpm -U dist/RPMS/*/perl-Net-HandlerSocket*.rpm
+
diff --git a/plugin/handler_socket/docs-en/perl-client.en.txt b/plugin/handler_socket/docs-en/perl-client.en.txt
new file mode 100644
index 00000000000..2b863c638f0
--- /dev/null
+++ b/plugin/handler_socket/docs-en/perl-client.en.txt
@@ -0,0 +1,126 @@
+
+-----------------------------------------------------------------
+To open a connection to the handlersocket plugin, you need to
+create a Net::HandlerSocket object.
+
+ use Net::HandlerSocket;
+ my $args = { host => 'localhost', port => 9998 };
+ my $hs = new Net::HandlerSocket($args);
+
+-----------------------------------------------------------------
+Before executing table operations, you need to open an index to
+work with.
+
+ my $err = $hs->open_index(3, 'database1', 'table1', 'PRIMARY',
+ 'f1,f2');
+ die $hs->get_error() if $res->[0] != 0;
+
+The first argument for open_index is an integer value which is
+used to identify an open table, which is only valid within the
+same Net::HandlerSocket object. The 4th argument is the name of
+index to open. If 'PRIMARY' is specified, the primary index is
+open. The 5th argument is a comma-separated list of column names.
+
+-----------------------------------------------------------------
+To read a record from a table using an index, call the
+execute_single method.
+
+ my $res = $hs->execute_single(3, '=', [ 'foo' ], 1, 0);
+ die $hs->get_error() if $res->[0] != 0;
+ shift(@$res);
+
+The first argument must be an integer which has specified as the
+first argument for open_index on the same Net::HandlerSocket
+object. The second argument specifies the search operation. The
+current version of handlersocket supports '=', '>=', '<=', '>',
+and '<'. The 3rd argument specifies the key to find, which must
+an arrayref whose length is equal to or smaller than the number
+of key columns of the index. The 4th and the 5th arguments
+specify the maximum number of records to be retrieved, and the
+number of records skipped before retrieving records. The columns
+to be retrieved are specified by the 5th argument for the
+corresponding open_index call.
+
+The execute_single method always returns an arrayref. The first
+element is the error code, which is 0 when no error is occured.
+The remaining are the field values. If more than one record is
+returned, it is flatten to an 1-dimensional array. For example,
+when 5 records that have 3 columns are returned, you can retrieve
+values using the following code.
+
+ die $hs->get_error() if $res->[0] != 0;
+ shift(@$res);
+ for (my $row = 0; $row < 5; ++$row) {
+ for (my $col = 0; $col < 3; ++$col) {
+ my $value = $res->[$row * 5 + $col];
+ # ...
+ }
+ }
+
+-----------------------------------------------------------------
+To update or delete records, you need to specify more arguments
+for the execute_single method. Note that the Net::HandlerSocket
+object must be connected to a handlersocket worker for write
+operations, which is port 9999 by default.
+(For safety, the port 9998 only allows read operations, and the
+port 9999 allows write operations also. The port 9999 allows
+read operations too, but slower than 9998 because of record
+locking etc.. Port numbers can be changed using the
+'handlersocket_port' and the 'handlersocket_port_wr'
+configuration options of mysqld.)
+
+ my $args = { host => 'localhost', port => 9999 };
+ my $hs = new Net::HandlerSocket($args);
+
+ my $res = $hs->execute_single(3, '=', [ 'bar' ], 1, 0, 'U',
+ [ 'fubar', 'hoge' ]);
+ die $hs->get_error() if $res->[0] != 0;
+ my $num_updated_rows = $res->[1];
+
+ my $res = $hs->execute_single(3, '=', [ 'baz' ], 1, 0, 'D');
+ die $hs->get_error() if $res->[0] != 0;
+ my $num_deleted_rows = $res->[1];
+
+The 6th argument for execute_single specifies the modification
+operation. The current version supports 'U' and 'D'. For the 'U'
+operation, the 7th argument specifies the new value for the row.
+The columns to be modified are specified by the 5th argument for
+the corresponding open_index call. For the 'D' operation, the
+7th argument can be omitted.
+
+-----------------------------------------------------------------
+The execute_single method can be used for inserting records also.
+
+ my $res = $hs->execute_single(3, '+', [ 'foo', 'bar', 'baz' ]);
+ die $hs->get_error() if $res->[0] != 0;
+ my $num_inserted_rows = $res->[1];
+
+The 3rd argument must be an arrayref whose elements correspond to
+the 5th argument for the corresponding open_index call. If there
+is a column which is not appeared in the 5th argument for the
+open_index, the default value for the column is set.
+
+-----------------------------------------------------------------
+Multiple operations can be executed in a single call. Executing
+multiple operations in a single call is much faster than
+executing them separatedly.
+
+ my $rarr = $hs->execute_multi([
+ [ 0, '>=', [ 'foo' ], 5, 0 ],
+ [ 2, '=', [ 'bar' ], 1, 0 ],
+ [ 4, '<', [ 'baz' ], 10, 5 ],
+ ]);
+ for my $res (@$rarr) {
+ die $hs->get_error() if $res->[0] != 0;
+ shift(@$res);
+ # ...
+ }
+
+-----------------------------------------------------------------
+When an error is occured, the first element of the returned
+arrayref becomes a non-zero value. A negative value indicates
+that an I/O error is occured and the Net::HandlerSocket object
+should be disposed. A positive value means that the connection is
+still active and the Net::HandlerSocket object can be reused
+later.
+
diff --git a/plugin/handler_socket/docs-en/protocol.en.txt b/plugin/handler_socket/docs-en/protocol.en.txt
new file mode 100644
index 00000000000..afde231df7d
--- /dev/null
+++ b/plugin/handler_socket/docs-en/protocol.en.txt
@@ -0,0 +1,198 @@
+
+----------------------------------------------------------------------------
+The HandlerSocket protocol
+
+----------------------------------------------------------------------------
+Basic syntax
+
+- The HandlerSocket protocol is line-based. Each line ends with LF(0x0a).
+- Each line consists a concatenation of tokens separated by HT(0x09).
+- A token is either NULL or an encoded string. Note that you need to
+ distinguish NULL from an empty string, as most DBMs does so.
+- NULL is expressed as a single NUL(0x00).
+- An encoded string is a string with the following encoding rules.
+ - Characters in the range [0x10 - 0xff] are encoded as itselves.
+ - A character in the range [0x00 - 0x0f] is prefixed by 0x01 and
+ shifted by 0x40. For example, 0x03 is encoded as 0x01 0x43.
+- Note that a string can be empty. A continuation of 0x09 0x09 means that
+ there is an empty string between them. A continuation of 0x09 0x0a means
+ that there is an empty string at the end of the line.
+
+----------------------------------------------------------------------------
+Request and Response
+
+- The HandlerSocket protocol is a simple request/response protocol. After a
+ connection is established, the client side sends a request, and then the
+ server side sends a response.
+- A request/response consists of a single line.
+- Requests can be pipelined; That is, you can send multiple requests (ie.
+ lines) at one time, and receive responses for them at one time.
+
+----------------------------------------------------------------------------
+'open_index' request
+
+The 'open_index' request has the following syntax.
+
+ P <indexid> <dbname> <tablename> <indexname> <columns> [<fcolumns>]
+
+- <indexid> is a number in decimal.
+- <dbname>, <tablename>, and <indexname> are strings. To open the primary
+ key, use PRIMARY as <indexname>.
+- <columns> is a comma-separated list of column names.
+- <fcolumns> is a comma-separated list of column names. This parameter is
+ optional.
+
+Once an 'open_index' request is issued, the HandlerSocket plugin opens the
+specified index and keep it open until the client connection is closed. Each
+open index is identified by <indexid>. If <indexid> is already open, the old
+open index is closed. You can open the same combination of <dbname>
+<tablename> <indexname> multple times, possibly with different <columns>.
+For efficiency, keep <indexid> small as far as possible.
+
+----------------------------------------------------------------------------
+Getting data
+
+The 'find' request has the following syntax.
+
+ <indexid> <op> <vlen> <v1> ... <vn> [LIM] [IN] [FILTER ...]
+
+LIM is a sequence of the following parameters.
+
+ <limit> <offset>
+
+IN is a sequence of the following parameters.
+
+ @ <icol> <ivlen> <iv1> ... <ivn>
+
+FILETER is a sequence of the following parameters.
+
+ <ftyp> <fop> <fcol> <fval>
+
+- <indexid> is a number. This number must be an <indexid> specified by a
+ 'open_index' request executed previously on the same connection.
+- <op> specifies the comparison operation to use. The current version of
+ HandlerSocket supports '=', '>', '>=', '<', and '<='.
+- <vlen> indicates the length of the trailing parameters <v1> ... <vn>. This
+ must be smaller than or equal to the number of index columns specified by
+ the <columns> parameter of the corresponding 'open_index' request.
+- <v1> ... <vn> specify the index column values to fetch.
+- LIM is optional. <limit> and <offset> are numbers. When omitted, it works
+ as if 1 and 0 are specified. These parameter works like LIMIT of SQL.
+ These values don't include the number of records skipped by a filter.
+- IN is optional. It works like WHERE ... IN syntax of SQL. <icol> must be
+ smaller than or equal to the number of index columns specified by the
+ <columns> parameter of the corresponding 'open_index' request. If IN is
+ specified in a find request, the <icol>-th parameter value of <v1> ...
+ <vn> is ignored.
+ smaller than or equal to the number of index columns specified by the
+- FILTERs are optional. A FILTER specifies a filter. <ftyp> is either 'F'
+ (filter) or 'W' (while). <fop> specifies the comparison operation to use.
+ <fcol> must be smaller than or equal to the number of columns specified by
+ the <fcolumns> parameter of the corresponding 'open_index' request.
+ Multiple filters can be specified, and work as the logical AND of them.
+ The difference of 'F' and 'W' is that, when a record does not meet the
+ specified condition, 'F' simply skips the record, and 'W' stops the loop.
+
+----------------------------------------------------------------------------
+Updating/Deleting data
+
+The 'find_modify' request has the following syntax.
+
+ <indexid> <op> <vlen> <v1> ... <vn> [LIM] [IN] [FILTER ...] MOD
+
+MOD is a sequence of the following parameters.
+
+ <mop> <m1> ... <mk>
+
+- <mop> is 'U' (update), '+' (increment), '-' (decrement), 'D' (delete),
+ 'U?', '+?', '-?', or 'D?'. If the '?' suffix is specified, it returns
+ the contents of the records before modification (as if it's a 'find'
+ request), instead of the number of modified records.
+- <m1> ... <mk> specifies the column values to set. The length of <m1> ...
+ <mk> must be smaller than or equal to the length of <columns> specified by
+ the corresponding 'open_index' request. If <mop> is 'D', these parameters
+ are ignored. If <mop> is '+' or '-', values must be numeric. If <mop> is
+ '-' and it attempts to change column values from negative to positive or
+ positive to negative, it is not modified.
+
+----------------------------------------------------------------------------
+Inserting data
+
+The 'insert' request has the following syntax.
+
+ <indexid> + <vlen> <v1> ... <vn>
+
+- <vlen> indicates the length of the trailing parameters <v1> ... <vn>. This
+ must be smaller than or equal to the length of <columns> specified by the
+ corresponding 'open_index' request.
+- <v1> ... <vn> specify the column values to set. For columns not in
+ <columns>, the default values for each column are set.
+
+----------------------------------------------------------------------------
+Authentication
+
+The 'auth' request has the following syntax.
+
+ A <atyp> <akey>
+
+- <atyp> must be '1'
+- An 'auth' request succeeds iff <akey> is the correct secret specified by
+ the 'handlersocket_plain_secret' or 'handlersocket_plain_secret_rw'.
+- If an authentication is enabled for a listener, any other requests on a
+ connection fail before an 'auth' request succeeded on the connection.
+
+----------------------------------------------------------------------------
+Response syntax
+
+HandlerSocket returns a response of the following syntax for each request.
+
+ <errorcode> <numcolumns> <r1> ... <rn>
+
+- <errorcode> indicates whether the request has successfully executed or not.
+ '0' means success. Non-zero means an error.
+- <numcolumns> indicates the number of columns of the result set.
+- <r1> ... <rn> is the result set. The length of <r1> ... <rn> is always a
+ multiple of <numcolumns>. It is possible that <r1> ... <rn> is empty.
+
+If <errorcode> is non-zero, <numcolumns> is always 1 and <r1> indicates a
+human-readable error message, though sometimes <r1> is not provided.
+
+----------------------------------------------------------------------------
+Response for 'open_index'
+
+If 'open_index' is succeeded, HandlerSocket returns a line of the following
+syntax.
+
+ 0 1
+
+----------------------------------------------------------------------------
+Response for 'find'
+
+If 'find' is succeeded, HandlerSocket returns a line of the following
+syntax.
+
+ 0 <numcolumns> <r1> ... <rn>
+
+- <numcolumns> always equals to the length of <columns> of the corresponding
+ 'open_index' request.
+- <r1> ... <rn> is the result set. If N rows are found, the length of <r1>
+ ... <rn> becomes ( <numcolumns> * N ).
+
+----------------------------------------------------------------------------
+Response for 'find_modify'
+
+If 'find_modify' is succeeded, HandlerSocket returns a line of the following
+syntax.
+
+ 0 1 <nummod>
+
+- <nummod> is the number of modified rows.
+
+----------------------------------------------------------------------------
+Response for 'insert'
+
+If 'insert' is succeeded, HanderSocket returns a line of the following
+syntax.
+
+ 0 1
+
diff --git a/plugin/handler_socket/docs-ja/about-handlersocket.ja.txt b/plugin/handler_socket/docs-ja/about-handlersocket.ja.txt
new file mode 100644
index 00000000000..2a152e87545
--- /dev/null
+++ b/plugin/handler_socket/docs-ja/about-handlersocket.ja.txt
@@ -0,0 +1,51 @@
+
+
+-----------------------------------------------------------------
+ソースコードã®åˆ©ç”¨ã«ã‚ãŸã£ã¦ã®å…責事項
+
+本ソフトウェアã®é–‹ç™ºè€…ãŠã‚ˆã³æ ªå¼ä¼šç¤¾ãƒ‡ã‚£ãƒ¼ãƒ»ã‚¨ãƒŒãƒ»ã‚¨ãƒ¼ã¯ã€æœ¬ãƒ•ãƒˆ
+ウェアã®ä¸ç¨¼å‹•ã€ç¨¼å‹•ä¸è‰¯ã‚’å«ã‚€æ³•å¾‹ä¸Šã®ç‘•ç–µæ‹…ä¿è²¬ä»»ã€ãã®ä»–ä¿è¨¼è²¬
+任を負ã‚ãªã„ã‚‚ã®ã¨ã—ã¾ã™ã€‚ã¾ãŸã€æœ¬ã‚½ãƒ•ãƒˆã‚¦ã‚¨ã‚¢ã®é–‹ç™ºè€…ãŠã‚ˆã³æ ªå¼
+会社ディー・エヌ・エーã¯ã€æœ¬ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã®å•†å“性ã€ã¾ãŸã¯ãŠå®¢æ§˜ã®
+特定ã®ç›®çš„ã«å¯¾ã™ã‚‹é©åˆæ€§ã«ã¤ã„ã¦ã€ã„ã‹ãªã‚‹ä¿è¨¼ã‚‚è² ã‚ãªã„ã‚‚ã®ã¨ã—
+ã¾ã™ã€‚
+
+-----------------------------------------------------------------
+handlersocket pluginã«ã¤ã„ã¦
+
+mysqlサーãƒã«å¸¸é§ã—ã€innodbç­‰ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚¨ãƒ³ã‚¸ãƒ³ã¸ã®ç›´æŽ¥ã®ã‚¢ã‚¯ã‚»
+スをæä¾›ã™ã‚‹ãƒ—ラグインã§ã™ã€‚handlersocketプラグインã¯è‡ªå‰ã®ãƒªã‚¹
+ナーをæŒã¡ã€å°‚用ã®ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆãƒ©ã‚¤ãƒ–ラリ(libhsclient)を使ã£ã¦ãã‚Œ
+ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¾ã™ã€‚
+
+mysqlã®æ¨™æº–クライアントライブラリ(libmysql)を使ã£ãŸã‚¢ã‚¯ã‚»ã‚¹ã¨æ¯”ã¹
+ã¦ã€ä»¥ä¸‹ã®ã‚ˆã†ãªåˆ©ç‚¹ãŒã‚ã‚Šã¾ã™ã€‚
+・接続ã‚ãŸã‚Šã«æ¶ˆè²»ã™ã‚‹ãƒªã‚½ãƒ¼ã‚¹ãŒå°‘ãªã„ãŸã‚ã€åŒæ™‚接続数ãŒäº‹å®Ÿä¸Šç„¡
+ 制é™ã€‚ã—ãŸãŒã£ã¦æŽ¥ç¶šæ•°ã‚’æ°—ã«ã›ãšæŒç¶šæŽ¥ç¶šã‚’使ãˆã¾ã™ã€‚
+・高速(å˜ç´”ãªå‚照クエリã§3å€ã€œ10å€ç¨‹åº¦)。
+・通信プロトコルãŒã‚³ãƒ³ãƒ‘クト。libmysqlを使ã†ã¨ãƒ‡ãƒ¼ã‚¿è»¢é€æ™‚ã«ãƒ¬
+ コードåãªã©ãŒä»˜éšã™ã‚‹ãŸã‚ã«é€šä¿¡å†…容ãŒå†—é•·ã§ã™ãŒã€libhsclientã§
+ ã¯ãƒ‡ãƒ¼ã‚¿ã®ã¿ãŒè»¢é€ã•ã‚Œã‚‹ãŸã‚ã€å¸¯åŸŸæ¶ˆè²»ãŒå°‘ãªããªã‚Šã¾ã™ã€‚å ´åˆã«
+ よã£ã¦ã¯10å€ä»¥ä¸Šlibmysqlã®ã»ã†ãŒå†—é•·ã«ãªã‚Šã¾ã™ã€‚
+
+ç¾åœ¨ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ä»¥ä¸‹ã®ã‚ˆã†ãªå‡¦ç†ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™ã€‚
+・指定ã•ã‚ŒãŸç´¢å¼•ã«ã¤ã„ã¦ã€æŒ‡å®šã•ã‚ŒãŸå€¤ã¨å®Œå…¨ä¸€è‡´ã™ã‚‹ã‚ˆã†ãªãƒ¬ã‚³ãƒ¼
+ ドをå–得。(SELECT ??? FROM tbl WHERE k1 = v1 AND k2 = v2...)。
+ 索引を使ã‚ãªã„検索ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。
+・指定ã•ã‚ŒãŸç´¢å¼•ã«ã¤ã„ã¦ã€æŒ‡å®šã•ã‚ŒãŸå€¤ã®ä½ç½®ã®å‰å¾Œã®ãƒ¬ã‚³ãƒ¼ãƒ‰ã‚’å–
+ 得。(SELECT ??? FROM tbl WHERE k1 >= v1 LIMIT 100)
+・å‰è¿°ã®ã‚ˆã†ãªæ‰‹æ®µã§å–å¾—ã—ãŸãƒ¬ã‚³ãƒ¼ãƒ‰ã«å¯¾ã™ã‚‹UPDATEã¨DELETE
+・レコードã®INSERT
+
+以下ã®ã‚ˆã†ãªè¨€èªžã‚’サãƒãƒ¼ãƒˆã—ã¾ã™ã€‚
+・C++。libhsclientをリンクã—ã¾ã™ã€‚
+・Perl。Net::HandlerSocketã‚’useã—ã¾ã™ã€‚
+
+ç¾åœ¨ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯GNU/Linuxã§ã®ã¿å‹•ä½œã—ã¾ã™ã€‚
+
+-----------------------------------------------------------------
+既知ã®å•é¡Œ
+
+・killã§handlersocketスレッドを殺ã™ã¨ã€ã‚¹ãƒ¬ãƒƒãƒ‰æ•°ãŒæ¸›ã£ãŸã¾ã¾å›žå¾©
+ ã—ã¾ã›ã‚“。
+
diff --git a/plugin/handler_socket/docs-ja/installation.ja.txt b/plugin/handler_socket/docs-ja/installation.ja.txt
new file mode 100644
index 00000000000..c14f47f6c02
--- /dev/null
+++ b/plugin/handler_socket/docs-ja/installation.ja.txt
@@ -0,0 +1,87 @@
+
+-----------------------------------------------------------------
+HandlerSocketプラグインã®ãƒ“ルド方法(RPMを使ã‚ãªã„方法)
+
+以下ã®ã‚ˆã†ã«ã—ã¦configureを実行ã—ã¾ã™ã€‚
+
+ $ ./autogen.sh
+ $ ./configure --with-mysql-source=/work/mysql-5.1.50 --with-mysql-bindir=/work/mysql-5.1.50-linux-x86_64-glibc23/bin --with-mysql-plugindir=/work/mysql-5.1.50-linux-x86_64-glibc23/lib/plugin
+
+ã“ã“ã§--with-mysql-sourceã«ã¯MySQLã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã®ãƒˆãƒƒãƒ—ディレク
+トリを指定ã—ã¾ã™ã€‚--with-mysql-bindirã«ã¯ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«æ¸ˆã¿ã®MySQL
+ã®mysql_configコマンドãŒæœ‰ã‚‹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’指定ã—ã¾ã™ã€‚
+ãã®å¾Œä»¥ä¸‹ã®ã‚ˆã†ã«ãƒ“ルド・インストールã—ã¾ã™ã€‚
+
+ $ make
+ $ sudo make install
+
+-----------------------------------------------------------------
+クライアントライブラリã®ãƒ“ルド方法(RPMを使ã‚ãªã„方法)
+
+クライアントライブラリをビルドã™ã‚‹éš›ã«ã¯ã€MySQLã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã¯
+å¿…è¦ã‚ã‚Šã¾ã›ã‚“。ã¾ãŸMySQLãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„ã‚‹å¿…è¦ã‚‚ã‚ã‚Šã¾ã›ã‚“。
+
+ $ ./autogen.sh
+ $ ./configure --disable-handlersocket-server
+ $ make
+ $ sudo make install
+ $ cd perl-Net-HandlerSocket
+ $ perl Makefile.PL
+ $ make
+ $ sudo make install
+
+-----------------------------------------------------------------
+ビルド方法(RPM)
+
+以下ã®ã‚ˆã†ã«å®Ÿè¡Œã™ã‚Œã°ã€rpmパッケージãŒãƒ“ルド&インストールã•ã‚Œã¾
+ã™ã€‚
+
+(MySQLサーãƒå´ã€HandlerSocketプラグインをインストールã™ã‚‹)
+ $ ./autogen.sh
+ $ ./configure --with-mysql-source=/work/mysql-5.1.50 --with-mysql-bindir=/work/mysql-5.1.50-linux-x86_64-glibc23/bin --with-mysql-plugindir=/work/mysql-5.1.50-linux-x86_64-glibc23/lib/plugin
+ $ make rpm_cli
+ $ sudo rpm -U dist/RPMS/*/libhsclient*.rpm
+ $ make rpm_c
+ $ sudo rpm -U dist/RPMS/*/handlersocket*.rpm
+
+(クライアントå´ã€ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆãƒ©ã‚¤ãƒ–ラリをインストールã™ã‚‹)
+ $ ./autogen.sh
+ $ ./configure --disable-handlersocket-server
+ $ make rpm_cli
+ $ sudo rpm -U dist/RPMS/*/libhsclient*.rpm
+ $ make rpm_perl
+ $ sudo rpm -U dist/RPMS/*/perl-Net-HandlerSocket*.rpm
+
+-----------------------------------------------------------------
+èµ·å‹•
+
+mysqlã‚’èµ·å‹•ã—ãŸçŠ¶æ…‹ã§ã€mysqlã®è¨­å®šãƒ•ã‚¡ã‚¤ãƒ«(my.cnfç­‰)ã«ä»¥ä¸‹ã®å†…容を
+追加ã—ã¾ã™ã€‚
+
+ [mysqld]
+ handlersocket_port = 9998
+ # handlersocketãŒæŽ¥ç¶šã‚’å—ã‘付ã‘ã‚‹ãƒãƒ¼ãƒˆ(å‚照系リクエスト用)
+ handlersocket_port_wr = 9999
+ # handlersocketãŒæŽ¥ç¶šã‚’å—ã‘付ã‘ã‚‹ãƒãƒ¼ãƒˆ(更新系リクエスト用)
+ handlersocket_address =
+ # handlersocketãŒãƒã‚¤ãƒ³ãƒ‰ã™ã‚‹ã‚¢ãƒ‰ãƒ¬ã‚¹(空ã®ã¾ã¾ã§OK)
+ handlersocket_verbose = 0
+ # デãƒãƒƒã‚°ç”¨
+ handlersocket_timeout = 300
+ # 通信タイムアウト(秒)
+ handlersocket_threads = 16
+ # handlersocketã®ãƒ¯ãƒ¼ã‚«ãƒ¼ã‚¹ãƒ¬ãƒƒãƒ‰æ•°
+ thread_concurrency = 128
+ # handlersocketãŒå¹¾ã¤ã‹ã®ã‚¹ãƒ¬ãƒƒãƒ‰ã‚’å æœ‰ã™ã‚‹ãŸã‚ã€å¤§ãã‚ã®
+ # 値を指定ã—ã¦ãã ã•ã„
+ open_files_limit = 65535
+ # ソケットを大é‡ã«é–‹ã‘るよã†ã«ã™ã‚‹ãŸã‚ã€å¤§ãã‚ã®å€¤ã‚’指定ã—
+ # ã¦ãã ã•ã„
+
+以下ã®ã‚¯ã‚¨ãƒªã‚’実行ã—ã¾ã™ã€‚
+
+ mysql> install plugin handlersocket soname 'handlersocket.so';
+ Query OK, 0 rows affected (0.06 sec)
+
+以上ã§handlersocketã¸ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚
+
diff --git a/plugin/handler_socket/docs-ja/perl-client.ja.txt b/plugin/handler_socket/docs-ja/perl-client.ja.txt
new file mode 100644
index 00000000000..5d3adfa3301
--- /dev/null
+++ b/plugin/handler_socket/docs-ja/perl-client.ja.txt
@@ -0,0 +1,118 @@
+
+-----------------------------------------------------------------
+handlersocketプラグインã¸ã®æŽ¥ç¶šã‚’é–‹ãã«ã¯ã€Net::HandlerSocketオブ
+ジェクトを作æˆã—ã¾ã™ã€‚
+
+ use Net::HandlerSocket;
+ my $args = { host => 'localhost', port => 9998 };
+ my $hs = new Net::HandlerSocket($args);
+
+-----------------------------------------------------------------
+検索ãªã©ã®å‘½ä»¤ã‚’実行ã™ã‚‹å‰ã«ã€å‡¦ç†å¯¾è±¡ã¨ãªã‚‹ç´¢å¼•ã‚’é–‹ãå¿…è¦ãŒã‚ã‚Š
+ã¾ã™ã€‚
+
+ my $err = $hs->open_index(3, 'database1', 'table1', 'PRIMARY',
+ 'f1,f2');
+ die $hs->get_error() if $res->[0] != 0;
+
+最åˆã®å¼•æ•°ã¯é–‹ã索引ã«ä»˜ã‘る番å·ã§ã™ã€‚付ã‘ãŸç•ªå·ã¯åŒä¸€ã®
+Net::HandlerSocketオブジェクトã«ã¤ã„ã¦ã®ã¿æœ‰åŠ¹ã§ã™ã€‚第4引数ã¯é–‹ã
+索引ã®åå‰ã§ã€ã€ŒPRIMARYã€ãŒæŒ‡å®šã•ã‚Œå ´åˆã¯ãƒ—ライマリキーãŒé–‹ã‹ã‚Œã¾
+ã™ã€‚第5引数ã¯ã€Œ,ã€ã§åŒºåˆ‡ã‚‰ã‚ŒãŸåˆ—åã®ãƒªã‚¹ãƒˆã§ã™ã€‚
+
+-----------------------------------------------------------------
+テーブルã‹ã‚‰ç´¢å¼•ã‚’使ã£ã¦è¡Œã‚’å–å¾—ã™ã‚‹ã«ã¯ã€execute_singleメソッド
+を呼ã³ã¾ã™ã€‚
+
+ my $res = $hs->execute_single(3, '=', [ 'foo' ], 1, 0);
+ die $hs->get_error() if $res->[0] != 0;
+ shift(@$res);
+
+最åˆã®å¼•æ•°ã¯ç´¢å¼•ã®ç•ªå·ã§ã€åŒã˜Net::HandlerSocketオブジェクトã¸
+open_indexã§ä»˜ã‘ãŸã‚‚ã®ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。第2引数ã«ã¯æ“作を指定
+ã—ã¾ã™ã€‚ç¾åœ¨ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã€ã€Œ=ã€ã€ã€Œ>=ã€ã€ã€Œ<=ã€ã€ã€Œ>ã€ã€ã€Œ<ã€
+ã®æ“作ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚第3引数ã¯é…列ã¸ã®å‚ç…§ã§ã€ã“ã‚Œã¯æŽ¢ã™ã¹ãè¡Œã®
+キー値を指定ã—ã¾ã™ã€‚é…列ã®é•·ã•ã¯ç´¢å¼•ã®ã‚­ãƒ¼ã®å€‹æ•°ã¨åŒã˜ã‹å°‘ãªã„æ•°
+ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。第4引数ã¨ç¬¬5引数ã¯ãã‚Œãžã‚Œã€å–å¾—ã™ã‚‹æœ€å¤§è¡Œ
+æ•°ã€å–å¾—å‰ã«èª­ã¿é£›ã°ã™è¡Œæ•°ã‚’指定ã—ã¾ã™ã€‚å–å¾—ã•ã‚Œã‚‹åˆ—ã¯å¯¾å¿œã™ã‚‹
+open_index呼ã³å‡ºã—ã®ç¬¬5引数ã§æŒ‡å®šã•ã‚ŒãŸã‚‚ã®ã«ãªã‚Šã¾ã™ã€‚
+
+execute_singleメソッドã¯å¸¸ã«é…列ã¸ã®å‚照を返ã—ã¾ã™ã€‚最åˆã®è¦ç´ ã¯
+エラーコードã§ã€ã“ã‚ŒãŒ0ãªã‚‰ã°æˆåŠŸã‚’表ã—ã¾ã™ã€‚残りã®è¦ç´ ã¯åˆ—ã®å€¤ã§
+ã™ã€‚ã‚‚ã—å–å¾—ã•ã‚ŒãŸãƒ‡ãƒ¼ã‚¿ãŒè¤‡æ•°è¡Œã®å ´åˆã¯ã€ãã‚ŒãŒä¸€ã¤ã®é…列ã¸é€£çµ
+ã•ã‚ŒãŸå½¢ã§æ ¼ç´ã•ã‚Œã¦ã„ã¾ã™ã€‚例ãˆã°ã€5è¡Œ3列ã®ãƒ‡ãƒ¼ã‚¿ã®å ´åˆã€æ¬¡ã®ã‚ˆ
+ã†ãªã‚³ãƒ¼ãƒ‰ã«ã‚ˆã£ã¦ãã®å†…容をå–å¾—ã§ãã¾ã™ã€‚
+
+ die $hs->get_error() if $res->[0] != 0;
+ shift(@$res);
+ for (my $row = 0; $row < 5; ++$row) {
+ for (my $col = 0; $col < 3; ++$col) {
+ my $value = $res->[$row * 5 + $col];
+ # ...
+ }
+ }
+
+-----------------------------------------------------------------
+行を更新ã¾ãŸã¯å‰Šé™¤ã™ã‚‹ã«ã¯ã€æ›´ã«å¤šãã®å¼•æ•°ã‚’指定ã—ã¦
+execute_singleメソッドを呼ã³å‡ºã—ã¾ã™ã€‚書ãè¾¼ã¿å‡¦ç†ã‚’ã™ã‚‹ã«ã¯ã€
+対象ã®Net::HandlerSocketオブジェクトã¯æ›´æ–°ç”¨handlersocketワーカ(æ—¢
+定ã§ã¯ãƒãƒ¼ãƒˆ9999)ã¸æŽ¥ç¶šã•ã‚ŒãŸã‚‚ã®ã§ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“。
+(安全ã®ãŸã‚ã€ãƒãƒ¼ãƒˆ9998ã¯å‚照処ç†ã ã‘ã‚’å—ã‘付ã‘ã€ãƒãƒ¼ãƒˆ9999ã¯æ›´æ–°
+処ç†ã‚‚å—ã‘付ã‘るよã†ã«ãªã£ã¦ã„ã¾ã™ã€‚ãƒãƒ¼ãƒˆ9999ã¯å‚照処ç†ã‚‚å—ã‘付
+ã‘ã¾ã™ãŒã€ãƒ¬ã‚³ãƒ¼ãƒ‰ãƒ­ãƒƒã‚¯ç­‰ã®å½±éŸ¿ã§é…ããªã‚Šã¾ã™ã€‚ãƒãƒ¼ãƒˆç•ªå·ã¯
+mysqldã®ã€Œhandlersocket_portã€ã¨ã€Œhandlersocket_port_wrã€ã®è¨­å®šé …
+ç›®ã§å¤‰æ›´ã§ãã¾ã™ã€‚)
+
+ my $args = { host => 'localhost', port => 9999 };
+ my $hs = new Net::HandlerSocket($args);
+
+ my $res = $hs->execute_single(3, '=', [ 'bar' ], 1, 0, 'U',
+ [ 'fubar', 'hoge' ]);
+ die $hs->get_error() if $res->[0] != 0;
+ my $num_updated_rows = $res->[1];
+
+ my $res = $hs->execute_single(3, '=', [ 'baz' ], 1, 0, 'D');
+ die $hs->get_error() if $res->[0] != 0;
+ my $num_deleted_rows = $res->[1];
+
+execute_singleã®ç¬¬6引数ã¯å¤‰æ›´å‡¦ç†ã®ç¨®é¡žã‚’指定ã—ã¾ã™ã€‚ç¾åœ¨ã®ãƒãƒ¼
+ジョンã§ã¯ã€ŒUã€ã¨ã€ŒDã€ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚「Uã€ã«ã¤ã„ã¦ã¯ã€ç¬¬7引数ã§
+æ–°ã—ã„値を指定ã—ã¾ã™ã€‚æ›´æ–°ã•ã‚Œã‚‹åˆ—ã¯ã€å¯¾å¿œã™ã‚‹open_index呼ã³å‡ºã—
+ã®ç¬¬5引数ã§æŒ‡å®šã•ã‚ŒãŸã‚‚ã®ã«ãªã‚Šã¾ã™ã€‚「Dã€ã«ã¤ã„ã¦ã¯ç¬¬7引数ã¯çœ
+ç•¥ã§ãã¾ã™ã€‚
+
+-----------------------------------------------------------------
+execute_singleメソッドã¯åˆ—ã®æŒ¿å…¥ã«ã‚‚使用ã§ãã¾ã™ã€‚
+
+ my $res = $hs->execute_single(3, '+', [ 'foo', 'bar', 'baz' ]);
+ die $hs->get_error() if $res->[0] != 0;
+ my $num_inserted_rows = $res->[1];
+
+第3引数ã¯ã€å¯¾å¿œã™ã‚‹open_index呼ã³å‡ºã—ã®ç¬¬5引数ã®åˆ—リストã¨åŒã˜ã 
+ã‘ã®é•·ã•ã®é…列ã¸ã®å‚ç…§ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。open_index呼ã³å‡ºã—ã®
+第5引数ã«æŒ‡å®šã•ã‚Œã¦ã„ãªã„列ã«ã¤ã„ã¦ã¯ã€ãã®åˆ—ã®æ—¢å®šå€¤ãŒã‚»ãƒƒãƒˆã•ã‚Œ
+ã¾ã™ã€‚
+
+-----------------------------------------------------------------
+execute_multiメソッドを使ãˆã°ã€è¤‡æ•°ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’一ã¤ã®å‘¼ã³å‡ºã—ã§
+実行ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã“ã‚Œã¯ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’個別ã«å®Ÿè¡Œã™ã‚‹ã‚ˆã‚Šé«˜é€Ÿ
+ã§ã™ã€‚
+
+ my $rarr = $hs->execute_multi([
+ [ 0, '>=', [ 'foo' ], 5, 0 ],
+ [ 2, '=', [ 'bar' ], 1, 0 ],
+ [ 4, '<', [ 'baz' ], 10, 5 ],
+ ]);
+ for my $res (@$rarr) {
+ die $hs->get_error() if $res->[0] != 0;
+ shift(@$res);
+ # ...
+ }
+
+-----------------------------------------------------------------
+エラーãŒèµ·ã“ã‚‹ã¨è¿”値ã®é…列å‚ç…§ã®æœ€åˆã®è¦ç´ ãŒ0以外ã«ãªã‚Šã¾ã™ã€‚è² ã®
+æ•°ã®å ´åˆã¯I/OエラーãŒèµ·ã“ã£ãŸã“ã¨ã‚’示ã—ã€ãã®å ´åˆã¯ãã®
+Net::HandlerSocketオブジェクトã¯ç ´æ£„ã™ã‚‹ã¹ãã§ã™ã€‚æ­£ã®å€¤ã®å ´åˆã¯
+接続ã¯ç¶­æŒã•ã‚Œã¦ã„ã‚‹ãŸã‚ã€ãã®ã‚ªãƒ–ジェクトã¯ãれ以後もå†åˆ©ç”¨ã§ã
+ã¾ã™ã€‚
+
diff --git a/plugin/handler_socket/docs-ja/protocol.ja.txt b/plugin/handler_socket/docs-ja/protocol.ja.txt
new file mode 100644
index 00000000000..01c9d39f71f
--- /dev/null
+++ b/plugin/handler_socket/docs-ja/protocol.ja.txt
@@ -0,0 +1,94 @@
+
+-----------------------------------------------------------------
+handlersocketã®é€šä¿¡ãƒ—ロトコル
+
+-----------------------------------------------------------------
+構文
+
+・コマンド行ã¯æ”¹è¡Œ(LF)ã§çµ‚ã‚る。
+・コマンド行ã¯è¤‡æ•°ã®ãƒˆãƒ¼ã‚¯ãƒ³ã‹ã‚‰ãªã‚Šã€ãƒˆãƒ¼ã‚¯ãƒ³é–“ã¯TABã§åŒºåˆ‡ã‚‰ã‚Œã‚‹ã€‚
+・トークンã¯NULLトークンã‹ã€æ–‡å­—列トークンã®ã„ãšã‚Œã‹ã€‚
+・NULLトークンã¯å˜ä¸€ã®NUL文字ã§ã‚らã‚ã•ã‚Œã‚‹ã€‚
+・文字列トークンã¯ã€0ãƒã‚¤ãƒˆä»¥ä¸Šã®æ–‡å­—列ã§ã‚らã‚ã•ã‚Œã‚‹ã€‚ãŸã ã—0x10
+ 未満ã®æ–‡å­—ã«ã¤ã„ã¦ã¯0x01ã‚’å‰ç½®ã—ã€0x40を加ãˆãŸã‚³ãƒ¼ãƒ‰ã§ã‚らã‚ã•
+ れる。ãれ以外ã®æ–‡å­—ã¯ãã®æ–‡å­—自身ã®ã‚³ãƒ¼ãƒ‰ã§ã‚らã‚ã•ã‚Œã‚‹ã€‚
+
+-----------------------------------------------------------------
+リクエストã¨ãƒ¬ã‚¹ãƒãƒ³ã‚¹
+
+・接続ãŒç¢ºç«‹ã—ãŸç›´å¾Œã®çŠ¶æ…‹ã§ã¯ã€ã¾ãšã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆãŒã‚³ãƒžãƒ³ãƒ‰è¡Œã‚’é€
+ る。(リクエスト)
+・サーãƒã¯ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆãŒé€ã£ãŸãƒªã‚¯ã‚¨ã‚¹ãƒˆã¨ä¸åº¦åŒã˜æ•°ã®ã‚³ãƒžãƒ³ãƒ‰è¡Œ
+ ã‚’è¿”ã™ã€‚(レスãƒãƒ³ã‚¹)
+・リクエストã¯ãƒ‘イプライン化ã—ã¦ã‚ˆã„。ã¤ã¾ã‚Šã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã¯å‰ã«
+ é€ã£ãŸãƒªã‚¯ã‚¨ã‚¹ãƒˆã«å¯¾ã™ã‚‹è¿”事を待ãŸãšã«æ¬¡ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’é€ã£ã¦ã‚‚
+ よã„。
+
+-----------------------------------------------------------------
+リクエスト
+
+・open_index命令ã¯æ¬¡ã®ã‚ˆã†ãªæ§‹æ–‡ã‚’æŒã¤ã€‚
+ 'P' indexid dbname tablename indexname fieldlist
+ indexidã¯é–‹ã„ã¦ã„る索引ã«ä»˜ã‘られる番å·ã§ã€åŒä¸€æŽ¥ç¶šä¸Šã§å¾Œã«å®Ÿè¡Œ
+ ã™ã‚‹å‘½ä»¤ã®ã€å¯¾è±¡ç´¢å¼•ã‚’指定ã™ã‚‹ãŸã‚ã«ä½¿ã‚れる。dbnameã€tablenameã€
+ indexnameã¯ãã‚Œãžã‚Œé–‹ããŸã„DBã€ãƒ†ãƒ¼ãƒ–ルã€ç´¢å¼•ã®åå‰ã€‚索引ã®åå‰
+ ã¨ã—ã¦"PRIMARY"を指定ã™ã‚‹ã¨ãƒ—ライマリキーãŒé–‹ã‹ã‚Œã‚‹ã€‚fieldlist
+ ã¯ã‚«ãƒ³ãƒžåŒºåˆ‡ã‚Šã®åˆ—åã®ãƒªã‚¹ãƒˆã€‚
+・find命令ã¯æ¬¡ã®ã‚ˆã†ãªæ§‹æ–‡ã‚’æŒã¤ã€‚
+ indexid op nflds v1 ... vn limit offset
+ indexidã¯å®Ÿè¡Œå¯¾è±¡ã®ç´¢å¼•ã‚’指定ã™ã‚‹ã€‚opã¯ç´¢å¼•æ¤œç´¢ã®æ¼”ç®—å­(後述)。
+ v1ã‹ã‚‰vnã¯å¯å¤‰é•·ã§ã€ãã®å€‹æ•°ã¯nflds。nfldsã¯indexidã§æŒ‡å®šã•ã‚ŒãŸ
+ open_index命令ã®indexnameã®ç´¢å¼•ã®fieldlistã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰æ•°ã«ç­‰ã—
+ ã„ã‹å°ã•ããªãã¦ã¯ãªã‚‰ãªã„。m2ã‹ã‚‰mkã¯å¯å¤‰é•·ã§ã€ãã®å€‹æ•°ã¯
+ indexidã§æŒ‡å®šã•ã‚ŒãŸopen_index命令ãŒç™ºè¡Œã•ã‚ŒãŸéš›ã®fieldlistã«ä¸€
+ 致ã—ãªã‘ã‚Œã°ãªã‚‰ãªã„。コマンド行ã®limit以é™ã¯çœç•¥ã§ãる。limit
+ ã¨offsetã¯ã€æ¤œç´¢æ¡ä»¶ã«åˆè‡´ã™ã‚‹åˆ—ã®ã†ã¡ãƒ¬ã‚¹ãƒãƒ³ã‚¹ã«è¿”ã™åˆ—æ•°ã®ä¸Š
+ é™ã¨ã€ã‚¹ã‚­ãƒƒãƒ—ã™ã‚‹åˆ—数。limitã¨offsetã‚’çœç•¥ã—ãŸå ´åˆã¯ãã‚Œãžã‚Œ1
+ ã¨0ãŒæŒ‡å®šã•ã‚ŒãŸã¨ãã¨åŒã˜å‹•ä½œã‚’ã™ã‚‹ã€‚find命令ã¯ãƒ¬ã‚¹ãƒãƒ³ã‚¹ã¨ã—ã¦ã€
+ æ¡ä»¶ã«åˆè‡´ã—ãŸåˆ—ã®ãƒªã‚¹ãƒˆã‚’è¿”ã™ã€‚opã¨ã—ã¦æŒ‡å®šã§ãる演算å­ã¯æ¬¡ã®
+ ã¨ãŠã‚Šã€‚
+ '=' - v1 ... vnã¨ä¸€è‡´ã™ã‚‹ã‚‚ã®ã‚’å–å¾—
+ '>' - v1 ... vnより大ãã„ã‚‚ã®ã‚’昇順ã«å–å¾—
+ '>=' - v1 ... vnã«ä¸€è‡´ã™ã‚‹ã‹å¤§ãã„ã‚‚ã®ã‚’昇順ã«å–å¾—
+ '<' - v1 ... vnよりå°ã•ã„ã‚‚ã®ã‚’é™é †ã«å–å¾—
+ '<=' - v1 ... vnã«ä¸€è‡´ã™ã‚‹ã‹ç­‰ã—ã„ã‚‚ã®ã‚’é™é †ã«å–å¾—
+ nfldsãŒ1より大ãã„(v1 ... vnãŒ2個以上)ã¨ãã¯è¾žæ›¸å¼é †åºã§æ¯”較ã•
+ れる。
+・find_modify命令ã¯æ¬¡ã®ã‚ˆã†ãªæ§‹æ–‡ã‚’æŒã¤ã€‚
+ indexid op nflds v1 ... vn limit offset modop m1 ... mk
+ modopよりå‰ã®éƒ¨åˆ†ã¯find命令ã¨åŒç­‰ã§ã€ã“ã‚Œã«ã‚ˆã£ã¦æ“作対象ã®è¡Œã‚’
+ 指定ã™ã‚‹ã€‚ãã®æ“作対象ã®è¡Œã«å¯¾ã—modopã§æŒ‡å®šã•ã‚ŒãŸå¤‰æ›´å‡¦ç†ã‚’実行
+ ã™ã‚‹ã€‚m1 ... mkã¯å¯å¤‰é•·ã§ã€çœç•¥ã§ãる。modopã¯æ¬¡ã„ãšã‚Œã‹ã€‚
+ 'U' - indexidã§æŒ‡å®šã•ã‚ŒãŸopen_index命令ã®fieldlist列
+ ã®å†…容をã€m1 ... mkã®å€¤ã§æ›´æ–°ã™ã‚‹ã€‚
+ 'D' - 対象ã®è¡Œã‚’削除ã™ã‚‹ã€‚m1 ... mkã®å€¤ã¯ç„¡è¦–ã•ã‚Œã‚‹ã€‚
+・insert命令ã¯ã®ã‚ˆã†ãªæ§‹æ–‡ã‚’æŒã¤ã€‚
+ indexid '+' nflds v1 ... vn
+ indexidã§æŒ‡å®šã•ã‚ŒãŸãƒ†ãƒ¼ãƒ–ルã«ã€åˆ—を挿入ã™ã‚‹ã€‚v1 ... vnã¯å¯å¤‰é•·
+ ã§ã€ãã®å€‹æ•°ã¯nflds。nfldsã¯indexidã§æŒ‡å®šã•ã‚ŒãŸopen_index命令ã®
+ indexnameã®ç´¢å¼•ã®fieldlistã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰æ•°ã«ç­‰ã—ã„ã‹å°ã•ããªãã¦
+ ã¯ãªã‚‰ãªã„。
+
+-----------------------------------------------------------------
+レスãƒãƒ³ã‚¹
+
+・open_index命令ãŒæˆåŠŸã—ãŸã¨ãã€ãƒ¬ã‚¹ãƒãƒ³ã‚¹ã¯æ¬¡ã®æ§‹æ–‡ã‚’æŒã¤ã€‚
+ '0' '1'
+・find命令ãŒæˆåŠŸã—ãŸã¨ãã€ãƒ¬ã‚¹ãƒãƒ³ã‚¹ã¯æ¬¡ã®æ§‹æ–‡ã‚’æŒã¤ã€‚
+ '0' nflds v1 ... vn
+ nfldsã¯çµæžœã‚»ãƒƒãƒˆã®åˆ—ã®æ•°ã‚’ã‚らã‚ã™ã€‚v1 ... vnã¯å¯å¤‰é•·ã§ã€ãã®
+ é•·ã•ã¯nfldsã®æ•´æ•°å€ã€‚v1 ... vnã¯ç©ºã®ã“ã¨ã‚‚ã‚ã‚Šã€ãã‚Œã¯æ¡ä»¶ã«åˆ
+ 致ã™ã‚‹ãƒ¬ã‚³ãƒ¼ãƒ‰ãŒå­˜åœ¨ã—ãªã‹ã£ãŸã“ã¨ã‚’ã‚らã‚ã™ã€‚çµæžœã‚»ãƒƒãƒˆãŒè¤‡æ•°
+ è¡Œã«ãªã£ãŸã¨ãã¯v1 ... vnã®é•·ã•ãŒnfldsã®2å€ä»¥ä¸Šã¨ãªã‚Šã€æœ€åˆã®
+ è¡Œã‹ã‚‰é †ã«v1 ... vnã«ã‚»ãƒƒãƒˆã•ã‚Œã‚‹ã€‚
+・modify命令ãŒæˆåŠŸã—ãŸã¨ãã€ãƒ¬ã‚¹ãƒãƒ³ã‚¹ã¯æ¬¡ã®æ§‹æ–‡ã‚’æŒã¤ã€‚
+ '0' '1' nummod
+ nummodã¯å¤‰æ›´ãŒæ–½ã•ã‚ŒãŸè¡Œæ•°ã€‚nummodãŒ0ã®ã¨ãã¯å¤‰æ›´ã•ã‚ŒãŸè¡ŒãŒç„¡
+ ã‹ã£ãŸã“ã¨ã‚’ã‚らã‚ã™ã€‚
+・insert命令ãŒæˆåŠŸã—ãŸã¨ãã€ãƒ¬ã‚¹ãƒãƒ³ã‚¹ã¯æ¬¡ã®æ§‹æ–‡ã‚’æŒã¤ã€‚
+ '0' '1'
+・命令ãŒå¤±æ•—ã—ãŸã¨ãã€ãƒ¬ã‚¹ãƒãƒ³ã‚¹ã¯å‘½ä»¤ã«é–¢ã‚らãšæ¬¡ã®æ§‹æ–‡ã‚’æŒã¤ã€‚
+ err '1' message
+ errã¯0以外ã®æ•°å€¤ã§ã€ã‚¨ãƒ©ãƒ¼ã‚³ãƒ¼ãƒ‰ã‚’ã‚らã‚ã™ã€‚messageã¯äººé–“å¯èª­ãª
+ エラーメッセージ。ãŸã ã—messageãŒç„¡ã„ã“ã¨ã‚‚ã‚る。
+
diff --git a/plugin/handler_socket/handlersocket/COPYRIGHT.txt b/plugin/handler_socket/handlersocket/COPYRIGHT.txt
new file mode 100644
index 00000000000..41dda1279e2
--- /dev/null
+++ b/plugin/handler_socket/handlersocket/COPYRIGHT.txt
@@ -0,0 +1,27 @@
+
+ Copyright (c) 2010 DeNA Co.,Ltd.
+ 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 above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of DeNA Co.,Ltd. nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY DeNA Co.,Ltd. "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 DeNA Co.,Ltd. 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.
+
diff --git a/plugin/handler_socket/handlersocket/Makefile.am b/plugin/handler_socket/handlersocket/Makefile.am
new file mode 100644
index 00000000000..7e47209bcf4
--- /dev/null
+++ b/plugin/handler_socket/handlersocket/Makefile.am
@@ -0,0 +1,8 @@
+pkgplugindir = $(PLUGIN_DIR)
+CXXFLAGS += -fimplicit-templates
+noinst_HEADERS = database.hpp hstcpsvr.hpp hstcpsvr_worker.hpp mysql_incl.hpp
+pkgplugin_LTLIBRARIES = handlersocket.la
+handlersocket_la_LDFLAGS = -module ../libhsclient/libhsclient.la -L$(top_builddir)/libservices -lmysqlservices
+handlersocket_la_CXXFLAGS = $(MYSQL_INC) $(MYSQL_CFLAGS) $(AM_CXXFLAGS) -I$(srcdir)/../libhsclient
+handlersocket_la_SOURCES = database.cpp handlersocket.cpp \
+ hstcpsvr_worker.cpp hstcpsvr.cpp
diff --git a/plugin/handler_socket/handlersocket/Makefile.plain.template b/plugin/handler_socket/handlersocket/Makefile.plain.template
new file mode 100644
index 00000000000..4d5f8c102ff
--- /dev/null
+++ b/plugin/handler_socket/handlersocket/Makefile.plain.template
@@ -0,0 +1,31 @@
+
+MYSQL_INC = HANDLERSOCKET_MYSQL_INC
+MYSQL_LIB = HANDLERSOCKET_MYSQL_LIB
+
+CXX = g++ -Wall -g -fno-rtti -fno-exceptions -fPIC -DPIC
+LIBS = $(MYSQL_LIB) -lhsclient -lpthread -lz
+CXXFLAGS = -I/usr/include/handlersocket $(MYSQL_INC)
+LDFLAGS =
+
+CXXFLAGS += -O3 -DNDEBUG
+
+HANDLERSOCKET_OBJS = database.o hstcpsvr.o hstcpsvr_worker.o
+
+all: handlersocket.so
+
+handlersocket.so: $(HANDLERSOCKET_OBJS) handlersocket.cpp
+ $(CXX) $(CXXFLAGS) -fno-strict-aliasing -shared $^ -o $@ $(LDFLAGS) \
+ -Wl,-soname -Wl,$@ $(LIBS)
+clean:
+ rm -f *.a *.so *.o
+
+LIBDIR = $(shell \
+ if [ -e /usr/lib64/mysql ]; then echo /usr/lib64; else echo /usr/lib; fi)
+
+install: handlersocket.so
+ sudo sh -c 'ulimit -c unlimited ; /etc/init.d/mysql stop ; \
+ cp handlersocket.so handlersocket.so.cpy && \
+ mv handlersocket.so.cpy \
+ $(LIBDIR)/mysql/plugin/handlersocket.so && \
+ /etc/init.d/mysql start'
+
diff --git a/plugin/handler_socket/handlersocket/database.cpp b/plugin/handler_socket/handlersocket/database.cpp
new file mode 100644
index 00000000000..311eec55fa8
--- /dev/null
+++ b/plugin/handler_socket/handlersocket/database.cpp
@@ -0,0 +1,1187 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "database.hpp"
+#include "string_util.hpp"
+#include "escape.hpp"
+#include "mysql_incl.hpp"
+
+#define DBG_KEY(x)
+#define DBG_SHUT(x)
+#define DBG_LOCK(x)
+#define DBG_THR(x)
+#define DBG_CMP(x)
+#define DBG_FLD(x)
+#define DBG_FILTER(x)
+#define DBG_REFCNT(x)
+#define DBG_KEYLEN(x)
+#define DBG_DELETED
+
+/* status variables */
+unsigned long long int open_tables_count;
+unsigned long long int close_tables_count;
+unsigned long long int lock_tables_count;
+unsigned long long int unlock_tables_count;
+unsigned long long int index_exec_count;
+
+namespace dena {
+
+prep_stmt::prep_stmt()
+ : dbctx(0), table_id(static_cast<size_t>(-1)),
+ idxnum(static_cast<size_t>(-1))
+{
+}
+prep_stmt::prep_stmt(dbcontext_i *c, size_t tbl, size_t idx,
+ const fields_type& rf, const fields_type& ff)
+ : dbctx(c), table_id(tbl), idxnum(idx), ret_fields(rf), filter_fields(ff)
+{
+ if (dbctx) {
+ dbctx->table_addref(table_id);
+ }
+}
+prep_stmt::~prep_stmt()
+{
+ if (dbctx) {
+ dbctx->table_release(table_id);
+ }
+}
+
+prep_stmt::prep_stmt(const prep_stmt& x)
+ : dbctx(x.dbctx), table_id(x.table_id), idxnum(x.idxnum),
+ ret_fields(x.ret_fields), filter_fields(x.filter_fields)
+{
+ if (dbctx) {
+ dbctx->table_addref(table_id);
+ }
+}
+
+prep_stmt&
+prep_stmt::operator =(const prep_stmt& x)
+{
+ if (this != &x) {
+ if (dbctx) {
+ dbctx->table_release(table_id);
+ }
+ dbctx = x.dbctx;
+ table_id = x.table_id;
+ idxnum = x.idxnum;
+ ret_fields = x.ret_fields;
+ filter_fields = x.filter_fields;
+ if (dbctx) {
+ dbctx->table_addref(table_id);
+ }
+ }
+ return *this;
+}
+
+struct database : public database_i, private noncopyable {
+ database(const config& c);
+ virtual ~database();
+ virtual dbcontext_ptr create_context(bool for_write) volatile;
+ virtual void stop() volatile;
+ virtual const config& get_conf() const volatile;
+ public:
+ int child_running;
+ private:
+ config conf;
+};
+
+struct tablevec_entry {
+ TABLE *table;
+ size_t refcount;
+ bool modified;
+ tablevec_entry() : table(0), refcount(0), modified(false) { }
+};
+
+struct expr_user_lock : private noncopyable {
+ expr_user_lock(THD *thd, int timeout)
+ : lck_key("handlersocket_wr", 16, &my_charset_latin1),
+ lck_timeout(timeout),
+ lck_func_get_lock(&lck_key, &lck_timeout),
+ lck_func_release_lock(&lck_key)
+ {
+ lck_key.fix_fields(thd, 0);
+ lck_timeout.fix_fields(thd, 0);
+ lck_func_get_lock.fix_fields(thd, 0);
+ lck_func_release_lock.fix_fields(thd, 0);
+ }
+ long long get_lock() {
+ return lck_func_get_lock.val_int();
+ }
+ long long release_lock() {
+ return lck_func_release_lock.val_int();
+ }
+ private:
+ Item_string lck_key;
+ Item_int lck_timeout;
+ Item_func_get_lock lck_func_get_lock;
+ Item_func_release_lock lck_func_release_lock;
+};
+
+struct dbcontext : public dbcontext_i, private noncopyable {
+ dbcontext(volatile database *d, bool for_write);
+ virtual ~dbcontext();
+ virtual void init_thread(const void *stack_botton,
+ volatile int& shutdown_flag);
+ virtual void term_thread();
+ virtual bool check_alive();
+ virtual void lock_tables_if();
+ virtual void unlock_tables_if();
+ virtual bool get_commit_error();
+ virtual void clear_error();
+ virtual void close_tables_if();
+ virtual void table_addref(size_t tbl_id);
+ virtual void table_release(size_t tbl_id);
+ virtual void cmd_open(dbcallback_i& cb, const cmd_open_args& args);
+ virtual void cmd_exec(dbcallback_i& cb, const cmd_exec_args& args);
+ virtual void set_statistics(size_t num_conns, size_t num_active);
+ private:
+ int set_thread_message(const char *fmt, ...)
+ __attribute__((format (printf, 2, 3)));
+ bool parse_fields(TABLE *const table, const char *str,
+ prep_stmt::fields_type& flds);
+ void cmd_insert_internal(dbcallback_i& cb, const prep_stmt& pst,
+ const string_ref *fvals, size_t fvalslen);
+ void cmd_sql_internal(dbcallback_i& cb, const prep_stmt& pst,
+ const string_ref *fvals, size_t fvalslen);
+ void cmd_find_internal(dbcallback_i& cb, const prep_stmt& pst,
+ ha_rkey_function find_flag, const cmd_exec_args& args);
+ size_t calc_filter_buf_size(TABLE *table, const prep_stmt& pst,
+ const record_filter *filters);
+ bool fill_filter_buf(TABLE *table, const prep_stmt& pst,
+ const record_filter *filters, uchar *filter_buf, size_t len);
+ int check_filter(dbcallback_i& cb, TABLE *table, const prep_stmt& pst,
+ const record_filter *filters, const uchar *filter_buf);
+ void resp_record(dbcallback_i& cb, TABLE *const table, const prep_stmt& pst);
+ void dump_record(dbcallback_i& cb, TABLE *const table, const prep_stmt& pst);
+ int modify_record(dbcallback_i& cb, TABLE *const table,
+ const prep_stmt& pst, const cmd_exec_args& args, char mod_op,
+ size_t& modified_count);
+ private:
+ typedef std::vector<tablevec_entry> table_vec_type;
+ typedef std::pair<std::string, std::string> table_name_type;
+ typedef std::map<table_name_type, size_t> table_map_type;
+ private:
+ volatile database *const dbref;
+ bool for_write_flag;
+ THD *thd;
+ MYSQL_LOCK *lock;
+ bool lock_failed;
+ std::auto_ptr<expr_user_lock> user_lock;
+ int user_level_lock_timeout;
+ bool user_level_lock_locked;
+ bool commit_error;
+ std::vector<char> info_message_buf;
+ table_vec_type table_vec;
+ table_map_type table_map;
+};
+
+database::database(const config& c)
+ : child_running(1), conf(c)
+{
+}
+
+database::~database()
+{
+}
+
+dbcontext_ptr
+database::create_context(bool for_write) volatile
+{
+ return dbcontext_ptr(new dbcontext(this, for_write));
+}
+
+void
+database::stop() volatile
+{
+ child_running = false;
+}
+
+const config&
+database::get_conf() const volatile
+{
+ return const_cast<const config&>(conf);
+}
+
+database_ptr
+database_i::create(const config& conf)
+{
+ return database_ptr(new database(conf));
+}
+
+dbcontext::dbcontext(volatile database *d, bool for_write)
+ : dbref(d), for_write_flag(for_write), thd(0), lock(0), lock_failed(false),
+ user_level_lock_timeout(0), user_level_lock_locked(false),
+ commit_error(false)
+{
+ info_message_buf.resize(8192);
+ user_level_lock_timeout = d->get_conf().get_int("wrlock_timeout", 12);
+}
+
+dbcontext::~dbcontext()
+{
+}
+
+namespace {
+
+int
+wait_server_to_start(THD *thd, volatile int& shutdown_flag)
+{
+ int r = 0;
+ DBG_SHUT(fprintf(stderr, "HNDSOCK wsts\n"));
+ pthread_mutex_lock(&LOCK_server_started);
+ while (!mysqld_server_started) {
+ timespec abstime;
+ set_timespec(abstime, 1);
+ pthread_cond_timedwait(&COND_server_started, &LOCK_server_started,
+ &abstime);
+ pthread_mutex_unlock(&LOCK_server_started);
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ killed_state st = thd->killed;
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
+ DBG_SHUT(fprintf(stderr, "HNDSOCK wsts kst %d\n", (int)st));
+ pthread_mutex_lock(&LOCK_server_started);
+ if (st != NOT_KILLED) {
+ DBG_SHUT(fprintf(stderr, "HNDSOCK wsts kst %d break\n", (int)st));
+ r = -1;
+ break;
+ }
+ if (shutdown_flag) {
+ DBG_SHUT(fprintf(stderr, "HNDSOCK wsts kst shut break\n"));
+ r = -1;
+ break;
+ }
+ }
+ pthread_mutex_unlock(&LOCK_server_started);
+ DBG_SHUT(fprintf(stderr, "HNDSOCK wsts done\n"));
+ return r;
+}
+
+}; // namespace
+
+#define DENA_THR_OFFSETOF(fld) ((char *)(&thd->fld) - (char *)thd)
+
+void
+dbcontext::init_thread(const void *stack_bottom, volatile int& shutdown_flag)
+{
+ DBG_THR(fprintf(stderr, "HNDSOCK init thread\n"));
+ {
+ my_thread_init();
+ thd = new THD;
+ thd->thread_stack = (char *)stack_bottom;
+ DBG_THR(fprintf(stderr,
+ "thread_stack = %p sizeof(THD)=%zu sizeof(mtx)=%zu "
+ "O: %zu %zu %zu %zu %zu %zu %zu\n",
+ thd->thread_stack, sizeof(THD), sizeof(LOCK_thread_count),
+ DENA_THR_OFFSETOF(mdl_context),
+ DENA_THR_OFFSETOF(net),
+ DENA_THR_OFFSETOF(LOCK_thd_data),
+ DENA_THR_OFFSETOF(mysys_var),
+ DENA_THR_OFFSETOF(stmt_arena),
+ DENA_THR_OFFSETOF(limit_found_rows),
+ DENA_THR_OFFSETOF(locked_tables_list)));
+ thd->store_globals();
+ thd->system_thread = static_cast<enum_thread_type>(1<<30UL);
+ memset(&thd->net, 0, sizeof(thd->net));
+ if (for_write_flag) {
+ #if MYSQL_VERSION_ID >= 50505
+ thd->variables.option_bits |= OPTION_BIN_LOG;
+ #else
+ thd->options |= OPTION_BIN_LOG;
+ #endif
+ safeFree(thd->db);
+ thd->db = 0;
+ thd->db = my_strdup("handlersocket", MYF(0));
+ }
+ my_pthread_setspecific_ptr(THR_THD, thd);
+ DBG_THR(fprintf(stderr, "HNDSOCK x0 %p\n", thd));
+ }
+ {
+ pthread_mutex_lock(&LOCK_thread_count);
+ thd->thread_id = thread_id++;
+ threads.append(thd);
+ ++thread_count;
+ pthread_mutex_unlock(&LOCK_thread_count);
+ }
+
+ DBG_THR(fprintf(stderr, "HNDSOCK init thread wsts\n"));
+ wait_server_to_start(thd, shutdown_flag);
+ DBG_THR(fprintf(stderr, "HNDSOCK init thread done\n"));
+
+ thd_proc_info(thd, &info_message_buf[0]);
+ set_thread_message("hs:listening");
+ DBG_THR(fprintf(stderr, "HNDSOCK x1 %p\n", thd));
+
+ lex_start(thd);
+
+ user_lock.reset(new expr_user_lock(thd, user_level_lock_timeout));
+}
+
+int
+dbcontext::set_thread_message(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ const int n = vsnprintf(&info_message_buf[0], info_message_buf.size(),
+ fmt, ap);
+ va_end(ap);
+ return n;
+}
+
+void
+dbcontext::term_thread()
+{
+ DBG_THR(fprintf(stderr, "HNDSOCK thread end %p\n", thd));
+ unlock_tables_if();
+ my_pthread_setspecific_ptr(THR_THD, 0);
+ {
+ pthread_mutex_lock(&LOCK_thread_count);
+ delete thd;
+ thd = 0;
+ --thread_count;
+ pthread_mutex_unlock(&LOCK_thread_count);
+ my_thread_end();
+ }
+}
+
+bool
+dbcontext::check_alive()
+{
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ killed_state st = thd->killed;
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
+ DBG_SHUT(fprintf(stderr, "chk HNDSOCK kst %p %p %d %zu\n", thd, &thd->killed,
+ (int)st, sizeof(*thd)));
+ if (st != NOT_KILLED) {
+ DBG_SHUT(fprintf(stderr, "chk HNDSOCK kst %d break\n", (int)st));
+ return false;
+ }
+ return true;
+}
+
+void
+dbcontext::lock_tables_if()
+{
+ if (lock_failed) {
+ return;
+ }
+ if (for_write_flag && !user_level_lock_locked) {
+ if (user_lock->get_lock()) {
+ user_level_lock_locked = true;
+ } else {
+ lock_failed = true;
+ return;
+ }
+ }
+ if (lock == 0) {
+ const size_t num_max = table_vec.size();
+ TABLE **const tables = DENA_ALLOCA_ALLOCATE(TABLE *, num_max + 1);
+ size_t num_open = 0;
+ for (size_t i = 0; i < num_max; ++i) {
+ if (table_vec[i].refcount > 0) {
+ tables[num_open++] = table_vec[i].table;
+ }
+ table_vec[i].modified = false;
+ }
+ #if MYSQL_VERSION_ID >= 50505
+ lock = thd->lock = mysql_lock_tables(thd, &tables[0], num_open, 0);
+ #else
+ bool need_reopen= false;
+ lock = thd->lock = mysql_lock_tables(thd, &tables[0], num_open,
+ MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN, &need_reopen);
+ #endif
+ statistic_increment(lock_tables_count, &LOCK_status);
+ thd_proc_info(thd, &info_message_buf[0]);
+ DENA_VERBOSE(100, fprintf(stderr, "HNDSOCK lock tables %p %p %zu %zu\n",
+ thd, lock, num_max, num_open));
+ if (lock == 0) {
+ lock_failed = true;
+ DENA_VERBOSE(10, fprintf(stderr, "HNDSOCK failed to lock tables %p\n",
+ thd));
+ }
+ if (for_write_flag) {
+ #if MYSQL_VERSION_ID >= 50505
+ thd->set_current_stmt_binlog_format_row();
+ #else
+ thd->current_stmt_binlog_row_based = 1;
+ #endif
+ }
+ DENA_ALLOCA_FREE(tables);
+ }
+ DBG_LOCK(fprintf(stderr, "HNDSOCK tblnum=%d\n", (int)tblnum));
+}
+
+void
+dbcontext::unlock_tables_if()
+{
+ if (lock != 0) {
+ DENA_VERBOSE(100, fprintf(stderr, "HNDSOCK unlock tables %p %p\n",
+ thd, thd->lock));
+ if (for_write_flag) {
+ for (size_t i = 0; i < table_vec.size(); ++i) {
+ if (table_vec[i].modified) {
+ query_cache_invalidate3(thd, table_vec[i].table, 1);
+ table_vec[i].table->file->ha_release_auto_increment();
+ }
+ }
+ }
+ {
+ bool suc = true;
+ #if MYSQL_VERSION_ID >= 50505
+ suc = (trans_commit_stmt(thd) == 0);
+ #else
+ suc = (ha_autocommit_or_rollback(thd, 0) == 0);
+ #endif
+ if (!suc) {
+ commit_error = true;
+ DENA_VERBOSE(10, fprintf(stderr,
+ "HNDSOCK unlock tables: commit failed\n"));
+ }
+ }
+ mysql_unlock_tables(thd, lock);
+ lock = thd->lock = 0;
+ statistic_increment(unlock_tables_count, &LOCK_status);
+ }
+ if (user_level_lock_locked) {
+ if (user_lock->release_lock()) {
+ user_level_lock_locked = false;
+ }
+ }
+}
+
+bool
+dbcontext::get_commit_error()
+{
+ return commit_error;
+}
+
+void
+dbcontext::clear_error()
+{
+ lock_failed = false;
+ commit_error = false;
+}
+
+void
+dbcontext::close_tables_if()
+{
+ unlock_tables_if();
+ DENA_VERBOSE(100, fprintf(stderr, "HNDSOCK close tables\n"));
+ close_thread_tables(thd);
+ #if MYSQL_VERSION_ID >= 50505
+ thd->mdl_context.release_transactional_locks();
+ #endif
+ if (!table_vec.empty()) {
+ statistic_increment(close_tables_count, &LOCK_status);
+ table_vec.clear();
+ table_map.clear();
+ }
+}
+
+void
+dbcontext::table_addref(size_t tbl_id)
+{
+ table_vec[tbl_id].refcount += 1;
+ DBG_REFCNT(fprintf(stderr, "%p %zu %zu addref\n", this, tbl_id,
+ table_vec[tbl_id].refcount));
+}
+
+void
+dbcontext::table_release(size_t tbl_id)
+{
+ table_vec[tbl_id].refcount -= 1;
+ DBG_REFCNT(fprintf(stderr, "%p %zu %zu release\n", this, tbl_id,
+ table_vec[tbl_id].refcount));
+}
+
+void
+dbcontext::resp_record(dbcallback_i& cb, TABLE *const table,
+ const prep_stmt& pst)
+{
+ char rwpstr_buf[64];
+ String rwpstr(rwpstr_buf, sizeof(rwpstr_buf), &my_charset_bin);
+ const prep_stmt::fields_type& rf = pst.get_ret_fields();
+ const size_t n = rf.size();
+ for (size_t i = 0; i < n; ++i) {
+ uint32_t fn = rf[i];
+ Field *const fld = table->field[fn];
+ DBG_FLD(fprintf(stderr, "fld=%p %zu\n", fld, fn));
+ if (fld->is_null()) {
+ /* null */
+ cb.dbcb_resp_entry(0, 0);
+ } else {
+ fld->val_str(&rwpstr, &rwpstr);
+ const size_t len = rwpstr.length();
+ if (len != 0) {
+ /* non-empty */
+ cb.dbcb_resp_entry(rwpstr.ptr(), rwpstr.length());
+ } else {
+ /* empty */
+ static const char empty_str[] = "";
+ cb.dbcb_resp_entry(empty_str, 0);
+ }
+ }
+ }
+}
+
+void
+dbcontext::dump_record(dbcallback_i& cb, TABLE *const table,
+ const prep_stmt& pst)
+{
+ char rwpstr_buf[64];
+ String rwpstr(rwpstr_buf, sizeof(rwpstr_buf), &my_charset_bin);
+ const prep_stmt::fields_type& rf = pst.get_ret_fields();
+ const size_t n = rf.size();
+ for (size_t i = 0; i < n; ++i) {
+ uint32_t fn = rf[i];
+ Field *const fld = table->field[fn];
+ if (fld->is_null()) {
+ /* null */
+ fprintf(stderr, "NULL");
+ } else {
+ fld->val_str(&rwpstr, &rwpstr);
+ const std::string s(rwpstr.ptr(), rwpstr.length());
+ fprintf(stderr, "[%s]", s.c_str());
+ }
+ }
+ fprintf(stderr, "\n");
+}
+
+int
+dbcontext::modify_record(dbcallback_i& cb, TABLE *const table,
+ const prep_stmt& pst, const cmd_exec_args& args, char mod_op,
+ size_t& modified_count)
+{
+ if (mod_op == 'U') {
+ /* update */
+ handler *const hnd = table->file;
+ uchar *const buf = table->record[0];
+ store_record(table, record[1]);
+ const prep_stmt::fields_type& rf = pst.get_ret_fields();
+ const size_t n = rf.size();
+ for (size_t i = 0; i < n; ++i) {
+ const string_ref& nv = args.uvals[i];
+ uint32_t fn = rf[i];
+ Field *const fld = table->field[fn];
+ if (nv.begin() == 0) {
+ fld->set_null();
+ } else {
+ fld->set_notnull();
+ fld->store(nv.begin(), nv.size(), &my_charset_bin);
+ }
+ }
+ table_vec[pst.get_table_id()].modified = true;
+ const int r = hnd->ha_update_row(table->record[1], buf);
+ if (r != 0 && r != HA_ERR_RECORD_IS_THE_SAME) {
+ return r;
+ }
+ ++modified_count; /* TODO: HA_ERR_RECORD_IS_THE_SAME? */
+ } else if (mod_op == 'D') {
+ /* delete */
+ handler *const hnd = table->file;
+ table_vec[pst.get_table_id()].modified = true;
+ const int r = hnd->ha_delete_row(table->record[0]);
+ if (r != 0) {
+ return r;
+ }
+ ++modified_count;
+ } else if (mod_op == '+' || mod_op == '-') {
+ /* increment/decrement */
+ handler *const hnd = table->file;
+ uchar *const buf = table->record[0];
+ store_record(table, record[1]);
+ const prep_stmt::fields_type& rf = pst.get_ret_fields();
+ const size_t n = rf.size();
+ size_t i = 0;
+ for (i = 0; i < n; ++i) {
+ const string_ref& nv = args.uvals[i];
+ uint32_t fn = rf[i];
+ Field *const fld = table->field[fn];
+ if (fld->is_null() || nv.begin() == 0) {
+ continue;
+ }
+ const long long pval = fld->val_int();
+ const long long llv = atoll_nocheck(nv.begin(), nv.end());
+ /* TODO: llv == 0? */
+ long long nval = 0;
+ if (mod_op == '+') {
+ /* increment */
+ nval = pval + llv;
+ } else {
+ /* decrement */
+ nval = pval - llv;
+ if ((pval < 0 && nval > 0) || (pval > 0 && nval < 0)) {
+ break; /* don't modify */
+ }
+ }
+ fld->store(nval, false);
+ }
+ if (i == n) {
+ /* modify */
+ table_vec[pst.get_table_id()].modified = true;
+ const int r = hnd->ha_update_row(table->record[1], buf);
+ if (r != 0 && r != HA_ERR_RECORD_IS_THE_SAME) {
+ return r;
+ }
+ ++modified_count;
+ }
+ }
+ return 0;
+}
+
+void
+dbcontext::cmd_insert_internal(dbcallback_i& cb, const prep_stmt& pst,
+ const string_ref *fvals, size_t fvalslen)
+{
+ if (!for_write_flag) {
+ return cb.dbcb_resp_short(2, "readonly");
+ }
+ lock_tables_if();
+ if (lock == 0) {
+ return cb.dbcb_resp_short(1, "lock_tables");
+ }
+ if (pst.get_table_id() >= table_vec.size()) {
+ return cb.dbcb_resp_short(2, "tblnum");
+ }
+ TABLE *const table = table_vec[pst.get_table_id()].table;
+ handler *const hnd = table->file;
+ uchar *const buf = table->record[0];
+ empty_record(table);
+ memset(buf, 0, table->s->null_bytes); /* clear null flags */
+ const prep_stmt::fields_type& rf = pst.get_ret_fields();
+ const size_t n = rf.size();
+ for (size_t i = 0; i < n; ++i) {
+ uint32_t fn = rf[i];
+ Field *const fld = table->field[fn];
+ if (fvals[i].begin() == 0) {
+ fld->set_null();
+ } else {
+ fld->store(fvals[i].begin(), fvals[i].size(), &my_charset_bin);
+ }
+ }
+ table->next_number_field = table->found_next_number_field;
+ /* FIXME: test */
+ const int r = hnd->ha_write_row(buf);
+ const ulonglong insert_id = table->file->insert_id_for_cur_row;
+ table->next_number_field = 0;
+ table_vec[pst.get_table_id()].modified = true;
+ if (r == 0 && table->found_next_number_field != 0) {
+ return cb.dbcb_resp_short_num64(0, insert_id);
+ }
+ if (r != 0) {
+ return cb.dbcb_resp_short_num(1, r);
+ }
+ return cb.dbcb_resp_short(0, "");
+}
+
+void
+dbcontext::cmd_sql_internal(dbcallback_i& cb, const prep_stmt& pst,
+ const string_ref *fvals, size_t fvalslen)
+{
+ if (fvalslen < 1) {
+ return cb.dbcb_resp_short(2, "syntax");
+ }
+ return cb.dbcb_resp_short(2, "notimpl");
+}
+
+static size_t
+prepare_keybuf(const cmd_exec_args& args, uchar *key_buf, TABLE *table,
+ KEY& kinfo, size_t invalues_index)
+{
+ size_t kplen_sum = 0;
+ DBG_KEY(fprintf(stderr, "SLOW\n"));
+ for (size_t i = 0; i < args.kvalslen; ++i) {
+ const KEY_PART_INFO & kpt = kinfo.key_part[i];
+ string_ref kval = args.kvals[i];
+ if (args.invalues_keypart >= 0 &&
+ static_cast<size_t>(args.invalues_keypart) == i) {
+ kval = args.invalues[invalues_index];
+ }
+ if (kval.begin() == 0) {
+ kpt.field->set_null();
+ } else {
+ kpt.field->set_notnull();
+ }
+ kpt.field->store(kval.begin(), kval.size(), &my_charset_bin);
+ kplen_sum += kpt.store_length;
+ DBG_KEYLEN(fprintf(stderr, "l=%u sl=%zu\n", kpt.length,
+ kpt.store_length));
+ }
+ key_copy(key_buf, table->record[0], &kinfo, kplen_sum);
+ DBG_KEYLEN(fprintf(stderr, "sum=%zu flen=%u\n", kplen_sum,
+ kinfo.key_length));
+ return kplen_sum;
+}
+
+void
+dbcontext::cmd_find_internal(dbcallback_i& cb, const prep_stmt& pst,
+ ha_rkey_function find_flag, const cmd_exec_args& args)
+{
+ const bool debug_out = (verbose_level >= 100);
+ bool need_resp_record = true;
+ char mod_op = 0;
+ const string_ref& mod_op_str = args.mod_op;
+ if (mod_op_str.size() != 0) {
+ if (!for_write_flag) {
+ return cb.dbcb_resp_short(2, "readonly");
+ }
+ mod_op = mod_op_str.begin()[0];
+ need_resp_record = mod_op_str.size() > 1 && mod_op_str.begin()[1] == '?';
+ switch (mod_op) {
+ case 'U': /* update */
+ case 'D': /* delete */
+ case '+': /* increment */
+ case '-': /* decrement */
+ break;
+ default:
+ if (debug_out) {
+ fprintf(stderr, "unknown modop: %c\n", mod_op);
+ }
+ return cb.dbcb_resp_short(2, "modop");
+ }
+ }
+ lock_tables_if();
+ if (lock == 0) {
+ return cb.dbcb_resp_short(1, "lock_tables");
+ }
+ if (pst.get_table_id() >= table_vec.size()) {
+ return cb.dbcb_resp_short(2, "tblnum");
+ }
+ TABLE *const table = table_vec[pst.get_table_id()].table;
+ /* keys */
+ if (pst.get_idxnum() >= table->s->keys) {
+ return cb.dbcb_resp_short(2, "idxnum");
+ }
+ KEY& kinfo = table->key_info[pst.get_idxnum()];
+ if (args.kvalslen > kinfo.key_parts) {
+ return cb.dbcb_resp_short(2, "kpnum");
+ }
+ uchar *const key_buf = DENA_ALLOCA_ALLOCATE(uchar, kinfo.key_length);
+ size_t invalues_idx = 0;
+ size_t kplen_sum = prepare_keybuf(args, key_buf, table, kinfo, invalues_idx);
+ /* filters */
+ uchar *filter_buf = 0;
+ if (args.filters != 0) {
+ const size_t filter_buf_len = calc_filter_buf_size(table, pst,
+ args.filters);
+ filter_buf = DENA_ALLOCA_ALLOCATE(uchar, filter_buf_len);
+ if (!fill_filter_buf(table, pst, args.filters, filter_buf,
+ filter_buf_len)) {
+ return cb.dbcb_resp_short(2, "filterblob");
+ }
+ }
+ /* handler */
+ table->read_set = &table->s->all_set;
+ handler *const hnd = table->file;
+ if (!for_write_flag) {
+ hnd->init_table_handle_for_HANDLER();
+ }
+ hnd->ha_index_or_rnd_end();
+ hnd->ha_index_init(pst.get_idxnum(), 1);
+ if (need_resp_record) {
+ cb.dbcb_resp_begin(pst.get_ret_fields().size());
+ }
+ const uint32_t limit = args.limit ? args.limit : 1;
+ uint32_t skip = args.skip;
+ size_t modified_count = 0;
+ int r = 0;
+ bool is_first = true;
+ for (uint32_t cnt = 0; cnt < limit + skip;) {
+ if (is_first) {
+ is_first = false;
+ const key_part_map kpm = (1U << args.kvalslen) - 1;
+ r = hnd->ha_index_read_map(table->record[0], key_buf, kpm, find_flag);
+ } else if (args.invalues_keypart >= 0) {
+ if (++invalues_idx >= args.invalueslen) {
+ break;
+ }
+ kplen_sum = prepare_keybuf(args, key_buf, table, kinfo, invalues_idx);
+ const key_part_map kpm = (1U << args.kvalslen) - 1;
+ r = hnd->ha_index_read_map(table->record[0], key_buf, kpm, find_flag);
+ } else {
+ switch (find_flag) {
+ case HA_READ_BEFORE_KEY:
+ case HA_READ_KEY_OR_PREV:
+ r = hnd->ha_index_prev(table->record[0]);
+ break;
+ case HA_READ_AFTER_KEY:
+ case HA_READ_KEY_OR_NEXT:
+ r = hnd->ha_index_next(table->record[0]);
+ break;
+ case HA_READ_KEY_EXACT:
+ r = hnd->ha_index_next_same(table->record[0], key_buf, kplen_sum);
+ break;
+ default:
+ r = HA_ERR_END_OF_FILE; /* to finish the loop */
+ break;
+ }
+ }
+ if (debug_out) {
+ fprintf(stderr, "r=%d\n", r);
+ if (r == 0 || r == HA_ERR_RECORD_DELETED) {
+ dump_record(cb, table, pst);
+ }
+ }
+ int filter_res = 0;
+ if (r != 0) {
+ /* no-count */
+ } else if (args.filters != 0 && (filter_res = check_filter(cb, table,
+ pst, args.filters, filter_buf)) != 0) {
+ if (filter_res < 0) {
+ break;
+ }
+ } else if (skip > 0) {
+ --skip;
+ } else {
+ /* hit */
+ if (need_resp_record) {
+ resp_record(cb, table, pst);
+ }
+ if (mod_op != 0) {
+ r = modify_record(cb, table, pst, args, mod_op, modified_count);
+ }
+ ++cnt;
+ }
+ if (args.invalues_keypart >= 0 && r == HA_ERR_KEY_NOT_FOUND) {
+ continue;
+ }
+ if (r != 0 && r != HA_ERR_RECORD_DELETED) {
+ break;
+ }
+ }
+ hnd->ha_index_or_rnd_end();
+ if (r != 0 && r != HA_ERR_RECORD_DELETED && r != HA_ERR_KEY_NOT_FOUND &&
+ r != HA_ERR_END_OF_FILE) {
+ /* failed */
+ if (need_resp_record) {
+ /* revert dbcb_resp_begin() and dbcb_resp_entry() */
+ cb.dbcb_resp_cancel();
+ }
+ cb.dbcb_resp_short_num(1, r);
+ } else {
+ /* succeeded */
+ if (need_resp_record) {
+ cb.dbcb_resp_end();
+ } else {
+ cb.dbcb_resp_short_num(0, modified_count);
+ }
+ }
+ DENA_ALLOCA_FREE(filter_buf);
+ DENA_ALLOCA_FREE(key_buf);
+}
+
+size_t
+dbcontext::calc_filter_buf_size(TABLE *table, const prep_stmt& pst,
+ const record_filter *filters)
+{
+ size_t filter_buf_len = 0;
+ for (const record_filter *f = filters; f->op.begin() != 0; ++f) {
+ if (f->val.begin() == 0) {
+ continue;
+ }
+ const uint32_t fn = pst.get_filter_fields()[f->ff_offset];
+ filter_buf_len += table->field[fn]->pack_length();
+ }
+ ++filter_buf_len;
+ /* Field_medium::cmp() calls uint3korr(), which may read 4 bytes.
+ Allocate 1 more byte for safety. */
+ return filter_buf_len;
+}
+
+bool
+dbcontext::fill_filter_buf(TABLE *table, const prep_stmt& pst,
+ const record_filter *filters, uchar *filter_buf, size_t len)
+{
+ memset(filter_buf, 0, len);
+ size_t pos = 0;
+ for (const record_filter *f = filters; f->op.begin() != 0; ++f) {
+ if (f->val.begin() == 0) {
+ continue;
+ }
+ const uint32_t fn = pst.get_filter_fields()[f->ff_offset];
+ Field *const fld = table->field[fn];
+ if ((fld->flags & BLOB_FLAG) != 0) {
+ return false;
+ }
+ fld->store(f->val.begin(), f->val.size(), &my_charset_bin);
+ const size_t packlen = fld->pack_length();
+ memcpy(filter_buf + pos, fld->ptr, packlen);
+ pos += packlen;
+ }
+ return true;
+}
+
+int
+dbcontext::check_filter(dbcallback_i& cb, TABLE *table, const prep_stmt& pst,
+ const record_filter *filters, const uchar *filter_buf)
+{
+ DBG_FILTER(fprintf(stderr, "check_filter\n"));
+ size_t pos = 0;
+ for (const record_filter *f = filters; f->op.begin() != 0; ++f) {
+ const string_ref& op = f->op;
+ const string_ref& val = f->val;
+ const uint32_t fn = pst.get_filter_fields()[f->ff_offset];
+ Field *const fld = table->field[fn];
+ const size_t packlen = fld->pack_length();
+ const uchar *const bval = filter_buf + pos;
+ int cv = 0;
+ if (fld->is_null()) {
+ cv = (val.begin() == 0) ? 0 : -1;
+ } else {
+ cv = (val.begin() == 0) ? 1 : fld->cmp(bval);
+ }
+ DBG_FILTER(fprintf(stderr, "check_filter cv=%d\n", cv));
+ bool cond = true;
+ if (op.size() == 1) {
+ switch (op.begin()[0]) {
+ case '>':
+ DBG_FILTER(fprintf(stderr, "check_filter op: >\n"));
+ cond = (cv > 0);
+ break;
+ case '<':
+ DBG_FILTER(fprintf(stderr, "check_filter op: <\n"));
+ cond = (cv < 0);
+ break;
+ case '=':
+ DBG_FILTER(fprintf(stderr, "check_filter op: =\n"));
+ cond = (cv == 0);
+ break;
+ default:
+ DBG_FILTER(fprintf(stderr, "check_filter op: unknown\n"));
+ cond = false; /* FIXME: error */
+ break;
+ }
+ } else if (op.size() == 2 && op.begin()[1] == '=') {
+ switch (op.begin()[0]) {
+ case '>':
+ DBG_FILTER(fprintf(stderr, "check_filter op: >=\n"));
+ cond = (cv >= 0);
+ break;
+ case '<':
+ DBG_FILTER(fprintf(stderr, "check_filter op: <=\n"));
+ cond = (cv <= 0);
+ break;
+ case '!':
+ DBG_FILTER(fprintf(stderr, "check_filter op: !=\n"));
+ cond = (cv != 0);
+ break;
+ default:
+ DBG_FILTER(fprintf(stderr, "check_filter op: unknown\n"));
+ cond = false; /* FIXME: error */
+ break;
+ }
+ }
+ DBG_FILTER(fprintf(stderr, "check_filter cond: %d\n", (int)cond));
+ if (!cond) {
+ return (f->filter_type == record_filter_type_skip) ? 1 : -1;
+ }
+ if (val.begin() != 0) {
+ pos += packlen;
+ }
+ }
+ return 0;
+}
+
+void
+dbcontext::cmd_open(dbcallback_i& cb, const cmd_open_args& arg)
+{
+ unlock_tables_if();
+ const table_name_type k = std::make_pair(std::string(arg.dbn),
+ std::string(arg.tbl));
+ const table_map_type::const_iterator iter = table_map.find(k);
+ uint32_t tblnum = 0;
+ if (iter != table_map.end()) {
+ tblnum = iter->second;
+ DBG_CMP(fprintf(stderr, "HNDSOCK k=%s tblnum=%d\n", k.c_str(),
+ (int)tblnum));
+ } else {
+ TABLE_LIST tables;
+ TABLE *table = 0;
+ bool refresh = true;
+ const thr_lock_type lock_type = for_write_flag ? TL_WRITE : TL_READ;
+ #if MYSQL_VERSION_ID >= 50505
+ tables.init_one_table(arg.dbn, strlen(arg.dbn), arg.tbl, strlen(arg.tbl),
+ arg.tbl, lock_type);
+ tables.mdl_request.init(MDL_key::TABLE, arg.dbn, arg.tbl,
+ for_write_flag ? MDL_SHARED_WRITE : MDL_SHARED_READ, MDL_TRANSACTION);
+ Open_table_context ot_act(thd, 0);
+ if (!open_table(thd, &tables, thd->mem_root, &ot_act)) {
+ table = tables.table;
+ }
+ #else
+ tables.init_one_table(arg.dbn, arg.tbl, lock_type);
+ table = open_table(thd, &tables, thd->mem_root, &refresh,
+ OPEN_VIEW_NO_PARSE);
+ #endif
+ if (table == 0) {
+ DENA_VERBOSE(20, fprintf(stderr,
+ "HNDSOCK failed to open %p [%s] [%s] [%d]\n",
+ thd, arg.dbn, arg.tbl, static_cast<int>(refresh)));
+ return cb.dbcb_resp_short(1, "open_table");
+ }
+ statistic_increment(open_tables_count, &LOCK_status);
+ table->reginfo.lock_type = lock_type;
+ table->use_all_columns();
+ tblnum = table_vec.size();
+ tablevec_entry e;
+ e.table = table;
+ table_vec.push_back(e);
+ table_map[k] = tblnum;
+ }
+ size_t idxnum = static_cast<size_t>(-1);
+ if (arg.idx[0] >= '0' && arg.idx[0] <= '9') {
+ /* numeric */
+ TABLE *const table = table_vec[tblnum].table;
+ idxnum = atoi(arg.idx);
+ if (idxnum >= table->s->keys) {
+ return cb.dbcb_resp_short(2, "idxnum");
+ }
+ } else {
+ const char *const idx_name_to_open =
+ arg.idx[0] == '\0' ? "PRIMARY" : arg.idx;
+ TABLE *const table = table_vec[tblnum].table;
+ for (uint i = 0; i < table->s->keys; ++i) {
+ KEY& kinfo = table->key_info[i];
+ if (strcmp(kinfo.name, idx_name_to_open) == 0) {
+ idxnum = i;
+ break;
+ }
+ }
+ }
+ if (idxnum == size_t(-1)) {
+ return cb.dbcb_resp_short(2, "idxnum");
+ }
+ prep_stmt::fields_type rf;
+ prep_stmt::fields_type ff;
+ if (!parse_fields(table_vec[tblnum].table, arg.retflds, rf)) {
+ return cb.dbcb_resp_short(2, "fld");
+ }
+ if (!parse_fields(table_vec[tblnum].table, arg.filflds, ff)) {
+ return cb.dbcb_resp_short(2, "fld");
+ }
+ prep_stmt p(this, tblnum, idxnum, rf, ff);
+ cb.dbcb_set_prep_stmt(arg.pst_id, p);
+ return cb.dbcb_resp_short(0, "");
+}
+
+bool
+dbcontext::parse_fields(TABLE *const table, const char *str,
+ prep_stmt::fields_type& flds)
+{
+ string_ref flds_sr(str, strlen(str));
+ std::vector<string_ref> fldnms;
+ if (flds_sr.size() != 0) {
+ split(',', flds_sr, fldnms);
+ }
+ for (size_t i = 0; i < fldnms.size(); ++i) {
+ Field **fld = 0;
+ size_t j = 0;
+ for (fld = table->field; *fld; ++fld, ++j) {
+ DBG_FLD(fprintf(stderr, "f %s\n", (*fld)->field_name));
+ string_ref fn((*fld)->field_name, strlen((*fld)->field_name));
+ if (fn == fldnms[i]) {
+ break;
+ }
+ }
+ if (*fld == 0) {
+ DBG_FLD(fprintf(stderr, "UNKNOWN FLD %s [%s]\n", retflds,
+ std::string(fldnms[i].begin(), fldnms[i].size()).c_str()));
+ return false;
+ }
+ DBG_FLD(fprintf(stderr, "FLD %s %zu\n", (*fld)->field_name, j));
+ flds.push_back(j);
+ }
+ return true;
+}
+
+enum db_write_op {
+ db_write_op_none = 0,
+ db_write_op_insert = 1,
+ db_write_op_sql = 2,
+};
+
+void
+dbcontext::cmd_exec(dbcallback_i& cb, const cmd_exec_args& args)
+{
+ const prep_stmt& p = *args.pst;
+ if (p.get_table_id() == static_cast<size_t>(-1)) {
+ return cb.dbcb_resp_short(2, "stmtnum");
+ }
+ ha_rkey_function find_flag = HA_READ_KEY_EXACT;
+ db_write_op wrop = db_write_op_none;
+ if (args.op.size() == 1) {
+ switch (args.op.begin()[0]) {
+ case '=':
+ find_flag = HA_READ_KEY_EXACT;
+ break;
+ case '>':
+ find_flag = HA_READ_AFTER_KEY;
+ break;
+ case '<':
+ find_flag = HA_READ_BEFORE_KEY;
+ break;
+ case '+':
+ wrop = db_write_op_insert;
+ break;
+ case 'S':
+ wrop = db_write_op_sql;
+ break;
+ default:
+ return cb.dbcb_resp_short(2, "op");
+ }
+ } else if (args.op.size() == 2 && args.op.begin()[1] == '=') {
+ switch (args.op.begin()[0]) {
+ case '>':
+ find_flag = HA_READ_KEY_OR_NEXT;
+ break;
+ case '<':
+ find_flag = HA_READ_KEY_OR_PREV;
+ break;
+ default:
+ return cb.dbcb_resp_short(2, "op");
+ }
+ } else {
+ return cb.dbcb_resp_short(2, "op");
+ }
+ if (args.kvalslen <= 0) {
+ return cb.dbcb_resp_short(2, "klen");
+ }
+ switch (wrop) {
+ case db_write_op_none:
+ return cmd_find_internal(cb, p, find_flag, args);
+ case db_write_op_insert:
+ return cmd_insert_internal(cb, p, args.kvals, args.kvalslen);
+ case db_write_op_sql:
+ return cmd_sql_internal(cb, p, args.kvals, args.kvalslen);
+ }
+}
+
+void
+dbcontext::set_statistics(size_t num_conns, size_t num_active)
+{
+ if (for_write_flag) {
+ set_thread_message("handlersocket: mode=wr, %zu conns, %zu active",
+ num_conns, num_active);
+ } else {
+ set_thread_message("handlersocket: mode=rd, %zu conns, %zu active",
+ num_conns, num_active);
+ }
+ /*
+ Don't set message buf if it's already in use. This saves slow call to
+ thd_proc_info() (if profiling is enabled)
+ */
+ if (thd->proc_info != &info_message_buf[0])
+ thd_proc_info(thd, &info_message_buf[0]);
+}
+
+};
+
diff --git a/plugin/handler_socket/handlersocket/database.hpp b/plugin/handler_socket/handlersocket/database.hpp
new file mode 100644
index 00000000000..a4aee0874c7
--- /dev/null
+++ b/plugin/handler_socket/handlersocket/database.hpp
@@ -0,0 +1,142 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_DATABASE_HPP
+#define DENA_DATABASE_HPP
+
+#include <string>
+#include <memory>
+#include <vector>
+#include <stdint.h>
+
+#include "string_buffer.hpp"
+#include "string_ref.hpp"
+#include "config.hpp"
+
+namespace dena {
+
+struct database_i;
+typedef std::auto_ptr<volatile database_i> database_ptr;
+
+struct dbcontext_i;
+typedef std::auto_ptr<dbcontext_i> dbcontext_ptr;
+
+struct database_i {
+ virtual ~database_i() { }
+ virtual dbcontext_ptr create_context(bool for_write) volatile = 0;
+ virtual void stop() volatile = 0;
+ virtual const config& get_conf() const volatile = 0;
+ static database_ptr create(const config& conf);
+};
+
+struct prep_stmt {
+ typedef std::vector<uint32_t> fields_type;
+ private:
+ dbcontext_i *dbctx; /* must be valid while *this is alive */
+ size_t table_id; /* a prep_stmt object holds a refcount of the table */
+ size_t idxnum;
+ fields_type ret_fields;
+ fields_type filter_fields;
+ public:
+ prep_stmt();
+ prep_stmt(dbcontext_i *c, size_t tbl, size_t idx, const fields_type& rf,
+ const fields_type& ff);
+ ~prep_stmt();
+ prep_stmt(const prep_stmt& x);
+ prep_stmt& operator =(const prep_stmt& x);
+ public:
+ size_t get_table_id() const { return table_id; }
+ size_t get_idxnum() const { return idxnum; }
+ const fields_type& get_ret_fields() const { return ret_fields; }
+ const fields_type& get_filter_fields() const { return filter_fields; }
+};
+
+struct dbcallback_i {
+ virtual ~dbcallback_i () { }
+ virtual void dbcb_set_prep_stmt(size_t pst_id, const prep_stmt& v) = 0;
+ virtual const prep_stmt *dbcb_get_prep_stmt(size_t pst_id) const = 0;
+ virtual void dbcb_resp_short(uint32_t code, const char *msg) = 0;
+ virtual void dbcb_resp_short_num(uint32_t code, uint32_t value) = 0;
+ virtual void dbcb_resp_short_num64(uint32_t code, uint64_t value) = 0;
+ virtual void dbcb_resp_begin(size_t num_flds) = 0;
+ virtual void dbcb_resp_entry(const char *fld, size_t fldlen) = 0;
+ virtual void dbcb_resp_end() = 0;
+ virtual void dbcb_resp_cancel() = 0;
+};
+
+enum record_filter_type {
+ record_filter_type_skip = 0,
+ record_filter_type_break = 1,
+};
+
+struct record_filter {
+ record_filter_type filter_type;
+ string_ref op;
+ uint32_t ff_offset; /* offset in filter_fields */
+ string_ref val;
+ record_filter() : filter_type(record_filter_type_skip), ff_offset(0) { }
+};
+
+struct cmd_open_args {
+ size_t pst_id;
+ const char *dbn;
+ const char *tbl;
+ const char *idx;
+ const char *retflds;
+ const char *filflds;
+ cmd_open_args() : pst_id(0), dbn(0), tbl(0), idx(0), retflds(0),
+ filflds(0) { }
+};
+
+struct cmd_exec_args {
+ const prep_stmt *pst;
+ string_ref op;
+ const string_ref *kvals;
+ size_t kvalslen;
+ uint32_t limit;
+ uint32_t skip;
+ string_ref mod_op;
+ const string_ref *uvals; /* size must be pst->retfieelds.size() */
+ const record_filter *filters;
+ int invalues_keypart;
+ const string_ref *invalues;
+ size_t invalueslen;
+ cmd_exec_args() : pst(0), kvals(0), kvalslen(0), limit(0), skip(0),
+ uvals(0), filters(0), invalues_keypart(-1), invalues(0), invalueslen(0) { }
+};
+
+struct dbcontext_i {
+ virtual ~dbcontext_i() { }
+ virtual void init_thread(const void *stack_bottom,
+ volatile int& shutdown_flag) = 0;
+ virtual void term_thread() = 0;
+ virtual bool check_alive() = 0;
+ virtual void lock_tables_if() = 0;
+ virtual void unlock_tables_if() = 0;
+ virtual bool get_commit_error() = 0;
+ virtual void clear_error() = 0;
+ virtual void close_tables_if() = 0;
+ virtual void table_addref(size_t tbl_id) = 0; /* TODO: hide */
+ virtual void table_release(size_t tbl_id) = 0; /* TODO: hide */
+ virtual void cmd_open(dbcallback_i& cb, const cmd_open_args& args) = 0;
+ virtual void cmd_exec(dbcallback_i& cb, const cmd_exec_args& args) = 0;
+ virtual void set_statistics(size_t num_conns, size_t num_active) = 0;
+};
+
+};
+
+extern unsigned long long int open_tables_count;
+extern unsigned long long int close_tables_count;
+extern unsigned long long int lock_tables_count;
+extern unsigned long long int unlock_tables_count;
+#if 0
+extern unsigned long long int index_exec_count;
+#endif
+
+#endif
+
diff --git a/plugin/handler_socket/handlersocket/handlersocket.cpp b/plugin/handler_socket/handlersocket/handlersocket.cpp
new file mode 100644
index 00000000000..7b60eaa28d3
--- /dev/null
+++ b/plugin/handler_socket/handlersocket/handlersocket.cpp
@@ -0,0 +1,216 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#include <memory>
+#include <string>
+#include <stdio.h>
+
+#include "config.hpp"
+#include "hstcpsvr.hpp"
+#include "string_util.hpp"
+#include "mysql_incl.hpp"
+
+#define DBG_LOG \
+ if (dena::verbose_level >= 100) { \
+ fprintf(stderr, "%s %p\n", __PRETTY_FUNCTION__, this); \
+ }
+#define DBG_DO(x) if (dena::verbose_level >= 100) { x; }
+
+#define DBG_DIR(x)
+
+using namespace dena;
+
+static char *handlersocket_address = 0;
+static char *handlersocket_port = 0;
+static char *handlersocket_port_wr = 0;
+static unsigned int handlersocket_epoll = 1;
+static unsigned int handlersocket_threads = 32;
+static unsigned int handlersocket_threads_wr = 1;
+static unsigned int handlersocket_timeout = 30;
+static unsigned int handlersocket_backlog = 32768;
+static unsigned int handlersocket_sndbuf = 0;
+static unsigned int handlersocket_rcvbuf = 0;
+static unsigned int handlersocket_readsize = 0;
+static unsigned int handlersocket_accept_balance = 0;
+static unsigned int handlersocket_wrlock_timeout = 0;
+static char *handlersocket_plain_secret = 0;
+static char *handlersocket_plain_secret_wr = 0;
+
+struct daemon_handlersocket_data {
+ hstcpsvr_ptr hssvr_rd;
+ hstcpsvr_ptr hssvr_wr;
+};
+
+static int
+daemon_handlersocket_init(void *p)
+{
+ DENA_VERBOSE(10, fprintf(stderr, "handlersocket: initialized\n"));
+ config conf;
+ conf["use_epoll"] = handlersocket_epoll ? "1" : "0";
+ if (handlersocket_address) {
+ conf["host"] = handlersocket_address;
+ }
+ if (handlersocket_port) {
+ conf["port"] = handlersocket_port;
+ }
+ /*
+ * unix domain socket
+ * conf["host"] = "/";
+ * conf["port"] = "/tmp/handlersocket";
+ */
+ if (handlersocket_threads > 0) {
+ conf["num_threads"] = to_stdstring(handlersocket_threads);
+ } else {
+ conf["num_threads"] = "1";
+ }
+ conf["timeout"] = to_stdstring(handlersocket_timeout);
+ conf["listen_backlog"] = to_stdstring(handlersocket_backlog);
+ conf["sndbuf"] = to_stdstring(handlersocket_sndbuf);
+ conf["rcvbuf"] = to_stdstring(handlersocket_rcvbuf);
+ conf["readsize"] = to_stdstring(handlersocket_readsize);
+ conf["accept_balance"] = to_stdstring(handlersocket_accept_balance);
+ conf["wrlock_timeout"] = to_stdstring(handlersocket_wrlock_timeout);
+ std::auto_ptr<daemon_handlersocket_data> ap(new daemon_handlersocket_data);
+ if (handlersocket_port != 0 && handlersocket_port_wr != handlersocket_port) {
+ conf["port"] = handlersocket_port;
+ if (handlersocket_plain_secret) {
+ conf["plain_secret"] = handlersocket_plain_secret;
+ }
+ ap->hssvr_rd = hstcpsvr_i::create(conf);
+ ap->hssvr_rd->start_listen();
+ }
+ if (handlersocket_port_wr != 0) {
+ if (handlersocket_threads_wr > 0) {
+ conf["num_threads"] = to_stdstring(handlersocket_threads_wr);
+ }
+ conf["port"] = handlersocket_port_wr;
+ conf["for_write"] = "1";
+ conf["plain_secret"] = "";
+ if (handlersocket_plain_secret_wr) {
+ conf["plain_secret"] = handlersocket_plain_secret_wr;
+ }
+ ap->hssvr_wr = hstcpsvr_i::create(conf);
+ ap->hssvr_wr->start_listen();
+ }
+ st_plugin_int *const plugin = static_cast<st_plugin_int *>(p);
+ plugin->data = ap.release();
+ return 0;
+}
+
+static int
+daemon_handlersocket_deinit(void *p)
+{
+ DENA_VERBOSE(10, fprintf(stderr, "handlersocket: terminated\n"));
+ st_plugin_int *const plugin = static_cast<st_plugin_int *>(p);
+ daemon_handlersocket_data *ptr =
+ static_cast<daemon_handlersocket_data *>(plugin->data);
+ delete ptr;
+ return 0;
+}
+
+static struct st_mysql_daemon daemon_handlersocket_plugin = {
+ MYSQL_DAEMON_INTERFACE_VERSION
+};
+
+static MYSQL_SYSVAR_UINT(verbose, dena::verbose_level, 0,
+ "0..10000", 0, 0, 10 /* default */, 0, 10000, 0);
+static MYSQL_SYSVAR_UINT(epoll, handlersocket_epoll, PLUGIN_VAR_READONLY,
+ "0..1", 0, 0, 1 /* default */, 0, 1, 0);
+static MYSQL_SYSVAR_STR(address, handlersocket_address,
+ PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "", NULL, NULL, NULL);
+static MYSQL_SYSVAR_STR(port, handlersocket_port,
+ PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "", NULL, NULL, NULL);
+static MYSQL_SYSVAR_STR(port_wr, handlersocket_port_wr,
+ PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "", NULL, NULL, NULL);
+static MYSQL_SYSVAR_UINT(threads, handlersocket_threads, PLUGIN_VAR_READONLY,
+ "1..3000", 0, 0, 16 /* default */, 1, 3000, 0);
+static MYSQL_SYSVAR_UINT(threads_wr, handlersocket_threads_wr,
+ PLUGIN_VAR_READONLY, "1..3000", 0, 0, 1 /* default */, 1, 3000, 0);
+static MYSQL_SYSVAR_UINT(timeout, handlersocket_timeout, PLUGIN_VAR_READONLY,
+ "30..3600", 0, 0, 300 /* default */, 30, 3600, 0);
+static MYSQL_SYSVAR_UINT(backlog, handlersocket_backlog, PLUGIN_VAR_READONLY,
+ "5..1000000", 0, 0, 32768 /* default */, 5, 1000000, 0);
+static MYSQL_SYSVAR_UINT(sndbuf, handlersocket_sndbuf, PLUGIN_VAR_READONLY,
+ "0..16777216", 0, 0, 0 /* default */, 0, 16777216, 0);
+static MYSQL_SYSVAR_UINT(rcvbuf, handlersocket_rcvbuf, PLUGIN_VAR_READONLY,
+ "0..16777216", 0, 0, 0 /* default */, 0, 16777216, 0);
+static MYSQL_SYSVAR_UINT(readsize, handlersocket_readsize, PLUGIN_VAR_READONLY,
+ "0..16777216", 0, 0, 0 /* default */, 0, 16777216, 0);
+static MYSQL_SYSVAR_UINT(accept_balance, handlersocket_accept_balance,
+ PLUGIN_VAR_READONLY, "0..10000", 0, 0, 0 /* default */, 0, 10000, 0);
+static MYSQL_SYSVAR_UINT(wrlock_timeout, handlersocket_wrlock_timeout,
+ PLUGIN_VAR_READONLY, "0..3600", 0, 0, 12 /* default */, 0, 3600, 0);
+static MYSQL_SYSVAR_STR(plain_secret, handlersocket_plain_secret,
+ PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "", NULL, NULL, NULL);
+static MYSQL_SYSVAR_STR(plain_secret_wr, handlersocket_plain_secret_wr,
+ PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "", NULL, NULL, NULL);
+
+
+/* warning: type-punning to incomplete type might break strict-aliasing
+ * rules */
+static struct st_mysql_sys_var *daemon_handlersocket_system_variables[] = {
+ MYSQL_SYSVAR(verbose),
+ MYSQL_SYSVAR(address),
+ MYSQL_SYSVAR(port),
+ MYSQL_SYSVAR(port_wr),
+ MYSQL_SYSVAR(epoll),
+ MYSQL_SYSVAR(threads),
+ MYSQL_SYSVAR(threads_wr),
+ MYSQL_SYSVAR(timeout),
+ MYSQL_SYSVAR(backlog),
+ MYSQL_SYSVAR(sndbuf),
+ MYSQL_SYSVAR(rcvbuf),
+ MYSQL_SYSVAR(readsize),
+ MYSQL_SYSVAR(accept_balance),
+ MYSQL_SYSVAR(wrlock_timeout),
+ MYSQL_SYSVAR(plain_secret),
+ MYSQL_SYSVAR(plain_secret_wr),
+ 0
+};
+
+static SHOW_VAR hs_status_variables[] = {
+ {"table_open", (char*) &open_tables_count, SHOW_LONGLONG},
+ {"table_close", (char*) &close_tables_count, SHOW_LONGLONG},
+ {"table_lock", (char*) &lock_tables_count, SHOW_LONGLONG},
+ {"table_unlock", (char*) &unlock_tables_count, SHOW_LONGLONG},
+ #if 0
+ {"index_exec", (char*) &index_exec_count, SHOW_LONGLONG},
+ #endif
+ {NullS, NullS, SHOW_LONG}
+};
+
+static int show_hs_vars(THD *thd, SHOW_VAR *var, char *buff)
+{
+ var->type= SHOW_ARRAY;
+ var->value= (char *) &hs_status_variables;
+ return 0;
+}
+
+static SHOW_VAR daemon_handlersocket_status_variables[] = {
+ {"Hs", (char*) show_hs_vars, SHOW_FUNC},
+ {NullS, NullS, SHOW_LONG}
+};
+
+
+mysql_declare_plugin(handlersocket)
+{
+ MYSQL_DAEMON_PLUGIN,
+ &daemon_handlersocket_plugin,
+ "handlersocket",
+ "higuchi dot akira at dena dot jp",
+ "",
+ PLUGIN_LICENSE_BSD,
+ daemon_handlersocket_init,
+ daemon_handlersocket_deinit,
+ 0x0100 /* 1.0 */,
+ daemon_handlersocket_status_variables,
+ daemon_handlersocket_system_variables,
+ 0
+}
+mysql_declare_plugin_end;
+
diff --git a/plugin/handler_socket/handlersocket/handlersocket.spec.template b/plugin/handler_socket/handlersocket/handlersocket.spec.template
new file mode 100644
index 00000000000..0ce8c0cb382
--- /dev/null
+++ b/plugin/handler_socket/handlersocket/handlersocket.spec.template
@@ -0,0 +1,29 @@
+Summary: handlersocket plugin for mysql
+Name: handlersocket
+Version: HANDLERSOCKET_VERSION
+Release: 1%{?dist}
+Group: System Environment/Libraries
+License: BSD
+Source: handlersocket.tar.gz
+Packager: Akira Higuchi <higuchi dot akira at dena dot jp>
+BuildRoot: /var/tmp/%{name}-%{version}-root
+
+%description
+
+%prep
+%setup -n %{name}
+
+%define _use_internal_dependency_generator 0
+
+%build
+make -f Makefile.plain
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT/%{_libdir}/mysql/plugin
+install -m 755 handlersocket.so $RPM_BUILD_ROOT/%{_libdir}/mysql/plugin/
+
+%files
+%defattr(-, root, root)
+%{_libdir}/mysql/plugin/*.so
+
diff --git a/plugin/handler_socket/handlersocket/hstcpsvr.cpp b/plugin/handler_socket/handlersocket/hstcpsvr.cpp
new file mode 100644
index 00000000000..13df7ba0838
--- /dev/null
+++ b/plugin/handler_socket/handlersocket/hstcpsvr.cpp
@@ -0,0 +1,149 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#include <stdlib.h>
+#include <vector>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/resource.h>
+
+#include "hstcpsvr.hpp"
+#include "hstcpsvr_worker.hpp"
+#include "thread.hpp"
+#include "fatal.hpp"
+#include "auto_ptrcontainer.hpp"
+
+#define DBG(x)
+
+namespace dena {
+
+struct worker_throbj {
+ worker_throbj(const hstcpsvr_worker_arg& arg)
+ : worker(hstcpsvr_worker_i::create(arg)) { }
+ void operator ()() {
+ worker->run();
+ }
+ hstcpsvr_worker_ptr worker;
+};
+
+struct hstcpsvr : public hstcpsvr_i, private noncopyable {
+ hstcpsvr(const config& c);
+ ~hstcpsvr();
+ virtual std::string start_listen();
+ private:
+ hstcpsvr_shared_c cshared;
+ volatile hstcpsvr_shared_v vshared;
+ typedef thread<worker_throbj> worker_thread_type;
+ typedef auto_ptrcontainer< std::vector<worker_thread_type *> > threads_type;
+ threads_type threads;
+ std::vector<unsigned int> thread_num_conns_vec;
+ private:
+ void stop_workers();
+};
+
+namespace {
+
+void
+check_nfile(size_t nfile)
+{
+ struct rlimit rl;
+ const int r = getrlimit(RLIMIT_NOFILE, &rl);
+ if (r != 0) {
+ fatal_abort("check_nfile: getrlimit failed");
+ }
+ if (rl.rlim_cur < static_cast<rlim_t>(nfile + 1000)) {
+ fprintf(stderr,
+ "[Warning] handlersocket: open_files_limit is too small.\n");
+ }
+}
+
+};
+
+hstcpsvr::hstcpsvr(const config& c)
+ : cshared(), vshared()
+{
+ vshared.shutdown = 0;
+ cshared.conf = c; /* copy */
+ if (cshared.conf["port"] == "") {
+ cshared.conf["port"] = "9999";
+ }
+ cshared.num_threads = cshared.conf.get_int("num_threads", 32);
+ cshared.sockargs.nonblocking = cshared.conf.get_int("nonblocking", 1);
+ cshared.sockargs.use_epoll = cshared.conf.get_int("use_epoll", 1);
+ if (cshared.sockargs.use_epoll) {
+ cshared.sockargs.nonblocking = 1;
+ }
+ cshared.readsize = cshared.conf.get_int("readsize", 1);
+ cshared.nb_conn_per_thread = cshared.conf.get_int("conn_per_thread", 1024);
+ cshared.for_write_flag = cshared.conf.get_int("for_write", 0);
+ cshared.plain_secret = cshared.conf.get_str("plain_secret", "");
+ cshared.require_auth = !cshared.plain_secret.empty();
+ cshared.sockargs.set(cshared.conf);
+ cshared.dbptr = database_i::create(c);
+ check_nfile(cshared.num_threads * cshared.nb_conn_per_thread);
+ thread_num_conns_vec.resize(cshared.num_threads);
+ cshared.thread_num_conns = thread_num_conns_vec.empty()
+ ? 0 : &thread_num_conns_vec[0];
+}
+
+hstcpsvr::~hstcpsvr()
+{
+ stop_workers();
+}
+
+std::string
+hstcpsvr::start_listen()
+{
+ std::string err;
+ if (threads.size() != 0) {
+ return "start_listen: already running";
+ }
+ if (socket_bind(cshared.listen_fd, cshared.sockargs, err) != 0) {
+ return "bind: " + err;
+ }
+ DENA_VERBOSE(20, fprintf(stderr, "bind done\n"));
+ const size_t stack_size = std::max(
+ cshared.conf.get_int("stack_size", 1 * 1024LL * 1024), 8 * 1024LL * 1024);
+ for (long i = 0; i < cshared.num_threads; ++i) {
+ hstcpsvr_worker_arg arg;
+ arg.cshared = &cshared;
+ arg.vshared = &vshared;
+ arg.worker_id = i;
+ std::auto_ptr< thread<worker_throbj> > thr(
+ new thread<worker_throbj>(arg, stack_size));
+ threads.push_back_ptr(thr);
+ }
+ DENA_VERBOSE(20, fprintf(stderr, "threads created\n"));
+ for (size_t i = 0; i < threads.size(); ++i) {
+ threads[i]->start();
+ }
+ DENA_VERBOSE(20, fprintf(stderr, "threads started\n"));
+ return std::string();
+}
+
+void
+hstcpsvr::stop_workers()
+{
+ vshared.shutdown = 1;
+ for (size_t i = 0; i < threads.size(); ++i) {
+ threads[i]->join();
+ }
+ threads.clear();
+}
+
+hstcpsvr_ptr
+hstcpsvr_i::create(const config& conf)
+{
+ return hstcpsvr_ptr(new hstcpsvr(conf));
+}
+
+};
+
diff --git a/plugin/handler_socket/handlersocket/hstcpsvr.hpp b/plugin/handler_socket/handlersocket/hstcpsvr.hpp
new file mode 100644
index 00000000000..811bfa25613
--- /dev/null
+++ b/plugin/handler_socket/handlersocket/hstcpsvr.hpp
@@ -0,0 +1,58 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_HSTCPSVR_HPP
+#define DENA_HSTCPSVR_HPP
+
+#include <memory>
+#include <string>
+#include <map>
+
+#include "mutex.hpp"
+#include "auto_file.hpp"
+#include "database.hpp"
+#include "config.hpp"
+#include "socket.hpp"
+
+namespace dena {
+
+struct hstcpsvr_shared_c {
+ config conf;
+ long num_threads;
+ long nb_conn_per_thread;
+ bool for_write_flag;
+ bool require_auth;
+ std::string plain_secret;
+ int readsize;
+ socket_args sockargs;
+ auto_file listen_fd;
+ database_ptr dbptr;
+ volatile unsigned int *thread_num_conns; /* 0 .. num_threads-1 */
+ hstcpsvr_shared_c() : num_threads(0), nb_conn_per_thread(100),
+ for_write_flag(false), require_auth(false), readsize(0),
+ thread_num_conns(0) { }
+};
+
+struct hstcpsvr_shared_v : public mutex {
+ int shutdown;
+ hstcpsvr_shared_v() : shutdown(0) { }
+};
+
+struct hstcpsvr_i;
+typedef std::auto_ptr<hstcpsvr_i> hstcpsvr_ptr;
+
+struct hstcpsvr_i {
+ virtual ~hstcpsvr_i() { }
+ virtual std::string start_listen() = 0;
+ static hstcpsvr_ptr create(const config& conf);
+};
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp b/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp
new file mode 100644
index 00000000000..c254d17dff5
--- /dev/null
+++ b/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp
@@ -0,0 +1,959 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#include <my_config.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <poll.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <signal.h>
+#include <list>
+#if __linux__
+#include <sys/epoll.h>
+#endif
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+
+#include "hstcpsvr_worker.hpp"
+#include "string_buffer.hpp"
+#include "auto_ptrcontainer.hpp"
+#include "string_util.hpp"
+#include "escape.hpp"
+
+#define DBG_FD(x)
+#define DBG_TR(x)
+#define DBG_EP(x)
+#define DBG_MULTI(x)
+
+/* TODO */
+#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(MSG_NOSIGNAL)
+#define MSG_NOSIGNAL 0
+#endif
+
+namespace dena {
+
+struct dbconnstate {
+ string_buffer readbuf;
+ string_buffer writebuf;
+ std::vector<prep_stmt> prep_stmts;
+ size_t resp_begin_pos;
+ size_t find_nl_pos;
+ void reset() {
+ readbuf.clear();
+ writebuf.clear();
+ prep_stmts.clear();
+ resp_begin_pos = 0;
+ find_nl_pos = 0;
+ }
+ dbconnstate() : resp_begin_pos(0), find_nl_pos(0) { }
+};
+
+struct hstcpsvr_conn;
+typedef auto_ptrcontainer< std::list<hstcpsvr_conn *> > hstcpsvr_conns_type;
+
+struct hstcpsvr_conn : public dbcallback_i {
+ public:
+ auto_file fd;
+ sockaddr_storage addr;
+ size_socket addr_len;
+ dbconnstate cstate;
+ std::string err;
+ size_t readsize;
+ bool nonblocking;
+ bool read_finished;
+ bool write_finished;
+ time_t nb_last_io;
+ hstcpsvr_conns_type::iterator conns_iter;
+ bool authorized;
+ public:
+ bool closed() const;
+ bool ok_to_close() const;
+ void reset();
+ int accept(const hstcpsvr_shared_c& cshared);
+ bool write_more(bool *more_r = 0);
+ bool read_more(bool *more_r = 0);
+ public:
+ virtual void dbcb_set_prep_stmt(size_t pst_id, const prep_stmt& v);
+ virtual const prep_stmt *dbcb_get_prep_stmt(size_t pst_id) const;
+ virtual void dbcb_resp_short(uint32_t code, const char *msg);
+ virtual void dbcb_resp_short_num(uint32_t code, uint32_t value);
+ virtual void dbcb_resp_short_num64(uint32_t code, uint64_t value);
+ virtual void dbcb_resp_begin(size_t num_flds);
+ virtual void dbcb_resp_entry(const char *fld, size_t fldlen);
+ virtual void dbcb_resp_end();
+ virtual void dbcb_resp_cancel();
+ public:
+ hstcpsvr_conn() : addr_len(sizeof(addr)), readsize(4096),
+ nonblocking(false), read_finished(false), write_finished(false),
+ nb_last_io(0), authorized(false) { }
+};
+
+bool
+hstcpsvr_conn::closed() const
+{
+ return fd.get() < 0;
+}
+
+bool
+hstcpsvr_conn::ok_to_close() const
+{
+ return write_finished || (read_finished && cstate.writebuf.size() == 0);
+}
+
+void
+hstcpsvr_conn::reset()
+{
+ addr = sockaddr_storage();
+ addr_len = sizeof(addr);
+ cstate.reset();
+ fd.reset();
+ read_finished = false;
+ write_finished = false;
+}
+
+int
+hstcpsvr_conn::accept(const hstcpsvr_shared_c& cshared)
+{
+ reset();
+ return socket_accept(cshared.listen_fd.get(), fd, cshared.sockargs, addr,
+ addr_len, err);
+}
+
+bool
+hstcpsvr_conn::write_more(bool *more_r)
+{
+ if (write_finished || cstate.writebuf.size() == 0) {
+ return false;
+ }
+ const size_t wlen = cstate.writebuf.size();
+ ssize_t len = send(fd.get(), cstate.writebuf.begin(), wlen, MSG_NOSIGNAL);
+ if (len <= 0) {
+ if (len == 0 || !nonblocking || errno != EWOULDBLOCK) {
+ cstate.writebuf.clear();
+ write_finished = true;
+ }
+ return false;
+ }
+ cstate.writebuf.erase_front(len);
+ /* FIXME: reallocate memory if too large */
+ if (more_r) {
+ *more_r = (static_cast<size_t>(len) == wlen);
+ }
+ return true;
+}
+
+bool
+hstcpsvr_conn::read_more(bool *more_r)
+{
+ if (read_finished) {
+ return false;
+ }
+ const size_t block_size = readsize > 4096 ? readsize : 4096;
+ char *wp = cstate.readbuf.make_space(block_size);
+ const ssize_t len = read(fd.get(), wp, block_size);
+ if (len <= 0) {
+ if (len == 0 || !nonblocking || errno != EWOULDBLOCK) {
+ read_finished = true;
+ }
+ return false;
+ }
+ cstate.readbuf.space_wrote(len);
+ if (more_r) {
+ *more_r = (static_cast<size_t>(len) == block_size);
+ }
+ return true;
+}
+
+void
+hstcpsvr_conn::dbcb_set_prep_stmt(size_t pst_id, const prep_stmt& v)
+{
+ if (cstate.prep_stmts.size() <= pst_id) {
+ cstate.prep_stmts.resize(pst_id + 1);
+ }
+ cstate.prep_stmts[pst_id] = v;
+}
+
+const prep_stmt *
+hstcpsvr_conn::dbcb_get_prep_stmt(size_t pst_id) const
+{
+ if (cstate.prep_stmts.size() <= pst_id) {
+ return 0;
+ }
+ return &cstate.prep_stmts[pst_id];
+}
+
+void
+hstcpsvr_conn::dbcb_resp_short(uint32_t code, const char *msg)
+{
+ write_ui32(cstate.writebuf, code);
+ const size_t msglen = strlen(msg);
+ if (msglen != 0) {
+ cstate.writebuf.append_literal("\t1\t");
+ cstate.writebuf.append(msg, msg + msglen);
+ } else {
+ cstate.writebuf.append_literal("\t1");
+ }
+ cstate.writebuf.append_literal("\n");
+}
+
+void
+hstcpsvr_conn::dbcb_resp_short_num(uint32_t code, uint32_t value)
+{
+ write_ui32(cstate.writebuf, code);
+ cstate.writebuf.append_literal("\t1\t");
+ write_ui32(cstate.writebuf, value);
+ cstate.writebuf.append_literal("\n");
+}
+
+void
+hstcpsvr_conn::dbcb_resp_short_num64(uint32_t code, uint64_t value)
+{
+ write_ui32(cstate.writebuf, code);
+ cstate.writebuf.append_literal("\t1\t");
+ write_ui64(cstate.writebuf, value);
+ cstate.writebuf.append_literal("\n");
+}
+
+void
+hstcpsvr_conn::dbcb_resp_begin(size_t num_flds)
+{
+ cstate.resp_begin_pos = cstate.writebuf.size();
+ cstate.writebuf.append_literal("0\t");
+ write_ui32(cstate.writebuf, num_flds);
+}
+
+void
+hstcpsvr_conn::dbcb_resp_entry(const char *fld, size_t fldlen)
+{
+ if (fld != 0) {
+ cstate.writebuf.append_literal("\t");
+ escape_string(cstate.writebuf, fld, fld + fldlen);
+ } else {
+ static const char t[] = "\t\0";
+ cstate.writebuf.append(t, t + 2);
+ }
+}
+
+void
+hstcpsvr_conn::dbcb_resp_end()
+{
+ cstate.writebuf.append_literal("\n");
+ cstate.resp_begin_pos = 0;
+}
+
+void
+hstcpsvr_conn::dbcb_resp_cancel()
+{
+ cstate.writebuf.resize(cstate.resp_begin_pos);
+ cstate.resp_begin_pos = 0;
+}
+
+struct hstcpsvr_worker : public hstcpsvr_worker_i, private noncopyable {
+ hstcpsvr_worker(const hstcpsvr_worker_arg& arg);
+ virtual void run();
+ private:
+ const hstcpsvr_shared_c& cshared;
+ volatile hstcpsvr_shared_v& vshared;
+ long worker_id;
+ dbcontext_ptr dbctx;
+ hstcpsvr_conns_type conns; /* conns refs dbctx */
+ time_t last_check_time;
+ std::vector<pollfd> pfds;
+ #ifdef __linux__
+ std::vector<epoll_event> events_vec;
+ auto_file epoll_fd;
+ #endif
+ bool accept_enabled;
+ int accept_balance;
+ std::vector<string_ref> invalues_work;
+ std::vector<record_filter> filters_work;
+ private:
+ int run_one_nb();
+ int run_one_ep();
+ void execute_lines(hstcpsvr_conn& conn);
+ void execute_line(char *start, char *finish, hstcpsvr_conn& conn);
+ void do_open_index(char *start, char *finish, hstcpsvr_conn& conn);
+ void do_exec_on_index(char *cmd_begin, char *cmd_end, char *start,
+ char *finish, hstcpsvr_conn& conn);
+ void do_authorization(char *start, char *finish, hstcpsvr_conn& conn);
+};
+
+hstcpsvr_worker::hstcpsvr_worker(const hstcpsvr_worker_arg& arg)
+ : cshared(*arg.cshared), vshared(*arg.vshared), worker_id(arg.worker_id),
+ dbctx(cshared.dbptr->create_context(cshared.for_write_flag)),
+ last_check_time(time(0)), accept_enabled(true), accept_balance(0)
+{
+ #ifdef __linux__
+ if (cshared.sockargs.use_epoll) {
+ epoll_fd.reset(epoll_create(10));
+ if (epoll_fd.get() < 0) {
+ fatal_abort("epoll_create");
+ }
+ epoll_event ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.events = EPOLLIN;
+ ev.data.ptr = 0;
+ if (epoll_ctl(epoll_fd.get(), EPOLL_CTL_ADD, cshared.listen_fd.get(), &ev)
+ != 0) {
+ fatal_abort("epoll_ctl EPOLL_CTL_ADD");
+ }
+ events_vec.resize(10240);
+ }
+ #endif
+ accept_balance = cshared.conf.get_int("accept_balance", 0);
+}
+
+namespace {
+
+struct thr_init {
+ thr_init(const dbcontext_ptr& dc, volatile int& shutdown_flag) : dbctx(dc) {
+ dbctx->init_thread(this, shutdown_flag);
+ }
+ ~thr_init() {
+ dbctx->term_thread();
+ }
+ const dbcontext_ptr& dbctx;
+};
+
+}; // namespace
+
+void
+hstcpsvr_worker::run()
+{
+ thr_init initobj(dbctx, vshared.shutdown);
+
+ #ifdef __linux__
+ if (cshared.sockargs.use_epoll) {
+ while (!vshared.shutdown && dbctx->check_alive()) {
+ run_one_ep();
+ }
+ } else if (cshared.sockargs.nonblocking) {
+ while (!vshared.shutdown && dbctx->check_alive()) {
+ run_one_nb();
+ }
+ } else {
+ /* UNUSED */
+ fatal_abort("run_one");
+ }
+ #else
+ while (!vshared.shutdown && dbctx->check_alive()) {
+ run_one_nb();
+ }
+ #endif
+}
+
+int
+hstcpsvr_worker::run_one_nb()
+{
+ size_t nfds = 0;
+ /* CLIENT SOCKETS */
+ for (hstcpsvr_conns_type::const_iterator i = conns.begin();
+ i != conns.end(); ++i) {
+ if (pfds.size() <= nfds) {
+ pfds.resize(nfds + 1);
+ }
+ pollfd& pfd = pfds[nfds++];
+ pfd.fd = (*i)->fd.get();
+ short ev = 0;
+ if ((*i)->cstate.writebuf.size() != 0) {
+ ev = POLLOUT;
+ } else {
+ ev = POLLIN;
+ }
+ pfd.events = pfd.revents = ev;
+ }
+ /* LISTENER */
+ {
+ const size_t cpt = cshared.nb_conn_per_thread;
+ const short ev = (cpt > nfds) ? POLLIN : 0;
+ if (pfds.size() <= nfds) {
+ pfds.resize(nfds + 1);
+ }
+ pollfd& pfd = pfds[nfds++];
+ pfd.fd = cshared.listen_fd.get();
+ pfd.events = pfd.revents = ev;
+ }
+ /* POLL */
+ const int npollev = poll(&pfds[0], nfds, 1 * 1000);
+ dbctx->set_statistics(conns.size(), npollev);
+ const time_t now = time(0);
+ size_t j = 0;
+ const short mask_in = ~POLLOUT;
+ const short mask_out = POLLOUT | POLLERR | POLLHUP | POLLNVAL;
+ /* READ */
+ for (hstcpsvr_conns_type::iterator i = conns.begin(); i != conns.end();
+ ++i, ++j) {
+ pollfd& pfd = pfds[j];
+ if ((pfd.revents & mask_in) == 0) {
+ continue;
+ }
+ hstcpsvr_conn& conn = **i;
+ if (conn.read_more()) {
+ if (conn.cstate.readbuf.size() > 0) {
+ const char ch = conn.cstate.readbuf.begin()[0];
+ if (ch == 'Q') {
+ vshared.shutdown = 1;
+ } else if (ch == '/') {
+ conn.cstate.readbuf.clear();
+ conn.cstate.find_nl_pos = 0;
+ conn.cstate.writebuf.clear();
+ conn.read_finished = true;
+ conn.write_finished = true;
+ }
+ }
+ conn.nb_last_io = now;
+ }
+ }
+ /* EXECUTE */
+ j = 0;
+ for (hstcpsvr_conns_type::iterator i = conns.begin(); i != conns.end();
+ ++i, ++j) {
+ pollfd& pfd = pfds[j];
+ if ((pfd.revents & mask_in) == 0 || (*i)->cstate.readbuf.size() == 0) {
+ continue;
+ }
+ execute_lines(**i);
+ }
+ /* COMMIT */
+ dbctx->unlock_tables_if();
+ const bool commit_error = dbctx->get_commit_error();
+ dbctx->clear_error();
+ /* WRITE/CLOSE */
+ j = 0;
+ for (hstcpsvr_conns_type::iterator i = conns.begin(); i != conns.end();
+ ++j) {
+ pollfd& pfd = pfds[j];
+ hstcpsvr_conn& conn = **i;
+ hstcpsvr_conns_type::iterator icur = i;
+ ++i;
+ if (commit_error) {
+ conn.reset();
+ continue;
+ }
+ if ((pfd.revents & (mask_out | mask_in)) != 0) {
+ if (conn.write_more()) {
+ conn.nb_last_io = now;
+ }
+ }
+ if (cshared.sockargs.timeout != 0 &&
+ conn.nb_last_io + cshared.sockargs.timeout < now) {
+ conn.reset();
+ }
+ if (conn.closed() || conn.ok_to_close()) {
+ conns.erase_ptr(icur);
+ }
+ }
+ /* ACCEPT */
+ {
+ pollfd& pfd = pfds[nfds - 1];
+ if ((pfd.revents & mask_in) != 0) {
+ std::auto_ptr<hstcpsvr_conn> c(new hstcpsvr_conn());
+ c->nonblocking = true;
+ c->readsize = cshared.readsize;
+ c->accept(cshared);
+ if (c->fd.get() >= 0) {
+ if (fcntl(c->fd.get(), F_SETFL, O_NONBLOCK) != 0) {
+ fatal_abort("F_SETFL O_NONBLOCK");
+ }
+ c->nb_last_io = now;
+ conns.push_back_ptr(c);
+ } else {
+ /* errno == 11 (EAGAIN) is not a fatal error. */
+ DENA_VERBOSE(100, fprintf(stderr,
+ "accept failed: errno=%d (not fatal)\n", errno));
+ }
+ }
+ }
+ DENA_VERBOSE(30, fprintf(stderr, "nb: %p nfds=%zu cns=%zu\n", this, nfds,
+ conns.size()));
+ if (conns.empty()) {
+ dbctx->close_tables_if();
+ }
+ dbctx->set_statistics(conns.size(), 0);
+ return 0;
+}
+
+#ifdef __linux__
+int
+hstcpsvr_worker::run_one_ep()
+{
+ epoll_event *const events = &events_vec[0];
+ const size_t num_events = events_vec.size();
+ const time_t now = time(0);
+ size_t in_count = 0, out_count = 0, accept_count = 0;
+ int nfds = epoll_wait(epoll_fd.get(), events, num_events, 1000);
+ /* READ/ACCEPT */
+ dbctx->set_statistics(conns.size(), nfds);
+ for (int i = 0; i < nfds; ++i) {
+ epoll_event& ev = events[i];
+ if ((ev.events & EPOLLIN) == 0) {
+ continue;
+ }
+ hstcpsvr_conn *const conn = static_cast<hstcpsvr_conn *>(ev.data.ptr);
+ if (conn == 0) {
+ /* listener */
+ ++accept_count;
+ DBG_EP(fprintf(stderr, "IN listener\n"));
+ std::auto_ptr<hstcpsvr_conn> c(new hstcpsvr_conn());
+ c->nonblocking = true;
+ c->readsize = cshared.readsize;
+ c->accept(cshared);
+ if (c->fd.get() >= 0) {
+ if (fcntl(c->fd.get(), F_SETFL, O_NONBLOCK) != 0) {
+ fatal_abort("F_SETFL O_NONBLOCK");
+ }
+ epoll_event cev;
+ memset(&cev, 0, sizeof(cev));
+ cev.events = EPOLLIN | EPOLLOUT | EPOLLET;
+ cev.data.ptr = c.get();
+ c->nb_last_io = now;
+ const int fd = c->fd.get();
+ conns.push_back_ptr(c);
+ conns.back()->conns_iter = --conns.end();
+ if (epoll_ctl(epoll_fd.get(), EPOLL_CTL_ADD, fd, &cev) != 0) {
+ fatal_abort("epoll_ctl EPOLL_CTL_ADD");
+ }
+ } else {
+ DENA_VERBOSE(100, fprintf(stderr,
+ "accept failed: errno=%d (not fatal)\n", errno));
+ }
+ } else {
+ /* client connection */
+ ++in_count;
+ DBG_EP(fprintf(stderr, "IN client\n"));
+ bool more_data = false;
+ while (conn->read_more(&more_data)) {
+ DBG_EP(fprintf(stderr, "IN client read_more\n"));
+ conn->nb_last_io = now;
+ if (!more_data) {
+ break;
+ }
+ }
+ }
+ }
+ /* EXECUTE */
+ for (int i = 0; i < nfds; ++i) {
+ epoll_event& ev = events[i];
+ hstcpsvr_conn *const conn = static_cast<hstcpsvr_conn *>(ev.data.ptr);
+ if ((ev.events & EPOLLIN) == 0 || conn == 0 ||
+ conn->cstate.readbuf.size() == 0) {
+ continue;
+ }
+ const char ch = conn->cstate.readbuf.begin()[0];
+ if (ch == 'Q') {
+ vshared.shutdown = 1;
+ } else if (ch == '/') {
+ conn->cstate.readbuf.clear();
+ conn->cstate.find_nl_pos = 0;
+ conn->cstate.writebuf.clear();
+ conn->read_finished = true;
+ conn->write_finished = true;
+ } else {
+ execute_lines(*conn);
+ }
+ }
+ /* COMMIT */
+ dbctx->unlock_tables_if();
+ const bool commit_error = dbctx->get_commit_error();
+ dbctx->clear_error();
+ /* WRITE */
+ for (int i = 0; i < nfds; ++i) {
+ epoll_event& ev = events[i];
+ hstcpsvr_conn *const conn = static_cast<hstcpsvr_conn *>(ev.data.ptr);
+ if (commit_error && conn != 0) {
+ conn->reset();
+ continue;
+ }
+ if ((ev.events & EPOLLOUT) == 0) {
+ continue;
+ }
+ ++out_count;
+ if (conn == 0) {
+ /* listener */
+ DBG_EP(fprintf(stderr, "OUT listener\n"));
+ } else {
+ /* client connection */
+ DBG_EP(fprintf(stderr, "OUT client\n"));
+ bool more_data = false;
+ while (conn->write_more(&more_data)) {
+ DBG_EP(fprintf(stderr, "OUT client write_more\n"));
+ conn->nb_last_io = now;
+ if (!more_data) {
+ break;
+ }
+ }
+ }
+ }
+ /* CLOSE */
+ for (int i = 0; i < nfds; ++i) {
+ epoll_event& ev = events[i];
+ hstcpsvr_conn *const conn = static_cast<hstcpsvr_conn *>(ev.data.ptr);
+ if (conn != 0 && conn->ok_to_close()) {
+ DBG_EP(fprintf(stderr, "CLOSE close\n"));
+ conns.erase_ptr(conn->conns_iter);
+ }
+ }
+ /* TIMEOUT & cleanup */
+ if (last_check_time + 10 < now) {
+ for (hstcpsvr_conns_type::iterator i = conns.begin();
+ i != conns.end(); ) {
+ hstcpsvr_conns_type::iterator icur = i;
+ ++i;
+ if (cshared.sockargs.timeout != 0 &&
+ (*icur)->nb_last_io + cshared.sockargs.timeout < now) {
+ conns.erase_ptr((*icur)->conns_iter);
+ }
+ }
+ last_check_time = now;
+ DENA_VERBOSE(20, fprintf(stderr, "ep: %p nfds=%d cns=%zu\n", this, nfds,
+ conns.size()));
+ }
+ DENA_VERBOSE(30, fprintf(stderr, "%p in=%zu out=%zu ac=%zu, cns=%zu\n",
+ this, in_count, out_count, accept_count, conns.size()));
+ if (conns.empty()) {
+ dbctx->close_tables_if();
+ }
+ /* STATISTICS */
+ const size_t num_conns = conns.size();
+ dbctx->set_statistics(num_conns, 0);
+ /* ENABLE/DISABLE ACCEPT */
+ if (accept_balance != 0) {
+ cshared.thread_num_conns[worker_id] = num_conns;
+ size_t total_num_conns = 0;
+ for (long i = 0; i < cshared.num_threads; ++i) {
+ total_num_conns += cshared.thread_num_conns[i];
+ }
+ bool e_acc = false;
+ if (num_conns < 10 ||
+ total_num_conns * 2 > num_conns * cshared.num_threads) {
+ e_acc = true;
+ }
+ epoll_event ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.events = EPOLLIN;
+ ev.data.ptr = 0;
+ if (e_acc == accept_enabled) {
+ } else if (e_acc) {
+ if (epoll_ctl(epoll_fd.get(), EPOLL_CTL_ADD, cshared.listen_fd.get(), &ev)
+ != 0) {
+ fatal_abort("epoll_ctl EPOLL_CTL_ADD");
+ }
+ } else {
+ if (epoll_ctl(epoll_fd.get(), EPOLL_CTL_DEL, cshared.listen_fd.get(), &ev)
+ != 0) {
+ fatal_abort("epoll_ctl EPOLL_CTL_ADD");
+ }
+ }
+ accept_enabled = e_acc;
+ }
+ return 0;
+}
+#endif
+
+void
+hstcpsvr_worker::execute_lines(hstcpsvr_conn& conn)
+{
+ DBG_MULTI(int cnt = 0);
+ dbconnstate& cstate = conn.cstate;
+ char *buf_end = cstate.readbuf.end();
+ char *line_begin = cstate.readbuf.begin();
+ char *find_pos = line_begin + cstate.find_nl_pos;
+ while (true) {
+ char *const nl = memchr_char(find_pos, '\n', buf_end - find_pos);
+ if (nl == 0) {
+ break;
+ }
+ char *const lf = (line_begin != nl && nl[-1] == '\r') ? nl - 1 : nl;
+ DBG_MULTI(cnt++);
+ execute_line(line_begin, lf, conn);
+ find_pos = line_begin = nl + 1;
+ }
+ cstate.readbuf.erase_front(line_begin - cstate.readbuf.begin());
+ cstate.find_nl_pos = cstate.readbuf.size();
+ DBG_MULTI(fprintf(stderr, "cnt=%d\n", cnt));
+}
+
+void
+hstcpsvr_worker::execute_line(char *start, char *finish, hstcpsvr_conn& conn)
+{
+ /* safe to modify, safe to dereference 'finish' */
+ char *const cmd_begin = start;
+ read_token(start, finish);
+ char *const cmd_end = start;
+ skip_one(start, finish);
+ if (cmd_begin == cmd_end) {
+ return conn.dbcb_resp_short(2, "cmd");
+ }
+ if (cmd_begin + 1 == cmd_end) {
+ if (cmd_begin[0] == 'P') {
+ if (cshared.require_auth && !conn.authorized) {
+ return conn.dbcb_resp_short(3, "unauth");
+ }
+ return do_open_index(start, finish, conn);
+ }
+ if (cmd_begin[0] == 'A') {
+ return do_authorization(start, finish, conn);
+ }
+ }
+ if (cmd_begin[0] >= '0' && cmd_begin[0] <= '9') {
+ if (cshared.require_auth && !conn.authorized) {
+ return conn.dbcb_resp_short(3, "unauth");
+ }
+ return do_exec_on_index(cmd_begin, cmd_end, start, finish, conn);
+ }
+ return conn.dbcb_resp_short(2, "cmd");
+}
+
+void
+hstcpsvr_worker::do_open_index(char *start, char *finish, hstcpsvr_conn& conn)
+{
+ const size_t pst_id = read_ui32(start, finish);
+ skip_one(start, finish);
+ /* dbname */
+ char *const dbname_begin = start;
+ read_token(start, finish);
+ char *const dbname_end = start;
+ skip_one(start, finish);
+ /* tblname */
+ char *const tblname_begin = start;
+ read_token(start, finish);
+ char *const tblname_end = start;
+ skip_one(start, finish);
+ /* idxname */
+ char *const idxname_begin = start;
+ read_token(start, finish);
+ char *const idxname_end = start;
+ skip_one(start, finish);
+ /* retfields */
+ char *const retflds_begin = start;
+ read_token(start, finish);
+ char *const retflds_end = start;
+ skip_one(start, finish);
+ /* filfields */
+ char *const filflds_begin = start;
+ read_token(start, finish);
+ char *const filflds_end = start;
+ dbname_end[0] = 0;
+ tblname_end[0] = 0;
+ idxname_end[0] = 0;
+ retflds_end[0] = 0;
+ filflds_end[0] = 0;
+ cmd_open_args args;
+ args.pst_id = pst_id;
+ args.dbn = dbname_begin;
+ args.tbl = tblname_begin;
+ args.idx = idxname_begin;
+ args.retflds = retflds_begin;
+ args.filflds = filflds_begin;
+ return dbctx->cmd_open(conn, args);
+}
+
+void
+hstcpsvr_worker::do_exec_on_index(char *cmd_begin, char *cmd_end, char *start,
+ char *finish, hstcpsvr_conn& conn)
+{
+ cmd_exec_args args;
+ const size_t pst_id = read_ui32(cmd_begin, cmd_end);
+ if (pst_id >= conn.cstate.prep_stmts.size()) {
+ return conn.dbcb_resp_short(2, "stmtnum");
+ }
+ args.pst = &conn.cstate.prep_stmts[pst_id];
+ char *const op_begin = start;
+ read_token(start, finish);
+ char *const op_end = start;
+ args.op = string_ref(op_begin, op_end);
+ skip_one(start, finish);
+ const uint32_t fldnum = read_ui32(start, finish);
+ string_ref *const flds = DENA_ALLOCA_ALLOCATE(string_ref, fldnum);
+ auto_alloca_free<string_ref> flds_autofree(flds);
+ args.kvals = flds;
+ args.kvalslen = fldnum;
+ for (size_t i = 0; i < fldnum; ++i) {
+ skip_one(start, finish);
+ char *const f_begin = start;
+ read_token(start, finish);
+ char *const f_end = start;
+ if (is_null_expression(f_begin, f_end)) {
+ /* null */
+ flds[i] = string_ref();
+ } else {
+ /* non-null */
+ char *wp = f_begin;
+ unescape_string(wp, f_begin, f_end);
+ flds[i] = string_ref(f_begin, wp - f_begin);
+ }
+ }
+ skip_one(start, finish);
+ args.limit = read_ui32(start, finish);
+ skip_one(start, finish);
+ args.skip = read_ui32(start, finish);
+ if (start == finish) {
+ /* simple query */
+ return dbctx->cmd_exec(conn, args);
+ }
+ /* has more options */
+ skip_one(start, finish);
+ /* in-clause */
+ if (start[0] == '@') {
+ read_token(start, finish); /* '@' */
+ skip_one(start, finish);
+ args.invalues_keypart = read_ui32(start, finish);
+ skip_one(start, finish);
+ args.invalueslen = read_ui32(start, finish);
+ if (args.invalueslen <= 0) {
+ return conn.dbcb_resp_short(2, "invalueslen");
+ }
+ if (invalues_work.size() < args.invalueslen) {
+ invalues_work.resize(args.invalueslen);
+ }
+ args.invalues = &invalues_work[0];
+ for (uint32_t i = 0; i < args.invalueslen; ++i) {
+ skip_one(start, finish);
+ char *const invalue_begin = start;
+ read_token(start, finish);
+ char *const invalue_end = start;
+ char *wp = invalue_begin;
+ unescape_string(wp, invalue_begin, invalue_end);
+ invalues_work[i] = string_ref(invalue_begin, wp - invalue_begin);
+ }
+ skip_one(start, finish);
+ }
+ if (start == finish) {
+ /* no more options */
+ return dbctx->cmd_exec(conn, args);
+ }
+ /* filters */
+ size_t filters_count = 0;
+ while (start != finish && (start[0] == 'W' || start[0] == 'F')) {
+ char *const filter_type_begin = start;
+ read_token(start, finish);
+ char *const filter_type_end = start;
+ skip_one(start, finish);
+ char *const filter_op_begin = start;
+ read_token(start, finish);
+ char *const filter_op_end = start;
+ skip_one(start, finish);
+ const uint32_t ff_offset = read_ui32(start, finish);
+ skip_one(start, finish);
+ char *const filter_val_begin = start;
+ read_token(start, finish);
+ char *const filter_val_end = start;
+ skip_one(start, finish);
+ if (filters_work.size() <= filters_count) {
+ filters_work.resize(filters_count + 1);
+ }
+ record_filter& fi = filters_work[filters_count];
+ if (filter_type_end != filter_type_begin + 1) {
+ return conn.dbcb_resp_short(2, "filtertype");
+ }
+ fi.filter_type = (filter_type_begin[0] == 'W')
+ ? record_filter_type_break : record_filter_type_skip;
+ const uint32_t num_filflds = args.pst->get_filter_fields().size();
+ if (ff_offset >= num_filflds) {
+ return conn.dbcb_resp_short(2, "filterfld");
+ }
+ fi.op = string_ref(filter_op_begin, filter_op_end);
+ fi.ff_offset = ff_offset;
+ if (is_null_expression(filter_val_begin, filter_val_end)) {
+ /* null */
+ fi.val = string_ref();
+ } else {
+ /* non-null */
+ char *wp = filter_val_begin;
+ unescape_string(wp, filter_val_begin, filter_val_end);
+ fi.val = string_ref(filter_val_begin, wp - filter_val_begin);
+ }
+ ++filters_count;
+ }
+ if (filters_count > 0) {
+ if (filters_work.size() <= filters_count) {
+ filters_work.resize(filters_count + 1);
+ }
+ filters_work[filters_count].op = string_ref(); /* sentinel */
+ args.filters = &filters_work[0];
+ } else {
+ args.filters = 0;
+ }
+ if (start == finish) {
+ /* no modops */
+ return dbctx->cmd_exec(conn, args);
+ }
+ /* has modops */
+ char *const mod_op_begin = start;
+ read_token(start, finish);
+ char *const mod_op_end = start;
+ args.mod_op = string_ref(mod_op_begin, mod_op_end);
+ const size_t num_uvals = args.pst->get_ret_fields().size();
+ string_ref *const uflds = DENA_ALLOCA_ALLOCATE(string_ref, num_uvals);
+ auto_alloca_free<string_ref> uflds_autofree(uflds);
+ for (size_t i = 0; i < num_uvals; ++i) {
+ skip_one(start, finish);
+ char *const f_begin = start;
+ read_token(start, finish);
+ char *const f_end = start;
+ if (is_null_expression(f_begin, f_end)) {
+ /* null */
+ uflds[i] = string_ref();
+ } else {
+ /* non-null */
+ char *wp = f_begin;
+ unescape_string(wp, f_begin, f_end);
+ uflds[i] = string_ref(f_begin, wp - f_begin);
+ }
+ }
+ args.uvals = uflds;
+ return dbctx->cmd_exec(conn, args);
+}
+
+void
+hstcpsvr_worker::do_authorization(char *start, char *finish,
+ hstcpsvr_conn& conn)
+{
+ /* auth type */
+ char *const authtype_begin = start;
+ read_token(start, finish);
+ char *const authtype_end = start;
+ const size_t authtype_len = authtype_end - authtype_begin;
+ skip_one(start, finish);
+ /* key */
+ char *const key_begin = start;
+ read_token(start, finish);
+ char *const key_end = start;
+ const size_t key_len = key_end - key_begin;
+ authtype_end[0] = 0;
+ key_end[0] = 0;
+ char *wp = key_begin;
+ unescape_string(wp, key_begin, key_end);
+ if (authtype_len != 1 || authtype_begin[0] != '1') {
+ return conn.dbcb_resp_short(3, "authtype");
+ }
+ if (cshared.plain_secret.size() == key_len &&
+ memcmp(cshared.plain_secret.data(), key_begin, key_len) == 0) {
+ conn.authorized = true;
+ } else {
+ conn.authorized = false;
+ }
+ if (!conn.authorized) {
+ return conn.dbcb_resp_short(3, "unauth");
+ } else {
+ return conn.dbcb_resp_short(0, "");
+ }
+}
+
+hstcpsvr_worker_ptr
+hstcpsvr_worker_i::create(const hstcpsvr_worker_arg& arg)
+{
+ return hstcpsvr_worker_ptr(new hstcpsvr_worker(arg));
+}
+
+};
+
diff --git a/plugin/handler_socket/handlersocket/hstcpsvr_worker.hpp b/plugin/handler_socket/handlersocket/hstcpsvr_worker.hpp
new file mode 100644
index 00000000000..497581c27a7
--- /dev/null
+++ b/plugin/handler_socket/handlersocket/hstcpsvr_worker.hpp
@@ -0,0 +1,35 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_HSTCPSVR_WORKER_HPP
+#define DENA_HSTCPSVR_WORKER_HPP
+
+#include "hstcpsvr.hpp"
+
+namespace dena {
+
+struct hstcpsvr_worker_i;
+typedef std::auto_ptr<hstcpsvr_worker_i> hstcpsvr_worker_ptr;
+
+struct hstcpsvr_worker_arg {
+ const hstcpsvr_shared_c *cshared;
+ volatile hstcpsvr_shared_v *vshared;
+ long worker_id;
+ hstcpsvr_worker_arg() : cshared(0), vshared(0), worker_id(0) { }
+};
+
+struct hstcpsvr_worker_i {
+ virtual ~hstcpsvr_worker_i() { }
+ virtual void run() = 0;
+ static hstcpsvr_worker_ptr create(const hstcpsvr_worker_arg& arg);
+};
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/handlersocket/mysql_incl.hpp b/plugin/handler_socket/handlersocket/mysql_incl.hpp
new file mode 100644
index 00000000000..d8dba709f28
--- /dev/null
+++ b/plugin/handler_socket/handlersocket/mysql_incl.hpp
@@ -0,0 +1,50 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_MYSQL_INCL_HPP
+#define DENA_MYSQL_INCL_HPP
+
+#ifndef HAVE_CONFIG_H
+#define HAVE_CONFIG_H
+#endif
+
+#define MYSQL_DYNAMIC_PLUGIN
+#define MYSQL_SERVER 1
+
+#include <my_config.h>
+
+#include <mysql_version.h>
+
+#if MYSQL_VERSION_ID >= 50505
+#include <my_pthread.h>
+#include <sql_priv.h>
+#include "sql_class.h"
+#include "unireg.h"
+#include "lock.h"
+#include "key.h" // key_copy()
+#include <my_global.h>
+#include <mysql/plugin.h>
+#include <transaction.h>
+#include <sql_base.h>
+// FIXME FIXME FIXME
+#define safeFree(X) my_free(X)
+#define pthread_cond_timedwait mysql_cond_timedwait
+#define pthread_mutex_lock mysql_mutex_lock
+#define pthread_mutex_unlock mysql_mutex_unlock
+#define current_stmt_binlog_row_based is_current_stmt_binlog_format_row
+#define clear_current_stmt_binlog_row_based clear_current_stmt_binlog_format_row
+
+#else
+#include "mysql_priv.h"
+#endif
+
+#undef min
+#undef max
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/COPYRIGHT.txt b/plugin/handler_socket/libhsclient/COPYRIGHT.txt
new file mode 100644
index 00000000000..41dda1279e2
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/COPYRIGHT.txt
@@ -0,0 +1,27 @@
+
+ Copyright (c) 2010 DeNA Co.,Ltd.
+ 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 above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of DeNA Co.,Ltd. nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY DeNA Co.,Ltd. "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 DeNA Co.,Ltd. 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.
+
diff --git a/plugin/handler_socket/libhsclient/Makefile.am b/plugin/handler_socket/libhsclient/Makefile.am
new file mode 100644
index 00000000000..343b41860b3
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/Makefile.am
@@ -0,0 +1,12 @@
+CXXFLAGS += -fimplicit-templates
+instdir = $(includedir)/handlersocket
+# TODO: these headers should be in dena/
+inst_HEADERS = allocator.hpp config.hpp mutex.hpp string_util.hpp \
+ auto_addrinfo.hpp escape.hpp socket.hpp thread.hpp auto_file.hpp \
+ fatal.hpp string_buffer.hpp util.hpp auto_ptrcontainer.hpp \
+ hstcpcli.hpp string_ref.hpp
+lib_LTLIBRARIES = libhsclient.la
+libhsclient_la_SOURCES = config.cpp escape.cpp fatal.cpp hstcpcli.cpp \
+ socket.cpp string_util.cpp
+libhsclient_la_CFLAGS = $(AM_CFLAGS)
+libhsclient_la_CXXFLAGS = $(AM_CXXFLAGS)
diff --git a/plugin/handler_socket/libhsclient/Makefile.plain b/plugin/handler_socket/libhsclient/Makefile.plain
new file mode 100644
index 00000000000..9e6277b6253
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/Makefile.plain
@@ -0,0 +1,27 @@
+
+CXX = g++ -Wall -g -fno-rtti -fno-exceptions -fPIC -DPIC
+LDFLAGS =
+
+CXXFLAGS += -O3 -DNDEBUG
+
+COMMON_OBJS = config.o fatal.o socket.o string_util.o escape.o
+HSCLIENT_OBJS = $(COMMON_OBJS) hstcpcli.o
+
+all: libhsclient.a
+
+libhsclient.a: $(HSCLIENT_OBJS)
+ $(AR) rc $@ $^
+ $(AR) s $@
+
+clean:
+ rm -f *.a *.so *.o
+
+LIBDIR = $(shell \
+ if [ -e /usr/lib64/mysql ]; then echo /usr/lib64; else echo /usr/lib; fi)
+
+install: libhsclient.a
+ sudo sh -c 'cp libhsclient.a libhsclient.a.cpy && \
+ mv libhsclient.a.cpy $(LIBDIR)/libhsclient.a && \
+ mkdir -p /usr/include/handlersocket && \
+ cp -a *.hpp /usr/include/handlersocket/'
+
diff --git a/plugin/handler_socket/libhsclient/allocator.hpp b/plugin/handler_socket/libhsclient/allocator.hpp
new file mode 100644
index 00000000000..82ff51f00e7
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/allocator.hpp
@@ -0,0 +1,64 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_ALLOCATOR_HPP
+#define DENA_ALLOCATOR_HPP
+
+#include <stdlib.h>
+#include <string.h>
+
+#if 0
+extern "C" {
+#include <tlsf.h>
+};
+#define DENA_MALLOC(x) tlsf_malloc(x)
+#define DENA_REALLOC(x, y) tlsf_realloc(x, y)
+#define DENA_FREE(x) tlsf_free(x)
+#define DENA_NEWCHAR(x) static_cast<char *>(tlsf_malloc(x))
+#define DENA_DELETE(x) tlsf_free(x)
+typedef std::allocator<int> allocator_type;
+#endif
+
+#if 1
+#define DENA_MALLOC(x) malloc(x)
+#define DENA_REALLOC(x, y) realloc(x, y)
+#define DENA_FREE(x) free(x)
+#define DENA_NEWCHAR(x) (new char[x])
+#define DENA_DELETE(x) (delete [] x)
+typedef std::allocator<int> allocator_type;
+#endif
+
+#if 1
+#define DENA_ALLOCA_ALLOCATE(typ, len) \
+ static_cast<typ *>(alloca((len) * sizeof(typ)))
+#define DENA_ALLOCA_FREE(x)
+#else
+#define DENA_ALLOCA_ALLOCATE(typ, len) \
+ static_cast<typ *>(malloc((len) * sizeof(typ)))
+#define DENA_ALLOCA_FREE(x) free(x)
+#endif
+
+namespace dena {
+
+template <typename T> struct auto_alloca_free {
+ auto_alloca_free(T *value) : value(value) { }
+ ~auto_alloca_free() {
+ /* no-op if alloca() is used */
+ DENA_ALLOCA_FREE(value);
+ }
+ private:
+ auto_alloca_free(const auto_alloca_free&);
+ auto_alloca_free& operator =(const auto_alloca_free&);
+ private:
+ T *value;
+};
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/auto_addrinfo.hpp b/plugin/handler_socket/libhsclient/auto_addrinfo.hpp
new file mode 100644
index 00000000000..f0c07060be1
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/auto_addrinfo.hpp
@@ -0,0 +1,52 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_AUTO_ADDRINFO_HPP
+#define DENA_AUTO_ADDRINFO_HPP
+
+#include <my_config.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+#include "util.hpp"
+
+typedef SOCKET_SIZE_TYPE size_socket;
+
+namespace dena {
+
+struct auto_addrinfo : private noncopyable {
+ auto_addrinfo() : addr(0) { }
+ ~auto_addrinfo() {
+ reset();
+ }
+ void reset(addrinfo *a = 0) {
+ if (addr != 0) {
+ freeaddrinfo(addr);
+ }
+ addr = a;
+ }
+ const addrinfo *get() const { return addr; }
+ int resolve(const char *node, const char *service, int flags = 0,
+ int family = AF_UNSPEC, int socktype = SOCK_STREAM, int protocol = 0) {
+ reset();
+ addrinfo hints;
+ hints.ai_flags = flags;
+ hints.ai_family = family;
+ hints.ai_socktype = socktype;
+ hints.ai_protocol = protocol;
+ return getaddrinfo(node, service, &hints, &addr);
+ }
+ private:
+ addrinfo *addr;
+};
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/auto_file.hpp b/plugin/handler_socket/libhsclient/auto_file.hpp
new file mode 100644
index 00000000000..841351e54cd
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/auto_file.hpp
@@ -0,0 +1,64 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_AUTO_FILE_HPP
+#define DENA_AUTO_FILE_HPP
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdio.h>
+
+#include "util.hpp"
+
+namespace dena {
+
+struct auto_file : private noncopyable {
+ auto_file() : fd(-1) { }
+ ~auto_file() {
+ reset();
+ }
+ int get() const { return fd; }
+ int close() {
+ if (fd < 0) {
+ return 0;
+ }
+ const int r = ::close(fd);
+ fd = -1;
+ return r;
+ }
+ void reset(int x = -1) {
+ if (fd >= 0) {
+ this->close();
+ }
+ fd = x;
+ }
+ private:
+ int fd;
+};
+
+struct auto_dir : private noncopyable {
+ auto_dir() : dp(0) { }
+ ~auto_dir() {
+ reset();
+ }
+ DIR *get() const { return dp; }
+ void reset(DIR *d = 0) {
+ if (dp != 0) {
+ closedir(dp);
+ }
+ dp = d;
+ }
+ private:
+ DIR *dp;
+};
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/auto_ptrcontainer.hpp b/plugin/handler_socket/libhsclient/auto_ptrcontainer.hpp
new file mode 100644
index 00000000000..314bc1516ff
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/auto_ptrcontainer.hpp
@@ -0,0 +1,67 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_AUTO_PTRCONTAINER_HPP
+#define DENA_AUTO_PTRCONTAINER_HPP
+
+namespace dena {
+
+template <typename Tcnt>
+struct auto_ptrcontainer {
+ typedef Tcnt container_type;
+ typedef typename container_type::value_type value_type;
+ typedef typename container_type::pointer pointer;
+ typedef typename container_type::reference reference;
+ typedef typename container_type::const_reference const_reference;
+ typedef typename container_type::size_type size_type;
+ typedef typename container_type::difference_type difference_type;
+ typedef typename container_type::iterator iterator;
+ typedef typename container_type::const_iterator const_iterator;
+ typedef typename container_type::reverse_iterator reverse_iterator;
+ typedef typename container_type::const_reverse_iterator
+ const_reverse_iterator;
+ iterator begin() { return cnt.begin(); }
+ const_iterator begin() const { return cnt.begin(); }
+ iterator end() { return cnt.end(); }
+ const_iterator end() const { return cnt.end(); }
+ reverse_iterator rbegin() { return cnt.rbegin(); }
+ reverse_iterator rend() { return cnt.rend(); }
+ const_reverse_iterator rbegin() const { return cnt.rbegin(); }
+ const_reverse_iterator rend() const { return cnt.rend(); }
+ size_type size() const { return cnt.size(); }
+ size_type max_size() const { return cnt.max_size(); }
+ bool empty() const { return cnt.empty(); }
+ reference front() { return cnt.front(); }
+ const_reference front() const { cnt.front(); }
+ reference back() { return cnt.back(); }
+ const_reference back() const { cnt.back(); }
+ void swap(auto_ptrcontainer& x) { cnt.swap(x.cnt); }
+ ~auto_ptrcontainer() {
+ for (iterator i = begin(); i != end(); ++i) {
+ delete *i;
+ }
+ }
+ template <typename Tap> void push_back_ptr(Tap& ap) {
+ cnt.push_back(ap.get());
+ ap.release();
+ }
+ void erase_ptr(iterator i) {
+ delete *i;
+ cnt.erase(i);
+ }
+ reference operator [](size_type n) { return cnt[n]; }
+ const_reference operator [](size_type n) const { return cnt[n]; }
+ void clear() { cnt.clear(); }
+ private:
+ Tcnt cnt;
+};
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/config.cpp b/plugin/handler_socket/libhsclient/config.cpp
new file mode 100644
index 00000000000..3c90b36db44
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/config.cpp
@@ -0,0 +1,67 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "config.hpp"
+
+namespace dena {
+
+unsigned int verbose_level = 0;
+
+std::string
+config::get_str(const std::string& key, const std::string& def) const
+{
+ const_iterator iter = this->find(key);
+ if (iter == this->end()) {
+ DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s(default)\n", key.c_str(),
+ def.c_str()));
+ return def;
+ }
+ DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s\n", key.c_str(),
+ iter->second.c_str()));
+ return iter->second;
+}
+
+long long
+config::get_int(const std::string& key, long long def) const
+{
+ const_iterator iter = this->find(key);
+ if (iter == this->end()) {
+ DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld(default)\n", key.c_str(),
+ def));
+ return def;
+ }
+ const long long r = atoll(iter->second.c_str());
+ DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld\n", key.c_str(), r));
+ return r;
+}
+
+void
+parse_args(int argc, char **argv, config& conf)
+{
+ for (int i = 1; i < argc; ++i) {
+ const char *const arg = argv[i];
+ const char *const eq = strchr(arg, '=');
+ if (eq == 0) {
+ continue;
+ }
+ const std::string key(arg, eq - arg);
+ const std::string val(eq + 1);
+ conf[key] = val;
+ }
+ config::const_iterator iter = conf.find("verbose");
+ if (iter != conf.end()) {
+ verbose_level = atoi(iter->second.c_str());
+ }
+}
+
+};
+
diff --git a/plugin/handler_socket/libhsclient/config.hpp b/plugin/handler_socket/libhsclient/config.hpp
new file mode 100644
index 00000000000..c9f16c76fa9
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/config.hpp
@@ -0,0 +1,32 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_CONFIG_HPP
+#define DENA_CONFIG_HPP
+
+#include <string>
+#include <map>
+
+#define DENA_VERBOSE(lv, x) if (dena::verbose_level >= (lv)) { (x); }
+
+namespace dena {
+
+struct config : public std::map<std::string, std::string> {
+ std::string get_str(const std::string& key, const std::string& def = "")
+ const;
+ long long get_int(const std::string& key, long long def = 0) const;
+};
+
+void parse_args(int argc, char **argv, config& conf);
+
+extern unsigned int verbose_level;
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/escape.cpp b/plugin/handler_socket/libhsclient/escape.cpp
new file mode 100644
index 00000000000..d4df8ae8dd7
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/escape.cpp
@@ -0,0 +1,127 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#include <stdio.h>
+
+#include "escape.hpp"
+#include "string_buffer.hpp"
+#include "fatal.hpp"
+#include "string_util.hpp"
+
+#define DBG_OP(x)
+#define DBG_BUF(x)
+
+namespace dena {
+
+enum special_char_t {
+ special_char_escape_prefix = 0x01, /* SOH */
+ special_char_noescape_min = 0x10, /* DLE */
+ special_char_escape_shift = 0x40, /* '@' */
+};
+
+void
+escape_string(char *& wp, const char *start, const char *finish)
+{
+ while (start != finish) {
+ const unsigned char c = *start;
+ if (c >= special_char_noescape_min) {
+ wp[0] = c; /* no need to escape */
+ } else {
+ wp[0] = special_char_escape_prefix;
+ ++wp;
+ wp[0] = c + special_char_escape_shift;
+ }
+ ++start;
+ ++wp;
+ }
+}
+
+void
+escape_string(string_buffer& ar, const char *start, const char *finish)
+{
+ const size_t buflen = (finish - start) * 2;
+ char *const wp_begin = ar.make_space(buflen);
+ char *wp = wp_begin;
+ escape_string(wp, start, finish);
+ ar.space_wrote(wp - wp_begin);
+}
+
+bool
+unescape_string(char *& wp, const char *start, const char *finish)
+{
+ /* works even if wp == start */
+ while (start != finish) {
+ const unsigned char c = *start;
+ if (c != special_char_escape_prefix) {
+ wp[0] = c;
+ } else if (start + 1 != finish) {
+ ++start;
+ const unsigned char cn = *start;
+ if (cn < special_char_escape_shift) {
+ return false;
+ }
+ wp[0] = cn - special_char_escape_shift;
+ } else {
+ return false;
+ }
+ ++start;
+ ++wp;
+ }
+ return true;
+}
+
+bool
+unescape_string(string_buffer& ar, const char *start, const char *finish)
+{
+ const size_t buflen = finish - start;
+ char *const wp_begin = ar.make_space(buflen);
+ char *wp = wp_begin;
+ const bool r = unescape_string(wp, start, finish);
+ ar.space_wrote(wp - wp_begin);
+ return r;
+}
+
+uint32_t
+read_ui32(char *& start, char *finish)
+{
+ char *const n_begin = start;
+ read_token(start, finish);
+ char *const n_end = start;
+ uint32_t v = 0;
+ for (char *p = n_begin; p != n_end; ++p) {
+ const char ch = p[0];
+ if (ch >= '0' && ch <= '9') {
+ v *= 10;
+ v += (ch - '0');
+ }
+ }
+ return v;
+}
+
+void
+write_ui32(string_buffer& buf, uint32_t v)
+{
+ char *wp = buf.make_space(12);
+ int len = snprintf(wp, 12, "%u", v);
+ if (len > 0) {
+ buf.space_wrote(len);
+ }
+}
+
+void
+write_ui64(string_buffer& buf, uint64_t v)
+{
+ char *wp = buf.make_space(22);
+ int len = snprintf(wp, 22, "%llu", static_cast<unsigned long long>(v));
+ if (len > 0) {
+ buf.space_wrote(len);
+ }
+}
+
+};
+
diff --git a/plugin/handler_socket/libhsclient/escape.hpp b/plugin/handler_socket/libhsclient/escape.hpp
new file mode 100644
index 00000000000..b928defeff6
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/escape.hpp
@@ -0,0 +1,66 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#include <stdint.h>
+
+#include "string_buffer.hpp"
+#include "string_ref.hpp"
+#include "string_util.hpp"
+
+#ifndef DENA_ESCAPE_HPP
+#define DENA_ESCAPE_HPP
+
+namespace dena {
+
+void escape_string(char *& wp, const char *start, const char *finish);
+void escape_string(string_buffer& ar, const char *start, const char *finish);
+bool unescape_string(char *& wp, const char *start, const char *finish);
+ /* unescaped_string() works even if wp == start */
+bool unescape_string(string_buffer& ar, const char *start, const char *finish);
+
+uint32_t read_ui32(char *& start, char *finish);
+void write_ui32(string_buffer& buf, uint32_t v);
+void write_ui64(string_buffer& buf, uint64_t v);
+
+inline bool
+is_null_expression(const char *start, const char *finish)
+{
+ return (finish == start + 1 && start[0] == 0);
+}
+
+inline void
+read_token(char *& start, char *finish)
+{
+ char *const p = memchr_char(start, '\t', finish - start);
+ if (p == 0) {
+ start = finish;
+ } else {
+ start = p;
+ }
+}
+
+inline void
+skip_token_delim_fold(char *& start, char *finish)
+{
+ while (start != finish && start[0] == '\t') {
+ ++start;
+ }
+}
+
+inline void
+skip_one(char *& start, char *finish)
+{
+ if (start != finish) {
+ ++start;
+ }
+}
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/fatal.cpp b/plugin/handler_socket/libhsclient/fatal.cpp
new file mode 100644
index 00000000000..5cdd8879ab1
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/fatal.cpp
@@ -0,0 +1,37 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include "fatal.hpp"
+
+namespace dena {
+
+const int opt_syslog = LOG_ERR | LOG_PID | LOG_CONS;
+
+void
+fatal_exit(const std::string& message)
+{
+ fprintf(stderr, "FATAL_EXIT: %s\n", message.c_str());
+ syslog(opt_syslog, "FATAL_EXIT: %s", message.c_str());
+ _exit(1);
+}
+
+void
+fatal_abort(const std::string& message)
+{
+ fprintf(stderr, "FATAL_COREDUMP: %s\n", message.c_str());
+ syslog(opt_syslog, "FATAL_COREDUMP: %s", message.c_str());
+ abort();
+}
+
+};
+
diff --git a/plugin/handler_socket/libhsclient/fatal.hpp b/plugin/handler_socket/libhsclient/fatal.hpp
new file mode 100644
index 00000000000..8a630fab1cb
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/fatal.hpp
@@ -0,0 +1,22 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_FATAL_HPP
+#define DENA_FATAL_HPP
+
+#include <string>
+
+namespace dena {
+
+void fatal_exit(const std::string& message);
+void fatal_abort(const std::string& message);
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/hstcpcli.cpp b/plugin/handler_socket/libhsclient/hstcpcli.cpp
new file mode 100644
index 00000000000..c0cb5fb1e97
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/hstcpcli.cpp
@@ -0,0 +1,441 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#include <stdexcept>
+
+#include "hstcpcli.hpp"
+#include "auto_file.hpp"
+#include "string_util.hpp"
+#include "auto_addrinfo.hpp"
+#include "escape.hpp"
+#include "util.hpp"
+
+/* TODO */
+#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(MSG_NOSIGNAL)
+#define MSG_NOSIGNAL 0
+#endif
+
+#define DBG(x)
+
+namespace dena {
+
+struct hstcpcli : public hstcpcli_i, private noncopyable {
+ hstcpcli(const socket_args& args);
+ virtual void close();
+ virtual int reconnect();
+ virtual bool stable_point();
+ virtual void request_buf_open_index(size_t pst_id, const char *dbn,
+ const char *tbl, const char *idx, const char *retflds, const char *filflds);
+ virtual void request_buf_auth(const char *secret, const char *typ);
+ virtual void request_buf_exec_generic(size_t pst_id, const string_ref& op,
+ const string_ref *kvs, size_t kvslen, uint32_t limit, uint32_t skip,
+ const string_ref& mod_op, const string_ref *mvs, size_t mvslen,
+ const hstcpcli_filter *fils, size_t filslen, int invalues_keypart,
+ const string_ref *invalues, size_t invalueslen);
+ virtual int request_send();
+ virtual int response_recv(size_t& num_flds_r);
+ virtual const string_ref *get_next_row();
+ virtual void response_buf_remove();
+ virtual int get_error_code();
+ virtual std::string get_error();
+ private:
+ int read_more();
+ void clear_error();
+ int set_error(int code, const std::string& str);
+ private:
+ auto_file fd;
+ socket_args sargs;
+ string_buffer readbuf;
+ string_buffer writebuf;
+ size_t response_end_offset; /* incl newline */
+ size_t cur_row_offset;
+ size_t num_flds;
+ size_t num_req_bufd; /* buffered but not yet sent */
+ size_t num_req_sent; /* sent but not yet received */
+ size_t num_req_rcvd; /* received but not yet removed */
+ int error_code;
+ std::string error_str;
+ std::vector<string_ref> flds;
+};
+
+hstcpcli::hstcpcli(const socket_args& args)
+ : sargs(args), response_end_offset(0), cur_row_offset(0), num_flds(0),
+ num_req_bufd(0), num_req_sent(0), num_req_rcvd(0), error_code(0)
+{
+ std::string err;
+ if (socket_connect(fd, sargs, err) != 0) {
+ set_error(-1, err);
+ }
+}
+
+void
+hstcpcli::close()
+{
+ fd.close();
+ readbuf.clear();
+ writebuf.clear();
+ flds.clear();
+ response_end_offset = 0;
+ cur_row_offset = 0;
+ num_flds = 0;
+ num_req_bufd = 0;
+ num_req_sent = 0;
+ num_req_rcvd = 0;
+}
+
+int
+hstcpcli::reconnect()
+{
+ clear_error();
+ close();
+ std::string err;
+ if (socket_connect(fd, sargs, err) != 0) {
+ set_error(-1, err);
+ }
+ return error_code;
+}
+
+bool
+hstcpcli::stable_point()
+{
+ /* returns true if cli can send a new request */
+ return fd.get() >= 0 && num_req_bufd == 0 && num_req_sent == 0 &&
+ num_req_rcvd == 0 && response_end_offset == 0;
+}
+
+int
+hstcpcli::get_error_code()
+{
+ return error_code;
+}
+
+std::string
+hstcpcli::get_error()
+{
+ return error_str;
+}
+
+int
+hstcpcli::read_more()
+{
+ const size_t block_size = 4096; // FIXME
+ char *const wp = readbuf.make_space(block_size);
+ const ssize_t rlen = read(fd.get(), wp, block_size);
+ if (rlen <= 0) {
+ if (rlen < 0) {
+ error_str = "read: failed";
+ } else {
+ error_str = "read: eof";
+ }
+ return rlen;
+ }
+ readbuf.space_wrote(rlen);
+ return rlen;
+}
+
+void
+hstcpcli::clear_error()
+{
+ DBG(fprintf(stderr, "CLEAR_ERROR: %d\n", error_code));
+ error_code = 0;
+ error_str.clear();
+}
+
+int
+hstcpcli::set_error(int code, const std::string& str)
+{
+ DBG(fprintf(stderr, "SET_ERROR: %d\n", code));
+ error_code = code;
+ error_str = str;
+ return error_code;
+}
+
+void
+hstcpcli::request_buf_open_index(size_t pst_id, const char *dbn,
+ const char *tbl, const char *idx, const char *retflds, const char *filflds)
+{
+ if (num_req_sent > 0 || num_req_rcvd > 0) {
+ close();
+ set_error(-1, "request_buf_open_index: protocol out of sync");
+ return;
+ }
+ const string_ref dbn_ref(dbn, strlen(dbn));
+ const string_ref tbl_ref(tbl, strlen(tbl));
+ const string_ref idx_ref(idx, strlen(idx));
+ const string_ref rfs_ref(retflds, strlen(retflds));
+ writebuf.append_literal("P\t");
+ append_uint32(writebuf, pst_id); // FIXME size_t ?
+ writebuf.append_literal("\t");
+ writebuf.append(dbn_ref.begin(), dbn_ref.end());
+ writebuf.append_literal("\t");
+ writebuf.append(tbl_ref.begin(), tbl_ref.end());
+ writebuf.append_literal("\t");
+ writebuf.append(idx_ref.begin(), idx_ref.end());
+ writebuf.append_literal("\t");
+ writebuf.append(rfs_ref.begin(), rfs_ref.end());
+ if (filflds != 0) {
+ const string_ref fls_ref(filflds, strlen(filflds));
+ writebuf.append_literal("\t");
+ writebuf.append(fls_ref.begin(), fls_ref.end());
+ }
+ writebuf.append_literal("\n");
+ ++num_req_bufd;
+}
+
+void
+hstcpcli::request_buf_auth(const char *secret, const char *typ)
+{
+ if (num_req_sent > 0 || num_req_rcvd > 0) {
+ close();
+ set_error(-1, "request_buf_auth: protocol out of sync");
+ return;
+ }
+ if (typ == 0) {
+ typ = "1";
+ }
+ const string_ref typ_ref(typ, strlen(typ));
+ const string_ref secret_ref(secret, strlen(secret));
+ writebuf.append_literal("A\t");
+ writebuf.append(typ_ref.begin(), typ_ref.end());
+ writebuf.append_literal("\t");
+ writebuf.append(secret_ref.begin(), secret_ref.end());
+ writebuf.append_literal("\n");
+ ++num_req_bufd;
+}
+
+namespace {
+
+void
+append_delim_value(string_buffer& buf, const char *start, const char *finish)
+{
+ if (start == 0) {
+ /* null */
+ const char t[] = "\t\0";
+ buf.append(t, t + 2);
+ } else {
+ /* non-null */
+ buf.append_literal("\t");
+ escape_string(buf, start, finish);
+ }
+}
+
+};
+
+void
+hstcpcli::request_buf_exec_generic(size_t pst_id, const string_ref& op,
+ const string_ref *kvs, size_t kvslen, uint32_t limit, uint32_t skip,
+ const string_ref& mod_op, const string_ref *mvs, size_t mvslen,
+ const hstcpcli_filter *fils, size_t filslen, int invalues_keypart,
+ const string_ref *invalues, size_t invalueslen)
+{
+ if (num_req_sent > 0 || num_req_rcvd > 0) {
+ close();
+ set_error(-1, "request_buf_exec_generic: protocol out of sync");
+ return;
+ }
+ append_uint32(writebuf, pst_id); // FIXME size_t ?
+ writebuf.append_literal("\t");
+ writebuf.append(op.begin(), op.end());
+ writebuf.append_literal("\t");
+ append_uint32(writebuf, kvslen); // FIXME size_t ?
+ for (size_t i = 0; i < kvslen; ++i) {
+ const string_ref& kv = kvs[i];
+ append_delim_value(writebuf, kv.begin(), kv.end());
+ }
+ if (limit != 0 || skip != 0 || invalues_keypart >= 0 ||
+ mod_op.size() != 0 || filslen != 0) {
+ /* has more option */
+ writebuf.append_literal("\t");
+ append_uint32(writebuf, limit); // FIXME size_t ?
+ if (skip != 0 || invalues_keypart >= 0 ||
+ mod_op.size() != 0 || filslen != 0) {
+ writebuf.append_literal("\t");
+ append_uint32(writebuf, skip); // FIXME size_t ?
+ }
+ if (invalues_keypart >= 0) {
+ writebuf.append_literal("\t@\t");
+ append_uint32(writebuf, invalues_keypart);
+ writebuf.append_literal("\t");
+ append_uint32(writebuf, invalueslen);
+ for (size_t i = 0; i < invalueslen; ++i) {
+ const string_ref& s = invalues[i];
+ append_delim_value(writebuf, s.begin(), s.end());
+ }
+ }
+ for (size_t i = 0; i < filslen; ++i) {
+ const hstcpcli_filter& f = fils[i];
+ writebuf.append_literal("\t");
+ writebuf.append(f.filter_type.begin(), f.filter_type.end());
+ writebuf.append_literal("\t");
+ writebuf.append(f.op.begin(), f.op.end());
+ writebuf.append_literal("\t");
+ append_uint32(writebuf, f.ff_offset);
+ append_delim_value(writebuf, f.val.begin(), f.val.end());
+ }
+ if (mod_op.size() != 0) {
+ writebuf.append_literal("\t");
+ writebuf.append(mod_op.begin(), mod_op.end());
+ for (size_t i = 0; i < mvslen; ++i) {
+ const string_ref& mv = mvs[i];
+ append_delim_value(writebuf, mv.begin(), mv.end());
+ }
+ }
+ }
+ writebuf.append_literal("\n");
+ ++num_req_bufd;
+}
+
+int
+hstcpcli::request_send()
+{
+ if (error_code < 0) {
+ return error_code;
+ }
+ clear_error();
+ if (fd.get() < 0) {
+ close();
+ return set_error(-1, "write: closed");
+ }
+ if (num_req_bufd == 0 || num_req_sent > 0 || num_req_rcvd > 0) {
+ close();
+ return set_error(-1, "request_send: protocol out of sync");
+ }
+ const size_t wrlen = writebuf.size();
+ const ssize_t r = send(fd.get(), writebuf.begin(), wrlen, MSG_NOSIGNAL);
+ if (r <= 0) {
+ close();
+ return set_error(-1, r < 0 ? "write: failed" : "write: eof");
+ }
+ writebuf.erase_front(r);
+ if (static_cast<size_t>(r) != wrlen) {
+ close();
+ return set_error(-1, "write: incomplete");
+ }
+ num_req_sent = num_req_bufd;
+ num_req_bufd = 0;
+ DBG(fprintf(stderr, "REQSEND 0\n"));
+ return 0;
+}
+
+int
+hstcpcli::response_recv(size_t& num_flds_r)
+{
+ if (error_code < 0) {
+ return error_code;
+ }
+ clear_error();
+ if (num_req_bufd > 0 || num_req_sent == 0 || num_req_rcvd > 0 ||
+ response_end_offset != 0) {
+ close();
+ return set_error(-1, "response_recv: protocol out of sync");
+ }
+ cur_row_offset = 0;
+ num_flds_r = num_flds = 0;
+ if (fd.get() < 0) {
+ return set_error(-1, "read: closed");
+ }
+ size_t offset = 0;
+ while (true) {
+ const char *const lbegin = readbuf.begin() + offset;
+ const char *const lend = readbuf.end();
+ const char *const nl = memchr_char(lbegin, '\n', lend - lbegin);
+ if (nl != 0) {
+ offset = (nl + 1) - readbuf.begin();
+ break;
+ }
+ if (read_more() <= 0) {
+ close();
+ return set_error(-1, "read: eof");
+ }
+ }
+ response_end_offset = offset;
+ --num_req_sent;
+ ++num_req_rcvd;
+ char *start = readbuf.begin();
+ char *const finish = start + response_end_offset - 1;
+ const size_t resp_code = read_ui32(start, finish);
+ skip_one(start, finish);
+ num_flds_r = num_flds = read_ui32(start, finish);
+ if (resp_code != 0) {
+ skip_one(start, finish);
+ char *const err_begin = start;
+ read_token(start, finish);
+ char *const err_end = start;
+ std::string e = std::string(err_begin, err_end - err_begin);
+ if (e.empty()) {
+ e = "unknown_error";
+ }
+ return set_error(resp_code, e);
+ }
+ cur_row_offset = start - readbuf.begin();
+ DBG(fprintf(stderr, "[%s] ro=%zu eol=%zu\n",
+ std::string(readbuf.begin(), readbuf.begin() + response_end_offset)
+ .c_str(),
+ cur_row_offset, response_end_offset));
+ DBG(fprintf(stderr, "RES 0\n"));
+ return 0;
+}
+
+const string_ref *
+hstcpcli::get_next_row()
+{
+ if (num_flds == 0) {
+ DBG(fprintf(stderr, "GNR NF 0\n"));
+ return 0;
+ }
+ if (flds.size() < num_flds) {
+ flds.resize(num_flds);
+ }
+ char *start = readbuf.begin() + cur_row_offset;
+ char *const finish = readbuf.begin() + response_end_offset - 1;
+ if (start >= finish) { /* start[0] == nl */
+ DBG(fprintf(stderr, "GNR FIN 0 %p %p\n", start, finish));
+ return 0;
+ }
+ for (size_t i = 0; i < num_flds; ++i) {
+ skip_one(start, finish);
+ char *const fld_begin = start;
+ read_token(start, finish);
+ char *const fld_end = start;
+ char *wp = fld_begin;
+ if (is_null_expression(fld_begin, fld_end)) {
+ /* null */
+ flds[i] = string_ref();
+ } else {
+ unescape_string(wp, fld_begin, fld_end); /* in-place */
+ flds[i] = string_ref(fld_begin, wp);
+ }
+ }
+ cur_row_offset = start - readbuf.begin();
+ return &flds[0];
+}
+
+void
+hstcpcli::response_buf_remove()
+{
+ if (response_end_offset == 0) {
+ close();
+ set_error(-1, "response_buf_remove: protocol out of sync");
+ return;
+ }
+ readbuf.erase_front(response_end_offset);
+ response_end_offset = 0;
+ --num_req_rcvd;
+ cur_row_offset = 0;
+ num_flds = 0;
+ flds.clear();
+}
+
+hstcpcli_ptr
+hstcpcli_i::create(const socket_args& args)
+{
+ return hstcpcli_ptr(new hstcpcli(args));
+}
+
+};
+
diff --git a/plugin/handler_socket/libhsclient/hstcpcli.hpp b/plugin/handler_socket/libhsclient/hstcpcli.hpp
new file mode 100644
index 00000000000..11dec8ebb0b
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/hstcpcli.hpp
@@ -0,0 +1,62 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_HSTCPCLI_HPP
+#define DENA_HSTCPCLI_HPP
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string>
+#include <memory>
+
+#include "config.hpp"
+#include "socket.hpp"
+#include "string_ref.hpp"
+#include "string_buffer.hpp"
+
+namespace dena {
+
+struct hstcpcli_filter {
+ string_ref filter_type;
+ string_ref op;
+ size_t ff_offset;
+ string_ref val;
+ hstcpcli_filter() : ff_offset(0) { }
+};
+
+struct hstcpcli_i;
+typedef std::auto_ptr<hstcpcli_i> hstcpcli_ptr;
+
+struct hstcpcli_i {
+ virtual ~hstcpcli_i() { }
+ virtual void close() = 0;
+ virtual int reconnect() = 0;
+ virtual bool stable_point() = 0;
+ virtual void request_buf_auth(const char *secret, const char *typ) = 0;
+ virtual void request_buf_open_index(size_t pst_id, const char *dbn,
+ const char *tbl, const char *idx, const char *retflds,
+ const char *filflds = 0) = 0;
+ virtual void request_buf_exec_generic(size_t pst_id, const string_ref& op,
+ const string_ref *kvs, size_t kvslen, uint32_t limit, uint32_t skip,
+ const string_ref& mod_op, const string_ref *mvs, size_t mvslen,
+ const hstcpcli_filter *fils = 0, size_t filslen = 0,
+ int invalues_keypart = -1, const string_ref *invalues = 0,
+ size_t invalueslen = 0) = 0; // FIXME: too long
+ virtual int request_send() = 0;
+ virtual int response_recv(size_t& num_flds_r) = 0;
+ virtual const string_ref *get_next_row() = 0;
+ virtual void response_buf_remove() = 0;
+ virtual int get_error_code() = 0;
+ virtual std::string get_error() = 0;
+ static hstcpcli_ptr create(const socket_args& args);
+};
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/libhsclient.spec.template b/plugin/handler_socket/libhsclient/libhsclient.spec.template
new file mode 100644
index 00000000000..3e4dfe04c25
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/libhsclient.spec.template
@@ -0,0 +1,39 @@
+Summary: handlersocket client library
+Name: libhsclient
+Version: HANDLERSOCKET_VERSION
+Release: 1%{?dist}
+Group: System Environment/Libraries
+License: BSD
+Source: libhsclient.tar.gz
+Packager: Akira Higuchi <higuchi dot akira at dena dot jp>
+BuildRoot: /var/tmp/%{name}-%{version}-root
+
+%description
+
+%prep
+%setup -n %{name}
+
+%define _use_internal_dependency_generator 0
+
+%build
+make -f Makefile.plain
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT/usr/include/handlersocket
+mkdir -p $RPM_BUILD_ROOT/%{_bindir}
+mkdir -p $RPM_BUILD_ROOT/%{_libdir}
+install -m 755 libhsclient.a $RPM_BUILD_ROOT/%{_libdir}
+install -m 644 *.hpp $RPM_BUILD_ROOT/usr/include/handlersocket/
+
+%post
+/sbin/ldconfig
+
+%postun
+/sbin/ldconfig
+
+%files
+%defattr(-, root, root)
+/usr/include/*
+%{_libdir}/*.a
+
diff --git a/plugin/handler_socket/libhsclient/mutex.hpp b/plugin/handler_socket/libhsclient/mutex.hpp
new file mode 100644
index 00000000000..9cef2757f21
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/mutex.hpp
@@ -0,0 +1,51 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_MUTEX_HPP
+#define DENA_MUTEX_HPP
+
+#include <pthread.h>
+#include <stdlib.h>
+
+#include "fatal.hpp"
+#include "util.hpp"
+
+namespace dena {
+
+struct condition;
+
+struct mutex : private noncopyable {
+ friend struct condition;
+ mutex() {
+ if (pthread_mutex_init(&mtx, 0) != 0) {
+ fatal_abort("pthread_mutex_init");
+ }
+ }
+ ~mutex() {
+ if (pthread_mutex_destroy(&mtx) != 0) {
+ fatal_abort("pthread_mutex_destroy");
+ }
+ }
+ void lock() const {
+ if (pthread_mutex_lock(&mtx) != 0) {
+ fatal_abort("pthread_mutex_lock");
+ }
+ }
+ void unlock() const {
+ if (pthread_mutex_unlock(&mtx) != 0) {
+ fatal_abort("pthread_mutex_unlock");
+ }
+ }
+ private:
+ mutable pthread_mutex_t mtx;
+};
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/socket.cpp b/plugin/handler_socket/libhsclient/socket.cpp
new file mode 100644
index 00000000000..0c4816589fa
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/socket.cpp
@@ -0,0 +1,186 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#include <stdexcept>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/un.h>
+
+#include "socket.hpp"
+#include "string_util.hpp"
+#include "fatal.hpp"
+
+namespace dena {
+
+void
+ignore_sigpipe()
+{
+ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
+ fatal_abort("SIGPIPE SIG_IGN");
+ }
+}
+
+void
+socket_args::set(const config& conf)
+{
+ timeout = conf.get_int("timeout", 600);
+ listen_backlog = conf.get_int("listen_backlog", 256);
+ std::string node = conf.get_str("host", "");
+ std::string port = conf.get_str("port", "");
+ if (!node.empty() || !port.empty()) {
+ if (family == AF_UNIX || node == "/") {
+ set_unix_domain(port.c_str());
+ } else {
+ const char *nd = node.empty() ? 0 : node.c_str();
+ if (resolve(nd, port.c_str()) != 0) {
+ fatal_exit("getaddrinfo failed: " + node + ":" + port);
+ }
+ }
+ }
+ sndbuf = conf.get_int("sndbuf", 0);
+ rcvbuf = conf.get_int("rcvbuf", 0);
+}
+
+void
+socket_args::set_unix_domain(const char *path)
+{
+ family = AF_UNIX;
+ addr = sockaddr_storage();
+ addrlen = sizeof(sockaddr_un);
+ sockaddr_un *const ap = reinterpret_cast<sockaddr_un *>(&addr);
+ ap->sun_family = AF_UNIX;
+ strncpy(ap->sun_path, path, sizeof(ap->sun_path) - 1);
+}
+
+int
+socket_args::resolve(const char *node, const char *service)
+{
+ const int flags = (node == 0) ? AI_PASSIVE : 0;
+ auto_addrinfo ai;
+ addr = sockaddr_storage();
+ addrlen = 0;
+ const int r = ai.resolve(node, service, flags, family, socktype, protocol);
+ if (r != 0) {
+ return r;
+ }
+ memcpy(&addr, ai.get()->ai_addr, ai.get()->ai_addrlen);
+ addrlen = ai.get()->ai_addrlen;
+ return 0;
+}
+
+int
+socket_set_options(auto_file& fd, const socket_args& args, std::string& err_r)
+{
+ if (args.timeout != 0 && !args.nonblocking) {
+ struct timeval tv;
+ tv.tv_sec = args.timeout;
+ tv.tv_usec = 0;
+ if (setsockopt(fd.get(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) != 0) {
+ return errno_string("setsockopt SO_RCVTIMEO", errno, err_r);
+ }
+ tv.tv_sec = args.timeout;
+ tv.tv_usec = 0;
+ if (setsockopt(fd.get(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) != 0) {
+ return errno_string("setsockopt SO_RCVTIMEO", errno, err_r);
+ }
+ }
+ if (args.nonblocking && fcntl(fd.get(), F_SETFL, O_NONBLOCK) != 0) {
+ return errno_string("fcntl O_NONBLOCK", errno, err_r);
+ }
+ if (args.sndbuf != 0) {
+ const int v = args.sndbuf;
+ if (setsockopt(fd.get(), SOL_SOCKET, SO_SNDBUF, &v, sizeof(v)) != 0) {
+ return errno_string("setsockopt SO_SNDBUF", errno, err_r);
+ }
+ }
+ if (args.rcvbuf != 0) {
+ const int v = args.rcvbuf;
+ if (setsockopt(fd.get(), SOL_SOCKET, SO_RCVBUF, &v, sizeof(v)) != 0) {
+ return errno_string("setsockopt SO_RCVBUF", errno, err_r);
+ }
+ }
+ return 0;
+}
+
+int
+socket_open(auto_file& fd, const socket_args& args, std::string& err_r)
+{
+ fd.reset(socket(args.family, args.socktype, args.protocol));
+ if (fd.get() < 0) {
+ return errno_string("socket", errno, err_r);
+ }
+ return socket_set_options(fd, args, err_r);
+}
+
+int
+socket_connect(auto_file& fd, const socket_args& args, std::string& err_r)
+{
+ int r = 0;
+ if ((r = socket_open(fd, args, err_r)) != 0) {
+ return r;
+ }
+ if (connect(fd.get(), reinterpret_cast<const sockaddr *>(&args.addr),
+ args.addrlen) != 0) {
+ if (!args.nonblocking || errno != EINPROGRESS) {
+ return errno_string("connect", errno, err_r);
+ }
+ }
+ return 0;
+}
+
+int
+socket_bind(auto_file& fd, const socket_args& args, std::string& err_r)
+{
+ fd.reset(socket(args.family, args.socktype, args.protocol));
+ if (fd.get() < 0) {
+ return errno_string("socket", errno, err_r);
+ }
+ if (args.reuseaddr) {
+ if (args.family == AF_UNIX) {
+ const sockaddr_un *const ap =
+ reinterpret_cast<const sockaddr_un *>(&args.addr);
+ if (unlink(ap->sun_path) != 0 && errno != ENOENT) {
+ return errno_string("unlink uds", errno, err_r);
+ }
+ } else {
+ int v = 1;
+ if (setsockopt(fd.get(), SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v)) != 0) {
+ return errno_string("setsockopt SO_REUSEADDR", errno, err_r);
+ }
+ }
+ }
+ if (bind(fd.get(), reinterpret_cast<const sockaddr *>(&args.addr),
+ args.addrlen) != 0) {
+ return errno_string("bind", errno, err_r);
+ }
+ if (listen(fd.get(), args.listen_backlog) != 0) {
+ return errno_string("listen", errno, err_r);
+ }
+ if (args.nonblocking && fcntl(fd.get(), F_SETFL, O_NONBLOCK) != 0) {
+ return errno_string("fcntl O_NONBLOCK", errno, err_r);
+ }
+ return 0;
+}
+
+int
+socket_accept(int listen_fd, auto_file& fd, const socket_args& args,
+ sockaddr_storage& addr_r, size_socket& addrlen_r, std::string& err_r)
+{
+ fd.reset(accept(listen_fd, reinterpret_cast<sockaddr *>(&addr_r),
+ &addrlen_r));
+ if (fd.get() < 0) {
+ return errno_string("accept", errno, err_r);
+ }
+ return socket_set_options(fd, args, err_r);
+}
+
+};
+
diff --git a/plugin/handler_socket/libhsclient/socket.hpp b/plugin/handler_socket/libhsclient/socket.hpp
new file mode 100644
index 00000000000..c6e638c9c01
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/socket.hpp
@@ -0,0 +1,51 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_SOCKET_HPP
+#define DENA_SOCKET_HPP
+
+#include <string>
+
+#include "auto_addrinfo.hpp"
+#include "auto_file.hpp"
+#include "config.hpp"
+
+namespace dena {
+
+struct socket_args {
+ sockaddr_storage addr;
+ size_socket addrlen;
+ int family;
+ int socktype;
+ int protocol;
+ int timeout;
+ int listen_backlog;
+ bool reuseaddr;
+ bool nonblocking;
+ bool use_epoll;
+ int sndbuf;
+ int rcvbuf;
+ socket_args() : addr(), addrlen(0), family(AF_INET), socktype(SOCK_STREAM),
+ protocol(0), timeout(600), listen_backlog(256),
+ reuseaddr(true), nonblocking(false), use_epoll(false),
+ sndbuf(0), rcvbuf(0) { }
+ void set(const config& conf);
+ void set_unix_domain(const char *path);
+ int resolve(const char *node, const char *service);
+};
+
+void ignore_sigpipe();
+int socket_bind(auto_file& fd, const socket_args& args, std::string& err_r);
+int socket_connect(auto_file& fd, const socket_args& args, std::string& err_r);
+int socket_accept(int listen_fd, auto_file& fd, const socket_args& args,
+ sockaddr_storage& addr_r, size_socket& addrlen_r, std::string& err_r);
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/string_buffer.hpp b/plugin/handler_socket/libhsclient/string_buffer.hpp
new file mode 100644
index 00000000000..708c0df30a4
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/string_buffer.hpp
@@ -0,0 +1,118 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_STRING_BUFFER_HPP
+#define DENA_STRING_BUFFER_HPP
+
+#include <vector>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.hpp"
+#include "allocator.hpp"
+#include "fatal.hpp"
+
+namespace dena {
+
+struct string_buffer : private noncopyable {
+ string_buffer() : buffer(0), begin_offset(0), end_offset(0), alloc_size(0) { }
+ ~string_buffer() {
+ DENA_FREE(buffer);
+ }
+ const char *begin() const {
+ return buffer + begin_offset;
+ }
+ const char *end() const {
+ return buffer + end_offset;
+ }
+ char *begin() {
+ return buffer + begin_offset;
+ }
+ char *end() {
+ return buffer + end_offset;
+ }
+ size_t size() const {
+ return end_offset - begin_offset;
+ }
+ void clear() {
+ begin_offset = end_offset = 0;
+ }
+ void resize(size_t len) {
+ if (size() < len) {
+ reserve(len);
+ memset(buffer + end_offset, 0, len - size());
+ }
+ end_offset = begin_offset + len;
+ }
+ void reserve(size_t len) {
+ if (alloc_size >= begin_offset + len) {
+ return;
+ }
+ size_t asz = alloc_size;
+ while (asz < begin_offset + len) {
+ if (asz == 0) {
+ asz = 16;
+ }
+ const size_t asz_n = asz << 1;
+ if (asz_n < asz) {
+ fatal_abort("string_buffer::resize() overflow");
+ }
+ asz = asz_n;
+ }
+ void *const p = DENA_REALLOC(buffer, asz);
+ if (p == 0) {
+ fatal_abort("string_buffer::resize() realloc");
+ }
+ buffer = static_cast<char *>(p);
+ alloc_size = asz;
+ }
+ void erase_front(size_t len) {
+ if (len >= size()) {
+ clear();
+ } else {
+ begin_offset += len;
+ }
+ }
+ char *make_space(size_t len) {
+ reserve(size() + len);
+ return buffer + end_offset;
+ }
+ void space_wrote(size_t len) {
+ len = std::min(len, alloc_size - end_offset);
+ end_offset += len;
+ }
+ template <size_t N>
+ void append_literal(const char (& str)[N]) {
+ append(str, str + N - 1);
+ }
+ void append(const char *start, const char *finish) {
+ const size_t len = finish - start;
+ reserve(size() + len);
+ memcpy(buffer + end_offset, start, len);
+ end_offset += len;
+ }
+ void append_2(const char *s1, const char *f1, const char *s2,
+ const char *f2) {
+ const size_t l1 = f1 - s1;
+ const size_t l2 = f2 - s2;
+ reserve(end_offset + l1 + l2);
+ memcpy(buffer + end_offset, s1, l1);
+ memcpy(buffer + end_offset + l1, s2, l2);
+ end_offset += l1 + l2;
+ }
+ private:
+ char *buffer;
+ size_t begin_offset;
+ size_t end_offset;
+ size_t alloc_size;
+};
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/string_ref.hpp b/plugin/handler_socket/libhsclient/string_ref.hpp
new file mode 100644
index 00000000000..c5f93065228
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/string_ref.hpp
@@ -0,0 +1,63 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_STRING_REF_HPP
+#define DENA_STRING_REF_HPP
+
+#include <vector>
+#include <string.h>
+
+namespace dena {
+
+struct string_wref {
+ typedef char value_type;
+ char *begin() const { return start; }
+ char *end() const { return start + length; }
+ size_t size() const { return length; }
+ private:
+ char *start;
+ size_t length;
+ public:
+ string_wref(char *s = 0, size_t len = 0) : start(s), length(len) { }
+};
+
+struct string_ref {
+ typedef const char value_type;
+ const char *begin() const { return start; }
+ const char *end() const { return start + length; }
+ size_t size() const { return length; }
+ private:
+ const char *start;
+ size_t length;
+ public:
+ string_ref(const char *s = 0, size_t len = 0) : start(s), length(len) { }
+ string_ref(const char *s, const char *f) : start(s), length(f - s) { }
+ string_ref(const string_wref& w) : start(w.begin()), length(w.size()) { }
+};
+
+template <size_t N> inline bool
+operator ==(const string_ref& x, const char (& y)[N]) {
+ return (x.size() == N - 1) && (::memcmp(x.begin(), y, N - 1) == 0);
+}
+
+inline bool
+operator ==(const string_ref& x, const string_ref& y) {
+ return (x.size() == y.size()) &&
+ (::memcmp(x.begin(), y.begin(), x.size()) == 0);
+}
+
+inline bool
+operator !=(const string_ref& x, const string_ref& y) {
+ return (x.size() != y.size()) ||
+ (::memcmp(x.begin(), y.begin(), x.size()) != 0);
+}
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/string_util.cpp b/plugin/handler_socket/libhsclient/string_util.cpp
new file mode 100644
index 00000000000..8ee6000f3d0
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/string_util.cpp
@@ -0,0 +1,182 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "string_util.hpp"
+
+namespace dena {
+
+string_wref
+get_token(char *& wp, char *wp_end, char delim)
+{
+ char *const wp_begin = wp;
+ char *const p = memchr_char(wp_begin, delim, wp_end - wp_begin);
+ if (p == 0) {
+ wp = wp_end;
+ return string_wref(wp_begin, wp_end - wp_begin);
+ }
+ wp = p + 1;
+ return string_wref(wp_begin, p - wp_begin);
+}
+
+template <typename T> T
+atoi_tmpl_nocheck(const char *start, const char *finish)
+{
+ T v = 0;
+ for (; start != finish; ++start) {
+ const char c = *start;
+ if (c < '0' || c > '9') {
+ break;
+ }
+ v *= 10;
+ v += static_cast<T>(c - '0');
+ }
+ return v;
+}
+
+template <typename T> T
+atoi_signed_tmpl_nocheck(const char *start, const char *finish)
+{
+ T v = 0;
+ bool negative = false;
+ if (start != finish) {
+ if (start[0] == '-') {
+ ++start;
+ negative = true;
+ } else if (start[0] == '+') {
+ ++start;
+ }
+ }
+ for (; start != finish; ++start) {
+ const char c = *start;
+ if (c < '0' || c > '9') {
+ break;
+ }
+ v *= 10;
+ if (negative) {
+ v -= static_cast<T>(c - '0');
+ } else {
+ v += static_cast<T>(c - '0');
+ }
+ }
+ return v;
+}
+
+uint32_t
+atoi_uint32_nocheck(const char *start, const char *finish)
+{
+ return atoi_tmpl_nocheck<uint32_t>(start, finish);
+}
+
+long long
+atoll_nocheck(const char *start, const char *finish)
+{
+ return atoi_signed_tmpl_nocheck<long long>(start, finish);
+}
+
+void
+append_uint32(string_buffer& buf, uint32_t v)
+{
+ char *const wp = buf.make_space(64);
+ const int len = snprintf(wp, 64, "%lu", static_cast<unsigned long>(v));
+ if (len > 0) {
+ buf.space_wrote(len);
+ }
+}
+
+std::string
+to_stdstring(uint32_t v)
+{
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%lu", static_cast<unsigned long>(v));
+ return std::string(buf);
+}
+
+int
+errno_string(const char *s, int en, std::string& err_r)
+{
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%s: %d", s, en);
+ err_r = std::string(buf);
+ return en;
+}
+
+template <typename T> size_t
+split_tmpl_arr(char delim, const T& buf, T *parts, size_t parts_len)
+{
+ typedef typename T::value_type value_type;
+ size_t i = 0;
+ value_type *start = buf.begin();
+ value_type *const finish = buf.end();
+ for (i = 0; i < parts_len; ++i) {
+ value_type *const p = memchr_char(start, delim, finish - start);
+ if (p == 0) {
+ parts[i] = T(start, finish - start);
+ ++i;
+ break;
+ }
+ parts[i] = T(start, p - start);
+ start = p + 1;
+ }
+ const size_t r = i;
+ for (; i < parts_len; ++i) {
+ parts[i] = T();
+ }
+ return r;
+}
+
+size_t
+split(char delim, const string_ref& buf, string_ref *parts,
+ size_t parts_len)
+{
+ return split_tmpl_arr(delim, buf, parts, parts_len);
+}
+
+size_t
+split(char delim, const string_wref& buf, string_wref *parts,
+ size_t parts_len)
+{
+ return split_tmpl_arr(delim, buf, parts, parts_len);
+}
+
+template <typename T, typename V> size_t
+split_tmpl_vec(char delim, const T& buf, V& parts)
+{
+ typedef typename T::value_type value_type;
+ size_t i = 0;
+ value_type *start = buf.begin();
+ value_type *const finish = buf.end();
+ while (true) {
+ value_type *const p = memchr_char(start, delim, finish - start);
+ if (p == 0) {
+ parts.push_back(T(start, finish - start));
+ break;
+ }
+ parts.push_back(T(start, p - start));
+ start = p + 1;
+ }
+ const size_t r = i;
+ return r;
+}
+
+size_t
+split(char delim, const string_ref& buf, std::vector<string_ref>& parts_r)
+{
+ return split_tmpl_vec(delim, buf, parts_r);
+}
+
+size_t
+split(char delim, const string_wref& buf, std::vector<string_wref>& parts_r)
+{
+ return split_tmpl_vec(delim, buf, parts_r);
+}
+
+};
+
diff --git a/plugin/handler_socket/libhsclient/string_util.hpp b/plugin/handler_socket/libhsclient/string_util.hpp
new file mode 100644
index 00000000000..45cc5b00c87
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/string_util.hpp
@@ -0,0 +1,53 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_STRING_UTIL_HPP
+#define DENA_STRING_UTIL_HPP
+
+#include <string>
+#include <string.h>
+#include <stdint.h>
+
+#include "string_buffer.hpp"
+#include "string_ref.hpp"
+
+namespace dena {
+
+inline const char *
+memchr_char(const char *s, int c, size_t n)
+{
+ return static_cast<const char *>(memchr(s, c, n));
+}
+
+inline char *
+memchr_char(char *s, int c, size_t n)
+{
+ return static_cast<char *>(memchr(s, c, n));
+}
+
+string_wref get_token(char *& wp, char *wp_end, char delim);
+uint32_t atoi_uint32_nocheck(const char *start, const char *finish);
+std::string to_stdstring(uint32_t v);
+void append_uint32(string_buffer& buf, uint32_t v);
+long long atoll_nocheck(const char *start, const char *finish);
+
+int errno_string(const char *s, int en, std::string& err_r);
+
+size_t split(char delim, const string_ref& buf, string_ref *parts,
+ size_t parts_len);
+size_t split(char delim, const string_wref& buf, string_wref *parts,
+ size_t parts_len);
+size_t split(char delim, const string_ref& buf,
+ std::vector<string_ref>& parts_r);
+size_t split(char delim, const string_wref& buf,
+ std::vector<string_wref>& parts_r);
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/thread.hpp b/plugin/handler_socket/libhsclient/thread.hpp
new file mode 100644
index 00000000000..8a43655427f
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/thread.hpp
@@ -0,0 +1,84 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_THREAD_HPP
+#define DENA_THREAD_HPP
+
+#include <stdexcept>
+#include <pthread.h>
+
+#include "fatal.hpp"
+
+namespace dena {
+
+template <typename T>
+struct thread : private noncopyable {
+ template <typename Ta> thread(const Ta& arg, size_t stack_sz = 256 * 1024)
+ : obj(arg), thr(0), need_join(false), stack_size(stack_sz) { }
+ template <typename Ta0, typename Ta1> thread(const Ta0& a0,
+ volatile Ta1& a1, size_t stack_sz = 256 * 1024)
+ : obj(a0, a1), thr(0), need_join(false), stack_size(stack_sz) { }
+ ~thread() {
+ join();
+ }
+ void start() {
+ if (!start_nothrow()) {
+ fatal_abort("thread::start");
+ }
+ }
+ bool start_nothrow() {
+ if (need_join) {
+ return need_join; /* true */
+ }
+ void *const arg = this;
+ pthread_attr_t attr;
+ if (pthread_attr_init(&attr) != 0) {
+ fatal_abort("pthread_attr_init");
+ }
+ if (pthread_attr_setstacksize(&attr, stack_size) != 0) {
+ fatal_abort("pthread_attr_setstacksize");
+ }
+ const int r = pthread_create(&thr, &attr, thread_main, arg);
+ if (pthread_attr_destroy(&attr) != 0) {
+ fatal_abort("pthread_attr_destroy");
+ }
+ if (r != 0) {
+ return need_join; /* false */
+ }
+ need_join = true;
+ return need_join; /* true */
+ }
+ void join() {
+ if (!need_join) {
+ return;
+ }
+ int e = 0;
+ if ((e = pthread_join(thr, 0)) != 0) {
+ fatal_abort("pthread_join");
+ }
+ need_join = false;
+ }
+ T& operator *() { return obj; }
+ T *operator ->() { return &obj; }
+ private:
+ static void *thread_main(void *arg) {
+ thread *p = static_cast<thread *>(arg);
+ p->obj();
+ return 0;
+ }
+ private:
+ T obj;
+ pthread_t thr;
+ bool need_join;
+ size_t stack_size;
+};
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/libhsclient/util.hpp b/plugin/handler_socket/libhsclient/util.hpp
new file mode 100644
index 00000000000..93d78cc7dc0
--- /dev/null
+++ b/plugin/handler_socket/libhsclient/util.hpp
@@ -0,0 +1,25 @@
+
+// vim:sw=2:ai
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#ifndef DENA_UTIL_HPP
+#define DENA_UTIL_HPP
+
+namespace dena {
+
+/* boost::noncopyable */
+struct noncopyable {
+ noncopyable() { }
+ private:
+ noncopyable(const noncopyable&);
+ noncopyable& operator =(const noncopyable&);
+};
+
+};
+
+#endif
+
diff --git a/plugin/handler_socket/misc/microbench-hs.log b/plugin/handler_socket/misc/microbench-hs.log
new file mode 100644
index 00000000000..9fffe12e3fd
--- /dev/null
+++ b/plugin/handler_socket/misc/microbench-hs.log
@@ -0,0 +1,130 @@
+[a@c54hdd libhsclient]$ ./hstest_hs.sh host=192.168.100.104 key_mask=1000000 num_threads=100 num=10000000 timelimit=10 dbname=hstest
+now: 1274127653 cntdiff: 265538 tdiff: 1.000996 rps: 265273.757409
+now: 1274127654 cntdiff: 265762 tdiff: 1.000995 rps: 265497.850684
+now: 1274127655 cntdiff: 265435 tdiff: 1.001010 rps: 265167.196749
+now: 1274127656 cntdiff: 265144 tdiff: 1.000994 rps: 264880.654203
+now: 1274127657 cntdiff: 265593 tdiff: 1.000995 rps: 265329.018659
+now: 1274127658 cntdiff: 264863 tdiff: 1.000996 rps: 264599.492138
+now: 1274127659 cntdiff: 265688 tdiff: 1.001008 rps: 265420.447231
+now: 1274127660 cntdiff: 265727 tdiff: 1.000999 rps: 265461.810594
+now: 1274127661 cntdiff: 265848 tdiff: 1.001010 rps: 265579.716809
+now: 1274127662 cntdiff: 265430 tdiff: 1.000992 rps: 265167.001723
+now: 1274127663 cntdiff: 266379 tdiff: 1.001008 rps: 266110.751381
+now: 1274127664 cntdiff: 266244 tdiff: 1.001003 rps: 265977.217679
+now: 1274127665 cntdiff: 265737 tdiff: 1.000996 rps: 265472.559379
+now: 1274127666 cntdiff: 265878 tdiff: 1.001003 rps: 265611.647683
+(1274127656.104648: 1328292, 1274127666.114649: 3985679), 265473.20173 qps
+
+
+*************************** 1. row ***************************
+ Type: InnoDB
+ Name:
+Status:
+=====================================
+100518 5:18:13 INNODB MONITOR OUTPUT
+=====================================
+Per second averages calculated from the last 5 seconds
+----------
+BACKGROUND THREAD
+----------
+srv_master_thread loops: 191 1_second, 190 sleeps, 18 10_second, 5 background, 5 flush
+srv_master_thread log flush and writes: 190
+----------
+SEMAPHORES
+----------
+OS WAIT ARRAY INFO: reservation count 53519, signal count 29547
+Mutex spin waits 3083488, rounds 5159906, OS waits 50700
+RW-shared spins 21, OS waits 16; RW-excl spins 1, OS waits 4
+Spin rounds per wait: 1.67 mutex, 30.00 RW-shared, 151.00 RW-excl
+------------
+TRANSACTIONS
+------------
+Trx id counter EDA36085
+Purge done for trx's n:o < EC1F94A7 undo n:o < 0
+History list length 20
+LIST OF TRANSACTIONS FOR EACH SESSION:
+---TRANSACTION 0, not started, process no 4533, OS thread id 1079281984
+MySQL thread id 11, query id 16 localhost root
+show engine innodb status
+---TRANSACTION ED9D5959, not started, process no 4533, OS thread id 1089849664
+MySQL thread id 7, query id 0 handlersocket: mode=rd, 0 conns, 0 active
+---TRANSACTION ED9D5956, not started, process no 4533, OS thread id 1238796608
+MySQL thread id 1, query id 0 handlersocket: mode=rd, 0 conns, 0 active
+---TRANSACTION EDA36084, not started, process no 4533, OS thread id 1255582016
+mysql tables in use 1, locked 1
+MySQL thread id 3, query id 0 handlersocket: mode=rd, 12 conns, 7 active
+---TRANSACTION EDA36080, not started, process no 4533, OS thread id 1247189312
+mysql tables in use 1, locked 1
+MySQL thread id 2, query id 0 handlersocket: mode=rd, 36 conns, 18 active
+---TRANSACTION EDA36082, ACTIVE 0 sec, process no 4533, OS thread id 1263974720 committing
+MySQL thread id 4, query id 0 handlersocket: mode=rd, 37 conns, 20 active
+Trx read view will not see trx with id >= EDA36083, sees < EDA3607D
+---TRANSACTION EDA3607D, ACTIVE 0 sec, process no 4533, OS thread id 1272367424, thread declared inside InnoDB 500
+mysql tables in use 1, locked 1
+MySQL thread id 5, query id 0 handlersocket: mode=rd, 15 conns, 9 active
+Trx read view will not see trx with id >= EDA3607E, sees < EDA36079
+--------
+FILE I/O
+--------
+I/O thread 0 state: waiting for i/o request (insert buffer thread)
+I/O thread 1 state: waiting for i/o request (log thread)
+I/O thread 2 state: waiting for i/o request (read thread)
+I/O thread 3 state: waiting for i/o request (read thread)
+I/O thread 4 state: waiting for i/o request (read thread)
+I/O thread 5 state: waiting for i/o request (read thread)
+I/O thread 6 state: waiting for i/o request (write thread)
+I/O thread 7 state: waiting for i/o request (write thread)
+I/O thread 8 state: waiting for i/o request (write thread)
+I/O thread 9 state: waiting for i/o request (write thread)
+Pending normal aio reads: 0, aio writes: 0,
+ ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
+Pending flushes (fsync) log: 0; buffer pool: 0
+71 OS file reads, 235 OS file writes, 235 OS fsyncs
+0.00 reads/s, 0 avg bytes/read, 1.00 writes/s, 1.00 fsyncs/s
+-------------------------------------
+INSERT BUFFER AND ADAPTIVE HASH INDEX
+-------------------------------------
+Ibuf: size 1, free list len 0, seg size 2,
+0 inserts, 0 merged recs, 0 merges
+Hash table size 12750011, node heap has 2 buffer(s)
+267203.76 hash searches/s, 0.00 non-hash searches/s
+---
+LOG
+---
+Log sequence number 147179727377
+Log flushed up to 147179726685
+Last checkpoint at 147179716475
+0 pending log writes, 0 pending chkp writes
+194 log i/o's done, 1.00 log i/o's/second
+----------------------
+BUFFER POOL AND MEMORY
+----------------------
+Total memory allocated 6587154432; in additional pool allocated 0
+Dictionary memory allocated 33640
+Buffer pool size 393216
+Free buffers 393154
+Database pages 60
+Old database pages 0
+Modified db pages 1
+Pending reads 0
+Pending writes: LRU 0, flush list 0, single page 0
+Pages made young 0, not young 0
+0.00 youngs/s, 0.00 non-youngs/s
+Pages read 60, created 0, written 23
+0.00 reads/s, 0.00 creates/s, 0.00 writes/s
+Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
+Pages read ahead 0.00/s, evicted without access 0.00/s
+LRU len: 60, unzip_LRU len: 0
+I/O sum[0]:cur[0], unzip sum[0]:cur[0]
+--------------
+ROW OPERATIONS
+--------------
+2 queries inside InnoDB, 0 queries in queue
+3 read views open inside InnoDB
+Main thread process no. 4533, id 1230403904, state: sleeping
+Number of rows inserted 0, updated 0, deleted 0, read 37653556
+0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 266608.28 reads/s
+----------------------------
+END OF INNODB MONITOR OUTPUT
+============================
+
diff --git a/plugin/handler_socket/misc/microbench-my.log b/plugin/handler_socket/misc/microbench-my.log
new file mode 100644
index 00000000000..2477af8a791
--- /dev/null
+++ b/plugin/handler_socket/misc/microbench-my.log
@@ -0,0 +1,125 @@
+
+[a@c54hdd libhsclient]$ ./hstest_my.sh host=192.168.100.104 key_mask=1000000 num_threads=100 num=10000000 timelimit=10 dbname=hstest
+now: 1274128046 cntdiff: 63061 tdiff: 1.000999 rps: 62998.066579
+now: 1274128047 cntdiff: 61227 tdiff: 1.001013 rps: 61165.037337
+now: 1274128048 cntdiff: 61367 tdiff: 1.001029 rps: 61303.917375
+now: 1274128049 cntdiff: 61959 tdiff: 1.000962 rps: 61899.451554
+now: 1274128050 cntdiff: 62176 tdiff: 1.001006 rps: 62113.520756
+now: 1274128051 cntdiff: 61367 tdiff: 1.000998 rps: 61305.815559
+now: 1274128052 cntdiff: 61644 tdiff: 1.001015 rps: 61581.497988
+now: 1274128053 cntdiff: 60659 tdiff: 1.000984 rps: 60599.373036
+now: 1274128054 cntdiff: 59459 tdiff: 1.000996 rps: 59399.831067
+now: 1274128055 cntdiff: 62310 tdiff: 1.001011 rps: 62247.074757
+now: 1274128056 cntdiff: 61947 tdiff: 1.000991 rps: 61885.664744
+now: 1274128057 cntdiff: 60675 tdiff: 1.001006 rps: 60614.029076
+now: 1274128058 cntdiff: 60312 tdiff: 1.001001 rps: 60251.680861
+now: 1274128059 cntdiff: 60290 tdiff: 1.001004 rps: 60229.530717
+(1274128049.309634: 309654, 1274128059.319648: 920493), 61022.79143 qps
+
+*************************** 1. row ***************************
+ Type: InnoDB
+ Name:
+Status:
+=====================================
+100518 5:24:51 INNODB MONITOR OUTPUT
+=====================================
+Per second averages calculated from the last 5 seconds
+----------
+BACKGROUND THREAD
+----------
+srv_master_thread loops: 220 1_second, 219 sleeps, 21 10_second, 6 background, 6 flush
+srv_master_thread log flush and writes: 219
+----------
+SEMAPHORES
+----------
+OS WAIT ARRAY INFO: reservation count 56193, signal count 30826
+Mutex spin waits 3415153, rounds 5618661, OS waits 53251
+RW-shared spins 24, OS waits 17; RW-excl spins 1, OS waits 5
+Spin rounds per wait: 1.65 mutex, 30.00 RW-shared, 181.00 RW-excl
+------------
+TRANSACTIONS
+------------
+Trx id counter EDB514D6
+Purge done for trx's n:o < EC1F94A7 undo n:o < 0
+History list length 20
+LIST OF TRANSACTIONS FOR EACH SESSION:
+---TRANSACTION 0, not started, process no 4533, OS thread id 1306585408
+MySQL thread id 113, query id 920620 localhost root
+show engine innodb status
+---TRANSACTION EDA708BB, not started, process no 4533, OS thread id 1272367424
+MySQL thread id 5, query id 0 handlersocket: mode=rd, 0 conns, 0 active
+---TRANSACTION ED9D5959, not started, process no 4533, OS thread id 1089849664
+MySQL thread id 7, query id 0 handlersocket: mode=rd, 0 conns, 0 active
+---TRANSACTION ED9D5956, not started, process no 4533, OS thread id 1238796608
+MySQL thread id 1, query id 0 handlersocket: mode=rd, 0 conns, 0 active
+---TRANSACTION EDA708BD, not started, process no 4533, OS thread id 1255582016
+MySQL thread id 3, query id 0 handlersocket: mode=rd, 0 conns, 0 active
+---TRANSACTION EDA708BF, not started, process no 4533, OS thread id 1247189312
+MySQL thread id 2, query id 0 handlersocket: mode=rd, 0 conns, 0 active
+---TRANSACTION EDA708BE, not started, process no 4533, OS thread id 1263974720
+MySQL thread id 4, query id 0 handlersocket: mode=rd, 0 conns, 0 active
+--------
+FILE I/O
+--------
+I/O thread 0 state: waiting for i/o request (insert buffer thread)
+I/O thread 1 state: waiting for i/o request (log thread)
+I/O thread 2 state: waiting for i/o request (read thread)
+I/O thread 3 state: waiting for i/o request (read thread)
+I/O thread 4 state: waiting for i/o request (read thread)
+I/O thread 5 state: waiting for i/o request (read thread)
+I/O thread 6 state: waiting for i/o request (write thread)
+I/O thread 7 state: waiting for i/o request (write thread)
+I/O thread 8 state: waiting for i/o request (write thread)
+I/O thread 9 state: waiting for i/o request (write thread)
+Pending normal aio reads: 0, aio writes: 0,
+ ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
+Pending flushes (fsync) log: 0; buffer pool: 0
+71 OS file reads, 269 OS file writes, 269 OS fsyncs
+0.00 reads/s, 0 avg bytes/read, 2.40 writes/s, 2.40 fsyncs/s
+-------------------------------------
+INSERT BUFFER AND ADAPTIVE HASH INDEX
+-------------------------------------
+Ibuf: size 1, free list len 0, seg size 2,
+0 inserts, 0 merged recs, 0 merges
+Hash table size 12750011, node heap has 2 buffer(s)
+65739.45 hash searches/s, 0.00 non-hash searches/s
+---
+LOG
+---
+Log sequence number 147179774153
+Log flushed up to 147179771813
+Last checkpoint at 147179761899
+0 pending log writes, 0 pending chkp writes
+220 log i/o's done, 1.60 log i/o's/second
+----------------------
+BUFFER POOL AND MEMORY
+----------------------
+Total memory allocated 6587154432; in additional pool allocated 0
+Dictionary memory allocated 33640
+Buffer pool size 393216
+Free buffers 393154
+Database pages 60
+Old database pages 0
+Modified db pages 1
+Pending reads 0
+Pending writes: LRU 0, flush list 0, single page 0
+Pages made young 0, not young 0
+0.00 youngs/s, 0.00 non-youngs/s
+Pages read 60, created 0, written 27
+0.00 reads/s, 0.00 creates/s, 0.40 writes/s
+Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
+Pages read ahead 0.00/s, evicted without access 0.00/s
+LRU len: 60, unzip_LRU len: 0
+I/O sum[0]:cur[0], unzip sum[0]:cur[0]
+--------------
+ROW OPERATIONS
+--------------
+0 queries inside InnoDB, 0 queries in queue
+1 read views open inside InnoDB
+Main thread process no. 4533, id 1230403904, state: sleeping
+Number of rows inserted 0, updated 0, deleted 0, read 40071920
+0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 66321.54 reads/s
+----------------------------
+END OF INNODB MONITOR OUTPUT
+============================
+
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/COPYRIGHT.txt b/plugin/handler_socket/perl-Net-HandlerSocket/COPYRIGHT.txt
new file mode 100644
index 00000000000..41dda1279e2
--- /dev/null
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/COPYRIGHT.txt
@@ -0,0 +1,27 @@
+
+ Copyright (c) 2010 DeNA Co.,Ltd.
+ 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 above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of DeNA Co.,Ltd. nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY DeNA Co.,Ltd. "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 DeNA Co.,Ltd. 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.
+
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/Changes b/plugin/handler_socket/perl-Net-HandlerSocket/Changes
new file mode 100644
index 00000000000..7ed1e0192d4
--- /dev/null
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/Changes
@@ -0,0 +1,6 @@
+Revision history for Perl extension HandlerSocket.
+
+0.01 Wed Mar 31 11:50:23 2010
+ - original version; created by h2xs 1.23 with options
+ -A -n HandlerSocket
+
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/HandlerSocket.xs b/plugin/handler_socket/perl-Net-HandlerSocket/HandlerSocket.xs
new file mode 100644
index 00000000000..8e8d2520337
--- /dev/null
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/HandlerSocket.xs
@@ -0,0 +1,637 @@
+
+// vim:ai:sw=2:ts=8
+
+/*
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ * See COPYRIGHT.txt for details.
+ */
+
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include "ppport.h"
+
+/*
+ below we'll include (indirectly) my_global.h, which defines
+ VERSION too. Undefine our VERSION here.
+*/
+#undef VERSION
+#include "hstcpcli.hpp"
+
+#define DBG(x)
+
+static SV *
+arr_get_entry(AV *av, I32 avmax, I32 idx)
+{
+ if (idx > avmax) {
+ DBG(fprintf(stderr, "arr_get_entry1 %d %d\n", avmax, idx));
+ return 0;
+ }
+ SV **const ev = av_fetch(av, idx, 0);
+ if (ev == 0) {
+ DBG(fprintf(stderr, "arr_get_entry2 %d %d\n", avmax, idx));
+ return 0;
+ }
+ return *ev;
+}
+
+static int
+arr_get_intval(AV *av, I32 avmax, I32 idx, int default_val = 0)
+{
+ SV *const e = arr_get_entry(av, avmax, idx);
+ if (e == 0) {
+ return default_val;
+ }
+ return SvIV(e);
+}
+
+static const char *
+sv_get_strval(SV *sv)
+{
+ if (sv == 0 || !SvPOK(sv)) {
+ DBG(fprintf(stderr, "sv_get_strval\n"));
+ return 0;
+ }
+ return SvPV_nolen(sv);
+}
+
+static const char *
+arr_get_strval(AV *av, I32 avmax, I32 idx)
+{
+ SV *const e = arr_get_entry(av, avmax, idx);
+ return sv_get_strval(e);
+}
+
+static AV *
+sv_get_arrval(SV *sv)
+{
+ if (sv == 0 || !SvROK(sv)) {
+ DBG(fprintf(stderr, "sv_get_arrval1\n"));
+ return 0;
+ }
+ SV *const svtarget = SvRV(sv);
+ if (svtarget == 0 || SvTYPE(svtarget) != SVt_PVAV) {
+ DBG(fprintf(stderr, "sv_get_arrval2\n"));
+ return 0;
+ }
+ return (AV *)svtarget;
+}
+
+static AV *
+arr_get_arrval(AV *av, I32 avmax, I32 idx)
+{
+ SV *const e = arr_get_entry(av, avmax, idx);
+ if (e == 0) {
+ DBG(fprintf(stderr, "arr_get_arrval1\n"));
+ return 0;
+ }
+ return sv_get_arrval(e);
+}
+
+static void
+hv_to_strmap(HV *hv, std::map<std::string, std::string>& m_r)
+{
+ if (hv == 0) {
+ return;
+ }
+ hv_iterinit(hv);
+ HE *hent = 0;
+ while ((hent = hv_iternext(hv)) != 0) {
+ I32 klen = 0;
+ char *const k = hv_iterkey(hent, &klen);
+ DBG(fprintf(stderr, "k=%s\n", k));
+ const std::string key(k, klen);
+ SV *const vsv = hv_iterval(hv, hent);
+ STRLEN vlen = 0;
+ char *const v = SvPV(vsv, vlen);
+ DBG(fprintf(stderr, "v=%s\n", v));
+ const std::string val(v, vlen);
+ m_r[key] = val;
+ }
+}
+
+static void
+strrefarr_push_back(std::vector<dena::string_ref>& a_r, SV *sv)
+{
+ if (sv == 0 || SvTYPE(sv) == SVt_NULL) { /* !SvPOK()? */
+ DBG(fprintf(stderr, "strrefarr_push_back: null\n"));
+ return a_r.push_back(dena::string_ref());
+ }
+ STRLEN vlen = 0;
+ char *const v = SvPV(sv, vlen);
+ DBG(fprintf(stderr, "strrefarr_push_back: %s\n", v));
+ a_r.push_back(dena::string_ref(v, vlen));
+}
+
+static void
+av_to_strrefarr(AV *av, std::vector<dena::string_ref>& a_r)
+{
+ if (av == 0) {
+ return;
+ }
+ const I32 len = av_len(av) + 1;
+ for (I32 i = 0; i < len; ++i) {
+ SV **const ev = av_fetch(av, i, 0);
+ strrefarr_push_back(a_r, ev ? *ev : 0);
+ }
+}
+
+static dena::string_ref
+sv_get_string_ref(SV *sv)
+{
+ if (sv == 0 || SvTYPE(sv) == SVt_NULL) { /* !SvPOK()? */
+ return dena::string_ref();
+ }
+ STRLEN vlen = 0;
+ char *const v = SvPV(sv, vlen);
+ return dena::string_ref(v, vlen);
+}
+
+static IV
+sv_get_iv(SV *sv)
+{
+ if (sv == 0 || !SvIOK(sv)) {
+ return 0;
+ }
+ return SvIV(sv);
+}
+
+static void
+av_to_filters(AV *av, std::vector<dena::hstcpcli_filter>& f_r)
+{
+ DBG(fprintf(stderr, "av_to_filters: %p\n", av));
+ if (av == 0) {
+ return;
+ }
+ const I32 len = av_len(av) + 1;
+ DBG(fprintf(stderr, "av_to_filters: len=%d\n", (int)len));
+ for (I32 i = 0; i < len; ++i) {
+ AV *const earr = arr_get_arrval(av, len, i);
+ if (earr == 0) {
+ continue;
+ }
+ const I32 earrlen = av_len(earr) + 1;
+ dena::hstcpcli_filter fe;
+ fe.filter_type = sv_get_string_ref(arr_get_entry(earr, earrlen, 0));
+ fe.op = sv_get_string_ref(arr_get_entry(earr, earrlen, 1));
+ fe.ff_offset = sv_get_iv(arr_get_entry(earr, earrlen, 2));
+ fe.val = sv_get_string_ref(arr_get_entry(earr, earrlen, 3));
+ f_r.push_back(fe);
+ DBG(fprintf(stderr, "av_to_filters: %s %s %d %s\n",
+ fe.filter_action.begin(), fe.filter_op.begin(), (int)fe.ff_offset,
+ fe.value.begin()));
+ }
+}
+
+static void
+set_process_verbose_level(const std::map<std::string, std::string>& m)
+{
+ std::map<std::string, std::string>::const_iterator iter = m.find("verbose");
+ if (iter != m.end()) {
+ dena::verbose_level = atoi(iter->second.c_str());
+ }
+}
+
+static AV *
+execute_internal(SV *obj, int id, const char *op, AV *keys, int limit,
+ int skip, const char *modop, AV *modvals, AV *filters, int invalues_keypart,
+ AV *invalues)
+{
+ AV *retval = (AV *)&PL_sv_undef;
+ dena::hstcpcli_i *const ptr =
+ reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
+ do {
+ std::vector<dena::string_ref> keyarr, mvarr;
+ std::vector<dena::hstcpcli_filter> farr;
+ std::vector<dena::string_ref> ivs;
+ av_to_strrefarr(keys, keyarr);
+ dena::string_ref modop_ref;
+ if (modop != 0) {
+ modop_ref = dena::string_ref(modop, strlen(modop));
+ av_to_strrefarr(modvals, mvarr);
+ }
+ if (filters != 0) {
+ av_to_filters(filters, farr);
+ }
+ if (invalues_keypart >= 0 && invalues != 0) {
+ av_to_strrefarr(invalues, ivs);
+ }
+ ptr->request_buf_exec_generic(id, dena::string_ref(op, strlen(op)),
+ &keyarr[0], keyarr.size(), limit, skip, modop_ref, &mvarr[0],
+ mvarr.size(), &farr[0], farr.size(), invalues_keypart, &ivs[0],
+ ivs.size());
+ AV *const av = newAV();
+ retval = av;
+ if (ptr->request_send() != 0) {
+ break;
+ }
+ size_t nflds = 0;
+ ptr->response_recv(nflds);
+ const int e = ptr->get_error_code();
+ DBG(fprintf(stderr, "e=%d nflds=%zu\n", e, nflds));
+ av_push(av, newSViv(e));
+ if (e != 0) {
+ const std::string s = ptr->get_error();
+ av_push(av, newSVpvn(s.data(), s.size()));
+ } else {
+ const dena::string_ref *row = 0;
+ while ((row = ptr->get_next_row()) != 0) {
+ DBG(fprintf(stderr, "row=%p\n", row));
+ for (size_t i = 0; i < nflds; ++i) {
+ const dena::string_ref& v = row[i];
+ DBG(fprintf(stderr, "FLD %zu v=%s vbegin=%p\n", i,
+ std::string(v.begin(), v.size())
+ .c_str(), v.begin()));
+ if (v.begin() != 0) {
+ SV *const e = newSVpvn(
+ v.begin(), v.size());
+ av_push(av, e);
+ } else {
+ av_push(av, &PL_sv_undef);
+ }
+ }
+ }
+ }
+ if (e >= 0) {
+ ptr->response_buf_remove();
+ }
+ } while (0);
+ return retval;
+}
+
+struct execute_arg {
+ int id;
+ const char *op;
+ AV *keys;
+ int limit;
+ int skip;
+ const char *modop;
+ AV *modvals;
+ AV *filters;
+ int invalues_keypart;
+ AV *invalues;
+ execute_arg() : id(0), op(0), keys(0), limit(0), skip(0), modop(0),
+ modvals(0), filters(0), invalues_keypart(-1), invalues(0) { }
+};
+
+static AV *
+execute_multi_internal(SV *obj, const execute_arg *args, size_t num_args)
+{
+ dena::hstcpcli_i *const ptr =
+ reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
+ /* appends multiple requests to the send buffer */
+ for (size_t i = 0; i < num_args; ++i) {
+ std::vector<dena::string_ref> keyarr, mvarr;
+ std::vector<dena::hstcpcli_filter> farr;
+ std::vector<dena::string_ref> ivs;
+ const execute_arg& arg = args[i];
+ av_to_strrefarr(arg.keys, keyarr);
+ dena::string_ref modop_ref;
+ if (arg.modop != 0) {
+ modop_ref = dena::string_ref(arg.modop, strlen(arg.modop));
+ av_to_strrefarr(arg.modvals, mvarr);
+ }
+ if (arg.filters != 0) {
+ av_to_filters(arg.filters, farr);
+ }
+ if (arg.invalues_keypart >= 0 && arg.invalues != 0) {
+ av_to_strrefarr(arg.invalues, ivs);
+ }
+ ptr->request_buf_exec_generic(arg.id,
+ dena::string_ref(arg.op, strlen(arg.op)), &keyarr[0], keyarr.size(),
+ arg.limit, arg.skip, modop_ref, &mvarr[0], mvarr.size(), &farr[0],
+ farr.size(), arg.invalues_keypart, &ivs[0], ivs.size());
+ }
+ AV *const retval = newAV();
+ /* sends the requests */
+ if (ptr->request_send() < 0) {
+ /* IO error */
+ AV *const av_respent = newAV();
+ av_push(retval, newRV_noinc((SV *)av_respent));
+ av_push(av_respent, newSViv(ptr->get_error_code()));
+ const std::string& s = ptr->get_error();
+ av_push(av_respent, newSVpvn(s.data(), s.size()));
+ return retval; /* retval : [ [ err_code, err_message ] ] */
+ }
+ /* receives responses */
+ for (size_t i = 0; i < num_args; ++i) {
+ AV *const av_respent = newAV();
+ av_push(retval, newRV_noinc((SV *)av_respent));
+ size_t nflds = 0;
+ const int e = ptr->response_recv(nflds);
+ av_push(av_respent, newSViv(e));
+ if (e != 0) {
+ const std::string& s = ptr->get_error();
+ av_push(av_respent, newSVpvn(s.data(), s.size()));
+ } else {
+ const dena::string_ref *row = 0;
+ while ((row = ptr->get_next_row()) != 0) {
+ for (size_t i = 0; i < nflds; ++i) {
+ const dena::string_ref& v = row[i];
+ DBG(fprintf(stderr, "%zu %s\n", i,
+ std::string(v.begin(), v.size()).c_str()));
+ if (v.begin() != 0) {
+ av_push(av_respent, newSVpvn(v.begin(), v.size()));
+ } else {
+ /* null */
+ av_push(av_respent, &PL_sv_undef);
+ }
+ }
+ }
+ }
+ if (e >= 0) {
+ ptr->response_buf_remove();
+ }
+ if (e < 0) {
+ return retval;
+ }
+ }
+ return retval;
+}
+
+MODULE = Net::HandlerSocket PACKAGE = Net::HandlerSocket
+
+SV *
+new(klass, args)
+ char *klass
+ HV *args
+CODE:
+ RETVAL = &PL_sv_undef;
+ dena::config conf;
+ hv_to_strmap(args, conf);
+ set_process_verbose_level(conf);
+ dena::socket_args sargs;
+ sargs.set(conf);
+ dena::hstcpcli_ptr p = dena::hstcpcli_i::create(sargs);
+ SV *const objref = newSViv(0);
+ SV *const obj = newSVrv(objref, klass);
+ dena::hstcpcli_i *const ptr = p.get();
+ sv_setiv(obj, reinterpret_cast<IV>(ptr));
+ p.release();
+ SvREADONLY_on(obj);
+ RETVAL = objref;
+OUTPUT:
+ RETVAL
+
+void
+DESTROY(obj)
+ SV *obj
+CODE:
+ dena::hstcpcli_i *const ptr =
+ reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
+ delete ptr;
+
+void
+close(obj)
+ SV *obj
+CODE:
+ dena::hstcpcli_i *const ptr =
+ reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
+ ptr->close();
+
+int
+reconnect(obj)
+ SV *obj
+CODE:
+ RETVAL = 0;
+ dena::hstcpcli_i *const ptr =
+ reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
+ RETVAL = ptr->reconnect();
+OUTPUT:
+ RETVAL
+
+int
+stable_point(obj)
+ SV *obj
+CODE:
+ RETVAL = 0;
+ dena::hstcpcli_i *const ptr =
+ reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
+ const bool rv = ptr->stable_point();
+ RETVAL = static_cast<int>(rv);
+OUTPUT:
+ RETVAL
+
+int
+get_error_code(obj)
+ SV *obj
+CODE:
+ RETVAL = 0;
+ dena::hstcpcli_i *const ptr =
+ reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
+ RETVAL = ptr->get_error_code();
+OUTPUT:
+ RETVAL
+
+SV *
+get_error(obj)
+ SV *obj
+CODE:
+ RETVAL = &PL_sv_undef;
+ dena::hstcpcli_i *const ptr =
+ reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
+ const std::string s = ptr->get_error();
+ RETVAL = newSVpvn(s.data(), s.size());
+OUTPUT:
+ RETVAL
+
+int
+auth(obj, key, typ = 0)
+ SV *obj
+ const char *key
+ const char *typ
+CODE:
+ RETVAL = 0;
+ dena::hstcpcli_i *const ptr =
+ reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
+ do {
+ ptr->request_buf_auth(key, typ);
+ if (ptr->request_send() != 0) {
+ break;
+ }
+ size_t nflds = 0;
+ ptr->response_recv(nflds);
+ const int e = ptr->get_error_code();
+ DBG(fprintf(stderr, "errcode=%d\n", ptr->get_error_code()));
+ if (e >= 0) {
+ ptr->response_buf_remove();
+ }
+ DBG(fprintf(stderr, "errcode=%d\n", ptr->get_error_code()));
+ } while (0);
+ RETVAL = ptr->get_error_code();
+OUTPUT:
+ RETVAL
+
+
+int
+open_index(obj, id, db, table, index, fields, ffields = 0)
+ SV *obj
+ int id
+ const char *db
+ const char *table
+ const char *index
+ const char *fields
+ SV *ffields
+CODE:
+ const char *const ffields_str = sv_get_strval(ffields);
+ RETVAL = 0;
+ dena::hstcpcli_i *const ptr =
+ reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
+ do {
+ ptr->request_buf_open_index(id, db, table, index, fields, ffields_str);
+ if (ptr->request_send() != 0) {
+ break;
+ }
+ size_t nflds = 0;
+ ptr->response_recv(nflds);
+ const int e = ptr->get_error_code();
+ DBG(fprintf(stderr, "errcode=%d\n", ptr->get_error_code()));
+ if (e >= 0) {
+ ptr->response_buf_remove();
+ }
+ DBG(fprintf(stderr, "errcode=%d\n", ptr->get_error_code()));
+ } while (0);
+ RETVAL = ptr->get_error_code();
+OUTPUT:
+ RETVAL
+
+AV *
+execute_single(obj, id, op, keys, limit, skip, mop = 0, mvs = 0, fils = 0, ivkeypart = -1, ivs = 0)
+ SV *obj
+ int id
+ const char *op
+ AV *keys
+ int limit
+ int skip
+ SV *mop
+ SV *mvs
+ SV *fils
+ int ivkeypart
+ SV *ivs
+CODE:
+ const char *const mop_str = sv_get_strval(mop);
+ AV *const mvs_av = sv_get_arrval(mvs);
+ AV *const fils_av = sv_get_arrval(fils);
+ AV *const ivs_av = sv_get_arrval(ivs);
+ RETVAL = execute_internal(obj, id, op, keys, limit, skip, mop_str, mvs_av,
+ fils_av, ivkeypart, ivs_av);
+ sv_2mortal((SV *)RETVAL);
+OUTPUT:
+ RETVAL
+
+AV *
+execute_multi(obj, cmds)
+ SV *obj
+ AV *cmds
+CODE:
+ DBG(fprintf(stderr, "execute_multi0\n"));
+ const I32 cmdsmax = av_len(cmds);
+ execute_arg args[cmdsmax + 1]; /* GNU */
+ for (I32 i = 0; i <= cmdsmax; ++i) {
+ AV *const avtarget = arr_get_arrval(cmds, cmdsmax, i);
+ if (avtarget == 0) {
+ DBG(fprintf(stderr, "execute_multi1 %d\n", i));
+ continue;
+ }
+ const I32 argmax = av_len(avtarget);
+ if (argmax < 2) {
+ DBG(fprintf(stderr, "execute_multi2 %d\n", i));
+ continue;
+ }
+ execute_arg& ag = args[i];
+ ag.id = arr_get_intval(avtarget, argmax, 0);
+ ag.op = arr_get_strval(avtarget, argmax, 1);
+ ag.keys = arr_get_arrval(avtarget, argmax, 2);
+ ag.limit = arr_get_intval(avtarget, argmax, 3);
+ ag.skip = arr_get_intval(avtarget, argmax, 4);
+ ag.modop = arr_get_strval(avtarget, argmax, 5);
+ ag.modvals = arr_get_arrval(avtarget, argmax, 6);
+ ag.filters = arr_get_arrval(avtarget, argmax, 7);
+ ag.invalues_keypart = arr_get_intval(avtarget, argmax, 8, -1);
+ ag.invalues = arr_get_arrval(avtarget, argmax, 9);
+ DBG(fprintf(stderr, "execute_multi3 %d: %d %s %p %d %d %s %p %p %d %p\n",
+ i, ag.id, ag.op, ag.keys, ag.limit, ag.skip, ag.modop, ag.modvals,
+ ag.filters, ag.invalues_keypart, ag.invalues));
+ }
+ RETVAL = execute_multi_internal(obj, args, cmdsmax + 1);
+ sv_2mortal((SV *)RETVAL);
+OUTPUT:
+ RETVAL
+
+AV *
+execute_find(obj, id, op, keys, limit, skip, mop = 0, mvs = 0, fils = 0, ivkeypart = -1, ivs = 0)
+ SV *obj
+ int id
+ const char *op
+ AV *keys
+ int limit
+ int skip
+ SV *mop
+ SV *mvs
+ SV *fils
+ int ivkeypart
+ SV *ivs
+CODE:
+ const char *const mop_str = sv_get_strval(mop);
+ AV *const mvs_av = sv_get_arrval(mvs);
+ AV *const fils_av = sv_get_arrval(fils);
+ AV *const ivs_av = sv_get_arrval(ivs);
+ RETVAL = execute_internal(obj, id, op, keys, limit, skip, mop_str, mvs_av,
+ fils_av, ivkeypart, ivs_av);
+ sv_2mortal((SV *)RETVAL);
+OUTPUT:
+ RETVAL
+
+AV *
+execute_update(obj, id, op, keys, limit, skip, modvals, fils = 0, ivkeypart = -1, ivs = 0)
+ SV *obj
+ int id
+ const char *op
+ AV *keys
+ int limit
+ int skip
+ AV *modvals
+ SV *fils
+ int ivkeypart
+ SV *ivs
+CODE:
+ AV *const fils_av = sv_get_arrval(fils);
+ AV *const ivs_av = sv_get_arrval(ivs);
+ RETVAL = execute_internal(obj, id, op, keys, limit, skip, "U",
+ modvals, fils_av, ivkeypart, ivs_av);
+ sv_2mortal((SV *)RETVAL);
+OUTPUT:
+ RETVAL
+
+AV *
+execute_delete(obj, id, op, keys, limit, skip, fils = 0, ivkeypart = -1, ivs = 0)
+ SV *obj
+ int id
+ const char *op
+ AV *keys
+ int limit
+ int skip
+ SV *fils
+ int ivkeypart
+ SV *ivs
+CODE:
+ AV *const fils_av = sv_get_arrval(fils);
+ AV *const ivs_av = sv_get_arrval(ivs);
+ RETVAL = execute_internal(obj, id, op, keys, limit, skip, "D", 0, fils_av,
+ ivkeypart, ivs_av);
+ sv_2mortal((SV *)RETVAL);
+OUTPUT:
+ RETVAL
+
+AV *
+execute_insert(obj, id, fvals)
+ SV *obj
+ int id
+ AV *fvals
+CODE:
+ RETVAL = execute_internal(obj, id, "+", fvals, 0, 0, 0, 0, 0, -1, 0);
+ sv_2mortal((SV *)RETVAL);
+OUTPUT:
+ RETVAL
+
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/MANIFEST b/plugin/handler_socket/perl-Net-HandlerSocket/MANIFEST
new file mode 100644
index 00000000000..874fadb5e19
--- /dev/null
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/MANIFEST
@@ -0,0 +1,8 @@
+Changes
+HandlerSocket.xs
+Makefile.PL
+MANIFEST
+ppport.h
+README
+t/HandlerSocket.t
+lib/Net/HandlerSocket.pm
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.in b/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.in
new file mode 100644
index 00000000000..1a9b1444fb8
--- /dev/null
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.in
@@ -0,0 +1,18 @@
+# use 5.010000;
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+ NAME => 'Net::HandlerSocket',
+ VERSION_FROM => 'lib/Net/HandlerSocket.pm', # finds $VERSION
+ PREREQ_PM => {}, # e.g., Module::Name => 1.1
+ ($] >= 5.005 ? ## Add these new keywords supported since 5.005
+ (ABSTRACT_FROM => 'lib/Net/HandlerSocket.pm', # retrieve abstract from module
+ AUTHOR => 'higuchi dot akira at dena dot jp>') : ()),
+ CC => 'g++ -fPIC',
+ LD => 'g++ -fPIC',
+ LIBS => ['-L@builddir@/../libhsclient -L@builddir@/../libhsclient/.libs -lhsclient'],
+ DEFINE => '',
+ INC => '-I. -I../libhsclient -I@builddir@/../libhsclient -I@top_builddir@/include',
+ OPTIMIZE => '-g -O3 -Wall -Wno-unused',
+);
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.installed b/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.installed
new file mode 100644
index 00000000000..0d01bceb819
--- /dev/null
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.installed
@@ -0,0 +1,20 @@
+# use 5.010000;
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+ NAME => 'Net::HandlerSocket',
+ VERSION_FROM => 'lib/Net/HandlerSocket.pm', # finds $VERSION
+ PREREQ_PM => {}, # e.g., Module::Name => 1.1
+ ($] >= 5.005 ? ## Add these new keywords supported since 5.005
+ (ABSTRACT_FROM => 'lib/Net/HandlerSocket.pm', # retrieve abstract from module
+ AUTHOR => 'higuchi dot akira at dena dot jp>') : ()),
+ CC => 'g++ -fPIC',
+ LD => 'g++ -fPIC',
+ LIBS => ['-lhsclient'], # e.g., '-lm'
+ DEFINE => '', # e.g., '-DHAVE_SOMETHING'
+ INC => '-I. -I/usr/include/handlersocket -I/usr/include/mysql',
+ OPTIMIZE => '-g -O3 -Wall -Wno-unused',
+ # Un-comment this if you add C files to link with later:
+ # OBJECT => '$(O_FILES)', # link all the C files too
+);
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/README b/plugin/handler_socket/perl-Net-HandlerSocket/README
new file mode 100644
index 00000000000..b6aec952cdf
--- /dev/null
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/README
@@ -0,0 +1,30 @@
+HandlerSocket version 0.01
+==========================
+
+The README is used to introduce the module and provide instructions on
+how to install the module, any machine dependencies it may have (for
+example C compilers and installed libraries) and any other information
+that should be provided before the module is installed.
+
+A README file is required for CPAN modules since CPAN extracts the
+README file from a module distribution so that people browsing the
+archive can use it get an idea of the modules uses. It is usually a
+good idea to provide version information here so that people can
+decide whether fixes for the module are worth downloading.
+
+INSTALLATION
+
+To install this module type the following:
+
+ perl Makefile.PL
+ make
+ make test
+ make install
+
+DEPENDENCIES
+
+COPYRIGHT AND LICENCE
+
+ Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+ See COPYRIGHT.txt for details.
+
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket.pm b/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket.pm
new file mode 100644
index 00000000000..f1ad55564c5
--- /dev/null
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket.pm
@@ -0,0 +1,68 @@
+
+package Net::HandlerSocket;
+
+use strict;
+use warnings;
+
+require Exporter;
+
+our @ISA = qw(Exporter);
+
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
+
+# This allows declaration use Net::HandlerSocket ':all';
+# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
+# will save memory.
+our %EXPORT_TAGS = ( 'all' => [ qw(
+
+) ] );
+
+our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
+
+our @EXPORT = qw(
+
+);
+
+our $VERSION = '0.01';
+
+require XSLoader;
+XSLoader::load('Net::HandlerSocket', $VERSION);
+
+# Preloaded methods go here.
+
+1;
+__END__
+# Below is stub documentation for your module. You'd better edit it!
+
+=head1 NAME
+
+Net::HandlerSocket - Perl extension for blah blah blah
+
+=head1 SYNOPSIS
+
+ use Net::HandlerSocket;
+ my $hsargs = { host => 'localhost', port => 9999 };
+ my $cli = new Net::HandlerSocket($hsargs);
+ $cli->open_index(1, 'testdb', 'testtable1', 'PRIMARY', 'foo,bar,baz');
+ $cli->open_index(2, 'testdb', 'testtable2', 'i2', 'hoge,fuga');
+ $cli->execute_find(1, '>=', [ 'aaa', 'bbb' ], 5, 100);
+ # select foo,bar,baz from testdb.testtable1
+ # where pk1 = 'aaa' and pk2 = 'bbb' order by pk1, pk2
+ # limit 100, 5
+
+=head1 DESCRIPTION
+
+Stub documentation for Net::HandlerSocket, created by h2xs.
+
+=head1 AUTHOR
+
+Akira HiguchiE<lt>higuchi dot akira at dena dot jpE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
+See COPYRIGHT.txt for details.
+
+=cut
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm b/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm
new file mode 100755
index 00000000000..c51fe60d591
--- /dev/null
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm
@@ -0,0 +1,362 @@
+#!/usr/bin/perl
+
+package Net::HandlerSocket::HSPool;
+
+use strict;
+use warnings;
+use Net::HandlerSocket;
+use Socket;
+
+sub new {
+ my $self = {
+ config => $_[1],
+ reopen_interval => 60,
+ hostmap => { },
+ };
+ return bless $self, $_[0];
+}
+
+sub clear_pool {
+ my ($self) = @_;
+ $self->{hostmap} = { };
+}
+
+sub on_error {
+ my ($self, $obj) = @_;
+ my $error_func = $self->{config}->{error};
+ if (defined($error_func)) {
+ return &{$error_func}($obj);
+ }
+ die $obj;
+}
+
+sub on_warning {
+ my ($self, $obj) = @_;
+ my $warning_func = $self->{config}->{warning};
+ if (defined($warning_func)) {
+ return &{$warning_func}($obj);
+ }
+}
+
+sub get_conf {
+ my ($self, $dbtbl) = @_;
+ my $hcent = $self->{config}->{hostmap}->{$dbtbl};
+ if (!defined($hcent)) {
+ $self->on_error("get_conf: $dbtbl not found");
+ return undef;
+ }
+ my %cpy = %$hcent;
+ $cpy{port} ||= 9998;
+ $cpy{timeout} ||= 2;
+ return \%cpy;
+}
+
+sub resolve_hostname {
+ my ($self, $hcent, $host_ip_list) = @_;
+ if (defined($host_ip_list)) {
+ if (scalar(@$host_ip_list) > 0) {
+ $hcent->{host} = shift(@$host_ip_list);
+ return $host_ip_list;
+ }
+ return undef; # no more ip
+ }
+ my $host = $hcent->{host}; # unresolved name
+ $hcent->{hostname} = $host;
+ my $resolve_list_func = $self->{config}->{resolve_list};
+ if (defined($resolve_list_func)) {
+ $host_ip_list = &{$resolve_list_func}($host);
+ if (scalar(@$host_ip_list) > 0) {
+ $hcent->{host} = shift(@$host_ip_list);
+ return $host_ip_list;
+ }
+ return undef; # no more ip
+ }
+ my $resolve_func = $self->{config}->{resolve};
+ if (defined($resolve_func)) {
+ $hcent->{host} = &{$resolve_func}($host);
+ return [];
+ }
+ my $packed = gethostbyname($host);
+ if (!defined($packed)) {
+ return undef;
+ }
+ $hcent->{host} = inet_ntoa($packed);
+ return [];
+}
+
+sub get_handle_exec {
+ my ($self, $db, $tbl, $idx, $cols, $exec_multi, $exec_args) = @_;
+ my $now = time();
+ my $dbtbl = join('.', $db, $tbl);
+ my $hcent = $self->get_conf($dbtbl); # copy
+ if (!defined($hcent)) {
+ return undef;
+ }
+ my $hmkey = join(':', $hcent->{host}, $hcent->{port});
+ my $hment = $self->{hostmap}->{$hmkey};
+ # [ open_time, handle, index_map, host, next_index_id ]
+ my $host_ip_list;
+ TRY_OTHER_IP:
+ if (!defined($hment) ||
+ $hment->[0] + $self->{reopen_interval} < $now ||
+ !$hment->[1]->stable_point()) {
+ $host_ip_list = $self->resolve_hostname($hcent, $host_ip_list);
+ if (!defined($host_ip_list)) {
+ my $hostport = $hmkey . '(' . $hcent->{host} . ')';
+ $self->on_error("HSPool::get_handle" .
+ "($db, $tbl, $idx, $cols): host=$hmkey: " .
+ "no more active ip");
+ return undef;
+ }
+ my $hnd = new Net::HandlerSocket($hcent);
+ my %m = ();
+ $hment = [ $now, $hnd, \%m, $hcent->{host}, 1 ];
+ $self->{hostmap}->{$hmkey} = $hment;
+ }
+ my $hnd = $hment->[1];
+ my $idxmap = $hment->[2];
+ my $imkey = join(':', $idx, $cols);
+ my $idx_id = $idxmap->{$imkey};
+ if (!defined($idx_id)) {
+ $idx_id = $hment->[4];
+ my $e = $hnd->open_index($idx_id, $db, $tbl, $idx, $cols);
+ if ($e != 0) {
+ my $estr = $hnd->get_error();
+ my $hostport = $hmkey . '(' . $hcent->{host} . ')';
+ my $errmess = "HSPool::get_handle open_index" .
+ "($db, $tbl, $idx, $cols): host=$hostport " .
+ "err=$e($estr)";
+ $self->on_warning($errmess);
+ $hnd->close();
+ $hment = undef;
+ goto TRY_OTHER_IP;
+ }
+ $hment->[4]++;
+ $idxmap->{$imkey} = $idx_id;
+ }
+ if ($exec_multi) {
+ my $resarr;
+ for my $cmdent (@$exec_args) {
+ $cmdent->[0] = $idx_id;
+ }
+ if (scalar(@$exec_args) == 0) {
+ $resarr = [];
+ } else {
+ $resarr = $hnd->execute_multi($exec_args);
+ }
+ my $i = 0;
+ for my $res (@$resarr) {
+ if ($res->[0] != 0) {
+ my $cmdent = $exec_args->[$i];
+ my $ec = $res->[0];
+ my $estr = $res->[1];
+ my $op = $cmdent->[1];
+ my $kfvs = $cmdent->[2];
+ my $kvstr = defined($kfvs)
+ ? join(',', @$kfvs) : '';
+ my $limit = $cmdent->[3] || 0;
+ my $skip = $cmdent->[4] || 0;
+ my $hostport = $hmkey . '(' . $hcent->{host}
+ . ')';
+ my $errmess = "HSPool::get_handle execm" .
+ "($db, $tbl, $idx, [$cols], " .
+ "($idx_id), $op, [$kvstr] " .
+ "$limit, $skip): " .
+ "host=$hostport err=$ec($estr)";
+ if ($res->[0] < 0 || $res->[0] == 2) {
+ $self->on_warning($errmess);
+ $hnd->close();
+ $hment = undef;
+ goto TRY_OTHER_IP;
+ } else {
+ $self->on_error($errmess);
+ }
+ }
+ shift(@$res);
+ ++$i;
+ }
+ return $resarr;
+ } else {
+ my $res = $hnd->execute_find($idx_id, @$exec_args);
+ if ($res->[0] != 0) {
+ my ($op, $kfvals, $limit, $skip) = @$exec_args;
+ my $ec = $res->[0];
+ my $estr = $res->[1];
+ my $kvstr = join(',', @$kfvals);
+ my $hostport = $hmkey . '(' . $hcent->{host} . ')';
+ my $errmess = "HSPool::get_handle exec" .
+ "($db, $tbl, $idx, [$cols], ($idx_id), " .
+ "$op, [$kvstr], $limit, $skip): " .
+ "host=$hostport err=$ec($estr)";
+ if ($res->[0] < 0 || $res->[0] == 2) {
+ $self->on_warning($errmess);
+ $hnd->close();
+ $hment = undef;
+ goto TRY_OTHER_IP;
+ } else {
+ $self->on_error($errmess);
+ }
+ }
+ shift(@$res);
+ return $res;
+ }
+}
+
+sub index_find {
+ my ($self, $db, $tbl, $idx, $cols, $op, $kfvals, $limit, $skip) = @_;
+ # cols: comma separated list
+ # kfvals: arrayref
+ $limit ||= 0;
+ $skip ||= 0;
+ my $res = $self->get_handle_exec($db, $tbl, $idx, $cols,
+ 0, [ $op, $kfvals, $limit, $skip ]);
+ return $res;
+}
+
+sub index_find_multi {
+ my ($self, $db, $tbl, $idx, $cols, $cmdlist) = @_;
+ # cols : comma separated list
+ # cmdlist : [ dummy, op, kfvals, limit, skip ]
+ # kfvals : arrayref
+ my $resarr = $self->get_handle_exec($db, $tbl, $idx, $cols,
+ 1, $cmdlist);
+ return $resarr;
+}
+
+sub result_single_to_arrarr {
+ my ($numcols, $hsres, $ret) = @_;
+ my $hsreslen = scalar(@$hsres);
+ my $rlen = int($hsreslen / $numcols);
+ $ret = [ ] if !defined($ret);
+ my @r = ();
+ my $p = 0;
+ for (my $i = 0; $i < $rlen; ++$i) {
+ my @a = splice(@$hsres, $p, $numcols);
+ $p += $numcols;
+ push(@$ret, \@a);
+ }
+ return $ret; # arrayref of arrayrefs
+}
+
+sub result_multi_to_arrarr {
+ my ($numcols, $mhsres, $ret) = @_;
+ $ret = [ ] if !defined($ret);
+ for my $hsres (@$mhsres) {
+ my $hsreslen = scalar(@$hsres);
+ my $rlen = int($hsreslen / $numcols);
+ my $p = 0;
+ for (my $i = 0; $i < $rlen; ++$i) {
+ my @a = splice(@$hsres, $p, $numcols);
+ $p += $numcols;
+ push(@$ret, \@a);
+ }
+ }
+ return $ret; # arrayref of arrayrefs
+}
+
+sub result_single_to_hasharr {
+ my ($names, $hsres, $ret) = @_;
+ my $nameslen = scalar(@$names);
+ my $hsreslen = scalar(@$hsres);
+ my $rlen = int($hsreslen / $nameslen);
+ $ret = [ ] if !defined($ret);
+ my $p = 0;
+ for (my $i = 0; $i < $rlen; ++$i) {
+ my %h = ();
+ for (my $j = 0; $j < $nameslen; ++$j, ++$p) {
+ $h{$names->[$j]} = $hsres->[$p];
+ }
+ push(@$ret, \%h);
+ }
+ return $ret; # arrayref of hashrefs
+}
+
+sub result_multi_to_hasharr {
+ my ($names, $mhsres, $ret) = @_;
+ my $nameslen = scalar(@$names);
+ $ret = [ ] if !defined($ret);
+ for my $hsres (@$mhsres) {
+ my $hsreslen = scalar(@$hsres);
+ my $rlen = int($hsreslen / $nameslen);
+ my $p = 0;
+ for (my $i = 0; $i < $rlen; ++$i) {
+ my %h = ();
+ for (my $j = 0; $j < $nameslen; ++$j, ++$p) {
+ $h{$names->[$j]} = $hsres->[$p];
+ }
+ push(@$ret, \%h);
+ }
+ }
+ return $ret; # arrayref of hashrefs
+}
+
+sub result_single_to_hashhash {
+ my ($names, $key, $hsres, $ret) = @_;
+ my $nameslen = scalar(@$names);
+ my $hsreslen = scalar(@$hsres);
+ my $rlen = int($hsreslen / $nameslen);
+ $ret = { } if !defined($ret);
+ my $p = 0;
+ for (my $i = 0; $i < $rlen; ++$i) {
+ my %h = ();
+ for (my $j = 0; $j < $nameslen; ++$j, ++$p) {
+ $h{$names->[$j]} = $hsres->[$p];
+ }
+ my $k = $h{$key};
+ $ret->{$k} = \%h if defined($k);
+ }
+ return $ret; # hashref of hashrefs
+}
+
+sub result_multi_to_hashhash {
+ my ($names, $key, $mhsres, $ret) = @_;
+ my $nameslen = scalar(@$names);
+ $ret = { } if !defined($ret);
+ for my $hsres (@$mhsres) {
+ my $hsreslen = scalar(@$hsres);
+ my $rlen = int($hsreslen / $nameslen);
+ my $p = 0;
+ for (my $i = 0; $i < $rlen; ++$i) {
+ my %h = ();
+ for (my $j = 0; $j < $nameslen; ++$j, ++$p) {
+ $h{$names->[$j]} = $hsres->[$p];
+ }
+ my $k = $h{$key};
+ $ret->{$k} = \%h if defined($k);
+ }
+ }
+ return $ret; # hashref of hashrefs
+}
+
+sub select_cols_where_eq_aa {
+ # SELECT $cols FROM $db.$tbl WHERE $idx_key = $kv LIMIT 1
+ my ($self, $db, $tbl, $idx, $cols_aref, $kv_aref) = @_;
+ my $cols_str = join(',', @$cols_aref);
+ my $res = $self->index_find($db, $tbl, $idx, $cols_str, '=', $kv_aref);
+ return result_single_to_arrarr(scalar(@$cols_aref), $res);
+}
+
+sub select_cols_where_eq_hh {
+ # SELECT $cols FROM $db.$tbl WHERE $idx_key = $kv LIMIT 1
+ my ($self, $db, $tbl, $idx, $cols_aref, $kv_aref, $retkey) = @_;
+ my $cols_str = join(',', @$cols_aref);
+ my $res = $self->index_find($db, $tbl, $idx, $cols_str, '=', $kv_aref);
+ my $r = result_single_to_hashhash($cols_aref, $retkey, $res);
+ return $r;
+}
+
+sub select_cols_where_in_hh {
+ # SELECT $cols FROM $db.$tbl WHERE $idx_key in ($vals)
+ my ($self, $db, $tbl, $idx, $cols_aref, $vals_aref, $retkey) = @_;
+ my $cols_str = join(',', @$cols_aref);
+ my @cmdlist = ();
+ for my $v (@$vals_aref) {
+ push(@cmdlist, [ -1, '=', [ $v ] ]);
+ }
+ my $res = $self->index_find_multi($db, $tbl, $idx, $cols_str,
+ \@cmdlist);
+ return result_multi_to_hashhash($cols_aref, $retkey, $res);
+}
+
+1;
+
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec.template b/plugin/handler_socket/perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec.template
new file mode 100644
index 00000000000..304baf03ffb
--- /dev/null
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec.template
@@ -0,0 +1,127 @@
+#
+# - HandlerSocket -
+# This spec file was automatically generated by cpan2rpm [ver: 2.027]
+# The following arguments were used:
+# --no-sign perl-Net-HandlerSocket.tar.gz
+# For more information on cpan2rpm please visit: http://perl.arix.com/
+#
+
+%define pkgname perl-Net-HandlerSocket
+%define filelist %{pkgname}-%{version}-filelist
+%define NVR %{pkgname}-%{version}-%{release}
+%define maketest 1
+
+name: perl-Net-HandlerSocket
+summary: HandlerSocket - Perl extension for handlersocket
+version: HANDLERSOCKET_VERSION
+release: 1%{?dist}
+packager: Akira Higuchi <higuchi dot akira at dena dot jp>
+license: BSD
+group: Applications/CPAN
+group: System Environment/Libraries
+buildroot: %{_tmppath}/%{name}-%{version}-%(id -u -n)
+prefix: %(echo %{_prefix})
+source: perl-Net-HandlerSocket.tar.gz
+BuildRequires: libhsclient
+Requires: libhsclient
+Obsoletes: perl-DB-HandlerSocket
+
+%description
+Stub documentation for HandlerSocket, created by h2xs. It looks like the
+author of the extension was negligent enough to leave the stub
+unedited.
+
+#
+# This package was generated automatically with the cpan2rpm
+# utility. To get this software or for more information
+# please visit: http://perl.arix.com/
+#
+
+%prep
+%setup -q -n %{pkgname}
+chmod -R u+w %{_builddir}/%{pkgname}
+
+%build
+grep -rsl '^#!.*perl' . |
+grep -v '.bak$' |xargs --no-run-if-empty \
+%__perl -MExtUtils::MakeMaker -e 'MY->fixin(@ARGV)'
+CFLAGS="$RPM_OPT_FLAGS"
+%{__perl} Makefile.PL.installed `%{__perl} -MExtUtils::MakeMaker -e ' print qq|PREFIX=%{buildroot}%{_prefix}| if \$ExtUtils::MakeMaker::VERSION =~ /5\.9[1-6]|6\.0[0-5]/ '`
+%{__make}
+%if %maketest
+%{__make} test
+%endif
+
+%install
+[ "%{buildroot}" != "/" ] && rm -rf %{buildroot}
+
+%{makeinstall} `%{__perl} -MExtUtils::MakeMaker -e ' print \$ExtUtils::MakeMaker::VERSION <= 6.05 ? qq|PREFIX=%{buildroot}%{_prefix}| : qq|DESTDIR=%{buildroot}| '`
+
+cmd=/usr/share/spec-helper/compress_files
+[ -x $cmd ] || cmd=/usr/lib/rpm/brp-compress
+[ -x $cmd ] && $cmd
+
+# SuSE Linux
+if [ -e /etc/SuSE-release -o -e /etc/UnitedLinux-release ]
+then
+ %{__mkdir_p} %{buildroot}/var/adm/perl-modules
+ %{__cat} `find %{buildroot} -name "perllocal.pod"` \
+ | %{__sed} -e s+%{buildroot}++g \
+ > %{buildroot}/var/adm/perl-modules/%{name}
+fi
+
+# remove special files
+find %{buildroot} -name "perllocal.pod" \
+ -o -name ".packlist" \
+ -o -name "*.bs" \
+ |xargs -i rm -f {}
+
+# no empty directories
+find %{buildroot}%{_prefix} \
+ -type d -depth \
+ -exec rmdir {} \; 2>/dev/null
+
+%{__perl} -MFile::Find -le '
+ find({ wanted => \&wanted, no_chdir => 1}, "%{buildroot}");
+ print "%doc Changes README";
+ for my $x (sort @dirs, @files) {
+ push @ret, $x unless indirs($x);
+ }
+ print join "\n", sort @ret;
+
+ sub wanted {
+ return if /auto$/;
+
+ local $_ = $File::Find::name;
+ my $f = $_; s|^\Q%{buildroot}\E||;
+ return unless length;
+ return $files[@files] = $_ if -f $f;
+
+ $d = $_;
+ /\Q$d\E/ && return for reverse sort @INC;
+ $d =~ /\Q$_\E/ && return
+ for qw|/etc %_prefix/man %_prefix/bin %_prefix/share|;
+
+ $dirs[@dirs] = $_;
+ }
+
+ sub indirs {
+ my $x = shift;
+ $x =~ /^\Q$_\E\// && $x ne $_ && return 1 for @dirs;
+ }
+ ' > %filelist
+
+[ -z %filelist ] && {
+ echo "ERROR: empty %files listing"
+ exit -1
+ }
+
+%clean
+[ "%{buildroot}" != "/" ] && rm -rf %{buildroot}
+
+%files -f %filelist
+%defattr(-,root,root)
+
+%changelog
+* Thu Apr 1 2010 a@localhost.localdomain
+- Initial build.
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/ppport.h b/plugin/handler_socket/perl-Net-HandlerSocket/ppport.h
new file mode 100644
index 00000000000..6e562f5b4a8
--- /dev/null
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/ppport.h
@@ -0,0 +1,6375 @@
+#if 0
+<<'SKIP';
+#endif
+/*
+----------------------------------------------------------------------
+
+ ppport.h -- Perl/Pollution/Portability Version 3.13
+
+ Automatically created by Devel::PPPort running under perl 5.010000.
+
+ Do NOT edit this file directly! -- Edit PPPort_pm.PL and the
+ includes in parts/inc/ instead.
+
+ Use 'perldoc ppport.h' to view the documentation below.
+
+----------------------------------------------------------------------
+
+SKIP
+
+=pod
+
+=head1 NAME
+
+ppport.h - Perl/Pollution/Portability version 3.13
+
+=head1 SYNOPSIS
+
+ perl ppport.h [options] [source files]
+
+ Searches current directory for files if no [source files] are given
+
+ --help show short help
+
+ --version show version
+
+ --patch=file write one patch file with changes
+ --copy=suffix write changed copies with suffix
+ --diff=program use diff program and options
+
+ --compat-version=version provide compatibility with Perl version
+ --cplusplus accept C++ comments
+
+ --quiet don't output anything except fatal errors
+ --nodiag don't show diagnostics
+ --nohints don't show hints
+ --nochanges don't suggest changes
+ --nofilter don't filter input files
+
+ --strip strip all script and doc functionality from
+ ppport.h
+
+ --list-provided list provided API
+ --list-unsupported list unsupported API
+ --api-info=name show Perl API portability information
+
+=head1 COMPATIBILITY
+
+This version of F<ppport.h> is designed to support operation with Perl
+installations back to 5.003, and has been tested up to 5.10.0.
+
+=head1 OPTIONS
+
+=head2 --help
+
+Display a brief usage summary.
+
+=head2 --version
+
+Display the version of F<ppport.h>.
+
+=head2 --patch=I<file>
+
+If this option is given, a single patch file will be created if
+any changes are suggested. This requires a working diff program
+to be installed on your system.
+
+=head2 --copy=I<suffix>
+
+If this option is given, a copy of each file will be saved with
+the given suffix that contains the suggested changes. This does
+not require any external programs. Note that this does not
+automagially add a dot between the original filename and the
+suffix. If you want the dot, you have to include it in the option
+argument.
+
+If neither C<--patch> or C<--copy> are given, the default is to
+simply print the diffs for each file. This requires either
+C<Text::Diff> or a C<diff> program to be installed.
+
+=head2 --diff=I<program>
+
+Manually set the diff program and options to use. The default
+is to use C<Text::Diff>, when installed, and output unified
+context diffs.
+
+=head2 --compat-version=I<version>
+
+Tell F<ppport.h> to check for compatibility with the given
+Perl version. The default is to check for compatibility with Perl
+version 5.003. You can use this option to reduce the output
+of F<ppport.h> if you intend to be backward compatible only
+down to a certain Perl version.
+
+=head2 --cplusplus
+
+Usually, F<ppport.h> will detect C++ style comments and
+replace them with C style comments for portability reasons.
+Using this option instructs F<ppport.h> to leave C++
+comments untouched.
+
+=head2 --quiet
+
+Be quiet. Don't print anything except fatal errors.
+
+=head2 --nodiag
+
+Don't output any diagnostic messages. Only portability
+alerts will be printed.
+
+=head2 --nohints
+
+Don't output any hints. Hints often contain useful portability
+notes. Warnings will still be displayed.
+
+=head2 --nochanges
+
+Don't suggest any changes. Only give diagnostic output and hints
+unless these are also deactivated.
+
+=head2 --nofilter
+
+Don't filter the list of input files. By default, files not looking
+like source code (i.e. not *.xs, *.c, *.cc, *.cpp or *.h) are skipped.
+
+=head2 --strip
+
+Strip all script and documentation functionality from F<ppport.h>.
+This reduces the size of F<ppport.h> dramatically and may be useful
+if you want to include F<ppport.h> in smaller modules without
+increasing their distribution size too much.
+
+The stripped F<ppport.h> will have a C<--unstrip> option that allows
+you to undo the stripping, but only if an appropriate C<Devel::PPPort>
+module is installed.
+
+=head2 --list-provided
+
+Lists the API elements for which compatibility is provided by
+F<ppport.h>. Also lists if it must be explicitly requested,
+if it has dependencies, and if there are hints or warnings for it.
+
+=head2 --list-unsupported
+
+Lists the API elements that are known not to be supported by
+F<ppport.h> and below which version of Perl they probably
+won't be available or work.
+
+=head2 --api-info=I<name>
+
+Show portability information for API elements matching I<name>.
+If I<name> is surrounded by slashes, it is interpreted as a regular
+expression.
+
+=head1 DESCRIPTION
+
+In order for a Perl extension (XS) module to be as portable as possible
+across differing versions of Perl itself, certain steps need to be taken.
+
+=over 4
+
+=item *
+
+Including this header is the first major one. This alone will give you
+access to a large part of the Perl API that hasn't been available in
+earlier Perl releases. Use
+
+ perl ppport.h --list-provided
+
+to see which API elements are provided by ppport.h.
+
+=item *
+
+You should avoid using deprecated parts of the API. For example, using
+global Perl variables without the C<PL_> prefix is deprecated. Also,
+some API functions used to have a C<perl_> prefix. Using this form is
+also deprecated. You can safely use the supported API, as F<ppport.h>
+will provide wrappers for older Perl versions.
+
+=item *
+
+If you use one of a few functions or variables that were not present in
+earlier versions of Perl, and that can't be provided using a macro, you
+have to explicitly request support for these functions by adding one or
+more C<#define>s in your source code before the inclusion of F<ppport.h>.
+
+These functions or variables will be marked C<explicit> in the list shown
+by C<--list-provided>.
+
+Depending on whether you module has a single or multiple files that
+use such functions or variables, you want either C<static> or global
+variants.
+
+For a C<static> function or variable (used only in a single source
+file), use:
+
+ #define NEED_function
+ #define NEED_variable
+
+For a global function or variable (used in multiple source files),
+use:
+
+ #define NEED_function_GLOBAL
+ #define NEED_variable_GLOBAL
+
+Note that you mustn't have more than one global request for the
+same function or variable in your project.
+
+ Function / Variable Static Request Global Request
+ -----------------------------------------------------------------------------------------
+ PL_signals NEED_PL_signals NEED_PL_signals_GLOBAL
+ eval_pv() NEED_eval_pv NEED_eval_pv_GLOBAL
+ grok_bin() NEED_grok_bin NEED_grok_bin_GLOBAL
+ grok_hex() NEED_grok_hex NEED_grok_hex_GLOBAL
+ grok_number() NEED_grok_number NEED_grok_number_GLOBAL
+ grok_numeric_radix() NEED_grok_numeric_radix NEED_grok_numeric_radix_GLOBAL
+ grok_oct() NEED_grok_oct NEED_grok_oct_GLOBAL
+ load_module() NEED_load_module NEED_load_module_GLOBAL
+ my_snprintf() NEED_my_snprintf NEED_my_snprintf_GLOBAL
+ my_strlcat() NEED_my_strlcat NEED_my_strlcat_GLOBAL
+ my_strlcpy() NEED_my_strlcpy NEED_my_strlcpy_GLOBAL
+ newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL
+ newRV_noinc() NEED_newRV_noinc NEED_newRV_noinc_GLOBAL
+ newSVpvn_share() NEED_newSVpvn_share NEED_newSVpvn_share_GLOBAL
+ sv_2pv_flags() NEED_sv_2pv_flags NEED_sv_2pv_flags_GLOBAL
+ sv_2pvbyte() NEED_sv_2pvbyte NEED_sv_2pvbyte_GLOBAL
+ sv_catpvf_mg() NEED_sv_catpvf_mg NEED_sv_catpvf_mg_GLOBAL
+ sv_catpvf_mg_nocontext() NEED_sv_catpvf_mg_nocontext NEED_sv_catpvf_mg_nocontext_GLOBAL
+ sv_pvn_force_flags() NEED_sv_pvn_force_flags NEED_sv_pvn_force_flags_GLOBAL
+ sv_setpvf_mg() NEED_sv_setpvf_mg NEED_sv_setpvf_mg_GLOBAL
+ sv_setpvf_mg_nocontext() NEED_sv_setpvf_mg_nocontext NEED_sv_setpvf_mg_nocontext_GLOBAL
+ vload_module() NEED_vload_module NEED_vload_module_GLOBAL
+ vnewSVpvf() NEED_vnewSVpvf NEED_vnewSVpvf_GLOBAL
+ warner() NEED_warner NEED_warner_GLOBAL
+
+To avoid namespace conflicts, you can change the namespace of the
+explicitly exported functions / variables using the C<DPPP_NAMESPACE>
+macro. Just C<#define> the macro before including C<ppport.h>:
+
+ #define DPPP_NAMESPACE MyOwnNamespace_
+ #include "ppport.h"
+
+The default namespace is C<DPPP_>.
+
+=back
+
+The good thing is that most of the above can be checked by running
+F<ppport.h> on your source code. See the next section for
+details.
+
+=head1 EXAMPLES
+
+To verify whether F<ppport.h> is needed for your module, whether you
+should make any changes to your code, and whether any special defines
+should be used, F<ppport.h> can be run as a Perl script to check your
+source code. Simply say:
+
+ perl ppport.h
+
+The result will usually be a list of patches suggesting changes
+that should at least be acceptable, if not necessarily the most
+efficient solution, or a fix for all possible problems.
+
+If you know that your XS module uses features only available in
+newer Perl releases, if you're aware that it uses C++ comments,
+and if you want all suggestions as a single patch file, you could
+use something like this:
+
+ perl ppport.h --compat-version=5.6.0 --cplusplus --patch=test.diff
+
+If you only want your code to be scanned without any suggestions
+for changes, use:
+
+ perl ppport.h --nochanges
+
+You can specify a different C<diff> program or options, using
+the C<--diff> option:
+
+ perl ppport.h --diff='diff -C 10'
+
+This would output context diffs with 10 lines of context.
+
+If you want to create patched copies of your files instead, use:
+
+ perl ppport.h --copy=.new
+
+To display portability information for the C<newSVpvn> function,
+use:
+
+ perl ppport.h --api-info=newSVpvn
+
+Since the argument to C<--api-info> can be a regular expression,
+you can use
+
+ perl ppport.h --api-info=/_nomg$/
+
+to display portability information for all C<_nomg> functions or
+
+ perl ppport.h --api-info=/./
+
+to display information for all known API elements.
+
+=head1 BUGS
+
+If this version of F<ppport.h> is causing failure during
+the compilation of this module, please check if newer versions
+of either this module or C<Devel::PPPort> are available on CPAN
+before sending a bug report.
+
+If F<ppport.h> was generated using the latest version of
+C<Devel::PPPort> and is causing failure of this module, please
+file a bug report using the CPAN Request Tracker at L<http://rt.cpan.org/>.
+
+Please include the following information:
+
+=over 4
+
+=item 1.
+
+The complete output from running "perl -V"
+
+=item 2.
+
+This file.
+
+=item 3.
+
+The name and version of the module you were trying to build.
+
+=item 4.
+
+A full log of the build that failed.
+
+=item 5.
+
+Any other information that you think could be relevant.
+
+=back
+
+For the latest version of this code, please get the C<Devel::PPPort>
+module from CPAN.
+
+=head1 COPYRIGHT
+
+Version 3.x, Copyright (c) 2004-2007, Marcus Holland-Moritz.
+
+Version 2.x, Copyright (C) 2001, Paul Marquess.
+
+Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+See L<Devel::PPPort>.
+
+=cut
+
+use strict;
+
+# Disable broken TRIE-optimization
+BEGIN { eval '${^RE_TRIE_MAXBUF} = -1' if $] >= 5.009004 && $] <= 5.009005 }
+
+my $VERSION = 3.13;
+
+my %opt = (
+ quiet => 0,
+ diag => 1,
+ hints => 1,
+ changes => 1,
+ cplusplus => 0,
+ filter => 1,
+ strip => 0,
+ version => 0,
+);
+
+my($ppport) = $0 =~ /([\w.]+)$/;
+my $LF = '(?:\r\n|[\r\n])'; # line feed
+my $HS = "[ \t]"; # horizontal whitespace
+
+# Never use C comments in this file!
+my $ccs = '/'.'*';
+my $cce = '*'.'/';
+my $rccs = quotemeta $ccs;
+my $rcce = quotemeta $cce;
+
+eval {
+ require Getopt::Long;
+ Getopt::Long::GetOptions(\%opt, qw(
+ help quiet diag! filter! hints! changes! cplusplus strip version
+ patch=s copy=s diff=s compat-version=s
+ list-provided list-unsupported api-info=s
+ )) or usage();
+};
+
+if ($@ and grep /^-/, @ARGV) {
+ usage() if "@ARGV" =~ /^--?h(?:elp)?$/;
+ die "Getopt::Long not found. Please don't use any options.\n";
+}
+
+if ($opt{version}) {
+ print "This is $0 $VERSION.\n";
+ exit 0;
+}
+
+usage() if $opt{help};
+strip() if $opt{strip};
+
+if (exists $opt{'compat-version'}) {
+ my($r,$v,$s) = eval { parse_version($opt{'compat-version'}) };
+ if ($@) {
+ die "Invalid version number format: '$opt{'compat-version'}'\n";
+ }
+ die "Only Perl 5 is supported\n" if $r != 5;
+ die "Invalid version number: $opt{'compat-version'}\n" if $v >= 1000 || $s >= 1000;
+ $opt{'compat-version'} = sprintf "%d.%03d%03d", $r, $v, $s;
+}
+else {
+ $opt{'compat-version'} = 5;
+}
+
+my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/
+ ? ( $1 => {
+ ($2 ? ( base => $2 ) : ()),
+ ($3 ? ( todo => $3 ) : ()),
+ (index($4, 'v') >= 0 ? ( varargs => 1 ) : ()),
+ (index($4, 'p') >= 0 ? ( provided => 1 ) : ()),
+ (index($4, 'n') >= 0 ? ( nothxarg => 1 ) : ()),
+ } )
+ : die "invalid spec: $_" } qw(
+AvFILLp|5.004050||p
+AvFILL|||
+CLASS|||n
+CX_CURPAD_SAVE|||
+CX_CURPAD_SV|||
+CopFILEAV|5.006000||p
+CopFILEGV_set|5.006000||p
+CopFILEGV|5.006000||p
+CopFILESV|5.006000||p
+CopFILE_set|5.006000||p
+CopFILE|5.006000||p
+CopSTASHPV_set|5.006000||p
+CopSTASHPV|5.006000||p
+CopSTASH_eq|5.006000||p
+CopSTASH_set|5.006000||p
+CopSTASH|5.006000||p
+CopyD|5.009002||p
+Copy|||
+CvPADLIST|||
+CvSTASH|||
+CvWEAKOUTSIDE|||
+DEFSV|5.004050||p
+END_EXTERN_C|5.005000||p
+ENTER|||
+ERRSV|5.004050||p
+EXTEND|||
+EXTERN_C|5.005000||p
+F0convert|||n
+FREETMPS|||
+GIMME_V||5.004000|n
+GIMME|||n
+GROK_NUMERIC_RADIX|5.007002||p
+G_ARRAY|||
+G_DISCARD|||
+G_EVAL|||
+G_NOARGS|||
+G_SCALAR|||
+G_VOID||5.004000|
+GetVars|||
+GvSV|||
+Gv_AMupdate|||
+HEf_SVKEY||5.004000|
+HeHASH||5.004000|
+HeKEY||5.004000|
+HeKLEN||5.004000|
+HePV||5.004000|
+HeSVKEY_force||5.004000|
+HeSVKEY_set||5.004000|
+HeSVKEY||5.004000|
+HeVAL||5.004000|
+HvNAME|||
+INT2PTR|5.006000||p
+IN_LOCALE_COMPILETIME|5.007002||p
+IN_LOCALE_RUNTIME|5.007002||p
+IN_LOCALE|5.007002||p
+IN_PERL_COMPILETIME|5.008001||p
+IS_NUMBER_GREATER_THAN_UV_MAX|5.007002||p
+IS_NUMBER_INFINITY|5.007002||p
+IS_NUMBER_IN_UV|5.007002||p
+IS_NUMBER_NAN|5.007003||p
+IS_NUMBER_NEG|5.007002||p
+IS_NUMBER_NOT_INT|5.007002||p
+IVSIZE|5.006000||p
+IVTYPE|5.006000||p
+IVdf|5.006000||p
+LEAVE|||
+LVRET|||
+MARK|||
+MULTICALL||5.009005|
+MY_CXT_CLONE|5.009002||p
+MY_CXT_INIT|5.007003||p
+MY_CXT|5.007003||p
+MoveD|5.009002||p
+Move|||
+NOOP|5.005000||p
+NUM2PTR|5.006000||p
+NVTYPE|5.006000||p
+NVef|5.006001||p
+NVff|5.006001||p
+NVgf|5.006001||p
+Newxc|5.009003||p
+Newxz|5.009003||p
+Newx|5.009003||p
+Nullav|||
+Nullch|||
+Nullcv|||
+Nullhv|||
+Nullsv|||
+ORIGMARK|||
+PAD_BASE_SV|||
+PAD_CLONE_VARS|||
+PAD_COMPNAME_FLAGS|||
+PAD_COMPNAME_GEN_set|||
+PAD_COMPNAME_GEN|||
+PAD_COMPNAME_OURSTASH|||
+PAD_COMPNAME_PV|||
+PAD_COMPNAME_TYPE|||
+PAD_RESTORE_LOCAL|||
+PAD_SAVE_LOCAL|||
+PAD_SAVE_SETNULLPAD|||
+PAD_SETSV|||
+PAD_SET_CUR_NOSAVE|||
+PAD_SET_CUR|||
+PAD_SVl|||
+PAD_SV|||
+PERL_ABS|5.008001||p
+PERL_BCDVERSION|5.009005||p
+PERL_GCC_BRACE_GROUPS_FORBIDDEN|5.008001||p
+PERL_HASH|5.004000||p
+PERL_INT_MAX|5.004000||p
+PERL_INT_MIN|5.004000||p
+PERL_LONG_MAX|5.004000||p
+PERL_LONG_MIN|5.004000||p
+PERL_MAGIC_arylen|5.007002||p
+PERL_MAGIC_backref|5.007002||p
+PERL_MAGIC_bm|5.007002||p
+PERL_MAGIC_collxfrm|5.007002||p
+PERL_MAGIC_dbfile|5.007002||p
+PERL_MAGIC_dbline|5.007002||p
+PERL_MAGIC_defelem|5.007002||p
+PERL_MAGIC_envelem|5.007002||p
+PERL_MAGIC_env|5.007002||p
+PERL_MAGIC_ext|5.007002||p
+PERL_MAGIC_fm|5.007002||p
+PERL_MAGIC_glob|5.009005||p
+PERL_MAGIC_isaelem|5.007002||p
+PERL_MAGIC_isa|5.007002||p
+PERL_MAGIC_mutex|5.009005||p
+PERL_MAGIC_nkeys|5.007002||p
+PERL_MAGIC_overload_elem|5.007002||p
+PERL_MAGIC_overload_table|5.007002||p
+PERL_MAGIC_overload|5.007002||p
+PERL_MAGIC_pos|5.007002||p
+PERL_MAGIC_qr|5.007002||p
+PERL_MAGIC_regdata|5.007002||p
+PERL_MAGIC_regdatum|5.007002||p
+PERL_MAGIC_regex_global|5.007002||p
+PERL_MAGIC_shared_scalar|5.007003||p
+PERL_MAGIC_shared|5.007003||p
+PERL_MAGIC_sigelem|5.007002||p
+PERL_MAGIC_sig|5.007002||p
+PERL_MAGIC_substr|5.007002||p
+PERL_MAGIC_sv|5.007002||p
+PERL_MAGIC_taint|5.007002||p
+PERL_MAGIC_tiedelem|5.007002||p
+PERL_MAGIC_tiedscalar|5.007002||p
+PERL_MAGIC_tied|5.007002||p
+PERL_MAGIC_utf8|5.008001||p
+PERL_MAGIC_uvar_elem|5.007003||p
+PERL_MAGIC_uvar|5.007002||p
+PERL_MAGIC_vec|5.007002||p
+PERL_MAGIC_vstring|5.008001||p
+PERL_QUAD_MAX|5.004000||p
+PERL_QUAD_MIN|5.004000||p
+PERL_REVISION|5.006000||p
+PERL_SCAN_ALLOW_UNDERSCORES|5.007003||p
+PERL_SCAN_DISALLOW_PREFIX|5.007003||p
+PERL_SCAN_GREATER_THAN_UV_MAX|5.007003||p
+PERL_SCAN_SILENT_ILLDIGIT|5.008001||p
+PERL_SHORT_MAX|5.004000||p
+PERL_SHORT_MIN|5.004000||p
+PERL_SIGNALS_UNSAFE_FLAG|5.008001||p
+PERL_SUBVERSION|5.006000||p
+PERL_UCHAR_MAX|5.004000||p
+PERL_UCHAR_MIN|5.004000||p
+PERL_UINT_MAX|5.004000||p
+PERL_UINT_MIN|5.004000||p
+PERL_ULONG_MAX|5.004000||p
+PERL_ULONG_MIN|5.004000||p
+PERL_UNUSED_ARG|5.009003||p
+PERL_UNUSED_CONTEXT|5.009004||p
+PERL_UNUSED_DECL|5.007002||p
+PERL_UNUSED_VAR|5.007002||p
+PERL_UQUAD_MAX|5.004000||p
+PERL_UQUAD_MIN|5.004000||p
+PERL_USE_GCC_BRACE_GROUPS|5.009004||p
+PERL_USHORT_MAX|5.004000||p
+PERL_USHORT_MIN|5.004000||p
+PERL_VERSION|5.006000||p
+PL_DBsignal|5.005000||p
+PL_DBsingle|||pn
+PL_DBsub|||pn
+PL_DBtrace|||pn
+PL_Sv|5.005000||p
+PL_compiling|5.004050||p
+PL_copline|5.009005||p
+PL_curcop|5.004050||p
+PL_curstash|5.004050||p
+PL_debstash|5.004050||p
+PL_defgv|5.004050||p
+PL_diehook|5.004050||p
+PL_dirty|5.004050||p
+PL_dowarn|||pn
+PL_errgv|5.004050||p
+PL_expect|5.009005||p
+PL_hexdigit|5.005000||p
+PL_hints|5.005000||p
+PL_last_in_gv|||n
+PL_laststatval|5.005000||p
+PL_modglobal||5.005000|n
+PL_na|5.004050||pn
+PL_no_modify|5.006000||p
+PL_ofs_sv|||n
+PL_perl_destruct_level|5.004050||p
+PL_perldb|5.004050||p
+PL_ppaddr|5.006000||p
+PL_rsfp_filters|5.004050||p
+PL_rsfp|5.004050||p
+PL_rs|||n
+PL_signals|5.008001||p
+PL_stack_base|5.004050||p
+PL_stack_sp|5.004050||p
+PL_statcache|5.005000||p
+PL_stdingv|5.004050||p
+PL_sv_arenaroot|5.004050||p
+PL_sv_no|5.004050||pn
+PL_sv_undef|5.004050||pn
+PL_sv_yes|5.004050||pn
+PL_tainted|5.004050||p
+PL_tainting|5.004050||p
+POP_MULTICALL||5.009005|
+POPi|||n
+POPl|||n
+POPn|||n
+POPpbytex||5.007001|n
+POPpx||5.005030|n
+POPp|||n
+POPs|||n
+PTR2IV|5.006000||p
+PTR2NV|5.006000||p
+PTR2UV|5.006000||p
+PTR2ul|5.007001||p
+PTRV|5.006000||p
+PUSHMARK|||
+PUSH_MULTICALL||5.009005|
+PUSHi|||
+PUSHmortal|5.009002||p
+PUSHn|||
+PUSHp|||
+PUSHs|||
+PUSHu|5.004000||p
+PUTBACK|||
+PerlIO_clearerr||5.007003|
+PerlIO_close||5.007003|
+PerlIO_context_layers||5.009004|
+PerlIO_eof||5.007003|
+PerlIO_error||5.007003|
+PerlIO_fileno||5.007003|
+PerlIO_fill||5.007003|
+PerlIO_flush||5.007003|
+PerlIO_get_base||5.007003|
+PerlIO_get_bufsiz||5.007003|
+PerlIO_get_cnt||5.007003|
+PerlIO_get_ptr||5.007003|
+PerlIO_read||5.007003|
+PerlIO_seek||5.007003|
+PerlIO_set_cnt||5.007003|
+PerlIO_set_ptrcnt||5.007003|
+PerlIO_setlinebuf||5.007003|
+PerlIO_stderr||5.007003|
+PerlIO_stdin||5.007003|
+PerlIO_stdout||5.007003|
+PerlIO_tell||5.007003|
+PerlIO_unread||5.007003|
+PerlIO_write||5.007003|
+Perl_signbit||5.009005|n
+PoisonFree|5.009004||p
+PoisonNew|5.009004||p
+PoisonWith|5.009004||p
+Poison|5.008000||p
+RETVAL|||n
+Renewc|||
+Renew|||
+SAVECLEARSV|||
+SAVECOMPPAD|||
+SAVEPADSV|||
+SAVETMPS|||
+SAVE_DEFSV|5.004050||p
+SPAGAIN|||
+SP|||
+START_EXTERN_C|5.005000||p
+START_MY_CXT|5.007003||p
+STMT_END|||p
+STMT_START|||p
+STR_WITH_LEN|5.009003||p
+ST|||
+SV_CONST_RETURN|5.009003||p
+SV_COW_DROP_PV|5.008001||p
+SV_COW_SHARED_HASH_KEYS|5.009005||p
+SV_GMAGIC|5.007002||p
+SV_HAS_TRAILING_NUL|5.009004||p
+SV_IMMEDIATE_UNREF|5.007001||p
+SV_MUTABLE_RETURN|5.009003||p
+SV_NOSTEAL|5.009002||p
+SV_SMAGIC|5.009003||p
+SV_UTF8_NO_ENCODING|5.008001||p
+SVf|5.006000||p
+SVt_IV|||
+SVt_NV|||
+SVt_PVAV|||
+SVt_PVCV|||
+SVt_PVHV|||
+SVt_PVMG|||
+SVt_PV|||
+Safefree|||
+Slab_Alloc|||
+Slab_Free|||
+Slab_to_rw|||
+StructCopy|||
+SvCUR_set|||
+SvCUR|||
+SvEND|||
+SvGAMAGIC||5.006001|
+SvGETMAGIC|5.004050||p
+SvGROW|||
+SvIOK_UV||5.006000|
+SvIOK_notUV||5.006000|
+SvIOK_off|||
+SvIOK_only_UV||5.006000|
+SvIOK_only|||
+SvIOK_on|||
+SvIOKp|||
+SvIOK|||
+SvIVX|||
+SvIV_nomg|5.009001||p
+SvIV_set|||
+SvIVx|||
+SvIV|||
+SvIsCOW_shared_hash||5.008003|
+SvIsCOW||5.008003|
+SvLEN_set|||
+SvLEN|||
+SvLOCK||5.007003|
+SvMAGIC_set|5.009003||p
+SvNIOK_off|||
+SvNIOKp|||
+SvNIOK|||
+SvNOK_off|||
+SvNOK_only|||
+SvNOK_on|||
+SvNOKp|||
+SvNOK|||
+SvNVX|||
+SvNV_set|||
+SvNVx|||
+SvNV|||
+SvOK|||
+SvOOK|||
+SvPOK_off|||
+SvPOK_only_UTF8||5.006000|
+SvPOK_only|||
+SvPOK_on|||
+SvPOKp|||
+SvPOK|||
+SvPVX_const|5.009003||p
+SvPVX_mutable|5.009003||p
+SvPVX|||
+SvPV_const|5.009003||p
+SvPV_flags_const_nolen|5.009003||p
+SvPV_flags_const|5.009003||p
+SvPV_flags_mutable|5.009003||p
+SvPV_flags|5.007002||p
+SvPV_force_flags_mutable|5.009003||p
+SvPV_force_flags_nolen|5.009003||p
+SvPV_force_flags|5.007002||p
+SvPV_force_mutable|5.009003||p
+SvPV_force_nolen|5.009003||p
+SvPV_force_nomg_nolen|5.009003||p
+SvPV_force_nomg|5.007002||p
+SvPV_force|||p
+SvPV_mutable|5.009003||p
+SvPV_nolen_const|5.009003||p
+SvPV_nolen|5.006000||p
+SvPV_nomg_const_nolen|5.009003||p
+SvPV_nomg_const|5.009003||p
+SvPV_nomg|5.007002||p
+SvPV_set|||
+SvPVbyte_force||5.009002|
+SvPVbyte_nolen||5.006000|
+SvPVbytex_force||5.006000|
+SvPVbytex||5.006000|
+SvPVbyte|5.006000||p
+SvPVutf8_force||5.006000|
+SvPVutf8_nolen||5.006000|
+SvPVutf8x_force||5.006000|
+SvPVutf8x||5.006000|
+SvPVutf8||5.006000|
+SvPVx|||
+SvPV|||
+SvREFCNT_dec|||
+SvREFCNT_inc_NN|5.009004||p
+SvREFCNT_inc_simple_NN|5.009004||p
+SvREFCNT_inc_simple_void_NN|5.009004||p
+SvREFCNT_inc_simple_void|5.009004||p
+SvREFCNT_inc_simple|5.009004||p
+SvREFCNT_inc_void_NN|5.009004||p
+SvREFCNT_inc_void|5.009004||p
+SvREFCNT_inc|||p
+SvREFCNT|||
+SvROK_off|||
+SvROK_on|||
+SvROK|||
+SvRV_set|5.009003||p
+SvRV|||
+SvRXOK||5.009005|
+SvRX||5.009005|
+SvSETMAGIC|||
+SvSHARED_HASH|5.009003||p
+SvSHARE||5.007003|
+SvSTASH_set|5.009003||p
+SvSTASH|||
+SvSetMagicSV_nosteal||5.004000|
+SvSetMagicSV||5.004000|
+SvSetSV_nosteal||5.004000|
+SvSetSV|||
+SvTAINTED_off||5.004000|
+SvTAINTED_on||5.004000|
+SvTAINTED||5.004000|
+SvTAINT|||
+SvTRUE|||
+SvTYPE|||
+SvUNLOCK||5.007003|
+SvUOK|5.007001|5.006000|p
+SvUPGRADE|||
+SvUTF8_off||5.006000|
+SvUTF8_on||5.006000|
+SvUTF8||5.006000|
+SvUVXx|5.004000||p
+SvUVX|5.004000||p
+SvUV_nomg|5.009001||p
+SvUV_set|5.009003||p
+SvUVx|5.004000||p
+SvUV|5.004000||p
+SvVOK||5.008001|
+SvVSTRING_mg|5.009004||p
+THIS|||n
+UNDERBAR|5.009002||p
+UTF8_MAXBYTES|5.009002||p
+UVSIZE|5.006000||p
+UVTYPE|5.006000||p
+UVXf|5.007001||p
+UVof|5.006000||p
+UVuf|5.006000||p
+UVxf|5.006000||p
+WARN_ALL|5.006000||p
+WARN_AMBIGUOUS|5.006000||p
+WARN_ASSERTIONS|5.009005||p
+WARN_BAREWORD|5.006000||p
+WARN_CLOSED|5.006000||p
+WARN_CLOSURE|5.006000||p
+WARN_DEBUGGING|5.006000||p
+WARN_DEPRECATED|5.006000||p
+WARN_DIGIT|5.006000||p
+WARN_EXEC|5.006000||p
+WARN_EXITING|5.006000||p
+WARN_GLOB|5.006000||p
+WARN_INPLACE|5.006000||p
+WARN_INTERNAL|5.006000||p
+WARN_IO|5.006000||p
+WARN_LAYER|5.008000||p
+WARN_MALLOC|5.006000||p
+WARN_MISC|5.006000||p
+WARN_NEWLINE|5.006000||p
+WARN_NUMERIC|5.006000||p
+WARN_ONCE|5.006000||p
+WARN_OVERFLOW|5.006000||p
+WARN_PACK|5.006000||p
+WARN_PARENTHESIS|5.006000||p
+WARN_PIPE|5.006000||p
+WARN_PORTABLE|5.006000||p
+WARN_PRECEDENCE|5.006000||p
+WARN_PRINTF|5.006000||p
+WARN_PROTOTYPE|5.006000||p
+WARN_QW|5.006000||p
+WARN_RECURSION|5.006000||p
+WARN_REDEFINE|5.006000||p
+WARN_REGEXP|5.006000||p
+WARN_RESERVED|5.006000||p
+WARN_SEMICOLON|5.006000||p
+WARN_SEVERE|5.006000||p
+WARN_SIGNAL|5.006000||p
+WARN_SUBSTR|5.006000||p
+WARN_SYNTAX|5.006000||p
+WARN_TAINT|5.006000||p
+WARN_THREADS|5.008000||p
+WARN_UNINITIALIZED|5.006000||p
+WARN_UNOPENED|5.006000||p
+WARN_UNPACK|5.006000||p
+WARN_UNTIE|5.006000||p
+WARN_UTF8|5.006000||p
+WARN_VOID|5.006000||p
+XCPT_CATCH|5.009002||p
+XCPT_RETHROW|5.009002||p
+XCPT_TRY_END|5.009002||p
+XCPT_TRY_START|5.009002||p
+XPUSHi|||
+XPUSHmortal|5.009002||p
+XPUSHn|||
+XPUSHp|||
+XPUSHs|||
+XPUSHu|5.004000||p
+XSRETURN_EMPTY|||
+XSRETURN_IV|||
+XSRETURN_NO|||
+XSRETURN_NV|||
+XSRETURN_PV|||
+XSRETURN_UNDEF|||
+XSRETURN_UV|5.008001||p
+XSRETURN_YES|||
+XSRETURN|||p
+XST_mIV|||
+XST_mNO|||
+XST_mNV|||
+XST_mPV|||
+XST_mUNDEF|||
+XST_mUV|5.008001||p
+XST_mYES|||
+XS_VERSION_BOOTCHECK|||
+XS_VERSION|||
+XSprePUSH|5.006000||p
+XS|||
+ZeroD|5.009002||p
+Zero|||
+_aMY_CXT|5.007003||p
+_pMY_CXT|5.007003||p
+aMY_CXT_|5.007003||p
+aMY_CXT|5.007003||p
+aTHXR_|5.009005||p
+aTHXR|5.009005||p
+aTHX_|5.006000||p
+aTHX|5.006000||p
+add_data|||n
+addmad|||
+allocmy|||
+amagic_call|||
+amagic_cmp_locale|||
+amagic_cmp|||
+amagic_i_ncmp|||
+amagic_ncmp|||
+any_dup|||
+ao|||
+append_elem|||
+append_list|||
+append_madprops|||
+apply_attrs_my|||
+apply_attrs_string||5.006001|
+apply_attrs|||
+apply|||
+atfork_lock||5.007003|n
+atfork_unlock||5.007003|n
+av_arylen_p||5.009003|
+av_clear|||
+av_create_and_push||5.009005|
+av_create_and_unshift_one||5.009005|
+av_delete||5.006000|
+av_exists||5.006000|
+av_extend|||
+av_fake|||
+av_fetch|||
+av_fill|||
+av_len|||
+av_make|||
+av_pop|||
+av_push|||
+av_reify|||
+av_shift|||
+av_store|||
+av_undef|||
+av_unshift|||
+ax|||n
+bad_type|||
+bind_match|||
+block_end|||
+block_gimme||5.004000|
+block_start|||
+boolSV|5.004000||p
+boot_core_PerlIO|||
+boot_core_UNIVERSAL|||
+boot_core_mro|||
+boot_core_xsutils|||
+bytes_from_utf8||5.007001|
+bytes_to_uni|||n
+bytes_to_utf8||5.006001|
+call_argv|5.006000||p
+call_atexit||5.006000|
+call_list||5.004000|
+call_method|5.006000||p
+call_pv|5.006000||p
+call_sv|5.006000||p
+calloc||5.007002|n
+cando|||
+cast_i32||5.006000|
+cast_iv||5.006000|
+cast_ulong||5.006000|
+cast_uv||5.006000|
+check_type_and_open|||
+check_uni|||
+checkcomma|||
+checkposixcc|||
+ckWARN|5.006000||p
+ck_anoncode|||
+ck_bitop|||
+ck_concat|||
+ck_defined|||
+ck_delete|||
+ck_die|||
+ck_eof|||
+ck_eval|||
+ck_exec|||
+ck_exists|||
+ck_exit|||
+ck_ftst|||
+ck_fun|||
+ck_glob|||
+ck_grep|||
+ck_index|||
+ck_join|||
+ck_lengthconst|||
+ck_lfun|||
+ck_listiob|||
+ck_match|||
+ck_method|||
+ck_null|||
+ck_open|||
+ck_readline|||
+ck_repeat|||
+ck_require|||
+ck_retarget|||
+ck_return|||
+ck_rfun|||
+ck_rvconst|||
+ck_sassign|||
+ck_select|||
+ck_shift|||
+ck_sort|||
+ck_spair|||
+ck_split|||
+ck_subr|||
+ck_substr|||
+ck_svconst|||
+ck_trunc|||
+ck_unpack|||
+ckwarn_d||5.009003|
+ckwarn||5.009003|
+cl_and|||n
+cl_anything|||n
+cl_init_zero|||n
+cl_init|||n
+cl_is_anything|||n
+cl_or|||n
+clear_placeholders|||
+closest_cop|||
+convert|||
+cop_free|||
+cr_textfilter|||
+create_eval_scope|||
+croak_nocontext|||vn
+croak|||v
+csighandler||5.009003|n
+curmad|||
+custom_op_desc||5.007003|
+custom_op_name||5.007003|
+cv_ckproto_len|||
+cv_ckproto|||
+cv_clone|||
+cv_const_sv||5.004000|
+cv_dump|||
+cv_undef|||
+cx_dump||5.005000|
+cx_dup|||
+cxinc|||
+dAXMARK|5.009003||p
+dAX|5.007002||p
+dITEMS|5.007002||p
+dMARK|||
+dMULTICALL||5.009003|
+dMY_CXT_SV|5.007003||p
+dMY_CXT|5.007003||p
+dNOOP|5.006000||p
+dORIGMARK|||
+dSP|||
+dTHR|5.004050||p
+dTHXR|5.009005||p
+dTHXa|5.006000||p
+dTHXoa|5.006000||p
+dTHX|5.006000||p
+dUNDERBAR|5.009002||p
+dVAR|5.009003||p
+dXCPT|5.009002||p
+dXSARGS|||
+dXSI32|||
+dXSTARG|5.006000||p
+deb_curcv|||
+deb_nocontext|||vn
+deb_stack_all|||
+deb_stack_n|||
+debop||5.005000|
+debprofdump||5.005000|
+debprof|||
+debstackptrs||5.007003|
+debstack||5.007003|
+debug_start_match|||
+deb||5.007003|v
+del_sv|||
+delete_eval_scope|||
+delimcpy||5.004000|
+deprecate_old|||
+deprecate|||
+despatch_signals||5.007001|
+destroy_matcher|||
+die_nocontext|||vn
+die_where|||
+die|||v
+dirp_dup|||
+div128|||
+djSP|||
+do_aexec5|||
+do_aexec|||
+do_aspawn|||
+do_binmode||5.004050|
+do_chomp|||
+do_chop|||
+do_close|||
+do_dump_pad|||
+do_eof|||
+do_exec3|||
+do_execfree|||
+do_exec|||
+do_gv_dump||5.006000|
+do_gvgv_dump||5.006000|
+do_hv_dump||5.006000|
+do_ipcctl|||
+do_ipcget|||
+do_join|||
+do_kv|||
+do_magic_dump||5.006000|
+do_msgrcv|||
+do_msgsnd|||
+do_oddball|||
+do_op_dump||5.006000|
+do_op_xmldump|||
+do_open9||5.006000|
+do_openn||5.007001|
+do_open||5.004000|
+do_pipe|||
+do_pmop_dump||5.006000|
+do_pmop_xmldump|||
+do_print|||
+do_readline|||
+do_seek|||
+do_semop|||
+do_shmio|||
+do_smartmatch|||
+do_spawn_nowait|||
+do_spawn|||
+do_sprintf|||
+do_sv_dump||5.006000|
+do_sysseek|||
+do_tell|||
+do_trans_complex_utf8|||
+do_trans_complex|||
+do_trans_count_utf8|||
+do_trans_count|||
+do_trans_simple_utf8|||
+do_trans_simple|||
+do_trans|||
+do_vecget|||
+do_vecset|||
+do_vop|||
+docatch_body|||
+docatch|||
+doeval|||
+dofile|||
+dofindlabel|||
+doform|||
+doing_taint||5.008001|n
+dooneliner|||
+doopen_pm|||
+doparseform|||
+dopoptoeval|||
+dopoptogiven|||
+dopoptolabel|||
+dopoptoloop|||
+dopoptosub_at|||
+dopoptosub|||
+dopoptowhen|||
+doref||5.009003|
+dounwind|||
+dowantarray|||
+dump_all||5.006000|
+dump_eval||5.006000|
+dump_exec_pos|||
+dump_fds|||
+dump_form||5.006000|
+dump_indent||5.006000|v
+dump_mstats|||
+dump_packsubs||5.006000|
+dump_sub||5.006000|
+dump_sv_child|||
+dump_trie_interim_list|||
+dump_trie_interim_table|||
+dump_trie|||
+dump_vindent||5.006000|
+dumpuntil|||
+dup_attrlist|||
+emulate_cop_io|||
+emulate_eaccess|||
+eval_pv|5.006000||p
+eval_sv|5.006000||p
+exec_failed|||
+expect_number|||
+fbm_compile||5.005000|
+fbm_instr||5.005000|
+fd_on_nosuid_fs|||
+feature_is_enabled|||
+filter_add|||
+filter_del|||
+filter_gets|||
+filter_read|||
+find_and_forget_pmops|||
+find_array_subscript|||
+find_beginning|||
+find_byclass|||
+find_hash_subscript|||
+find_in_my_stash|||
+find_runcv||5.008001|
+find_rundefsvoffset||5.009002|
+find_script|||
+find_uninit_var|||
+first_symbol|||n
+fold_constants|||
+forbid_setid|||
+force_ident|||
+force_list|||
+force_next|||
+force_version|||
+force_word|||
+forget_pmop|||
+form_nocontext|||vn
+form||5.004000|v
+fp_dup|||
+fprintf_nocontext|||vn
+free_global_struct|||
+free_tied_hv_pool|||
+free_tmps|||
+gen_constant_list|||
+get_arena|||
+get_av|5.006000||p
+get_context||5.006000|n
+get_cvn_flags||5.009005|
+get_cv|5.006000||p
+get_db_sub|||
+get_debug_opts|||
+get_hash_seed|||
+get_hv|5.006000||p
+get_mstats|||
+get_no_modify|||
+get_num|||
+get_op_descs||5.005000|
+get_op_names||5.005000|
+get_opargs|||
+get_ppaddr||5.006000|
+get_re_arg|||
+get_sv|5.006000||p
+get_vtbl||5.005030|
+getcwd_sv||5.007002|
+getenv_len|||
+glob_2number|||
+glob_2pv|||
+glob_assign_glob|||
+glob_assign_ref|||
+gp_dup|||
+gp_free|||
+gp_ref|||
+grok_bin|5.007003||p
+grok_hex|5.007003||p
+grok_number|5.007002||p
+grok_numeric_radix|5.007002||p
+grok_oct|5.007003||p
+group_end|||
+gv_AVadd|||
+gv_HVadd|||
+gv_IOadd|||
+gv_SVadd|||
+gv_autoload4||5.004000|
+gv_check|||
+gv_const_sv||5.009003|
+gv_dump||5.006000|
+gv_efullname3||5.004000|
+gv_efullname4||5.006001|
+gv_efullname|||
+gv_ename|||
+gv_fetchfile_flags||5.009005|
+gv_fetchfile|||
+gv_fetchmeth_autoload||5.007003|
+gv_fetchmethod_autoload||5.004000|
+gv_fetchmethod|||
+gv_fetchmeth|||
+gv_fetchpvn_flags||5.009002|
+gv_fetchpv|||
+gv_fetchsv||5.009002|
+gv_fullname3||5.004000|
+gv_fullname4||5.006001|
+gv_fullname|||
+gv_handler||5.007001|
+gv_init_sv|||
+gv_init|||
+gv_name_set||5.009004|
+gv_stashpvn|5.004000||p
+gv_stashpvs||5.009003|
+gv_stashpv|||
+gv_stashsv|||
+he_dup|||
+hek_dup|||
+hfreeentries|||
+hsplit|||
+hv_assert||5.009005|
+hv_auxinit|||n
+hv_backreferences_p|||
+hv_clear_placeholders||5.009001|
+hv_clear|||
+hv_copy_hints_hv|||
+hv_delayfree_ent||5.004000|
+hv_delete_common|||
+hv_delete_ent||5.004000|
+hv_delete|||
+hv_eiter_p||5.009003|
+hv_eiter_set||5.009003|
+hv_exists_ent||5.004000|
+hv_exists|||
+hv_fetch_common|||
+hv_fetch_ent||5.004000|
+hv_fetchs|5.009003||p
+hv_fetch|||
+hv_free_ent||5.004000|
+hv_iterinit|||
+hv_iterkeysv||5.004000|
+hv_iterkey|||
+hv_iternext_flags||5.008000|
+hv_iternextsv|||
+hv_iternext|||
+hv_iterval|||
+hv_kill_backrefs|||
+hv_ksplit||5.004000|
+hv_magic_check|||n
+hv_magic_uvar_xkey|||
+hv_magic|||
+hv_name_set||5.009003|
+hv_notallowed|||
+hv_placeholders_get||5.009003|
+hv_placeholders_p||5.009003|
+hv_placeholders_set||5.009003|
+hv_riter_p||5.009003|
+hv_riter_set||5.009003|
+hv_scalar||5.009001|
+hv_store_ent||5.004000|
+hv_store_flags||5.008000|
+hv_stores|5.009004||p
+hv_store|||
+hv_undef|||
+ibcmp_locale||5.004000|
+ibcmp_utf8||5.007003|
+ibcmp|||
+incl_perldb|||
+incline|||
+incpush_if_exists|||
+incpush|||
+ingroup|||
+init_argv_symbols|||
+init_debugger|||
+init_global_struct|||
+init_i18nl10n||5.006000|
+init_i18nl14n||5.006000|
+init_ids|||
+init_interp|||
+init_main_stash|||
+init_perllib|||
+init_postdump_symbols|||
+init_predump_symbols|||
+init_stacks||5.005000|
+init_tm||5.007002|
+instr|||
+intro_my|||
+intuit_method|||
+intuit_more|||
+invert|||
+io_close|||
+isALNUM|||
+isALPHA|||
+isDIGIT|||
+isLOWER|||
+isSPACE|||
+isUPPER|||
+is_an_int|||
+is_gv_magical_sv|||
+is_gv_magical|||
+is_handle_constructor|||n
+is_list_assignment|||
+is_lvalue_sub||5.007001|
+is_uni_alnum_lc||5.006000|
+is_uni_alnumc_lc||5.006000|
+is_uni_alnumc||5.006000|
+is_uni_alnum||5.006000|
+is_uni_alpha_lc||5.006000|
+is_uni_alpha||5.006000|
+is_uni_ascii_lc||5.006000|
+is_uni_ascii||5.006000|
+is_uni_cntrl_lc||5.006000|
+is_uni_cntrl||5.006000|
+is_uni_digit_lc||5.006000|
+is_uni_digit||5.006000|
+is_uni_graph_lc||5.006000|
+is_uni_graph||5.006000|
+is_uni_idfirst_lc||5.006000|
+is_uni_idfirst||5.006000|
+is_uni_lower_lc||5.006000|
+is_uni_lower||5.006000|
+is_uni_print_lc||5.006000|
+is_uni_print||5.006000|
+is_uni_punct_lc||5.006000|
+is_uni_punct||5.006000|
+is_uni_space_lc||5.006000|
+is_uni_space||5.006000|
+is_uni_upper_lc||5.006000|
+is_uni_upper||5.006000|
+is_uni_xdigit_lc||5.006000|
+is_uni_xdigit||5.006000|
+is_utf8_alnumc||5.006000|
+is_utf8_alnum||5.006000|
+is_utf8_alpha||5.006000|
+is_utf8_ascii||5.006000|
+is_utf8_char_slow|||n
+is_utf8_char||5.006000|
+is_utf8_cntrl||5.006000|
+is_utf8_common|||
+is_utf8_digit||5.006000|
+is_utf8_graph||5.006000|
+is_utf8_idcont||5.008000|
+is_utf8_idfirst||5.006000|
+is_utf8_lower||5.006000|
+is_utf8_mark||5.006000|
+is_utf8_print||5.006000|
+is_utf8_punct||5.006000|
+is_utf8_space||5.006000|
+is_utf8_string_loclen||5.009003|
+is_utf8_string_loc||5.008001|
+is_utf8_string||5.006001|
+is_utf8_upper||5.006000|
+is_utf8_xdigit||5.006000|
+isa_lookup|||
+items|||n
+ix|||n
+jmaybe|||
+join_exact|||
+keyword|||
+leave_scope|||
+lex_end|||
+lex_start|||
+linklist|||
+listkids|||
+list|||
+load_module_nocontext|||vn
+load_module|5.006000||pv
+localize|||
+looks_like_bool|||
+looks_like_number|||
+lop|||
+mPUSHi|5.009002||p
+mPUSHn|5.009002||p
+mPUSHp|5.009002||p
+mPUSHu|5.009002||p
+mXPUSHi|5.009002||p
+mXPUSHn|5.009002||p
+mXPUSHp|5.009002||p
+mXPUSHu|5.009002||p
+mad_free|||
+madlex|||
+madparse|||
+magic_clear_all_env|||
+magic_clearenv|||
+magic_clearhint|||
+magic_clearpack|||
+magic_clearsig|||
+magic_dump||5.006000|
+magic_existspack|||
+magic_freearylen_p|||
+magic_freeovrld|||
+magic_freeregexp|||
+magic_getarylen|||
+magic_getdefelem|||
+magic_getnkeys|||
+magic_getpack|||
+magic_getpos|||
+magic_getsig|||
+magic_getsubstr|||
+magic_gettaint|||
+magic_getuvar|||
+magic_getvec|||
+magic_get|||
+magic_killbackrefs|||
+magic_len|||
+magic_methcall|||
+magic_methpack|||
+magic_nextpack|||
+magic_regdata_cnt|||
+magic_regdatum_get|||
+magic_regdatum_set|||
+magic_scalarpack|||
+magic_set_all_env|||
+magic_setamagic|||
+magic_setarylen|||
+magic_setbm|||
+magic_setcollxfrm|||
+magic_setdbline|||
+magic_setdefelem|||
+magic_setenv|||
+magic_setfm|||
+magic_setglob|||
+magic_sethint|||
+magic_setisa|||
+magic_setmglob|||
+magic_setnkeys|||
+magic_setpack|||
+magic_setpos|||
+magic_setregexp|||
+magic_setsig|||
+magic_setsubstr|||
+magic_settaint|||
+magic_setutf8|||
+magic_setuvar|||
+magic_setvec|||
+magic_set|||
+magic_sizepack|||
+magic_wipepack|||
+magicname|||
+make_matcher|||
+make_trie_failtable|||
+make_trie|||
+malloced_size|||n
+malloc||5.007002|n
+markstack_grow|||
+matcher_matches_sv|||
+measure_struct|||
+memEQ|5.004000||p
+memNE|5.004000||p
+mem_collxfrm|||
+mess_alloc|||
+mess_nocontext|||vn
+mess||5.006000|v
+method_common|||
+mfree||5.007002|n
+mg_clear|||
+mg_copy|||
+mg_dup|||
+mg_find|||
+mg_free|||
+mg_get|||
+mg_length||5.005000|
+mg_localize|||
+mg_magical|||
+mg_set|||
+mg_size||5.005000|
+mini_mktime||5.007002|
+missingterm|||
+mode_from_discipline|||
+modkids|||
+mod|||
+more_bodies|||
+more_sv|||
+moreswitches|||
+mro_get_linear_isa_c3||5.009005|
+mro_get_linear_isa_dfs||5.009005|
+mro_get_linear_isa||5.009005|
+mro_isa_changed_in|||
+mro_meta_dup|||
+mro_meta_init|||
+mro_method_changed_in||5.009005|
+mul128|||
+mulexp10|||n
+my_atof2||5.007002|
+my_atof||5.006000|
+my_attrs|||
+my_bcopy|||n
+my_betoh16|||n
+my_betoh32|||n
+my_betoh64|||n
+my_betohi|||n
+my_betohl|||n
+my_betohs|||n
+my_bzero|||n
+my_chsize|||
+my_clearenv|||
+my_cxt_index|||
+my_cxt_init|||
+my_dirfd||5.009005|
+my_exit_jump|||
+my_exit|||
+my_failure_exit||5.004000|
+my_fflush_all||5.006000|
+my_fork||5.007003|n
+my_htobe16|||n
+my_htobe32|||n
+my_htobe64|||n
+my_htobei|||n
+my_htobel|||n
+my_htobes|||n
+my_htole16|||n
+my_htole32|||n
+my_htole64|||n
+my_htolei|||n
+my_htolel|||n
+my_htoles|||n
+my_htonl|||
+my_kid|||
+my_letoh16|||n
+my_letoh32|||n
+my_letoh64|||n
+my_letohi|||n
+my_letohl|||n
+my_letohs|||n
+my_lstat|||
+my_memcmp||5.004000|n
+my_memset|||n
+my_ntohl|||
+my_pclose||5.004000|
+my_popen_list||5.007001|
+my_popen||5.004000|
+my_setenv|||
+my_snprintf|5.009004||pvn
+my_socketpair||5.007003|n
+my_sprintf||5.009003|vn
+my_stat|||
+my_strftime||5.007002|
+my_strlcat|5.009004||pn
+my_strlcpy|5.009004||pn
+my_swabn|||n
+my_swap|||
+my_unexec|||
+my_vsnprintf||5.009004|n
+my|||
+need_utf8|||n
+newANONATTRSUB||5.006000|
+newANONHASH|||
+newANONLIST|||
+newANONSUB|||
+newASSIGNOP|||
+newATTRSUB||5.006000|
+newAVREF|||
+newAV|||
+newBINOP|||
+newCONDOP|||
+newCONSTSUB|5.004050||p
+newCVREF|||
+newDEFSVOP|||
+newFORM|||
+newFOROP|||
+newGIVENOP||5.009003|
+newGIVWHENOP|||
+newGP|||
+newGVOP|||
+newGVREF|||
+newGVgen|||
+newHVREF|||
+newHVhv||5.005000|
+newHV|||
+newIO|||
+newLISTOP|||
+newLOGOP|||
+newLOOPEX|||
+newLOOPOP|||
+newMADPROP|||
+newMADsv|||
+newMYSUB|||
+newNULLLIST|||
+newOP|||
+newPADOP|||
+newPMOP|||
+newPROG|||
+newPVOP|||
+newRANGE|||
+newRV_inc|5.004000||p
+newRV_noinc|5.004000||p
+newRV|||
+newSLICEOP|||
+newSTATEOP|||
+newSUB|||
+newSVOP|||
+newSVREF|||
+newSV_type||5.009005|
+newSVhek||5.009003|
+newSViv|||
+newSVnv|||
+newSVpvf_nocontext|||vn
+newSVpvf||5.004000|v
+newSVpvn_share|5.007001||p
+newSVpvn|5.004050||p
+newSVpvs_share||5.009003|
+newSVpvs|5.009003||p
+newSVpv|||
+newSVrv|||
+newSVsv|||
+newSVuv|5.006000||p
+newSV|||
+newTOKEN|||
+newUNOP|||
+newWHENOP||5.009003|
+newWHILEOP||5.009003|
+newXS_flags||5.009004|
+newXSproto||5.006000|
+newXS||5.006000|
+new_collate||5.006000|
+new_constant|||
+new_ctype||5.006000|
+new_he|||
+new_logop|||
+new_numeric||5.006000|
+new_stackinfo||5.005000|
+new_version||5.009000|
+new_warnings_bitfield|||
+next_symbol|||
+nextargv|||
+nextchar|||
+ninstr|||
+no_bareword_allowed|||
+no_fh_allowed|||
+no_op|||
+not_a_number|||
+nothreadhook||5.008000|
+nuke_stacks|||
+num_overflow|||n
+offer_nice_chunk|||
+oopsAV|||
+oopsCV|||
+oopsHV|||
+op_clear|||
+op_const_sv|||
+op_dump||5.006000|
+op_free|||
+op_getmad_weak|||
+op_getmad|||
+op_null||5.007002|
+op_refcnt_dec|||
+op_refcnt_inc|||
+op_refcnt_lock||5.009002|
+op_refcnt_unlock||5.009002|
+op_xmldump|||
+open_script|||
+pMY_CXT_|5.007003||p
+pMY_CXT|5.007003||p
+pTHX_|5.006000||p
+pTHX|5.006000||p
+packWARN|5.007003||p
+pack_cat||5.007003|
+pack_rec|||
+package|||
+packlist||5.008001|
+pad_add_anon|||
+pad_add_name|||
+pad_alloc|||
+pad_block_start|||
+pad_check_dup|||
+pad_compname_type|||
+pad_findlex|||
+pad_findmy|||
+pad_fixup_inner_anons|||
+pad_free|||
+pad_leavemy|||
+pad_new|||
+pad_peg|||n
+pad_push|||
+pad_reset|||
+pad_setsv|||
+pad_sv||5.009005|
+pad_swipe|||
+pad_tidy|||
+pad_undef|||
+parse_body|||
+parse_unicode_opts|||
+parser_dup|||
+parser_free|||
+path_is_absolute|||n
+peep|||
+pending_Slabs_to_ro|||
+perl_alloc_using|||n
+perl_alloc|||n
+perl_clone_using|||n
+perl_clone|||n
+perl_construct|||n
+perl_destruct||5.007003|n
+perl_free|||n
+perl_parse||5.006000|n
+perl_run|||n
+pidgone|||
+pm_description|||
+pmflag|||
+pmop_dump||5.006000|
+pmop_xmldump|||
+pmruntime|||
+pmtrans|||
+pop_scope|||
+pregcomp||5.009005|
+pregexec|||
+pregfree|||
+prepend_elem|||
+prepend_madprops|||
+printbuf|||
+printf_nocontext|||vn
+process_special_blocks|||
+ptr_table_clear||5.009005|
+ptr_table_fetch||5.009005|
+ptr_table_find|||n
+ptr_table_free||5.009005|
+ptr_table_new||5.009005|
+ptr_table_split||5.009005|
+ptr_table_store||5.009005|
+push_scope|||
+put_byte|||
+pv_display||5.006000|
+pv_escape||5.009004|
+pv_pretty||5.009004|
+pv_uni_display||5.007003|
+qerror|||
+qsortsvu|||
+re_compile||5.009005|
+re_croak2|||
+re_dup|||
+re_intuit_start||5.009005|
+re_intuit_string||5.006000|
+readpipe_override|||
+realloc||5.007002|n
+reentrant_free|||
+reentrant_init|||
+reentrant_retry|||vn
+reentrant_size|||
+ref_array_or_hash|||
+refcounted_he_chain_2hv|||
+refcounted_he_fetch|||
+refcounted_he_free|||
+refcounted_he_new|||
+refcounted_he_value|||
+refkids|||
+refto|||
+ref||5.009003|
+reg_check_named_buff_matched|||
+reg_named_buff_all||5.009005|
+reg_named_buff_exists||5.009005|
+reg_named_buff_fetch||5.009005|
+reg_named_buff_firstkey||5.009005|
+reg_named_buff_iter|||
+reg_named_buff_nextkey||5.009005|
+reg_named_buff_scalar||5.009005|
+reg_named_buff|||
+reg_namedseq|||
+reg_node|||
+reg_numbered_buff_fetch|||
+reg_numbered_buff_length|||
+reg_numbered_buff_store|||
+reg_qr_package|||
+reg_recode|||
+reg_scan_name|||
+reg_skipcomment|||
+reg_stringify||5.009005|
+reg_temp_copy|||
+reganode|||
+regatom|||
+regbranch|||
+regclass_swash||5.009004|
+regclass|||
+regcppop|||
+regcppush|||
+regcurly|||n
+regdump_extflags|||
+regdump||5.005000|
+regdupe_internal|||
+regexec_flags||5.005000|
+regfree_internal||5.009005|
+reghop3|||n
+reghop4|||n
+reghopmaybe3|||n
+reginclass|||
+reginitcolors||5.006000|
+reginsert|||
+regmatch|||
+regnext||5.005000|
+regpiece|||
+regpposixcc|||
+regprop|||
+regrepeat|||
+regtail_study|||
+regtail|||
+regtry|||
+reguni|||
+regwhite|||n
+reg|||
+repeatcpy|||
+report_evil_fh|||
+report_uninit|||
+require_pv||5.006000|
+require_tie_mod|||
+restore_magic|||
+rninstr|||
+rsignal_restore|||
+rsignal_save|||
+rsignal_state||5.004000|
+rsignal||5.004000|
+run_body|||
+run_user_filter|||
+runops_debug||5.005000|
+runops_standard||5.005000|
+rvpv_dup|||
+rxres_free|||
+rxres_restore|||
+rxres_save|||
+safesyscalloc||5.006000|n
+safesysfree||5.006000|n
+safesysmalloc||5.006000|n
+safesysrealloc||5.006000|n
+same_dirent|||
+save_I16||5.004000|
+save_I32|||
+save_I8||5.006000|
+save_aelem||5.004050|
+save_alloc||5.006000|
+save_aptr|||
+save_ary|||
+save_bool||5.008001|
+save_clearsv|||
+save_delete|||
+save_destructor_x||5.006000|
+save_destructor||5.006000|
+save_freeop|||
+save_freepv|||
+save_freesv|||
+save_generic_pvref||5.006001|
+save_generic_svref||5.005030|
+save_gp||5.004000|
+save_hash|||
+save_hek_flags|||n
+save_helem||5.004050|
+save_hints||5.005000|
+save_hptr|||
+save_int|||
+save_item|||
+save_iv||5.005000|
+save_lines|||
+save_list|||
+save_long|||
+save_magic|||
+save_mortalizesv||5.007001|
+save_nogv|||
+save_op|||
+save_padsv||5.007001|
+save_pptr|||
+save_re_context||5.006000|
+save_scalar_at|||
+save_scalar|||
+save_set_svflags||5.009000|
+save_shared_pvref||5.007003|
+save_sptr|||
+save_svref|||
+save_vptr||5.006000|
+savepvn|||
+savepvs||5.009003|
+savepv|||
+savesharedpvn||5.009005|
+savesharedpv||5.007003|
+savestack_grow_cnt||5.008001|
+savestack_grow|||
+savesvpv||5.009002|
+sawparens|||
+scalar_mod_type|||n
+scalarboolean|||
+scalarkids|||
+scalarseq|||
+scalarvoid|||
+scalar|||
+scan_bin||5.006000|
+scan_commit|||
+scan_const|||
+scan_formline|||
+scan_heredoc|||
+scan_hex|||
+scan_ident|||
+scan_inputsymbol|||
+scan_num||5.007001|
+scan_oct|||
+scan_pat|||
+scan_str|||
+scan_subst|||
+scan_trans|||
+scan_version||5.009001|
+scan_vstring||5.009005|
+scan_word|||
+scope|||
+screaminstr||5.005000|
+seed||5.008001|
+sequence_num|||
+sequence_tail|||
+sequence|||
+set_context||5.006000|n
+set_csh|||
+set_numeric_local||5.006000|
+set_numeric_radix||5.006000|
+set_numeric_standard||5.006000|
+setdefout|||
+setenv_getix|||
+share_hek_flags|||
+share_hek||5.004000|
+si_dup|||
+sighandler|||n
+simplify_sort|||
+skipspace0|||
+skipspace1|||
+skipspace2|||
+skipspace|||
+softref2xv|||
+sortcv_stacked|||
+sortcv_xsub|||
+sortcv|||
+sortsv_flags||5.009003|
+sortsv||5.007003|
+space_join_names_mortal|||
+ss_dup|||
+stack_grow|||
+start_force|||
+start_glob|||
+start_subparse||5.004000|
+stashpv_hvname_match||5.009005|
+stdize_locale|||
+strEQ|||
+strGE|||
+strGT|||
+strLE|||
+strLT|||
+strNE|||
+str_to_version||5.006000|
+strip_return|||
+strnEQ|||
+strnNE|||
+study_chunk|||
+sub_crush_depth|||
+sublex_done|||
+sublex_push|||
+sublex_start|||
+sv_2bool|||
+sv_2cv|||
+sv_2io|||
+sv_2iuv_common|||
+sv_2iuv_non_preserve|||
+sv_2iv_flags||5.009001|
+sv_2iv|||
+sv_2mortal|||
+sv_2nv|||
+sv_2pv_flags|5.007002||p
+sv_2pv_nolen|5.006000||p
+sv_2pvbyte_nolen|5.006000||p
+sv_2pvbyte|5.006000||p
+sv_2pvutf8_nolen||5.006000|
+sv_2pvutf8||5.006000|
+sv_2pv|||
+sv_2uv_flags||5.009001|
+sv_2uv|5.004000||p
+sv_add_arena|||
+sv_add_backref|||
+sv_backoff|||
+sv_bless|||
+sv_cat_decode||5.008001|
+sv_catpv_mg|5.004050||p
+sv_catpvf_mg_nocontext|||pvn
+sv_catpvf_mg|5.006000|5.004000|pv
+sv_catpvf_nocontext|||vn
+sv_catpvf||5.004000|v
+sv_catpvn_flags||5.007002|
+sv_catpvn_mg|5.004050||p
+sv_catpvn_nomg|5.007002||p
+sv_catpvn|||
+sv_catpvs|5.009003||p
+sv_catpv|||
+sv_catsv_flags||5.007002|
+sv_catsv_mg|5.004050||p
+sv_catsv_nomg|5.007002||p
+sv_catsv|||
+sv_catxmlpvn|||
+sv_catxmlsv|||
+sv_chop|||
+sv_clean_all|||
+sv_clean_objs|||
+sv_clear|||
+sv_cmp_locale||5.004000|
+sv_cmp|||
+sv_collxfrm|||
+sv_compile_2op||5.008001|
+sv_copypv||5.007003|
+sv_dec|||
+sv_del_backref|||
+sv_derived_from||5.004000|
+sv_does||5.009004|
+sv_dump|||
+sv_dup|||
+sv_eq|||
+sv_exp_grow|||
+sv_force_normal_flags||5.007001|
+sv_force_normal||5.006000|
+sv_free2|||
+sv_free_arenas|||
+sv_free|||
+sv_gets||5.004000|
+sv_grow|||
+sv_i_ncmp|||
+sv_inc|||
+sv_insert|||
+sv_isa|||
+sv_isobject|||
+sv_iv||5.005000|
+sv_kill_backrefs|||
+sv_len_utf8||5.006000|
+sv_len|||
+sv_magic_portable|5.009005|5.004000|p
+sv_magicext||5.007003|
+sv_magic|||
+sv_mortalcopy|||
+sv_ncmp|||
+sv_newmortal|||
+sv_newref|||
+sv_nolocking||5.007003|
+sv_nosharing||5.007003|
+sv_nounlocking|||
+sv_nv||5.005000|
+sv_peek||5.005000|
+sv_pos_b2u_midway|||
+sv_pos_b2u||5.006000|
+sv_pos_u2b_cached|||
+sv_pos_u2b_forwards|||n
+sv_pos_u2b_midway|||n
+sv_pos_u2b||5.006000|
+sv_pvbyten_force||5.006000|
+sv_pvbyten||5.006000|
+sv_pvbyte||5.006000|
+sv_pvn_force_flags|5.007002||p
+sv_pvn_force|||
+sv_pvn_nomg|5.007003||p
+sv_pvn|||
+sv_pvutf8n_force||5.006000|
+sv_pvutf8n||5.006000|
+sv_pvutf8||5.006000|
+sv_pv||5.006000|
+sv_recode_to_utf8||5.007003|
+sv_reftype|||
+sv_release_COW|||
+sv_replace|||
+sv_report_used|||
+sv_reset|||
+sv_rvweaken||5.006000|
+sv_setiv_mg|5.004050||p
+sv_setiv|||
+sv_setnv_mg|5.006000||p
+sv_setnv|||
+sv_setpv_mg|5.004050||p
+sv_setpvf_mg_nocontext|||pvn
+sv_setpvf_mg|5.006000|5.004000|pv
+sv_setpvf_nocontext|||vn
+sv_setpvf||5.004000|v
+sv_setpviv_mg||5.008001|
+sv_setpviv||5.008001|
+sv_setpvn_mg|5.004050||p
+sv_setpvn|||
+sv_setpvs|5.009004||p
+sv_setpv|||
+sv_setref_iv|||
+sv_setref_nv|||
+sv_setref_pvn|||
+sv_setref_pv|||
+sv_setref_uv||5.007001|
+sv_setsv_cow|||
+sv_setsv_flags||5.007002|
+sv_setsv_mg|5.004050||p
+sv_setsv_nomg|5.007002||p
+sv_setsv|||
+sv_setuv_mg|5.004050||p
+sv_setuv|5.004000||p
+sv_tainted||5.004000|
+sv_taint||5.004000|
+sv_true||5.005000|
+sv_unglob|||
+sv_uni_display||5.007003|
+sv_unmagic|||
+sv_unref_flags||5.007001|
+sv_unref|||
+sv_untaint||5.004000|
+sv_upgrade|||
+sv_usepvn_flags||5.009004|
+sv_usepvn_mg|5.004050||p
+sv_usepvn|||
+sv_utf8_decode||5.006000|
+sv_utf8_downgrade||5.006000|
+sv_utf8_encode||5.006000|
+sv_utf8_upgrade_flags||5.007002|
+sv_utf8_upgrade||5.007001|
+sv_uv|5.005000||p
+sv_vcatpvf_mg|5.006000|5.004000|p
+sv_vcatpvfn||5.004000|
+sv_vcatpvf|5.006000|5.004000|p
+sv_vsetpvf_mg|5.006000|5.004000|p
+sv_vsetpvfn||5.004000|
+sv_vsetpvf|5.006000|5.004000|p
+sv_xmlpeek|||
+svtype|||
+swallow_bom|||
+swash_fetch||5.007002|
+swash_get|||
+swash_init||5.006000|
+sys_intern_clear|||
+sys_intern_dup|||
+sys_intern_init|||
+taint_env|||
+taint_proper|||
+tmps_grow||5.006000|
+toLOWER|||
+toUPPER|||
+to_byte_substr|||
+to_uni_fold||5.007003|
+to_uni_lower_lc||5.006000|
+to_uni_lower||5.007003|
+to_uni_title_lc||5.006000|
+to_uni_title||5.007003|
+to_uni_upper_lc||5.006000|
+to_uni_upper||5.007003|
+to_utf8_case||5.007003|
+to_utf8_fold||5.007003|
+to_utf8_lower||5.007003|
+to_utf8_substr|||
+to_utf8_title||5.007003|
+to_utf8_upper||5.007003|
+token_free|||
+token_getmad|||
+tokenize_use|||
+tokeq|||
+tokereport|||
+too_few_arguments|||
+too_many_arguments|||
+uiv_2buf|||n
+unlnk|||
+unpack_rec|||
+unpack_str||5.007003|
+unpackstring||5.008001|
+unshare_hek_or_pvn|||
+unshare_hek|||
+unsharepvn||5.004000|
+unwind_handler_stack|||
+update_debugger_info|||
+upg_version||5.009005|
+usage|||
+utf16_to_utf8_reversed||5.006001|
+utf16_to_utf8||5.006001|
+utf8_distance||5.006000|
+utf8_hop||5.006000|
+utf8_length||5.007001|
+utf8_mg_pos_cache_update|||
+utf8_to_bytes||5.006001|
+utf8_to_uvchr||5.007001|
+utf8_to_uvuni||5.007001|
+utf8n_to_uvchr|||
+utf8n_to_uvuni||5.007001|
+utilize|||
+uvchr_to_utf8_flags||5.007003|
+uvchr_to_utf8|||
+uvuni_to_utf8_flags||5.007003|
+uvuni_to_utf8||5.007001|
+validate_suid|||
+varname|||
+vcmp||5.009000|
+vcroak||5.006000|
+vdeb||5.007003|
+vdie_common|||
+vdie_croak_common|||
+vdie|||
+vform||5.006000|
+visit|||
+vivify_defelem|||
+vivify_ref|||
+vload_module|5.006000||p
+vmess||5.006000|
+vnewSVpvf|5.006000|5.004000|p
+vnormal||5.009002|
+vnumify||5.009000|
+vstringify||5.009000|
+vverify||5.009003|
+vwarner||5.006000|
+vwarn||5.006000|
+wait4pid|||
+warn_nocontext|||vn
+warner_nocontext|||vn
+warner|5.006000|5.004000|pv
+warn|||v
+watch|||
+whichsig|||
+write_no_mem|||
+write_to_stderr|||
+xmldump_all|||
+xmldump_attr|||
+xmldump_eval|||
+xmldump_form|||
+xmldump_indent|||v
+xmldump_packsubs|||
+xmldump_sub|||
+xmldump_vindent|||
+yyerror|||
+yylex|||
+yyparse|||
+yywarn|||
+);
+
+if (exists $opt{'list-unsupported'}) {
+ my $f;
+ for $f (sort { lc $a cmp lc $b } keys %API) {
+ next unless $API{$f}{todo};
+ print "$f ", '.'x(40-length($f)), " ", format_version($API{$f}{todo}), "\n";
+ }
+ exit 0;
+}
+
+# Scan for possible replacement candidates
+
+my(%replace, %need, %hints, %warnings, %depends);
+my $replace = 0;
+my($hint, $define, $function);
+
+sub find_api
+{
+ my $code = shift;
+ $code =~ s{
+ / (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]*)
+ | "[^"\\]*(?:\\.[^"\\]*)*"
+ | '[^'\\]*(?:\\.[^'\\]*)*' }{}egsx;
+ grep { exists $API{$_} } $code =~ /(\w+)/mg;
+}
+
+while (<DATA>) {
+ if ($hint) {
+ my $h = $hint->[0] eq 'Hint' ? \%hints : \%warnings;
+ if (m{^\s*\*\s(.*?)\s*$}) {
+ for (@{$hint->[1]}) {
+ $h->{$_} ||= ''; # suppress warning with older perls
+ $h->{$_} .= "$1\n";
+ }
+ }
+ else { undef $hint }
+ }
+
+ $hint = [$1, [split /,?\s+/, $2]]
+ if m{^\s*$rccs\s+(Hint|Warning):\s+(\w+(?:,?\s+\w+)*)\s*$};
+
+ if ($define) {
+ if ($define->[1] =~ /\\$/) {
+ $define->[1] .= $_;
+ }
+ else {
+ if (exists $API{$define->[0]} && $define->[1] !~ /^DPPP_\(/) {
+ my @n = find_api($define->[1]);
+ push @{$depends{$define->[0]}}, @n if @n
+ }
+ undef $define;
+ }
+ }
+
+ $define = [$1, $2] if m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(.*)};
+
+ if ($function) {
+ if (/^}/) {
+ if (exists $API{$function->[0]}) {
+ my @n = find_api($function->[1]);
+ push @{$depends{$function->[0]}}, @n if @n
+ }
+ undef $define;
+ }
+ else {
+ $function->[1] .= $_;
+ }
+ }
+
+ $function = [$1, ''] if m{^DPPP_\(my_(\w+)\)};
+
+ $replace = $1 if m{^\s*$rccs\s+Replace:\s+(\d+)\s+$rcce\s*$};
+ $replace{$2} = $1 if $replace and m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+)};
+ $replace{$2} = $1 if m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+).*$rccs\s+Replace\s+$rcce};
+ $replace{$1} = $2 if m{^\s*$rccs\s+Replace (\w+) with (\w+)\s+$rcce\s*$};
+
+ if (m{^\s*$rccs\s+(\w+)\s+depends\s+on\s+(\w+(\s*,\s*\w+)*)\s+$rcce\s*$}) {
+ push @{$depends{$1}}, map { s/\s+//g; $_ } split /,/, $2;
+ }
+
+ $need{$1} = 1 if m{^#if\s+defined\(NEED_(\w+)(?:_GLOBAL)?\)};
+}
+
+for (values %depends) {
+ my %s;
+ $_ = [sort grep !$s{$_}++, @$_];
+}
+
+if (exists $opt{'api-info'}) {
+ my $f;
+ my $count = 0;
+ my $match = $opt{'api-info'} =~ m!^/(.*)/$! ? $1 : "^\Q$opt{'api-info'}\E\$";
+ for $f (sort { lc $a cmp lc $b } keys %API) {
+ next unless $f =~ /$match/;
+ print "\n=== $f ===\n\n";
+ my $info = 0;
+ if ($API{$f}{base} || $API{$f}{todo}) {
+ my $base = format_version($API{$f}{base} || $API{$f}{todo});
+ print "Supported at least starting from perl-$base.\n";
+ $info++;
+ }
+ if ($API{$f}{provided}) {
+ my $todo = $API{$f}{todo} ? format_version($API{$f}{todo}) : "5.003";
+ print "Support by $ppport provided back to perl-$todo.\n";
+ print "Support needs to be explicitly requested by NEED_$f.\n" if exists $need{$f};
+ print "Depends on: ", join(', ', @{$depends{$f}}), ".\n" if exists $depends{$f};
+ print "\n$hints{$f}" if exists $hints{$f};
+ print "\nWARNING:\n$warnings{$f}" if exists $warnings{$f};
+ $info++;
+ }
+ print "No portability information available.\n" unless $info;
+ $count++;
+ }
+ $count or print "Found no API matching '$opt{'api-info'}'.";
+ print "\n";
+ exit 0;
+}
+
+if (exists $opt{'list-provided'}) {
+ my $f;
+ for $f (sort { lc $a cmp lc $b } keys %API) {
+ next unless $API{$f}{provided};
+ my @flags;
+ push @flags, 'explicit' if exists $need{$f};
+ push @flags, 'depend' if exists $depends{$f};
+ push @flags, 'hint' if exists $hints{$f};
+ push @flags, 'warning' if exists $warnings{$f};
+ my $flags = @flags ? ' ['.join(', ', @flags).']' : '';
+ print "$f$flags\n";
+ }
+ exit 0;
+}
+
+my @files;
+my @srcext = qw( .xs .c .h .cc .cpp -c.inc -xs.inc );
+my $srcext = join '|', map { quotemeta $_ } @srcext;
+
+if (@ARGV) {
+ my %seen;
+ for (@ARGV) {
+ if (-e) {
+ if (-f) {
+ push @files, $_ unless $seen{$_}++;
+ }
+ else { warn "'$_' is not a file.\n" }
+ }
+ else {
+ my @new = grep { -f } glob $_
+ or warn "'$_' does not exist.\n";
+ push @files, grep { !$seen{$_}++ } @new;
+ }
+ }
+}
+else {
+ eval {
+ require File::Find;
+ File::Find::find(sub {
+ $File::Find::name =~ /($srcext)$/i
+ and push @files, $File::Find::name;
+ }, '.');
+ };
+ if ($@) {
+ @files = map { glob "*$_" } @srcext;
+ }
+}
+
+if (!@ARGV || $opt{filter}) {
+ my(@in, @out);
+ my %xsc = map { /(.*)\.xs$/ ? ("$1.c" => 1, "$1.cc" => 1) : () } @files;
+ for (@files) {
+ my $out = exists $xsc{$_} || /\b\Q$ppport\E$/i || !/($srcext)$/i;
+ push @{ $out ? \@out : \@in }, $_;
+ }
+ if (@ARGV && @out) {
+ warning("Skipping the following files (use --nofilter to avoid this):\n| ", join "\n| ", @out);
+ }
+ @files = @in;
+}
+
+die "No input files given!\n" unless @files;
+
+my(%files, %global, %revreplace);
+%revreplace = reverse %replace;
+my $filename;
+my $patch_opened = 0;
+
+for $filename (@files) {
+ unless (open IN, "<$filename") {
+ warn "Unable to read from $filename: $!\n";
+ next;
+ }
+
+ info("Scanning $filename ...");
+
+ my $c = do { local $/; <IN> };
+ close IN;
+
+ my %file = (orig => $c, changes => 0);
+
+ # Temporarily remove C/XS comments and strings from the code
+ my @ccom;
+
+ $c =~ s{
+ ( ^$HS*\#$HS*include\b[^\r\n]+\b(?:\Q$ppport\E|XSUB\.h)\b[^\r\n]*
+ | ^$HS*\#$HS*(?:define|elif|if(?:def)?)\b[^\r\n]* )
+ | ( ^$HS*\#[^\r\n]*
+ | "[^"\\]*(?:\\.[^"\\]*)*"
+ | '[^'\\]*(?:\\.[^'\\]*)*'
+ | / (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]* ) )
+ }{ defined $2 and push @ccom, $2;
+ defined $1 ? $1 : "$ccs$#ccom$cce" }mgsex;
+
+ $file{ccom} = \@ccom;
+ $file{code} = $c;
+ $file{has_inc_ppport} = $c =~ /^$HS*#$HS*include[^\r\n]+\b\Q$ppport\E\b/m;
+
+ my $func;
+
+ for $func (keys %API) {
+ my $match = $func;
+ $match .= "|$revreplace{$func}" if exists $revreplace{$func};
+ if ($c =~ /\b(?:Perl_)?($match)\b/) {
+ $file{uses_replace}{$1}++ if exists $revreplace{$func} && $1 eq $revreplace{$func};
+ $file{uses_Perl}{$func}++ if $c =~ /\bPerl_$func\b/;
+ if (exists $API{$func}{provided}) {
+ $file{uses_provided}{$func}++;
+ if (!exists $API{$func}{base} || $API{$func}{base} > $opt{'compat-version'}) {
+ $file{uses}{$func}++;
+ my @deps = rec_depend($func);
+ if (@deps) {
+ $file{uses_deps}{$func} = \@deps;
+ for (@deps) {
+ $file{uses}{$_} = 0 unless exists $file{uses}{$_};
+ }
+ }
+ for ($func, @deps) {
+ $file{needs}{$_} = 'static' if exists $need{$_};
+ }
+ }
+ }
+ if (exists $API{$func}{todo} && $API{$func}{todo} > $opt{'compat-version'}) {
+ if ($c =~ /\b$func\b/) {
+ $file{uses_todo}{$func}++;
+ }
+ }
+ }
+ }
+
+ while ($c =~ /^$HS*#$HS*define$HS+(NEED_(\w+?)(_GLOBAL)?)\b/mg) {
+ if (exists $need{$2}) {
+ $file{defined $3 ? 'needed_global' : 'needed_static'}{$2}++;
+ }
+ else { warning("Possibly wrong #define $1 in $filename") }
+ }
+
+ for (qw(uses needs uses_todo needed_global needed_static)) {
+ for $func (keys %{$file{$_}}) {
+ push @{$global{$_}{$func}}, $filename;
+ }
+ }
+
+ $files{$filename} = \%file;
+}
+
+# Globally resolve NEED_'s
+my $need;
+for $need (keys %{$global{needs}}) {
+ if (@{$global{needs}{$need}} > 1) {
+ my @targets = @{$global{needs}{$need}};
+ my @t = grep $files{$_}{needed_global}{$need}, @targets;
+ @targets = @t if @t;
+ @t = grep /\.xs$/i, @targets;
+ @targets = @t if @t;
+ my $target = shift @targets;
+ $files{$target}{needs}{$need} = 'global';
+ for (@{$global{needs}{$need}}) {
+ $files{$_}{needs}{$need} = 'extern' if $_ ne $target;
+ }
+ }
+}
+
+for $filename (@files) {
+ exists $files{$filename} or next;
+
+ info("=== Analyzing $filename ===");
+
+ my %file = %{$files{$filename}};
+ my $func;
+ my $c = $file{code};
+ my $warnings = 0;
+
+ for $func (sort keys %{$file{uses_Perl}}) {
+ if ($API{$func}{varargs}) {
+ unless ($API{$func}{nothxarg}) {
+ my $changes = ($c =~ s{\b(Perl_$func\s*\(\s*)(?!aTHX_?)(\)|[^\s)]*\))}
+ { $1 . ($2 eq ')' ? 'aTHX' : 'aTHX_ ') . $2 }ge);
+ if ($changes) {
+ warning("Doesn't pass interpreter argument aTHX to Perl_$func");
+ $file{changes} += $changes;
+ }
+ }
+ }
+ else {
+ warning("Uses Perl_$func instead of $func");
+ $file{changes} += ($c =~ s{\bPerl_$func(\s*)\((\s*aTHX_?)?\s*}
+ {$func$1(}g);
+ }
+ }
+
+ for $func (sort keys %{$file{uses_replace}}) {
+ warning("Uses $func instead of $replace{$func}");
+ $file{changes} += ($c =~ s/\b$func\b/$replace{$func}/g);
+ }
+
+ for $func (sort keys %{$file{uses_provided}}) {
+ if ($file{uses}{$func}) {
+ if (exists $file{uses_deps}{$func}) {
+ diag("Uses $func, which depends on ", join(', ', @{$file{uses_deps}{$func}}));
+ }
+ else {
+ diag("Uses $func");
+ }
+ }
+ $warnings += hint($func);
+ }
+
+ unless ($opt{quiet}) {
+ for $func (sort keys %{$file{uses_todo}}) {
+ print "*** WARNING: Uses $func, which may not be portable below perl ",
+ format_version($API{$func}{todo}), ", even with '$ppport'\n";
+ $warnings++;
+ }
+ }
+
+ for $func (sort keys %{$file{needed_static}}) {
+ my $message = '';
+ if (not exists $file{uses}{$func}) {
+ $message = "No need to define NEED_$func if $func is never used";
+ }
+ elsif (exists $file{needs}{$func} && $file{needs}{$func} ne 'static') {
+ $message = "No need to define NEED_$func when already needed globally";
+ }
+ if ($message) {
+ diag($message);
+ $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_$func\b.*$LF//mg);
+ }
+ }
+
+ for $func (sort keys %{$file{needed_global}}) {
+ my $message = '';
+ if (not exists $global{uses}{$func}) {
+ $message = "No need to define NEED_${func}_GLOBAL if $func is never used";
+ }
+ elsif (exists $file{needs}{$func}) {
+ if ($file{needs}{$func} eq 'extern') {
+ $message = "No need to define NEED_${func}_GLOBAL when already needed globally";
+ }
+ elsif ($file{needs}{$func} eq 'static') {
+ $message = "No need to define NEED_${func}_GLOBAL when only used in this file";
+ }
+ }
+ if ($message) {
+ diag($message);
+ $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_${func}_GLOBAL\b.*$LF//mg);
+ }
+ }
+
+ $file{needs_inc_ppport} = keys %{$file{uses}};
+
+ if ($file{needs_inc_ppport}) {
+ my $pp = '';
+
+ for $func (sort keys %{$file{needs}}) {
+ my $type = $file{needs}{$func};
+ next if $type eq 'extern';
+ my $suffix = $type eq 'global' ? '_GLOBAL' : '';
+ unless (exists $file{"needed_$type"}{$func}) {
+ if ($type eq 'global') {
+ diag("Files [@{$global{needs}{$func}}] need $func, adding global request");
+ }
+ else {
+ diag("File needs $func, adding static request");
+ }
+ $pp .= "#define NEED_$func$suffix\n";
+ }
+ }
+
+ if ($pp && ($c =~ s/^(?=$HS*#$HS*define$HS+NEED_\w+)/$pp/m)) {
+ $pp = '';
+ $file{changes}++;
+ }
+
+ unless ($file{has_inc_ppport}) {
+ diag("Needs to include '$ppport'");
+ $pp .= qq(#include "$ppport"\n)
+ }
+
+ if ($pp) {
+ $file{changes} += ($c =~ s/^($HS*#$HS*define$HS+NEED_\w+.*?)^/$1$pp/ms)
+ || ($c =~ s/^(?=$HS*#$HS*include.*\Q$ppport\E)/$pp/m)
+ || ($c =~ s/^($HS*#$HS*include.*XSUB.*\s*?)^/$1$pp/m)
+ || ($c =~ s/^/$pp/);
+ }
+ }
+ else {
+ if ($file{has_inc_ppport}) {
+ diag("No need to include '$ppport'");
+ $file{changes} += ($c =~ s/^$HS*?#$HS*include.*\Q$ppport\E.*?$LF//m);
+ }
+ }
+
+ # put back in our C comments
+ my $ix;
+ my $cppc = 0;
+ my @ccom = @{$file{ccom}};
+ for $ix (0 .. $#ccom) {
+ if (!$opt{cplusplus} && $ccom[$ix] =~ s!^//!!) {
+ $cppc++;
+ $file{changes} += $c =~ s/$rccs$ix$rcce/$ccs$ccom[$ix] $cce/;
+ }
+ else {
+ $c =~ s/$rccs$ix$rcce/$ccom[$ix]/;
+ }
+ }
+
+ if ($cppc) {
+ my $s = $cppc != 1 ? 's' : '';
+ warning("Uses $cppc C++ style comment$s, which is not portable");
+ }
+
+ my $s = $warnings != 1 ? 's' : '';
+ my $warn = $warnings ? " ($warnings warning$s)" : '';
+ info("Analysis completed$warn");
+
+ if ($file{changes}) {
+ if (exists $opt{copy}) {
+ my $newfile = "$filename$opt{copy}";
+ if (-e $newfile) {
+ error("'$newfile' already exists, refusing to write copy of '$filename'");
+ }
+ else {
+ local *F;
+ if (open F, ">$newfile") {
+ info("Writing copy of '$filename' with changes to '$newfile'");
+ print F $c;
+ close F;
+ }
+ else {
+ error("Cannot open '$newfile' for writing: $!");
+ }
+ }
+ }
+ elsif (exists $opt{patch} || $opt{changes}) {
+ if (exists $opt{patch}) {
+ unless ($patch_opened) {
+ if (open PATCH, ">$opt{patch}") {
+ $patch_opened = 1;
+ }
+ else {
+ error("Cannot open '$opt{patch}' for writing: $!");
+ delete $opt{patch};
+ $opt{changes} = 1;
+ goto fallback;
+ }
+ }
+ mydiff(\*PATCH, $filename, $c);
+ }
+ else {
+fallback:
+ info("Suggested changes:");
+ mydiff(\*STDOUT, $filename, $c);
+ }
+ }
+ else {
+ my $s = $file{changes} == 1 ? '' : 's';
+ info("$file{changes} potentially required change$s detected");
+ }
+ }
+ else {
+ info("Looks good");
+ }
+}
+
+close PATCH if $patch_opened;
+
+exit 0;
+
+
+sub try_use { eval "use @_;"; return $@ eq '' }
+
+sub mydiff
+{
+ local *F = shift;
+ my($file, $str) = @_;
+ my $diff;
+
+ if (exists $opt{diff}) {
+ $diff = run_diff($opt{diff}, $file, $str);
+ }
+
+ if (!defined $diff and try_use('Text::Diff')) {
+ $diff = Text::Diff::diff($file, \$str, { STYLE => 'Unified' });
+ $diff = <<HEADER . $diff;
+--- $file
++++ $file.patched
+HEADER
+ }
+
+ if (!defined $diff) {
+ $diff = run_diff('diff -u', $file, $str);
+ }
+
+ if (!defined $diff) {
+ $diff = run_diff('diff', $file, $str);
+ }
+
+ if (!defined $diff) {
+ error("Cannot generate a diff. Please install Text::Diff or use --copy.");
+ return;
+ }
+
+ print F $diff;
+}
+
+sub run_diff
+{
+ my($prog, $file, $str) = @_;
+ my $tmp = 'dppptemp';
+ my $suf = 'aaa';
+ my $diff = '';
+ local *F;
+
+ while (-e "$tmp.$suf") { $suf++ }
+ $tmp = "$tmp.$suf";
+
+ if (open F, ">$tmp") {
+ print F $str;
+ close F;
+
+ if (open F, "$prog $file $tmp |") {
+ while (<F>) {
+ s/\Q$tmp\E/$file.patched/;
+ $diff .= $_;
+ }
+ close F;
+ unlink $tmp;
+ return $diff;
+ }
+
+ unlink $tmp;
+ }
+ else {
+ error("Cannot open '$tmp' for writing: $!");
+ }
+
+ return undef;
+}
+
+sub rec_depend
+{
+ my($func, $seen) = @_;
+ return () unless exists $depends{$func};
+ $seen = {%{$seen||{}}};
+ return () if $seen->{$func}++;
+ my %s;
+ grep !$s{$_}++, map { ($_, rec_depend($_, $seen)) } @{$depends{$func}};
+}
+
+sub parse_version
+{
+ my $ver = shift;
+
+ if ($ver =~ /^(\d+)\.(\d+)\.(\d+)$/) {
+ return ($1, $2, $3);
+ }
+ elsif ($ver !~ /^\d+\.[\d_]+$/) {
+ die "cannot parse version '$ver'\n";
+ }
+
+ $ver =~ s/_//g;
+ $ver =~ s/$/000000/;
+
+ my($r,$v,$s) = $ver =~ /(\d+)\.(\d{3})(\d{3})/;
+
+ $v = int $v;
+ $s = int $s;
+
+ if ($r < 5 || ($r == 5 && $v < 6)) {
+ if ($s % 10) {
+ die "cannot parse version '$ver'\n";
+ }
+ }
+
+ return ($r, $v, $s);
+}
+
+sub format_version
+{
+ my $ver = shift;
+
+ $ver =~ s/$/000000/;
+ my($r,$v,$s) = $ver =~ /(\d+)\.(\d{3})(\d{3})/;
+
+ $v = int $v;
+ $s = int $s;
+
+ if ($r < 5 || ($r == 5 && $v < 6)) {
+ if ($s % 10) {
+ die "invalid version '$ver'\n";
+ }
+ $s /= 10;
+
+ $ver = sprintf "%d.%03d", $r, $v;
+ $s > 0 and $ver .= sprintf "_%02d", $s;
+
+ return $ver;
+ }
+
+ return sprintf "%d.%d.%d", $r, $v, $s;
+}
+
+sub info
+{
+ $opt{quiet} and return;
+ print @_, "\n";
+}
+
+sub diag
+{
+ $opt{quiet} and return;
+ $opt{diag} and print @_, "\n";
+}
+
+sub warning
+{
+ $opt{quiet} and return;
+ print "*** ", @_, "\n";
+}
+
+sub error
+{
+ print "*** ERROR: ", @_, "\n";
+}
+
+my %given_hints;
+my %given_warnings;
+sub hint
+{
+ $opt{quiet} and return;
+ my $func = shift;
+ my $rv = 0;
+ if (exists $warnings{$func} && !$given_warnings{$func}++) {
+ my $warn = $warnings{$func};
+ $warn =~ s!^!*** !mg;
+ print "*** WARNING: $func\n", $warn;
+ $rv++;
+ }
+ if ($opt{hints} && exists $hints{$func} && !$given_hints{$func}++) {
+ my $hint = $hints{$func};
+ $hint =~ s/^/ /mg;
+ print " --- hint for $func ---\n", $hint;
+ }
+ $rv;
+}
+
+sub usage
+{
+ my($usage) = do { local(@ARGV,$/)=($0); <> } =~ /^=head\d$HS+SYNOPSIS\s*^(.*?)\s*^=/ms;
+ my %M = ( 'I' => '*' );
+ $usage =~ s/^\s*perl\s+\S+/$^X $0/;
+ $usage =~ s/([A-Z])<([^>]+)>/$M{$1}$2$M{$1}/g;
+
+ print <<ENDUSAGE;
+
+Usage: $usage
+
+See perldoc $0 for details.
+
+ENDUSAGE
+
+ exit 2;
+}
+
+sub strip
+{
+ my $self = do { local(@ARGV,$/)=($0); <> };
+ my($copy) = $self =~ /^=head\d\s+COPYRIGHT\s*^(.*?)^=\w+/ms;
+ $copy =~ s/^(?=\S+)/ /gms;
+ $self =~ s/^$HS+Do NOT edit.*?(?=^-)/$copy/ms;
+ $self =~ s/^SKIP.*(?=^__DATA__)/SKIP
+if (\@ARGV && \$ARGV[0] eq '--unstrip') {
+ eval { require Devel::PPPort };
+ \$@ and die "Cannot require Devel::PPPort, please install.\\n";
+ if (\$Devel::PPPort::VERSION < $VERSION) {
+ die "$0 was originally generated with Devel::PPPort $VERSION.\\n"
+ . "Your Devel::PPPort is only version \$Devel::PPPort::VERSION.\\n"
+ . "Please install a newer version, or --unstrip will not work.\\n";
+ }
+ Devel::PPPort::WriteFile(\$0);
+ exit 0;
+}
+print <<END;
+
+Sorry, but this is a stripped version of \$0.
+
+To be able to use its original script and doc functionality,
+please try to regenerate this file using:
+
+ \$^X \$0 --unstrip
+
+END
+/ms;
+ my($pl, $c) = $self =~ /(.*^__DATA__)(.*)/ms;
+ $c =~ s{
+ / (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]*)
+ | ( "[^"\\]*(?:\\.[^"\\]*)*"
+ | '[^'\\]*(?:\\.[^'\\]*)*' )
+ | ($HS+) }{ defined $2 ? ' ' : ($1 || '') }gsex;
+ $c =~ s!\s+$!!mg;
+ $c =~ s!^$LF!!mg;
+ $c =~ s!^\s*#\s*!#!mg;
+ $c =~ s!^\s+!!mg;
+
+ open OUT, ">$0" or die "cannot strip $0: $!\n";
+ print OUT "$pl$c\n";
+
+ exit 0;
+}
+
+__DATA__
+*/
+
+#ifndef _P_P_PORTABILITY_H_
+#define _P_P_PORTABILITY_H_
+
+#ifndef DPPP_NAMESPACE
+# define DPPP_NAMESPACE DPPP_
+#endif
+
+#define DPPP_CAT2(x,y) CAT2(x,y)
+#define DPPP_(name) DPPP_CAT2(DPPP_NAMESPACE, name)
+
+#ifndef PERL_REVISION
+# if !defined(__PATCHLEVEL_H_INCLUDED__) && !(defined(PATCHLEVEL) && defined(SUBVERSION))
+# define PERL_PATCHLEVEL_H_IMPLICIT
+# include <patchlevel.h>
+# endif
+# if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL)))
+# include <could_not_find_Perl_patchlevel.h>
+# endif
+# ifndef PERL_REVISION
+# define PERL_REVISION (5)
+ /* Replace: 1 */
+# define PERL_VERSION PATCHLEVEL
+# define PERL_SUBVERSION SUBVERSION
+ /* Replace PERL_PATCHLEVEL with PERL_VERSION */
+ /* Replace: 0 */
+# endif
+#endif
+
+#define _dpppDEC2BCD(dec) ((((dec)/100)<<8)|((((dec)%100)/10)<<4)|((dec)%10))
+#define PERL_BCDVERSION ((_dpppDEC2BCD(PERL_REVISION)<<24)|(_dpppDEC2BCD(PERL_VERSION)<<12)|_dpppDEC2BCD(PERL_SUBVERSION))
+
+/* It is very unlikely that anyone will try to use this with Perl 6
+ (or greater), but who knows.
+ */
+#if PERL_REVISION != 5
+# error ppport.h only works with Perl version 5
+#endif /* PERL_REVISION != 5 */
+
+#ifdef I_LIMITS
+# include <limits.h>
+#endif
+
+#ifndef PERL_UCHAR_MIN
+# define PERL_UCHAR_MIN ((unsigned char)0)
+#endif
+
+#ifndef PERL_UCHAR_MAX
+# ifdef UCHAR_MAX
+# define PERL_UCHAR_MAX ((unsigned char)UCHAR_MAX)
+# else
+# ifdef MAXUCHAR
+# define PERL_UCHAR_MAX ((unsigned char)MAXUCHAR)
+# else
+# define PERL_UCHAR_MAX ((unsigned char)~(unsigned)0)
+# endif
+# endif
+#endif
+
+#ifndef PERL_USHORT_MIN
+# define PERL_USHORT_MIN ((unsigned short)0)
+#endif
+
+#ifndef PERL_USHORT_MAX
+# ifdef USHORT_MAX
+# define PERL_USHORT_MAX ((unsigned short)USHORT_MAX)
+# else
+# ifdef MAXUSHORT
+# define PERL_USHORT_MAX ((unsigned short)MAXUSHORT)
+# else
+# ifdef USHRT_MAX
+# define PERL_USHORT_MAX ((unsigned short)USHRT_MAX)
+# else
+# define PERL_USHORT_MAX ((unsigned short)~(unsigned)0)
+# endif
+# endif
+# endif
+#endif
+
+#ifndef PERL_SHORT_MAX
+# ifdef SHORT_MAX
+# define PERL_SHORT_MAX ((short)SHORT_MAX)
+# else
+# ifdef MAXSHORT /* Often used in <values.h> */
+# define PERL_SHORT_MAX ((short)MAXSHORT)
+# else
+# ifdef SHRT_MAX
+# define PERL_SHORT_MAX ((short)SHRT_MAX)
+# else
+# define PERL_SHORT_MAX ((short) (PERL_USHORT_MAX >> 1))
+# endif
+# endif
+# endif
+#endif
+
+#ifndef PERL_SHORT_MIN
+# ifdef SHORT_MIN
+# define PERL_SHORT_MIN ((short)SHORT_MIN)
+# else
+# ifdef MINSHORT
+# define PERL_SHORT_MIN ((short)MINSHORT)
+# else
+# ifdef SHRT_MIN
+# define PERL_SHORT_MIN ((short)SHRT_MIN)
+# else
+# define PERL_SHORT_MIN (-PERL_SHORT_MAX - ((3 & -1) == 3))
+# endif
+# endif
+# endif
+#endif
+
+#ifndef PERL_UINT_MAX
+# ifdef UINT_MAX
+# define PERL_UINT_MAX ((unsigned int)UINT_MAX)
+# else
+# ifdef MAXUINT
+# define PERL_UINT_MAX ((unsigned int)MAXUINT)
+# else
+# define PERL_UINT_MAX (~(unsigned int)0)
+# endif
+# endif
+#endif
+
+#ifndef PERL_UINT_MIN
+# define PERL_UINT_MIN ((unsigned int)0)
+#endif
+
+#ifndef PERL_INT_MAX
+# ifdef INT_MAX
+# define PERL_INT_MAX ((int)INT_MAX)
+# else
+# ifdef MAXINT /* Often used in <values.h> */
+# define PERL_INT_MAX ((int)MAXINT)
+# else
+# define PERL_INT_MAX ((int)(PERL_UINT_MAX >> 1))
+# endif
+# endif
+#endif
+
+#ifndef PERL_INT_MIN
+# ifdef INT_MIN
+# define PERL_INT_MIN ((int)INT_MIN)
+# else
+# ifdef MININT
+# define PERL_INT_MIN ((int)MININT)
+# else
+# define PERL_INT_MIN (-PERL_INT_MAX - ((3 & -1) == 3))
+# endif
+# endif
+#endif
+
+#ifndef PERL_ULONG_MAX
+# ifdef ULONG_MAX
+# define PERL_ULONG_MAX ((unsigned long)ULONG_MAX)
+# else
+# ifdef MAXULONG
+# define PERL_ULONG_MAX ((unsigned long)MAXULONG)
+# else
+# define PERL_ULONG_MAX (~(unsigned long)0)
+# endif
+# endif
+#endif
+
+#ifndef PERL_ULONG_MIN
+# define PERL_ULONG_MIN ((unsigned long)0L)
+#endif
+
+#ifndef PERL_LONG_MAX
+# ifdef LONG_MAX
+# define PERL_LONG_MAX ((long)LONG_MAX)
+# else
+# ifdef MAXLONG
+# define PERL_LONG_MAX ((long)MAXLONG)
+# else
+# define PERL_LONG_MAX ((long) (PERL_ULONG_MAX >> 1))
+# endif
+# endif
+#endif
+
+#ifndef PERL_LONG_MIN
+# ifdef LONG_MIN
+# define PERL_LONG_MIN ((long)LONG_MIN)
+# else
+# ifdef MINLONG
+# define PERL_LONG_MIN ((long)MINLONG)
+# else
+# define PERL_LONG_MIN (-PERL_LONG_MAX - ((3 & -1) == 3))
+# endif
+# endif
+#endif
+
+#if defined(HAS_QUAD) && (defined(convex) || defined(uts))
+# ifndef PERL_UQUAD_MAX
+# ifdef ULONGLONG_MAX
+# define PERL_UQUAD_MAX ((unsigned long long)ULONGLONG_MAX)
+# else
+# ifdef MAXULONGLONG
+# define PERL_UQUAD_MAX ((unsigned long long)MAXULONGLONG)
+# else
+# define PERL_UQUAD_MAX (~(unsigned long long)0)
+# endif
+# endif
+# endif
+
+# ifndef PERL_UQUAD_MIN
+# define PERL_UQUAD_MIN ((unsigned long long)0L)
+# endif
+
+# ifndef PERL_QUAD_MAX
+# ifdef LONGLONG_MAX
+# define PERL_QUAD_MAX ((long long)LONGLONG_MAX)
+# else
+# ifdef MAXLONGLONG
+# define PERL_QUAD_MAX ((long long)MAXLONGLONG)
+# else
+# define PERL_QUAD_MAX ((long long) (PERL_UQUAD_MAX >> 1))
+# endif
+# endif
+# endif
+
+# ifndef PERL_QUAD_MIN
+# ifdef LONGLONG_MIN
+# define PERL_QUAD_MIN ((long long)LONGLONG_MIN)
+# else
+# ifdef MINLONGLONG
+# define PERL_QUAD_MIN ((long long)MINLONGLONG)
+# else
+# define PERL_QUAD_MIN (-PERL_QUAD_MAX - ((3 & -1) == 3))
+# endif
+# endif
+# endif
+#endif
+
+/* This is based on code from 5.003 perl.h */
+#ifdef HAS_QUAD
+# ifdef cray
+#ifndef IVTYPE
+# define IVTYPE int
+#endif
+
+#ifndef IV_MIN
+# define IV_MIN PERL_INT_MIN
+#endif
+
+#ifndef IV_MAX
+# define IV_MAX PERL_INT_MAX
+#endif
+
+#ifndef UV_MIN
+# define UV_MIN PERL_UINT_MIN
+#endif
+
+#ifndef UV_MAX
+# define UV_MAX PERL_UINT_MAX
+#endif
+
+# ifdef INTSIZE
+#ifndef IVSIZE
+# define IVSIZE INTSIZE
+#endif
+
+# endif
+# else
+# if defined(convex) || defined(uts)
+#ifndef IVTYPE
+# define IVTYPE long long
+#endif
+
+#ifndef IV_MIN
+# define IV_MIN PERL_QUAD_MIN
+#endif
+
+#ifndef IV_MAX
+# define IV_MAX PERL_QUAD_MAX
+#endif
+
+#ifndef UV_MIN
+# define UV_MIN PERL_UQUAD_MIN
+#endif
+
+#ifndef UV_MAX
+# define UV_MAX PERL_UQUAD_MAX
+#endif
+
+# ifdef LONGLONGSIZE
+#ifndef IVSIZE
+# define IVSIZE LONGLONGSIZE
+#endif
+
+# endif
+# else
+#ifndef IVTYPE
+# define IVTYPE long
+#endif
+
+#ifndef IV_MIN
+# define IV_MIN PERL_LONG_MIN
+#endif
+
+#ifndef IV_MAX
+# define IV_MAX PERL_LONG_MAX
+#endif
+
+#ifndef UV_MIN
+# define UV_MIN PERL_ULONG_MIN
+#endif
+
+#ifndef UV_MAX
+# define UV_MAX PERL_ULONG_MAX
+#endif
+
+# ifdef LONGSIZE
+#ifndef IVSIZE
+# define IVSIZE LONGSIZE
+#endif
+
+# endif
+# endif
+# endif
+#ifndef IVSIZE
+# define IVSIZE 8
+#endif
+
+#ifndef PERL_QUAD_MIN
+# define PERL_QUAD_MIN IV_MIN
+#endif
+
+#ifndef PERL_QUAD_MAX
+# define PERL_QUAD_MAX IV_MAX
+#endif
+
+#ifndef PERL_UQUAD_MIN
+# define PERL_UQUAD_MIN UV_MIN
+#endif
+
+#ifndef PERL_UQUAD_MAX
+# define PERL_UQUAD_MAX UV_MAX
+#endif
+
+#else
+#ifndef IVTYPE
+# define IVTYPE long
+#endif
+
+#ifndef IV_MIN
+# define IV_MIN PERL_LONG_MIN
+#endif
+
+#ifndef IV_MAX
+# define IV_MAX PERL_LONG_MAX
+#endif
+
+#ifndef UV_MIN
+# define UV_MIN PERL_ULONG_MIN
+#endif
+
+#ifndef UV_MAX
+# define UV_MAX PERL_ULONG_MAX
+#endif
+
+#endif
+
+#ifndef IVSIZE
+# ifdef LONGSIZE
+# define IVSIZE LONGSIZE
+# else
+# define IVSIZE 4 /* A bold guess, but the best we can make. */
+# endif
+#endif
+#ifndef UVTYPE
+# define UVTYPE unsigned IVTYPE
+#endif
+
+#ifndef UVSIZE
+# define UVSIZE IVSIZE
+#endif
+#ifndef sv_setuv
+# define sv_setuv(sv, uv) \
+ STMT_START { \
+ UV TeMpUv = uv; \
+ if (TeMpUv <= IV_MAX) \
+ sv_setiv(sv, TeMpUv); \
+ else \
+ sv_setnv(sv, (double)TeMpUv); \
+ } STMT_END
+#endif
+#ifndef newSVuv
+# define newSVuv(uv) ((uv) <= IV_MAX ? newSViv((IV)uv) : newSVnv((NV)uv))
+#endif
+#ifndef sv_2uv
+# define sv_2uv(sv) ((PL_Sv = (sv)), (UV) (SvNOK(PL_Sv) ? SvNV(PL_Sv) : sv_2nv(PL_Sv)))
+#endif
+
+#ifndef SvUVX
+# define SvUVX(sv) ((UV)SvIVX(sv))
+#endif
+
+#ifndef SvUVXx
+# define SvUVXx(sv) SvUVX(sv)
+#endif
+
+#ifndef SvUV
+# define SvUV(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv))
+#endif
+
+#ifndef SvUVx
+# define SvUVx(sv) ((PL_Sv = (sv)), SvUV(PL_Sv))
+#endif
+
+/* Hint: sv_uv
+ * Always use the SvUVx() macro instead of sv_uv().
+ */
+#ifndef sv_uv
+# define sv_uv(sv) SvUVx(sv)
+#endif
+
+#if !defined(SvUOK) && defined(SvIOK_UV)
+# define SvUOK(sv) SvIOK_UV(sv)
+#endif
+#ifndef XST_mUV
+# define XST_mUV(i,v) (ST(i) = sv_2mortal(newSVuv(v)) )
+#endif
+
+#ifndef XSRETURN_UV
+# define XSRETURN_UV(v) STMT_START { XST_mUV(0,v); XSRETURN(1); } STMT_END
+#endif
+#ifndef PUSHu
+# define PUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); PUSHTARG; } STMT_END
+#endif
+
+#ifndef XPUSHu
+# define XPUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); XPUSHTARG; } STMT_END
+#endif
+
+#ifdef HAS_MEMCMP
+#ifndef memNE
+# define memNE(s1,s2,l) (memcmp(s1,s2,l))
+#endif
+
+#ifndef memEQ
+# define memEQ(s1,s2,l) (!memcmp(s1,s2,l))
+#endif
+
+#else
+#ifndef memNE
+# define memNE(s1,s2,l) (bcmp(s1,s2,l))
+#endif
+
+#ifndef memEQ
+# define memEQ(s1,s2,l) (!bcmp(s1,s2,l))
+#endif
+
+#endif
+#ifndef MoveD
+# define MoveD(s,d,n,t) memmove((char*)(d),(char*)(s), (n) * sizeof(t))
+#endif
+
+#ifndef CopyD
+# define CopyD(s,d,n,t) memcpy((char*)(d),(char*)(s), (n) * sizeof(t))
+#endif
+
+#ifdef HAS_MEMSET
+#ifndef ZeroD
+# define ZeroD(d,n,t) memzero((char*)(d), (n) * sizeof(t))
+#endif
+
+#else
+#ifndef ZeroD
+# define ZeroD(d,n,t) ((void)memzero((char*)(d), (n) * sizeof(t)), d)
+#endif
+
+#endif
+#ifndef PoisonWith
+# define PoisonWith(d,n,t,b) (void)memset((char*)(d), (U8)(b), (n) * sizeof(t))
+#endif
+
+#ifndef PoisonNew
+# define PoisonNew(d,n,t) PoisonWith(d,n,t,0xAB)
+#endif
+
+#ifndef PoisonFree
+# define PoisonFree(d,n,t) PoisonWith(d,n,t,0xEF)
+#endif
+
+#ifndef Poison
+# define Poison(d,n,t) PoisonFree(d,n,t)
+#endif
+#ifndef Newx
+# define Newx(v,n,t) New(0,v,n,t)
+#endif
+
+#ifndef Newxc
+# define Newxc(v,n,t,c) Newc(0,v,n,t,c)
+#endif
+
+#ifndef Newxz
+# define Newxz(v,n,t) Newz(0,v,n,t)
+#endif
+
+#ifndef PERL_UNUSED_DECL
+# ifdef HASATTRIBUTE
+# if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER)
+# define PERL_UNUSED_DECL
+# else
+# define PERL_UNUSED_DECL __attribute__((unused))
+# endif
+# else
+# define PERL_UNUSED_DECL
+# endif
+#endif
+
+#ifndef PERL_UNUSED_ARG
+# if defined(lint) && defined(S_SPLINT_S) /* www.splint.org */
+# include <note.h>
+# define PERL_UNUSED_ARG(x) NOTE(ARGUNUSED(x))
+# else
+# define PERL_UNUSED_ARG(x) ((void)x)
+# endif
+#endif
+
+#ifndef PERL_UNUSED_VAR
+# define PERL_UNUSED_VAR(x) ((void)x)
+#endif
+
+#ifndef PERL_UNUSED_CONTEXT
+# ifdef USE_ITHREADS
+# define PERL_UNUSED_CONTEXT PERL_UNUSED_ARG(my_perl)
+# else
+# define PERL_UNUSED_CONTEXT
+# endif
+#endif
+#ifndef NOOP
+# define NOOP /*EMPTY*/(void)0
+#endif
+
+#ifndef dNOOP
+# define dNOOP extern int /*@unused@*/ Perl___notused PERL_UNUSED_DECL
+#endif
+
+#ifndef NVTYPE
+# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE)
+# define NVTYPE long double
+# else
+# define NVTYPE double
+# endif
+typedef NVTYPE NV;
+#endif
+
+#ifndef INT2PTR
+
+# if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE)
+# define PTRV UV
+# define INT2PTR(any,d) (any)(d)
+# else
+# if PTRSIZE == LONGSIZE
+# define PTRV unsigned long
+# else
+# define PTRV unsigned
+# endif
+# define INT2PTR(any,d) (any)(PTRV)(d)
+# endif
+
+# define NUM2PTR(any,d) (any)(PTRV)(d)
+# define PTR2IV(p) INT2PTR(IV,p)
+# define PTR2UV(p) INT2PTR(UV,p)
+# define PTR2NV(p) NUM2PTR(NV,p)
+
+# if PTRSIZE == LONGSIZE
+# define PTR2ul(p) (unsigned long)(p)
+# else
+# define PTR2ul(p) INT2PTR(unsigned long,p)
+# endif
+
+#endif /* !INT2PTR */
+
+#undef START_EXTERN_C
+#undef END_EXTERN_C
+#undef EXTERN_C
+#ifdef __cplusplus
+# define START_EXTERN_C extern "C" {
+# define END_EXTERN_C }
+# define EXTERN_C extern "C"
+#else
+# define START_EXTERN_C
+# define END_EXTERN_C
+# define EXTERN_C extern
+#endif
+
+#if defined(PERL_GCC_PEDANTIC)
+# ifndef PERL_GCC_BRACE_GROUPS_FORBIDDEN
+# define PERL_GCC_BRACE_GROUPS_FORBIDDEN
+# endif
+#endif
+
+#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) && !defined(__cplusplus)
+# ifndef PERL_USE_GCC_BRACE_GROUPS
+# define PERL_USE_GCC_BRACE_GROUPS
+# endif
+#endif
+
+#undef STMT_START
+#undef STMT_END
+#ifdef PERL_USE_GCC_BRACE_GROUPS
+# define STMT_START (void)( /* gcc supports ``({ STATEMENTS; })'' */
+# define STMT_END )
+#else
+# if defined(VOIDFLAGS) && (VOIDFLAGS) && (defined(sun) || defined(__sun__)) && !defined(__GNUC__)
+# define STMT_START if (1)
+# define STMT_END else (void)0
+# else
+# define STMT_START do
+# define STMT_END while (0)
+# endif
+#endif
+#ifndef boolSV
+# define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no)
+#endif
+
+/* DEFSV appears first in 5.004_56 */
+#ifndef DEFSV
+# define DEFSV GvSV(PL_defgv)
+#endif
+
+#ifndef SAVE_DEFSV
+# define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv))
+#endif
+
+/* Older perls (<=5.003) lack AvFILLp */
+#ifndef AvFILLp
+# define AvFILLp AvFILL
+#endif
+#ifndef ERRSV
+# define ERRSV get_sv("@",FALSE)
+#endif
+#ifndef newSVpvn
+# define newSVpvn(data,len) ((data) \
+ ? ((len) ? newSVpv((data), (len)) : newSVpv("", 0)) \
+ : newSV(0))
+#endif
+
+/* Hint: gv_stashpvn
+ * This function's backport doesn't support the length parameter, but
+ * rather ignores it. Portability can only be ensured if the length
+ * parameter is used for speed reasons, but the length can always be
+ * correctly computed from the string argument.
+ */
+#ifndef gv_stashpvn
+# define gv_stashpvn(str,len,create) gv_stashpv(str,create)
+#endif
+
+/* Replace: 1 */
+#ifndef get_cv
+# define get_cv perl_get_cv
+#endif
+
+#ifndef get_sv
+# define get_sv perl_get_sv
+#endif
+
+#ifndef get_av
+# define get_av perl_get_av
+#endif
+
+#ifndef get_hv
+# define get_hv perl_get_hv
+#endif
+
+/* Replace: 0 */
+#ifndef dUNDERBAR
+# define dUNDERBAR dNOOP
+#endif
+
+#ifndef UNDERBAR
+# define UNDERBAR DEFSV
+#endif
+#ifndef dAX
+# define dAX I32 ax = MARK - PL_stack_base + 1
+#endif
+
+#ifndef dITEMS
+# define dITEMS I32 items = SP - MARK
+#endif
+#ifndef dXSTARG
+# define dXSTARG SV * targ = sv_newmortal()
+#endif
+#ifndef dAXMARK
+# define dAXMARK I32 ax = POPMARK; \
+ register SV ** const mark = PL_stack_base + ax++
+#endif
+#ifndef XSprePUSH
+# define XSprePUSH (sp = PL_stack_base + ax - 1)
+#endif
+
+#if (PERL_BCDVERSION < 0x5005000)
+# undef XSRETURN
+# define XSRETURN(off) \
+ STMT_START { \
+ PL_stack_sp = PL_stack_base + ax + ((off) - 1); \
+ return; \
+ } STMT_END
+#endif
+#ifndef PERL_ABS
+# define PERL_ABS(x) ((x) < 0 ? -(x) : (x))
+#endif
+#ifndef dVAR
+# define dVAR dNOOP
+#endif
+#ifndef SVf
+# define SVf "_"
+#endif
+#ifndef UTF8_MAXBYTES
+# define UTF8_MAXBYTES UTF8_MAXLEN
+#endif
+#ifndef PERL_HASH
+# define PERL_HASH(hash,str,len) \
+ STMT_START { \
+ const char *s_PeRlHaSh = str; \
+ I32 i_PeRlHaSh = len; \
+ U32 hash_PeRlHaSh = 0; \
+ while (i_PeRlHaSh--) \
+ hash_PeRlHaSh = hash_PeRlHaSh * 33 + *s_PeRlHaSh++; \
+ (hash) = hash_PeRlHaSh; \
+ } STMT_END
+#endif
+
+#ifndef PERL_SIGNALS_UNSAFE_FLAG
+
+#define PERL_SIGNALS_UNSAFE_FLAG 0x0001
+
+#if (PERL_BCDVERSION < 0x5008000)
+# define D_PPP_PERL_SIGNALS_INIT PERL_SIGNALS_UNSAFE_FLAG
+#else
+# define D_PPP_PERL_SIGNALS_INIT 0
+#endif
+
+#if defined(NEED_PL_signals)
+static U32 DPPP_(my_PL_signals) = D_PPP_PERL_SIGNALS_INIT;
+#elif defined(NEED_PL_signals_GLOBAL)
+U32 DPPP_(my_PL_signals) = D_PPP_PERL_SIGNALS_INIT;
+#else
+extern U32 DPPP_(my_PL_signals);
+#endif
+#define PL_signals DPPP_(my_PL_signals)
+
+#endif
+
+/* Hint: PL_ppaddr
+ * Calling an op via PL_ppaddr requires passing a context argument
+ * for threaded builds. Since the context argument is different for
+ * 5.005 perls, you can use aTHXR (supplied by ppport.h), which will
+ * automatically be defined as the correct argument.
+ */
+
+#if (PERL_BCDVERSION <= 0x5005005)
+/* Replace: 1 */
+# define PL_ppaddr ppaddr
+# define PL_no_modify no_modify
+/* Replace: 0 */
+#endif
+
+#if (PERL_BCDVERSION <= 0x5004005)
+/* Replace: 1 */
+# define PL_DBsignal DBsignal
+# define PL_DBsingle DBsingle
+# define PL_DBsub DBsub
+# define PL_DBtrace DBtrace
+# define PL_Sv Sv
+# define PL_compiling compiling
+# define PL_copline copline
+# define PL_curcop curcop
+# define PL_curstash curstash
+# define PL_debstash debstash
+# define PL_defgv defgv
+# define PL_diehook diehook
+# define PL_dirty dirty
+# define PL_dowarn dowarn
+# define PL_errgv errgv
+# define PL_expect expect
+# define PL_hexdigit hexdigit
+# define PL_hints hints
+# define PL_laststatval laststatval
+# define PL_na na
+# define PL_perl_destruct_level perl_destruct_level
+# define PL_perldb perldb
+# define PL_rsfp_filters rsfp_filters
+# define PL_rsfp rsfp
+# define PL_stack_base stack_base
+# define PL_stack_sp stack_sp
+# define PL_statcache statcache
+# define PL_stdingv stdingv
+# define PL_sv_arenaroot sv_arenaroot
+# define PL_sv_no sv_no
+# define PL_sv_undef sv_undef
+# define PL_sv_yes sv_yes
+# define PL_tainted tainted
+# define PL_tainting tainting
+/* Replace: 0 */
+#endif
+
+/* Warning: PL_expect, PL_copline, PL_rsfp, PL_rsfp_filters
+ * Do not use this variable. It is internal to the perl parser
+ * and may change or even be removed in the future. Note that
+ * as of perl 5.9.5 you cannot assign to this variable anymore.
+ */
+
+/* TODO: cannot assign to these vars; is it worth fixing? */
+#if (PERL_BCDVERSION >= 0x5009005)
+# define PL_expect (PL_parser ? PL_parser->expect : 0)
+# define PL_copline (PL_parser ? PL_parser->copline : 0)
+# define PL_rsfp (PL_parser ? PL_parser->rsfp : (PerlIO *) 0)
+# define PL_rsfp_filters (PL_parser ? PL_parser->rsfp_filters : (AV *) 0)
+#endif
+#ifndef dTHR
+# define dTHR dNOOP
+#endif
+#ifndef dTHX
+# define dTHX dNOOP
+#endif
+
+#ifndef dTHXa
+# define dTHXa(x) dNOOP
+#endif
+#ifndef pTHX
+# define pTHX void
+#endif
+
+#ifndef pTHX_
+# define pTHX_
+#endif
+
+#ifndef aTHX
+# define aTHX
+#endif
+
+#ifndef aTHX_
+# define aTHX_
+#endif
+
+#if (PERL_BCDVERSION < 0x5006000)
+# ifdef USE_THREADS
+# define aTHXR thr
+# define aTHXR_ thr,
+# else
+# define aTHXR
+# define aTHXR_
+# endif
+# define dTHXR dTHR
+#else
+# define aTHXR aTHX
+# define aTHXR_ aTHX_
+# define dTHXR dTHX
+#endif
+#ifndef dTHXoa
+# define dTHXoa(x) dTHXa(x)
+#endif
+#ifndef PUSHmortal
+# define PUSHmortal PUSHs(sv_newmortal())
+#endif
+
+#ifndef mPUSHp
+# define mPUSHp(p,l) sv_setpvn_mg(PUSHmortal, (p), (l))
+#endif
+
+#ifndef mPUSHn
+# define mPUSHn(n) sv_setnv_mg(PUSHmortal, (NV)(n))
+#endif
+
+#ifndef mPUSHi
+# define mPUSHi(i) sv_setiv_mg(PUSHmortal, (IV)(i))
+#endif
+
+#ifndef mPUSHu
+# define mPUSHu(u) sv_setuv_mg(PUSHmortal, (UV)(u))
+#endif
+#ifndef XPUSHmortal
+# define XPUSHmortal XPUSHs(sv_newmortal())
+#endif
+
+#ifndef mXPUSHp
+# define mXPUSHp(p,l) STMT_START { EXTEND(sp,1); sv_setpvn_mg(PUSHmortal, (p), (l)); } STMT_END
+#endif
+
+#ifndef mXPUSHn
+# define mXPUSHn(n) STMT_START { EXTEND(sp,1); sv_setnv_mg(PUSHmortal, (NV)(n)); } STMT_END
+#endif
+
+#ifndef mXPUSHi
+# define mXPUSHi(i) STMT_START { EXTEND(sp,1); sv_setiv_mg(PUSHmortal, (IV)(i)); } STMT_END
+#endif
+
+#ifndef mXPUSHu
+# define mXPUSHu(u) STMT_START { EXTEND(sp,1); sv_setuv_mg(PUSHmortal, (UV)(u)); } STMT_END
+#endif
+
+/* Replace: 1 */
+#ifndef call_sv
+# define call_sv perl_call_sv
+#endif
+
+#ifndef call_pv
+# define call_pv perl_call_pv
+#endif
+
+#ifndef call_argv
+# define call_argv perl_call_argv
+#endif
+
+#ifndef call_method
+# define call_method perl_call_method
+#endif
+#ifndef eval_sv
+# define eval_sv perl_eval_sv
+#endif
+#ifndef PERL_LOADMOD_DENY
+# define PERL_LOADMOD_DENY 0x1
+#endif
+
+#ifndef PERL_LOADMOD_NOIMPORT
+# define PERL_LOADMOD_NOIMPORT 0x2
+#endif
+
+#ifndef PERL_LOADMOD_IMPORT_OPS
+# define PERL_LOADMOD_IMPORT_OPS 0x4
+#endif
+
+/* Replace: 0 */
+
+/* Replace perl_eval_pv with eval_pv */
+
+#ifndef eval_pv
+#if defined(NEED_eval_pv)
+static SV* DPPP_(my_eval_pv)(char *p, I32 croak_on_error);
+static
+#else
+extern SV* DPPP_(my_eval_pv)(char *p, I32 croak_on_error);
+#endif
+
+#ifdef eval_pv
+# undef eval_pv
+#endif
+#define eval_pv(a,b) DPPP_(my_eval_pv)(aTHX_ a,b)
+#define Perl_eval_pv DPPP_(my_eval_pv)
+
+#if defined(NEED_eval_pv) || defined(NEED_eval_pv_GLOBAL)
+
+SV*
+DPPP_(my_eval_pv)(char *p, I32 croak_on_error)
+{
+ dSP;
+ SV* sv = newSVpv(p, 0);
+
+ PUSHMARK(sp);
+ eval_sv(sv, G_SCALAR);
+ SvREFCNT_dec(sv);
+
+ SPAGAIN;
+ sv = POPs;
+ PUTBACK;
+
+ if (croak_on_error && SvTRUE(GvSV(errgv)))
+ croak(SvPVx(GvSV(errgv), na));
+
+ return sv;
+}
+
+#endif
+#endif
+
+#ifndef vload_module
+#if defined(NEED_vload_module)
+static void DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args);
+static
+#else
+extern void DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args);
+#endif
+
+#ifdef vload_module
+# undef vload_module
+#endif
+#define vload_module(a,b,c,d) DPPP_(my_vload_module)(aTHX_ a,b,c,d)
+#define Perl_vload_module DPPP_(my_vload_module)
+
+#if defined(NEED_vload_module) || defined(NEED_vload_module_GLOBAL)
+
+void
+DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args)
+{
+ dTHR;
+ dVAR;
+ OP *veop, *imop;
+
+ OP * const modname = newSVOP(OP_CONST, 0, name);
+ /* 5.005 has a somewhat hacky force_normal that doesn't croak on
+ SvREADONLY() if PL_compling is true. Current perls take care in
+ ck_require() to correctly turn off SvREADONLY before calling
+ force_normal_flags(). This seems a better fix than fudging PL_compling
+ */
+ SvREADONLY_off(((SVOP*)modname)->op_sv);
+ modname->op_private |= OPpCONST_BARE;
+ if (ver) {
+ veop = newSVOP(OP_CONST, 0, ver);
+ }
+ else
+ veop = NULL;
+ if (flags & PERL_LOADMOD_NOIMPORT) {
+ imop = sawparens(newNULLLIST());
+ }
+ else if (flags & PERL_LOADMOD_IMPORT_OPS) {
+ imop = va_arg(*args, OP*);
+ }
+ else {
+ SV *sv;
+ imop = NULL;
+ sv = va_arg(*args, SV*);
+ while (sv) {
+ imop = append_elem(OP_LIST, imop, newSVOP(OP_CONST, 0, sv));
+ sv = va_arg(*args, SV*);
+ }
+ }
+ {
+ const line_t ocopline = PL_copline;
+ COP * const ocurcop = PL_curcop;
+ const int oexpect = PL_expect;
+
+#if (PERL_BCDVERSION >= 0x5004000)
+ utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0),
+ veop, modname, imop);
+#else
+ utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(),
+ modname, imop);
+#endif
+ PL_expect = oexpect;
+ PL_copline = ocopline;
+ PL_curcop = ocurcop;
+ }
+}
+
+#endif
+#endif
+
+#ifndef load_module
+#if defined(NEED_load_module)
+static void DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...);
+static
+#else
+extern void DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...);
+#endif
+
+#ifdef load_module
+# undef load_module
+#endif
+#define load_module DPPP_(my_load_module)
+#define Perl_load_module DPPP_(my_load_module)
+
+#if defined(NEED_load_module) || defined(NEED_load_module_GLOBAL)
+
+void
+DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...)
+{
+ va_list args;
+ va_start(args, ver);
+ vload_module(flags, name, ver, &args);
+ va_end(args);
+}
+
+#endif
+#endif
+#ifndef newRV_inc
+# define newRV_inc(sv) newRV(sv) /* Replace */
+#endif
+
+#ifndef newRV_noinc
+#if defined(NEED_newRV_noinc)
+static SV * DPPP_(my_newRV_noinc)(SV *sv);
+static
+#else
+extern SV * DPPP_(my_newRV_noinc)(SV *sv);
+#endif
+
+#ifdef newRV_noinc
+# undef newRV_noinc
+#endif
+#define newRV_noinc(a) DPPP_(my_newRV_noinc)(aTHX_ a)
+#define Perl_newRV_noinc DPPP_(my_newRV_noinc)
+
+#if defined(NEED_newRV_noinc) || defined(NEED_newRV_noinc_GLOBAL)
+SV *
+DPPP_(my_newRV_noinc)(SV *sv)
+{
+ SV *rv = (SV *)newRV(sv);
+ SvREFCNT_dec(sv);
+ return rv;
+}
+#endif
+#endif
+
+/* Hint: newCONSTSUB
+ * Returns a CV* as of perl-5.7.1. This return value is not supported
+ * by Devel::PPPort.
+ */
+
+/* newCONSTSUB from IO.xs is in the core starting with 5.004_63 */
+#if (PERL_BCDVERSION < 0x5004063) && (PERL_BCDVERSION != 0x5004005)
+#if defined(NEED_newCONSTSUB)
+static void DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv);
+static
+#else
+extern void DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv);
+#endif
+
+#ifdef newCONSTSUB
+# undef newCONSTSUB
+#endif
+#define newCONSTSUB(a,b,c) DPPP_(my_newCONSTSUB)(aTHX_ a,b,c)
+#define Perl_newCONSTSUB DPPP_(my_newCONSTSUB)
+
+#if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL)
+
+void
+DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv)
+{
+ U32 oldhints = PL_hints;
+ HV *old_cop_stash = PL_curcop->cop_stash;
+ HV *old_curstash = PL_curstash;
+ line_t oldline = PL_curcop->cop_line;
+ PL_curcop->cop_line = PL_copline;
+
+ PL_hints &= ~HINT_BLOCK_SCOPE;
+ if (stash)
+ PL_curstash = PL_curcop->cop_stash = stash;
+
+ newSUB(
+
+#if (PERL_BCDVERSION < 0x5003022)
+ start_subparse(),
+#elif (PERL_BCDVERSION == 0x5003022)
+ start_subparse(0),
+#else /* 5.003_23 onwards */
+ start_subparse(FALSE, 0),
+#endif
+
+ newSVOP(OP_CONST, 0, newSVpv((char *) name, 0)),
+ newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */
+ newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv))
+ );
+
+ PL_hints = oldhints;
+ PL_curcop->cop_stash = old_cop_stash;
+ PL_curstash = old_curstash;
+ PL_curcop->cop_line = oldline;
+}
+#endif
+#endif
+
+/*
+ * Boilerplate macros for initializing and accessing interpreter-local
+ * data from C. All statics in extensions should be reworked to use
+ * this, if you want to make the extension thread-safe. See ext/re/re.xs
+ * for an example of the use of these macros.
+ *
+ * Code that uses these macros is responsible for the following:
+ * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts"
+ * 2. Declare a typedef named my_cxt_t that is a structure that contains
+ * all the data that needs to be interpreter-local.
+ * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t.
+ * 4. Use the MY_CXT_INIT macro such that it is called exactly once
+ * (typically put in the BOOT: section).
+ * 5. Use the members of the my_cxt_t structure everywhere as
+ * MY_CXT.member.
+ * 6. Use the dMY_CXT macro (a declaration) in all the functions that
+ * access MY_CXT.
+ */
+
+#if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \
+ defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT)
+
+#ifndef START_MY_CXT
+
+/* This must appear in all extensions that define a my_cxt_t structure,
+ * right after the definition (i.e. at file scope). The non-threads
+ * case below uses it to declare the data as static. */
+#define START_MY_CXT
+
+#if (PERL_BCDVERSION < 0x5004068)
+/* Fetches the SV that keeps the per-interpreter data. */
+#define dMY_CXT_SV \
+ SV *my_cxt_sv = get_sv(MY_CXT_KEY, FALSE)
+#else /* >= perl5.004_68 */
+#define dMY_CXT_SV \
+ SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \
+ sizeof(MY_CXT_KEY)-1, TRUE)
+#endif /* < perl5.004_68 */
+
+/* This declaration should be used within all functions that use the
+ * interpreter-local data. */
+#define dMY_CXT \
+ dMY_CXT_SV; \
+ my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv))
+
+/* Creates and zeroes the per-interpreter data.
+ * (We allocate my_cxtp in a Perl SV so that it will be released when
+ * the interpreter goes away.) */
+#define MY_CXT_INIT \
+ dMY_CXT_SV; \
+ /* newSV() allocates one more than needed */ \
+ my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
+ Zero(my_cxtp, 1, my_cxt_t); \
+ sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
+
+/* This macro must be used to access members of the my_cxt_t structure.
+ * e.g. MYCXT.some_data */
+#define MY_CXT (*my_cxtp)
+
+/* Judicious use of these macros can reduce the number of times dMY_CXT
+ * is used. Use is similar to pTHX, aTHX etc. */
+#define pMY_CXT my_cxt_t *my_cxtp
+#define pMY_CXT_ pMY_CXT,
+#define _pMY_CXT ,pMY_CXT
+#define aMY_CXT my_cxtp
+#define aMY_CXT_ aMY_CXT,
+#define _aMY_CXT ,aMY_CXT
+
+#endif /* START_MY_CXT */
+
+#ifndef MY_CXT_CLONE
+/* Clones the per-interpreter data. */
+#define MY_CXT_CLONE \
+ dMY_CXT_SV; \
+ my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
+ Copy(INT2PTR(my_cxt_t*, SvUV(my_cxt_sv)), my_cxtp, 1, my_cxt_t);\
+ sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
+#endif
+
+#else /* single interpreter */
+
+#ifndef START_MY_CXT
+
+#define START_MY_CXT static my_cxt_t my_cxt;
+#define dMY_CXT_SV dNOOP
+#define dMY_CXT dNOOP
+#define MY_CXT_INIT NOOP
+#define MY_CXT my_cxt
+
+#define pMY_CXT void
+#define pMY_CXT_
+#define _pMY_CXT
+#define aMY_CXT
+#define aMY_CXT_
+#define _aMY_CXT
+
+#endif /* START_MY_CXT */
+
+#ifndef MY_CXT_CLONE
+#define MY_CXT_CLONE NOOP
+#endif
+
+#endif
+
+#ifndef IVdf
+# if IVSIZE == LONGSIZE
+# define IVdf "ld"
+# define UVuf "lu"
+# define UVof "lo"
+# define UVxf "lx"
+# define UVXf "lX"
+# else
+# if IVSIZE == INTSIZE
+# define IVdf "d"
+# define UVuf "u"
+# define UVof "o"
+# define UVxf "x"
+# define UVXf "X"
+# endif
+# endif
+#endif
+
+#ifndef NVef
+# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \
+ defined(PERL_PRIfldbl) /* Not very likely, but let's try anyway. */
+# define NVef PERL_PRIeldbl
+# define NVff PERL_PRIfldbl
+# define NVgf PERL_PRIgldbl
+# else
+# define NVef "e"
+# define NVff "f"
+# define NVgf "g"
+# endif
+#endif
+
+#ifndef SvREFCNT_inc
+# ifdef PERL_USE_GCC_BRACE_GROUPS
+# define SvREFCNT_inc(sv) \
+ ({ \
+ SV * const _sv = (SV*)(sv); \
+ if (_sv) \
+ (SvREFCNT(_sv))++; \
+ _sv; \
+ })
+# else
+# define SvREFCNT_inc(sv) \
+ ((PL_Sv=(SV*)(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL)
+# endif
+#endif
+
+#ifndef SvREFCNT_inc_simple
+# ifdef PERL_USE_GCC_BRACE_GROUPS
+# define SvREFCNT_inc_simple(sv) \
+ ({ \
+ if (sv) \
+ (SvREFCNT(sv))++; \
+ (SV *)(sv); \
+ })
+# else
+# define SvREFCNT_inc_simple(sv) \
+ ((sv) ? (SvREFCNT(sv)++,(SV*)(sv)) : NULL)
+# endif
+#endif
+
+#ifndef SvREFCNT_inc_NN
+# ifdef PERL_USE_GCC_BRACE_GROUPS
+# define SvREFCNT_inc_NN(sv) \
+ ({ \
+ SV * const _sv = (SV*)(sv); \
+ SvREFCNT(_sv)++; \
+ _sv; \
+ })
+# else
+# define SvREFCNT_inc_NN(sv) \
+ (PL_Sv=(SV*)(sv),++(SvREFCNT(PL_Sv)),PL_Sv)
+# endif
+#endif
+
+#ifndef SvREFCNT_inc_void
+# ifdef PERL_USE_GCC_BRACE_GROUPS
+# define SvREFCNT_inc_void(sv) \
+ ({ \
+ SV * const _sv = (SV*)(sv); \
+ if (_sv) \
+ (void)(SvREFCNT(_sv)++); \
+ })
+# else
+# define SvREFCNT_inc_void(sv) \
+ (void)((PL_Sv=(SV*)(sv)) ? ++(SvREFCNT(PL_Sv)) : 0)
+# endif
+#endif
+#ifndef SvREFCNT_inc_simple_void
+# define SvREFCNT_inc_simple_void(sv) STMT_START { if (sv) SvREFCNT(sv)++; } STMT_END
+#endif
+
+#ifndef SvREFCNT_inc_simple_NN
+# define SvREFCNT_inc_simple_NN(sv) (++SvREFCNT(sv), (SV*)(sv))
+#endif
+
+#ifndef SvREFCNT_inc_void_NN
+# define SvREFCNT_inc_void_NN(sv) (void)(++SvREFCNT((SV*)(sv)))
+#endif
+
+#ifndef SvREFCNT_inc_simple_void_NN
+# define SvREFCNT_inc_simple_void_NN(sv) (void)(++SvREFCNT((SV*)(sv)))
+#endif
+
+/* Backwards compatibility stuff... :-( */
+#if !defined(NEED_sv_2pv_flags) && defined(NEED_sv_2pv_nolen)
+# define NEED_sv_2pv_flags
+#endif
+#if !defined(NEED_sv_2pv_flags_GLOBAL) && defined(NEED_sv_2pv_nolen_GLOBAL)
+# define NEED_sv_2pv_flags_GLOBAL
+#endif
+
+/* Hint: sv_2pv_nolen
+ * Use the SvPV_nolen() or SvPV_nolen_const() macros instead of sv_2pv_nolen().
+ */
+#ifndef sv_2pv_nolen
+# define sv_2pv_nolen(sv) SvPV_nolen(sv)
+#endif
+
+#ifdef SvPVbyte
+
+/* Hint: SvPVbyte
+ * Does not work in perl-5.6.1, ppport.h implements a version
+ * borrowed from perl-5.7.3.
+ */
+
+#if (PERL_BCDVERSION < 0x5007000)
+
+#if defined(NEED_sv_2pvbyte)
+static char * DPPP_(my_sv_2pvbyte)(pTHX_ SV * sv, STRLEN * lp);
+static
+#else
+extern char * DPPP_(my_sv_2pvbyte)(pTHX_ SV * sv, STRLEN * lp);
+#endif
+
+#ifdef sv_2pvbyte
+# undef sv_2pvbyte
+#endif
+#define sv_2pvbyte(a,b) DPPP_(my_sv_2pvbyte)(aTHX_ a,b)
+#define Perl_sv_2pvbyte DPPP_(my_sv_2pvbyte)
+
+#if defined(NEED_sv_2pvbyte) || defined(NEED_sv_2pvbyte_GLOBAL)
+
+char *
+DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp)
+{
+ sv_utf8_downgrade(sv,0);
+ return SvPV(sv,*lp);
+}
+
+#endif
+
+/* Hint: sv_2pvbyte
+ * Use the SvPVbyte() macro instead of sv_2pvbyte().
+ */
+
+#undef SvPVbyte
+
+#define SvPVbyte(sv, lp) \
+ ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \
+ ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp))
+
+#endif
+
+#else
+
+# define SvPVbyte SvPV
+# define sv_2pvbyte sv_2pv
+
+#endif
+#ifndef sv_2pvbyte_nolen
+# define sv_2pvbyte_nolen(sv) sv_2pv_nolen(sv)
+#endif
+
+/* Hint: sv_pvn
+ * Always use the SvPV() macro instead of sv_pvn().
+ */
+
+/* Hint: sv_pvn_force
+ * Always use the SvPV_force() macro instead of sv_pvn_force().
+ */
+
+/* If these are undefined, they're not handled by the core anyway */
+#ifndef SV_IMMEDIATE_UNREF
+# define SV_IMMEDIATE_UNREF 0
+#endif
+
+#ifndef SV_GMAGIC
+# define SV_GMAGIC 0
+#endif
+
+#ifndef SV_COW_DROP_PV
+# define SV_COW_DROP_PV 0
+#endif
+
+#ifndef SV_UTF8_NO_ENCODING
+# define SV_UTF8_NO_ENCODING 0
+#endif
+
+#ifndef SV_NOSTEAL
+# define SV_NOSTEAL 0
+#endif
+
+#ifndef SV_CONST_RETURN
+# define SV_CONST_RETURN 0
+#endif
+
+#ifndef SV_MUTABLE_RETURN
+# define SV_MUTABLE_RETURN 0
+#endif
+
+#ifndef SV_SMAGIC
+# define SV_SMAGIC 0
+#endif
+
+#ifndef SV_HAS_TRAILING_NUL
+# define SV_HAS_TRAILING_NUL 0
+#endif
+
+#ifndef SV_COW_SHARED_HASH_KEYS
+# define SV_COW_SHARED_HASH_KEYS 0
+#endif
+
+#if (PERL_BCDVERSION < 0x5007002)
+
+#if defined(NEED_sv_2pv_flags)
+static char * DPPP_(my_sv_2pv_flags)(pTHX_ SV * sv, STRLEN * lp, I32 flags);
+static
+#else
+extern char * DPPP_(my_sv_2pv_flags)(pTHX_ SV * sv, STRLEN * lp, I32 flags);
+#endif
+
+#ifdef sv_2pv_flags
+# undef sv_2pv_flags
+#endif
+#define sv_2pv_flags(a,b,c) DPPP_(my_sv_2pv_flags)(aTHX_ a,b,c)
+#define Perl_sv_2pv_flags DPPP_(my_sv_2pv_flags)
+
+#if defined(NEED_sv_2pv_flags) || defined(NEED_sv_2pv_flags_GLOBAL)
+
+char *
+DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags)
+{
+ STRLEN n_a = (STRLEN) flags;
+ return sv_2pv(sv, lp ? lp : &n_a);
+}
+
+#endif
+
+#if defined(NEED_sv_pvn_force_flags)
+static char * DPPP_(my_sv_pvn_force_flags)(pTHX_ SV * sv, STRLEN * lp, I32 flags);
+static
+#else
+extern char * DPPP_(my_sv_pvn_force_flags)(pTHX_ SV * sv, STRLEN * lp, I32 flags);
+#endif
+
+#ifdef sv_pvn_force_flags
+# undef sv_pvn_force_flags
+#endif
+#define sv_pvn_force_flags(a,b,c) DPPP_(my_sv_pvn_force_flags)(aTHX_ a,b,c)
+#define Perl_sv_pvn_force_flags DPPP_(my_sv_pvn_force_flags)
+
+#if defined(NEED_sv_pvn_force_flags) || defined(NEED_sv_pvn_force_flags_GLOBAL)
+
+char *
+DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags)
+{
+ STRLEN n_a = (STRLEN) flags;
+ return sv_pvn_force(sv, lp ? lp : &n_a);
+}
+
+#endif
+
+#endif
+#ifndef SvPV_const
+# define SvPV_const(sv, lp) SvPV_flags_const(sv, lp, SV_GMAGIC)
+#endif
+
+#ifndef SvPV_mutable
+# define SvPV_mutable(sv, lp) SvPV_flags_mutable(sv, lp, SV_GMAGIC)
+#endif
+#ifndef SvPV_flags
+# define SvPV_flags(sv, lp, flags) \
+ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+ ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags))
+#endif
+#ifndef SvPV_flags_const
+# define SvPV_flags_const(sv, lp, flags) \
+ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+ ? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \
+ (const char*) sv_2pv_flags(sv, &lp, flags|SV_CONST_RETURN))
+#endif
+#ifndef SvPV_flags_const_nolen
+# define SvPV_flags_const_nolen(sv, flags) \
+ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+ ? SvPVX_const(sv) : \
+ (const char*) sv_2pv_flags(sv, 0, flags|SV_CONST_RETURN))
+#endif
+#ifndef SvPV_flags_mutable
+# define SvPV_flags_mutable(sv, lp, flags) \
+ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+ ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \
+ sv_2pv_flags(sv, &lp, flags|SV_MUTABLE_RETURN))
+#endif
+#ifndef SvPV_force
+# define SvPV_force(sv, lp) SvPV_force_flags(sv, lp, SV_GMAGIC)
+#endif
+
+#ifndef SvPV_force_nolen
+# define SvPV_force_nolen(sv) SvPV_force_flags_nolen(sv, SV_GMAGIC)
+#endif
+
+#ifndef SvPV_force_mutable
+# define SvPV_force_mutable(sv, lp) SvPV_force_flags_mutable(sv, lp, SV_GMAGIC)
+#endif
+
+#ifndef SvPV_force_nomg
+# define SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0)
+#endif
+
+#ifndef SvPV_force_nomg_nolen
+# define SvPV_force_nomg_nolen(sv) SvPV_force_flags_nolen(sv, 0)
+#endif
+#ifndef SvPV_force_flags
+# define SvPV_force_flags(sv, lp, flags) \
+ ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
+ ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags))
+#endif
+#ifndef SvPV_force_flags_nolen
+# define SvPV_force_flags_nolen(sv, flags) \
+ ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
+ ? SvPVX(sv) : sv_pvn_force_flags(sv, 0, flags))
+#endif
+#ifndef SvPV_force_flags_mutable
+# define SvPV_force_flags_mutable(sv, lp, flags) \
+ ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
+ ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) \
+ : sv_pvn_force_flags(sv, &lp, flags|SV_MUTABLE_RETURN))
+#endif
+#ifndef SvPV_nolen
+# define SvPV_nolen(sv) \
+ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+ ? SvPVX(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC))
+#endif
+#ifndef SvPV_nolen_const
+# define SvPV_nolen_const(sv) \
+ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+ ? SvPVX_const(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC|SV_CONST_RETURN))
+#endif
+#ifndef SvPV_nomg
+# define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0)
+#endif
+
+#ifndef SvPV_nomg_const
+# define SvPV_nomg_const(sv, lp) SvPV_flags_const(sv, lp, 0)
+#endif
+
+#ifndef SvPV_nomg_const_nolen
+# define SvPV_nomg_const_nolen(sv) SvPV_flags_const_nolen(sv, 0)
+#endif
+#ifndef SvMAGIC_set
+# define SvMAGIC_set(sv, val) \
+ STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
+ (((XPVMG*) SvANY(sv))->xmg_magic = (val)); } STMT_END
+#endif
+
+#if (PERL_BCDVERSION < 0x5009003)
+#ifndef SvPVX_const
+# define SvPVX_const(sv) ((const char*) (0 + SvPVX(sv)))
+#endif
+
+#ifndef SvPVX_mutable
+# define SvPVX_mutable(sv) (0 + SvPVX(sv))
+#endif
+#ifndef SvRV_set
+# define SvRV_set(sv, val) \
+ STMT_START { assert(SvTYPE(sv) >= SVt_RV); \
+ (((XRV*) SvANY(sv))->xrv_rv = (val)); } STMT_END
+#endif
+
+#else
+#ifndef SvPVX_const
+# define SvPVX_const(sv) ((const char*)((sv)->sv_u.svu_pv))
+#endif
+
+#ifndef SvPVX_mutable
+# define SvPVX_mutable(sv) ((sv)->sv_u.svu_pv)
+#endif
+#ifndef SvRV_set
+# define SvRV_set(sv, val) \
+ STMT_START { assert(SvTYPE(sv) >= SVt_RV); \
+ ((sv)->sv_u.svu_rv = (val)); } STMT_END
+#endif
+
+#endif
+#ifndef SvSTASH_set
+# define SvSTASH_set(sv, val) \
+ STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
+ (((XPVMG*) SvANY(sv))->xmg_stash = (val)); } STMT_END
+#endif
+
+#if (PERL_BCDVERSION < 0x5004000)
+#ifndef SvUV_set
+# define SvUV_set(sv, val) \
+ STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
+ (((XPVIV*) SvANY(sv))->xiv_iv = (IV) (val)); } STMT_END
+#endif
+
+#else
+#ifndef SvUV_set
+# define SvUV_set(sv, val) \
+ STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
+ (((XPVUV*) SvANY(sv))->xuv_uv = (val)); } STMT_END
+#endif
+
+#endif
+
+#if (PERL_BCDVERSION >= 0x5004000) && !defined(vnewSVpvf)
+#if defined(NEED_vnewSVpvf)
+static SV * DPPP_(my_vnewSVpvf)(pTHX_ const char * pat, va_list * args);
+static
+#else
+extern SV * DPPP_(my_vnewSVpvf)(pTHX_ const char * pat, va_list * args);
+#endif
+
+#ifdef vnewSVpvf
+# undef vnewSVpvf
+#endif
+#define vnewSVpvf(a,b) DPPP_(my_vnewSVpvf)(aTHX_ a,b)
+#define Perl_vnewSVpvf DPPP_(my_vnewSVpvf)
+
+#if defined(NEED_vnewSVpvf) || defined(NEED_vnewSVpvf_GLOBAL)
+
+SV *
+DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args)
+{
+ register SV *sv = newSV(0);
+ sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
+ return sv;
+}
+
+#endif
+#endif
+
+#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vcatpvf)
+# define sv_vcatpvf(sv, pat, args) sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*))
+#endif
+
+#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vsetpvf)
+# define sv_vsetpvf(sv, pat, args) sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*))
+#endif
+
+#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_catpvf_mg)
+#if defined(NEED_sv_catpvf_mg)
+static void DPPP_(my_sv_catpvf_mg)(pTHX_ SV * sv, const char * pat, ...);
+static
+#else
+extern void DPPP_(my_sv_catpvf_mg)(pTHX_ SV * sv, const char * pat, ...);
+#endif
+
+#define Perl_sv_catpvf_mg DPPP_(my_sv_catpvf_mg)
+
+#if defined(NEED_sv_catpvf_mg) || defined(NEED_sv_catpvf_mg_GLOBAL)
+
+void
+DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...)
+{
+ va_list args;
+ va_start(args, pat);
+ sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+ SvSETMAGIC(sv);
+ va_end(args);
+}
+
+#endif
+#endif
+
+#ifdef PERL_IMPLICIT_CONTEXT
+#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_catpvf_mg_nocontext)
+#if defined(NEED_sv_catpvf_mg_nocontext)
+static void DPPP_(my_sv_catpvf_mg_nocontext)(SV * sv, const char * pat, ...);
+static
+#else
+extern void DPPP_(my_sv_catpvf_mg_nocontext)(SV * sv, const char * pat, ...);
+#endif
+
+#define sv_catpvf_mg_nocontext DPPP_(my_sv_catpvf_mg_nocontext)
+#define Perl_sv_catpvf_mg_nocontext DPPP_(my_sv_catpvf_mg_nocontext)
+
+#if defined(NEED_sv_catpvf_mg_nocontext) || defined(NEED_sv_catpvf_mg_nocontext_GLOBAL)
+
+void
+DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...)
+{
+ dTHX;
+ va_list args;
+ va_start(args, pat);
+ sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+ SvSETMAGIC(sv);
+ va_end(args);
+}
+
+#endif
+#endif
+#endif
+
+/* sv_catpvf_mg depends on sv_catpvf_mg_nocontext */
+#ifndef sv_catpvf_mg
+# ifdef PERL_IMPLICIT_CONTEXT
+# define sv_catpvf_mg Perl_sv_catpvf_mg_nocontext
+# else
+# define sv_catpvf_mg Perl_sv_catpvf_mg
+# endif
+#endif
+
+#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vcatpvf_mg)
+# define sv_vcatpvf_mg(sv, pat, args) \
+ STMT_START { \
+ sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); \
+ SvSETMAGIC(sv); \
+ } STMT_END
+#endif
+
+#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_setpvf_mg)
+#if defined(NEED_sv_setpvf_mg)
+static void DPPP_(my_sv_setpvf_mg)(pTHX_ SV * sv, const char * pat, ...);
+static
+#else
+extern void DPPP_(my_sv_setpvf_mg)(pTHX_ SV * sv, const char * pat, ...);
+#endif
+
+#define Perl_sv_setpvf_mg DPPP_(my_sv_setpvf_mg)
+
+#if defined(NEED_sv_setpvf_mg) || defined(NEED_sv_setpvf_mg_GLOBAL)
+
+void
+DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...)
+{
+ va_list args;
+ va_start(args, pat);
+ sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+ SvSETMAGIC(sv);
+ va_end(args);
+}
+
+#endif
+#endif
+
+#ifdef PERL_IMPLICIT_CONTEXT
+#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_setpvf_mg_nocontext)
+#if defined(NEED_sv_setpvf_mg_nocontext)
+static void DPPP_(my_sv_setpvf_mg_nocontext)(SV * sv, const char * pat, ...);
+static
+#else
+extern void DPPP_(my_sv_setpvf_mg_nocontext)(SV * sv, const char * pat, ...);
+#endif
+
+#define sv_setpvf_mg_nocontext DPPP_(my_sv_setpvf_mg_nocontext)
+#define Perl_sv_setpvf_mg_nocontext DPPP_(my_sv_setpvf_mg_nocontext)
+
+#if defined(NEED_sv_setpvf_mg_nocontext) || defined(NEED_sv_setpvf_mg_nocontext_GLOBAL)
+
+void
+DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...)
+{
+ dTHX;
+ va_list args;
+ va_start(args, pat);
+ sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+ SvSETMAGIC(sv);
+ va_end(args);
+}
+
+#endif
+#endif
+#endif
+
+/* sv_setpvf_mg depends on sv_setpvf_mg_nocontext */
+#ifndef sv_setpvf_mg
+# ifdef PERL_IMPLICIT_CONTEXT
+# define sv_setpvf_mg Perl_sv_setpvf_mg_nocontext
+# else
+# define sv_setpvf_mg Perl_sv_setpvf_mg
+# endif
+#endif
+
+#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vsetpvf_mg)
+# define sv_vsetpvf_mg(sv, pat, args) \
+ STMT_START { \
+ sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); \
+ SvSETMAGIC(sv); \
+ } STMT_END
+#endif
+
+#ifndef newSVpvn_share
+
+#if defined(NEED_newSVpvn_share)
+static SV * DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash);
+static
+#else
+extern SV * DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash);
+#endif
+
+#ifdef newSVpvn_share
+# undef newSVpvn_share
+#endif
+#define newSVpvn_share(a,b,c) DPPP_(my_newSVpvn_share)(aTHX_ a,b,c)
+#define Perl_newSVpvn_share DPPP_(my_newSVpvn_share)
+
+#if defined(NEED_newSVpvn_share) || defined(NEED_newSVpvn_share_GLOBAL)
+
+SV *
+DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash)
+{
+ SV *sv;
+ if (len < 0)
+ len = -len;
+ if (!hash)
+ PERL_HASH(hash, (char*) src, len);
+ sv = newSVpvn((char *) src, len);
+ sv_upgrade(sv, SVt_PVIV);
+ SvIVX(sv) = hash;
+ SvREADONLY_on(sv);
+ SvPOK_on(sv);
+ return sv;
+}
+
+#endif
+
+#endif
+#ifndef SvSHARED_HASH
+# define SvSHARED_HASH(sv) (0 + SvUVX(sv))
+#endif
+#ifndef WARN_ALL
+# define WARN_ALL 0
+#endif
+
+#ifndef WARN_CLOSURE
+# define WARN_CLOSURE 1
+#endif
+
+#ifndef WARN_DEPRECATED
+# define WARN_DEPRECATED 2
+#endif
+
+#ifndef WARN_EXITING
+# define WARN_EXITING 3
+#endif
+
+#ifndef WARN_GLOB
+# define WARN_GLOB 4
+#endif
+
+#ifndef WARN_IO
+# define WARN_IO 5
+#endif
+
+#ifndef WARN_CLOSED
+# define WARN_CLOSED 6
+#endif
+
+#ifndef WARN_EXEC
+# define WARN_EXEC 7
+#endif
+
+#ifndef WARN_LAYER
+# define WARN_LAYER 8
+#endif
+
+#ifndef WARN_NEWLINE
+# define WARN_NEWLINE 9
+#endif
+
+#ifndef WARN_PIPE
+# define WARN_PIPE 10
+#endif
+
+#ifndef WARN_UNOPENED
+# define WARN_UNOPENED 11
+#endif
+
+#ifndef WARN_MISC
+# define WARN_MISC 12
+#endif
+
+#ifndef WARN_NUMERIC
+# define WARN_NUMERIC 13
+#endif
+
+#ifndef WARN_ONCE
+# define WARN_ONCE 14
+#endif
+
+#ifndef WARN_OVERFLOW
+# define WARN_OVERFLOW 15
+#endif
+
+#ifndef WARN_PACK
+# define WARN_PACK 16
+#endif
+
+#ifndef WARN_PORTABLE
+# define WARN_PORTABLE 17
+#endif
+
+#ifndef WARN_RECURSION
+# define WARN_RECURSION 18
+#endif
+
+#ifndef WARN_REDEFINE
+# define WARN_REDEFINE 19
+#endif
+
+#ifndef WARN_REGEXP
+# define WARN_REGEXP 20
+#endif
+
+#ifndef WARN_SEVERE
+# define WARN_SEVERE 21
+#endif
+
+#ifndef WARN_DEBUGGING
+# define WARN_DEBUGGING 22
+#endif
+
+#ifndef WARN_INPLACE
+# define WARN_INPLACE 23
+#endif
+
+#ifndef WARN_INTERNAL
+# define WARN_INTERNAL 24
+#endif
+
+#ifndef WARN_MALLOC
+# define WARN_MALLOC 25
+#endif
+
+#ifndef WARN_SIGNAL
+# define WARN_SIGNAL 26
+#endif
+
+#ifndef WARN_SUBSTR
+# define WARN_SUBSTR 27
+#endif
+
+#ifndef WARN_SYNTAX
+# define WARN_SYNTAX 28
+#endif
+
+#ifndef WARN_AMBIGUOUS
+# define WARN_AMBIGUOUS 29
+#endif
+
+#ifndef WARN_BAREWORD
+# define WARN_BAREWORD 30
+#endif
+
+#ifndef WARN_DIGIT
+# define WARN_DIGIT 31
+#endif
+
+#ifndef WARN_PARENTHESIS
+# define WARN_PARENTHESIS 32
+#endif
+
+#ifndef WARN_PRECEDENCE
+# define WARN_PRECEDENCE 33
+#endif
+
+#ifndef WARN_PRINTF
+# define WARN_PRINTF 34
+#endif
+
+#ifndef WARN_PROTOTYPE
+# define WARN_PROTOTYPE 35
+#endif
+
+#ifndef WARN_QW
+# define WARN_QW 36
+#endif
+
+#ifndef WARN_RESERVED
+# define WARN_RESERVED 37
+#endif
+
+#ifndef WARN_SEMICOLON
+# define WARN_SEMICOLON 38
+#endif
+
+#ifndef WARN_TAINT
+# define WARN_TAINT 39
+#endif
+
+#ifndef WARN_THREADS
+# define WARN_THREADS 40
+#endif
+
+#ifndef WARN_UNINITIALIZED
+# define WARN_UNINITIALIZED 41
+#endif
+
+#ifndef WARN_UNPACK
+# define WARN_UNPACK 42
+#endif
+
+#ifndef WARN_UNTIE
+# define WARN_UNTIE 43
+#endif
+
+#ifndef WARN_UTF8
+# define WARN_UTF8 44
+#endif
+
+#ifndef WARN_VOID
+# define WARN_VOID 45
+#endif
+
+#ifndef WARN_ASSERTIONS
+# define WARN_ASSERTIONS 46
+#endif
+#ifndef packWARN
+# define packWARN(a) (a)
+#endif
+
+#ifndef ckWARN
+# ifdef G_WARN_ON
+# define ckWARN(a) (PL_dowarn & G_WARN_ON)
+# else
+# define ckWARN(a) PL_dowarn
+# endif
+#endif
+
+#if (PERL_BCDVERSION >= 0x5004000) && !defined(warner)
+#if defined(NEED_warner)
+static void DPPP_(my_warner)(U32 err, const char *pat, ...);
+static
+#else
+extern void DPPP_(my_warner)(U32 err, const char *pat, ...);
+#endif
+
+#define Perl_warner DPPP_(my_warner)
+
+#if defined(NEED_warner) || defined(NEED_warner_GLOBAL)
+
+void
+DPPP_(my_warner)(U32 err, const char *pat, ...)
+{
+ SV *sv;
+ va_list args;
+
+ PERL_UNUSED_ARG(err);
+
+ va_start(args, pat);
+ sv = vnewSVpvf(pat, &args);
+ va_end(args);
+ sv_2mortal(sv);
+ warn("%s", SvPV_nolen(sv));
+}
+
+#define warner Perl_warner
+
+#define Perl_warner_nocontext Perl_warner
+
+#endif
+#endif
+
+/* concatenating with "" ensures that only literal strings are accepted as argument
+ * note that STR_WITH_LEN() can't be used as argument to macros or functions that
+ * under some configurations might be macros
+ */
+#ifndef STR_WITH_LEN
+# define STR_WITH_LEN(s) (s ""), (sizeof(s)-1)
+#endif
+#ifndef newSVpvs
+# define newSVpvs(str) newSVpvn(str "", sizeof(str) - 1)
+#endif
+
+#ifndef sv_catpvs
+# define sv_catpvs(sv, str) sv_catpvn(sv, str "", sizeof(str) - 1)
+#endif
+
+#ifndef sv_setpvs
+# define sv_setpvs(sv, str) sv_setpvn(sv, str "", sizeof(str) - 1)
+#endif
+
+#ifndef hv_fetchs
+# define hv_fetchs(hv, key, lval) hv_fetch(hv, key "", sizeof(key) - 1, lval)
+#endif
+
+#ifndef hv_stores
+# define hv_stores(hv, key, val) hv_store(hv, key "", sizeof(key) - 1, val, 0)
+#endif
+#ifndef SvGETMAGIC
+# define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END
+#endif
+#ifndef PERL_MAGIC_sv
+# define PERL_MAGIC_sv '\0'
+#endif
+
+#ifndef PERL_MAGIC_overload
+# define PERL_MAGIC_overload 'A'
+#endif
+
+#ifndef PERL_MAGIC_overload_elem
+# define PERL_MAGIC_overload_elem 'a'
+#endif
+
+#ifndef PERL_MAGIC_overload_table
+# define PERL_MAGIC_overload_table 'c'
+#endif
+
+#ifndef PERL_MAGIC_bm
+# define PERL_MAGIC_bm 'B'
+#endif
+
+#ifndef PERL_MAGIC_regdata
+# define PERL_MAGIC_regdata 'D'
+#endif
+
+#ifndef PERL_MAGIC_regdatum
+# define PERL_MAGIC_regdatum 'd'
+#endif
+
+#ifndef PERL_MAGIC_env
+# define PERL_MAGIC_env 'E'
+#endif
+
+#ifndef PERL_MAGIC_envelem
+# define PERL_MAGIC_envelem 'e'
+#endif
+
+#ifndef PERL_MAGIC_fm
+# define PERL_MAGIC_fm 'f'
+#endif
+
+#ifndef PERL_MAGIC_regex_global
+# define PERL_MAGIC_regex_global 'g'
+#endif
+
+#ifndef PERL_MAGIC_isa
+# define PERL_MAGIC_isa 'I'
+#endif
+
+#ifndef PERL_MAGIC_isaelem
+# define PERL_MAGIC_isaelem 'i'
+#endif
+
+#ifndef PERL_MAGIC_nkeys
+# define PERL_MAGIC_nkeys 'k'
+#endif
+
+#ifndef PERL_MAGIC_dbfile
+# define PERL_MAGIC_dbfile 'L'
+#endif
+
+#ifndef PERL_MAGIC_dbline
+# define PERL_MAGIC_dbline 'l'
+#endif
+
+#ifndef PERL_MAGIC_mutex
+# define PERL_MAGIC_mutex 'm'
+#endif
+
+#ifndef PERL_MAGIC_shared
+# define PERL_MAGIC_shared 'N'
+#endif
+
+#ifndef PERL_MAGIC_shared_scalar
+# define PERL_MAGIC_shared_scalar 'n'
+#endif
+
+#ifndef PERL_MAGIC_collxfrm
+# define PERL_MAGIC_collxfrm 'o'
+#endif
+
+#ifndef PERL_MAGIC_tied
+# define PERL_MAGIC_tied 'P'
+#endif
+
+#ifndef PERL_MAGIC_tiedelem
+# define PERL_MAGIC_tiedelem 'p'
+#endif
+
+#ifndef PERL_MAGIC_tiedscalar
+# define PERL_MAGIC_tiedscalar 'q'
+#endif
+
+#ifndef PERL_MAGIC_qr
+# define PERL_MAGIC_qr 'r'
+#endif
+
+#ifndef PERL_MAGIC_sig
+# define PERL_MAGIC_sig 'S'
+#endif
+
+#ifndef PERL_MAGIC_sigelem
+# define PERL_MAGIC_sigelem 's'
+#endif
+
+#ifndef PERL_MAGIC_taint
+# define PERL_MAGIC_taint 't'
+#endif
+
+#ifndef PERL_MAGIC_uvar
+# define PERL_MAGIC_uvar 'U'
+#endif
+
+#ifndef PERL_MAGIC_uvar_elem
+# define PERL_MAGIC_uvar_elem 'u'
+#endif
+
+#ifndef PERL_MAGIC_vstring
+# define PERL_MAGIC_vstring 'V'
+#endif
+
+#ifndef PERL_MAGIC_vec
+# define PERL_MAGIC_vec 'v'
+#endif
+
+#ifndef PERL_MAGIC_utf8
+# define PERL_MAGIC_utf8 'w'
+#endif
+
+#ifndef PERL_MAGIC_substr
+# define PERL_MAGIC_substr 'x'
+#endif
+
+#ifndef PERL_MAGIC_defelem
+# define PERL_MAGIC_defelem 'y'
+#endif
+
+#ifndef PERL_MAGIC_glob
+# define PERL_MAGIC_glob '*'
+#endif
+
+#ifndef PERL_MAGIC_arylen
+# define PERL_MAGIC_arylen '#'
+#endif
+
+#ifndef PERL_MAGIC_pos
+# define PERL_MAGIC_pos '.'
+#endif
+
+#ifndef PERL_MAGIC_backref
+# define PERL_MAGIC_backref '<'
+#endif
+
+#ifndef PERL_MAGIC_ext
+# define PERL_MAGIC_ext '~'
+#endif
+
+/* That's the best we can do... */
+#ifndef sv_catpvn_nomg
+# define sv_catpvn_nomg sv_catpvn
+#endif
+
+#ifndef sv_catsv_nomg
+# define sv_catsv_nomg sv_catsv
+#endif
+
+#ifndef sv_setsv_nomg
+# define sv_setsv_nomg sv_setsv
+#endif
+
+#ifndef sv_pvn_nomg
+# define sv_pvn_nomg sv_pvn
+#endif
+
+#ifndef SvIV_nomg
+# define SvIV_nomg SvIV
+#endif
+
+#ifndef SvUV_nomg
+# define SvUV_nomg SvUV
+#endif
+
+#ifndef sv_catpv_mg
+# define sv_catpv_mg(sv, ptr) \
+ STMT_START { \
+ SV *TeMpSv = sv; \
+ sv_catpv(TeMpSv,ptr); \
+ SvSETMAGIC(TeMpSv); \
+ } STMT_END
+#endif
+
+#ifndef sv_catpvn_mg
+# define sv_catpvn_mg(sv, ptr, len) \
+ STMT_START { \
+ SV *TeMpSv = sv; \
+ sv_catpvn(TeMpSv,ptr,len); \
+ SvSETMAGIC(TeMpSv); \
+ } STMT_END
+#endif
+
+#ifndef sv_catsv_mg
+# define sv_catsv_mg(dsv, ssv) \
+ STMT_START { \
+ SV *TeMpSv = dsv; \
+ sv_catsv(TeMpSv,ssv); \
+ SvSETMAGIC(TeMpSv); \
+ } STMT_END
+#endif
+
+#ifndef sv_setiv_mg
+# define sv_setiv_mg(sv, i) \
+ STMT_START { \
+ SV *TeMpSv = sv; \
+ sv_setiv(TeMpSv,i); \
+ SvSETMAGIC(TeMpSv); \
+ } STMT_END
+#endif
+
+#ifndef sv_setnv_mg
+# define sv_setnv_mg(sv, num) \
+ STMT_START { \
+ SV *TeMpSv = sv; \
+ sv_setnv(TeMpSv,num); \
+ SvSETMAGIC(TeMpSv); \
+ } STMT_END
+#endif
+
+#ifndef sv_setpv_mg
+# define sv_setpv_mg(sv, ptr) \
+ STMT_START { \
+ SV *TeMpSv = sv; \
+ sv_setpv(TeMpSv,ptr); \
+ SvSETMAGIC(TeMpSv); \
+ } STMT_END
+#endif
+
+#ifndef sv_setpvn_mg
+# define sv_setpvn_mg(sv, ptr, len) \
+ STMT_START { \
+ SV *TeMpSv = sv; \
+ sv_setpvn(TeMpSv,ptr,len); \
+ SvSETMAGIC(TeMpSv); \
+ } STMT_END
+#endif
+
+#ifndef sv_setsv_mg
+# define sv_setsv_mg(dsv, ssv) \
+ STMT_START { \
+ SV *TeMpSv = dsv; \
+ sv_setsv(TeMpSv,ssv); \
+ SvSETMAGIC(TeMpSv); \
+ } STMT_END
+#endif
+
+#ifndef sv_setuv_mg
+# define sv_setuv_mg(sv, i) \
+ STMT_START { \
+ SV *TeMpSv = sv; \
+ sv_setuv(TeMpSv,i); \
+ SvSETMAGIC(TeMpSv); \
+ } STMT_END
+#endif
+
+#ifndef sv_usepvn_mg
+# define sv_usepvn_mg(sv, ptr, len) \
+ STMT_START { \
+ SV *TeMpSv = sv; \
+ sv_usepvn(TeMpSv,ptr,len); \
+ SvSETMAGIC(TeMpSv); \
+ } STMT_END
+#endif
+#ifndef SvVSTRING_mg
+# define SvVSTRING_mg(sv) (SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_vstring) : NULL)
+#endif
+
+/* Hint: sv_magic_portable
+ * This is a compatibility function that is only available with
+ * Devel::PPPort. It is NOT in the perl core.
+ * Its purpose is to mimic the 5.8.0 behaviour of sv_magic() when
+ * it is being passed a name pointer with namlen == 0. In that
+ * case, perl 5.8.0 and later store the pointer, not a copy of it.
+ * The compatibility can be provided back to perl 5.004. With
+ * earlier versions, the code will not compile.
+ */
+
+#if (PERL_BCDVERSION < 0x5004000)
+
+ /* code that uses sv_magic_portable will not compile */
+
+#elif (PERL_BCDVERSION < 0x5008000)
+
+# define sv_magic_portable(sv, obj, how, name, namlen) \
+ STMT_START { \
+ SV *SvMp_sv = (sv); \
+ char *SvMp_name = (char *) (name); \
+ I32 SvMp_namlen = (namlen); \
+ if (SvMp_name && SvMp_namlen == 0) \
+ { \
+ MAGIC *mg; \
+ sv_magic(SvMp_sv, obj, how, 0, 0); \
+ mg = SvMAGIC(SvMp_sv); \
+ mg->mg_len = -42; /* XXX: this is the tricky part */ \
+ mg->mg_ptr = SvMp_name; \
+ } \
+ else \
+ { \
+ sv_magic(SvMp_sv, obj, how, SvMp_name, SvMp_namlen); \
+ } \
+ } STMT_END
+
+#else
+
+# define sv_magic_portable(a, b, c, d, e) sv_magic(a, b, c, d, e)
+
+#endif
+
+#ifdef USE_ITHREADS
+#ifndef CopFILE
+# define CopFILE(c) ((c)->cop_file)
+#endif
+
+#ifndef CopFILEGV
+# define CopFILEGV(c) (CopFILE(c) ? gv_fetchfile(CopFILE(c)) : Nullgv)
+#endif
+
+#ifndef CopFILE_set
+# define CopFILE_set(c,pv) ((c)->cop_file = savepv(pv))
+#endif
+
+#ifndef CopFILESV
+# define CopFILESV(c) (CopFILE(c) ? GvSV(gv_fetchfile(CopFILE(c))) : Nullsv)
+#endif
+
+#ifndef CopFILEAV
+# define CopFILEAV(c) (CopFILE(c) ? GvAV(gv_fetchfile(CopFILE(c))) : Nullav)
+#endif
+
+#ifndef CopSTASHPV
+# define CopSTASHPV(c) ((c)->cop_stashpv)
+#endif
+
+#ifndef CopSTASHPV_set
+# define CopSTASHPV_set(c,pv) ((c)->cop_stashpv = ((pv) ? savepv(pv) : Nullch))
+#endif
+
+#ifndef CopSTASH
+# define CopSTASH(c) (CopSTASHPV(c) ? gv_stashpv(CopSTASHPV(c),GV_ADD) : Nullhv)
+#endif
+
+#ifndef CopSTASH_set
+# define CopSTASH_set(c,hv) CopSTASHPV_set(c, (hv) ? HvNAME(hv) : Nullch)
+#endif
+
+#ifndef CopSTASH_eq
+# define CopSTASH_eq(c,hv) ((hv) && (CopSTASHPV(c) == HvNAME(hv) \
+ || (CopSTASHPV(c) && HvNAME(hv) \
+ && strEQ(CopSTASHPV(c), HvNAME(hv)))))
+#endif
+
+#else
+#ifndef CopFILEGV
+# define CopFILEGV(c) ((c)->cop_filegv)
+#endif
+
+#ifndef CopFILEGV_set
+# define CopFILEGV_set(c,gv) ((c)->cop_filegv = (GV*)SvREFCNT_inc(gv))
+#endif
+
+#ifndef CopFILE_set
+# define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv))
+#endif
+
+#ifndef CopFILESV
+# define CopFILESV(c) (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : Nullsv)
+#endif
+
+#ifndef CopFILEAV
+# define CopFILEAV(c) (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : Nullav)
+#endif
+
+#ifndef CopFILE
+# define CopFILE(c) (CopFILESV(c) ? SvPVX(CopFILESV(c)) : Nullch)
+#endif
+
+#ifndef CopSTASH
+# define CopSTASH(c) ((c)->cop_stash)
+#endif
+
+#ifndef CopSTASH_set
+# define CopSTASH_set(c,hv) ((c)->cop_stash = (hv))
+#endif
+
+#ifndef CopSTASHPV
+# define CopSTASHPV(c) (CopSTASH(c) ? HvNAME(CopSTASH(c)) : Nullch)
+#endif
+
+#ifndef CopSTASHPV_set
+# define CopSTASHPV_set(c,pv) CopSTASH_set((c), gv_stashpv(pv,GV_ADD))
+#endif
+
+#ifndef CopSTASH_eq
+# define CopSTASH_eq(c,hv) (CopSTASH(c) == (hv))
+#endif
+
+#endif /* USE_ITHREADS */
+#ifndef IN_PERL_COMPILETIME
+# define IN_PERL_COMPILETIME (PL_curcop == &PL_compiling)
+#endif
+
+#ifndef IN_LOCALE_RUNTIME
+# define IN_LOCALE_RUNTIME (PL_curcop->op_private & HINT_LOCALE)
+#endif
+
+#ifndef IN_LOCALE_COMPILETIME
+# define IN_LOCALE_COMPILETIME (PL_hints & HINT_LOCALE)
+#endif
+
+#ifndef IN_LOCALE
+# define IN_LOCALE (IN_PERL_COMPILETIME ? IN_LOCALE_COMPILETIME : IN_LOCALE_RUNTIME)
+#endif
+#ifndef IS_NUMBER_IN_UV
+# define IS_NUMBER_IN_UV 0x01
+#endif
+
+#ifndef IS_NUMBER_GREATER_THAN_UV_MAX
+# define IS_NUMBER_GREATER_THAN_UV_MAX 0x02
+#endif
+
+#ifndef IS_NUMBER_NOT_INT
+# define IS_NUMBER_NOT_INT 0x04
+#endif
+
+#ifndef IS_NUMBER_NEG
+# define IS_NUMBER_NEG 0x08
+#endif
+
+#ifndef IS_NUMBER_INFINITY
+# define IS_NUMBER_INFINITY 0x10
+#endif
+
+#ifndef IS_NUMBER_NAN
+# define IS_NUMBER_NAN 0x20
+#endif
+#ifndef GROK_NUMERIC_RADIX
+# define GROK_NUMERIC_RADIX(sp, send) grok_numeric_radix(sp, send)
+#endif
+#ifndef PERL_SCAN_GREATER_THAN_UV_MAX
+# define PERL_SCAN_GREATER_THAN_UV_MAX 0x02
+#endif
+
+#ifndef PERL_SCAN_SILENT_ILLDIGIT
+# define PERL_SCAN_SILENT_ILLDIGIT 0x04
+#endif
+
+#ifndef PERL_SCAN_ALLOW_UNDERSCORES
+# define PERL_SCAN_ALLOW_UNDERSCORES 0x01
+#endif
+
+#ifndef PERL_SCAN_DISALLOW_PREFIX
+# define PERL_SCAN_DISALLOW_PREFIX 0x02
+#endif
+
+#ifndef grok_numeric_radix
+#if defined(NEED_grok_numeric_radix)
+static bool DPPP_(my_grok_numeric_radix)(pTHX_ const char ** sp, const char * send);
+static
+#else
+extern bool DPPP_(my_grok_numeric_radix)(pTHX_ const char ** sp, const char * send);
+#endif
+
+#ifdef grok_numeric_radix
+# undef grok_numeric_radix
+#endif
+#define grok_numeric_radix(a,b) DPPP_(my_grok_numeric_radix)(aTHX_ a,b)
+#define Perl_grok_numeric_radix DPPP_(my_grok_numeric_radix)
+
+#if defined(NEED_grok_numeric_radix) || defined(NEED_grok_numeric_radix_GLOBAL)
+bool
+DPPP_(my_grok_numeric_radix)(pTHX_ const char **sp, const char *send)
+{
+#ifdef USE_LOCALE_NUMERIC
+#ifdef PL_numeric_radix_sv
+ if (PL_numeric_radix_sv && IN_LOCALE) {
+ STRLEN len;
+ char* radix = SvPV(PL_numeric_radix_sv, len);
+ if (*sp + len <= send && memEQ(*sp, radix, len)) {
+ *sp += len;
+ return TRUE;
+ }
+ }
+#else
+ /* older perls don't have PL_numeric_radix_sv so the radix
+ * must manually be requested from locale.h
+ */
+#include <locale.h>
+ dTHR; /* needed for older threaded perls */
+ struct lconv *lc = localeconv();
+ char *radix = lc->decimal_point;
+ if (radix && IN_LOCALE) {
+ STRLEN len = strlen(radix);
+ if (*sp + len <= send && memEQ(*sp, radix, len)) {
+ *sp += len;
+ return TRUE;
+ }
+ }
+#endif
+#endif /* USE_LOCALE_NUMERIC */
+ /* always try "." if numeric radix didn't match because
+ * we may have data from different locales mixed */
+ if (*sp < send && **sp == '.') {
+ ++*sp;
+ return TRUE;
+ }
+ return FALSE;
+}
+#endif
+#endif
+
+#ifndef grok_number
+#if defined(NEED_grok_number)
+static int DPPP_(my_grok_number)(pTHX_ const char * pv, STRLEN len, UV * valuep);
+static
+#else
+extern int DPPP_(my_grok_number)(pTHX_ const char * pv, STRLEN len, UV * valuep);
+#endif
+
+#ifdef grok_number
+# undef grok_number
+#endif
+#define grok_number(a,b,c) DPPP_(my_grok_number)(aTHX_ a,b,c)
+#define Perl_grok_number DPPP_(my_grok_number)
+
+#if defined(NEED_grok_number) || defined(NEED_grok_number_GLOBAL)
+int
+DPPP_(my_grok_number)(pTHX_ const char *pv, STRLEN len, UV *valuep)
+{
+ const char *s = pv;
+ const char *send = pv + len;
+ const UV max_div_10 = UV_MAX / 10;
+ const char max_mod_10 = UV_MAX % 10;
+ int numtype = 0;
+ int sawinf = 0;
+ int sawnan = 0;
+
+ while (s < send && isSPACE(*s))
+ s++;
+ if (s == send) {
+ return 0;
+ } else if (*s == '-') {
+ s++;
+ numtype = IS_NUMBER_NEG;
+ }
+ else if (*s == '+')
+ s++;
+
+ if (s == send)
+ return 0;
+
+ /* next must be digit or the radix separator or beginning of infinity */
+ if (isDIGIT(*s)) {
+ /* UVs are at least 32 bits, so the first 9 decimal digits cannot
+ overflow. */
+ UV value = *s - '0';
+ /* This construction seems to be more optimiser friendly.
+ (without it gcc does the isDIGIT test and the *s - '0' separately)
+ With it gcc on arm is managing 6 instructions (6 cycles) per digit.
+ In theory the optimiser could deduce how far to unroll the loop
+ before checking for overflow. */
+ if (++s < send) {
+ int digit = *s - '0';
+ if (digit >= 0 && digit <= 9) {
+ value = value * 10 + digit;
+ if (++s < send) {
+ digit = *s - '0';
+ if (digit >= 0 && digit <= 9) {
+ value = value * 10 + digit;
+ if (++s < send) {
+ digit = *s - '0';
+ if (digit >= 0 && digit <= 9) {
+ value = value * 10 + digit;
+ if (++s < send) {
+ digit = *s - '0';
+ if (digit >= 0 && digit <= 9) {
+ value = value * 10 + digit;
+ if (++s < send) {
+ digit = *s - '0';
+ if (digit >= 0 && digit <= 9) {
+ value = value * 10 + digit;
+ if (++s < send) {
+ digit = *s - '0';
+ if (digit >= 0 && digit <= 9) {
+ value = value * 10 + digit;
+ if (++s < send) {
+ digit = *s - '0';
+ if (digit >= 0 && digit <= 9) {
+ value = value * 10 + digit;
+ if (++s < send) {
+ digit = *s - '0';
+ if (digit >= 0 && digit <= 9) {
+ value = value * 10 + digit;
+ if (++s < send) {
+ /* Now got 9 digits, so need to check
+ each time for overflow. */
+ digit = *s - '0';
+ while (digit >= 0 && digit <= 9
+ && (value < max_div_10
+ || (value == max_div_10
+ && digit <= max_mod_10))) {
+ value = value * 10 + digit;
+ if (++s < send)
+ digit = *s - '0';
+ else
+ break;
+ }
+ if (digit >= 0 && digit <= 9
+ && (s < send)) {
+ /* value overflowed.
+ skip the remaining digits, don't
+ worry about setting *valuep. */
+ do {
+ s++;
+ } while (s < send && isDIGIT(*s));
+ numtype |=
+ IS_NUMBER_GREATER_THAN_UV_MAX;
+ goto skip_value;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ numtype |= IS_NUMBER_IN_UV;
+ if (valuep)
+ *valuep = value;
+
+ skip_value:
+ if (GROK_NUMERIC_RADIX(&s, send)) {
+ numtype |= IS_NUMBER_NOT_INT;
+ while (s < send && isDIGIT(*s)) /* optional digits after the radix */
+ s++;
+ }
+ }
+ else if (GROK_NUMERIC_RADIX(&s, send)) {
+ numtype |= IS_NUMBER_NOT_INT | IS_NUMBER_IN_UV; /* valuep assigned below */
+ /* no digits before the radix means we need digits after it */
+ if (s < send && isDIGIT(*s)) {
+ do {
+ s++;
+ } while (s < send && isDIGIT(*s));
+ if (valuep) {
+ /* integer approximation is valid - it's 0. */
+ *valuep = 0;
+ }
+ }
+ else
+ return 0;
+ } else if (*s == 'I' || *s == 'i') {
+ s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
+ s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
+ s++; if (s < send && (*s == 'I' || *s == 'i')) {
+ s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
+ s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
+ s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
+ s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
+ s++;
+ }
+ sawinf = 1;
+ } else if (*s == 'N' || *s == 'n') {
+ /* XXX TODO: There are signaling NaNs and quiet NaNs. */
+ s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
+ s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
+ s++;
+ sawnan = 1;
+ } else
+ return 0;
+
+ if (sawinf) {
+ numtype &= IS_NUMBER_NEG; /* Keep track of sign */
+ numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
+ } else if (sawnan) {
+ numtype &= IS_NUMBER_NEG; /* Keep track of sign */
+ numtype |= IS_NUMBER_NAN | IS_NUMBER_NOT_INT;
+ } else if (s < send) {
+ /* we can have an optional exponent part */
+ if (*s == 'e' || *s == 'E') {
+ /* The only flag we keep is sign. Blow away any "it's UV" */
+ numtype &= IS_NUMBER_NEG;
+ numtype |= IS_NUMBER_NOT_INT;
+ s++;
+ if (s < send && (*s == '-' || *s == '+'))
+ s++;
+ if (s < send && isDIGIT(*s)) {
+ do {
+ s++;
+ } while (s < send && isDIGIT(*s));
+ }
+ else
+ return 0;
+ }
+ }
+ while (s < send && isSPACE(*s))
+ s++;
+ if (s >= send)
+ return numtype;
+ if (len == 10 && memEQ(pv, "0 but true", 10)) {
+ if (valuep)
+ *valuep = 0;
+ return IS_NUMBER_IN_UV;
+ }
+ return 0;
+}
+#endif
+#endif
+
+/*
+ * The grok_* routines have been modified to use warn() instead of
+ * Perl_warner(). Also, 'hexdigit' was the former name of PL_hexdigit,
+ * which is why the stack variable has been renamed to 'xdigit'.
+ */
+
+#ifndef grok_bin
+#if defined(NEED_grok_bin)
+static UV DPPP_(my_grok_bin)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result);
+static
+#else
+extern UV DPPP_(my_grok_bin)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result);
+#endif
+
+#ifdef grok_bin
+# undef grok_bin
+#endif
+#define grok_bin(a,b,c,d) DPPP_(my_grok_bin)(aTHX_ a,b,c,d)
+#define Perl_grok_bin DPPP_(my_grok_bin)
+
+#if defined(NEED_grok_bin) || defined(NEED_grok_bin_GLOBAL)
+UV
+DPPP_(my_grok_bin)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result)
+{
+ const char *s = start;
+ STRLEN len = *len_p;
+ UV value = 0;
+ NV value_nv = 0;
+
+ const UV max_div_2 = UV_MAX / 2;
+ bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES;
+ bool overflowed = FALSE;
+
+ if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) {
+ /* strip off leading b or 0b.
+ for compatibility silently suffer "b" and "0b" as valid binary
+ numbers. */
+ if (len >= 1) {
+ if (s[0] == 'b') {
+ s++;
+ len--;
+ }
+ else if (len >= 2 && s[0] == '0' && s[1] == 'b') {
+ s+=2;
+ len-=2;
+ }
+ }
+ }
+
+ for (; len-- && *s; s++) {
+ char bit = *s;
+ if (bit == '0' || bit == '1') {
+ /* Write it in this wonky order with a goto to attempt to get the
+ compiler to make the common case integer-only loop pretty tight.
+ With gcc seems to be much straighter code than old scan_bin. */
+ redo:
+ if (!overflowed) {
+ if (value <= max_div_2) {
+ value = (value << 1) | (bit - '0');
+ continue;
+ }
+ /* Bah. We're just overflowed. */
+ warn("Integer overflow in binary number");
+ overflowed = TRUE;
+ value_nv = (NV) value;
+ }
+ value_nv *= 2.0;
+ /* If an NV has not enough bits in its mantissa to
+ * represent a UV this summing of small low-order numbers
+ * is a waste of time (because the NV cannot preserve
+ * the low-order bits anyway): we could just remember when
+ * did we overflow and in the end just multiply value_nv by the
+ * right amount. */
+ value_nv += (NV)(bit - '0');
+ continue;
+ }
+ if (bit == '_' && len && allow_underscores && (bit = s[1])
+ && (bit == '0' || bit == '1'))
+ {
+ --len;
+ ++s;
+ goto redo;
+ }
+ if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT))
+ warn("Illegal binary digit '%c' ignored", *s);
+ break;
+ }
+
+ if ( ( overflowed && value_nv > 4294967295.0)
+#if UVSIZE > 4
+ || (!overflowed && value > 0xffffffff )
+#endif
+ ) {
+ warn("Binary number > 0b11111111111111111111111111111111 non-portable");
+ }
+ *len_p = s - start;
+ if (!overflowed) {
+ *flags = 0;
+ return value;
+ }
+ *flags = PERL_SCAN_GREATER_THAN_UV_MAX;
+ if (result)
+ *result = value_nv;
+ return UV_MAX;
+}
+#endif
+#endif
+
+#ifndef grok_hex
+#if defined(NEED_grok_hex)
+static UV DPPP_(my_grok_hex)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result);
+static
+#else
+extern UV DPPP_(my_grok_hex)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result);
+#endif
+
+#ifdef grok_hex
+# undef grok_hex
+#endif
+#define grok_hex(a,b,c,d) DPPP_(my_grok_hex)(aTHX_ a,b,c,d)
+#define Perl_grok_hex DPPP_(my_grok_hex)
+
+#if defined(NEED_grok_hex) || defined(NEED_grok_hex_GLOBAL)
+UV
+DPPP_(my_grok_hex)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result)
+{
+ const char *s = start;
+ STRLEN len = *len_p;
+ UV value = 0;
+ NV value_nv = 0;
+
+ const UV max_div_16 = UV_MAX / 16;
+ bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES;
+ bool overflowed = FALSE;
+ const char *xdigit;
+
+ if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) {
+ /* strip off leading x or 0x.
+ for compatibility silently suffer "x" and "0x" as valid hex numbers.
+ */
+ if (len >= 1) {
+ if (s[0] == 'x') {
+ s++;
+ len--;
+ }
+ else if (len >= 2 && s[0] == '0' && s[1] == 'x') {
+ s+=2;
+ len-=2;
+ }
+ }
+ }
+
+ for (; len-- && *s; s++) {
+ xdigit = strchr((char *) PL_hexdigit, *s);
+ if (xdigit) {
+ /* Write it in this wonky order with a goto to attempt to get the
+ compiler to make the common case integer-only loop pretty tight.
+ With gcc seems to be much straighter code than old scan_hex. */
+ redo:
+ if (!overflowed) {
+ if (value <= max_div_16) {
+ value = (value << 4) | ((xdigit - PL_hexdigit) & 15);
+ continue;
+ }
+ warn("Integer overflow in hexadecimal number");
+ overflowed = TRUE;
+ value_nv = (NV) value;
+ }
+ value_nv *= 16.0;
+ /* If an NV has not enough bits in its mantissa to
+ * represent a UV this summing of small low-order numbers
+ * is a waste of time (because the NV cannot preserve
+ * the low-order bits anyway): we could just remember when
+ * did we overflow and in the end just multiply value_nv by the
+ * right amount of 16-tuples. */
+ value_nv += (NV)((xdigit - PL_hexdigit) & 15);
+ continue;
+ }
+ if (*s == '_' && len && allow_underscores && s[1]
+ && (xdigit = strchr((char *) PL_hexdigit, s[1])))
+ {
+ --len;
+ ++s;
+ goto redo;
+ }
+ if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT))
+ warn("Illegal hexadecimal digit '%c' ignored", *s);
+ break;
+ }
+
+ if ( ( overflowed && value_nv > 4294967295.0)
+#if UVSIZE > 4
+ || (!overflowed && value > 0xffffffff )
+#endif
+ ) {
+ warn("Hexadecimal number > 0xffffffff non-portable");
+ }
+ *len_p = s - start;
+ if (!overflowed) {
+ *flags = 0;
+ return value;
+ }
+ *flags = PERL_SCAN_GREATER_THAN_UV_MAX;
+ if (result)
+ *result = value_nv;
+ return UV_MAX;
+}
+#endif
+#endif
+
+#ifndef grok_oct
+#if defined(NEED_grok_oct)
+static UV DPPP_(my_grok_oct)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result);
+static
+#else
+extern UV DPPP_(my_grok_oct)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result);
+#endif
+
+#ifdef grok_oct
+# undef grok_oct
+#endif
+#define grok_oct(a,b,c,d) DPPP_(my_grok_oct)(aTHX_ a,b,c,d)
+#define Perl_grok_oct DPPP_(my_grok_oct)
+
+#if defined(NEED_grok_oct) || defined(NEED_grok_oct_GLOBAL)
+UV
+DPPP_(my_grok_oct)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result)
+{
+ const char *s = start;
+ STRLEN len = *len_p;
+ UV value = 0;
+ NV value_nv = 0;
+
+ const UV max_div_8 = UV_MAX / 8;
+ bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES;
+ bool overflowed = FALSE;
+
+ for (; len-- && *s; s++) {
+ /* gcc 2.95 optimiser not smart enough to figure that this subtraction
+ out front allows slicker code. */
+ int digit = *s - '0';
+ if (digit >= 0 && digit <= 7) {
+ /* Write it in this wonky order with a goto to attempt to get the
+ compiler to make the common case integer-only loop pretty tight.
+ */
+ redo:
+ if (!overflowed) {
+ if (value <= max_div_8) {
+ value = (value << 3) | digit;
+ continue;
+ }
+ /* Bah. We're just overflowed. */
+ warn("Integer overflow in octal number");
+ overflowed = TRUE;
+ value_nv = (NV) value;
+ }
+ value_nv *= 8.0;
+ /* If an NV has not enough bits in its mantissa to
+ * represent a UV this summing of small low-order numbers
+ * is a waste of time (because the NV cannot preserve
+ * the low-order bits anyway): we could just remember when
+ * did we overflow and in the end just multiply value_nv by the
+ * right amount of 8-tuples. */
+ value_nv += (NV)digit;
+ continue;
+ }
+ if (digit == ('_' - '0') && len && allow_underscores
+ && (digit = s[1] - '0') && (digit >= 0 && digit <= 7))
+ {
+ --len;
+ ++s;
+ goto redo;
+ }
+ /* Allow \octal to work the DWIM way (that is, stop scanning
+ * as soon as non-octal characters are seen, complain only iff
+ * someone seems to want to use the digits eight and nine). */
+ if (digit == 8 || digit == 9) {
+ if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT))
+ warn("Illegal octal digit '%c' ignored", *s);
+ }
+ break;
+ }
+
+ if ( ( overflowed && value_nv > 4294967295.0)
+#if UVSIZE > 4
+ || (!overflowed && value > 0xffffffff )
+#endif
+ ) {
+ warn("Octal number > 037777777777 non-portable");
+ }
+ *len_p = s - start;
+ if (!overflowed) {
+ *flags = 0;
+ return value;
+ }
+ *flags = PERL_SCAN_GREATER_THAN_UV_MAX;
+ if (result)
+ *result = value_nv;
+ return UV_MAX;
+}
+#endif
+#endif
+
+#if !defined(my_snprintf)
+#if defined(NEED_my_snprintf)
+static int DPPP_(my_my_snprintf)(char * buffer, const Size_t len, const char * format, ...);
+static
+#else
+extern int DPPP_(my_my_snprintf)(char * buffer, const Size_t len, const char * format, ...);
+#endif
+
+#define my_snprintf DPPP_(my_my_snprintf)
+#define Perl_my_snprintf DPPP_(my_my_snprintf)
+
+#if defined(NEED_my_snprintf) || defined(NEED_my_snprintf_GLOBAL)
+
+int
+DPPP_(my_my_snprintf)(char *buffer, const Size_t len, const char *format, ...)
+{
+ dTHX;
+ int retval;
+ va_list ap;
+ va_start(ap, format);
+#ifdef HAS_VSNPRINTF
+ retval = vsnprintf(buffer, len, format, ap);
+#else
+ retval = vsprintf(buffer, format, ap);
+#endif
+ va_end(ap);
+ if (retval >= (int)len)
+ Perl_croak(aTHX_ "panic: my_snprintf buffer overflow");
+ return retval;
+}
+
+#endif
+#endif
+
+#ifdef NO_XSLOCKS
+# ifdef dJMPENV
+# define dXCPT dJMPENV; int rEtV = 0
+# define XCPT_TRY_START JMPENV_PUSH(rEtV); if (rEtV == 0)
+# define XCPT_TRY_END JMPENV_POP;
+# define XCPT_CATCH if (rEtV != 0)
+# define XCPT_RETHROW JMPENV_JUMP(rEtV)
+# else
+# define dXCPT Sigjmp_buf oldTOP; int rEtV = 0
+# define XCPT_TRY_START Copy(top_env, oldTOP, 1, Sigjmp_buf); rEtV = Sigsetjmp(top_env, 1); if (rEtV == 0)
+# define XCPT_TRY_END Copy(oldTOP, top_env, 1, Sigjmp_buf);
+# define XCPT_CATCH if (rEtV != 0)
+# define XCPT_RETHROW Siglongjmp(top_env, rEtV)
+# endif
+#endif
+
+#if !defined(my_strlcat)
+#if defined(NEED_my_strlcat)
+static Size_t DPPP_(my_my_strlcat)(char * dst, const char * src, Size_t size);
+static
+#else
+extern Size_t DPPP_(my_my_strlcat)(char * dst, const char * src, Size_t size);
+#endif
+
+#define my_strlcat DPPP_(my_my_strlcat)
+#define Perl_my_strlcat DPPP_(my_my_strlcat)
+
+#if defined(NEED_my_strlcat) || defined(NEED_my_strlcat_GLOBAL)
+
+Size_t
+DPPP_(my_my_strlcat)(char *dst, const char *src, Size_t size)
+{
+ Size_t used, length, copy;
+
+ used = strlen(dst);
+ length = strlen(src);
+ if (size > 0 && used < size - 1) {
+ copy = (length >= size - used) ? size - used - 1 : length;
+ memcpy(dst + used, src, copy);
+ dst[used + copy] = '\0';
+ }
+ return used + length;
+}
+#endif
+#endif
+
+#if !defined(my_strlcpy)
+#if defined(NEED_my_strlcpy)
+static Size_t DPPP_(my_my_strlcpy)(char * dst, const char * src, Size_t size);
+static
+#else
+extern Size_t DPPP_(my_my_strlcpy)(char * dst, const char * src, Size_t size);
+#endif
+
+#define my_strlcpy DPPP_(my_my_strlcpy)
+#define Perl_my_strlcpy DPPP_(my_my_strlcpy)
+
+#if defined(NEED_my_strlcpy) || defined(NEED_my_strlcpy_GLOBAL)
+
+Size_t
+DPPP_(my_my_strlcpy)(char *dst, const char *src, Size_t size)
+{
+ Size_t length, copy;
+
+ length = strlen(src);
+ if (size > 0) {
+ copy = (length >= size) ? size - 1 : length;
+ memcpy(dst, src, copy);
+ dst[copy] = '\0';
+ }
+ return length;
+}
+
+#endif
+#endif
+
+#endif /* _P_P_PORTABILITY_H_ */
+
+/* End of File ppport.h */
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/t/HandlerSocket.t b/plugin/handler_socket/perl-Net-HandlerSocket/t/HandlerSocket.t
new file mode 100644
index 00000000000..adb7c981e23
--- /dev/null
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/t/HandlerSocket.t
@@ -0,0 +1,15 @@
+# Before `make install' is performed this script should be runnable with
+# `make test'. After `make install' it should work as `perl HandlerSocket.t'
+
+#########################
+
+# change 'tests => 1' to 'tests => last_test_to_print';
+
+use Test::More tests => 1;
+BEGIN { use_ok('Net::HandlerSocket') };
+
+#########################
+
+# Insert your test code below, the Test::More module is use()ed here so read
+# its man page ( perldoc Test::More ) for help writing this test script.
+
diff --git a/plugin/handler_socket/plug.in b/plugin/handler_socket/plug.in
new file mode 100644
index 00000000000..fd351dec98d
--- /dev/null
+++ b/plugin/handler_socket/plug.in
@@ -0,0 +1,20 @@
+MYSQL_PLUGIN(handlersocket, [HandlerSocket], [HandlerSocket], [max])
+MYSQL_PLUGIN_DYNAMIC(handlersocket, handlersocket.la)
+MYSQL_PLUGIN_ACTIONS(handlersocket,
+[
+ ac_mysql_source_dir='$(top_srcdir)'
+ MYSQL_INC="-I$ac_mysql_source_dir/sql"
+ MYSQL_INC="$MYSQL_INC -I$ac_mysql_source_dir/include"
+ MYSQL_INC="$MYSQL_INC -I$ac_mysql_source_dir/regex"
+ MYSQL_INC="$MYSQL_INC -I$ac_mysql_source_dir"
+ MYSQL_LIB='-L$(top_builddir)/libservices -lmysqlservices'
+ PLUGIN_DIR='$(pkglibdir)/plugin'
+ HANDLERSOCKET_SUBDIRS="libhsclient handlersocket client"
+
+ AC_SUBST(MYSQL_INC)
+ AC_SUBST(MYSQL_CFLAGS)
+ AC_SUBST(MYSQL_LIB)
+ AC_SUBST(PLUGIN_DIR)
+ AC_SUBST(HANDLERSOCKET_SUBDIRS)
+ AC_CONFIG_FILES(plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL)
+])
diff --git a/plugin/handler_socket/regtest/common/binary_my.cnf b/plugin/handler_socket/regtest/common/binary_my.cnf
new file mode 100644
index 00000000000..c3f7c02c7c6
--- /dev/null
+++ b/plugin/handler_socket/regtest/common/binary_my.cnf
@@ -0,0 +1,4 @@
+
+[perl]
+default-character-set-name = binary
+
diff --git a/plugin/handler_socket/regtest/common/compat.sh b/plugin/handler_socket/regtest/common/compat.sh
new file mode 100644
index 00000000000..7804bdf16e1
--- /dev/null
+++ b/plugin/handler_socket/regtest/common/compat.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+if [ "`uname -o`" = "Cygwin" ]; then
+ export DIFF='diff --ignore-space --strip-trailing-cr'
+elif [ "`uname`" = "Darwin" ]; then
+ export DIFF='diff'
+else
+ export DIFF='diff --ignore-space --strip-trailing-cr'
+fi
+
+compile_c() {
+ if [ "`uname -o`" = "Cygwin" ]; then
+ cl /W3 /I../.. /EHsc /FD /MD "$1" /link /DLL "/OUT:$2.dll" \
+ ../../libase.lib 2> cl.log
+ else
+ $CXX -I../.. -O3 -g -Wall -fPIC -shared "$1" -o "$2.so"
+ fi
+}
+
+compile_j() {
+ if [ "`uname -o`" = "Cygwin" ]; then
+ jdk="`echo /cygdrive/c/Program\ Files/Java/jdk* | head -1`"
+ else
+ jdk="$SUNJDK"
+ fi
+ "$jdk/bin/javac" -g "$1"/*.java
+ "$jdk/bin/jar" -cf "$1.jar" "$1"/*.class
+}
+
diff --git a/plugin/handler_socket/regtest/common/hstest.pm b/plugin/handler_socket/regtest/common/hstest.pm
new file mode 100644
index 00000000000..348242b027f
--- /dev/null
+++ b/plugin/handler_socket/regtest/common/hstest.pm
@@ -0,0 +1,66 @@
+
+# vim:sw=2:ai
+
+package hstest;
+
+use DBI;
+use Net::HandlerSocket;
+
+our %conf = ();
+
+sub get_conf_env {
+ my ($key, $defval) = @_;
+ return $ENV{$key} || $defval;
+}
+
+sub init_conf {
+ $conf{host} = get_conf_env("MYHOST", "localhost");
+ $conf{myport} = get_conf_env("MYPORT", 3306);
+ $conf{dbname} = get_conf_env("MYDBNAME", "hstestdb");
+ $conf{ssps} = get_conf_env("MYSSPS");
+ $conf{user} = get_conf_env("MYSQLUSER", "root");
+ $conf{pass} = get_conf_env("MYSQLPASS", "");
+ $conf{hsport} = get_conf_env("HSPORT", 9998);
+ $conf{hspass} = get_conf_env("HSPASS", undef);
+}
+
+sub get_dbi_connection {
+ my ($dbname, $host, $myport, $ssps, $user, $pass)
+ = ($conf{dbname}, $conf{host}, $conf{myport}, $conf{ssps},
+ $conf{user}, $conf{pass});
+ my $mycnf = "binary_my.cnf";
+ my $dsn = "DBI:mysql:database=;host=$host;port=$myport"
+ . ";mysql_server_prepare=$ssps"
+ . ";mysql_read_default_group=perl"
+ . ";mysql_read_default_file=../common/$mycnf";
+ my $dbh = DBI->connect($dsn, $user, $pass, { RaiseError => 1 });
+ return $dbh;
+}
+
+sub init_testdb {
+ my $charset = $_[0] || "binary";
+ my $dbh = get_dbi_connection();
+ my $dbname = $conf{dbname};
+ $dbh->do("drop database if exists $dbname");
+ $dbh->do("create database $dbname default character set $charset");
+ $dbh->do("use $dbname");
+ return $dbh;
+}
+
+sub get_hs_connection {
+ my ($host, $port) = @_;
+ $host ||= $conf{host};
+ $port ||= $conf{hsport};
+ my $hsargs = { 'host' => $host, 'port' => $port };
+ my $conn = new Net::HandlerSocket($hsargs);
+ if (defined($conn) && defined($conf{hspass})) {
+ $conn->auth($conf{hspass});
+ }
+ return $conn;
+}
+
+
+init_conf();
+
+1;
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/run.sh b/plugin/handler_socket/regtest/test_01_lib/run.sh
new file mode 100755
index 00000000000..8514612832f
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/run.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+TESTS="01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23";
+
+source ../common/compat.sh
+
+for i in $TESTS; do
+ perl "test$i.pl" > test$i.log 2> test$i.log2
+done
+for i in $TESTS; do
+ if ! $DIFF -u test$i.log test$i.expected; then
+ echo "test$i failed";
+ exit 1
+ fi
+ if [ -f "test$i.expect2" ]; then
+ lines="`wc -l < test$i.expect2`"
+ head -$lines test$i.log2 > test$i.log2h
+ if ! $DIFF -u test$i.log2h test$i.expect2 && \
+ ! $DIFF -u test$i.log2h test$i.expect2ef; then
+ echo "test$i failed";
+ exit 1
+ fi
+ fi
+done
+echo "OK."
+exit 0
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test01.expected b/plugin/handler_socket/regtest/test_01_lib/test01.expected
new file mode 100644
index 00000000000..37da3242f23
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test01.expected
@@ -0,0 +1,100 @@
+k0 v1020
+k1 v6351
+k10 v70410
+k11 v75111
+k12 v36712
+k13 v40013
+k14 v39714
+k15 v17015
+k16 v71916
+k17 v73417
+k18 v58718
+k19 v49419
+k2 v8032
+k20 v52320
+k21 v95421
+k22 v43322
+k23 v82023
+k24 v28324
+k25 v83725
+k26 v20526
+k27 v41527
+k28 v54528
+k29 v58329
+k3 v9253
+k30 v5230
+k31 v32331
+k32 v61432
+k33 v67933
+k34 v80534
+k35 v45135
+k36 v11536
+k37 v26937
+k38 v21838
+k39 v61739
+k4 v7754
+k40 v87840
+k41 v34541
+k42 v51242
+k43 v96943
+k44 v40844
+k45 v29145
+k46 v85846
+k47 v95347
+k48 v71048
+k49 v14249
+k5 v5375
+k50 v68250
+k51 v93451
+k52 v62152
+k53 v96553
+k54 v57454
+k55 v20455
+k56 v29856
+k57 v13457
+k58 v98358
+k59 v44459
+k6 v5926
+k60 v14460
+k61 v15261
+k62 v18762
+k63 v21563
+k64 v864
+k65 v69765
+k66 v65166
+k67 v28067
+k68 v70168
+k69 v53769
+k7 v4147
+k70 v41370
+k71 v6971
+k72 v8672
+k73 v82273
+k74 v67074
+k75 v37075
+k76 v80676
+k77 v68877
+k78 v2678
+k79 v6679
+k8 v5908
+k80 v80280
+k81 v17181
+k82 v55782
+k83 v84783
+k84 v77784
+k85 v73085
+k86 v98786
+k87 v11587
+k88 v64688
+k89 v49689
+k9 v3029
+k90 v12090
+k91 v68491
+k92 v37492
+k93 v6593
+k94 v37094
+k95 v17495
+k96 v82896
+k97 v86797
+k98 v75998
+k99 v70399
diff --git a/plugin/handler_socket/regtest/test_01_lib/test01.pl b/plugin/handler_socket/regtest/test_01_lib/test01.pl
new file mode 100644
index 00000000000..d3a072fb3cc
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test01.pl
@@ -0,0 +1,38 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for libmysql
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 100;
+$dbh->do(
+ "create table $table (k varchar(30) primary key, v varchar(30) not null) " .
+ "engine = innodb");
+srand(999);
+
+my %valmap = ();
+
+my $sth = $dbh->prepare("insert into $table values (?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "k" . $i;
+ my $v = "v" . int(rand(1000)) . $i;
+ $sth->execute($k, $v);
+ $valmap{$k} = $v;
+}
+
+my $aref = $dbh->selectall_arrayref("select k,v from $table order by k");
+for my $row (@$aref) {
+ my ($k, $v) = @$row;
+ print "$k $v\n";
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test02.expected b/plugin/handler_socket/regtest/test_01_lib/test02.expected
new file mode 100644
index 00000000000..37da3242f23
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test02.expected
@@ -0,0 +1,100 @@
+k0 v1020
+k1 v6351
+k10 v70410
+k11 v75111
+k12 v36712
+k13 v40013
+k14 v39714
+k15 v17015
+k16 v71916
+k17 v73417
+k18 v58718
+k19 v49419
+k2 v8032
+k20 v52320
+k21 v95421
+k22 v43322
+k23 v82023
+k24 v28324
+k25 v83725
+k26 v20526
+k27 v41527
+k28 v54528
+k29 v58329
+k3 v9253
+k30 v5230
+k31 v32331
+k32 v61432
+k33 v67933
+k34 v80534
+k35 v45135
+k36 v11536
+k37 v26937
+k38 v21838
+k39 v61739
+k4 v7754
+k40 v87840
+k41 v34541
+k42 v51242
+k43 v96943
+k44 v40844
+k45 v29145
+k46 v85846
+k47 v95347
+k48 v71048
+k49 v14249
+k5 v5375
+k50 v68250
+k51 v93451
+k52 v62152
+k53 v96553
+k54 v57454
+k55 v20455
+k56 v29856
+k57 v13457
+k58 v98358
+k59 v44459
+k6 v5926
+k60 v14460
+k61 v15261
+k62 v18762
+k63 v21563
+k64 v864
+k65 v69765
+k66 v65166
+k67 v28067
+k68 v70168
+k69 v53769
+k7 v4147
+k70 v41370
+k71 v6971
+k72 v8672
+k73 v82273
+k74 v67074
+k75 v37075
+k76 v80676
+k77 v68877
+k78 v2678
+k79 v6679
+k8 v5908
+k80 v80280
+k81 v17181
+k82 v55782
+k83 v84783
+k84 v77784
+k85 v73085
+k86 v98786
+k87 v11587
+k88 v64688
+k89 v49689
+k9 v3029
+k90 v12090
+k91 v68491
+k92 v37492
+k93 v6593
+k94 v37094
+k95 v17495
+k96 v82896
+k97 v86797
+k98 v75998
+k99 v70399
diff --git a/plugin/handler_socket/regtest/test_01_lib/test02.pl b/plugin/handler_socket/regtest/test_01_lib/test02.pl
new file mode 100644
index 00000000000..c69515d76e9
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test02.pl
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for '>='
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 100;
+$dbh->do(
+ "create table $table (k varchar(30) primary key, v varchar(30) not null) " .
+ "engine = innodb");
+srand(999);
+
+my %valmap = ();
+
+my $sth = $dbh->prepare("insert into $table values (?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "k" . $i;
+ my $v = "v" . int(rand(1000)) . $i;
+ $sth->execute($k, $v);
+ $valmap{$k} = $v;
+}
+
+my $hs = hstest::get_hs_connection();
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v');
+my $r = $hs->execute_single(1, '>=', [ '' ], 10000, 0);
+shift(@$r);
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = $r->[$i * 2];
+ my $v = $r->[$i * 2 + 1];
+ print "$k $v\n";
+}
+
+my $aref = $dbh->selectall_arrayref("select k,v from $table order by k");
+for my $row (@$aref) {
+ my ($k, $v) = @$row;
+ #print "$k $v\n";
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test03.expected b/plugin/handler_socket/regtest/test_01_lib/test03.expected
new file mode 100644
index 00000000000..87b90cd0b86
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test03.expected
@@ -0,0 +1,771 @@
+WR
+0 0
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+7 7
+8 8
+9 9
+10 10
+11 11
+12 12
+13 13
+14 14
+15 15
+16 16
+17 17
+18 18
+19 19
+20 20
+21 21
+22 22
+23 23
+24 24
+25 25
+26 26
+27 27
+28 28
+29 29
+30 30
+31 31
+32 32
+33 33
+34 34
+35 35
+36 36
+37 37
+38 38
+39 39
+40 40
+41 41
+42 42
+43 43
+44 44
+45 45
+46 46
+47 47
+48 48
+49 49
+50 50
+51 51
+52 52
+53 53
+54 54
+55 55
+56 56
+57 57
+58 58
+59 59
+60 60
+61 61
+62 62
+63 63
+64 64
+65 65
+66 66
+67 67
+68 68
+69 69
+70 70
+71 71
+72 72
+73 73
+74 74
+75 75
+76 76
+77 77
+78 78
+79 79
+80 80
+81 81
+82 82
+83 83
+84 84
+85 85
+86 86
+87 87
+88 88
+89 89
+90 90
+91 91
+92 92
+93 93
+94 94
+95 95
+96 96
+97 97
+98 98
+99 99
+100 100
+101 101
+102 102
+103 103
+104 104
+105 105
+106 106
+107 107
+108 108
+109 109
+110 110
+111 111
+112 112
+113 113
+114 114
+115 115
+116 116
+117 117
+118 118
+119 119
+120 120
+121 121
+122 122
+123 123
+124 124
+125 125
+126 126
+127 127
+128 128
+129 129
+130 130
+131 131
+132 132
+133 133
+134 134
+135 135
+136 136
+137 137
+138 138
+139 139
+140 140
+141 141
+142 142
+143 143
+144 144
+145 145
+146 146
+147 147
+148 148
+149 149
+150 150
+151 151
+152 152
+153 153
+154 154
+155 155
+156 156
+157 157
+158 158
+159 159
+160 160
+161 161
+162 162
+163 163
+164 164
+165 165
+166 166
+167 167
+168 168
+169 169
+170 170
+171 171
+172 172
+173 173
+174 174
+175 175
+176 176
+177 177
+178 178
+179 179
+180 180
+181 181
+182 182
+183 183
+184 184
+185 185
+186 186
+187 187
+188 188
+189 189
+190 190
+191 191
+192 192
+193 193
+194 194
+195 195
+196 196
+197 197
+198 198
+199 199
+200 200
+201 201
+202 202
+203 203
+204 204
+205 205
+206 206
+207 207
+208 208
+209 209
+210 210
+211 211
+212 212
+213 213
+214 214
+215 215
+216 216
+217 217
+218 218
+219 219
+220 220
+221 221
+222 222
+223 223
+224 224
+225 225
+226 226
+227 227
+228 228
+229 229
+230 230
+231 231
+232 232
+233 233
+234 234
+235 235
+236 236
+237 237
+238 238
+239 239
+240 240
+241 241
+242 242
+243 243
+244 244
+245 245
+246 246
+247 247
+248 248
+249 249
+250 250
+251 251
+252 252
+253 253
+254 254
+255 255
+HS
+0 0
+1 1
+10 10
+100 100
+101 101
+102 102
+103 103
+104 104
+105 105
+106 106
+107 107
+108 108
+109 109
+11 11
+110 110
+111 111
+112 112
+113 113
+114 114
+115 115
+116 116
+117 117
+118 118
+119 119
+12 12
+120 120
+121 121
+122 122
+123 123
+124 124
+125 125
+126 126
+127 127
+128 128
+129 129
+13 13
+130 130
+131 131
+132 132
+133 133
+134 134
+135 135
+136 136
+137 137
+138 138
+139 139
+14 14
+140 140
+141 141
+142 142
+143 143
+144 144
+145 145
+146 146
+147 147
+148 148
+149 149
+15 15
+150 150
+151 151
+152 152
+153 153
+154 154
+155 155
+156 156
+157 157
+158 158
+159 159
+16 16
+160 160
+161 161
+162 162
+163 163
+164 164
+165 165
+166 166
+167 167
+168 168
+169 169
+17 17
+170 170
+171 171
+172 172
+173 173
+174 174
+175 175
+176 176
+177 177
+178 178
+179 179
+18 18
+180 180
+181 181
+182 182
+183 183
+184 184
+185 185
+186 186
+187 187
+188 188
+189 189
+19 19
+190 190
+191 191
+192 192
+193 193
+194 194
+195 195
+196 196
+197 197
+198 198
+199 199
+2 2
+20 20
+200 200
+201 201
+202 202
+203 203
+204 204
+205 205
+206 206
+207 207
+208 208
+209 209
+21 21
+210 210
+211 211
+212 212
+213 213
+214 214
+215 215
+216 216
+217 217
+218 218
+219 219
+22 22
+220 220
+221 221
+222 222
+223 223
+224 224
+225 225
+226 226
+227 227
+228 228
+229 229
+23 23
+230 230
+231 231
+232 232
+233 233
+234 234
+235 235
+236 236
+237 237
+238 238
+239 239
+24 24
+240 240
+241 241
+242 242
+243 243
+244 244
+245 245
+246 246
+247 247
+248 248
+249 249
+25 25
+250 250
+251 251
+252 252
+253 253
+254 254
+255 255
+26 26
+27 27
+28 28
+29 29
+3 3
+30 30
+31 31
+32 32
+33 33
+34 34
+35 35
+36 36
+37 37
+38 38
+39 39
+4 4
+40 40
+41 41
+42 42
+43 43
+44 44
+45 45
+46 46
+47 47
+48 48
+49 49
+5 5
+50 50
+51 51
+52 52
+53 53
+54 54
+55 55
+56 56
+57 57
+58 58
+59 59
+6 6
+60 60
+61 61
+62 62
+63 63
+64 64
+65 65
+66 66
+67 67
+68 68
+69 69
+7 7
+70 70
+71 71
+72 72
+73 73
+74 74
+75 75
+76 76
+77 77
+78 78
+79 79
+8 8
+80 80
+81 81
+82 82
+83 83
+84 84
+85 85
+86 86
+87 87
+88 88
+89 89
+9 9
+90 90
+91 91
+92 92
+93 93
+94 94
+95 95
+96 96
+97 97
+98 98
+99 99
+MY
+0 0
+1 1
+10 10
+100 100
+101 101
+102 102
+103 103
+104 104
+105 105
+106 106
+107 107
+108 108
+109 109
+11 11
+110 110
+111 111
+112 112
+113 113
+114 114
+115 115
+116 116
+117 117
+118 118
+119 119
+12 12
+120 120
+121 121
+122 122
+123 123
+124 124
+125 125
+126 126
+127 127
+128 128
+129 129
+13 13
+130 130
+131 131
+132 132
+133 133
+134 134
+135 135
+136 136
+137 137
+138 138
+139 139
+14 14
+140 140
+141 141
+142 142
+143 143
+144 144
+145 145
+146 146
+147 147
+148 148
+149 149
+15 15
+150 150
+151 151
+152 152
+153 153
+154 154
+155 155
+156 156
+157 157
+158 158
+159 159
+16 16
+160 160
+161 161
+162 162
+163 163
+164 164
+165 165
+166 166
+167 167
+168 168
+169 169
+17 17
+170 170
+171 171
+172 172
+173 173
+174 174
+175 175
+176 176
+177 177
+178 178
+179 179
+18 18
+180 180
+181 181
+182 182
+183 183
+184 184
+185 185
+186 186
+187 187
+188 188
+189 189
+19 19
+190 190
+191 191
+192 192
+193 193
+194 194
+195 195
+196 196
+197 197
+198 198
+199 199
+2 2
+20 20
+200 200
+201 201
+202 202
+203 203
+204 204
+205 205
+206 206
+207 207
+208 208
+209 209
+21 21
+210 210
+211 211
+212 212
+213 213
+214 214
+215 215
+216 216
+217 217
+218 218
+219 219
+22 22
+220 220
+221 221
+222 222
+223 223
+224 224
+225 225
+226 226
+227 227
+228 228
+229 229
+23 23
+230 230
+231 231
+232 232
+233 233
+234 234
+235 235
+236 236
+237 237
+238 238
+239 239
+24 24
+240 240
+241 241
+242 242
+243 243
+244 244
+245 245
+246 246
+247 247
+248 248
+249 249
+25 25
+250 250
+251 251
+252 252
+253 253
+254 254
+255 255
+26 26
+27 27
+28 28
+29 29
+3 3
+30 30
+31 31
+32 32
+33 33
+34 34
+35 35
+36 36
+37 37
+38 38
+39 39
+4 4
+40 40
+41 41
+42 42
+43 43
+44 44
+45 45
+46 46
+47 47
+48 48
+49 49
+5 5
+50 50
+51 51
+52 52
+53 53
+54 54
+55 55
+56 56
+57 57
+58 58
+59 59
+6 6
+60 60
+61 61
+62 62
+63 63
+64 64
+65 65
+66 66
+67 67
+68 68
+69 69
+7 7
+70 70
+71 71
+72 72
+73 73
+74 74
+75 75
+76 76
+77 77
+78 78
+79 79
+8 8
+80 80
+81 81
+82 82
+83 83
+84 84
+85 85
+86 86
+87 87
+88 88
+89 89
+9 9
+90 90
+91 91
+92 92
+93 93
+94 94
+95 95
+96 96
+97 97
+98 98
+99 99
diff --git a/plugin/handler_socket/regtest/test_01_lib/test03.pl b/plugin/handler_socket/regtest/test_01_lib/test03.pl
new file mode 100644
index 00000000000..a081786c132
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test03.pl
@@ -0,0 +1,61 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for binary cleanness (#1)
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 256;
+$dbh->do(
+ "create table $table (k varchar(30) primary key, v varchar(30) not null) " .
+ "engine = innodb default charset = binary");
+srand(999);
+
+my %valmap = ();
+
+print "WR\n";
+my $sth = $dbh->prepare("insert into $table values (?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "" . $i;
+ my $v = pack("C", $i);
+ my $vnum = unpack("C", $v);
+ print "$k $vnum\n";
+ $sth->execute($k, $v);
+ $valmap{$k} = $v;
+}
+
+my $hs = hstest::get_hs_connection();
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v');
+my $r = $hs->execute_single(1, '>=', [ '' ], 10000, 0);
+shift(@$r);
+print "HS\n";
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = $r->[$i * 2];
+ my $v = $r->[$i * 2 + 1];
+ my $vnum = unpack("C", $v);
+ print "$k $vnum\n";
+ print "MISMATCH\n" if ($k ne $vnum);
+ print "LEN\n" if (length($v) != 1);
+}
+undef $hs;
+
+print "MY\n";
+my $aref = $dbh->selectall_arrayref("select k,v from $table order by k");
+for my $row (@$aref) {
+ my ($k, $v) = @$row;
+ my $vnum = unpack("C", $v);
+ print "$k $vnum\n";
+ print "MISMATCH\n" if ($k ne $vnum);
+ print "LEN\n" if (length($v) != 1);
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test04.expected b/plugin/handler_socket/regtest/test_01_lib/test04.expected
new file mode 100644
index 00000000000..ceeac4387b7
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test04.expected
Binary files differ
diff --git a/plugin/handler_socket/regtest/test_01_lib/test04.pl b/plugin/handler_socket/regtest/test_01_lib/test04.pl
new file mode 100644
index 00000000000..52fe11364c8
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test04.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for binary cleanness (#2)
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 256;
+$dbh->do(
+ "create table $table (k varchar(30) primary key, v varchar(30) not null) " .
+ "engine = innodb default charset = binary");
+srand(999);
+
+my %valmap = ();
+
+print "WR\n";
+my $sth = $dbh->prepare("insert into $table values (?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "" . $i;
+ my $v = pack("C", $i);
+ my $vnum = unpack("C", $v);
+ print "$k $vnum\n";
+ $sth->execute($k, "a" . $v . "a");
+ $valmap{$k} = $v;
+}
+
+my $hs = hstest::get_hs_connection();
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v');
+my $r = $hs->execute_single(1, '>=', [ '' ], 10000, 0);
+shift(@$r);
+print "HS\n";
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = $r->[$i * 2];
+ my $v = $r->[$i * 2 + 1];
+ my $len = length($v);
+ my $vnum = unpack("C", substr($v, 1, 1));
+ print "$k $vnum $len [$v]\n";
+ print "MISMATCH\n" if ($k ne $vnum);
+ print "LEN\n" if $len != 3;
+}
+undef $hs;
+
+print "MY\n";
+my $aref = $dbh->selectall_arrayref("select k,v from $table order by k");
+for my $row (@$aref) {
+ my ($k, $v) = @$row;
+ my $len = length($v);
+ my $vnum = unpack("C", substr($v, 1, 1));
+ print "$k $vnum $len [$v]\n";
+ print "MISMATCH\n" if ($k ne $vnum);
+ print "LEN\n" if $len != 3;
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test05.expected b/plugin/handler_socket/regtest/test_01_lib/test05.expected
new file mode 100644
index 00000000000..6a86a446e66
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test05.expected
@@ -0,0 +1,771 @@
+WR
+0 [null]
+1 1
+2 [null]
+3 3
+4 [null]
+5 5
+6 [null]
+7 7
+8 [null]
+9 9
+10 [null]
+11 11
+12 [null]
+13 13
+14 [null]
+15 15
+16 [null]
+17 17
+18 [null]
+19 19
+20 [null]
+21 21
+22 [null]
+23 23
+24 [null]
+25 25
+26 [null]
+27 27
+28 [null]
+29 29
+30 [null]
+31 31
+32 [null]
+33 33
+34 [null]
+35 35
+36 [null]
+37 37
+38 [null]
+39 39
+40 [null]
+41 41
+42 [null]
+43 43
+44 [null]
+45 45
+46 [null]
+47 47
+48 [null]
+49 49
+50 [null]
+51 51
+52 [null]
+53 53
+54 [null]
+55 55
+56 [null]
+57 57
+58 [null]
+59 59
+60 [null]
+61 61
+62 [null]
+63 63
+64 [null]
+65 65
+66 [null]
+67 67
+68 [null]
+69 69
+70 [null]
+71 71
+72 [null]
+73 73
+74 [null]
+75 75
+76 [null]
+77 77
+78 [null]
+79 79
+80 [null]
+81 81
+82 [null]
+83 83
+84 [null]
+85 85
+86 [null]
+87 87
+88 [null]
+89 89
+90 [null]
+91 91
+92 [null]
+93 93
+94 [null]
+95 95
+96 [null]
+97 97
+98 [null]
+99 99
+100 [null]
+101 101
+102 [null]
+103 103
+104 [null]
+105 105
+106 [null]
+107 107
+108 [null]
+109 109
+110 [null]
+111 111
+112 [null]
+113 113
+114 [null]
+115 115
+116 [null]
+117 117
+118 [null]
+119 119
+120 [null]
+121 121
+122 [null]
+123 123
+124 [null]
+125 125
+126 [null]
+127 127
+128 [null]
+129 129
+130 [null]
+131 131
+132 [null]
+133 133
+134 [null]
+135 135
+136 [null]
+137 137
+138 [null]
+139 139
+140 [null]
+141 141
+142 [null]
+143 143
+144 [null]
+145 145
+146 [null]
+147 147
+148 [null]
+149 149
+150 [null]
+151 151
+152 [null]
+153 153
+154 [null]
+155 155
+156 [null]
+157 157
+158 [null]
+159 159
+160 [null]
+161 161
+162 [null]
+163 163
+164 [null]
+165 165
+166 [null]
+167 167
+168 [null]
+169 169
+170 [null]
+171 171
+172 [null]
+173 173
+174 [null]
+175 175
+176 [null]
+177 177
+178 [null]
+179 179
+180 [null]
+181 181
+182 [null]
+183 183
+184 [null]
+185 185
+186 [null]
+187 187
+188 [null]
+189 189
+190 [null]
+191 191
+192 [null]
+193 193
+194 [null]
+195 195
+196 [null]
+197 197
+198 [null]
+199 199
+200 [null]
+201 201
+202 [null]
+203 203
+204 [null]
+205 205
+206 [null]
+207 207
+208 [null]
+209 209
+210 [null]
+211 211
+212 [null]
+213 213
+214 [null]
+215 215
+216 [null]
+217 217
+218 [null]
+219 219
+220 [null]
+221 221
+222 [null]
+223 223
+224 [null]
+225 225
+226 [null]
+227 227
+228 [null]
+229 229
+230 [null]
+231 231
+232 [null]
+233 233
+234 [null]
+235 235
+236 [null]
+237 237
+238 [null]
+239 239
+240 [null]
+241 241
+242 [null]
+243 243
+244 [null]
+245 245
+246 [null]
+247 247
+248 [null]
+249 249
+250 [null]
+251 251
+252 [null]
+253 253
+254 [null]
+255 255
+HS
+0 [null]
+1 1
+10 [null]
+100 [null]
+101 101
+102 [null]
+103 103
+104 [null]
+105 105
+106 [null]
+107 107
+108 [null]
+109 109
+11 11
+110 [null]
+111 111
+112 [null]
+113 113
+114 [null]
+115 115
+116 [null]
+117 117
+118 [null]
+119 119
+12 [null]
+120 [null]
+121 121
+122 [null]
+123 123
+124 [null]
+125 125
+126 [null]
+127 127
+128 [null]
+129 129
+13 13
+130 [null]
+131 131
+132 [null]
+133 133
+134 [null]
+135 135
+136 [null]
+137 137
+138 [null]
+139 139
+14 [null]
+140 [null]
+141 141
+142 [null]
+143 143
+144 [null]
+145 145
+146 [null]
+147 147
+148 [null]
+149 149
+15 15
+150 [null]
+151 151
+152 [null]
+153 153
+154 [null]
+155 155
+156 [null]
+157 157
+158 [null]
+159 159
+16 [null]
+160 [null]
+161 161
+162 [null]
+163 163
+164 [null]
+165 165
+166 [null]
+167 167
+168 [null]
+169 169
+17 17
+170 [null]
+171 171
+172 [null]
+173 173
+174 [null]
+175 175
+176 [null]
+177 177
+178 [null]
+179 179
+18 [null]
+180 [null]
+181 181
+182 [null]
+183 183
+184 [null]
+185 185
+186 [null]
+187 187
+188 [null]
+189 189
+19 19
+190 [null]
+191 191
+192 [null]
+193 193
+194 [null]
+195 195
+196 [null]
+197 197
+198 [null]
+199 199
+2 [null]
+20 [null]
+200 [null]
+201 201
+202 [null]
+203 203
+204 [null]
+205 205
+206 [null]
+207 207
+208 [null]
+209 209
+21 21
+210 [null]
+211 211
+212 [null]
+213 213
+214 [null]
+215 215
+216 [null]
+217 217
+218 [null]
+219 219
+22 [null]
+220 [null]
+221 221
+222 [null]
+223 223
+224 [null]
+225 225
+226 [null]
+227 227
+228 [null]
+229 229
+23 23
+230 [null]
+231 231
+232 [null]
+233 233
+234 [null]
+235 235
+236 [null]
+237 237
+238 [null]
+239 239
+24 [null]
+240 [null]
+241 241
+242 [null]
+243 243
+244 [null]
+245 245
+246 [null]
+247 247
+248 [null]
+249 249
+25 25
+250 [null]
+251 251
+252 [null]
+253 253
+254 [null]
+255 255
+26 [null]
+27 27
+28 [null]
+29 29
+3 3
+30 [null]
+31 31
+32 [null]
+33 33
+34 [null]
+35 35
+36 [null]
+37 37
+38 [null]
+39 39
+4 [null]
+40 [null]
+41 41
+42 [null]
+43 43
+44 [null]
+45 45
+46 [null]
+47 47
+48 [null]
+49 49
+5 5
+50 [null]
+51 51
+52 [null]
+53 53
+54 [null]
+55 55
+56 [null]
+57 57
+58 [null]
+59 59
+6 [null]
+60 [null]
+61 61
+62 [null]
+63 63
+64 [null]
+65 65
+66 [null]
+67 67
+68 [null]
+69 69
+7 7
+70 [null]
+71 71
+72 [null]
+73 73
+74 [null]
+75 75
+76 [null]
+77 77
+78 [null]
+79 79
+8 [null]
+80 [null]
+81 81
+82 [null]
+83 83
+84 [null]
+85 85
+86 [null]
+87 87
+88 [null]
+89 89
+9 9
+90 [null]
+91 91
+92 [null]
+93 93
+94 [null]
+95 95
+96 [null]
+97 97
+98 [null]
+99 99
+MY
+0 [null]
+1 1
+10 [null]
+100 [null]
+101 101
+102 [null]
+103 103
+104 [null]
+105 105
+106 [null]
+107 107
+108 [null]
+109 109
+11 11
+110 [null]
+111 111
+112 [null]
+113 113
+114 [null]
+115 115
+116 [null]
+117 117
+118 [null]
+119 119
+12 [null]
+120 [null]
+121 121
+122 [null]
+123 123
+124 [null]
+125 125
+126 [null]
+127 127
+128 [null]
+129 129
+13 13
+130 [null]
+131 131
+132 [null]
+133 133
+134 [null]
+135 135
+136 [null]
+137 137
+138 [null]
+139 139
+14 [null]
+140 [null]
+141 141
+142 [null]
+143 143
+144 [null]
+145 145
+146 [null]
+147 147
+148 [null]
+149 149
+15 15
+150 [null]
+151 151
+152 [null]
+153 153
+154 [null]
+155 155
+156 [null]
+157 157
+158 [null]
+159 159
+16 [null]
+160 [null]
+161 161
+162 [null]
+163 163
+164 [null]
+165 165
+166 [null]
+167 167
+168 [null]
+169 169
+17 17
+170 [null]
+171 171
+172 [null]
+173 173
+174 [null]
+175 175
+176 [null]
+177 177
+178 [null]
+179 179
+18 [null]
+180 [null]
+181 181
+182 [null]
+183 183
+184 [null]
+185 185
+186 [null]
+187 187
+188 [null]
+189 189
+19 19
+190 [null]
+191 191
+192 [null]
+193 193
+194 [null]
+195 195
+196 [null]
+197 197
+198 [null]
+199 199
+2 [null]
+20 [null]
+200 [null]
+201 201
+202 [null]
+203 203
+204 [null]
+205 205
+206 [null]
+207 207
+208 [null]
+209 209
+21 21
+210 [null]
+211 211
+212 [null]
+213 213
+214 [null]
+215 215
+216 [null]
+217 217
+218 [null]
+219 219
+22 [null]
+220 [null]
+221 221
+222 [null]
+223 223
+224 [null]
+225 225
+226 [null]
+227 227
+228 [null]
+229 229
+23 23
+230 [null]
+231 231
+232 [null]
+233 233
+234 [null]
+235 235
+236 [null]
+237 237
+238 [null]
+239 239
+24 [null]
+240 [null]
+241 241
+242 [null]
+243 243
+244 [null]
+245 245
+246 [null]
+247 247
+248 [null]
+249 249
+25 25
+250 [null]
+251 251
+252 [null]
+253 253
+254 [null]
+255 255
+26 [null]
+27 27
+28 [null]
+29 29
+3 3
+30 [null]
+31 31
+32 [null]
+33 33
+34 [null]
+35 35
+36 [null]
+37 37
+38 [null]
+39 39
+4 [null]
+40 [null]
+41 41
+42 [null]
+43 43
+44 [null]
+45 45
+46 [null]
+47 47
+48 [null]
+49 49
+5 5
+50 [null]
+51 51
+52 [null]
+53 53
+54 [null]
+55 55
+56 [null]
+57 57
+58 [null]
+59 59
+6 [null]
+60 [null]
+61 61
+62 [null]
+63 63
+64 [null]
+65 65
+66 [null]
+67 67
+68 [null]
+69 69
+7 7
+70 [null]
+71 71
+72 [null]
+73 73
+74 [null]
+75 75
+76 [null]
+77 77
+78 [null]
+79 79
+8 [null]
+80 [null]
+81 81
+82 [null]
+83 83
+84 [null]
+85 85
+86 [null]
+87 87
+88 [null]
+89 89
+9 9
+90 [null]
+91 91
+92 [null]
+93 93
+94 [null]
+95 95
+96 [null]
+97 97
+98 [null]
+99 99
diff --git a/plugin/handler_socket/regtest/test_01_lib/test05.pl b/plugin/handler_socket/regtest/test_01_lib/test05.pl
new file mode 100644
index 00000000000..10b1a0805a0
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test05.pl
@@ -0,0 +1,59 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for binary cleanness (#3)
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 256;
+$dbh->do(
+ "create table $table (k varchar(30) primary key, v varchar(30)) " .
+ "engine = innodb default charset = binary");
+srand(999);
+
+my %valmap = ();
+
+print "WR\n";
+my $sth = $dbh->prepare("insert into $table values (?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "" . $i;
+ my $v = ($i % 2 == 1) ? $i : undef;
+ $sth->execute($k, $v);
+ $v = "[null]" if !defined($v);
+ print "$k $v\n";
+ $valmap{$k} = $v;
+}
+
+my $hs = hstest::get_hs_connection();
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v');
+my $r = $hs->execute_single(1, '>=', [ '' ], 10000, 0);
+shift(@$r);
+print "HS\n";
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = $r->[$i * 2];
+ my $v = $r->[$i * 2 + 1];
+ $v = "[null]" if !defined($v);
+ print "$k $v\n";
+ print "MISMATCH\n" if ($valmap{$k} ne $v);
+}
+undef $hs;
+
+print "MY\n";
+my $aref = $dbh->selectall_arrayref("select k,v from $table order by k");
+for my $row (@$aref) {
+ my ($k, $v) = @$row;
+ $v = "[null]" if !defined($v);
+ print "$k $v\n";
+ print "MISMATCH\n" if ($valmap{$k} ne $v);
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test06.expected b/plugin/handler_socket/regtest/test_01_lib/test06.expected
new file mode 100644
index 00000000000..b376c4af0be
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test06.expected
@@ -0,0 +1,644 @@
+HSINSERTDUMP_TABLE
+0 v1_0 v2_0
+1 v1_1 v2_1
+10 v1_10 v2_10
+100 v1_100 v2_100
+101 v1_101 v2_101
+102 v1_102 v2_102
+103 v1_103 v2_103
+104 v1_104 v2_104
+105 v1_105 v2_105
+106 v1_106 v2_106
+107 v1_107 v2_107
+108 v1_108 v2_108
+109 v1_109 v2_109
+11 v1_11 v2_11
+110 v1_110 v2_110
+111 v1_111 v2_111
+112 v1_112 v2_112
+113 v1_113 v2_113
+114 v1_114 v2_114
+115 v1_115 v2_115
+116 v1_116 v2_116
+117 v1_117 v2_117
+118 v1_118 v2_118
+119 v1_119 v2_119
+12 v1_12 v2_12
+120 v1_120 v2_120
+121 v1_121 v2_121
+122 v1_122 v2_122
+123 v1_123 v2_123
+124 v1_124 v2_124
+125 v1_125 v2_125
+126 v1_126 v2_126
+127 v1_127 v2_127
+128 v1_128 v2_128
+129 v1_129 v2_129
+13 v1_13 v2_13
+130 v1_130 v2_130
+131 v1_131 v2_131
+132 v1_132 v2_132
+133 v1_133 v2_133
+134 v1_134 v2_134
+135 v1_135 v2_135
+136 v1_136 v2_136
+137 v1_137 v2_137
+138 v1_138 v2_138
+139 v1_139 v2_139
+14 v1_14 v2_14
+140 v1_140 v2_140
+141 v1_141 v2_141
+142 v1_142 v2_142
+143 v1_143 v2_143
+144 v1_144 v2_144
+145 v1_145 v2_145
+146 v1_146 v2_146
+147 v1_147 v2_147
+148 v1_148 v2_148
+149 v1_149 v2_149
+15 v1_15 v2_15
+150 v1_150 v2_150
+151 v1_151 v2_151
+152 v1_152 v2_152
+153 v1_153 v2_153
+154 v1_154 v2_154
+155 v1_155 v2_155
+156 v1_156 v2_156
+157 v1_157 v2_157
+158 v1_158 v2_158
+159 v1_159 v2_159
+16 v1_16 v2_16
+160 v1_160 v2_160
+161 v1_161 v2_161
+162 v1_162 v2_162
+163 v1_163 v2_163
+164 v1_164 v2_164
+165 v1_165 v2_165
+166 v1_166 v2_166
+167 v1_167 v2_167
+168 v1_168 v2_168
+169 v1_169 v2_169
+17 v1_17 v2_17
+170 v1_170 v2_170
+171 v1_171 v2_171
+172 v1_172 v2_172
+173 v1_173 v2_173
+174 v1_174 v2_174
+175 v1_175 v2_175
+176 v1_176 v2_176
+177 v1_177 v2_177
+178 v1_178 v2_178
+179 v1_179 v2_179
+18 v1_18 v2_18
+180 v1_180 v2_180
+181 v1_181 v2_181
+182 v1_182 v2_182
+183 v1_183 v2_183
+184 v1_184 v2_184
+185 v1_185 v2_185
+186 v1_186 v2_186
+187 v1_187 v2_187
+188 v1_188 v2_188
+189 v1_189 v2_189
+19 v1_19 v2_19
+190 v1_190 v2_190
+191 v1_191 v2_191
+192 v1_192 v2_192
+193 v1_193 v2_193
+194 v1_194 v2_194
+195 v1_195 v2_195
+196 v1_196 v2_196
+197 v1_197 v2_197
+198 v1_198 v2_198
+199 v1_199 v2_199
+2 v1_2 v2_2
+20 v1_20 v2_20
+200 v1_200 v2_200
+201 v1_201 v2_201
+202 v1_202 v2_202
+203 v1_203 v2_203
+204 v1_204 v2_204
+205 v1_205 v2_205
+206 v1_206 v2_206
+207 v1_207 v2_207
+208 v1_208 v2_208
+209 v1_209 v2_209
+21 v1_21 v2_21
+210 v1_210 v2_210
+211 v1_211 v2_211
+212 v1_212 v2_212
+213 v1_213 v2_213
+214 v1_214 v2_214
+215 v1_215 v2_215
+216 v1_216 v2_216
+217 v1_217 v2_217
+218 v1_218 v2_218
+219 v1_219 v2_219
+22 v1_22 v2_22
+220 v1_220 v2_220
+221 v1_221 v2_221
+222 v1_222 v2_222
+223 v1_223 v2_223
+224 v1_224 v2_224
+225 v1_225 v2_225
+226 v1_226 v2_226
+227 v1_227 v2_227
+228 v1_228 v2_228
+229 v1_229 v2_229
+23 v1_23 v2_23
+230 v1_230 v2_230
+231 v1_231 v2_231
+232 v1_232 v2_232
+233 v1_233 v2_233
+234 v1_234 v2_234
+235 v1_235 v2_235
+236 v1_236 v2_236
+237 v1_237 v2_237
+238 v1_238 v2_238
+239 v1_239 v2_239
+24 v1_24 v2_24
+240 v1_240 v2_240
+241 v1_241 v2_241
+242 v1_242 v2_242
+243 v1_243 v2_243
+244 v1_244 v2_244
+245 v1_245 v2_245
+246 v1_246 v2_246
+247 v1_247 v2_247
+248 v1_248 v2_248
+249 v1_249 v2_249
+25 v1_25 v2_25
+250 v1_250 v2_250
+251 v1_251 v2_251
+252 v1_252 v2_252
+253 v1_253 v2_253
+254 v1_254 v2_254
+255 v1_255 v2_255
+26 v1_26 v2_26
+27 v1_27 v2_27
+28 v1_28 v2_28
+29 v1_29 v2_29
+3 v1_3 v2_3
+30 v1_30 v2_30
+31 v1_31 v2_31
+32 v1_32 v2_32
+33 v1_33 v2_33
+34 v1_34 v2_34
+35 v1_35 v2_35
+36 v1_36 v2_36
+37 v1_37 v2_37
+38 v1_38 v2_38
+39 v1_39 v2_39
+4 v1_4 v2_4
+40 v1_40 v2_40
+41 v1_41 v2_41
+42 v1_42 v2_42
+43 v1_43 v2_43
+44 v1_44 v2_44
+45 v1_45 v2_45
+46 v1_46 v2_46
+47 v1_47 v2_47
+48 v1_48 v2_48
+49 v1_49 v2_49
+5 v1_5 v2_5
+50 v1_50 v2_50
+51 v1_51 v2_51
+52 v1_52 v2_52
+53 v1_53 v2_53
+54 v1_54 v2_54
+55 v1_55 v2_55
+56 v1_56 v2_56
+57 v1_57 v2_57
+58 v1_58 v2_58
+59 v1_59 v2_59
+6 v1_6 v2_6
+60 v1_60 v2_60
+61 v1_61 v2_61
+62 v1_62 v2_62
+63 v1_63 v2_63
+64 v1_64 v2_64
+65 v1_65 v2_65
+66 v1_66 v2_66
+67 v1_67 v2_67
+68 v1_68 v2_68
+69 v1_69 v2_69
+7 v1_7 v2_7
+70 v1_70 v2_70
+71 v1_71 v2_71
+72 v1_72 v2_72
+73 v1_73 v2_73
+74 v1_74 v2_74
+75 v1_75 v2_75
+76 v1_76 v2_76
+77 v1_77 v2_77
+78 v1_78 v2_78
+79 v1_79 v2_79
+8 v1_8 v2_8
+80 v1_80 v2_80
+81 v1_81 v2_81
+82 v1_82 v2_82
+83 v1_83 v2_83
+84 v1_84 v2_84
+85 v1_85 v2_85
+86 v1_86 v2_86
+87 v1_87 v2_87
+88 v1_88 v2_88
+89 v1_89 v2_89
+9 v1_9 v2_9
+90 v1_90 v2_90
+91 v1_91 v2_91
+92 v1_92 v2_92
+93 v1_93 v2_93
+94 v1_94 v2_94
+95 v1_95 v2_95
+96 v1_96 v2_96
+97 v1_97 v2_97
+98 v1_98 v2_98
+99 v1_99 v2_99
+HSUPDATEDUMP_TABLE
+0 mod_0 v2_0
+1 mod_1 v2_1
+10 mod_10 v2_10
+100 mod_100 v2_100
+101 mod_101 v2_101
+102 mod_102 v2_102
+103 mod_103 v2_103
+104 mod_104 v2_104
+105 mod_105 v2_105
+106 mod_106 v2_106
+107 mod_107 v2_107
+108 mod_108 v2_108
+109 mod_109 v2_109
+11 mod_11 v2_11
+110 mod_110 v2_110
+111 mod_111 v2_111
+112 mod_112 v2_112
+113 mod_113 v2_113
+114 mod_114 v2_114
+115 mod_115 v2_115
+116 mod_116 v2_116
+117 mod_117 v2_117
+118 mod_118 v2_118
+119 mod_119 v2_119
+12 mod_12 v2_12
+120 mod_120 v2_120
+121 mod_121 v2_121
+122 mod_122 v2_122
+123 mod_123 v2_123
+124 mod_124 v2_124
+125 mod_125 v2_125
+126 mod_126 v2_126
+127 mod_127 v2_127
+128 mod_128 v2_128
+129 mod_129 v2_129
+13 mod_13 v2_13
+130 mod_130 v2_130
+131 mod_131 v2_131
+132 mod_132 v2_132
+133 mod_133 v2_133
+134 mod_134 v2_134
+135 mod_135 v2_135
+136 mod_136 v2_136
+137 mod_137 v2_137
+138 mod_138 v2_138
+139 mod_139 v2_139
+14 mod_14 v2_14
+140 mod_140 v2_140
+141 mod_141 v2_141
+142 mod_142 v2_142
+143 mod_143 v2_143
+144 mod_144 v2_144
+145 mod_145 v2_145
+146 mod_146 v2_146
+147 mod_147 v2_147
+148 mod_148 v2_148
+149 mod_149 v2_149
+15 mod_15 v2_15
+150 mod_150 v2_150
+151 mod_151 v2_151
+152 mod_152 v2_152
+153 mod_153 v2_153
+154 mod_154 v2_154
+155 mod_155 v2_155
+156 mod_156 v2_156
+157 mod_157 v2_157
+158 mod_158 v2_158
+159 mod_159 v2_159
+16 mod_16 v2_16
+160 mod_160 v2_160
+161 mod_161 v2_161
+162 mod_162 v2_162
+163 mod_163 v2_163
+164 mod_164 v2_164
+165 mod_165 v2_165
+166 mod_166 v2_166
+167 mod_167 v2_167
+168 mod_168 v2_168
+169 mod_169 v2_169
+17 mod_17 v2_17
+170 mod_170 v2_170
+171 mod_171 v2_171
+172 mod_172 v2_172
+173 mod_173 v2_173
+174 mod_174 v2_174
+175 mod_175 v2_175
+176 mod_176 v2_176
+177 mod_177 v2_177
+178 mod_178 v2_178
+179 mod_179 v2_179
+18 mod_18 v2_18
+180 mod_180 v2_180
+181 mod_181 v2_181
+182 mod_182 v2_182
+183 mod_183 v2_183
+184 mod_184 v2_184
+185 mod_185 v2_185
+186 mod_186 v2_186
+187 mod_187 v2_187
+188 mod_188 v2_188
+189 mod_189 v2_189
+19 mod_19 v2_19
+190 mod_190 v2_190
+191 mod_191 v2_191
+192 mod_192 v2_192
+193 mod_193 v2_193
+194 mod_194 v2_194
+195 mod_195 v2_195
+196 mod_196 v2_196
+197 mod_197 v2_197
+198 mod_198 v2_198
+199 mod_199 v2_199
+2 mod_2 v2_2
+20 mod_20 v2_20
+200 mod_200 v2_200
+201 mod_201 v2_201
+202 mod_202 v2_202
+203 mod_203 v2_203
+204 mod_204 v2_204
+205 mod_205 v2_205
+206 mod_206 v2_206
+207 mod_207 v2_207
+208 mod_208 v2_208
+209 mod_209 v2_209
+21 mod_21 v2_21
+210 mod_210 v2_210
+211 mod_211 v2_211
+212 mod_212 v2_212
+213 mod_213 v2_213
+214 mod_214 v2_214
+215 mod_215 v2_215
+216 mod_216 v2_216
+217 mod_217 v2_217
+218 mod_218 v2_218
+219 mod_219 v2_219
+22 mod_22 v2_22
+220 mod_220 v2_220
+221 mod_221 v2_221
+222 mod_222 v2_222
+223 mod_223 v2_223
+224 mod_224 v2_224
+225 mod_225 v2_225
+226 mod_226 v2_226
+227 mod_227 v2_227
+228 mod_228 v2_228
+229 mod_229 v2_229
+23 mod_23 v2_23
+230 mod_230 v2_230
+231 mod_231 v2_231
+232 mod_232 v2_232
+233 mod_233 v2_233
+234 mod_234 v2_234
+235 mod_235 v2_235
+236 mod_236 v2_236
+237 mod_237 v2_237
+238 mod_238 v2_238
+239 mod_239 v2_239
+24 mod_24 v2_24
+240 mod_240 v2_240
+241 mod_241 v2_241
+242 mod_242 v2_242
+243 mod_243 v2_243
+244 mod_244 v2_244
+245 mod_245 v2_245
+246 mod_246 v2_246
+247 mod_247 v2_247
+248 mod_248 v2_248
+249 mod_249 v2_249
+25 mod_25 v2_25
+250 mod_250 v2_250
+251 mod_251 v2_251
+252 mod_252 v2_252
+253 mod_253 v2_253
+254 mod_254 v2_254
+255 mod_255 v2_255
+26 mod_26 v2_26
+27 mod_27 v2_27
+28 mod_28 v2_28
+29 mod_29 v2_29
+3 mod_3 v2_3
+30 mod_30 v2_30
+31 mod_31 v2_31
+32 mod_32 v2_32
+33 mod_33 v2_33
+34 mod_34 v2_34
+35 mod_35 v2_35
+36 mod_36 v2_36
+37 mod_37 v2_37
+38 mod_38 v2_38
+39 mod_39 v2_39
+4 mod_4 v2_4
+40 mod_40 v2_40
+41 mod_41 v2_41
+42 mod_42 v2_42
+43 mod_43 v2_43
+44 mod_44 v2_44
+45 mod_45 v2_45
+46 mod_46 v2_46
+47 mod_47 v2_47
+48 mod_48 v2_48
+49 mod_49 v2_49
+5 mod_5 v2_5
+50 mod_50 v2_50
+51 mod_51 v2_51
+52 mod_52 v2_52
+53 mod_53 v2_53
+54 mod_54 v2_54
+55 mod_55 v2_55
+56 mod_56 v2_56
+57 mod_57 v2_57
+58 mod_58 v2_58
+59 mod_59 v2_59
+6 mod_6 v2_6
+60 mod_60 v2_60
+61 mod_61 v2_61
+62 mod_62 v2_62
+63 mod_63 v2_63
+64 mod_64 v2_64
+65 mod_65 v2_65
+66 mod_66 v2_66
+67 mod_67 v2_67
+68 mod_68 v2_68
+69 mod_69 v2_69
+7 mod_7 v2_7
+70 mod_70 v2_70
+71 mod_71 v2_71
+72 mod_72 v2_72
+73 mod_73 v2_73
+74 mod_74 v2_74
+75 mod_75 v2_75
+76 mod_76 v2_76
+77 mod_77 v2_77
+78 mod_78 v2_78
+79 mod_79 v2_79
+8 mod_8 v2_8
+80 mod_80 v2_80
+81 mod_81 v2_81
+82 mod_82 v2_82
+83 mod_83 v2_83
+84 mod_84 v2_84
+85 mod_85 v2_85
+86 mod_86 v2_86
+87 mod_87 v2_87
+88 mod_88 v2_88
+89 mod_89 v2_89
+9 mod_9 v2_9
+90 mod_90 v2_90
+91 mod_91 v2_91
+92 mod_92 v2_92
+93 mod_93 v2_93
+94 mod_94 v2_94
+95 mod_95 v2_95
+96 mod_96 v2_96
+97 mod_97 v2_97
+98 mod_98 v2_98
+99 mod_99 v2_99
+HSDELETE
+DUMP_TABLE
+1 mod_1 v2_1
+101 mod_101 v2_101
+103 mod_103 v2_103
+105 mod_105 v2_105
+107 mod_107 v2_107
+109 mod_109 v2_109
+11 mod_11 v2_11
+111 mod_111 v2_111
+113 mod_113 v2_113
+115 mod_115 v2_115
+117 mod_117 v2_117
+119 mod_119 v2_119
+121 mod_121 v2_121
+123 mod_123 v2_123
+125 mod_125 v2_125
+127 mod_127 v2_127
+129 mod_129 v2_129
+13 mod_13 v2_13
+131 mod_131 v2_131
+133 mod_133 v2_133
+135 mod_135 v2_135
+137 mod_137 v2_137
+139 mod_139 v2_139
+141 mod_141 v2_141
+143 mod_143 v2_143
+145 mod_145 v2_145
+147 mod_147 v2_147
+149 mod_149 v2_149
+15 mod_15 v2_15
+151 mod_151 v2_151
+153 mod_153 v2_153
+155 mod_155 v2_155
+157 mod_157 v2_157
+159 mod_159 v2_159
+161 mod_161 v2_161
+163 mod_163 v2_163
+165 mod_165 v2_165
+167 mod_167 v2_167
+169 mod_169 v2_169
+17 mod_17 v2_17
+171 mod_171 v2_171
+173 mod_173 v2_173
+175 mod_175 v2_175
+177 mod_177 v2_177
+179 mod_179 v2_179
+181 mod_181 v2_181
+183 mod_183 v2_183
+185 mod_185 v2_185
+187 mod_187 v2_187
+189 mod_189 v2_189
+19 mod_19 v2_19
+191 mod_191 v2_191
+193 mod_193 v2_193
+195 mod_195 v2_195
+197 mod_197 v2_197
+199 mod_199 v2_199
+201 mod_201 v2_201
+203 mod_203 v2_203
+205 mod_205 v2_205
+207 mod_207 v2_207
+209 mod_209 v2_209
+21 mod_21 v2_21
+211 mod_211 v2_211
+213 mod_213 v2_213
+215 mod_215 v2_215
+217 mod_217 v2_217
+219 mod_219 v2_219
+221 mod_221 v2_221
+223 mod_223 v2_223
+225 mod_225 v2_225
+227 mod_227 v2_227
+229 mod_229 v2_229
+23 mod_23 v2_23
+231 mod_231 v2_231
+233 mod_233 v2_233
+235 mod_235 v2_235
+237 mod_237 v2_237
+239 mod_239 v2_239
+241 mod_241 v2_241
+243 mod_243 v2_243
+245 mod_245 v2_245
+247 mod_247 v2_247
+249 mod_249 v2_249
+25 mod_25 v2_25
+251 mod_251 v2_251
+253 mod_253 v2_253
+255 mod_255 v2_255
+27 mod_27 v2_27
+29 mod_29 v2_29
+3 mod_3 v2_3
+31 mod_31 v2_31
+33 mod_33 v2_33
+35 mod_35 v2_35
+37 mod_37 v2_37
+39 mod_39 v2_39
+41 mod_41 v2_41
+43 mod_43 v2_43
+45 mod_45 v2_45
+47 mod_47 v2_47
+49 mod_49 v2_49
+5 mod_5 v2_5
+51 mod_51 v2_51
+53 mod_53 v2_53
+55 mod_55 v2_55
+57 mod_57 v2_57
+59 mod_59 v2_59
+61 mod_61 v2_61
+63 mod_63 v2_63
+65 mod_65 v2_65
+67 mod_67 v2_67
+69 mod_69 v2_69
+7 mod_7 v2_7
+71 mod_71 v2_71
+73 mod_73 v2_73
+75 mod_75 v2_75
+77 mod_77 v2_77
+79 mod_79 v2_79
+81 mod_81 v2_81
+83 mod_83 v2_83
+85 mod_85 v2_85
+87 mod_87 v2_87
+89 mod_89 v2_89
+9 mod_9 v2_9
+91 mod_91 v2_91
+93 mod_93 v2_93
+95 mod_95 v2_95
+97 mod_97 v2_97
+99 mod_99 v2_99
diff --git a/plugin/handler_socket/regtest/test_01_lib/test06.pl b/plugin/handler_socket/regtest/test_01_lib/test06.pl
new file mode 100644
index 00000000000..fb0549f2295
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test06.pl
@@ -0,0 +1,90 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for insert/update/delete
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 256;
+$dbh->do(
+ "create table $table (" .
+ "k varchar(30) primary key, " .
+ "v1 varchar(30), " .
+ "v2 varchar(30)) " .
+ "engine = innodb default charset = binary");
+srand(999);
+
+my %valmap = ();
+
+print "HSINSERT";
+my $hs = hstest::get_hs_connection(undef, 9999);
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v1,v2');
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "" . $i;
+ my $v1 = "v1_" . $i;
+ my $v2 = "v2_" . $i;
+ my $r = $hs->execute_insert(1, [ $k, $v1, $v2 ]);
+ my $err = $r->[0];
+ if ($err != 0) {
+ my $err_str = $r->[1];
+ print "$err $err_str\n";
+ }
+}
+undef $hs;
+
+dump_table();
+
+print "HSUPDATE";
+$hs = hstest::get_hs_connection(undef, 9999);
+$dbname = $hstest::conf{dbname};
+$hs->open_index(2, $dbname, $table, '', 'v1');
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $r = $hs->execute_single(2, '=', [ $i ], 1000, 0, 'U', [ "mod_$i" ]);
+ my $err = $r->[0];
+ if ($err != 0) {
+ my $err_str = $r->[1];
+ print "$err $err_str\n";
+ }
+}
+undef $hs;
+
+dump_table();
+
+print "HSDELETE\n";
+$hs = hstest::get_hs_connection(undef, 9999);
+$dbname = $hstest::conf{dbname};
+$hs->open_index(3, $dbname, $table, '', '');
+for (my $i = 0; $i < $tablesize; $i = $i + 2) {
+ my $r = $hs->execute_single(3, '=', [ $i ], 1000, 0, 'D');
+ my $err = $r->[0];
+ if ($err != 0) {
+ my $err_str = $r->[1];
+ print "$err $err_str\n";
+ }
+}
+undef $hs;
+
+dump_table();
+
+sub dump_table {
+ print "DUMP_TABLE\n";
+ my $aref = $dbh->selectall_arrayref("select k,v1,v2 from $table order by k");
+ for my $row (@$aref) {
+ my ($k, $v1, $v2) = @$row;
+ $v1 = "[null]" if !defined($v1);
+ $v2 = "[null]" if !defined($v2);
+ print "$k $v1 $v2\n";
+ # print "MISMATCH\n" if ($valmap{$k} ne $v);
+ }
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test07.expected b/plugin/handler_socket/regtest/test_01_lib/test07.expected
new file mode 100644
index 00000000000..f2047c2e237
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test07.expected
@@ -0,0 +1,304 @@
+MY
+0 1v1020 2v6350
+1 1v8031 2v9251
+2 1v7752 2v5372
+3 [NULL] 2v4143
+4 1v5904 2v3024
+5 1v7045 2v7515
+6 1v3676 2v4006
+7 1v3977 2v1707
+8 1v7198 2v7348
+9 1v5879 2v4949
+10 1v52310 2v95410
+11 1v43311 2v82011
+12 1v28312 2v83712
+13 [NULL] 2v41513
+14 1v54514 2v58314
+15 1v5215 2v32315
+16 1v61416 2v67916
+17 1v80517 2v45117
+18 1v11518 2v26918
+19 1v21819 2v61719
+20 1v87820 2v34520
+21 1v51221 2v96921
+22 1v40822 2v29122
+23 [NULL] 2v95323
+24 1v71024 2v14224
+25 1v68225 2v93425
+26 1v62126 2v96526
+27 1v57427 2v20427
+28 1v29828 2v13428
+29 1v98329 2v44429
+30 1v14430 2v15230
+31 1v18731 2v21531
+32 1v832 2v69732
+33 [NULL] 2v28033
+34 1v70134 2v53734
+35 1v41335 2v6935
+36 1v8636 2v82236
+37 1v67037 2v37037
+38 1v80638 2v68838
+39 1v2639 2v6639
+40 1v80240 2v17140
+41 1v55741 2v84741
+42 1v77742 2v73042
+43 [NULL] 2v11543
+44 1v64644 2v49644
+45 1v12045 2v68445
+46 1v37446 2v6546
+47 1v37047 2v17447
+48 1v82848 2v86748
+49 1v75949 2v70349
+50 1v84350 2v94250
+51 1v40151 2v36251
+52 1v36752 2v30752
+53 [NULL] 2v16753
+54 1v79954 2v82954
+55 1v53955 2v37955
+56 1v56056 2v85856
+57 1v57957 2v2657
+58 1v88758 2v50758
+59 1v34559 2v89859
+60 1v43060 2v80160
+61 1v84561 2v32561
+62 1v62462 2v48062
+63 [NULL] 2v67663
+64 1v5364 2v73664
+65 1v80965 2v27065
+66 1v17566 2v83966
+67 1v6167 2v22267
+68 1v35868 2v50568
+69 1v62769 2v90669
+70 1v4670 2v98170
+71 1v11971 2v471
+72 1v1472 2v48072
+73 [NULL] 2v40573
+74 1v87574 2v63974
+75 1v82775 2v34475
+76 1v59876 2v56376
+77 1v77077 2v51677
+78 1v53878 2v54878
+79 1v35779 2v32279
+80 1v3680 2v37080
+81 1v33181 2v81581
+82 1v76982 2v66882
+83 [NULL] 2v28183
+84 1v69684 2v45284
+85 1v40685 2v185
+86 1v39586 2v32486
+87 1v3687 2v73887
+88 1v16088 2v7988
+89 1v75989 2v65789
+90 1v3190 2v78390
+91 1v65091 2v82491
+92 1v85292 2v6892
+93 [NULL] 2v54693
+94 1v81394 2v77594
+95 1v8795 2v69695
+96 1v19696 2v38096
+97 1v7997 2v75197
+98 1v32398 2v21798
+99 1v3799 2v70199
+HS
+0 1v1020 2v6350
+1 1v8031 2v9251
+2 1v7752 2v5372
+3 [NULL] 2v4143
+4 1v5904 2v3024
+5 1v7045 2v7515
+6 1v3676 2v4006
+7 1v3977 2v1707
+8 1v7198 2v7348
+9 1v5879 2v4949
+10 1v52310 2v95410
+11 1v43311 2v82011
+12 1v28312 2v83712
+13 [NULL] 2v41513
+14 1v54514 2v58314
+15 1v5215 2v32315
+16 1v61416 2v67916
+17 1v80517 2v45117
+18 1v11518 2v26918
+19 1v21819 2v61719
+20 1v87820 2v34520
+21 1v51221 2v96921
+22 1v40822 2v29122
+23 [NULL] 2v95323
+24 1v71024 2v14224
+25 1v68225 2v93425
+26 1v62126 2v96526
+27 1v57427 2v20427
+28 1v29828 2v13428
+29 1v98329 2v44429
+30 1v14430 2v15230
+31 1v18731 2v21531
+32 1v832 2v69732
+33 [NULL] 2v28033
+34 1v70134 2v53734
+35 1v41335 2v6935
+36 1v8636 2v82236
+37 1v67037 2v37037
+38 1v80638 2v68838
+39 1v2639 2v6639
+40 1v80240 2v17140
+41 1v55741 2v84741
+42 1v77742 2v73042
+43 [NULL] 2v11543
+44 1v64644 2v49644
+45 1v12045 2v68445
+46 1v37446 2v6546
+47 1v37047 2v17447
+48 1v82848 2v86748
+49 1v75949 2v70349
+50 1v84350 2v94250
+51 1v40151 2v36251
+52 1v36752 2v30752
+53 [NULL] 2v16753
+54 1v79954 2v82954
+55 1v53955 2v37955
+56 1v56056 2v85856
+57 1v57957 2v2657
+58 1v88758 2v50758
+59 1v34559 2v89859
+60 1v43060 2v80160
+61 1v84561 2v32561
+62 1v62462 2v48062
+63 [NULL] 2v67663
+64 1v5364 2v73664
+65 1v80965 2v27065
+66 1v17566 2v83966
+67 1v6167 2v22267
+68 1v35868 2v50568
+69 1v62769 2v90669
+70 1v4670 2v98170
+71 1v11971 2v471
+72 1v1472 2v48072
+73 [NULL] 2v40573
+74 1v87574 2v63974
+75 1v82775 2v34475
+76 1v59876 2v56376
+77 1v77077 2v51677
+78 1v53878 2v54878
+79 1v35779 2v32279
+80 1v3680 2v37080
+81 1v33181 2v81581
+82 1v76982 2v66882
+83 [NULL] 2v28183
+84 1v69684 2v45284
+85 1v40685 2v185
+86 1v39586 2v32486
+87 1v3687 2v73887
+88 1v16088 2v7988
+89 1v75989 2v65789
+90 1v3190 2v78390
+91 1v65091 2v82491
+92 1v85292 2v6892
+93 [NULL] 2v54693
+94 1v81394 2v77594
+95 1v8795 2v69695
+96 1v19696 2v38096
+97 1v7997 2v75197
+98 1v32398 2v21798
+99 1v3799 2v70199
+2ndIDX
+2ndidx 0 1v1020 => 0 1v1020 2v6350
+2ndidx 1 1v8031 => 1 1v8031 2v9251
+2ndidx 2 1v7752 => 2 1v7752 2v5372
+2ndidx 4 1v5904 => 4 1v5904 2v3024
+2ndidx 5 1v7045 => 5 1v7045 2v7515
+2ndidx 6 1v3676 => 6 1v3676 2v4006
+2ndidx 7 1v3977 => 7 1v3977 2v1707
+2ndidx 8 1v7198 => 8 1v7198 2v7348
+2ndidx 9 1v5879 => 9 1v5879 2v4949
+2ndidx 10 1v52310 => 10 1v52310 2v95410
+2ndidx 11 1v43311 => 11 1v43311 2v82011
+2ndidx 12 1v28312 => 12 1v28312 2v83712
+2ndidx 14 1v54514 => 14 1v54514 2v58314
+2ndidx 15 1v5215 => 15 1v5215 2v32315
+2ndidx 16 1v61416 => 16 1v61416 2v67916
+2ndidx 17 1v80517 => 17 1v80517 2v45117
+2ndidx 18 1v11518 => 18 1v11518 2v26918
+2ndidx 19 1v21819 => 19 1v21819 2v61719
+2ndidx 20 1v87820 => 20 1v87820 2v34520
+2ndidx 21 1v51221 => 21 1v51221 2v96921
+2ndidx 22 1v40822 => 22 1v40822 2v29122
+2ndidx 24 1v71024 => 24 1v71024 2v14224
+2ndidx 25 1v68225 => 25 1v68225 2v93425
+2ndidx 26 1v62126 => 26 1v62126 2v96526
+2ndidx 27 1v57427 => 27 1v57427 2v20427
+2ndidx 28 1v29828 => 28 1v29828 2v13428
+2ndidx 29 1v98329 => 29 1v98329 2v44429
+2ndidx 30 1v14430 => 30 1v14430 2v15230
+2ndidx 31 1v18731 => 31 1v18731 2v21531
+2ndidx 32 1v832 => 32 1v832 2v69732
+2ndidx 34 1v70134 => 34 1v70134 2v53734
+2ndidx 35 1v41335 => 35 1v41335 2v6935
+2ndidx 36 1v8636 => 36 1v8636 2v82236
+2ndidx 37 1v67037 => 37 1v67037 2v37037
+2ndidx 38 1v80638 => 38 1v80638 2v68838
+2ndidx 39 1v2639 => 39 1v2639 2v6639
+2ndidx 40 1v80240 => 40 1v80240 2v17140
+2ndidx 41 1v55741 => 41 1v55741 2v84741
+2ndidx 42 1v77742 => 42 1v77742 2v73042
+2ndidx 44 1v64644 => 44 1v64644 2v49644
+2ndidx 45 1v12045 => 45 1v12045 2v68445
+2ndidx 46 1v37446 => 46 1v37446 2v6546
+2ndidx 47 1v37047 => 47 1v37047 2v17447
+2ndidx 48 1v82848 => 48 1v82848 2v86748
+2ndidx 49 1v75949 => 49 1v75949 2v70349
+2ndidx 50 1v84350 => 50 1v84350 2v94250
+2ndidx 51 1v40151 => 51 1v40151 2v36251
+2ndidx 52 1v36752 => 52 1v36752 2v30752
+2ndidx 54 1v79954 => 54 1v79954 2v82954
+2ndidx 55 1v53955 => 55 1v53955 2v37955
+2ndidx 56 1v56056 => 56 1v56056 2v85856
+2ndidx 57 1v57957 => 57 1v57957 2v2657
+2ndidx 58 1v88758 => 58 1v88758 2v50758
+2ndidx 59 1v34559 => 59 1v34559 2v89859
+2ndidx 60 1v43060 => 60 1v43060 2v80160
+2ndidx 61 1v84561 => 61 1v84561 2v32561
+2ndidx 62 1v62462 => 62 1v62462 2v48062
+2ndidx 64 1v5364 => 64 1v5364 2v73664
+2ndidx 65 1v80965 => 65 1v80965 2v27065
+2ndidx 66 1v17566 => 66 1v17566 2v83966
+2ndidx 67 1v6167 => 67 1v6167 2v22267
+2ndidx 68 1v35868 => 68 1v35868 2v50568
+2ndidx 69 1v62769 => 69 1v62769 2v90669
+2ndidx 70 1v4670 => 70 1v4670 2v98170
+2ndidx 71 1v11971 => 71 1v11971 2v471
+2ndidx 72 1v1472 => 72 1v1472 2v48072
+2ndidx 74 1v87574 => 74 1v87574 2v63974
+2ndidx 75 1v82775 => 75 1v82775 2v34475
+2ndidx 76 1v59876 => 76 1v59876 2v56376
+2ndidx 77 1v77077 => 77 1v77077 2v51677
+2ndidx 78 1v53878 => 78 1v53878 2v54878
+2ndidx 79 1v35779 => 79 1v35779 2v32279
+2ndidx 80 1v3680 => 80 1v3680 2v37080
+2ndidx 81 1v33181 => 81 1v33181 2v81581
+2ndidx 82 1v76982 => 82 1v76982 2v66882
+2ndidx 84 1v69684 => 84 1v69684 2v45284
+2ndidx 85 1v40685 => 85 1v40685 2v185
+2ndidx 86 1v39586 => 86 1v39586 2v32486
+2ndidx 87 1v3687 => 87 1v3687 2v73887
+2ndidx 88 1v16088 => 88 1v16088 2v7988
+2ndidx 89 1v75989 => 89 1v75989 2v65789
+2ndidx 90 1v3190 => 90 1v3190 2v78390
+2ndidx 91 1v65091 => 91 1v65091 2v82491
+2ndidx 92 1v85292 => 92 1v85292 2v6892
+2ndidx 94 1v81394 => 94 1v81394 2v77594
+2ndidx 95 1v8795 => 95 1v8795 2v69695
+2ndidx 96 1v19696 => 96 1v19696 2v38096
+2ndidx 97 1v7997 => 97 1v7997 2v75197
+2ndidx 98 1v32398 => 98 1v32398 2v21798
+2ndidx 99 1v3799 => 99 1v3799 2v70199
+2ndIDX NULL
+2ndidxnull 3 2v4143
+2ndidxnull 13 2v41513
+2ndidxnull 23 2v95323
+2ndidxnull 33 2v28033
+2ndidxnull 43 2v11543
+2ndidxnull 53 2v16753
+2ndidxnull 63 2v67663
+2ndidxnull 73 2v40573
+2ndidxnull 83 2v28183
+2ndidxnull 93 2v54693
diff --git a/plugin/handler_socket/regtest/test_01_lib/test07.pl b/plugin/handler_socket/regtest/test_01_lib/test07.pl
new file mode 100644
index 00000000000..fa9802366d8
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test07.pl
@@ -0,0 +1,98 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for nulls
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+# use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 100;
+$dbh->do(
+ "create table $table (" .
+ "k int primary key, v1 varchar(30), v2 varchar(30), " .
+ "key idxv1 (v1) " .
+ ") engine = innodb");
+srand(999);
+
+my %valmap = ();
+
+my $sth = $dbh->prepare("insert into $table values (?,?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "" . $i;
+ my $v1 = "1v" . int(rand(1000)) . $i;
+ my $v2 = "2v" . int(rand(1000)) . $i;
+ if ($i % 10 == 3) {
+ $v1 = undef;
+ }
+ $sth->execute($k, $v1, $v2);
+ $valmap{$k} = $v1;
+}
+
+print "MY\n";
+my $aref = $dbh->selectall_arrayref("select k,v1,v2 from $table order by k");
+for my $row (@$aref) {
+ my ($k, $v1, $v2) = @$row;
+ $v1 = "[NULL]" if (!defined($v1));
+ print "$k $v1 $v2\n";
+}
+
+print "HS\n";
+my $hs = hstest::get_hs_connection();
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v1,v2');
+my $r = $hs->execute_single(1, '>=', [ '' ], 10000, 0);
+shift(@$r);
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = $r->[$i * 3];
+ my $v1 = $r->[$i * 3 + 1];
+ my $v2 = $r->[$i * 3 + 2];
+ $v1 = "[NULL]" if (!defined($v1));
+ print "$k $v1 $v2\n";
+}
+
+print "2ndIDX\n";
+$hs->open_index(2, $dbname, $table, 'idxv1', 'k,v1,v2');
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "" . $i;
+ my $v1 = $valmap{$k};
+ next if !defined($v1);
+ my $r = $hs->execute_single(2, '=', [ $v1 ], 1, 0);
+ shift(@$r);
+ my $r_k = $r->[0];
+ my $r_v1 = $r->[1];
+ my $r_v2 = $r->[2];
+ print "2ndidx $k $v1 => $r_k $r_v1 $r_v2\n";
+}
+
+print "2ndIDX NULL\n";
+{
+ my %rvals = ();
+ my $v1 = undef;
+ my @arr;
+ push(@arr, undef);
+ my $kv = \@arr;
+ my $r = $hs->execute_single(2, "=", $kv, 10000, 0);
+ shift(@$r);
+ for (my $i = 0; $i < scalar(@$r); $i += 3) {
+ my $k = $r->[$i];
+ my $v1 = $r->[$i + 1];
+ my $v2 = $r->[$i + 2];
+ $rvals{$k} = [ $k, $v1, $v2 ];
+ }
+ for my $i (sort { $a <=> $b } keys %rvals) {
+ my $rec = $rvals{$i};
+ my $k = $rec->[0];
+ my $v1 = $rec->[1];
+ my $v2 = $rec->[2];
+ print "2ndidxnull $k $v2\n";
+ }
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test08.expected b/plugin/handler_socket/regtest/test_01_lib/test08.expected
new file mode 100644
index 00000000000..64d705daab8
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test08.expected
@@ -0,0 +1,2 @@
+[0][k5][v5375]
+[0]
diff --git a/plugin/handler_socket/regtest/test_01_lib/test08.pl b/plugin/handler_socket/regtest/test_01_lib/test08.pl
new file mode 100644
index 00000000000..c33bf190d29
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test08.pl
@@ -0,0 +1,48 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for not-found
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 100;
+$dbh->do(
+ "create table $table (k varchar(30) primary key, v varchar(30) not null) " .
+ "engine = innodb");
+srand(999);
+
+my %valmap = ();
+
+my $sth = $dbh->prepare("insert into $table values (?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "k" . $i;
+ my $v = "v" . int(rand(1000)) . $i;
+ $sth->execute($k, $v);
+ $valmap{$k} = $v;
+}
+
+my $hs = hstest::get_hs_connection();
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v');
+
+dump_rec($hs, 1, 'k5'); # found
+dump_rec($hs, 1, 'k000000'); # notfound
+
+sub dump_rec {
+ my ($hs, $idxid, $key) = @_;
+ my $r = $hs->execute_single($idxid, '=', [ $key ], 1, 0);
+ for my $fld (@$r) {
+ print "[$fld]";
+ }
+ print "\n";
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test09.expected b/plugin/handler_socket/regtest/test_01_lib/test09.expected
new file mode 100644
index 00000000000..12cb11824db
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test09.expected
@@ -0,0 +1,12 @@
+DEL
+[0][1]
+[0][k50][v68250][k51][v93451]
+DELINS
+[0][k6][v5926][k60][v14460][k61][v15261]
+[0][1]
+[0]
+[0][k6][v5926][k60][INS][k61][v15261]
+DELUPUP
+[0][k7][v4147][k70][v41370][k71][v6971]
+[0][1]
+[0][k7][v4147][k70][UP][k71][v6971]
diff --git a/plugin/handler_socket/regtest/test_01_lib/test09.pl b/plugin/handler_socket/regtest/test_01_lib/test09.pl
new file mode 100644
index 00000000000..14fd9c26641
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test09.pl
@@ -0,0 +1,67 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for multiple modify requests
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 100;
+$dbh->do(
+ "create table $table (k varchar(30) primary key, v varchar(30) not null) " .
+ "engine = innodb");
+srand(999);
+
+my %valmap = ();
+
+my $sth = $dbh->prepare("insert into $table values (?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "k" . $i;
+ my $v = "v" . int(rand(1000)) . $i;
+ $sth->execute($k, $v);
+ $valmap{$k} = $v;
+}
+
+my $hs = hstest::get_hs_connection(undef, 9999);
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v');
+
+exec_multi(
+ "DEL",
+ [ 1, '=', [ 'k5' ], 1, 0, 'D' ],
+ [ 1, '>=', [ 'k5' ], 2, 0 ],
+);
+exec_multi(
+ "DELINS",
+ [ 1, '>=', [ 'k6' ], 3, 0 ],
+ [ 1, '=', [ 'k60' ], 1, 0, 'D' ],
+ [ 1, '+', [ 'k60', 'INS' ] ],
+ [ 1, '>=', [ 'k6' ], 3, 0 ],
+);
+exec_multi(
+ "DELUPUP",
+ [ 1, '>=', [ 'k7' ], 3, 0 ],
+ [ 1, '=', [ 'k70' ], 1, 0, 'U', [ 'k70', 'UP' ] ],
+ [ 1, '>=', [ 'k7' ], 3, 0 ],
+);
+
+sub exec_multi {
+ my $mess = shift(@_);
+ print "$mess\n";
+ my $mres = $hs->execute_multi(\@_);
+ for my $res (@$mres) {
+ for my $fld (@$res) {
+ print "[$fld]";
+ }
+ print "\n";
+ }
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test10.expected b/plugin/handler_socket/regtest/test_01_lib/test10.expected
new file mode 100644
index 00000000000..6716abad1c7
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test10.expected
@@ -0,0 +1,771 @@
+HSINSERTDUMP_TABLE
+0 v1_0 [null]
+1 v1_1 [null]
+10 v1_10 [null]
+100 v1_100 [null]
+101 v1_101 [null]
+102 v1_102 [null]
+103 v1_103 [null]
+104 v1_104 [null]
+105 v1_105 [null]
+106 v1_106 [null]
+107 v1_107 [null]
+108 v1_108 [null]
+109 v1_109 [null]
+11 v1_11 [null]
+110 v1_110 [null]
+111 v1_111 [null]
+112 v1_112 [null]
+113 v1_113 [null]
+114 v1_114 [null]
+115 v1_115 [null]
+116 v1_116 [null]
+117 v1_117 [null]
+118 v1_118 [null]
+119 v1_119 [null]
+12 v1_12 [null]
+120 v1_120 [null]
+121 v1_121 [null]
+122 v1_122 [null]
+123 v1_123 [null]
+124 v1_124 [null]
+125 v1_125 [null]
+126 v1_126 [null]
+127 v1_127 [null]
+128 v1_128 [null]
+129 v1_129 [null]
+13 v1_13 [null]
+130 v1_130 [null]
+131 v1_131 [null]
+132 v1_132 [null]
+133 v1_133 [null]
+134 v1_134 [null]
+135 v1_135 [null]
+136 v1_136 [null]
+137 v1_137 [null]
+138 v1_138 [null]
+139 v1_139 [null]
+14 v1_14 [null]
+140 v1_140 [null]
+141 v1_141 [null]
+142 v1_142 [null]
+143 v1_143 [null]
+144 v1_144 [null]
+145 v1_145 [null]
+146 v1_146 [null]
+147 v1_147 [null]
+148 v1_148 [null]
+149 v1_149 [null]
+15 v1_15 [null]
+150 v1_150 [null]
+151 v1_151 [null]
+152 v1_152 [null]
+153 v1_153 [null]
+154 v1_154 [null]
+155 v1_155 [null]
+156 v1_156 [null]
+157 v1_157 [null]
+158 v1_158 [null]
+159 v1_159 [null]
+16 v1_16 [null]
+160 v1_160 [null]
+161 v1_161 [null]
+162 v1_162 [null]
+163 v1_163 [null]
+164 v1_164 [null]
+165 v1_165 [null]
+166 v1_166 [null]
+167 v1_167 [null]
+168 v1_168 [null]
+169 v1_169 [null]
+17 v1_17 [null]
+170 v1_170 [null]
+171 v1_171 [null]
+172 v1_172 [null]
+173 v1_173 [null]
+174 v1_174 [null]
+175 v1_175 [null]
+176 v1_176 [null]
+177 v1_177 [null]
+178 v1_178 [null]
+179 v1_179 [null]
+18 v1_18 [null]
+180 v1_180 [null]
+181 v1_181 [null]
+182 v1_182 [null]
+183 v1_183 [null]
+184 v1_184 [null]
+185 v1_185 [null]
+186 v1_186 [null]
+187 v1_187 [null]
+188 v1_188 [null]
+189 v1_189 [null]
+19 v1_19 [null]
+190 v1_190 [null]
+191 v1_191 [null]
+192 v1_192 [null]
+193 v1_193 [null]
+194 v1_194 [null]
+195 v1_195 [null]
+196 v1_196 [null]
+197 v1_197 [null]
+198 v1_198 [null]
+199 v1_199 [null]
+2 v1_2 [null]
+20 v1_20 [null]
+200 v1_200 [null]
+201 v1_201 [null]
+202 v1_202 [null]
+203 v1_203 [null]
+204 v1_204 [null]
+205 v1_205 [null]
+206 v1_206 [null]
+207 v1_207 [null]
+208 v1_208 [null]
+209 v1_209 [null]
+21 v1_21 [null]
+210 v1_210 [null]
+211 v1_211 [null]
+212 v1_212 [null]
+213 v1_213 [null]
+214 v1_214 [null]
+215 v1_215 [null]
+216 v1_216 [null]
+217 v1_217 [null]
+218 v1_218 [null]
+219 v1_219 [null]
+22 v1_22 [null]
+220 v1_220 [null]
+221 v1_221 [null]
+222 v1_222 [null]
+223 v1_223 [null]
+224 v1_224 [null]
+225 v1_225 [null]
+226 v1_226 [null]
+227 v1_227 [null]
+228 v1_228 [null]
+229 v1_229 [null]
+23 v1_23 [null]
+230 v1_230 [null]
+231 v1_231 [null]
+232 v1_232 [null]
+233 v1_233 [null]
+234 v1_234 [null]
+235 v1_235 [null]
+236 v1_236 [null]
+237 v1_237 [null]
+238 v1_238 [null]
+239 v1_239 [null]
+24 v1_24 [null]
+240 v1_240 [null]
+241 v1_241 [null]
+242 v1_242 [null]
+243 v1_243 [null]
+244 v1_244 [null]
+245 v1_245 [null]
+246 v1_246 [null]
+247 v1_247 [null]
+248 v1_248 [null]
+249 v1_249 [null]
+25 v1_25 [null]
+250 v1_250 [null]
+251 v1_251 [null]
+252 v1_252 [null]
+253 v1_253 [null]
+254 v1_254 [null]
+255 v1_255 [null]
+26 v1_26 [null]
+27 v1_27 [null]
+28 v1_28 [null]
+29 v1_29 [null]
+3 v1_3 [null]
+30 v1_30 [null]
+31 v1_31 [null]
+32 v1_32 [null]
+33 v1_33 [null]
+34 v1_34 [null]
+35 v1_35 [null]
+36 v1_36 [null]
+37 v1_37 [null]
+38 v1_38 [null]
+39 v1_39 [null]
+4 v1_4 [null]
+40 v1_40 [null]
+41 v1_41 [null]
+42 v1_42 [null]
+43 v1_43 [null]
+44 v1_44 [null]
+45 v1_45 [null]
+46 v1_46 [null]
+47 v1_47 [null]
+48 v1_48 [null]
+49 v1_49 [null]
+5 v1_5 [null]
+50 v1_50 [null]
+51 v1_51 [null]
+52 v1_52 [null]
+53 v1_53 [null]
+54 v1_54 [null]
+55 v1_55 [null]
+56 v1_56 [null]
+57 v1_57 [null]
+58 v1_58 [null]
+59 v1_59 [null]
+6 v1_6 [null]
+60 v1_60 [null]
+61 v1_61 [null]
+62 v1_62 [null]
+63 v1_63 [null]
+64 v1_64 [null]
+65 v1_65 [null]
+66 v1_66 [null]
+67 v1_67 [null]
+68 v1_68 [null]
+69 v1_69 [null]
+7 v1_7 [null]
+70 v1_70 [null]
+71 v1_71 [null]
+72 v1_72 [null]
+73 v1_73 [null]
+74 v1_74 [null]
+75 v1_75 [null]
+76 v1_76 [null]
+77 v1_77 [null]
+78 v1_78 [null]
+79 v1_79 [null]
+8 v1_8 [null]
+80 v1_80 [null]
+81 v1_81 [null]
+82 v1_82 [null]
+83 v1_83 [null]
+84 v1_84 [null]
+85 v1_85 [null]
+86 v1_86 [null]
+87 v1_87 [null]
+88 v1_88 [null]
+89 v1_89 [null]
+9 v1_9 [null]
+90 v1_90 [null]
+91 v1_91 [null]
+92 v1_92 [null]
+93 v1_93 [null]
+94 v1_94 [null]
+95 v1_95 [null]
+96 v1_96 [null]
+97 v1_97 [null]
+98 v1_98 [null]
+99 v1_99 [null]
+HSUPDATEDUMP_TABLE
+0 [null] [null]
+1 [null] [null]
+10 [null] [null]
+100 [null] [null]
+101 [null] [null]
+102 [null] [null]
+103 [null] [null]
+104 [null] [null]
+105 [null] [null]
+106 [null] [null]
+107 [null] [null]
+108 [null] [null]
+109 [null] [null]
+11 [null] [null]
+110 [null] [null]
+111 [null] [null]
+112 [null] [null]
+113 [null] [null]
+114 [null] [null]
+115 [null] [null]
+116 [null] [null]
+117 [null] [null]
+118 [null] [null]
+119 [null] [null]
+12 [null] [null]
+120 [null] [null]
+121 [null] [null]
+122 [null] [null]
+123 [null] [null]
+124 [null] [null]
+125 [null] [null]
+126 [null] [null]
+127 [null] [null]
+128 [null] [null]
+129 [null] [null]
+13 [null] [null]
+130 [null] [null]
+131 [null] [null]
+132 [null] [null]
+133 [null] [null]
+134 [null] [null]
+135 [null] [null]
+136 [null] [null]
+137 [null] [null]
+138 [null] [null]
+139 [null] [null]
+14 [null] [null]
+140 [null] [null]
+141 [null] [null]
+142 [null] [null]
+143 [null] [null]
+144 [null] [null]
+145 [null] [null]
+146 [null] [null]
+147 [null] [null]
+148 [null] [null]
+149 [null] [null]
+15 [null] [null]
+150 [null] [null]
+151 [null] [null]
+152 [null] [null]
+153 [null] [null]
+154 [null] [null]
+155 [null] [null]
+156 [null] [null]
+157 [null] [null]
+158 [null] [null]
+159 [null] [null]
+16 [null] [null]
+160 [null] [null]
+161 [null] [null]
+162 [null] [null]
+163 [null] [null]
+164 [null] [null]
+165 [null] [null]
+166 [null] [null]
+167 [null] [null]
+168 [null] [null]
+169 [null] [null]
+17 [null] [null]
+170 [null] [null]
+171 [null] [null]
+172 [null] [null]
+173 [null] [null]
+174 [null] [null]
+175 [null] [null]
+176 [null] [null]
+177 [null] [null]
+178 [null] [null]
+179 [null] [null]
+18 [null] [null]
+180 [null] [null]
+181 [null] [null]
+182 [null] [null]
+183 [null] [null]
+184 [null] [null]
+185 [null] [null]
+186 [null] [null]
+187 [null] [null]
+188 [null] [null]
+189 [null] [null]
+19 [null] [null]
+190 [null] [null]
+191 [null] [null]
+192 [null] [null]
+193 [null] [null]
+194 [null] [null]
+195 [null] [null]
+196 [null] [null]
+197 [null] [null]
+198 [null] [null]
+199 [null] [null]
+2 [null] [null]
+20 [null] [null]
+200 [null] [null]
+201 [null] [null]
+202 [null] [null]
+203 [null] [null]
+204 [null] [null]
+205 [null] [null]
+206 [null] [null]
+207 [null] [null]
+208 [null] [null]
+209 [null] [null]
+21 [null] [null]
+210 [null] [null]
+211 [null] [null]
+212 [null] [null]
+213 [null] [null]
+214 [null] [null]
+215 [null] [null]
+216 [null] [null]
+217 [null] [null]
+218 [null] [null]
+219 [null] [null]
+22 [null] [null]
+220 [null] [null]
+221 [null] [null]
+222 [null] [null]
+223 [null] [null]
+224 [null] [null]
+225 [null] [null]
+226 [null] [null]
+227 [null] [null]
+228 [null] [null]
+229 [null] [null]
+23 [null] [null]
+230 [null] [null]
+231 [null] [null]
+232 [null] [null]
+233 [null] [null]
+234 [null] [null]
+235 [null] [null]
+236 [null] [null]
+237 [null] [null]
+238 [null] [null]
+239 [null] [null]
+24 [null] [null]
+240 [null] [null]
+241 [null] [null]
+242 [null] [null]
+243 [null] [null]
+244 [null] [null]
+245 [null] [null]
+246 [null] [null]
+247 [null] [null]
+248 [null] [null]
+249 [null] [null]
+25 [null] [null]
+250 [null] [null]
+251 [null] [null]
+252 [null] [null]
+253 [null] [null]
+254 [null] [null]
+255 [null] [null]
+26 [null] [null]
+27 [null] [null]
+28 [null] [null]
+29 [null] [null]
+3 [null] [null]
+30 [null] [null]
+31 [null] [null]
+32 [null] [null]
+33 [null] [null]
+34 [null] [null]
+35 [null] [null]
+36 [null] [null]
+37 [null] [null]
+38 [null] [null]
+39 [null] [null]
+4 [null] [null]
+40 [null] [null]
+41 [null] [null]
+42 [null] [null]
+43 [null] [null]
+44 [null] [null]
+45 [null] [null]
+46 [null] [null]
+47 [null] [null]
+48 [null] [null]
+49 [null] [null]
+5 [null] [null]
+50 [null] [null]
+51 [null] [null]
+52 [null] [null]
+53 [null] [null]
+54 [null] [null]
+55 [null] [null]
+56 [null] [null]
+57 [null] [null]
+58 [null] [null]
+59 [null] [null]
+6 [null] [null]
+60 [null] [null]
+61 [null] [null]
+62 [null] [null]
+63 [null] [null]
+64 [null] [null]
+65 [null] [null]
+66 [null] [null]
+67 [null] [null]
+68 [null] [null]
+69 [null] [null]
+7 [null] [null]
+70 [null] [null]
+71 [null] [null]
+72 [null] [null]
+73 [null] [null]
+74 [null] [null]
+75 [null] [null]
+76 [null] [null]
+77 [null] [null]
+78 [null] [null]
+79 [null] [null]
+8 [null] [null]
+80 [null] [null]
+81 [null] [null]
+82 [null] [null]
+83 [null] [null]
+84 [null] [null]
+85 [null] [null]
+86 [null] [null]
+87 [null] [null]
+88 [null] [null]
+89 [null] [null]
+9 [null] [null]
+90 [null] [null]
+91 [null] [null]
+92 [null] [null]
+93 [null] [null]
+94 [null] [null]
+95 [null] [null]
+96 [null] [null]
+97 [null] [null]
+98 [null] [null]
+99 [null] [null]
+HSUPDATEDUMP_TABLE
+0 hoge [null]
+1 hoge [null]
+10 hoge [null]
+100 hoge [null]
+101 hoge [null]
+102 hoge [null]
+103 hoge [null]
+104 hoge [null]
+105 hoge [null]
+106 hoge [null]
+107 hoge [null]
+108 hoge [null]
+109 hoge [null]
+11 hoge [null]
+110 hoge [null]
+111 hoge [null]
+112 hoge [null]
+113 hoge [null]
+114 hoge [null]
+115 hoge [null]
+116 hoge [null]
+117 hoge [null]
+118 hoge [null]
+119 hoge [null]
+12 hoge [null]
+120 hoge [null]
+121 hoge [null]
+122 hoge [null]
+123 hoge [null]
+124 hoge [null]
+125 hoge [null]
+126 hoge [null]
+127 hoge [null]
+128 hoge [null]
+129 hoge [null]
+13 hoge [null]
+130 hoge [null]
+131 hoge [null]
+132 hoge [null]
+133 hoge [null]
+134 hoge [null]
+135 hoge [null]
+136 hoge [null]
+137 hoge [null]
+138 hoge [null]
+139 hoge [null]
+14 hoge [null]
+140 hoge [null]
+141 hoge [null]
+142 hoge [null]
+143 hoge [null]
+144 hoge [null]
+145 hoge [null]
+146 hoge [null]
+147 hoge [null]
+148 hoge [null]
+149 hoge [null]
+15 hoge [null]
+150 hoge [null]
+151 hoge [null]
+152 hoge [null]
+153 hoge [null]
+154 hoge [null]
+155 hoge [null]
+156 hoge [null]
+157 hoge [null]
+158 hoge [null]
+159 hoge [null]
+16 hoge [null]
+160 hoge [null]
+161 hoge [null]
+162 hoge [null]
+163 hoge [null]
+164 hoge [null]
+165 hoge [null]
+166 hoge [null]
+167 hoge [null]
+168 hoge [null]
+169 hoge [null]
+17 hoge [null]
+170 hoge [null]
+171 hoge [null]
+172 hoge [null]
+173 hoge [null]
+174 hoge [null]
+175 hoge [null]
+176 hoge [null]
+177 hoge [null]
+178 hoge [null]
+179 hoge [null]
+18 hoge [null]
+180 hoge [null]
+181 hoge [null]
+182 hoge [null]
+183 hoge [null]
+184 hoge [null]
+185 hoge [null]
+186 hoge [null]
+187 hoge [null]
+188 hoge [null]
+189 hoge [null]
+19 hoge [null]
+190 hoge [null]
+191 hoge [null]
+192 hoge [null]
+193 hoge [null]
+194 hoge [null]
+195 hoge [null]
+196 hoge [null]
+197 hoge [null]
+198 hoge [null]
+199 hoge [null]
+2 hoge [null]
+20 hoge [null]
+200 hoge [null]
+201 hoge [null]
+202 hoge [null]
+203 hoge [null]
+204 hoge [null]
+205 hoge [null]
+206 hoge [null]
+207 hoge [null]
+208 hoge [null]
+209 hoge [null]
+21 hoge [null]
+210 hoge [null]
+211 hoge [null]
+212 hoge [null]
+213 hoge [null]
+214 hoge [null]
+215 hoge [null]
+216 hoge [null]
+217 hoge [null]
+218 hoge [null]
+219 hoge [null]
+22 hoge [null]
+220 hoge [null]
+221 hoge [null]
+222 hoge [null]
+223 hoge [null]
+224 hoge [null]
+225 hoge [null]
+226 hoge [null]
+227 hoge [null]
+228 hoge [null]
+229 hoge [null]
+23 hoge [null]
+230 hoge [null]
+231 hoge [null]
+232 hoge [null]
+233 hoge [null]
+234 hoge [null]
+235 hoge [null]
+236 hoge [null]
+237 hoge [null]
+238 hoge [null]
+239 hoge [null]
+24 hoge [null]
+240 hoge [null]
+241 hoge [null]
+242 hoge [null]
+243 hoge [null]
+244 hoge [null]
+245 hoge [null]
+246 hoge [null]
+247 hoge [null]
+248 hoge [null]
+249 hoge [null]
+25 hoge [null]
+250 hoge [null]
+251 hoge [null]
+252 hoge [null]
+253 hoge [null]
+254 hoge [null]
+255 hoge [null]
+26 hoge [null]
+27 hoge [null]
+28 hoge [null]
+29 hoge [null]
+3 hoge [null]
+30 hoge [null]
+31 hoge [null]
+32 hoge [null]
+33 hoge [null]
+34 hoge [null]
+35 hoge [null]
+36 hoge [null]
+37 hoge [null]
+38 hoge [null]
+39 hoge [null]
+4 hoge [null]
+40 hoge [null]
+41 hoge [null]
+42 hoge [null]
+43 hoge [null]
+44 hoge [null]
+45 hoge [null]
+46 hoge [null]
+47 hoge [null]
+48 hoge [null]
+49 hoge [null]
+5 hoge [null]
+50 hoge [null]
+51 hoge [null]
+52 hoge [null]
+53 hoge [null]
+54 hoge [null]
+55 hoge [null]
+56 hoge [null]
+57 hoge [null]
+58 hoge [null]
+59 hoge [null]
+6 hoge [null]
+60 hoge [null]
+61 hoge [null]
+62 hoge [null]
+63 hoge [null]
+64 hoge [null]
+65 hoge [null]
+66 hoge [null]
+67 hoge [null]
+68 hoge [null]
+69 hoge [null]
+7 hoge [null]
+70 hoge [null]
+71 hoge [null]
+72 hoge [null]
+73 hoge [null]
+74 hoge [null]
+75 hoge [null]
+76 hoge [null]
+77 hoge [null]
+78 hoge [null]
+79 hoge [null]
+8 hoge [null]
+80 hoge [null]
+81 hoge [null]
+82 hoge [null]
+83 hoge [null]
+84 hoge [null]
+85 hoge [null]
+86 hoge [null]
+87 hoge [null]
+88 hoge [null]
+89 hoge [null]
+9 hoge [null]
+90 hoge [null]
+91 hoge [null]
+92 hoge [null]
+93 hoge [null]
+94 hoge [null]
+95 hoge [null]
+96 hoge [null]
+97 hoge [null]
+98 hoge [null]
+99 hoge [null]
diff --git a/plugin/handler_socket/regtest/test_01_lib/test10.pl b/plugin/handler_socket/regtest/test_01_lib/test10.pl
new file mode 100644
index 00000000000..fd294fe8b78
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test10.pl
@@ -0,0 +1,93 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for nulls
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 256;
+$dbh->do(
+ "create table $table (" .
+ "k varchar(30) primary key, " .
+ "v1 varchar(30), " .
+ "v2 varchar(30)) " .
+ "engine = innodb default charset = binary");
+srand(999);
+
+my %valmap = ();
+
+# setting null
+print "HSINSERT";
+my $hs = hstest::get_hs_connection(undef, 9999);
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v1,v2');
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "" . $i;
+ my $v1 = "v1_" . $i;
+ my $v2 = undef; # null value
+ my $r = $hs->execute_insert(1, [ $k, $v1, $v2 ]);
+ my $err = $r->[0];
+ if ($err != 0) {
+ my $err_str = $r->[1];
+ print "$err $err_str\n";
+ }
+}
+undef $hs;
+
+dump_table();
+
+# setting null
+print "HSUPDATE";
+$hs = hstest::get_hs_connection(undef, 9999);
+$dbname = $hstest::conf{dbname};
+$hs->open_index(2, $dbname, $table, '', 'v1');
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $r = $hs->execute_single(2, '=', [ $i ], 1000, 0, 'U', [ undef ]);
+ my $err = $r->[0];
+ if ($err != 0) {
+ my $err_str = $r->[1];
+ print "$err $err_str\n";
+ }
+}
+undef $hs;
+
+dump_table();
+
+# setting non-null
+print "HSUPDATE";
+$hs = hstest::get_hs_connection(undef, 9999);
+$dbname = $hstest::conf{dbname};
+$hs->open_index(2, $dbname, $table, '', 'v1');
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $r = $hs->execute_single(2, '=', [ $i ], 1000, 0, 'U', [ "hoge" ]);
+ my $err = $r->[0];
+ if ($err != 0) {
+ my $err_str = $r->[1];
+ print "$err $err_str\n";
+ }
+}
+undef $hs;
+
+dump_table();
+
+sub dump_table {
+ print "DUMP_TABLE\n";
+ my $aref = $dbh->selectall_arrayref("select k,v1,v2 from $table order by k");
+ for my $row (@$aref) {
+ my ($k, $v1, $v2) = @$row;
+ $v1 = "[null]" if !defined($v1);
+ $v2 = "[null]" if !defined($v2);
+ print "$k $v1 $v2\n";
+ # print "MISMATCH\n" if ($valmap{$k} ne $v);
+ }
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test11.expected b/plugin/handler_socket/regtest/test_01_lib/test11.expected
new file mode 100644
index 00000000000..4359d470cb8
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test11.expected
@@ -0,0 +1,37 @@
+VAL
+[0][k5][5]
+[0][k6][6]
+[0][k7][7]
+[0][k8][8]
+INCREMENT
+[0][1]
+[0][1]
+[0][1]
+[0][1]
+VAL
+[0][k5][8]
+[0][k6][18]
+[0][k7][-4]
+[0][k8][-7]
+DECREMENT
+[0][1]
+[0][0]
+[0][1]
+[0][0]
+VAL
+[0][k5][6]
+[0][k6][18]
+[0][k7][-84]
+[0][k8][-7]
+INCREMENT
+[0][6]
+[0][7]
+[0][8]
+[0][9]
+[0][10]
+[0][11]
+[0][12]
+[0][13]
+[0][14]
+VAL
+[0][k5][15]
diff --git a/plugin/handler_socket/regtest/test_01_lib/test11.pl b/plugin/handler_socket/regtest/test_01_lib/test11.pl
new file mode 100644
index 00000000000..5cfe3e83614
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test11.pl
@@ -0,0 +1,112 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for increment/decrement
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 100;
+$dbh->do(
+ "create table $table (k varchar(30) primary key, v varchar(30) not null) " .
+ "engine = innodb");
+srand(999);
+
+my %valmap = ();
+
+my $sth = $dbh->prepare("insert into $table values (?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "k" . $i;
+ my $v = $i;
+ $sth->execute($k, $v);
+ $valmap{$k} = $v;
+}
+
+my $hs = hstest::get_hs_connection(undef, 9999);
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v');
+$hs->open_index(2, $dbname, $table, '', 'v');
+
+exec_multi(
+ "VAL",
+ [ 1, '=', [ 'k5' ], 1, 0 ],
+ [ 1, '=', [ 'k6' ], 1, 0 ],
+ [ 1, '=', [ 'k7' ], 1, 0 ],
+ [ 1, '=', [ 'k8' ], 1, 0 ],
+);
+# 5, 6, 7, 8
+
+exec_multi(
+ "INCREMENT",
+ [ 2, '=', [ 'k5' ], 1, 0, '+', [ 3 ] ],
+ [ 2, '=', [ 'k6' ], 1, 0, '+', [ 12 ] ],
+ [ 2, '=', [ 'k7' ], 1, 0, '+', [ -11 ] ],
+ [ 2, '=', [ 'k8' ], 1, 0, '+', [ -15 ] ],
+);
+
+exec_multi(
+ "VAL",
+ [ 1, '=', [ 'k5' ], 1, 0 ],
+ [ 1, '=', [ 'k6' ], 1, 0 ],
+ [ 1, '=', [ 'k7' ], 1, 0 ],
+ [ 1, '=', [ 'k8' ], 1, 0 ],
+);
+# 8, 18, -4, -7
+
+exec_multi(
+ "DECREMENT",
+ [ 2, '=', [ 'k5' ], 1, 0, '-', [ 2 ] ],
+ [ 2, '=', [ 'k6' ], 1, 0, '-', [ 24 ] ],
+ [ 2, '=', [ 'k7' ], 1, 0, '-', [ 80 ] ],
+ [ 2, '=', [ 'k8' ], 1, 0, '-', [ -80 ] ],
+);
+# mod, no, mod, no
+
+exec_multi(
+ "VAL",
+ [ 1, '=', [ 'k5' ], 1, 0 ],
+ [ 1, '=', [ 'k6' ], 1, 0 ],
+ [ 1, '=', [ 'k7' ], 1, 0 ],
+ [ 1, '=', [ 'k8' ], 1, 0 ],
+);
+# 6, 18, -84, -7
+
+exec_multi(
+ "INCREMENT",
+ [ 2, '=', [ 'k5' ], 1, 0, '+?', [ 1 ] ],
+ [ 2, '=', [ 'k5' ], 1, 0, '+?', [ 1 ] ],
+ [ 2, '=', [ 'k5' ], 1, 0, '+?', [ 1 ] ],
+ [ 2, '=', [ 'k5' ], 1, 0, '+?', [ 1 ] ],
+ [ 2, '=', [ 'k5' ], 1, 0, '+?', [ 1 ] ],
+ [ 2, '=', [ 'k5' ], 1, 0, '+?', [ 1 ] ],
+ [ 2, '=', [ 'k5' ], 1, 0, '+?', [ 1 ] ],
+ [ 2, '=', [ 'k5' ], 1, 0, '+?', [ 1 ] ],
+ [ 2, '=', [ 'k5' ], 1, 0, '+?', [ 1 ] ],
+);
+
+exec_multi(
+ "VAL",
+ [ 1, '=', [ 'k5' ], 1, 0 ],
+);
+# 15
+
+sub exec_multi {
+ my $mess = shift(@_);
+ print "$mess\n";
+ my $mres = $hs->execute_multi(\@_);
+ for my $res (@$mres) {
+ for my $fld (@$res) {
+ print "[$fld]";
+ }
+ print "\n";
+ }
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test12.expected b/plugin/handler_socket/regtest/test_01_lib/test12.expected
new file mode 100644
index 00000000000..96002e798b1
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test12.expected
@@ -0,0 +1,273 @@
+VAL
+code=0
+[k1_0][k2_0][0][0]
+[k1_0][k2_1][1][0]
+[k1_0][k2_2][2][0]
+[k1_0][k2_3][3][0]
+[k1_0][k2_4][4][0]
+[k1_0][k2_5][5][0]
+[k1_0][k2_6][6][0]
+[k1_0][k2_7][7][0]
+[k1_0][k2_8][8][0]
+[k1_0][k2_9][9][0]
+[k1_1][k2_0][1][0]
+[k1_1][k2_1][2][1]
+[k1_1][k2_2][3][2]
+[k1_1][k2_3][4][3]
+[k1_1][k2_4][5][4]
+[k1_1][k2_5][6][5]
+[k1_1][k2_6][7][6]
+[k1_1][k2_7][8][7]
+[k1_1][k2_8][9][8]
+[k1_1][k2_9][10][9]
+[k1_2][k2_0][2][0]
+[k1_2][k2_1][3][2]
+[k1_2][k2_2][4][4]
+[k1_2][k2_3][5][6]
+[k1_2][k2_4][6][8]
+[k1_2][k2_5][7][10]
+[k1_2][k2_6][8][12]
+[k1_2][k2_7][9][14]
+[k1_2][k2_8][10][16]
+[k1_2][k2_9][11][18]
+[k1_3][k2_0][3][0]
+[k1_3][k2_1][4][3]
+[k1_3][k2_2][5][6]
+[k1_3][k2_3][6][9]
+[k1_3][k2_4][7][12]
+[k1_3][k2_5][8][15]
+[k1_3][k2_6][9][18]
+[k1_3][k2_7][10][21]
+[k1_3][k2_8][11][24]
+[k1_3][k2_9][12][27]
+[k1_4][k2_0][4][0]
+[k1_4][k2_1][5][4]
+[k1_4][k2_2][6][8]
+[k1_4][k2_3][7][12]
+[k1_4][k2_4][8][16]
+[k1_4][k2_5][9][20]
+[k1_4][k2_6][10][24]
+[k1_4][k2_7][11][28]
+[k1_4][k2_8][12][32]
+[k1_4][k2_9][13][36]
+[k1_5][k2_0][5][0]
+[k1_5][k2_1][6][5]
+[k1_5][k2_2][7][10]
+[k1_5][k2_3][8][15]
+[k1_5][k2_4][9][20]
+[k1_5][k2_5][10][25]
+[k1_5][k2_6][11][30]
+[k1_5][k2_7][12][35]
+[k1_5][k2_8][13][40]
+[k1_5][k2_9][14][45]
+[k1_6][k2_0][6][0]
+[k1_6][k2_1][7][6]
+[k1_6][k2_2][8][12]
+[k1_6][k2_3][9][18]
+[k1_6][k2_4][10][24]
+[k1_6][k2_5][11][30]
+[k1_6][k2_6][12][36]
+[k1_6][k2_7][13][42]
+[k1_6][k2_8][14][48]
+[k1_6][k2_9][15][54]
+[k1_7][k2_0][7][0]
+[k1_7][k2_1][8][7]
+[k1_7][k2_2][9][14]
+[k1_7][k2_3][10][21]
+[k1_7][k2_4][11][28]
+[k1_7][k2_5][12][35]
+[k1_7][k2_6][13][42]
+[k1_7][k2_7][14][49]
+[k1_7][k2_8][15][56]
+[k1_7][k2_9][16][63]
+[k1_8][k2_0][8][0]
+[k1_8][k2_1][9][8]
+[k1_8][k2_2][10][16]
+[k1_8][k2_3][11][24]
+[k1_8][k2_4][12][32]
+[k1_8][k2_5][13][40]
+[k1_8][k2_6][14][48]
+[k1_8][k2_7][15][56]
+[k1_8][k2_8][16][64]
+[k1_8][k2_9][17][72]
+[k1_9][k2_0][9][0]
+[k1_9][k2_1][10][9]
+[k1_9][k2_2][11][18]
+[k1_9][k2_3][12][27]
+[k1_9][k2_4][13][36]
+[k1_9][k2_5][14][45]
+[k1_9][k2_6][15][54]
+[k1_9][k2_7][16][63]
+[k1_9][k2_8][17][72]
+[k1_9][k2_9][18][81]
+
+FILTER
+code=0
+[k1_0][k2_5][5][0]
+[k1_1][k2_5][6][5]
+[k1_2][k2_5][7][10]
+[k1_3][k2_5][8][15]
+[k1_4][k2_5][9][20]
+[k1_5][k2_5][10][25]
+[k1_6][k2_5][11][30]
+[k1_7][k2_5][12][35]
+[k1_8][k2_5][13][40]
+[k1_9][k2_5][14][45]
+
+FILTER
+code=0
+[k1_0][k2_5][5][0]
+[k1_1][k2_5][6][5]
+[k1_2][k2_5][7][10]
+[k1_3][k2_5][8][15]
+[k1_4][k2_5][9][20]
+[k1_5][k2_5][10][25]
+[k1_6][k2_5][11][30]
+[k1_7][k2_5][12][35]
+[k1_8][k2_5][13][40]
+[k1_9][k2_5][14][45]
+
+FILTER
+code=0
+[k1_0][k2_3][3][0]
+[k1_1][k2_2][3][2]
+[k1_2][k2_1][3][2]
+[k1_3][k2_0][3][0]
+
+FILTER
+code=0
+[k1_1][k2_0][1][0]
+[k1_1][k2_1][2][1]
+[k1_1][k2_2][3][2]
+[k1_1][k2_3][4][3]
+[k1_1][k2_4][5][4]
+[k1_1][k2_5][6][5]
+[k1_1][k2_6][7][6]
+[k1_1][k2_7][8][7]
+[k1_1][k2_8][9][8]
+[k1_1][k2_9][10][9]
+[k1_2][k2_0][2][0]
+[k1_2][k2_1][3][2]
+[k1_2][k2_2][4][4]
+[k1_2][k2_3][5][6]
+[k1_2][k2_4][6][8]
+[k1_2][k2_5][7][10]
+[k1_2][k2_6][8][12]
+[k1_2][k2_7][9][14]
+[k1_2][k2_8][10][16]
+[k1_2][k2_9][11][18]
+
+FILTER
+code=0
+[k1_2][k2_5][7][10]
+[k1_2][k2_6][8][12]
+[k1_2][k2_7][9][14]
+[k1_2][k2_8][10][16]
+[k1_2][k2_9][11][18]
+
+FILTER
+code=0
+[2]
+VAL
+code=0
+[k1_0][k2_0][0][0]
+[k1_0][k2_1][1][0]
+[k1_0][k2_2][2][0]
+[k1_0][k2_3][3][0]
+[k1_0][k2_4][4][0]
+[k1_0][k2_5][5][0]
+[k1_0][k2_6][6][0]
+[k1_0][k2_7][7][0]
+[k1_0][k2_8][8][0]
+[k1_0][k2_9][9][0]
+[k1_1][k2_0][1][0]
+[k1_1][k2_1][2][1]
+[k1_1][k2_2][3][2]
+[k1_1][k2_3][4][3]
+[k1_1][k2_4][5][4]
+[k1_1][k2_5][6][5]
+[k1_1][k2_6][7][6]
+[k1_1][k2_7][8][7]
+[k1_1][k2_8][9][8]
+[k1_1][k2_9][10][9]
+[k1_2][k2_0][2][0]
+[k1_2][k2_1][3][2]
+[k1_2][k2_2][4][4]
+[k1_2][k2_3][5][6]
+[k1_2][k2_4][6][8]
+[k1_2][k2_5][-1][10]
+[k1_2][k2_6][8][12]
+[k1_2][k2_7][9][14]
+[k1_2][k2_8][10][16]
+[k1_2][k2_9][11][18]
+[k1_3][k2_0][3][0]
+[k1_3][k2_1][4][3]
+[k1_3][k2_2][5][6]
+[k1_3][k2_3][6][9]
+[k1_3][k2_4][7][12]
+[k1_3][k2_5][8][15]
+[k1_3][k2_6][9][18]
+[k1_3][k2_7][10][21]
+[k1_3][k2_8][11][24]
+[k1_3][k2_9][12][27]
+[k1_4][k2_0][4][0]
+[k1_4][k2_1][5][4]
+[k1_4][k2_2][6][8]
+[k1_4][k2_3][7][12]
+[k1_4][k2_4][8][16]
+[k1_4][k2_5][9][20]
+[k1_4][k2_6][10][24]
+[k1_4][k2_7][11][28]
+[k1_4][k2_8][12][32]
+[k1_4][k2_9][13][36]
+[k1_5][k2_0][5][0]
+[k1_5][k2_1][6][5]
+[k1_5][k2_2][-1][10]
+[k1_5][k2_3][8][15]
+[k1_5][k2_4][9][20]
+[k1_5][k2_5][10][25]
+[k1_5][k2_6][11][30]
+[k1_5][k2_7][12][35]
+[k1_5][k2_8][13][40]
+[k1_5][k2_9][14][45]
+[k1_6][k2_0][6][0]
+[k1_6][k2_1][7][6]
+[k1_6][k2_2][8][12]
+[k1_6][k2_3][9][18]
+[k1_6][k2_4][10][24]
+[k1_6][k2_5][11][30]
+[k1_6][k2_6][12][36]
+[k1_6][k2_7][13][42]
+[k1_6][k2_8][14][48]
+[k1_6][k2_9][15][54]
+[k1_7][k2_0][7][0]
+[k1_7][k2_1][8][7]
+[k1_7][k2_2][9][14]
+[k1_7][k2_3][10][21]
+[k1_7][k2_4][11][28]
+[k1_7][k2_5][12][35]
+[k1_7][k2_6][13][42]
+[k1_7][k2_7][14][49]
+[k1_7][k2_8][15][56]
+[k1_7][k2_9][16][63]
+[k1_8][k2_0][8][0]
+[k1_8][k2_1][9][8]
+[k1_8][k2_2][10][16]
+[k1_8][k2_3][11][24]
+[k1_8][k2_4][12][32]
+[k1_8][k2_5][13][40]
+[k1_8][k2_6][14][48]
+[k1_8][k2_7][15][56]
+[k1_8][k2_8][16][64]
+[k1_8][k2_9][17][72]
+[k1_9][k2_0][9][0]
+[k1_9][k2_1][10][9]
+[k1_9][k2_2][11][18]
+[k1_9][k2_3][12][27]
+[k1_9][k2_4][13][36]
+[k1_9][k2_5][14][45]
+[k1_9][k2_6][15][54]
+[k1_9][k2_7][16][63]
+[k1_9][k2_8][17][72]
+[k1_9][k2_9][18][81]
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test12.pl b/plugin/handler_socket/regtest/test_01_lib/test12.pl
new file mode 100644
index 00000000000..100a779de4e
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test12.pl
@@ -0,0 +1,134 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for filters
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 10;
+$dbh->do(
+ "create table $table " .
+ "(k1 varchar(30) not null, k2 varchar(30) not null, " .
+ "v1 int not null, v2 int not null, " .
+ "primary key (k1, k2) ) engine = innodb");
+srand(999);
+
+my $sth = $dbh->prepare("insert into $table values (?,?,?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ for (my $j = 0; $j < $tablesize; ++$j) {
+ my $k1 = "k1_" . $i;
+ my $k2 = "k2_" . $j;
+ my $v1 = $i + $j;
+ my $v2 = $i * $j;
+ $sth->execute($k1, $k2, $v1, $v2);
+ }
+}
+
+my $hs = hstest::get_hs_connection(undef, 9999);
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k1,k2,v1,v2', 'k2');
+$hs->open_index(2, $dbname, $table, '', 'k1,k2,v1,v2', 'k1,k2,v1,v2');
+$hs->open_index(3, $dbname, $table, '', 'v1', 'k1,v2');
+
+exec_multi(
+ 4, "VAL",
+ [ 1, '>=', [ '', '' ], 1000, 0 ],
+);
+# all
+
+# select k1, k2, v1, v2 ... where (k1, k2) >= ('', '') and k2 = 'k2_5'
+exec_single(
+ 4, "FILTER",
+ [ 1, '>=', [ '', '' ], 1000, 0, undef, undef, [ [ 'F', '=', 0, 'k2_5' ] ] ]
+);
+
+# same as above
+exec_multi(
+ 4, "FILTER",
+ [ 1, '>=', [ '', '' ], 1000, 0, undef, undef, [ [ 'F', '=', 0, 'k2_5' ] ] ],
+);
+
+# select k1, k2, v1, v2 ... where (k1, k2) >= ('', '') and v1 = 3
+exec_multi(
+ 4, "FILTER",
+ [ 2, '>=', [ '', '' ], 1000, 0, undef, undef, [ [ 'F', '=', 2, 3 ] ] ],
+);
+
+# select k1, k2, v1, v2 ... where (k1, k2) >= ('k1_1', '') and k1 <= 'k1_2'
+exec_multi(
+ 4, "FILTER",
+ [ 2, '>=', [ 'k1_1', '' ], 1000, 0, undef, undef,
+ [ [ 'W', '<=', 0, 'k1_2' ] ] ],
+);
+
+# select k1, k2, v1, v2 ... where (k1, k2) >= ('k1_1', '') and k1 <= 'k1_2'
+# and v2 >= 10
+exec_multi(
+ 4, "FILTER",
+ [ 2, '>=', [ 'k1_1', '' ], 1000, 0, undef, undef,
+ [ [ 'W', '<=', 0, 'k1_2' ], [ 'F', '>=', 3, 10 ] ] ],
+);
+
+# update ... set v2 = -1 where (k1, k2) >= ('k1_3', '') and v2 = 10
+exec_multi(
+ 4, "FILTER",
+ [ 3, '>=', [ 'k1_1', '' ], 1000, 0, 'U', [ -1 ],
+ [ [ 'F', '=', 1, 10 ] ] ],
+);
+
+exec_multi(
+ 4, "VAL",
+ [ 1, '>=', [ '', '' ], 1000, 0 ],
+);
+# all
+
+exit 0;
+
+sub exec_single {
+ my ($width, $mess, $req) = @_;
+ print "$mess\n";
+ my $res = $hs->execute_single(@$req);
+ {
+ my $code = shift(@$res);
+ print "code=$code\n";
+ my $i = 0;
+ for my $fld (@$res) {
+ print "[$fld]";
+ if (++$i >= $width) {
+ print "\n";
+ $i = 0;
+ }
+ }
+ print "\n";
+ }
+}
+
+sub exec_multi {
+ my $width = shift(@_);
+ my $mess = shift(@_);
+ print "$mess\n";
+ my $mres = $hs->execute_multi(\@_);
+ for my $res (@$mres) {
+ my $code = shift(@$res);
+ print "code=$code\n";
+ my $i = 0;
+ for my $fld (@$res) {
+ print "[$fld]";
+ if (++$i >= $width) {
+ print "\n";
+ $i = 0;
+ }
+ }
+ print "\n";
+ }
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test13.expected b/plugin/handler_socket/regtest/test_01_lib/test13.expected
new file mode 100644
index 00000000000..3330382ebf6
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test13.expected
@@ -0,0 +1,92 @@
+HSINSERT
+11 v1hs_0
+12 v1hs_1
+13 v1hs_2
+14 v1hs_3
+15 v1hs_4
+16 v1hs_5
+17 v1hs_6
+18 v1hs_7
+19 v1hs_8
+20 v1hs_9
+21 v1hs3_0
+22 v1hs3_0
+23 v1hs3_0
+24 v1hs3_1
+25 v1hs3_1
+26 v1hs3_1
+27 v1hs3_2
+28 v1hs3_2
+29 v1hs3_2
+30 v1hs3_3
+31 v1hs3_3
+32 v1hs3_3
+33 v1hs3_4
+34 v1hs3_4
+35 v1hs3_4
+36 v1hs3_5
+37 v1hs3_5
+38 v1hs3_5
+39 v1hs3_6
+40 v1hs3_6
+41 v1hs3_6
+42 v1hs3_7
+43 v1hs3_7
+44 v1hs3_7
+45 v1hs3_8
+46 v1hs3_8
+47 v1hs3_8
+48 v1hs3_9
+49 v1hs3_9
+50 v1hs3_9
+DUMP_TABLE
+1 v1sql_0 v2sql_0
+2 v1sql_1 v2sql_1
+3 v1sql_2 v2sql_2
+4 v1sql_3 v2sql_3
+5 v1sql_4 v2sql_4
+6 v1sql_5 v2sql_5
+7 v1sql_6 v2sql_6
+8 v1sql_7 v2sql_7
+9 v1sql_8 v2sql_8
+10 v1sql_9 v2sql_9
+11 v1hs_0 v2hs_0
+12 v1hs_1 v2hs_1
+13 v1hs_2 v2hs_2
+14 v1hs_3 v2hs_3
+15 v1hs_4 v2hs_4
+16 v1hs_5 v2hs_5
+17 v1hs_6 v2hs_6
+18 v1hs_7 v2hs_7
+19 v1hs_8 v2hs_8
+20 v1hs_9 v2hs_9
+21 v1hs3_0 v2hs3_0
+22 v1hs3_0 v2hs3_0
+23 v1hs3_0 v2hs3_0
+24 v1hs3_1 v2hs3_1
+25 v1hs3_1 v2hs3_1
+26 v1hs3_1 v2hs3_1
+27 v1hs3_2 v2hs3_2
+28 v1hs3_2 v2hs3_2
+29 v1hs3_2 v2hs3_2
+30 v1hs3_3 v2hs3_3
+31 v1hs3_3 v2hs3_3
+32 v1hs3_3 v2hs3_3
+33 v1hs3_4 v2hs3_4
+34 v1hs3_4 v2hs3_4
+35 v1hs3_4 v2hs3_4
+36 v1hs3_5 v2hs3_5
+37 v1hs3_5 v2hs3_5
+38 v1hs3_5 v2hs3_5
+39 v1hs3_6 v2hs3_6
+40 v1hs3_6 v2hs3_6
+41 v1hs3_6 v2hs3_6
+42 v1hs3_7 v2hs3_7
+43 v1hs3_7 v2hs3_7
+44 v1hs3_7 v2hs3_7
+45 v1hs3_8 v2hs3_8
+46 v1hs3_8 v2hs3_8
+47 v1hs3_8 v2hs3_8
+48 v1hs3_9 v2hs3_9
+49 v1hs3_9 v2hs3_9
+50 v1hs3_9 v2hs3_9
diff --git a/plugin/handler_socket/regtest/test_01_lib/test13.pl b/plugin/handler_socket/regtest/test_01_lib/test13.pl
new file mode 100644
index 00000000000..1e1104d2a07
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test13.pl
@@ -0,0 +1,92 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for auto_increment
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 10;
+$dbh->do(
+ "create table $table (" .
+ "k int primary key auto_increment, " .
+ "v1 varchar(30), " .
+ "v2 varchar(30)) " .
+ "engine = myisam default charset = binary");
+srand(999);
+
+my $sth = $dbh->prepare("insert into $table values (?,?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = 0;
+ my $v1 = "v1sql_" . $i;
+ my $v2 = "v2sql_" . $i;
+ $sth->execute($k, $v1, $v2);
+}
+
+my %valmap = ();
+
+print "HSINSERT\n";
+my $hs = hstest::get_hs_connection(undef, 9999);
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v1,v2');
+# inserts with auto_increment
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = 0;
+ my $v1 = "v1hs_" . $i;
+ my $v2 = "v2hs_" . $i;
+ my $r = $hs->execute_insert(1, [ $k, $v1, $v2 ]);
+ my $err = $r->[0];
+ if ($err != 0) {
+ my $err_str = $r->[1];
+ print "$err $err_str\n";
+ } else {
+ my $id = $r->[1];
+ print "$id $v1\n";
+ }
+}
+# make sure that it works even when inserts are pipelined. these requests
+# are possibly executed in a single transaction.
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = 0;
+ my $v1 = "v1hs3_" . $i;
+ my $v2 = "v2hs3_" . $i;
+ my $r = $hs->execute_multi([
+ [ 1, '+', [$k, $v1, $v2] ],
+ [ 1, '+', [$k, $v1, $v2] ],
+ [ 1, '+', [$k, $v1, $v2] ],
+ ]);
+ for (my $i = 0; $i < 3; ++$i) {
+ my $err = $r->[$i]->[0];
+ if ($err != 0) {
+ my $err_str = $r->[$i]->[1];
+ print "$err $err_str\n";
+ } else {
+ my $id = $r->[$i]->[1];
+ print "$id $v1\n";
+ }
+ }
+}
+undef $hs;
+
+dump_table();
+
+sub dump_table {
+ print "DUMP_TABLE\n";
+ my $aref = $dbh->selectall_arrayref("select k,v1,v2 from $table order by k");
+ for my $row (@$aref) {
+ my ($k, $v1, $v2) = @$row;
+ $v1 = "[null]" if !defined($v1);
+ $v2 = "[null]" if !defined($v2);
+ print "$k $v1 $v2\n";
+ # print "MISMATCH\n" if ($valmap{$k} ne $v);
+ }
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test14.expected b/plugin/handler_socket/regtest/test_01_lib/test14.expected
new file mode 100644
index 00000000000..00149dd9ac9
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test14.expected
@@ -0,0 +1,144 @@
+DUMP_TABLE
+0
+1 0 A
+2 01 AB
+3 012 ABC
+4 0123 ABCD
+5 01234 ABCDE
+6 012345 ABCDEF
+7 0123456 ABCDEFG
+8 01234567 ABCDEFGH
+9 012345678 ABCDEFGHI
+10 0123456789 ABCDEFGHIJ
+11 01234567890 ABCDEFGHIJA
+12 012345678901 ABCDEFGHIJAB
+13 0123456789012 ABCDEFGHIJABC
+14 01234567890123 ABCDEFGHIJABCD
+15 012345678901234 ABCDEFGHIJABCDE
+16 0123456789012345 ABCDEFGHIJABCDEF
+17 01234567890123456 ABCDEFGHIJABCDEFG
+18 012345678901234567 ABCDEFGHIJABCDEFGH
+19 0123456789012345678 ABCDEFGHIJABCDEFGHI
+20 01234567890123456789 ABCDEFGHIJABCDEFGHIJ
+21 012345678901234567890 ABCDEFGHIJABCDEFGHIJA
+22 0123456789012345678901 ABCDEFGHIJABCDEFGHIJAB
+23 01234567890123456789012 ABCDEFGHIJABCDEFGHIJABC
+24 012345678901234567890123 ABCDEFGHIJABCDEFGHIJABCD
+25 0123456789012345678901234 ABCDEFGHIJABCDEFGHIJABCDE
+26 01234567890123456789012345 ABCDEFGHIJABCDEFGHIJABCDEF
+27 012345678901234567890123456 ABCDEFGHIJABCDEFGHIJABCDEFG
+28 0123456789012345678901234567 ABCDEFGHIJABCDEFGHIJABCDEFGH
+29 01234567890123456789012345678 ABCDEFGHIJABCDEFGHIJABCDEFGHI
+30 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+31 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+32 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+33 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+34 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+35 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+36 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+37 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+38 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+39 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+40 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+41 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+42 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+43 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+44 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+45 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+46 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+47 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+48 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+49 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+PK 0
+I1 0
+I2 0
+PK 1 0 A
+I1 1 0 A
+I2 1 0 A
+PK 2 01 AB
+I1 2 01 AB
+I2 2 01 AB
+PK 3 012 ABC
+I1 3 012 ABC
+I2 3 012 ABC
+PK 4 0123 ABCD
+I1 4 0123 ABCD
+I2 4 0123 ABCD
+PK 5 01234 ABCDE
+I1 5 01234 ABCDE
+I2 5 01234 ABCDE
+PK 6 012345 ABCDEF
+I1 6 012345 ABCDEF
+I2 6 012345 ABCDEF
+PK 7 0123456 ABCDEFG
+I1 7 0123456 ABCDEFG
+I2 7 0123456 ABCDEFG
+PK 8 01234567 ABCDEFGH
+I1 8 01234567 ABCDEFGH
+I2 8 01234567 ABCDEFGH
+PK 9 012345678 ABCDEFGHI
+I1 9 012345678 ABCDEFGHI
+I2 9 012345678 ABCDEFGHI
+PK 10 0123456789 ABCDEFGHIJ
+I1 10 0123456789 ABCDEFGHIJ
+I2 10 0123456789 ABCDEFGHIJ
+PK 11 01234567890 ABCDEFGHIJA
+I1 11 01234567890 ABCDEFGHIJA
+I2 11 01234567890 ABCDEFGHIJA
+PK 12 012345678901 ABCDEFGHIJAB
+I1 12 012345678901 ABCDEFGHIJAB
+I2 12 012345678901 ABCDEFGHIJAB
+PK 13 0123456789012 ABCDEFGHIJABC
+I1 13 0123456789012 ABCDEFGHIJABC
+I2 13 0123456789012 ABCDEFGHIJABC
+PK 14 01234567890123 ABCDEFGHIJABCD
+I1 14 01234567890123 ABCDEFGHIJABCD
+I2 14 01234567890123 ABCDEFGHIJABCD
+PK 15 012345678901234 ABCDEFGHIJABCDE
+I1 15 012345678901234 ABCDEFGHIJABCDE
+I2 15 012345678901234 ABCDEFGHIJABCDE
+PK 16 0123456789012345 ABCDEFGHIJABCDEF
+I1 16 0123456789012345 ABCDEFGHIJABCDEF
+I2 16 0123456789012345 ABCDEFGHIJABCDEF
+PK 17 01234567890123456 ABCDEFGHIJABCDEFG
+I1 17 01234567890123456 ABCDEFGHIJABCDEFG
+I2 17 01234567890123456 ABCDEFGHIJABCDEFG
+PK 18 012345678901234567 ABCDEFGHIJABCDEFGH
+I1 18 012345678901234567 ABCDEFGHIJABCDEFGH
+I2 18 012345678901234567 ABCDEFGHIJABCDEFGH
+PK 19 0123456789012345678 ABCDEFGHIJABCDEFGHI
+I1 19 0123456789012345678 ABCDEFGHIJABCDEFGHI
+I2 19 0123456789012345678 ABCDEFGHIJABCDEFGHI
+PK 20 01234567890123456789 ABCDEFGHIJABCDEFGHIJ
+I1 20 01234567890123456789 ABCDEFGHIJABCDEFGHIJ
+I2 20 01234567890123456789 ABCDEFGHIJABCDEFGHIJ
+PK 21 012345678901234567890 ABCDEFGHIJABCDEFGHIJA
+I1 21 012345678901234567890 ABCDEFGHIJABCDEFGHIJA
+I2 21 012345678901234567890 ABCDEFGHIJABCDEFGHIJA
+PK 22 0123456789012345678901 ABCDEFGHIJABCDEFGHIJAB
+I1 22 0123456789012345678901 ABCDEFGHIJABCDEFGHIJAB
+I2 22 0123456789012345678901 ABCDEFGHIJABCDEFGHIJAB
+PK 23 01234567890123456789012 ABCDEFGHIJABCDEFGHIJABC
+I1 23 01234567890123456789012 ABCDEFGHIJABCDEFGHIJABC
+I2 23 01234567890123456789012 ABCDEFGHIJABCDEFGHIJABC
+PK 24 012345678901234567890123 ABCDEFGHIJABCDEFGHIJABCD
+I1 24 012345678901234567890123 ABCDEFGHIJABCDEFGHIJABCD
+I2 24 012345678901234567890123 ABCDEFGHIJABCDEFGHIJABCD
+PK 25 0123456789012345678901234 ABCDEFGHIJABCDEFGHIJABCDE
+I1 25 0123456789012345678901234 ABCDEFGHIJABCDEFGHIJABCDE
+I2 25 0123456789012345678901234 ABCDEFGHIJABCDEFGHIJABCDE
+PK 26 01234567890123456789012345 ABCDEFGHIJABCDEFGHIJABCDEF
+I1 26 01234567890123456789012345 ABCDEFGHIJABCDEFGHIJABCDEF
+I2 26 01234567890123456789012345 ABCDEFGHIJABCDEFGHIJABCDEF
+PK 27 012345678901234567890123456 ABCDEFGHIJABCDEFGHIJABCDEFG
+I1 27 012345678901234567890123456 ABCDEFGHIJABCDEFGHIJABCDEFG
+I2 27 012345678901234567890123456 ABCDEFGHIJABCDEFGHIJABCDEFG
+PK 28 0123456789012345678901234567 ABCDEFGHIJABCDEFGHIJABCDEFGH
+I1 28 0123456789012345678901234567 ABCDEFGHIJABCDEFGHIJABCDEFGH
+I2 28 0123456789012345678901234567 ABCDEFGHIJABCDEFGHIJABCDEFGH
+PK 29 01234567890123456789012345678 ABCDEFGHIJABCDEFGHIJABCDEFGHI
+I1 29 01234567890123456789012345678 ABCDEFGHIJABCDEFGHIJABCDEFGHI
+I2 29 01234567890123456789012345678 ABCDEFGHIJABCDEFGHIJABCDEFGHI
+PK 30 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+I1 30 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
+I2 30 012345678901234567890123456789 ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
diff --git a/plugin/handler_socket/regtest/test_01_lib/test14.pl b/plugin/handler_socket/regtest/test_01_lib/test14.pl
new file mode 100644
index 00000000000..68ce87bdd63
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test14.pl
@@ -0,0 +1,80 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for bugfix: commit/c88efe637f6a184b55d2bd8d060bda3e556572d8
+# (some trailing bytes were dropped for varlen or nullable key fields)
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 50;
+$dbh->do(
+ "create table $table (" .
+ "k int primary key, " .
+ "v1 varchar(30), " .
+ "v2 varchar(30), " .
+ "index i1(v1), index i2(v2, v1)) " .
+ "engine = myisam default charset = binary");
+srand(999);
+
+my %valmap = ();
+
+my $sth = $dbh->prepare("insert into $table values (?,?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = $i;
+ my ($s1, $s2) = ("", "");
+ for (my $j = 0; $j < $i; ++$j) {
+ $s1 .= chr(48 + $j % 10);
+ $s2 .= chr(65 + $j % 10);
+ }
+ my $v1 = $s1;
+ my $v2 = $s2;
+ $sth->execute($k, $v1, $v2);
+ $valmap{$k} = [ $v1, $v2 ];
+}
+
+dump_table();
+
+my $hs = hstest::get_hs_connection(undef, 9999);
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v1,v2');
+$hs->open_index(2, $dbname, $table, 'i1', 'k,v1,v2');
+$hs->open_index(3, $dbname, $table, 'i2', 'k,v1,v2');
+
+for (my $i = 0; $i <= 30; ++$i) {
+ my ($v1, $v2) = @{$valmap{$i}};
+ my ($rk, $rv1, $rv2);
+ my $r = $hs->execute_single(1, '=', [ $i ], 1, 0);
+ shift(@$r);
+ ($rk, $rv1, $rv2) = @$r;
+ print "PK $rk $rv1 $rv2\n";
+ $r = $hs->execute_single(2, '=', [ $v1 ], 1, 0);
+ shift(@$r);
+ ($rk, $rv1, $rv2) = @$r;
+ print "I1 $rk $rv1 $rv2\n";
+ $r = $hs->execute_single(3, '=', [ $v2, $v1 ], 1, 0);
+ shift(@$r);
+ ($rk, $rv1, $rv2) = @$r;
+ print "I2 $rk $rv1 $rv2\n";
+}
+
+sub dump_table {
+ print "DUMP_TABLE\n";
+ my $aref = $dbh->selectall_arrayref("select k,v1,v2 from $table order by k");
+ for my $row (@$aref) {
+ my ($k, $v1, $v2) = @$row;
+ $v1 = "[null]" if !defined($v1);
+ $v2 = "[null]" if !defined($v2);
+ print "$k $v1 $v2\n";
+ # print "MISMATCH\n" if ($valmap{$k} ne $v);
+ }
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test15.expected b/plugin/handler_socket/regtest/test_01_lib/test15.expected
new file mode 100644
index 00000000000..ea15afef5d8
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test15.expected
@@ -0,0 +1,764 @@
+TYPE TINYINT
+DUMP_TABLE_BEGIN
+-128 s-128 -128
+-42 s-42 -42
+-14 s-14 -14
+-4 s-4 -4
+-1 s-1 -1
+0 s0 0
+1 s1 1
+4 s4 4
+14 s14 14
+42 s42 42
+127 s127 127
+DUMP_TABLE_END
+PK[-128] -128 s-128 -128
+I1[s-128] -128 s-128 -128
+I2[-128, s-128] -128 s-128 -128
+I2p[-128] -128 s-128 -128
+PK[-42] -42 s-42 -42
+I1[s-42] -42 s-42 -42
+I2[-42, s-42] -42 s-42 -42
+I2p[-42] -42 s-42 -42
+PK[-14] -14 s-14 -14
+I1[s-14] -14 s-14 -14
+I2[-14, s-14] -14 s-14 -14
+I2p[-14] -14 s-14 -14
+PK[-4] -4 s-4 -4
+I1[s-4] -4 s-4 -4
+I2[-4, s-4] -4 s-4 -4
+I2p[-4] -4 s-4 -4
+PK[-1] -1 s-1 -1
+I1[s-1] -1 s-1 -1
+I2[-1, s-1] -1 s-1 -1
+I2p[-1] -1 s-1 -1
+PK[-1] -1 s-1 -1
+I1[s-1] -1 s-1 -1
+I2[-1, s-1] -1 s-1 -1
+I2p[-1] -1 s-1 -1
+PK[0] 0 s0 0
+I1[s0] 0 s0 0
+I2[0, s0] 0 s0 0
+I2p[0] 0 s0 0
+PK[0] 0 s0 0
+I1[s0] 0 s0 0
+I2[0, s0] 0 s0 0
+I2p[0] 0 s0 0
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[4] 4 s4 4
+I1[s4] 4 s4 4
+I2[4, s4] 4 s4 4
+I2p[4] 4 s4 4
+PK[14] 14 s14 14
+I1[s14] 14 s14 14
+I2[14, s14] 14 s14 14
+I2p[14] 14 s14 14
+PK[42] 42 s42 42
+I1[s42] 42 s42 42
+I2[42, s42] 42 s42 42
+I2p[42] 42 s42 42
+PK[127] 127 s127 127
+I1[s127] 127 s127 127
+I2[127, s127] 127 s127 127
+I2p[127] 127 s127 127
+
+TYPE TINYINT UNSIGNED
+DUMP_TABLE_BEGIN
+0 s0 0
+1 s1 1
+3 s3 3
+9 s9 9
+28 s28 28
+85 s85 85
+255 s255 255
+DUMP_TABLE_END
+PK[0] 0 s0 0
+I1[s0] 0 s0 0
+I2[0, s0] 0 s0 0
+I2p[0] 0 s0 0
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[3] 3 s3 3
+I1[s3] 3 s3 3
+I2[3, s3] 3 s3 3
+I2p[3] 3 s3 3
+PK[9] 9 s9 9
+I1[s9] 9 s9 9
+I2[9, s9] 9 s9 9
+I2p[9] 9 s9 9
+PK[28] 28 s28 28
+I1[s28] 28 s28 28
+I2[28, s28] 28 s28 28
+I2p[28] 28 s28 28
+PK[85] 85 s85 85
+I1[s85] 85 s85 85
+I2[85, s85] 85 s85 85
+I2p[85] 85 s85 85
+PK[255] 255 s255 255
+I1[s255] 255 s255 255
+I2[255, s255] 255 s255 255
+I2p[255] 255 s255 255
+
+TYPE SMALLINT
+DUMP_TABLE_BEGIN
+-32768 s-32768 -32768
+-10922 s-10922 -10922
+-3640 s-3640 -3640
+-1213 s-1213 -1213
+-404 s-404 -404
+-134 s-134 -134
+-1 s-1 -1
+0 s0 0
+1 s1 1
+134 s134 134
+404 s404 404
+1213 s1213 1213
+3640 s3640 3640
+10922 s10922 10922
+32767 s32768 32767
+DUMP_TABLE_END
+PK[-32768] -32768 s-32768 -32768
+I1[s-32768] -32768 s-32768 -32768
+I2[-32768, s-32768] -32768 s-32768 -32768
+I2p[-32768] -32768 s-32768 -32768
+PK[-10922] -10922 s-10922 -10922
+I1[s-10922] -10922 s-10922 -10922
+I2[-10922, s-10922] -10922 s-10922 -10922
+I2p[-10922] -10922 s-10922 -10922
+PK[-3640] -3640 s-3640 -3640
+I1[s-3640] -3640 s-3640 -3640
+I2[-3640, s-3640] -3640 s-3640 -3640
+I2p[-3640] -3640 s-3640 -3640
+PK[-1213] -1213 s-1213 -1213
+I1[s-1213] -1213 s-1213 -1213
+I2[-1213, s-1213] -1213 s-1213 -1213
+I2p[-1213] -1213 s-1213 -1213
+PK[-404] -404 s-404 -404
+I1[s-404] -404 s-404 -404
+I2[-404, s-404] -404 s-404 -404
+I2p[-404] -404 s-404 -404
+PK[-134] -134 s-134 -134
+I1[s-134] -134 s-134 -134
+I2[-134, s-134] -134 s-134 -134
+I2p[-134] -134 s-134 -134
+PK[-1] -1 s-1 -1
+I1[s-1] -1 s-1 -1
+I2[-1, s-1] -1 s-1 -1
+I2p[-1] -1 s-1 -1
+PK[0] 0 s0 0
+I1[s0] 0 s0 0
+I2[0, s0] 0 s0 0
+I2p[0] 0 s0 0
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[134] 134 s134 134
+I1[s134] 134 s134 134
+I2[134, s134] 134 s134 134
+I2p[134] 134 s134 134
+PK[404] 404 s404 404
+I1[s404] 404 s404 404
+I2[404, s404] 404 s404 404
+I2p[404] 404 s404 404
+PK[1213] 1213 s1213 1213
+I1[s1213] 1213 s1213 1213
+I2[1213, s1213] 1213 s1213 1213
+I2p[1213] 1213 s1213 1213
+PK[3640] 3640 s3640 3640
+I1[s3640] 3640 s3640 3640
+I2[3640, s3640] 3640 s3640 3640
+I2p[3640] 3640 s3640 3640
+PK[10922] 10922 s10922 10922
+I1[s10922] 10922 s10922 10922
+I2[10922, s10922] 10922 s10922 10922
+I2p[10922] 10922 s10922 10922
+PK[32768] 32767 s32768 32767
+I1[s32768] 32767 s32768 32767
+I2[32768, s32768] 32767 s32768 32767
+I2p[32768] 32767 s32768 32767
+
+TYPE SMALLINT UNSIGNED
+DUMP_TABLE_BEGIN
+0 s0 0
+1 s1 1
+269 s269 269
+809 s809 809
+2427 s2427 2427
+7281 s7281 7281
+21845 s21845 21845
+65535 s65535 65535
+DUMP_TABLE_END
+PK[0] 0 s0 0
+I1[s0] 0 s0 0
+I2[0, s0] 0 s0 0
+I2p[0] 0 s0 0
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[269] 269 s269 269
+I1[s269] 269 s269 269
+I2[269, s269] 269 s269 269
+I2p[269] 269 s269 269
+PK[809] 809 s809 809
+I1[s809] 809 s809 809
+I2[809, s809] 809 s809 809
+I2p[809] 809 s809 809
+PK[2427] 2427 s2427 2427
+I1[s2427] 2427 s2427 2427
+I2[2427, s2427] 2427 s2427 2427
+I2p[2427] 2427 s2427 2427
+PK[7281] 7281 s7281 7281
+I1[s7281] 7281 s7281 7281
+I2[7281, s7281] 7281 s7281 7281
+I2p[7281] 7281 s7281 7281
+PK[21845] 21845 s21845 21845
+I1[s21845] 21845 s21845 21845
+I2[21845, s21845] 21845 s21845 21845
+I2p[21845] 21845 s21845 21845
+PK[65535] 65535 s65535 65535
+I1[s65535] 65535 s65535 65535
+I2[65535, s65535] 65535 s65535 65535
+I2p[65535] 65535 s65535 65535
+
+TYPE MEDIUMINT
+DUMP_TABLE_BEGIN
+-8388608 s-8388608 -8388608
+-2796202 s-2796202 -2796202
+-932067 s-932067 -932067
+-310689 s-310689 -310689
+-103563 s-103563 -103563
+-34521 s-34521 -34521
+-1 s-1 -1
+0 s0 0
+1 s1 1
+34521 s34521 34521
+103563 s103563 103563
+310689 s310689 310689
+932067 s932067 932067
+2796202 s2796202 2796202
+8388607 s8388607 8388607
+DUMP_TABLE_END
+PK[-8388608] -8388608 s-8388608 -8388608
+I1[s-8388608] -8388608 s-8388608 -8388608
+I2[-8388608, s-8388608] -8388608 s-8388608 -8388608
+I2p[-8388608] -8388608 s-8388608 -8388608
+PK[-2796202] -2796202 s-2796202 -2796202
+I1[s-2796202] -2796202 s-2796202 -2796202
+I2[-2796202, s-2796202] -2796202 s-2796202 -2796202
+I2p[-2796202] -2796202 s-2796202 -2796202
+PK[-932067] -932067 s-932067 -932067
+I1[s-932067] -932067 s-932067 -932067
+I2[-932067, s-932067] -932067 s-932067 -932067
+I2p[-932067] -932067 s-932067 -932067
+PK[-310689] -310689 s-310689 -310689
+I1[s-310689] -310689 s-310689 -310689
+I2[-310689, s-310689] -310689 s-310689 -310689
+I2p[-310689] -310689 s-310689 -310689
+PK[-103563] -103563 s-103563 -103563
+I1[s-103563] -103563 s-103563 -103563
+I2[-103563, s-103563] -103563 s-103563 -103563
+I2p[-103563] -103563 s-103563 -103563
+PK[-34521] -34521 s-34521 -34521
+I1[s-34521] -34521 s-34521 -34521
+I2[-34521, s-34521] -34521 s-34521 -34521
+I2p[-34521] -34521 s-34521 -34521
+PK[-1] -1 s-1 -1
+I1[s-1] -1 s-1 -1
+I2[-1, s-1] -1 s-1 -1
+I2p[-1] -1 s-1 -1
+PK[0] 0 s0 0
+I1[s0] 0 s0 0
+I2[0, s0] 0 s0 0
+I2p[0] 0 s0 0
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[34521] 34521 s34521 34521
+I1[s34521] 34521 s34521 34521
+I2[34521, s34521] 34521 s34521 34521
+I2p[34521] 34521 s34521 34521
+PK[103563] 103563 s103563 103563
+I1[s103563] 103563 s103563 103563
+I2[103563, s103563] 103563 s103563 103563
+I2p[103563] 103563 s103563 103563
+PK[310689] 310689 s310689 310689
+I1[s310689] 310689 s310689 310689
+I2[310689, s310689] 310689 s310689 310689
+I2p[310689] 310689 s310689 310689
+PK[932067] 932067 s932067 932067
+I1[s932067] 932067 s932067 932067
+I2[932067, s932067] 932067 s932067 932067
+I2p[932067] 932067 s932067 932067
+PK[2796202] 2796202 s2796202 2796202
+I1[s2796202] 2796202 s2796202 2796202
+I2[2796202, s2796202] 2796202 s2796202 2796202
+I2p[2796202] 2796202 s2796202 2796202
+PK[8388607] 8388607 s8388607 8388607
+I1[s8388607] 8388607 s8388607 8388607
+I2[8388607, s8388607] 8388607 s8388607 8388607
+I2p[8388607] 8388607 s8388607 8388607
+
+TYPE MEDIUMINT UNSIGNED
+DUMP_TABLE_BEGIN
+0 s0 0
+1 s1 1
+69042 s69042 69042
+207126 s207126 207126
+621378 s621378 621378
+1864135 s1864135 1864135
+5592405 s5592405 5592405
+16777215 s16777215 16777215
+DUMP_TABLE_END
+PK[0] 0 s0 0
+I1[s0] 0 s0 0
+I2[0, s0] 0 s0 0
+I2p[0] 0 s0 0
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[69042] 69042 s69042 69042
+I1[s69042] 69042 s69042 69042
+I2[69042, s69042] 69042 s69042 69042
+I2p[69042] 69042 s69042 69042
+PK[207126] 207126 s207126 207126
+I1[s207126] 207126 s207126 207126
+I2[207126, s207126] 207126 s207126 207126
+I2p[207126] 207126 s207126 207126
+PK[621378] 621378 s621378 621378
+I1[s621378] 621378 s621378 621378
+I2[621378, s621378] 621378 s621378 621378
+I2p[621378] 621378 s621378 621378
+PK[1864135] 1864135 s1864135 1864135
+I1[s1864135] 1864135 s1864135 1864135
+I2[1864135, s1864135] 1864135 s1864135 1864135
+I2p[1864135] 1864135 s1864135 1864135
+PK[5592405] 5592405 s5592405 5592405
+I1[s5592405] 5592405 s5592405 5592405
+I2[5592405, s5592405] 5592405 s5592405 5592405
+I2p[5592405] 5592405 s5592405 5592405
+PK[16777215] 16777215 s16777215 16777215
+I1[s16777215] 16777215 s16777215 16777215
+I2[16777215, s16777215] 16777215 s16777215 16777215
+I2p[16777215] 16777215 s16777215 16777215
+
+TYPE INT
+DUMP_TABLE_BEGIN
+-2147483648 s-2147483648 -2147483648
+-715827882 s-715827882 -715827882
+-238609294 s-238609294 -238609294
+-79536431 s-79536431 -79536431
+-26512143 s-26512143 -26512143
+-8837381 s-8837381 -8837381
+-1 s-1 -1
+0 s0 0
+1 s1 1
+8837381 s8837381 8837381
+26512143 s26512143 26512143
+79536431 s79536431 79536431
+238609294 s238609294 238609294
+715827882 s715827882 715827882
+2147483647 s2147483647 2147483647
+DUMP_TABLE_END
+PK[-2147483648] -2147483648 s-2147483648 -2147483648
+I1[s-2147483648] -2147483648 s-2147483648 -2147483648
+I2[-2147483648, s-2147483648] -2147483648 s-2147483648 -2147483648
+I2p[-2147483648] -2147483648 s-2147483648 -2147483648
+PK[-715827882] -715827882 s-715827882 -715827882
+I1[s-715827882] -715827882 s-715827882 -715827882
+I2[-715827882, s-715827882] -715827882 s-715827882 -715827882
+I2p[-715827882] -715827882 s-715827882 -715827882
+PK[-238609294] -238609294 s-238609294 -238609294
+I1[s-238609294] -238609294 s-238609294 -238609294
+I2[-238609294, s-238609294] -238609294 s-238609294 -238609294
+I2p[-238609294] -238609294 s-238609294 -238609294
+PK[-79536431] -79536431 s-79536431 -79536431
+I1[s-79536431] -79536431 s-79536431 -79536431
+I2[-79536431, s-79536431] -79536431 s-79536431 -79536431
+I2p[-79536431] -79536431 s-79536431 -79536431
+PK[-26512143] -26512143 s-26512143 -26512143
+I1[s-26512143] -26512143 s-26512143 -26512143
+I2[-26512143, s-26512143] -26512143 s-26512143 -26512143
+I2p[-26512143] -26512143 s-26512143 -26512143
+PK[-8837381] -8837381 s-8837381 -8837381
+I1[s-8837381] -8837381 s-8837381 -8837381
+I2[-8837381, s-8837381] -8837381 s-8837381 -8837381
+I2p[-8837381] -8837381 s-8837381 -8837381
+PK[-1] -1 s-1 -1
+I1[s-1] -1 s-1 -1
+I2[-1, s-1] -1 s-1 -1
+I2p[-1] -1 s-1 -1
+PK[0] 0 s0 0
+I1[s0] 0 s0 0
+I2[0, s0] 0 s0 0
+I2p[0] 0 s0 0
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[8837381] 8837381 s8837381 8837381
+I1[s8837381] 8837381 s8837381 8837381
+I2[8837381, s8837381] 8837381 s8837381 8837381
+I2p[8837381] 8837381 s8837381 8837381
+PK[26512143] 26512143 s26512143 26512143
+I1[s26512143] 26512143 s26512143 26512143
+I2[26512143, s26512143] 26512143 s26512143 26512143
+I2p[26512143] 26512143 s26512143 26512143
+PK[79536431] 79536431 s79536431 79536431
+I1[s79536431] 79536431 s79536431 79536431
+I2[79536431, s79536431] 79536431 s79536431 79536431
+I2p[79536431] 79536431 s79536431 79536431
+PK[238609294] 238609294 s238609294 238609294
+I1[s238609294] 238609294 s238609294 238609294
+I2[238609294, s238609294] 238609294 s238609294 238609294
+I2p[238609294] 238609294 s238609294 238609294
+PK[715827882] 715827882 s715827882 715827882
+I1[s715827882] 715827882 s715827882 715827882
+I2[715827882, s715827882] 715827882 s715827882 715827882
+I2p[715827882] 715827882 s715827882 715827882
+PK[2147483647] 2147483647 s2147483647 2147483647
+I1[s2147483647] 2147483647 s2147483647 2147483647
+I2[2147483647, s2147483647] 2147483647 s2147483647 2147483647
+I2p[2147483647] 2147483647 s2147483647 2147483647
+
+TYPE INT UNSIGNED
+DUMP_TABLE_BEGIN
+0 s0 0
+1 s1 1
+17674762 s17674762 17674762
+53024287 s53024287 53024287
+159072862 s159072862 159072862
+477218588 s477218588 477218588
+1431655765 s1431655765 1431655765
+4294967295 s4294967295 4294967295
+DUMP_TABLE_END
+PK[0] 0 s0 0
+I1[s0] 0 s0 0
+I2[0, s0] 0 s0 0
+I2p[0] 0 s0 0
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[17674762] 17674762 s17674762 17674762
+I1[s17674762] 17674762 s17674762 17674762
+I2[17674762, s17674762] 17674762 s17674762 17674762
+I2p[17674762] 17674762 s17674762 17674762
+PK[53024287] 53024287 s53024287 53024287
+I1[s53024287] 53024287 s53024287 53024287
+I2[53024287, s53024287] 53024287 s53024287 53024287
+I2p[53024287] 53024287 s53024287 53024287
+PK[159072862] 159072862 s159072862 159072862
+I1[s159072862] 159072862 s159072862 159072862
+I2[159072862, s159072862] 159072862 s159072862 159072862
+I2p[159072862] 159072862 s159072862 159072862
+PK[477218588] 477218588 s477218588 477218588
+I1[s477218588] 477218588 s477218588 477218588
+I2[477218588, s477218588] 477218588 s477218588 477218588
+I2p[477218588] 477218588 s477218588 477218588
+PK[1431655765] 1431655765 s1431655765 1431655765
+I1[s1431655765] 1431655765 s1431655765 1431655765
+I2[1431655765, s1431655765] 1431655765 s1431655765 1431655765
+I2p[1431655765] 1431655765 s1431655765 1431655765
+PK[4294967295] 4294967295 s4294967295 4294967295
+I1[s4294967295] 4294967295 s4294967295 4294967295
+I2[4294967295, s4294967295] 4294967295 s4294967295 4294967295
+I2p[4294967295] 4294967295 s4294967295 4294967295
+
+TYPE BIGINT
+DUMP_TABLE_BEGIN
+-9223372036854775808 s-9223372036854775808 -9223372036854775808
+-3074457345618258602 s-3074457345618258602 -3074457345618258602
+-1024819115206086200 s-1024819115206086200 -1024819115206086200
+-341606371735362066 s-341606371735362066 -341606371735362066
+-113868790578454022 s-113868790578454022 -113868790578454022
+-37956263526151340 s-37956263526151340 -37956263526151340
+-1 s-1 -1
+0 s0 0
+1 s1 1
+37956263526151340 s37956263526151340 37956263526151340
+113868790578454022 s113868790578454022 113868790578454022
+341606371735362066 s341606371735362066 341606371735362066
+1024819115206086200 s1024819115206086200 1024819115206086200
+3074457345618258602 s3074457345618258602 3074457345618258602
+9223372036854775807 s9223372036854775807 9223372036854775807
+DUMP_TABLE_END
+PK[-9223372036854775808] -9223372036854775808 s-9223372036854775808 -9223372036854775808
+I1[s-9223372036854775808] -9223372036854775808 s-9223372036854775808 -9223372036854775808
+I2[-9223372036854775808, s-9223372036854775808] -9223372036854775808 s-9223372036854775808 -9223372036854775808
+I2p[-9223372036854775808] -9223372036854775808 s-9223372036854775808 -9223372036854775808
+PK[-3074457345618258602] -3074457345618258602 s-3074457345618258602 -3074457345618258602
+I1[s-3074457345618258602] -3074457345618258602 s-3074457345618258602 -3074457345618258602
+I2[-3074457345618258602, s-3074457345618258602] -3074457345618258602 s-3074457345618258602 -3074457345618258602
+I2p[-3074457345618258602] -3074457345618258602 s-3074457345618258602 -3074457345618258602
+PK[-1024819115206086200] -1024819115206086200 s-1024819115206086200 -1024819115206086200
+I1[s-1024819115206086200] -1024819115206086200 s-1024819115206086200 -1024819115206086200
+I2[-1024819115206086200, s-1024819115206086200] -1024819115206086200 s-1024819115206086200 -1024819115206086200
+I2p[-1024819115206086200] -1024819115206086200 s-1024819115206086200 -1024819115206086200
+PK[-341606371735362066] -341606371735362066 s-341606371735362066 -341606371735362066
+I1[s-341606371735362066] -341606371735362066 s-341606371735362066 -341606371735362066
+I2[-341606371735362066, s-341606371735362066] -341606371735362066 s-341606371735362066 -341606371735362066
+I2p[-341606371735362066] -341606371735362066 s-341606371735362066 -341606371735362066
+PK[-113868790578454022] -113868790578454022 s-113868790578454022 -113868790578454022
+I1[s-113868790578454022] -113868790578454022 s-113868790578454022 -113868790578454022
+I2[-113868790578454022, s-113868790578454022] -113868790578454022 s-113868790578454022 -113868790578454022
+I2p[-113868790578454022] -113868790578454022 s-113868790578454022 -113868790578454022
+PK[-37956263526151340] -37956263526151340 s-37956263526151340 -37956263526151340
+I1[s-37956263526151340] -37956263526151340 s-37956263526151340 -37956263526151340
+I2[-37956263526151340, s-37956263526151340] -37956263526151340 s-37956263526151340 -37956263526151340
+I2p[-37956263526151340] -37956263526151340 s-37956263526151340 -37956263526151340
+PK[-1] -1 s-1 -1
+I1[s-1] -1 s-1 -1
+I2[-1, s-1] -1 s-1 -1
+I2p[-1] -1 s-1 -1
+PK[0] 0 s0 0
+I1[s0] 0 s0 0
+I2[0, s0] 0 s0 0
+I2p[0] 0 s0 0
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[37956263526151340] 37956263526151340 s37956263526151340 37956263526151340
+I1[s37956263526151340] 37956263526151340 s37956263526151340 37956263526151340
+I2[37956263526151340, s37956263526151340] 37956263526151340 s37956263526151340 37956263526151340
+I2p[37956263526151340] 37956263526151340 s37956263526151340 37956263526151340
+PK[113868790578454022] 113868790578454022 s113868790578454022 113868790578454022
+I1[s113868790578454022] 113868790578454022 s113868790578454022 113868790578454022
+I2[113868790578454022, s113868790578454022] 113868790578454022 s113868790578454022 113868790578454022
+I2p[113868790578454022] 113868790578454022 s113868790578454022 113868790578454022
+PK[341606371735362066] 341606371735362066 s341606371735362066 341606371735362066
+I1[s341606371735362066] 341606371735362066 s341606371735362066 341606371735362066
+I2[341606371735362066, s341606371735362066] 341606371735362066 s341606371735362066 341606371735362066
+I2p[341606371735362066] 341606371735362066 s341606371735362066 341606371735362066
+PK[1024819115206086200] 1024819115206086200 s1024819115206086200 1024819115206086200
+I1[s1024819115206086200] 1024819115206086200 s1024819115206086200 1024819115206086200
+I2[1024819115206086200, s1024819115206086200] 1024819115206086200 s1024819115206086200 1024819115206086200
+I2p[1024819115206086200] 1024819115206086200 s1024819115206086200 1024819115206086200
+PK[3074457345618258602] 3074457345618258602 s3074457345618258602 3074457345618258602
+I1[s3074457345618258602] 3074457345618258602 s3074457345618258602 3074457345618258602
+I2[3074457345618258602, s3074457345618258602] 3074457345618258602 s3074457345618258602 3074457345618258602
+I2p[3074457345618258602] 3074457345618258602 s3074457345618258602 3074457345618258602
+PK[9223372036854775807] 9223372036854775807 s9223372036854775807 9223372036854775807
+I1[s9223372036854775807] 9223372036854775807 s9223372036854775807 9223372036854775807
+I2[9223372036854775807, s9223372036854775807] 9223372036854775807 s9223372036854775807 9223372036854775807
+I2p[9223372036854775807] 9223372036854775807 s9223372036854775807 9223372036854775807
+
+TYPE BIGINT UNSIGNED
+DUMP_TABLE_BEGIN
+0 s0 0
+1 s1 1
+75912527052302681 s75912527052302681 75912527052302681
+227737581156908044 s227737581156908044 227737581156908044
+683212743470724133 s683212743470724133 683212743470724133
+2049638230412172401 s2049638230412172401 2049638230412172401
+6148914691236517205 s6148914691236517205 6148914691236517205
+18446744073709551615 s18446744073709551615 18446744073709551615
+DUMP_TABLE_END
+PK[0] 0 s0 0
+I1[s0] 0 s0 0
+I2[0, s0] 0 s0 0
+I2p[0] 0 s0 0
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[75912527052302681] 75912527052302681 s75912527052302681 75912527052302681
+I1[s75912527052302681] 75912527052302681 s75912527052302681 75912527052302681
+I2[75912527052302681, s75912527052302681] 75912527052302681 s75912527052302681 75912527052302681
+I2p[75912527052302681] 75912527052302681 s75912527052302681 75912527052302681
+PK[227737581156908044] 227737581156908044 s227737581156908044 227737581156908044
+I1[s227737581156908044] 227737581156908044 s227737581156908044 227737581156908044
+I2[227737581156908044, s227737581156908044] 227737581156908044 s227737581156908044 227737581156908044
+I2p[227737581156908044] 227737581156908044 s227737581156908044 227737581156908044
+PK[683212743470724133] 683212743470724133 s683212743470724133 683212743470724133
+I1[s683212743470724133] 683212743470724133 s683212743470724133 683212743470724133
+I2[683212743470724133, s683212743470724133] 683212743470724133 s683212743470724133 683212743470724133
+I2p[683212743470724133] 683212743470724133 s683212743470724133 683212743470724133
+PK[2049638230412172401] 2049638230412172401 s2049638230412172401 2049638230412172401
+I1[s2049638230412172401] 2049638230412172401 s2049638230412172401 2049638230412172401
+I2[2049638230412172401, s2049638230412172401] 2049638230412172401 s2049638230412172401 2049638230412172401
+I2p[2049638230412172401] 2049638230412172401 s2049638230412172401 2049638230412172401
+PK[6148914691236517205] 6148914691236517205 s6148914691236517205 6148914691236517205
+I1[s6148914691236517205] 6148914691236517205 s6148914691236517205 6148914691236517205
+I2[6148914691236517205, s6148914691236517205] 6148914691236517205 s6148914691236517205 6148914691236517205
+I2p[6148914691236517205] 6148914691236517205 s6148914691236517205 6148914691236517205
+PK[18446744073709551615] 18446744073709551615 s18446744073709551615 18446744073709551615
+I1[s18446744073709551615] 18446744073709551615 s18446744073709551615 18446744073709551615
+I2[18446744073709551615, s18446744073709551615] 18446744073709551615 s18446744073709551615 18446744073709551615
+I2p[18446744073709551615] 18446744073709551615 s18446744073709551615 18446744073709551615
+
+TYPE FLOAT
+DUMP_TABLE_BEGIN
+-32768 s-32768 -32768
+-10922 s-10922 -10922
+-3640 s-3640 -3640
+-1213 s-1213 -1213
+-404 s-404 -404
+-134 s-134 -134
+-1 s-1 -1
+0 s0 0
+1 s1 1
+134 s134 134
+404 s404 404
+1213 s1213 1213
+3640 s3640 3640
+10922 s10922 10922
+32768 s32768 32768
+DUMP_TABLE_END
+PK[-32768] -32768 s-32768 -32768
+I1[s-32768] -32768 s-32768 -32768
+I2[-32768, s-32768] -32768 s-32768 -32768
+I2p[-32768] -32768 s-32768 -32768
+PK[-10922] -10922 s-10922 -10922
+I1[s-10922] -10922 s-10922 -10922
+I2[-10922, s-10922] -10922 s-10922 -10922
+I2p[-10922] -10922 s-10922 -10922
+PK[-3640] -3640 s-3640 -3640
+I1[s-3640] -3640 s-3640 -3640
+I2[-3640, s-3640] -3640 s-3640 -3640
+I2p[-3640] -3640 s-3640 -3640
+PK[-1213] -1213 s-1213 -1213
+I1[s-1213] -1213 s-1213 -1213
+I2[-1213, s-1213] -1213 s-1213 -1213
+I2p[-1213] -1213 s-1213 -1213
+PK[-404] -404 s-404 -404
+I1[s-404] -404 s-404 -404
+I2[-404, s-404] -404 s-404 -404
+I2p[-404] -404 s-404 -404
+PK[-134] -134 s-134 -134
+I1[s-134] -134 s-134 -134
+I2[-134, s-134] -134 s-134 -134
+I2p[-134] -134 s-134 -134
+PK[-1] -1 s-1 -1
+I1[s-1] -1 s-1 -1
+I2[-1, s-1] -1 s-1 -1
+I2p[-1] -1 s-1 -1
+PK[0] 0 s0 0
+I1[s0] 0 s0 0
+I2[0, s0] 0 s0 0
+I2p[0] 0 s0 0
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[134] 134 s134 134
+I1[s134] 134 s134 134
+I2[134, s134] 134 s134 134
+I2p[134] 134 s134 134
+PK[404] 404 s404 404
+I1[s404] 404 s404 404
+I2[404, s404] 404 s404 404
+I2p[404] 404 s404 404
+PK[1213] 1213 s1213 1213
+I1[s1213] 1213 s1213 1213
+I2[1213, s1213] 1213 s1213 1213
+I2p[1213] 1213 s1213 1213
+PK[3640] 3640 s3640 3640
+I1[s3640] 3640 s3640 3640
+I2[3640, s3640] 3640 s3640 3640
+I2p[3640] 3640 s3640 3640
+PK[10922] 10922 s10922 10922
+I1[s10922] 10922 s10922 10922
+I2[10922, s10922] 10922 s10922 10922
+I2p[10922] 10922 s10922 10922
+PK[32768] 32768 s32768 32768
+I1[s32768] 32768 s32768 32768
+I2[32768, s32768] 32768 s32768 32768
+I2p[32768] 32768 s32768 32768
+
+TYPE DOUBLE
+DUMP_TABLE_BEGIN
+-2147483648 s-2147483648 -2147483648
+-715827882 s-715827882 -715827882
+-238609294 s-238609294 -238609294
+-79536431 s-79536431 -79536431
+-26512143 s-26512143 -26512143
+-8837381 s-8837381 -8837381
+-1 s-1 -1
+0 s0 0
+1 s1 1
+8837381 s8837381 8837381
+26512143 s26512143 26512143
+79536431 s79536431 79536431
+238609294 s238609294 238609294
+715827882 s715827882 715827882
+2147483647 s2147483647 2147483647
+DUMP_TABLE_END
+PK[-2147483648] -2147483648 s-2147483648 -2147483648
+I1[s-2147483648] -2147483648 s-2147483648 -2147483648
+I2[-2147483648, s-2147483648] -2147483648 s-2147483648 -2147483648
+I2p[-2147483648] -2147483648 s-2147483648 -2147483648
+PK[-715827882] -715827882 s-715827882 -715827882
+I1[s-715827882] -715827882 s-715827882 -715827882
+I2[-715827882, s-715827882] -715827882 s-715827882 -715827882
+I2p[-715827882] -715827882 s-715827882 -715827882
+PK[-238609294] -238609294 s-238609294 -238609294
+I1[s-238609294] -238609294 s-238609294 -238609294
+I2[-238609294, s-238609294] -238609294 s-238609294 -238609294
+I2p[-238609294] -238609294 s-238609294 -238609294
+PK[-79536431] -79536431 s-79536431 -79536431
+I1[s-79536431] -79536431 s-79536431 -79536431
+I2[-79536431, s-79536431] -79536431 s-79536431 -79536431
+I2p[-79536431] -79536431 s-79536431 -79536431
+PK[-26512143] -26512143 s-26512143 -26512143
+I1[s-26512143] -26512143 s-26512143 -26512143
+I2[-26512143, s-26512143] -26512143 s-26512143 -26512143
+I2p[-26512143] -26512143 s-26512143 -26512143
+PK[-8837381] -8837381 s-8837381 -8837381
+I1[s-8837381] -8837381 s-8837381 -8837381
+I2[-8837381, s-8837381] -8837381 s-8837381 -8837381
+I2p[-8837381] -8837381 s-8837381 -8837381
+PK[-1] -1 s-1 -1
+I1[s-1] -1 s-1 -1
+I2[-1, s-1] -1 s-1 -1
+I2p[-1] -1 s-1 -1
+PK[0] 0 s0 0
+I1[s0] 0 s0 0
+I2[0, s0] 0 s0 0
+I2p[0] 0 s0 0
+PK[1] 1 s1 1
+I1[s1] 1 s1 1
+I2[1, s1] 1 s1 1
+I2p[1] 1 s1 1
+PK[8837381] 8837381 s8837381 8837381
+I1[s8837381] 8837381 s8837381 8837381
+I2[8837381, s8837381] 8837381 s8837381 8837381
+I2p[8837381] 8837381 s8837381 8837381
+PK[26512143] 26512143 s26512143 26512143
+I1[s26512143] 26512143 s26512143 26512143
+I2[26512143, s26512143] 26512143 s26512143 26512143
+I2p[26512143] 26512143 s26512143 26512143
+PK[79536431] 79536431 s79536431 79536431
+I1[s79536431] 79536431 s79536431 79536431
+I2[79536431, s79536431] 79536431 s79536431 79536431
+I2p[79536431] 79536431 s79536431 79536431
+PK[238609294] 238609294 s238609294 238609294
+I1[s238609294] 238609294 s238609294 238609294
+I2[238609294, s238609294] 238609294 s238609294 238609294
+I2p[238609294] 238609294 s238609294 238609294
+PK[715827882] 715827882 s715827882 715827882
+I1[s715827882] 715827882 s715827882 715827882
+I2[715827882, s715827882] 715827882 s715827882 715827882
+I2p[715827882] 715827882 s715827882 715827882
+PK[2147483647] 2147483647 s2147483647 2147483647
+I1[s2147483647] 2147483647 s2147483647 2147483647
+I2[2147483647, s2147483647] 2147483647 s2147483647 2147483647
+I2p[2147483647] 2147483647 s2147483647 2147483647
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test15.pl b/plugin/handler_socket/regtest/test_01_lib/test15.pl
new file mode 100644
index 00000000000..4c56d355708
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test15.pl
@@ -0,0 +1,114 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for various numeric types
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use bigint;
+use hstest;
+
+my $numeric_types = [
+ [ 'TINYINT', -128, 127 ],
+ [ 'TINYINT UNSIGNED', 0, 255 ],
+ [ 'SMALLINT', -32768, 32768 ],
+ [ 'SMALLINT UNSIGNED', 0, 65535 ],
+ [ 'MEDIUMINT', -8388608, 8388607 ],
+ [ 'MEDIUMINT UNSIGNED', 0, 16777215 ],
+ [ 'INT', -2147483648, 2147483647 ],
+ [ 'INT UNSIGNED', 0, 4294967295 ],
+ [ 'BIGINT', -9223372036854775808, 9223372036854775807 ],
+ [ 'BIGINT UNSIGNED', 0, 18446744073709551615 ],
+ [ 'FLOAT', -32768, 32768 ],
+ [ 'DOUBLE', -2147483648, 2147483647 ],
+];
+
+my $table = 'hstesttbl';
+my $dbh;
+for my $rec (@$numeric_types) {
+ my ($typ, $minval, $maxval) = @$rec;
+ my @vals = ();
+ push(@vals, 0);
+ push(@vals, 1);
+ push(@vals, $maxval);
+ if ($minval != 0) {
+ push(@vals, -1);
+ push(@vals, $minval);
+ }
+ my $v1 = $minval;
+ my $v2 = $maxval;
+ for (my $i = 0; $i < 5; ++$i) {
+ $v1 /= 3;
+ $v2 /= 3;
+ if ($v1 != 0) {
+ push(@vals, int($v1));
+ }
+ push(@vals, int($v2));
+ }
+ @vals = sort { $a <=> $b } @vals;
+ print("TYPE $typ\n");
+ test_one($typ, \@vals);
+ print("\n");
+}
+
+sub test_one {
+ my ($typ, $values) = @_;
+ $dbh = hstest::init_testdb();
+ $dbh->do(
+ "create table $table (" .
+ "k $typ primary key, " .
+ "v1 varchar(512), " .
+ "v2 $typ, " .
+ "index i1(v1), index i2(v2, v1)) " .
+ "engine = myisam default charset = binary");
+ my $hs = hstest::get_hs_connection(undef, 9999);
+ my $dbname = $hstest::conf{dbname};
+ $hs->open_index(1, $dbname, $table, '', 'k,v1,v2');
+ $hs->open_index(2, $dbname, $table, 'i1', 'k,v1,v2');
+ $hs->open_index(3, $dbname, $table, 'i2', 'k,v1,v2');
+ for my $k (@$values) {
+ my $kstr = 's' . $k;
+ $hs->execute_single(1, '+', [ $k, $kstr, $k ], 0, 0);
+ }
+ dump_table();
+ for my $k (@$values) {
+ my $kstr = 's' . $k;
+ my ($rk, $rv1, $rv2);
+ my $r;
+ $r = $hs->execute_single(1, '=', [ $k ], 1, 0);
+ shift(@$r);
+ ($rk, $rv1, $rv2) = @$r;
+ print "PK[$k] $rk $rv1 $rv2\n";
+ $r = $hs->execute_single(2, '=', [ $kstr ], 1, 0);
+ shift(@$r);
+ ($rk, $rv1, $rv2) = @$r;
+ print "I1[$kstr] $rk $rv1 $rv2\n";
+ $r = $hs->execute_single(3, '=', [ $k, $kstr ], 1, 0);
+ shift(@$r);
+ ($rk, $rv1, $rv2) = @$r;
+ print "I2[$k, $kstr] $rk $rv1 $rv2\n";
+ $r = $hs->execute_single(3, '=', [ $k ], 1, 0);
+ shift(@$r);
+ ($rk, $rv1, $rv2) = @$r;
+ print "I2p[$k] $rk $rv1 $rv2\n";
+ }
+}
+
+sub dump_table {
+ print "DUMP_TABLE_BEGIN\n";
+ my $aref = $dbh->selectall_arrayref("select k,v1,v2 from $table order by k");
+ for my $row (@$aref) {
+ my ($k, $v1, $v2) = @$row;
+ $v1 = "[null]" if !defined($v1);
+ $v2 = "[null]" if !defined($v2);
+ print "$k $v1 $v2\n";
+ # print "MISMATCH\n" if ($valmap{$k} ne $v);
+ }
+ print "DUMP_TABLE_END\n";
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test16.expected b/plugin/handler_socket/regtest/test_01_lib/test16.expected
new file mode 100644
index 00000000000..b708b95cdf3
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test16.expected
@@ -0,0 +1,66 @@
+TYPE DATE
+DUMP_TABLE_BEGIN
+0000-00-00 s0000-00-00 0000-00-00
+2011-01-01 s2011-01-01 2011-01-01
+9999-12-31 s9999-12-31 9999-12-31
+DUMP_TABLE_END
+PK[0000-00-00] 0000-00-00 s0000-00-00 0000-00-00
+I1[s0000-00-00] 0000-00-00 s0000-00-00 0000-00-00
+I2[0000-00-00, s0000-00-00] 0000-00-00 s0000-00-00 0000-00-00
+I2p[0000-00-00] 0000-00-00 s0000-00-00 0000-00-00
+PK[2011-01-01] 2011-01-01 s2011-01-01 2011-01-01
+I1[s2011-01-01] 2011-01-01 s2011-01-01 2011-01-01
+I2[2011-01-01, s2011-01-01] 2011-01-01 s2011-01-01 2011-01-01
+I2p[2011-01-01] 2011-01-01 s2011-01-01 2011-01-01
+PK[9999-12-31] 9999-12-31 s9999-12-31 9999-12-31
+I1[s9999-12-31] 9999-12-31 s9999-12-31 9999-12-31
+I2[9999-12-31, s9999-12-31] 9999-12-31 s9999-12-31 9999-12-31
+I2p[9999-12-31] 9999-12-31 s9999-12-31 9999-12-31
+
+TYPE DATETIME
+DUMP_TABLE_BEGIN
+0000-00-00 00:00:00 s0 0000-00-00 00:00:00
+2011-01-01 18:30:25 s2011-01-01 18:30:25 2011-01-01 18:30:25
+DUMP_TABLE_END
+PK[0] 0000-00-00 00:00:00 s0 0000-00-00 00:00:00
+I1[s0] 0000-00-00 00:00:00 s0 0000-00-00 00:00:00
+I2[0, s0] 0000-00-00 00:00:00 s0 0000-00-00 00:00:00
+I2p[0] 0000-00-00 00:00:00 s0 0000-00-00 00:00:00
+PK[2011-01-01 18:30:25] 2011-01-01 18:30:25 s2011-01-01 18:30:25 2011-01-01 18:30:25
+I1[s2011-01-01 18:30:25] 2011-01-01 18:30:25 s2011-01-01 18:30:25 2011-01-01 18:30:25
+I2[2011-01-01 18:30:25, s2011-01-01 18:30:25] 2011-01-01 18:30:25 s2011-01-01 18:30:25 2011-01-01 18:30:25
+I2p[2011-01-01 18:30:25] 2011-01-01 18:30:25 s2011-01-01 18:30:25 2011-01-01 18:30:25
+
+TYPE TIME
+DUMP_TABLE_BEGIN
+00:00:00 s0 00:00:00
+18:30:25 s18:30:25 18:30:25
+DUMP_TABLE_END
+PK[0] 00:00:00 s0 00:00:00
+I1[s0] 00:00:00 s0 00:00:00
+I2[0, s0] 00:00:00 s0 00:00:00
+I2p[0] 00:00:00 s0 00:00:00
+PK[18:30:25] 18:30:25 s18:30:25 18:30:25
+I1[s18:30:25] 18:30:25 s18:30:25 18:30:25
+I2[18:30:25, s18:30:25] 18:30:25 s18:30:25 18:30:25
+I2p[18:30:25] 18:30:25 s18:30:25 18:30:25
+
+TYPE YEAR(4)
+DUMP_TABLE_BEGIN
+1901 s1901 1901
+2011 s2011 2011
+2155 s2155 2155
+DUMP_TABLE_END
+PK[1901] 1901 s1901 1901
+I1[s1901] 1901 s1901 1901
+I2[1901, s1901] 1901 s1901 1901
+I2p[1901] 1901 s1901 1901
+PK[2011] 2011 s2011 2011
+I1[s2011] 2011 s2011 2011
+I2[2011, s2011] 2011 s2011 2011
+I2p[2011] 2011 s2011 2011
+PK[2155] 2155 s2155 2155
+I1[s2155] 2155 s2155 2155
+I2[2155, s2155] 2155 s2155 2155
+I2p[2155] 2155 s2155 2155
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test16.pl b/plugin/handler_socket/regtest/test_01_lib/test16.pl
new file mode 100644
index 00000000000..6db8c576d7a
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test16.pl
@@ -0,0 +1,88 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for date/datetime types
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use bigint;
+use hstest;
+
+my $datetime_types = [
+ [ 'DATE', '0000-00-00', '2011-01-01', '9999-12-31' ],
+ [ 'DATETIME', 0, '2011-01-01 18:30:25' ],
+ [ 'TIME', 0, '18:30:25' ],
+ [ 'YEAR(4)', 1901, 2011, 2155 ],
+ # [ 'TIMESTAMP', 0, 999999999 ], # DOES NOT WORK YET
+];
+
+my $table = 'hstesttbl';
+my $dbh;
+for my $rec (@$datetime_types) {
+ my ($typ, @vals) = @$rec;
+ print("TYPE $typ\n");
+ test_one($typ, \@vals);
+ print("\n");
+}
+
+sub test_one {
+ my ($typ, $values) = @_;
+ $dbh = hstest::init_testdb();
+ $dbh->do(
+ "create table $table (" .
+ "k $typ primary key, " .
+ "v1 varchar(512), " .
+ "v2 $typ, " .
+ "index i1(v1), index i2(v2, v1)) " .
+ "engine = myisam default charset = binary");
+ my $hs = hstest::get_hs_connection(undef, 9999);
+ my $dbname = $hstest::conf{dbname};
+ $hs->open_index(1, $dbname, $table, '', 'k,v1,v2');
+ $hs->open_index(2, $dbname, $table, 'i1', 'k,v1,v2');
+ $hs->open_index(3, $dbname, $table, 'i2', 'k,v1,v2');
+ for my $k (@$values) {
+ my $kstr = 's' . $k;
+ $hs->execute_single(1, '+', [ $k, $kstr, $k ], 0, 0);
+ }
+ dump_table();
+ for my $k (@$values) {
+ my $kstr = 's' . $k;
+ my ($rk, $rv1, $rv2);
+ my $r;
+ $r = $hs->execute_single(1, '=', [ $k ], 1, 0);
+ shift(@$r);
+ ($rk, $rv1, $rv2) = @$r;
+ print "PK[$k] $rk $rv1 $rv2\n";
+ $r = $hs->execute_single(2, '=', [ $kstr ], 1, 0);
+ shift(@$r);
+ ($rk, $rv1, $rv2) = @$r;
+ print "I1[$kstr] $rk $rv1 $rv2\n";
+ $r = $hs->execute_single(3, '=', [ $k, $kstr ], 1, 0);
+ shift(@$r);
+ ($rk, $rv1, $rv2) = @$r;
+ print "I2[$k, $kstr] $rk $rv1 $rv2\n";
+ $r = $hs->execute_single(3, '=', [ $k ], 1, 0);
+ shift(@$r);
+ ($rk, $rv1, $rv2) = @$r;
+ print "I2p[$k] $rk $rv1 $rv2\n";
+ }
+}
+
+sub dump_table {
+ print "DUMP_TABLE_BEGIN\n";
+ my $aref = $dbh->selectall_arrayref("select k,v1,v2 from $table order by k");
+ for my $row (@$aref) {
+ my ($k, $v1, $v2) = @$row;
+ $v1 = "[null]" if !defined($v1);
+ $v2 = "[null]" if !defined($v2);
+ print "$k $v1 $v2\n";
+ # print "MISMATCH\n" if ($valmap{$k} ne $v);
+ }
+ print "DUMP_TABLE_END\n";
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test17.expected b/plugin/handler_socket/regtest/test_01_lib/test17.expected
new file mode 100644
index 00000000000..77176d31722
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test17.expected
Binary files differ
diff --git a/plugin/handler_socket/regtest/test_01_lib/test17.pl b/plugin/handler_socket/regtest/test_01_lib/test17.pl
new file mode 100644
index 00000000000..b7861b880f5
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test17.pl
@@ -0,0 +1,125 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for string types
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use bigint;
+use hstest;
+
+my $string_types = [
+ [ 'CHAR(10)', undef, 1, 2, 5, 10 ],
+ [ 'VARCHAR(10)', undef, 1, 2, 5, 10 ],
+ [ 'BINARY(10)', undef, 1, 2, 5, 10 ],
+ [ 'VARBINARY(10)', undef, 1, 2, 5, 10 ],
+ [ 'CHAR(255)', undef, 1, 2, 5, 10, 100, 200, 255 ],
+ [ 'VARCHAR(255)', undef, 1, 2, 5, 10, 100, 200, 255 ],
+ [ 'VARCHAR(511)', undef, 1, 2, 5, 10, 100, 200, 511 ],
+ [ 'LONGTEXT', 500, 1, 2, 5, 10, 100, 200, 511 ],
+ [ 'LONGBLOB', 500, 1, 2, 5, 10, 100, 200, 511 ],
+# [ 'VARCHAR(4096)', 500, 1, 2, 5, 10, 100, 200, 255, 256, 4095 ],
+# [ 'VARCHAR(16383)', 500, 1, 2, 5, 10, 100, 200, 255, 256, 4095, 4096, 16383 ],
+# [ 'VARBINARY(16383)', 500, 1, 2, 5, 10, 100, 200, 255, 256, 4095, 4096, 16383 ],
+];
+
+my $table = 'hstesttbl';
+my $dbh;
+for my $rec (@$string_types) {
+ my ($typ, $keylen, @vs) = @$rec;
+ my @vals = ();
+ for my $len (@vs) {
+ my $s = '';
+ my @arr = ();
+ srand(999);
+ # print "$len 1\n";
+ for (my $i = 0; $i < $len; ++$i) {
+ my $v = int(rand(10));
+ $arr[$i] = chr(65 + $v);
+ }
+ # print "2\n";
+ push(@vals, join('', @arr));
+ }
+ print("TYPE $typ\n");
+ test_one($typ, $keylen, \@vals);
+ print("\n");
+}
+
+sub test_one {
+ my ($typ, $keylen, $values) = @_;
+ my $keylen_str = '';
+ if (defined($keylen)) {
+ $keylen_str = "($keylen)";
+ }
+ $dbh = hstest::init_testdb();
+ $dbh->do(
+ "create table $table (" .
+ "k $typ, " .
+ "v1 varchar(2047), " .
+ "v2 $typ, " .
+ "primary key(k$keylen_str), " .
+ "index i1(v1), index i2(v2$keylen_str, v1(300))) " .
+ "engine = myisam default charset = latin1");
+ my $hs = hstest::get_hs_connection(undef, 9999);
+ my $dbname = $hstest::conf{dbname};
+ $hs->open_index(1, $dbname, $table, '', 'k,v1,v2');
+ $hs->open_index(2, $dbname, $table, 'i1', 'k,v1,v2');
+ $hs->open_index(3, $dbname, $table, 'i2', 'k,v1,v2');
+ for my $k (@$values) {
+ my $kstr = 's' . $k;
+ $hs->execute_single(1, '+', [ $k, $kstr, $k ], 0, 0);
+ }
+ # dump_table();
+ for my $k (@$values) {
+ my $kstr = 's' . $k;
+ my ($rk, $rv1, $rv2);
+ my $r;
+ $r = $hs->execute_single(1, '=', [ $k ], 1, 0);
+ shift(@$r);
+ check_value("$typ:PK", @$r);
+ $r = $hs->execute_single(2, '=', [ $kstr ], 1, 0);
+ shift(@$r);
+ check_value("$typ:I1", @$r);
+ $r = $hs->execute_single(3, '=', [ $k, $kstr ], 1, 0);
+ shift(@$r);
+ check_value("$typ:I2", @$r);
+ $r = $hs->execute_single(3, '=', [ $k ], 1, 0);
+ shift(@$r);
+ check_value("$typ:I2p", @$r);
+ }
+}
+
+sub check_value {
+ my ($mess, $rk, $rv1, $rv2) = @_;
+ $rk ||= '';
+ $rv1 ||= '';
+ $rv2 ||= '';
+ if ($rv2 ne $rk) {
+ print "$mess: V2 NE\n$rk\n$rv2\n";
+ return;
+ }
+ if ($rv1 ne 's' . $rk) {
+ print "$mess: V1 NE\n$rk\n$rv1\n";
+ return;
+ }
+ print "$mess: EQ\n";
+}
+
+sub dump_table {
+ print "DUMP_TABLE_BEGIN\n";
+ my $aref = $dbh->selectall_arrayref("select k,v1,v2 from $table order by k");
+ for my $row (@$aref) {
+ my ($k, $v1, $v2) = @$row;
+ $v1 = "[null]" if !defined($v1);
+ $v2 = "[null]" if !defined($v2);
+ print "$k $v1 $v2\n";
+ # print "MISMATCH\n" if ($valmap{$k} ne $v);
+ }
+ print "DUMP_TABLE_END\n";
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test18.expected b/plugin/handler_socket/regtest/test_01_lib/test18.expected
new file mode 100644
index 00000000000..9e09341cae9
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test18.expected
@@ -0,0 +1,22 @@
+HSINSERT
+1 v1hs_0
+2 v1hs_1
+3 v1hs_2
+4 v1hs_3
+5 v1hs_4
+6 v1hs_5
+7 v1hs_6
+8 v1hs_7
+9 v1hs_8
+10 v1hs_9
+DUMP_TABLE
+1 v1hs_0
+2 v1hs_1
+3 v1hs_2
+4 v1hs_3
+5 v1hs_4
+6 v1hs_5
+7 v1hs_6
+8 v1hs_7
+9 v1hs_8
+10 v1hs_9
diff --git a/plugin/handler_socket/regtest/test_01_lib/test18.pl b/plugin/handler_socket/regtest/test_01_lib/test18.pl
new file mode 100644
index 00000000000..87047bc9cba
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test18.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# tests that columns to be inserted are specified by open_index
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 10;
+$dbh->do(
+ "create table $table (" .
+ "k int primary key auto_increment, " .
+ "v1 varchar(30), " .
+ "v2 varchar(30)) " .
+ "engine = myisam default charset = binary");
+srand(999);
+
+my %valmap = ();
+
+print "HSINSERT\n";
+my $hs = hstest::get_hs_connection(undef, 9999);
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'v1');
+# inserts with auto_increment
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = 0;
+ my $v1 = "v1hs_" . $i;
+ my $v2 = "v2hs_" . $i;
+ my $r = $hs->execute_insert(1, [ $v1 ]);
+ my $err = $r->[0];
+ if ($err != 0) {
+ my $err_str = $r->[1];
+ print "$err $err_str\n";
+ } else {
+ my $id = $r->[1];
+ print "$id $v1\n";
+ }
+}
+
+undef $hs;
+
+dump_table();
+
+sub dump_table {
+ print "DUMP_TABLE\n";
+ my $aref = $dbh->selectall_arrayref("select k,v1,v2 from $table order by k");
+ for my $row (@$aref) {
+ my ($k, $v1, $v2) = @$row;
+ $v1 = "[null]" if !defined($v1);
+ $v2 = "[null]" if !defined($v2);
+ print "$k $v1 $v2\n";
+ # print "MISMATCH\n" if ($valmap{$k} ne $v);
+ }
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test19.expected b/plugin/handler_socket/regtest/test_01_lib/test19.expected
new file mode 100644
index 00000000000..1c37b403d6a
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test19.expected
@@ -0,0 +1,14894 @@
+
+TINYINT -------------------------------------------------
+
+FILTER(TINYINT) NO FILTER
+code=0 rows=30
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 = -128
+code=0 rows=3
+[0][0][0][-128]
+[1][0][1][-128]
+[2][0][2][-128]
+
+FILTER(TINYINT) v2 != -128
+code=0 rows=27
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[0][9][0][NULL]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[1][9][1][NULL]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 >= -128
+code=0 rows=27
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 < -128
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 > -128
+code=0 rows=24
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 <= -128
+code=0 rows=6
+[0][0][0][-128]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 = -42
+code=0 rows=3
+[0][1][0][-42]
+[1][1][1][-42]
+[2][1][2][-42]
+
+FILTER(TINYINT) v2 != -42
+code=0 rows=27
+[0][0][0][-128]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 >= -42
+code=0 rows=24
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 < -42
+code=0 rows=6
+[0][0][0][-128]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 > -42
+code=0 rows=21
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 <= -42
+code=0 rows=9
+[0][0][0][-128]
+[0][1][0][-42]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 = -14
+code=0 rows=3
+[0][2][0][-14]
+[1][2][1][-14]
+[2][2][2][-14]
+
+FILTER(TINYINT) v2 != -14
+code=0 rows=27
+[0][0][0][-128]
+[0][1][0][-42]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 >= -14
+code=0 rows=21
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 < -14
+code=0 rows=9
+[0][0][0][-128]
+[0][1][0][-42]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 > -14
+code=0 rows=18
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 <= -14
+code=0 rows=12
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 = -4
+code=0 rows=3
+[0][3][0][-4]
+[1][3][1][-4]
+[2][3][2][-4]
+
+FILTER(TINYINT) v2 != -4
+code=0 rows=27
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 >= -4
+code=0 rows=18
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 < -4
+code=0 rows=12
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 > -4
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 <= -4
+code=0 rows=15
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 = 0
+code=0 rows=3
+[0][4][0][0]
+[1][4][1][0]
+[2][4][2][0]
+
+FILTER(TINYINT) v2 != 0
+code=0 rows=27
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 >= 0
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 < 0
+code=0 rows=15
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 > 0
+code=0 rows=12
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 <= 0
+code=0 rows=18
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 = 4
+code=0 rows=3
+[0][5][0][4]
+[1][5][1][4]
+[2][5][2][4]
+
+FILTER(TINYINT) v2 != 4
+code=0 rows=27
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 >= 4
+code=0 rows=12
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 < 4
+code=0 rows=18
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 > 4
+code=0 rows=9
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 <= 4
+code=0 rows=21
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 = 14
+code=0 rows=3
+[0][6][0][14]
+[1][6][1][14]
+[2][6][2][14]
+
+FILTER(TINYINT) v2 != 14
+code=0 rows=27
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][7][0][42]
+[0][8][0][127]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][7][1][42]
+[1][8][1][127]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][7][2][42]
+[2][8][2][127]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 >= 14
+code=0 rows=9
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 < 14
+code=0 rows=21
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 > 14
+code=0 rows=6
+[0][7][0][42]
+[0][8][0][127]
+[1][7][1][42]
+[1][8][1][127]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 <= 14
+code=0 rows=24
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 = 42
+code=0 rows=3
+[0][7][0][42]
+[1][7][1][42]
+[2][7][2][42]
+
+FILTER(TINYINT) v2 != 42
+code=0 rows=27
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][8][0][127]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][8][1][127]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][8][2][127]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 >= 42
+code=0 rows=6
+[0][7][0][42]
+[0][8][0][127]
+[1][7][1][42]
+[1][8][1][127]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 < 42
+code=0 rows=24
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 > 42
+code=0 rows=3
+[0][8][0][127]
+[1][8][1][127]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 <= 42
+code=0 rows=27
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 = 127
+code=0 rows=3
+[0][8][0][127]
+[1][8][1][127]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 != 127
+code=0 rows=27
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 >= 127
+code=0 rows=3
+[0][8][0][127]
+[1][8][1][127]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 < 127
+code=0 rows=27
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 > 127
+code=0 rows=0
+
+FILTER(TINYINT) v2 <= 127
+code=0 rows=30
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 = NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 != NULL
+code=0 rows=27
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 >= NULL
+code=0 rows=30
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[0][9][0][NULL]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[1][9][1][NULL]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+[2][9][2][NULL]
+
+FILTER(TINYINT) v2 < NULL
+code=0 rows=0
+
+FILTER(TINYINT) v2 > NULL
+code=0 rows=27
+[0][0][0][-128]
+[0][1][0][-42]
+[0][2][0][-14]
+[0][3][0][-4]
+[0][4][0][0]
+[0][5][0][4]
+[0][6][0][14]
+[0][7][0][42]
+[0][8][0][127]
+[1][0][1][-128]
+[1][1][1][-42]
+[1][2][1][-14]
+[1][3][1][-4]
+[1][4][1][0]
+[1][5][1][4]
+[1][6][1][14]
+[1][7][1][42]
+[1][8][1][127]
+[2][0][2][-128]
+[2][1][2][-42]
+[2][2][2][-14]
+[2][3][2][-4]
+[2][4][2][0]
+[2][5][2][4]
+[2][6][2][14]
+[2][7][2][42]
+[2][8][2][127]
+
+FILTER(TINYINT) v2 <= NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+
+TINYINT UNSIGNED -------------------------------------------------
+
+FILTER(TINYINT UNSIGNED) NO FILTER
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][9]
+[0][2][0][28]
+[0][3][0][85]
+[0][4][0][255]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][9]
+[1][2][1][28]
+[1][3][1][85]
+[1][4][1][255]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][9]
+[2][2][2][28]
+[2][3][2][85]
+[2][4][2][255]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 = 0
+code=0 rows=3
+[0][0][0][0]
+[1][0][1][0]
+[2][0][2][0]
+
+FILTER(TINYINT UNSIGNED) v2 != 0
+code=0 rows=15
+[0][1][0][9]
+[0][2][0][28]
+[0][3][0][85]
+[0][4][0][255]
+[0][5][0][NULL]
+[1][1][1][9]
+[1][2][1][28]
+[1][3][1][85]
+[1][4][1][255]
+[1][5][1][NULL]
+[2][1][2][9]
+[2][2][2][28]
+[2][3][2][85]
+[2][4][2][255]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 >= 0
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][9]
+[0][2][0][28]
+[0][3][0][85]
+[0][4][0][255]
+[1][0][1][0]
+[1][1][1][9]
+[1][2][1][28]
+[1][3][1][85]
+[1][4][1][255]
+[2][0][2][0]
+[2][1][2][9]
+[2][2][2][28]
+[2][3][2][85]
+[2][4][2][255]
+
+FILTER(TINYINT UNSIGNED) v2 < 0
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 > 0
+code=0 rows=12
+[0][1][0][9]
+[0][2][0][28]
+[0][3][0][85]
+[0][4][0][255]
+[1][1][1][9]
+[1][2][1][28]
+[1][3][1][85]
+[1][4][1][255]
+[2][1][2][9]
+[2][2][2][28]
+[2][3][2][85]
+[2][4][2][255]
+
+FILTER(TINYINT UNSIGNED) v2 <= 0
+code=0 rows=6
+[0][0][0][0]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 = 9
+code=0 rows=3
+[0][1][0][9]
+[1][1][1][9]
+[2][1][2][9]
+
+FILTER(TINYINT UNSIGNED) v2 != 9
+code=0 rows=15
+[0][0][0][0]
+[0][2][0][28]
+[0][3][0][85]
+[0][4][0][255]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][2][1][28]
+[1][3][1][85]
+[1][4][1][255]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][2][2][28]
+[2][3][2][85]
+[2][4][2][255]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 >= 9
+code=0 rows=12
+[0][1][0][9]
+[0][2][0][28]
+[0][3][0][85]
+[0][4][0][255]
+[1][1][1][9]
+[1][2][1][28]
+[1][3][1][85]
+[1][4][1][255]
+[2][1][2][9]
+[2][2][2][28]
+[2][3][2][85]
+[2][4][2][255]
+
+FILTER(TINYINT UNSIGNED) v2 < 9
+code=0 rows=6
+[0][0][0][0]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 > 9
+code=0 rows=9
+[0][2][0][28]
+[0][3][0][85]
+[0][4][0][255]
+[1][2][1][28]
+[1][3][1][85]
+[1][4][1][255]
+[2][2][2][28]
+[2][3][2][85]
+[2][4][2][255]
+
+FILTER(TINYINT UNSIGNED) v2 <= 9
+code=0 rows=9
+[0][0][0][0]
+[0][1][0][9]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][9]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][9]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 = 28
+code=0 rows=3
+[0][2][0][28]
+[1][2][1][28]
+[2][2][2][28]
+
+FILTER(TINYINT UNSIGNED) v2 != 28
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][9]
+[0][3][0][85]
+[0][4][0][255]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][9]
+[1][3][1][85]
+[1][4][1][255]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][9]
+[2][3][2][85]
+[2][4][2][255]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 >= 28
+code=0 rows=9
+[0][2][0][28]
+[0][3][0][85]
+[0][4][0][255]
+[1][2][1][28]
+[1][3][1][85]
+[1][4][1][255]
+[2][2][2][28]
+[2][3][2][85]
+[2][4][2][255]
+
+FILTER(TINYINT UNSIGNED) v2 < 28
+code=0 rows=9
+[0][0][0][0]
+[0][1][0][9]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][9]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][9]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 > 28
+code=0 rows=6
+[0][3][0][85]
+[0][4][0][255]
+[1][3][1][85]
+[1][4][1][255]
+[2][3][2][85]
+[2][4][2][255]
+
+FILTER(TINYINT UNSIGNED) v2 <= 28
+code=0 rows=12
+[0][0][0][0]
+[0][1][0][9]
+[0][2][0][28]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][9]
+[1][2][1][28]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][9]
+[2][2][2][28]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 = 85
+code=0 rows=3
+[0][3][0][85]
+[1][3][1][85]
+[2][3][2][85]
+
+FILTER(TINYINT UNSIGNED) v2 != 85
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][9]
+[0][2][0][28]
+[0][4][0][255]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][9]
+[1][2][1][28]
+[1][4][1][255]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][9]
+[2][2][2][28]
+[2][4][2][255]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 >= 85
+code=0 rows=6
+[0][3][0][85]
+[0][4][0][255]
+[1][3][1][85]
+[1][4][1][255]
+[2][3][2][85]
+[2][4][2][255]
+
+FILTER(TINYINT UNSIGNED) v2 < 85
+code=0 rows=12
+[0][0][0][0]
+[0][1][0][9]
+[0][2][0][28]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][9]
+[1][2][1][28]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][9]
+[2][2][2][28]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 > 85
+code=0 rows=3
+[0][4][0][255]
+[1][4][1][255]
+[2][4][2][255]
+
+FILTER(TINYINT UNSIGNED) v2 <= 85
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][9]
+[0][2][0][28]
+[0][3][0][85]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][9]
+[1][2][1][28]
+[1][3][1][85]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][9]
+[2][2][2][28]
+[2][3][2][85]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 = 255
+code=0 rows=3
+[0][4][0][255]
+[1][4][1][255]
+[2][4][2][255]
+
+FILTER(TINYINT UNSIGNED) v2 != 255
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][9]
+[0][2][0][28]
+[0][3][0][85]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][9]
+[1][2][1][28]
+[1][3][1][85]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][9]
+[2][2][2][28]
+[2][3][2][85]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 >= 255
+code=0 rows=3
+[0][4][0][255]
+[1][4][1][255]
+[2][4][2][255]
+
+FILTER(TINYINT UNSIGNED) v2 < 255
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][9]
+[0][2][0][28]
+[0][3][0][85]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][9]
+[1][2][1][28]
+[1][3][1][85]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][9]
+[2][2][2][28]
+[2][3][2][85]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 > 255
+code=0 rows=0
+
+FILTER(TINYINT UNSIGNED) v2 <= 255
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][9]
+[0][2][0][28]
+[0][3][0][85]
+[0][4][0][255]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][9]
+[1][2][1][28]
+[1][3][1][85]
+[1][4][1][255]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][9]
+[2][2][2][28]
+[2][3][2][85]
+[2][4][2][255]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 = NULL
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 != NULL
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][9]
+[0][2][0][28]
+[0][3][0][85]
+[0][4][0][255]
+[1][0][1][0]
+[1][1][1][9]
+[1][2][1][28]
+[1][3][1][85]
+[1][4][1][255]
+[2][0][2][0]
+[2][1][2][9]
+[2][2][2][28]
+[2][3][2][85]
+[2][4][2][255]
+
+FILTER(TINYINT UNSIGNED) v2 >= NULL
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][9]
+[0][2][0][28]
+[0][3][0][85]
+[0][4][0][255]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][9]
+[1][2][1][28]
+[1][3][1][85]
+[1][4][1][255]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][9]
+[2][2][2][28]
+[2][3][2][85]
+[2][4][2][255]
+[2][5][2][NULL]
+
+FILTER(TINYINT UNSIGNED) v2 < NULL
+code=0 rows=0
+
+FILTER(TINYINT UNSIGNED) v2 > NULL
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][9]
+[0][2][0][28]
+[0][3][0][85]
+[0][4][0][255]
+[1][0][1][0]
+[1][1][1][9]
+[1][2][1][28]
+[1][3][1][85]
+[1][4][1][255]
+[2][0][2][0]
+[2][1][2][9]
+[2][2][2][28]
+[2][3][2][85]
+[2][4][2][255]
+
+FILTER(TINYINT UNSIGNED) v2 <= NULL
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+
+SMALLINT -------------------------------------------------
+
+FILTER(SMALLINT) NO FILTER
+code=0 rows=30
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 = -32768
+code=0 rows=3
+[0][0][0][-32768]
+[1][0][1][-32768]
+[2][0][2][-32768]
+
+FILTER(SMALLINT) v2 != -32768
+code=0 rows=27
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[0][9][0][NULL]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[1][9][1][NULL]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 >= -32768
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 < -32768
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 > -32768
+code=0 rows=24
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 <= -32768
+code=0 rows=6
+[0][0][0][-32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 = -10922
+code=0 rows=3
+[0][1][0][-10922]
+[1][1][1][-10922]
+[2][1][2][-10922]
+
+FILTER(SMALLINT) v2 != -10922
+code=0 rows=27
+[0][0][0][-32768]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 >= -10922
+code=0 rows=24
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 < -10922
+code=0 rows=6
+[0][0][0][-32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 > -10922
+code=0 rows=21
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 <= -10922
+code=0 rows=9
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 = -3640
+code=0 rows=3
+[0][2][0][-3640]
+[1][2][1][-3640]
+[2][2][2][-3640]
+
+FILTER(SMALLINT) v2 != -3640
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 >= -3640
+code=0 rows=21
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 < -3640
+code=0 rows=9
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 > -3640
+code=0 rows=18
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 <= -3640
+code=0 rows=12
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 = -1213
+code=0 rows=3
+[0][3][0][-1213]
+[1][3][1][-1213]
+[2][3][2][-1213]
+
+FILTER(SMALLINT) v2 != -1213
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 >= -1213
+code=0 rows=18
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 < -1213
+code=0 rows=12
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 > -1213
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 <= -1213
+code=0 rows=15
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 = 0
+code=0 rows=3
+[0][4][0][0]
+[1][4][1][0]
+[2][4][2][0]
+
+FILTER(SMALLINT) v2 != 0
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 >= 0
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 < 0
+code=0 rows=15
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 > 0
+code=0 rows=12
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 <= 0
+code=0 rows=18
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 = 1213
+code=0 rows=3
+[0][5][0][1213]
+[1][5][1][1213]
+[2][5][2][1213]
+
+FILTER(SMALLINT) v2 != 1213
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 >= 1213
+code=0 rows=12
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 < 1213
+code=0 rows=18
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 > 1213
+code=0 rows=9
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 <= 1213
+code=0 rows=21
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 = 3640
+code=0 rows=3
+[0][6][0][3640]
+[1][6][1][3640]
+[2][6][2][3640]
+
+FILTER(SMALLINT) v2 != 3640
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][7][0][10922]
+[0][8][0][32767]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][7][1][10922]
+[1][8][1][32767]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][7][2][10922]
+[2][8][2][32767]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 >= 3640
+code=0 rows=9
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 < 3640
+code=0 rows=21
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 > 3640
+code=0 rows=6
+[0][7][0][10922]
+[0][8][0][32767]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 <= 3640
+code=0 rows=24
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 = 10922
+code=0 rows=3
+[0][7][0][10922]
+[1][7][1][10922]
+[2][7][2][10922]
+
+FILTER(SMALLINT) v2 != 10922
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][8][0][32767]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][8][1][32767]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][8][2][32767]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 >= 10922
+code=0 rows=6
+[0][7][0][10922]
+[0][8][0][32767]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 < 10922
+code=0 rows=24
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 > 10922
+code=0 rows=3
+[0][8][0][32767]
+[1][8][1][32767]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 <= 10922
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 = 32768
+code=0 rows=3
+[0][8][0][32767]
+[1][8][1][32767]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 != 32768
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 >= 32768
+code=0 rows=3
+[0][8][0][32767]
+[1][8][1][32767]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 < 32768
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 > 32768
+code=0 rows=0
+
+FILTER(SMALLINT) v2 <= 32768
+code=0 rows=30
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 = NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 != NULL
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 >= NULL
+code=0 rows=30
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+[2][9][2][NULL]
+
+FILTER(SMALLINT) v2 < NULL
+code=0 rows=0
+
+FILTER(SMALLINT) v2 > NULL
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32767]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32767]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32767]
+
+FILTER(SMALLINT) v2 <= NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+
+SMALLINT UNSIGNED -------------------------------------------------
+
+FILTER(SMALLINT UNSIGNED) NO FILTER
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][2427]
+[0][2][0][7281]
+[0][3][0][21845]
+[0][4][0][65535]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][4][1][65535]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][4][2][65535]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 = 0
+code=0 rows=3
+[0][0][0][0]
+[1][0][1][0]
+[2][0][2][0]
+
+FILTER(SMALLINT UNSIGNED) v2 != 0
+code=0 rows=15
+[0][1][0][2427]
+[0][2][0][7281]
+[0][3][0][21845]
+[0][4][0][65535]
+[0][5][0][NULL]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][4][1][65535]
+[1][5][1][NULL]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][4][2][65535]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 >= 0
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][2427]
+[0][2][0][7281]
+[0][3][0][21845]
+[0][4][0][65535]
+[1][0][1][0]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][4][1][65535]
+[2][0][2][0]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][4][2][65535]
+
+FILTER(SMALLINT UNSIGNED) v2 < 0
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 > 0
+code=0 rows=12
+[0][1][0][2427]
+[0][2][0][7281]
+[0][3][0][21845]
+[0][4][0][65535]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][4][1][65535]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][4][2][65535]
+
+FILTER(SMALLINT UNSIGNED) v2 <= 0
+code=0 rows=6
+[0][0][0][0]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 = 2427
+code=0 rows=3
+[0][1][0][2427]
+[1][1][1][2427]
+[2][1][2][2427]
+
+FILTER(SMALLINT UNSIGNED) v2 != 2427
+code=0 rows=15
+[0][0][0][0]
+[0][2][0][7281]
+[0][3][0][21845]
+[0][4][0][65535]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][4][1][65535]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][4][2][65535]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 >= 2427
+code=0 rows=12
+[0][1][0][2427]
+[0][2][0][7281]
+[0][3][0][21845]
+[0][4][0][65535]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][4][1][65535]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][4][2][65535]
+
+FILTER(SMALLINT UNSIGNED) v2 < 2427
+code=0 rows=6
+[0][0][0][0]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 > 2427
+code=0 rows=9
+[0][2][0][7281]
+[0][3][0][21845]
+[0][4][0][65535]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][4][1][65535]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][4][2][65535]
+
+FILTER(SMALLINT UNSIGNED) v2 <= 2427
+code=0 rows=9
+[0][0][0][0]
+[0][1][0][2427]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][2427]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][2427]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 = 7281
+code=0 rows=3
+[0][2][0][7281]
+[1][2][1][7281]
+[2][2][2][7281]
+
+FILTER(SMALLINT UNSIGNED) v2 != 7281
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][2427]
+[0][3][0][21845]
+[0][4][0][65535]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][2427]
+[1][3][1][21845]
+[1][4][1][65535]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][2427]
+[2][3][2][21845]
+[2][4][2][65535]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 >= 7281
+code=0 rows=9
+[0][2][0][7281]
+[0][3][0][21845]
+[0][4][0][65535]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][4][1][65535]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][4][2][65535]
+
+FILTER(SMALLINT UNSIGNED) v2 < 7281
+code=0 rows=9
+[0][0][0][0]
+[0][1][0][2427]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][2427]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][2427]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 > 7281
+code=0 rows=6
+[0][3][0][21845]
+[0][4][0][65535]
+[1][3][1][21845]
+[1][4][1][65535]
+[2][3][2][21845]
+[2][4][2][65535]
+
+FILTER(SMALLINT UNSIGNED) v2 <= 7281
+code=0 rows=12
+[0][0][0][0]
+[0][1][0][2427]
+[0][2][0][7281]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 = 21845
+code=0 rows=3
+[0][3][0][21845]
+[1][3][1][21845]
+[2][3][2][21845]
+
+FILTER(SMALLINT UNSIGNED) v2 != 21845
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][2427]
+[0][2][0][7281]
+[0][4][0][65535]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][4][1][65535]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][4][2][65535]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 >= 21845
+code=0 rows=6
+[0][3][0][21845]
+[0][4][0][65535]
+[1][3][1][21845]
+[1][4][1][65535]
+[2][3][2][21845]
+[2][4][2][65535]
+
+FILTER(SMALLINT UNSIGNED) v2 < 21845
+code=0 rows=12
+[0][0][0][0]
+[0][1][0][2427]
+[0][2][0][7281]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 > 21845
+code=0 rows=3
+[0][4][0][65535]
+[1][4][1][65535]
+[2][4][2][65535]
+
+FILTER(SMALLINT UNSIGNED) v2 <= 21845
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][2427]
+[0][2][0][7281]
+[0][3][0][21845]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 = 65535
+code=0 rows=3
+[0][4][0][65535]
+[1][4][1][65535]
+[2][4][2][65535]
+
+FILTER(SMALLINT UNSIGNED) v2 != 65535
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][2427]
+[0][2][0][7281]
+[0][3][0][21845]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 >= 65535
+code=0 rows=3
+[0][4][0][65535]
+[1][4][1][65535]
+[2][4][2][65535]
+
+FILTER(SMALLINT UNSIGNED) v2 < 65535
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][2427]
+[0][2][0][7281]
+[0][3][0][21845]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 > 65535
+code=0 rows=0
+
+FILTER(SMALLINT UNSIGNED) v2 <= 65535
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][2427]
+[0][2][0][7281]
+[0][3][0][21845]
+[0][4][0][65535]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][4][1][65535]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][4][2][65535]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 = NULL
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 != NULL
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][2427]
+[0][2][0][7281]
+[0][3][0][21845]
+[0][4][0][65535]
+[1][0][1][0]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][4][1][65535]
+[2][0][2][0]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][4][2][65535]
+
+FILTER(SMALLINT UNSIGNED) v2 >= NULL
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][2427]
+[0][2][0][7281]
+[0][3][0][21845]
+[0][4][0][65535]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][4][1][65535]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][4][2][65535]
+[2][5][2][NULL]
+
+FILTER(SMALLINT UNSIGNED) v2 < NULL
+code=0 rows=0
+
+FILTER(SMALLINT UNSIGNED) v2 > NULL
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][2427]
+[0][2][0][7281]
+[0][3][0][21845]
+[0][4][0][65535]
+[1][0][1][0]
+[1][1][1][2427]
+[1][2][1][7281]
+[1][3][1][21845]
+[1][4][1][65535]
+[2][0][2][0]
+[2][1][2][2427]
+[2][2][2][7281]
+[2][3][2][21845]
+[2][4][2][65535]
+
+FILTER(SMALLINT UNSIGNED) v2 <= NULL
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+
+MEDIUMINT -------------------------------------------------
+
+FILTER(MEDIUMINT) NO FILTER
+code=0 rows=30
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 = -8388608
+code=0 rows=3
+[0][0][0][-8388608]
+[1][0][1][-8388608]
+[2][0][2][-8388608]
+
+FILTER(MEDIUMINT) v2 != -8388608
+code=0 rows=27
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[0][9][0][NULL]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[1][9][1][NULL]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 >= -8388608
+code=0 rows=27
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 < -8388608
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 > -8388608
+code=0 rows=24
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 <= -8388608
+code=0 rows=6
+[0][0][0][-8388608]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 = -2796202
+code=0 rows=3
+[0][1][0][-2796202]
+[1][1][1][-2796202]
+[2][1][2][-2796202]
+
+FILTER(MEDIUMINT) v2 != -2796202
+code=0 rows=27
+[0][0][0][-8388608]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 >= -2796202
+code=0 rows=24
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 < -2796202
+code=0 rows=6
+[0][0][0][-8388608]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 > -2796202
+code=0 rows=21
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 <= -2796202
+code=0 rows=9
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 = -932067
+code=0 rows=3
+[0][2][0][-932067]
+[1][2][1][-932067]
+[2][2][2][-932067]
+
+FILTER(MEDIUMINT) v2 != -932067
+code=0 rows=27
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 >= -932067
+code=0 rows=21
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 < -932067
+code=0 rows=9
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 > -932067
+code=0 rows=18
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 <= -932067
+code=0 rows=12
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 = -310689
+code=0 rows=3
+[0][3][0][-310689]
+[1][3][1][-310689]
+[2][3][2][-310689]
+
+FILTER(MEDIUMINT) v2 != -310689
+code=0 rows=27
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 >= -310689
+code=0 rows=18
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 < -310689
+code=0 rows=12
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 > -310689
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 <= -310689
+code=0 rows=15
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 = 0
+code=0 rows=3
+[0][4][0][0]
+[1][4][1][0]
+[2][4][2][0]
+
+FILTER(MEDIUMINT) v2 != 0
+code=0 rows=27
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 >= 0
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 < 0
+code=0 rows=15
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 > 0
+code=0 rows=12
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 <= 0
+code=0 rows=18
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 = 310689
+code=0 rows=3
+[0][5][0][310689]
+[1][5][1][310689]
+[2][5][2][310689]
+
+FILTER(MEDIUMINT) v2 != 310689
+code=0 rows=27
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 >= 310689
+code=0 rows=12
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 < 310689
+code=0 rows=18
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 > 310689
+code=0 rows=9
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 <= 310689
+code=0 rows=21
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 = 932067
+code=0 rows=3
+[0][6][0][932067]
+[1][6][1][932067]
+[2][6][2][932067]
+
+FILTER(MEDIUMINT) v2 != 932067
+code=0 rows=27
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][7][2][2796202]
+[2][8][2][8388607]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 >= 932067
+code=0 rows=9
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 < 932067
+code=0 rows=21
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 > 932067
+code=0 rows=6
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 <= 932067
+code=0 rows=24
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 = 2796202
+code=0 rows=3
+[0][7][0][2796202]
+[1][7][1][2796202]
+[2][7][2][2796202]
+
+FILTER(MEDIUMINT) v2 != 2796202
+code=0 rows=27
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][8][0][8388607]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][8][1][8388607]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][8][2][8388607]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 >= 2796202
+code=0 rows=6
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 < 2796202
+code=0 rows=24
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 > 2796202
+code=0 rows=3
+[0][8][0][8388607]
+[1][8][1][8388607]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 <= 2796202
+code=0 rows=27
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 = 8388607
+code=0 rows=3
+[0][8][0][8388607]
+[1][8][1][8388607]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 != 8388607
+code=0 rows=27
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 >= 8388607
+code=0 rows=3
+[0][8][0][8388607]
+[1][8][1][8388607]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 < 8388607
+code=0 rows=27
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 > 8388607
+code=0 rows=0
+
+FILTER(MEDIUMINT) v2 <= 8388607
+code=0 rows=30
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 = NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 != NULL
+code=0 rows=27
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 >= NULL
+code=0 rows=30
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[0][9][0][NULL]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[1][9][1][NULL]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+[2][9][2][NULL]
+
+FILTER(MEDIUMINT) v2 < NULL
+code=0 rows=0
+
+FILTER(MEDIUMINT) v2 > NULL
+code=0 rows=27
+[0][0][0][-8388608]
+[0][1][0][-2796202]
+[0][2][0][-932067]
+[0][3][0][-310689]
+[0][4][0][0]
+[0][5][0][310689]
+[0][6][0][932067]
+[0][7][0][2796202]
+[0][8][0][8388607]
+[1][0][1][-8388608]
+[1][1][1][-2796202]
+[1][2][1][-932067]
+[1][3][1][-310689]
+[1][4][1][0]
+[1][5][1][310689]
+[1][6][1][932067]
+[1][7][1][2796202]
+[1][8][1][8388607]
+[2][0][2][-8388608]
+[2][1][2][-2796202]
+[2][2][2][-932067]
+[2][3][2][-310689]
+[2][4][2][0]
+[2][5][2][310689]
+[2][6][2][932067]
+[2][7][2][2796202]
+[2][8][2][8388607]
+
+FILTER(MEDIUMINT) v2 <= NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+
+MEDIUMINT UNSIGNED -------------------------------------------------
+
+FILTER(MEDIUMINT UNSIGNED) NO FILTER
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][4][0][16777215]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][4][2][16777215]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 = 0
+code=0 rows=3
+[0][0][0][0]
+[1][0][1][0]
+[2][0][2][0]
+
+FILTER(MEDIUMINT UNSIGNED) v2 != 0
+code=0 rows=15
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][4][0][16777215]
+[0][5][0][NULL]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[1][5][1][NULL]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][4][2][16777215]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 >= 0
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][4][0][16777215]
+[1][0][1][0]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[2][0][2][0]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][4][2][16777215]
+
+FILTER(MEDIUMINT UNSIGNED) v2 < 0
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 > 0
+code=0 rows=12
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][4][0][16777215]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][4][2][16777215]
+
+FILTER(MEDIUMINT UNSIGNED) v2 <= 0
+code=0 rows=6
+[0][0][0][0]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 = 621378
+code=0 rows=3
+[0][1][0][621378]
+[1][1][1][621378]
+[2][1][2][621378]
+
+FILTER(MEDIUMINT UNSIGNED) v2 != 621378
+code=0 rows=15
+[0][0][0][0]
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][4][0][16777215]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][4][2][16777215]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 >= 621378
+code=0 rows=12
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][4][0][16777215]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][4][2][16777215]
+
+FILTER(MEDIUMINT UNSIGNED) v2 < 621378
+code=0 rows=6
+[0][0][0][0]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 > 621378
+code=0 rows=9
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][4][0][16777215]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][4][2][16777215]
+
+FILTER(MEDIUMINT UNSIGNED) v2 <= 621378
+code=0 rows=9
+[0][0][0][0]
+[0][1][0][621378]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][621378]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][621378]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 = 1864135
+code=0 rows=3
+[0][2][0][1864135]
+[1][2][1][1864135]
+[2][2][2][1864135]
+
+FILTER(MEDIUMINT UNSIGNED) v2 != 1864135
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][621378]
+[0][3][0][5592405]
+[0][4][0][16777215]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][621378]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][621378]
+[2][3][2][5592405]
+[2][4][2][16777215]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 >= 1864135
+code=0 rows=9
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][4][0][16777215]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][4][2][16777215]
+
+FILTER(MEDIUMINT UNSIGNED) v2 < 1864135
+code=0 rows=9
+[0][0][0][0]
+[0][1][0][621378]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][621378]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][621378]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 > 1864135
+code=0 rows=6
+[0][3][0][5592405]
+[0][4][0][16777215]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[2][3][2][5592405]
+[2][4][2][16777215]
+
+FILTER(MEDIUMINT UNSIGNED) v2 <= 1864135
+code=0 rows=12
+[0][0][0][0]
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 = 5592405
+code=0 rows=3
+[0][3][0][5592405]
+[1][3][1][5592405]
+[2][3][2][5592405]
+
+FILTER(MEDIUMINT UNSIGNED) v2 != 5592405
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][4][0][16777215]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][4][1][16777215]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][4][2][16777215]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 >= 5592405
+code=0 rows=6
+[0][3][0][5592405]
+[0][4][0][16777215]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[2][3][2][5592405]
+[2][4][2][16777215]
+
+FILTER(MEDIUMINT UNSIGNED) v2 < 5592405
+code=0 rows=12
+[0][0][0][0]
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 > 5592405
+code=0 rows=3
+[0][4][0][16777215]
+[1][4][1][16777215]
+[2][4][2][16777215]
+
+FILTER(MEDIUMINT UNSIGNED) v2 <= 5592405
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 = 16777215
+code=0 rows=3
+[0][4][0][16777215]
+[1][4][1][16777215]
+[2][4][2][16777215]
+
+FILTER(MEDIUMINT UNSIGNED) v2 != 16777215
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 >= 16777215
+code=0 rows=3
+[0][4][0][16777215]
+[1][4][1][16777215]
+[2][4][2][16777215]
+
+FILTER(MEDIUMINT UNSIGNED) v2 < 16777215
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 > 16777215
+code=0 rows=0
+
+FILTER(MEDIUMINT UNSIGNED) v2 <= 16777215
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][4][0][16777215]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][4][2][16777215]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 = NULL
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 != NULL
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][4][0][16777215]
+[1][0][1][0]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[2][0][2][0]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][4][2][16777215]
+
+FILTER(MEDIUMINT UNSIGNED) v2 >= NULL
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][4][0][16777215]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][4][2][16777215]
+[2][5][2][NULL]
+
+FILTER(MEDIUMINT UNSIGNED) v2 < NULL
+code=0 rows=0
+
+FILTER(MEDIUMINT UNSIGNED) v2 > NULL
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][621378]
+[0][2][0][1864135]
+[0][3][0][5592405]
+[0][4][0][16777215]
+[1][0][1][0]
+[1][1][1][621378]
+[1][2][1][1864135]
+[1][3][1][5592405]
+[1][4][1][16777215]
+[2][0][2][0]
+[2][1][2][621378]
+[2][2][2][1864135]
+[2][3][2][5592405]
+[2][4][2][16777215]
+
+FILTER(MEDIUMINT UNSIGNED) v2 <= NULL
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+
+INT -------------------------------------------------
+
+FILTER(INT) NO FILTER
+code=0 rows=30
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(INT) v2 = -2147483648
+code=0 rows=3
+[0][0][0][-2147483648]
+[1][0][1][-2147483648]
+[2][0][2][-2147483648]
+
+FILTER(INT) v2 != -2147483648
+code=0 rows=27
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(INT) v2 >= -2147483648
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 < -2147483648
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(INT) v2 > -2147483648
+code=0 rows=24
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 <= -2147483648
+code=0 rows=6
+[0][0][0][-2147483648]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][9][2][NULL]
+
+FILTER(INT) v2 = -715827882
+code=0 rows=3
+[0][1][0][-715827882]
+[1][1][1][-715827882]
+[2][1][2][-715827882]
+
+FILTER(INT) v2 != -715827882
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(INT) v2 >= -715827882
+code=0 rows=24
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 < -715827882
+code=0 rows=6
+[0][0][0][-2147483648]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][9][2][NULL]
+
+FILTER(INT) v2 > -715827882
+code=0 rows=21
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 <= -715827882
+code=0 rows=9
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][9][2][NULL]
+
+FILTER(INT) v2 = -238609294
+code=0 rows=3
+[0][2][0][-238609294]
+[1][2][1][-238609294]
+[2][2][2][-238609294]
+
+FILTER(INT) v2 != -238609294
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(INT) v2 >= -238609294
+code=0 rows=21
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 < -238609294
+code=0 rows=9
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][9][2][NULL]
+
+FILTER(INT) v2 > -238609294
+code=0 rows=18
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 <= -238609294
+code=0 rows=12
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][9][2][NULL]
+
+FILTER(INT) v2 = -79536431
+code=0 rows=3
+[0][3][0][-79536431]
+[1][3][1][-79536431]
+[2][3][2][-79536431]
+
+FILTER(INT) v2 != -79536431
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(INT) v2 >= -79536431
+code=0 rows=18
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 < -79536431
+code=0 rows=12
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][9][2][NULL]
+
+FILTER(INT) v2 > -79536431
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 <= -79536431
+code=0 rows=15
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][9][2][NULL]
+
+FILTER(INT) v2 = 0
+code=0 rows=3
+[0][4][0][0]
+[1][4][1][0]
+[2][4][2][0]
+
+FILTER(INT) v2 != 0
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(INT) v2 >= 0
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 < 0
+code=0 rows=15
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][9][2][NULL]
+
+FILTER(INT) v2 > 0
+code=0 rows=12
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 <= 0
+code=0 rows=18
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(INT) v2 = 79536431
+code=0 rows=3
+[0][5][0][79536431]
+[1][5][1][79536431]
+[2][5][2][79536431]
+
+FILTER(INT) v2 != 79536431
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(INT) v2 >= 79536431
+code=0 rows=12
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 < 79536431
+code=0 rows=18
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(INT) v2 > 79536431
+code=0 rows=9
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 <= 79536431
+code=0 rows=21
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][9][2][NULL]
+
+FILTER(INT) v2 = 238609294
+code=0 rows=3
+[0][6][0][238609294]
+[1][6][1][238609294]
+[2][6][2][238609294]
+
+FILTER(INT) v2 != 238609294
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(INT) v2 >= 238609294
+code=0 rows=9
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 < 238609294
+code=0 rows=21
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][9][2][NULL]
+
+FILTER(INT) v2 > 238609294
+code=0 rows=6
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 <= 238609294
+code=0 rows=24
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][9][2][NULL]
+
+FILTER(INT) v2 = 715827882
+code=0 rows=3
+[0][7][0][715827882]
+[1][7][1][715827882]
+[2][7][2][715827882]
+
+FILTER(INT) v2 != 715827882
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(INT) v2 >= 715827882
+code=0 rows=6
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 < 715827882
+code=0 rows=24
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][9][2][NULL]
+
+FILTER(INT) v2 > 715827882
+code=0 rows=3
+[0][8][0][2147483647]
+[1][8][1][2147483647]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 <= 715827882
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][9][2][NULL]
+
+FILTER(INT) v2 = 2147483647
+code=0 rows=3
+[0][8][0][2147483647]
+[1][8][1][2147483647]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 != 2147483647
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][9][2][NULL]
+
+FILTER(INT) v2 >= 2147483647
+code=0 rows=3
+[0][8][0][2147483647]
+[1][8][1][2147483647]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 < 2147483647
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][9][2][NULL]
+
+FILTER(INT) v2 > 2147483647
+code=0 rows=0
+
+FILTER(INT) v2 <= 2147483647
+code=0 rows=30
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(INT) v2 = NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(INT) v2 != NULL
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 >= NULL
+code=0 rows=30
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(INT) v2 < NULL
+code=0 rows=0
+
+FILTER(INT) v2 > NULL
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(INT) v2 <= NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+
+INT UNSIGNED -------------------------------------------------
+
+FILTER(INT UNSIGNED) NO FILTER
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 = 0
+code=0 rows=3
+[0][0][0][0]
+[1][0][1][0]
+[2][0][2][0]
+
+FILTER(INT UNSIGNED) v2 != 0
+code=0 rows=15
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[0][5][0][NULL]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[1][5][1][NULL]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 >= 0
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+
+FILTER(INT UNSIGNED) v2 < 0
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 > 0
+code=0 rows=12
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+
+FILTER(INT UNSIGNED) v2 <= 0
+code=0 rows=6
+[0][0][0][0]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 = 159072862
+code=0 rows=3
+[0][1][0][159072862]
+[1][1][1][159072862]
+[2][1][2][159072862]
+
+FILTER(INT UNSIGNED) v2 != 159072862
+code=0 rows=15
+[0][0][0][0]
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 >= 159072862
+code=0 rows=12
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+
+FILTER(INT UNSIGNED) v2 < 159072862
+code=0 rows=6
+[0][0][0][0]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 > 159072862
+code=0 rows=9
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+
+FILTER(INT UNSIGNED) v2 <= 159072862
+code=0 rows=9
+[0][0][0][0]
+[0][1][0][159072862]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 = 477218588
+code=0 rows=3
+[0][2][0][477218588]
+[1][2][1][477218588]
+[2][2][2][477218588]
+
+FILTER(INT UNSIGNED) v2 != 477218588
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][159072862]
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 >= 477218588
+code=0 rows=9
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+
+FILTER(INT UNSIGNED) v2 < 477218588
+code=0 rows=9
+[0][0][0][0]
+[0][1][0][159072862]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 > 477218588
+code=0 rows=6
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+
+FILTER(INT UNSIGNED) v2 <= 477218588
+code=0 rows=12
+[0][0][0][0]
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 = 1431655765
+code=0 rows=3
+[0][3][0][1431655765]
+[1][3][1][1431655765]
+[2][3][2][1431655765]
+
+FILTER(INT UNSIGNED) v2 != 1431655765
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][4][0][4294967295]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][4][1][4294967295]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][4][2][4294967295]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 >= 1431655765
+code=0 rows=6
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+
+FILTER(INT UNSIGNED) v2 < 1431655765
+code=0 rows=12
+[0][0][0][0]
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 > 1431655765
+code=0 rows=3
+[0][4][0][4294967295]
+[1][4][1][4294967295]
+[2][4][2][4294967295]
+
+FILTER(INT UNSIGNED) v2 <= 1431655765
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 = 4294967295
+code=0 rows=3
+[0][4][0][4294967295]
+[1][4][1][4294967295]
+[2][4][2][4294967295]
+
+FILTER(INT UNSIGNED) v2 != 4294967295
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 >= 4294967295
+code=0 rows=3
+[0][4][0][4294967295]
+[1][4][1][4294967295]
+[2][4][2][4294967295]
+
+FILTER(INT UNSIGNED) v2 < 4294967295
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 > 4294967295
+code=0 rows=0
+
+FILTER(INT UNSIGNED) v2 <= 4294967295
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 = NULL
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 != NULL
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+
+FILTER(INT UNSIGNED) v2 >= NULL
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+[2][5][2][NULL]
+
+FILTER(INT UNSIGNED) v2 < NULL
+code=0 rows=0
+
+FILTER(INT UNSIGNED) v2 > NULL
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][159072862]
+[0][2][0][477218588]
+[0][3][0][1431655765]
+[0][4][0][4294967295]
+[1][0][1][0]
+[1][1][1][159072862]
+[1][2][1][477218588]
+[1][3][1][1431655765]
+[1][4][1][4294967295]
+[2][0][2][0]
+[2][1][2][159072862]
+[2][2][2][477218588]
+[2][3][2][1431655765]
+[2][4][2][4294967295]
+
+FILTER(INT UNSIGNED) v2 <= NULL
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+
+BIGINT -------------------------------------------------
+
+FILTER(BIGINT) NO FILTER
+code=0 rows=30
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 = -9223372036854775808
+code=0 rows=3
+[0][0][0][-9223372036854775808]
+[1][0][1][-9223372036854775808]
+[2][0][2][-9223372036854775808]
+
+FILTER(BIGINT) v2 != -9223372036854775808
+code=0 rows=27
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[0][9][0][NULL]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[1][9][1][NULL]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 >= -9223372036854775808
+code=0 rows=27
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 < -9223372036854775808
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 > -9223372036854775808
+code=0 rows=24
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 <= -9223372036854775808
+code=0 rows=6
+[0][0][0][-9223372036854775808]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 = -3074457345618258602
+code=0 rows=3
+[0][1][0][-3074457345618258602]
+[1][1][1][-3074457345618258602]
+[2][1][2][-3074457345618258602]
+
+FILTER(BIGINT) v2 != -3074457345618258602
+code=0 rows=27
+[0][0][0][-9223372036854775808]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 >= -3074457345618258602
+code=0 rows=24
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 < -3074457345618258602
+code=0 rows=6
+[0][0][0][-9223372036854775808]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 > -3074457345618258602
+code=0 rows=21
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 <= -3074457345618258602
+code=0 rows=9
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 = -1024819115206086200
+code=0 rows=3
+[0][2][0][-1024819115206086200]
+[1][2][1][-1024819115206086200]
+[2][2][2][-1024819115206086200]
+
+FILTER(BIGINT) v2 != -1024819115206086200
+code=0 rows=27
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 >= -1024819115206086200
+code=0 rows=21
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 < -1024819115206086200
+code=0 rows=9
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 > -1024819115206086200
+code=0 rows=18
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 <= -1024819115206086200
+code=0 rows=12
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 = -341606371735362066
+code=0 rows=3
+[0][3][0][-341606371735362066]
+[1][3][1][-341606371735362066]
+[2][3][2][-341606371735362066]
+
+FILTER(BIGINT) v2 != -341606371735362066
+code=0 rows=27
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 >= -341606371735362066
+code=0 rows=18
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 < -341606371735362066
+code=0 rows=12
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 > -341606371735362066
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 <= -341606371735362066
+code=0 rows=15
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 = 0
+code=0 rows=3
+[0][4][0][0]
+[1][4][1][0]
+[2][4][2][0]
+
+FILTER(BIGINT) v2 != 0
+code=0 rows=27
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 >= 0
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 < 0
+code=0 rows=15
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 > 0
+code=0 rows=12
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 <= 0
+code=0 rows=18
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 = 341606371735362066
+code=0 rows=3
+[0][5][0][341606371735362066]
+[1][5][1][341606371735362066]
+[2][5][2][341606371735362066]
+
+FILTER(BIGINT) v2 != 341606371735362066
+code=0 rows=27
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 >= 341606371735362066
+code=0 rows=12
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 < 341606371735362066
+code=0 rows=18
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 > 341606371735362066
+code=0 rows=9
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 <= 341606371735362066
+code=0 rows=21
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 = 1024819115206086200
+code=0 rows=3
+[0][6][0][1024819115206086200]
+[1][6][1][1024819115206086200]
+[2][6][2][1024819115206086200]
+
+FILTER(BIGINT) v2 != 1024819115206086200
+code=0 rows=27
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 >= 1024819115206086200
+code=0 rows=9
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 < 1024819115206086200
+code=0 rows=21
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 > 1024819115206086200
+code=0 rows=6
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 <= 1024819115206086200
+code=0 rows=24
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 = 3074457345618258602
+code=0 rows=3
+[0][7][0][3074457345618258602]
+[1][7][1][3074457345618258602]
+[2][7][2][3074457345618258602]
+
+FILTER(BIGINT) v2 != 3074457345618258602
+code=0 rows=27
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][8][0][9223372036854775807]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][8][1][9223372036854775807]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][8][2][9223372036854775807]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 >= 3074457345618258602
+code=0 rows=6
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 < 3074457345618258602
+code=0 rows=24
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 > 3074457345618258602
+code=0 rows=3
+[0][8][0][9223372036854775807]
+[1][8][1][9223372036854775807]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 <= 3074457345618258602
+code=0 rows=27
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 = 9223372036854775807
+code=0 rows=3
+[0][8][0][9223372036854775807]
+[1][8][1][9223372036854775807]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 != 9223372036854775807
+code=0 rows=27
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 >= 9223372036854775807
+code=0 rows=3
+[0][8][0][9223372036854775807]
+[1][8][1][9223372036854775807]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 < 9223372036854775807
+code=0 rows=27
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 > 9223372036854775807
+code=0 rows=0
+
+FILTER(BIGINT) v2 <= 9223372036854775807
+code=0 rows=30
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 = NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 != NULL
+code=0 rows=27
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 >= NULL
+code=0 rows=30
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[0][9][0][NULL]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[1][9][1][NULL]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+[2][9][2][NULL]
+
+FILTER(BIGINT) v2 < NULL
+code=0 rows=0
+
+FILTER(BIGINT) v2 > NULL
+code=0 rows=27
+[0][0][0][-9223372036854775808]
+[0][1][0][-3074457345618258602]
+[0][2][0][-1024819115206086200]
+[0][3][0][-341606371735362066]
+[0][4][0][0]
+[0][5][0][341606371735362066]
+[0][6][0][1024819115206086200]
+[0][7][0][3074457345618258602]
+[0][8][0][9223372036854775807]
+[1][0][1][-9223372036854775808]
+[1][1][1][-3074457345618258602]
+[1][2][1][-1024819115206086200]
+[1][3][1][-341606371735362066]
+[1][4][1][0]
+[1][5][1][341606371735362066]
+[1][6][1][1024819115206086200]
+[1][7][1][3074457345618258602]
+[1][8][1][9223372036854775807]
+[2][0][2][-9223372036854775808]
+[2][1][2][-3074457345618258602]
+[2][2][2][-1024819115206086200]
+[2][3][2][-341606371735362066]
+[2][4][2][0]
+[2][5][2][341606371735362066]
+[2][6][2][1024819115206086200]
+[2][7][2][3074457345618258602]
+[2][8][2][9223372036854775807]
+
+FILTER(BIGINT) v2 <= NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+
+BIGINT UNSIGNED -------------------------------------------------
+
+FILTER(BIGINT UNSIGNED) NO FILTER
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 = 0
+code=0 rows=3
+[0][0][0][0]
+[1][0][1][0]
+[2][0][2][0]
+
+FILTER(BIGINT UNSIGNED) v2 != 0
+code=0 rows=15
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[0][5][0][NULL]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[1][5][1][NULL]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 >= 0
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+
+FILTER(BIGINT UNSIGNED) v2 < 0
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 > 0
+code=0 rows=12
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+
+FILTER(BIGINT UNSIGNED) v2 <= 0
+code=0 rows=6
+[0][0][0][0]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 = 683212743470724133
+code=0 rows=3
+[0][1][0][683212743470724133]
+[1][1][1][683212743470724133]
+[2][1][2][683212743470724133]
+
+FILTER(BIGINT UNSIGNED) v2 != 683212743470724133
+code=0 rows=15
+[0][0][0][0]
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 >= 683212743470724133
+code=0 rows=12
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+
+FILTER(BIGINT UNSIGNED) v2 < 683212743470724133
+code=0 rows=6
+[0][0][0][0]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 > 683212743470724133
+code=0 rows=9
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+
+FILTER(BIGINT UNSIGNED) v2 <= 683212743470724133
+code=0 rows=9
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 = 2049638230412172401
+code=0 rows=3
+[0][2][0][2049638230412172401]
+[1][2][1][2049638230412172401]
+[2][2][2][2049638230412172401]
+
+FILTER(BIGINT UNSIGNED) v2 != 2049638230412172401
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 >= 2049638230412172401
+code=0 rows=9
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+
+FILTER(BIGINT UNSIGNED) v2 < 2049638230412172401
+code=0 rows=9
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 > 2049638230412172401
+code=0 rows=6
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+
+FILTER(BIGINT UNSIGNED) v2 <= 2049638230412172401
+code=0 rows=12
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 = 6148914691236517205
+code=0 rows=3
+[0][3][0][6148914691236517205]
+[1][3][1][6148914691236517205]
+[2][3][2][6148914691236517205]
+
+FILTER(BIGINT UNSIGNED) v2 != 6148914691236517205
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][4][0][18446744073709551615]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][4][1][18446744073709551615]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][4][2][18446744073709551615]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 >= 6148914691236517205
+code=0 rows=6
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+
+FILTER(BIGINT UNSIGNED) v2 < 6148914691236517205
+code=0 rows=12
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 > 6148914691236517205
+code=0 rows=3
+[0][4][0][18446744073709551615]
+[1][4][1][18446744073709551615]
+[2][4][2][18446744073709551615]
+
+FILTER(BIGINT UNSIGNED) v2 <= 6148914691236517205
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 = 18446744073709551615
+code=0 rows=3
+[0][4][0][18446744073709551615]
+[1][4][1][18446744073709551615]
+[2][4][2][18446744073709551615]
+
+FILTER(BIGINT UNSIGNED) v2 != 18446744073709551615
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 >= 18446744073709551615
+code=0 rows=3
+[0][4][0][18446744073709551615]
+[1][4][1][18446744073709551615]
+[2][4][2][18446744073709551615]
+
+FILTER(BIGINT UNSIGNED) v2 < 18446744073709551615
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 > 18446744073709551615
+code=0 rows=0
+
+FILTER(BIGINT UNSIGNED) v2 <= 18446744073709551615
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 = NULL
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 != NULL
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+
+FILTER(BIGINT UNSIGNED) v2 >= NULL
+code=0 rows=18
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[0][5][0][NULL]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[1][5][1][NULL]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+[2][5][2][NULL]
+
+FILTER(BIGINT UNSIGNED) v2 < NULL
+code=0 rows=0
+
+FILTER(BIGINT UNSIGNED) v2 > NULL
+code=0 rows=15
+[0][0][0][0]
+[0][1][0][683212743470724133]
+[0][2][0][2049638230412172401]
+[0][3][0][6148914691236517205]
+[0][4][0][18446744073709551615]
+[1][0][1][0]
+[1][1][1][683212743470724133]
+[1][2][1][2049638230412172401]
+[1][3][1][6148914691236517205]
+[1][4][1][18446744073709551615]
+[2][0][2][0]
+[2][1][2][683212743470724133]
+[2][2][2][2049638230412172401]
+[2][3][2][6148914691236517205]
+[2][4][2][18446744073709551615]
+
+FILTER(BIGINT UNSIGNED) v2 <= NULL
+code=0 rows=3
+[0][5][0][NULL]
+[1][5][1][NULL]
+[2][5][2][NULL]
+
+
+FLOAT -------------------------------------------------
+
+FILTER(FLOAT) NO FILTER
+code=0 rows=30
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 = -32768
+code=0 rows=3
+[0][0][0][-32768]
+[1][0][1][-32768]
+[2][0][2][-32768]
+
+FILTER(FLOAT) v2 != -32768
+code=0 rows=27
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[0][9][0][NULL]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[1][9][1][NULL]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 >= -32768
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 < -32768
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 > -32768
+code=0 rows=24
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 <= -32768
+code=0 rows=6
+[0][0][0][-32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 = -10922
+code=0 rows=3
+[0][1][0][-10922]
+[1][1][1][-10922]
+[2][1][2][-10922]
+
+FILTER(FLOAT) v2 != -10922
+code=0 rows=27
+[0][0][0][-32768]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 >= -10922
+code=0 rows=24
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 < -10922
+code=0 rows=6
+[0][0][0][-32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 > -10922
+code=0 rows=21
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 <= -10922
+code=0 rows=9
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 = -3640
+code=0 rows=3
+[0][2][0][-3640]
+[1][2][1][-3640]
+[2][2][2][-3640]
+
+FILTER(FLOAT) v2 != -3640
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 >= -3640
+code=0 rows=21
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 < -3640
+code=0 rows=9
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 > -3640
+code=0 rows=18
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 <= -3640
+code=0 rows=12
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 = -1213
+code=0 rows=3
+[0][3][0][-1213]
+[1][3][1][-1213]
+[2][3][2][-1213]
+
+FILTER(FLOAT) v2 != -1213
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 >= -1213
+code=0 rows=18
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 < -1213
+code=0 rows=12
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 > -1213
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 <= -1213
+code=0 rows=15
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 = 0
+code=0 rows=3
+[0][4][0][0]
+[1][4][1][0]
+[2][4][2][0]
+
+FILTER(FLOAT) v2 != 0
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 >= 0
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 < 0
+code=0 rows=15
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 > 0
+code=0 rows=12
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 <= 0
+code=0 rows=18
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 = 1213
+code=0 rows=3
+[0][5][0][1213]
+[1][5][1][1213]
+[2][5][2][1213]
+
+FILTER(FLOAT) v2 != 1213
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 >= 1213
+code=0 rows=12
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 < 1213
+code=0 rows=18
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 > 1213
+code=0 rows=9
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 <= 1213
+code=0 rows=21
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 = 3640
+code=0 rows=3
+[0][6][0][3640]
+[1][6][1][3640]
+[2][6][2][3640]
+
+FILTER(FLOAT) v2 != 3640
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][7][0][10922]
+[0][8][0][32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][7][1][10922]
+[1][8][1][32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][7][2][10922]
+[2][8][2][32768]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 >= 3640
+code=0 rows=9
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 < 3640
+code=0 rows=21
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 > 3640
+code=0 rows=6
+[0][7][0][10922]
+[0][8][0][32768]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 <= 3640
+code=0 rows=24
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 = 10922
+code=0 rows=3
+[0][7][0][10922]
+[1][7][1][10922]
+[2][7][2][10922]
+
+FILTER(FLOAT) v2 != 10922
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][8][0][32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][8][1][32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][8][2][32768]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 >= 10922
+code=0 rows=6
+[0][7][0][10922]
+[0][8][0][32768]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 < 10922
+code=0 rows=24
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 > 10922
+code=0 rows=3
+[0][8][0][32768]
+[1][8][1][32768]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 <= 10922
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 = 32768
+code=0 rows=3
+[0][8][0][32768]
+[1][8][1][32768]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 != 32768
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 >= 32768
+code=0 rows=3
+[0][8][0][32768]
+[1][8][1][32768]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 < 32768
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 > 32768
+code=0 rows=0
+
+FILTER(FLOAT) v2 <= 32768
+code=0 rows=30
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 = NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 != NULL
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 >= NULL
+code=0 rows=30
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[0][9][0][NULL]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[1][9][1][NULL]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+[2][9][2][NULL]
+
+FILTER(FLOAT) v2 < NULL
+code=0 rows=0
+
+FILTER(FLOAT) v2 > NULL
+code=0 rows=27
+[0][0][0][-32768]
+[0][1][0][-10922]
+[0][2][0][-3640]
+[0][3][0][-1213]
+[0][4][0][0]
+[0][5][0][1213]
+[0][6][0][3640]
+[0][7][0][10922]
+[0][8][0][32768]
+[1][0][1][-32768]
+[1][1][1][-10922]
+[1][2][1][-3640]
+[1][3][1][-1213]
+[1][4][1][0]
+[1][5][1][1213]
+[1][6][1][3640]
+[1][7][1][10922]
+[1][8][1][32768]
+[2][0][2][-32768]
+[2][1][2][-10922]
+[2][2][2][-3640]
+[2][3][2][-1213]
+[2][4][2][0]
+[2][5][2][1213]
+[2][6][2][3640]
+[2][7][2][10922]
+[2][8][2][32768]
+
+FILTER(FLOAT) v2 <= NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+
+DOUBLE -------------------------------------------------
+
+FILTER(DOUBLE) NO FILTER
+code=0 rows=30
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 = -2147483648
+code=0 rows=3
+[0][0][0][-2147483648]
+[1][0][1][-2147483648]
+[2][0][2][-2147483648]
+
+FILTER(DOUBLE) v2 != -2147483648
+code=0 rows=27
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 >= -2147483648
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 < -2147483648
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 > -2147483648
+code=0 rows=24
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 <= -2147483648
+code=0 rows=6
+[0][0][0][-2147483648]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 = -715827882
+code=0 rows=3
+[0][1][0][-715827882]
+[1][1][1][-715827882]
+[2][1][2][-715827882]
+
+FILTER(DOUBLE) v2 != -715827882
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 >= -715827882
+code=0 rows=24
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 < -715827882
+code=0 rows=6
+[0][0][0][-2147483648]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 > -715827882
+code=0 rows=21
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 <= -715827882
+code=0 rows=9
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 = -238609294
+code=0 rows=3
+[0][2][0][-238609294]
+[1][2][1][-238609294]
+[2][2][2][-238609294]
+
+FILTER(DOUBLE) v2 != -238609294
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 >= -238609294
+code=0 rows=21
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 < -238609294
+code=0 rows=9
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 > -238609294
+code=0 rows=18
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 <= -238609294
+code=0 rows=12
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 = -79536431
+code=0 rows=3
+[0][3][0][-79536431]
+[1][3][1][-79536431]
+[2][3][2][-79536431]
+
+FILTER(DOUBLE) v2 != -79536431
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 >= -79536431
+code=0 rows=18
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 < -79536431
+code=0 rows=12
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 > -79536431
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 <= -79536431
+code=0 rows=15
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 = 0
+code=0 rows=3
+[0][4][0][0]
+[1][4][1][0]
+[2][4][2][0]
+
+FILTER(DOUBLE) v2 != 0
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 >= 0
+code=0 rows=15
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 < 0
+code=0 rows=15
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 > 0
+code=0 rows=12
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 <= 0
+code=0 rows=18
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 = 79536431
+code=0 rows=3
+[0][5][0][79536431]
+[1][5][1][79536431]
+[2][5][2][79536431]
+
+FILTER(DOUBLE) v2 != 79536431
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 >= 79536431
+code=0 rows=12
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 < 79536431
+code=0 rows=18
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 > 79536431
+code=0 rows=9
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 <= 79536431
+code=0 rows=21
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 = 238609294
+code=0 rows=3
+[0][6][0][238609294]
+[1][6][1][238609294]
+[2][6][2][238609294]
+
+FILTER(DOUBLE) v2 != 238609294
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 >= 238609294
+code=0 rows=9
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 < 238609294
+code=0 rows=21
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 > 238609294
+code=0 rows=6
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 <= 238609294
+code=0 rows=24
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 = 715827882
+code=0 rows=3
+[0][7][0][715827882]
+[1][7][1][715827882]
+[2][7][2][715827882]
+
+FILTER(DOUBLE) v2 != 715827882
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 >= 715827882
+code=0 rows=6
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 < 715827882
+code=0 rows=24
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 > 715827882
+code=0 rows=3
+[0][8][0][2147483647]
+[1][8][1][2147483647]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 <= 715827882
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 = 2147483647
+code=0 rows=3
+[0][8][0][2147483647]
+[1][8][1][2147483647]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 != 2147483647
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 >= 2147483647
+code=0 rows=3
+[0][8][0][2147483647]
+[1][8][1][2147483647]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 < 2147483647
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 > 2147483647
+code=0 rows=0
+
+FILTER(DOUBLE) v2 <= 2147483647
+code=0 rows=30
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 = NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 != NULL
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 >= NULL
+code=0 rows=30
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[0][9][0][NULL]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[1][9][1][NULL]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+[2][9][2][NULL]
+
+FILTER(DOUBLE) v2 < NULL
+code=0 rows=0
+
+FILTER(DOUBLE) v2 > NULL
+code=0 rows=27
+[0][0][0][-2147483648]
+[0][1][0][-715827882]
+[0][2][0][-238609294]
+[0][3][0][-79536431]
+[0][4][0][0]
+[0][5][0][79536431]
+[0][6][0][238609294]
+[0][7][0][715827882]
+[0][8][0][2147483647]
+[1][0][1][-2147483648]
+[1][1][1][-715827882]
+[1][2][1][-238609294]
+[1][3][1][-79536431]
+[1][4][1][0]
+[1][5][1][79536431]
+[1][6][1][238609294]
+[1][7][1][715827882]
+[1][8][1][2147483647]
+[2][0][2][-2147483648]
+[2][1][2][-715827882]
+[2][2][2][-238609294]
+[2][3][2][-79536431]
+[2][4][2][0]
+[2][5][2][79536431]
+[2][6][2][238609294]
+[2][7][2][715827882]
+[2][8][2][2147483647]
+
+FILTER(DOUBLE) v2 <= NULL
+code=0 rows=3
+[0][9][0][NULL]
+[1][9][1][NULL]
+[2][9][2][NULL]
+
+
+DATE -------------------------------------------------
+
+FILTER(DATE) NO FILTER
+code=0 rows=12
+[0][0][0][0000-00-00]
+[0][1][0][2011-01-01]
+[0][2][0][9999-12-31]
+[0][3][0][NULL]
+[1][0][1][0000-00-00]
+[1][1][1][2011-01-01]
+[1][2][1][9999-12-31]
+[1][3][1][NULL]
+[2][0][2][0000-00-00]
+[2][1][2][2011-01-01]
+[2][2][2][9999-12-31]
+[2][3][2][NULL]
+
+FILTER(DATE) v2 = 0000-00-00
+code=0 rows=3
+[0][0][0][0000-00-00]
+[1][0][1][0000-00-00]
+[2][0][2][0000-00-00]
+
+FILTER(DATE) v2 != 0000-00-00
+code=0 rows=9
+[0][1][0][2011-01-01]
+[0][2][0][9999-12-31]
+[0][3][0][NULL]
+[1][1][1][2011-01-01]
+[1][2][1][9999-12-31]
+[1][3][1][NULL]
+[2][1][2][2011-01-01]
+[2][2][2][9999-12-31]
+[2][3][2][NULL]
+
+FILTER(DATE) v2 >= 0000-00-00
+code=0 rows=9
+[0][0][0][0000-00-00]
+[0][1][0][2011-01-01]
+[0][2][0][9999-12-31]
+[1][0][1][0000-00-00]
+[1][1][1][2011-01-01]
+[1][2][1][9999-12-31]
+[2][0][2][0000-00-00]
+[2][1][2][2011-01-01]
+[2][2][2][9999-12-31]
+
+FILTER(DATE) v2 < 0000-00-00
+code=0 rows=3
+[0][3][0][NULL]
+[1][3][1][NULL]
+[2][3][2][NULL]
+
+FILTER(DATE) v2 > 0000-00-00
+code=0 rows=6
+[0][1][0][2011-01-01]
+[0][2][0][9999-12-31]
+[1][1][1][2011-01-01]
+[1][2][1][9999-12-31]
+[2][1][2][2011-01-01]
+[2][2][2][9999-12-31]
+
+FILTER(DATE) v2 <= 0000-00-00
+code=0 rows=6
+[0][0][0][0000-00-00]
+[0][3][0][NULL]
+[1][0][1][0000-00-00]
+[1][3][1][NULL]
+[2][0][2][0000-00-00]
+[2][3][2][NULL]
+
+FILTER(DATE) v2 = 2011-01-01
+code=0 rows=3
+[0][1][0][2011-01-01]
+[1][1][1][2011-01-01]
+[2][1][2][2011-01-01]
+
+FILTER(DATE) v2 != 2011-01-01
+code=0 rows=9
+[0][0][0][0000-00-00]
+[0][2][0][9999-12-31]
+[0][3][0][NULL]
+[1][0][1][0000-00-00]
+[1][2][1][9999-12-31]
+[1][3][1][NULL]
+[2][0][2][0000-00-00]
+[2][2][2][9999-12-31]
+[2][3][2][NULL]
+
+FILTER(DATE) v2 >= 2011-01-01
+code=0 rows=6
+[0][1][0][2011-01-01]
+[0][2][0][9999-12-31]
+[1][1][1][2011-01-01]
+[1][2][1][9999-12-31]
+[2][1][2][2011-01-01]
+[2][2][2][9999-12-31]
+
+FILTER(DATE) v2 < 2011-01-01
+code=0 rows=6
+[0][0][0][0000-00-00]
+[0][3][0][NULL]
+[1][0][1][0000-00-00]
+[1][3][1][NULL]
+[2][0][2][0000-00-00]
+[2][3][2][NULL]
+
+FILTER(DATE) v2 > 2011-01-01
+code=0 rows=3
+[0][2][0][9999-12-31]
+[1][2][1][9999-12-31]
+[2][2][2][9999-12-31]
+
+FILTER(DATE) v2 <= 2011-01-01
+code=0 rows=9
+[0][0][0][0000-00-00]
+[0][1][0][2011-01-01]
+[0][3][0][NULL]
+[1][0][1][0000-00-00]
+[1][1][1][2011-01-01]
+[1][3][1][NULL]
+[2][0][2][0000-00-00]
+[2][1][2][2011-01-01]
+[2][3][2][NULL]
+
+FILTER(DATE) v2 = 9999-12-31
+code=0 rows=3
+[0][2][0][9999-12-31]
+[1][2][1][9999-12-31]
+[2][2][2][9999-12-31]
+
+FILTER(DATE) v2 != 9999-12-31
+code=0 rows=9
+[0][0][0][0000-00-00]
+[0][1][0][2011-01-01]
+[0][3][0][NULL]
+[1][0][1][0000-00-00]
+[1][1][1][2011-01-01]
+[1][3][1][NULL]
+[2][0][2][0000-00-00]
+[2][1][2][2011-01-01]
+[2][3][2][NULL]
+
+FILTER(DATE) v2 >= 9999-12-31
+code=0 rows=3
+[0][2][0][9999-12-31]
+[1][2][1][9999-12-31]
+[2][2][2][9999-12-31]
+
+FILTER(DATE) v2 < 9999-12-31
+code=0 rows=9
+[0][0][0][0000-00-00]
+[0][1][0][2011-01-01]
+[0][3][0][NULL]
+[1][0][1][0000-00-00]
+[1][1][1][2011-01-01]
+[1][3][1][NULL]
+[2][0][2][0000-00-00]
+[2][1][2][2011-01-01]
+[2][3][2][NULL]
+
+FILTER(DATE) v2 > 9999-12-31
+code=0 rows=0
+
+FILTER(DATE) v2 <= 9999-12-31
+code=0 rows=12
+[0][0][0][0000-00-00]
+[0][1][0][2011-01-01]
+[0][2][0][9999-12-31]
+[0][3][0][NULL]
+[1][0][1][0000-00-00]
+[1][1][1][2011-01-01]
+[1][2][1][9999-12-31]
+[1][3][1][NULL]
+[2][0][2][0000-00-00]
+[2][1][2][2011-01-01]
+[2][2][2][9999-12-31]
+[2][3][2][NULL]
+
+FILTER(DATE) v2 = NULL
+code=0 rows=3
+[0][3][0][NULL]
+[1][3][1][NULL]
+[2][3][2][NULL]
+
+FILTER(DATE) v2 != NULL
+code=0 rows=9
+[0][0][0][0000-00-00]
+[0][1][0][2011-01-01]
+[0][2][0][9999-12-31]
+[1][0][1][0000-00-00]
+[1][1][1][2011-01-01]
+[1][2][1][9999-12-31]
+[2][0][2][0000-00-00]
+[2][1][2][2011-01-01]
+[2][2][2][9999-12-31]
+
+FILTER(DATE) v2 >= NULL
+code=0 rows=12
+[0][0][0][0000-00-00]
+[0][1][0][2011-01-01]
+[0][2][0][9999-12-31]
+[0][3][0][NULL]
+[1][0][1][0000-00-00]
+[1][1][1][2011-01-01]
+[1][2][1][9999-12-31]
+[1][3][1][NULL]
+[2][0][2][0000-00-00]
+[2][1][2][2011-01-01]
+[2][2][2][9999-12-31]
+[2][3][2][NULL]
+
+FILTER(DATE) v2 < NULL
+code=0 rows=0
+
+FILTER(DATE) v2 > NULL
+code=0 rows=9
+[0][0][0][0000-00-00]
+[0][1][0][2011-01-01]
+[0][2][0][9999-12-31]
+[1][0][1][0000-00-00]
+[1][1][1][2011-01-01]
+[1][2][1][9999-12-31]
+[2][0][2][0000-00-00]
+[2][1][2][2011-01-01]
+[2][2][2][9999-12-31]
+
+FILTER(DATE) v2 <= NULL
+code=0 rows=3
+[0][3][0][NULL]
+[1][3][1][NULL]
+[2][3][2][NULL]
+
+
+DATETIME -------------------------------------------------
+
+FILTER(DATETIME) NO FILTER
+code=0 rows=9
+[0][0][0][0000-00-00 00:00:00]
+[0][1][0][2011-01-01 18:30:25]
+[0][2][0][NULL]
+[1][0][1][0000-00-00 00:00:00]
+[1][1][1][2011-01-01 18:30:25]
+[1][2][1][NULL]
+[2][0][2][0000-00-00 00:00:00]
+[2][1][2][2011-01-01 18:30:25]
+[2][2][2][NULL]
+
+FILTER(DATETIME) v2 = 0
+code=0 rows=3
+[0][0][0][0000-00-00 00:00:00]
+[1][0][1][0000-00-00 00:00:00]
+[2][0][2][0000-00-00 00:00:00]
+
+FILTER(DATETIME) v2 != 0
+code=0 rows=6
+[0][1][0][2011-01-01 18:30:25]
+[0][2][0][NULL]
+[1][1][1][2011-01-01 18:30:25]
+[1][2][1][NULL]
+[2][1][2][2011-01-01 18:30:25]
+[2][2][2][NULL]
+
+FILTER(DATETIME) v2 >= 0
+code=0 rows=6
+[0][0][0][0000-00-00 00:00:00]
+[0][1][0][2011-01-01 18:30:25]
+[1][0][1][0000-00-00 00:00:00]
+[1][1][1][2011-01-01 18:30:25]
+[2][0][2][0000-00-00 00:00:00]
+[2][1][2][2011-01-01 18:30:25]
+
+FILTER(DATETIME) v2 < 0
+code=0 rows=3
+[0][2][0][NULL]
+[1][2][1][NULL]
+[2][2][2][NULL]
+
+FILTER(DATETIME) v2 > 0
+code=0 rows=3
+[0][1][0][2011-01-01 18:30:25]
+[1][1][1][2011-01-01 18:30:25]
+[2][1][2][2011-01-01 18:30:25]
+
+FILTER(DATETIME) v2 <= 0
+code=0 rows=6
+[0][0][0][0000-00-00 00:00:00]
+[0][2][0][NULL]
+[1][0][1][0000-00-00 00:00:00]
+[1][2][1][NULL]
+[2][0][2][0000-00-00 00:00:00]
+[2][2][2][NULL]
+
+FILTER(DATETIME) v2 = 2011-01-01 18:30:25
+code=0 rows=3
+[0][1][0][2011-01-01 18:30:25]
+[1][1][1][2011-01-01 18:30:25]
+[2][1][2][2011-01-01 18:30:25]
+
+FILTER(DATETIME) v2 != 2011-01-01 18:30:25
+code=0 rows=6
+[0][0][0][0000-00-00 00:00:00]
+[0][2][0][NULL]
+[1][0][1][0000-00-00 00:00:00]
+[1][2][1][NULL]
+[2][0][2][0000-00-00 00:00:00]
+[2][2][2][NULL]
+
+FILTER(DATETIME) v2 >= 2011-01-01 18:30:25
+code=0 rows=3
+[0][1][0][2011-01-01 18:30:25]
+[1][1][1][2011-01-01 18:30:25]
+[2][1][2][2011-01-01 18:30:25]
+
+FILTER(DATETIME) v2 < 2011-01-01 18:30:25
+code=0 rows=6
+[0][0][0][0000-00-00 00:00:00]
+[0][2][0][NULL]
+[1][0][1][0000-00-00 00:00:00]
+[1][2][1][NULL]
+[2][0][2][0000-00-00 00:00:00]
+[2][2][2][NULL]
+
+FILTER(DATETIME) v2 > 2011-01-01 18:30:25
+code=0 rows=0
+
+FILTER(DATETIME) v2 <= 2011-01-01 18:30:25
+code=0 rows=9
+[0][0][0][0000-00-00 00:00:00]
+[0][1][0][2011-01-01 18:30:25]
+[0][2][0][NULL]
+[1][0][1][0000-00-00 00:00:00]
+[1][1][1][2011-01-01 18:30:25]
+[1][2][1][NULL]
+[2][0][2][0000-00-00 00:00:00]
+[2][1][2][2011-01-01 18:30:25]
+[2][2][2][NULL]
+
+FILTER(DATETIME) v2 = NULL
+code=0 rows=3
+[0][2][0][NULL]
+[1][2][1][NULL]
+[2][2][2][NULL]
+
+FILTER(DATETIME) v2 != NULL
+code=0 rows=6
+[0][0][0][0000-00-00 00:00:00]
+[0][1][0][2011-01-01 18:30:25]
+[1][0][1][0000-00-00 00:00:00]
+[1][1][1][2011-01-01 18:30:25]
+[2][0][2][0000-00-00 00:00:00]
+[2][1][2][2011-01-01 18:30:25]
+
+FILTER(DATETIME) v2 >= NULL
+code=0 rows=9
+[0][0][0][0000-00-00 00:00:00]
+[0][1][0][2011-01-01 18:30:25]
+[0][2][0][NULL]
+[1][0][1][0000-00-00 00:00:00]
+[1][1][1][2011-01-01 18:30:25]
+[1][2][1][NULL]
+[2][0][2][0000-00-00 00:00:00]
+[2][1][2][2011-01-01 18:30:25]
+[2][2][2][NULL]
+
+FILTER(DATETIME) v2 < NULL
+code=0 rows=0
+
+FILTER(DATETIME) v2 > NULL
+code=0 rows=6
+[0][0][0][0000-00-00 00:00:00]
+[0][1][0][2011-01-01 18:30:25]
+[1][0][1][0000-00-00 00:00:00]
+[1][1][1][2011-01-01 18:30:25]
+[2][0][2][0000-00-00 00:00:00]
+[2][1][2][2011-01-01 18:30:25]
+
+FILTER(DATETIME) v2 <= NULL
+code=0 rows=3
+[0][2][0][NULL]
+[1][2][1][NULL]
+[2][2][2][NULL]
+
+
+TIME -------------------------------------------------
+
+FILTER(TIME) NO FILTER
+code=0 rows=9
+[0][0][0][00:00:00]
+[0][1][0][18:30:25]
+[0][2][0][NULL]
+[1][0][1][00:00:00]
+[1][1][1][18:30:25]
+[1][2][1][NULL]
+[2][0][2][00:00:00]
+[2][1][2][18:30:25]
+[2][2][2][NULL]
+
+FILTER(TIME) v2 = 0
+code=0 rows=3
+[0][0][0][00:00:00]
+[1][0][1][00:00:00]
+[2][0][2][00:00:00]
+
+FILTER(TIME) v2 != 0
+code=0 rows=6
+[0][1][0][18:30:25]
+[0][2][0][NULL]
+[1][1][1][18:30:25]
+[1][2][1][NULL]
+[2][1][2][18:30:25]
+[2][2][2][NULL]
+
+FILTER(TIME) v2 >= 0
+code=0 rows=6
+[0][0][0][00:00:00]
+[0][1][0][18:30:25]
+[1][0][1][00:00:00]
+[1][1][1][18:30:25]
+[2][0][2][00:00:00]
+[2][1][2][18:30:25]
+
+FILTER(TIME) v2 < 0
+code=0 rows=3
+[0][2][0][NULL]
+[1][2][1][NULL]
+[2][2][2][NULL]
+
+FILTER(TIME) v2 > 0
+code=0 rows=3
+[0][1][0][18:30:25]
+[1][1][1][18:30:25]
+[2][1][2][18:30:25]
+
+FILTER(TIME) v2 <= 0
+code=0 rows=6
+[0][0][0][00:00:00]
+[0][2][0][NULL]
+[1][0][1][00:00:00]
+[1][2][1][NULL]
+[2][0][2][00:00:00]
+[2][2][2][NULL]
+
+FILTER(TIME) v2 = 18:30:25
+code=0 rows=3
+[0][1][0][18:30:25]
+[1][1][1][18:30:25]
+[2][1][2][18:30:25]
+
+FILTER(TIME) v2 != 18:30:25
+code=0 rows=6
+[0][0][0][00:00:00]
+[0][2][0][NULL]
+[1][0][1][00:00:00]
+[1][2][1][NULL]
+[2][0][2][00:00:00]
+[2][2][2][NULL]
+
+FILTER(TIME) v2 >= 18:30:25
+code=0 rows=3
+[0][1][0][18:30:25]
+[1][1][1][18:30:25]
+[2][1][2][18:30:25]
+
+FILTER(TIME) v2 < 18:30:25
+code=0 rows=6
+[0][0][0][00:00:00]
+[0][2][0][NULL]
+[1][0][1][00:00:00]
+[1][2][1][NULL]
+[2][0][2][00:00:00]
+[2][2][2][NULL]
+
+FILTER(TIME) v2 > 18:30:25
+code=0 rows=0
+
+FILTER(TIME) v2 <= 18:30:25
+code=0 rows=9
+[0][0][0][00:00:00]
+[0][1][0][18:30:25]
+[0][2][0][NULL]
+[1][0][1][00:00:00]
+[1][1][1][18:30:25]
+[1][2][1][NULL]
+[2][0][2][00:00:00]
+[2][1][2][18:30:25]
+[2][2][2][NULL]
+
+FILTER(TIME) v2 = NULL
+code=0 rows=3
+[0][2][0][NULL]
+[1][2][1][NULL]
+[2][2][2][NULL]
+
+FILTER(TIME) v2 != NULL
+code=0 rows=6
+[0][0][0][00:00:00]
+[0][1][0][18:30:25]
+[1][0][1][00:00:00]
+[1][1][1][18:30:25]
+[2][0][2][00:00:00]
+[2][1][2][18:30:25]
+
+FILTER(TIME) v2 >= NULL
+code=0 rows=9
+[0][0][0][00:00:00]
+[0][1][0][18:30:25]
+[0][2][0][NULL]
+[1][0][1][00:00:00]
+[1][1][1][18:30:25]
+[1][2][1][NULL]
+[2][0][2][00:00:00]
+[2][1][2][18:30:25]
+[2][2][2][NULL]
+
+FILTER(TIME) v2 < NULL
+code=0 rows=0
+
+FILTER(TIME) v2 > NULL
+code=0 rows=6
+[0][0][0][00:00:00]
+[0][1][0][18:30:25]
+[1][0][1][00:00:00]
+[1][1][1][18:30:25]
+[2][0][2][00:00:00]
+[2][1][2][18:30:25]
+
+FILTER(TIME) v2 <= NULL
+code=0 rows=3
+[0][2][0][NULL]
+[1][2][1][NULL]
+[2][2][2][NULL]
+
+
+YEAR(4) -------------------------------------------------
+
+FILTER(YEAR(4)) NO FILTER
+code=0 rows=8
+[1][0][1][1901]
+[1][1][1][2011]
+[1][2][1][2155]
+[1][3][1][NULL]
+[2][0][2][1901]
+[2][1][2][2011]
+[2][2][2][2155]
+[2][3][2][NULL]
+
+FILTER(YEAR(4)) v2 = 1901
+code=0 rows=2
+[1][0][1][1901]
+[2][0][2][1901]
+
+FILTER(YEAR(4)) v2 != 1901
+code=0 rows=6
+[1][1][1][2011]
+[1][2][1][2155]
+[1][3][1][NULL]
+[2][1][2][2011]
+[2][2][2][2155]
+[2][3][2][NULL]
+
+FILTER(YEAR(4)) v2 >= 1901
+code=0 rows=6
+[1][0][1][1901]
+[1][1][1][2011]
+[1][2][1][2155]
+[2][0][2][1901]
+[2][1][2][2011]
+[2][2][2][2155]
+
+FILTER(YEAR(4)) v2 < 1901
+code=0 rows=2
+[1][3][1][NULL]
+[2][3][2][NULL]
+
+FILTER(YEAR(4)) v2 > 1901
+code=0 rows=4
+[1][1][1][2011]
+[1][2][1][2155]
+[2][1][2][2011]
+[2][2][2][2155]
+
+FILTER(YEAR(4)) v2 <= 1901
+code=0 rows=4
+[1][0][1][1901]
+[1][3][1][NULL]
+[2][0][2][1901]
+[2][3][2][NULL]
+
+FILTER(YEAR(4)) v2 = 2011
+code=0 rows=2
+[1][1][1][2011]
+[2][1][2][2011]
+
+FILTER(YEAR(4)) v2 != 2011
+code=0 rows=6
+[1][0][1][1901]
+[1][2][1][2155]
+[1][3][1][NULL]
+[2][0][2][1901]
+[2][2][2][2155]
+[2][3][2][NULL]
+
+FILTER(YEAR(4)) v2 >= 2011
+code=0 rows=4
+[1][1][1][2011]
+[1][2][1][2155]
+[2][1][2][2011]
+[2][2][2][2155]
+
+FILTER(YEAR(4)) v2 < 2011
+code=0 rows=4
+[1][0][1][1901]
+[1][3][1][NULL]
+[2][0][2][1901]
+[2][3][2][NULL]
+
+FILTER(YEAR(4)) v2 > 2011
+code=0 rows=2
+[1][2][1][2155]
+[2][2][2][2155]
+
+FILTER(YEAR(4)) v2 <= 2011
+code=0 rows=6
+[1][0][1][1901]
+[1][1][1][2011]
+[1][3][1][NULL]
+[2][0][2][1901]
+[2][1][2][2011]
+[2][3][2][NULL]
+
+FILTER(YEAR(4)) v2 = 2155
+code=0 rows=2
+[1][2][1][2155]
+[2][2][2][2155]
+
+FILTER(YEAR(4)) v2 != 2155
+code=0 rows=6
+[1][0][1][1901]
+[1][1][1][2011]
+[1][3][1][NULL]
+[2][0][2][1901]
+[2][1][2][2011]
+[2][3][2][NULL]
+
+FILTER(YEAR(4)) v2 >= 2155
+code=0 rows=2
+[1][2][1][2155]
+[2][2][2][2155]
+
+FILTER(YEAR(4)) v2 < 2155
+code=0 rows=6
+[1][0][1][1901]
+[1][1][1][2011]
+[1][3][1][NULL]
+[2][0][2][1901]
+[2][1][2][2011]
+[2][3][2][NULL]
+
+FILTER(YEAR(4)) v2 > 2155
+code=0 rows=0
+
+FILTER(YEAR(4)) v2 <= 2155
+code=0 rows=8
+[1][0][1][1901]
+[1][1][1][2011]
+[1][2][1][2155]
+[1][3][1][NULL]
+[2][0][2][1901]
+[2][1][2][2011]
+[2][2][2][2155]
+[2][3][2][NULL]
+
+FILTER(YEAR(4)) v2 = NULL
+code=0 rows=2
+[1][3][1][NULL]
+[2][3][2][NULL]
+
+FILTER(YEAR(4)) v2 != NULL
+code=0 rows=6
+[1][0][1][1901]
+[1][1][1][2011]
+[1][2][1][2155]
+[2][0][2][1901]
+[2][1][2][2011]
+[2][2][2][2155]
+
+FILTER(YEAR(4)) v2 >= NULL
+code=0 rows=8
+[1][0][1][1901]
+[1][1][1][2011]
+[1][2][1][2155]
+[1][3][1][NULL]
+[2][0][2][1901]
+[2][1][2][2011]
+[2][2][2][2155]
+[2][3][2][NULL]
+
+FILTER(YEAR(4)) v2 < NULL
+code=0 rows=0
+
+FILTER(YEAR(4)) v2 > NULL
+code=0 rows=6
+[1][0][1][1901]
+[1][1][1][2011]
+[1][2][1][2155]
+[2][0][2][1901]
+[2][1][2][2011]
+[2][2][2][2155]
+
+FILTER(YEAR(4)) v2 <= NULL
+code=0 rows=2
+[1][3][1][NULL]
+[2][3][2][NULL]
+
+
+CHAR(10) -------------------------------------------------
+
+FILTER(CHAR(10)) NO FILTER
+code=0 rows=15
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 = B
+code=0 rows=3
+[0][0][0][B
+[1][0][1][B
+[2][0][2][B
+
+FILTER(CHAR(10)) v2 != B
+code=0 rows=12
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 >= B
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+
+FILTER(CHAR(10)) v2 < B
+code=0 rows=3
+[0][4][0][NULL]
+[1][4][1][NULL]
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 > B
+code=0 rows=9
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+
+FILTER(CHAR(10)) v2 <= B
+code=0 rows=6
+[0][0][0][B
+[0][4][0][NULL]
+[1][0][1][B
+[1][4][1][NULL]
+[2][0][2][B
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 = GI
+code=0 rows=3
+[0][1][0][GI
+[1][1][1][GI
+[2][1][2][GI
+
+FILTER(CHAR(10)) v2 != GI
+code=0 rows=12
+[0][0][0][B
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 >= GI
+code=0 rows=6
+[0][1][0][GI
+[0][2][0][JHFFE
+[1][1][1][GI
+[1][2][1][JHFFE
+[2][1][2][GI
+[2][2][2][JHFFE
+
+FILTER(CHAR(10)) v2 < GI
+code=0 rows=9
+[0][0][0][B
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 > GI
+code=0 rows=3
+[0][2][0][JHFFE
+[1][2][1][JHFFE
+[2][2][2][JHFFE
+
+FILTER(CHAR(10)) v2 <= GI
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 = JHFFE
+code=0 rows=3
+[0][2][0][JHFFE
+[1][2][1][JHFFE
+[2][2][2][JHFFE
+
+FILTER(CHAR(10)) v2 != JHFFE
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 >= JHFFE
+code=0 rows=3
+[0][2][0][JHFFE
+[1][2][1][JHFFE
+[2][2][2][JHFFE
+
+FILTER(CHAR(10)) v2 < JHFFE
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 > JHFFE
+code=0 rows=0
+
+FILTER(CHAR(10)) v2 <= JHFFE
+code=0 rows=15
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 = FDHHDEDBHH
+code=0 rows=3
+[0][3][0][FDHHDEDBHH]
+[1][3][1][FDHHDEDBHH]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(CHAR(10)) v2 != FDHHDEDBHH
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 >= FDHHDEDBHH
+code=0 rows=9
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+
+FILTER(CHAR(10)) v2 < FDHHDEDBHH
+code=0 rows=6
+[0][0][0][B
+[0][4][0][NULL]
+[1][0][1][B
+[1][4][1][NULL]
+[2][0][2][B
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 > FDHHDEDBHH
+code=0 rows=6
+[0][1][0][GI
+[0][2][0][JHFFE
+[1][1][1][GI
+[1][2][1][JHFFE
+[2][1][2][GI
+[2][2][2][JHFFE
+
+FILTER(CHAR(10)) v2 <= FDHHDEDBHH
+code=0 rows=9
+[0][0][0][B
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 = NULL
+code=0 rows=3
+[0][4][0][NULL]
+[1][4][1][NULL]
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 != NULL
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+
+FILTER(CHAR(10)) v2 >= NULL
+code=0 rows=15
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(CHAR(10)) v2 < NULL
+code=0 rows=0
+
+FILTER(CHAR(10)) v2 > NULL
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+
+FILTER(CHAR(10)) v2 <= NULL
+code=0 rows=3
+[0][4][0][NULL]
+[1][4][1][NULL]
+[2][4][2][NULL]
+
+
+VARCHAR(10) -------------------------------------------------
+
+FILTER(VARCHAR(10)) NO FILTER
+code=0 rows=15
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 = B
+code=0 rows=3
+[0][0][0][B]
+[1][0][1][B]
+[2][0][2][B]
+
+FILTER(VARCHAR(10)) v2 != B
+code=0 rows=12
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 >= B
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARCHAR(10)) v2 < B
+code=0 rows=3
+[0][4][0][NULL]
+[1][4][1][NULL]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 > B
+code=0 rows=9
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARCHAR(10)) v2 <= B
+code=0 rows=6
+[0][0][0][B]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 = GI
+code=0 rows=3
+[0][1][0][GI]
+[1][1][1][GI]
+[2][1][2][GI]
+
+FILTER(VARCHAR(10)) v2 != GI
+code=0 rows=12
+[0][0][0][B]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 >= GI
+code=0 rows=6
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(10)) v2 < GI
+code=0 rows=9
+[0][0][0][B]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 > GI
+code=0 rows=3
+[0][2][0][JHFFE]
+[1][2][1][JHFFE]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(10)) v2 <= GI
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 = JHFFE
+code=0 rows=3
+[0][2][0][JHFFE]
+[1][2][1][JHFFE]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(10)) v2 != JHFFE
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 >= JHFFE
+code=0 rows=3
+[0][2][0][JHFFE]
+[1][2][1][JHFFE]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(10)) v2 < JHFFE
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 > JHFFE
+code=0 rows=0
+
+FILTER(VARCHAR(10)) v2 <= JHFFE
+code=0 rows=15
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 = FDHHDEDBHH
+code=0 rows=3
+[0][3][0][FDHHDEDBHH]
+[1][3][1][FDHHDEDBHH]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARCHAR(10)) v2 != FDHHDEDBHH
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 >= FDHHDEDBHH
+code=0 rows=9
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARCHAR(10)) v2 < FDHHDEDBHH
+code=0 rows=6
+[0][0][0][B]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 > FDHHDEDBHH
+code=0 rows=6
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(10)) v2 <= FDHHDEDBHH
+code=0 rows=9
+[0][0][0][B]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 = NULL
+code=0 rows=3
+[0][4][0][NULL]
+[1][4][1][NULL]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 != NULL
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARCHAR(10)) v2 >= NULL
+code=0 rows=15
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARCHAR(10)) v2 < NULL
+code=0 rows=0
+
+FILTER(VARCHAR(10)) v2 > NULL
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARCHAR(10)) v2 <= NULL
+code=0 rows=3
+[0][4][0][NULL]
+[1][4][1][NULL]
+[2][4][2][NULL]
+
+
+BINARY(10) -------------------------------------------------
+
+FILTER(BINARY(10)) NO FILTER
+code=0 rows=15
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 = B
+code=0 rows=3
+[0][0][0][B
+[1][0][1][B
+[2][0][2][B
+
+FILTER(BINARY(10)) v2 != B
+code=0 rows=12
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 >= B
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+
+FILTER(BINARY(10)) v2 < B
+code=0 rows=3
+[0][4][0][NULL]
+[1][4][1][NULL]
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 > B
+code=0 rows=9
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+
+FILTER(BINARY(10)) v2 <= B
+code=0 rows=6
+[0][0][0][B
+[0][4][0][NULL]
+[1][0][1][B
+[1][4][1][NULL]
+[2][0][2][B
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 = GI
+code=0 rows=3
+[0][1][0][GI
+[1][1][1][GI
+[2][1][2][GI
+
+FILTER(BINARY(10)) v2 != GI
+code=0 rows=12
+[0][0][0][B
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 >= GI
+code=0 rows=6
+[0][1][0][GI
+[0][2][0][JHFFE
+[1][1][1][GI
+[1][2][1][JHFFE
+[2][1][2][GI
+[2][2][2][JHFFE
+
+FILTER(BINARY(10)) v2 < GI
+code=0 rows=9
+[0][0][0][B
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 > GI
+code=0 rows=3
+[0][2][0][JHFFE
+[1][2][1][JHFFE
+[2][2][2][JHFFE
+
+FILTER(BINARY(10)) v2 <= GI
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 = JHFFE
+code=0 rows=3
+[0][2][0][JHFFE
+[1][2][1][JHFFE
+[2][2][2][JHFFE
+
+FILTER(BINARY(10)) v2 != JHFFE
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 >= JHFFE
+code=0 rows=3
+[0][2][0][JHFFE
+[1][2][1][JHFFE
+[2][2][2][JHFFE
+
+FILTER(BINARY(10)) v2 < JHFFE
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 > JHFFE
+code=0 rows=0
+
+FILTER(BINARY(10)) v2 <= JHFFE
+code=0 rows=15
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 = FDHHDEDBHH
+code=0 rows=3
+[0][3][0][FDHHDEDBHH]
+[1][3][1][FDHHDEDBHH]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(BINARY(10)) v2 != FDHHDEDBHH
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 >= FDHHDEDBHH
+code=0 rows=9
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+
+FILTER(BINARY(10)) v2 < FDHHDEDBHH
+code=0 rows=6
+[0][0][0][B
+[0][4][0][NULL]
+[1][0][1][B
+[1][4][1][NULL]
+[2][0][2][B
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 > FDHHDEDBHH
+code=0 rows=6
+[0][1][0][GI
+[0][2][0][JHFFE
+[1][1][1][GI
+[1][2][1][JHFFE
+[2][1][2][GI
+[2][2][2][JHFFE
+
+FILTER(BINARY(10)) v2 <= FDHHDEDBHH
+code=0 rows=9
+[0][0][0][B
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 = NULL
+code=0 rows=3
+[0][4][0][NULL]
+[1][4][1][NULL]
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 != NULL
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+
+FILTER(BINARY(10)) v2 >= NULL
+code=0 rows=15
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(BINARY(10)) v2 < NULL
+code=0 rows=0
+
+FILTER(BINARY(10)) v2 > NULL
+code=0 rows=12
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH]
+
+FILTER(BINARY(10)) v2 <= NULL
+code=0 rows=3
+[0][4][0][NULL]
+[1][4][1][NULL]
+[2][4][2][NULL]
+
+
+VARBINARY(10) -------------------------------------------------
+
+FILTER(VARBINARY(10)) NO FILTER
+code=0 rows=15
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 = B
+code=0 rows=3
+[0][0][0][B]
+[1][0][1][B]
+[2][0][2][B]
+
+FILTER(VARBINARY(10)) v2 != B
+code=0 rows=12
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 >= B
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARBINARY(10)) v2 < B
+code=0 rows=3
+[0][4][0][NULL]
+[1][4][1][NULL]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 > B
+code=0 rows=9
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARBINARY(10)) v2 <= B
+code=0 rows=6
+[0][0][0][B]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 = GI
+code=0 rows=3
+[0][1][0][GI]
+[1][1][1][GI]
+[2][1][2][GI]
+
+FILTER(VARBINARY(10)) v2 != GI
+code=0 rows=12
+[0][0][0][B]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 >= GI
+code=0 rows=6
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+
+FILTER(VARBINARY(10)) v2 < GI
+code=0 rows=9
+[0][0][0][B]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 > GI
+code=0 rows=3
+[0][2][0][JHFFE]
+[1][2][1][JHFFE]
+[2][2][2][JHFFE]
+
+FILTER(VARBINARY(10)) v2 <= GI
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 = JHFFE
+code=0 rows=3
+[0][2][0][JHFFE]
+[1][2][1][JHFFE]
+[2][2][2][JHFFE]
+
+FILTER(VARBINARY(10)) v2 != JHFFE
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 >= JHFFE
+code=0 rows=3
+[0][2][0][JHFFE]
+[1][2][1][JHFFE]
+[2][2][2][JHFFE]
+
+FILTER(VARBINARY(10)) v2 < JHFFE
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 > JHFFE
+code=0 rows=0
+
+FILTER(VARBINARY(10)) v2 <= JHFFE
+code=0 rows=15
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 = FDHHDEDBHH
+code=0 rows=3
+[0][3][0][FDHHDEDBHH]
+[1][3][1][FDHHDEDBHH]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARBINARY(10)) v2 != FDHHDEDBHH
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 >= FDHHDEDBHH
+code=0 rows=9
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARBINARY(10)) v2 < FDHHDEDBHH
+code=0 rows=6
+[0][0][0][B]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 > FDHHDEDBHH
+code=0 rows=6
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+
+FILTER(VARBINARY(10)) v2 <= FDHHDEDBHH
+code=0 rows=9
+[0][0][0][B]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 = NULL
+code=0 rows=3
+[0][4][0][NULL]
+[1][4][1][NULL]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 != NULL
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARBINARY(10)) v2 >= NULL
+code=0 rows=15
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][NULL]
+
+FILTER(VARBINARY(10)) v2 < NULL
+code=0 rows=0
+
+FILTER(VARBINARY(10)) v2 > NULL
+code=0 rows=12
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARBINARY(10)) v2 <= NULL
+code=0 rows=3
+[0][4][0][NULL]
+[1][4][1][NULL]
+[2][4][2][NULL]
+
+
+CHAR(255) -------------------------------------------------
+
+FILTER(CHAR(255)) NO FILTER
+code=0 rows=24
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 = B
+code=0 rows=3
+[0][0][0][B
+[1][0][1][B
+[2][0][2][B
+
+FILTER(CHAR(255)) v2 != B
+code=0 rows=21
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 >= B
+code=0 rows=21
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+
+FILTER(CHAR(255)) v2 < B
+code=0 rows=3
+[0][7][0][NULL]
+[1][7][1][NULL]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 > B
+code=0 rows=18
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+
+FILTER(CHAR(255)) v2 <= B
+code=0 rows=6
+[0][0][0][B
+[0][7][0][NULL]
+[1][0][1][B
+[1][7][1][NULL]
+[2][0][2][B
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 = GI
+code=0 rows=3
+[0][1][0][GI
+[1][1][1][GI
+[2][1][2][GI
+
+FILTER(CHAR(255)) v2 != GI
+code=0 rows=21
+[0][0][0][B
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 >= GI
+code=0 rows=6
+[0][1][0][GI
+[0][2][0][JHFFE
+[1][1][1][GI
+[1][2][1][JHFFE
+[2][1][2][GI
+[2][2][2][JHFFE
+
+FILTER(CHAR(255)) v2 < GI
+code=0 rows=18
+[0][0][0][B
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 > GI
+code=0 rows=3
+[0][2][0][JHFFE
+[1][2][1][JHFFE
+[2][2][2][JHFFE
+
+FILTER(CHAR(255)) v2 <= GI
+code=0 rows=21
+[0][0][0][B
+[0][1][0][GI
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 = JHFFE
+code=0 rows=3
+[0][2][0][JHFFE
+[1][2][1][JHFFE
+[2][2][2][JHFFE
+
+FILTER(CHAR(255)) v2 != JHFFE
+code=0 rows=21
+[0][0][0][B
+[0][1][0][GI
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 >= JHFFE
+code=0 rows=3
+[0][2][0][JHFFE
+[1][2][1][JHFFE
+[2][2][2][JHFFE
+
+FILTER(CHAR(255)) v2 < JHFFE
+code=0 rows=21
+[0][0][0][B
+[0][1][0][GI
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 > JHFFE
+code=0 rows=0
+
+FILTER(CHAR(255)) v2 <= JHFFE
+code=0 rows=24
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 = FDHHDEDBHH
+code=0 rows=3
+[0][3][0][FDHHDEDBHH
+[1][3][1][FDHHDEDBHH
+[2][3][2][FDHHDEDBHH
+
+FILTER(CHAR(255)) v2 != FDHHDEDBHH
+code=0 rows=21
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 >= FDHHDEDBHH
+code=0 rows=12
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+
+FILTER(CHAR(255)) v2 < FDHHDEDBHH
+code=0 rows=12
+[0][0][0][B
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 > FDHHDEDBHH
+code=0 rows=9
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+
+FILTER(CHAR(255)) v2 <= FDHHDEDBHH
+code=0 rows=15
+[0][0][0][B
+[0][3][0][FDHHDEDBHH
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][3][1][FDHHDEDBHH
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][3][2][FDHHDEDBHH
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 = FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=3
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+
+FILTER(CHAR(255)) v2 != FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=21
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 >= FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=9
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+
+FILTER(CHAR(255)) v2 < FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=15
+[0][0][0][B
+[0][3][0][FDHHDEDBHH
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][3][1][FDHHDEDBHH
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][3][2][FDHHDEDBHH
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 > FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=6
+[0][1][0][GI
+[0][2][0][JHFFE
+[1][1][1][GI
+[1][2][1][JHFFE
+[2][1][2][GI
+[2][2][2][JHFFE
+
+FILTER(CHAR(255)) v2 <= FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=18
+[0][0][0][B
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 = DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=3
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+
+FILTER(CHAR(255)) v2 != DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=21
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 >= DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=15
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+
+FILTER(CHAR(255)) v2 < DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=9
+[0][0][0][B
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 > DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=12
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+
+FILTER(CHAR(255)) v2 <= DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=12
+[0][0][0][B
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 = DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI
+code=0 rows=3
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+
+FILTER(CHAR(255)) v2 != DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI
+code=0 rows=21
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][7][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][7][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 >= DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI
+code=0 rows=18
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+
+FILTER(CHAR(255)) v2 < DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI
+code=0 rows=6
+[0][0][0][B
+[0][7][0][NULL]
+[1][0][1][B
+[1][7][1][NULL]
+[2][0][2][B
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 > DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI
+code=0 rows=15
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+
+FILTER(CHAR(255)) v2 <= DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI
+code=0 rows=9
+[0][0][0][B
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 = NULL
+code=0 rows=3
+[0][7][0][NULL]
+[1][7][1][NULL]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 != NULL
+code=0 rows=21
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+
+FILTER(CHAR(255)) v2 >= NULL
+code=0 rows=24
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(CHAR(255)) v2 < NULL
+code=0 rows=0
+
+FILTER(CHAR(255)) v2 > NULL
+code=0 rows=21
+[0][0][0][B
+[0][1][0][GI
+[0][2][0][JHFFE
+[0][3][0][FDHHDEDBHH
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][0][1][B
+[1][1][1][GI
+[1][2][1][JHFFE
+[1][3][1][FDHHDEDBHH
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][0][2][B
+[2][1][2][GI
+[2][2][2][JHFFE
+[2][3][2][FDHHDEDBHH
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+
+FILTER(CHAR(255)) v2 <= NULL
+code=0 rows=3
+[0][7][0][NULL]
+[1][7][1][NULL]
+[2][7][2][NULL]
+
+
+VARCHAR(255) -------------------------------------------------
+
+FILTER(VARCHAR(255)) NO FILTER
+code=0 rows=24
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 = B
+code=0 rows=3
+[0][0][0][B]
+[1][0][1][B]
+[2][0][2][B]
+
+FILTER(VARCHAR(255)) v2 != B
+code=0 rows=21
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 >= B
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+
+FILTER(VARCHAR(255)) v2 < B
+code=0 rows=3
+[0][7][0][NULL]
+[1][7][1][NULL]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 > B
+code=0 rows=18
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+
+FILTER(VARCHAR(255)) v2 <= B
+code=0 rows=6
+[0][0][0][B]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 = GI
+code=0 rows=3
+[0][1][0][GI]
+[1][1][1][GI]
+[2][1][2][GI]
+
+FILTER(VARCHAR(255)) v2 != GI
+code=0 rows=21
+[0][0][0][B]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 >= GI
+code=0 rows=6
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(255)) v2 < GI
+code=0 rows=18
+[0][0][0][B]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 > GI
+code=0 rows=3
+[0][2][0][JHFFE]
+[1][2][1][JHFFE]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(255)) v2 <= GI
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 = JHFFE
+code=0 rows=3
+[0][2][0][JHFFE]
+[1][2][1][JHFFE]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(255)) v2 != JHFFE
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 >= JHFFE
+code=0 rows=3
+[0][2][0][JHFFE]
+[1][2][1][JHFFE]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(255)) v2 < JHFFE
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 > JHFFE
+code=0 rows=0
+
+FILTER(VARCHAR(255)) v2 <= JHFFE
+code=0 rows=24
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 = FDHHDEDBHH
+code=0 rows=3
+[0][3][0][FDHHDEDBHH]
+[1][3][1][FDHHDEDBHH]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARCHAR(255)) v2 != FDHHDEDBHH
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 >= FDHHDEDBHH
+code=0 rows=12
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+
+FILTER(VARCHAR(255)) v2 < FDHHDEDBHH
+code=0 rows=12
+[0][0][0][B]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 > FDHHDEDBHH
+code=0 rows=9
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+
+FILTER(VARCHAR(255)) v2 <= FDHHDEDBHH
+code=0 rows=15
+[0][0][0][B]
+[0][3][0][FDHHDEDBHH]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][3][1][FDHHDEDBHH]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][3][2][FDHHDEDBHH]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 = FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=3
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+
+FILTER(VARCHAR(255)) v2 != FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 >= FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=9
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+
+FILTER(VARCHAR(255)) v2 < FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=15
+[0][0][0][B]
+[0][3][0][FDHHDEDBHH]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][3][1][FDHHDEDBHH]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][3][2][FDHHDEDBHH]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 > FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=6
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(255)) v2 <= FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=18
+[0][0][0][B]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 = DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=3
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+
+FILTER(VARCHAR(255)) v2 != DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 >= DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=15
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+
+FILTER(VARCHAR(255)) v2 < DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=9
+[0][0][0][B]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 > DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=12
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+
+FILTER(VARCHAR(255)) v2 <= DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=12
+[0][0][0][B]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 = DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI
+code=0 rows=3
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+
+FILTER(VARCHAR(255)) v2 != DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 >= DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI
+code=0 rows=18
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+
+FILTER(VARCHAR(255)) v2 < DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI
+code=0 rows=6
+[0][0][0][B]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 > DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI
+code=0 rows=15
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+
+FILTER(VARCHAR(255)) v2 <= DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI
+code=0 rows=9
+[0][0][0][B]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 = NULL
+code=0 rows=3
+[0][7][0][NULL]
+[1][7][1][NULL]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 != NULL
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+
+FILTER(VARCHAR(255)) v2 >= NULL
+code=0 rows=24
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(255)) v2 < NULL
+code=0 rows=0
+
+FILTER(VARCHAR(255)) v2 > NULL
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGI]
+
+FILTER(VARCHAR(255)) v2 <= NULL
+code=0 rows=3
+[0][7][0][NULL]
+[1][7][1][NULL]
+[2][7][2][NULL]
+
+
+VARCHAR(511) -------------------------------------------------
+
+FILTER(VARCHAR(511)) NO FILTER
+code=0 rows=24
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 = B
+code=0 rows=3
+[0][0][0][B]
+[1][0][1][B]
+[2][0][2][B]
+
+FILTER(VARCHAR(511)) v2 != B
+code=0 rows=21
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 >= B
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+
+FILTER(VARCHAR(511)) v2 < B
+code=0 rows=3
+[0][7][0][NULL]
+[1][7][1][NULL]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 > B
+code=0 rows=18
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+
+FILTER(VARCHAR(511)) v2 <= B
+code=0 rows=6
+[0][0][0][B]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 = GI
+code=0 rows=3
+[0][1][0][GI]
+[1][1][1][GI]
+[2][1][2][GI]
+
+FILTER(VARCHAR(511)) v2 != GI
+code=0 rows=21
+[0][0][0][B]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 >= GI
+code=0 rows=6
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(511)) v2 < GI
+code=0 rows=18
+[0][0][0][B]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 > GI
+code=0 rows=3
+[0][2][0][JHFFE]
+[1][2][1][JHFFE]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(511)) v2 <= GI
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 = JHFFE
+code=0 rows=3
+[0][2][0][JHFFE]
+[1][2][1][JHFFE]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(511)) v2 != JHFFE
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 >= JHFFE
+code=0 rows=3
+[0][2][0][JHFFE]
+[1][2][1][JHFFE]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(511)) v2 < JHFFE
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 > JHFFE
+code=0 rows=0
+
+FILTER(VARCHAR(511)) v2 <= JHFFE
+code=0 rows=24
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 = FDHHDEDBHH
+code=0 rows=3
+[0][3][0][FDHHDEDBHH]
+[1][3][1][FDHHDEDBHH]
+[2][3][2][FDHHDEDBHH]
+
+FILTER(VARCHAR(511)) v2 != FDHHDEDBHH
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 >= FDHHDEDBHH
+code=0 rows=12
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+
+FILTER(VARCHAR(511)) v2 < FDHHDEDBHH
+code=0 rows=12
+[0][0][0][B]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 > FDHHDEDBHH
+code=0 rows=9
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+
+FILTER(VARCHAR(511)) v2 <= FDHHDEDBHH
+code=0 rows=15
+[0][0][0][B]
+[0][3][0][FDHHDEDBHH]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][3][1][FDHHDEDBHH]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][3][2][FDHHDEDBHH]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 = FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=3
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+
+FILTER(VARCHAR(511)) v2 != FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 >= FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=9
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+
+FILTER(VARCHAR(511)) v2 < FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=15
+[0][0][0][B]
+[0][3][0][FDHHDEDBHH]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][3][1][FDHHDEDBHH]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][3][2][FDHHDEDBHH]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 > FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=6
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+
+FILTER(VARCHAR(511)) v2 <= FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=0 rows=18
+[0][0][0][B]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 = DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=3
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+
+FILTER(VARCHAR(511)) v2 != DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 >= DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=15
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+
+FILTER(VARCHAR(511)) v2 < DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=9
+[0][0][0][B]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 > DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=12
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+
+FILTER(VARCHAR(511)) v2 <= DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=0 rows=12
+[0][0][0][B]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 = DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=0 rows=3
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+
+FILTER(VARCHAR(511)) v2 != DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 >= DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=0 rows=18
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+
+FILTER(VARCHAR(511)) v2 < DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=0 rows=6
+[0][0][0][B]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 > DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=0 rows=15
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+
+FILTER(VARCHAR(511)) v2 <= DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=0 rows=9
+[0][0][0][B]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 = NULL
+code=0 rows=3
+[0][7][0][NULL]
+[1][7][1][NULL]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 != NULL
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+
+FILTER(VARCHAR(511)) v2 >= NULL
+code=0 rows=24
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(VARCHAR(511)) v2 < NULL
+code=0 rows=0
+
+FILTER(VARCHAR(511)) v2 > NULL
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+
+FILTER(VARCHAR(511)) v2 <= NULL
+code=0 rows=3
+[0][7][0][NULL]
+[1][7][1][NULL]
+[2][7][2][NULL]
+
+
+LONGTEXT -------------------------------------------------
+
+FILTER(LONGTEXT) NO FILTER
+code=0 rows=24
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(LONGTEXT) v2 = B
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 != B
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 >= B
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 < B
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 > B
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 <= B
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 = GI
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 != GI
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 >= GI
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 < GI
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 > GI
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 <= GI
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 = JHFFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 != JHFFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 >= JHFFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 < JHFFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 > JHFFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 <= JHFFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 = FDHHDEDBHH
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 != FDHHDEDBHH
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 >= FDHHDEDBHH
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 < FDHHDEDBHH
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 > FDHHDEDBHH
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 <= FDHHDEDBHH
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 = FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 != FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 >= FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 < FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 > FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 <= FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 = DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 != DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 >= DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 < DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 > DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 <= DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 = DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 != DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 >= DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 < DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 > DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 <= DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=2 rows=0
+[filterblob]
+FILTER(LONGTEXT) v2 = NULL
+code=0 rows=3
+[0][7][0][NULL]
+[1][7][1][NULL]
+[2][7][2][NULL]
+
+FILTER(LONGTEXT) v2 != NULL
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+
+FILTER(LONGTEXT) v2 >= NULL
+code=0 rows=24
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(LONGTEXT) v2 < NULL
+code=0 rows=0
+
+FILTER(LONGTEXT) v2 > NULL
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+
+FILTER(LONGTEXT) v2 <= NULL
+code=0 rows=3
+[0][7][0][NULL]
+[1][7][1][NULL]
+[2][7][2][NULL]
+
+
+LONGBLOB -------------------------------------------------
+
+FILTER(LONGBLOB) NO FILTER
+code=0 rows=24
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(LONGBLOB) v2 = B
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 != B
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 >= B
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 < B
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 > B
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 <= B
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 = GI
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 != GI
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 >= GI
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 < GI
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 > GI
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 <= GI
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 = JHFFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 != JHFFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 >= JHFFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 < JHFFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 > JHFFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 <= JHFFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 = FDHHDEDBHH
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 != FDHHDEDBHH
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 >= FDHHDEDBHH
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 < FDHHDEDBHH
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 > FDHHDEDBHH
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 <= FDHHDEDBHH
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 = FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 != FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 >= FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 < FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 > FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 <= FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 = DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 != DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 >= DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 < DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 > DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 <= DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 = DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 != DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 >= DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 < DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 > DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 <= DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA
+code=2 rows=0
+[filterblob]
+FILTER(LONGBLOB) v2 = NULL
+code=0 rows=3
+[0][7][0][NULL]
+[1][7][1][NULL]
+[2][7][2][NULL]
+
+FILTER(LONGBLOB) v2 != NULL
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+
+FILTER(LONGBLOB) v2 >= NULL
+code=0 rows=24
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[0][7][0][NULL]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][7][1][NULL]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][7][2][NULL]
+
+FILTER(LONGBLOB) v2 < NULL
+code=0 rows=0
+
+FILTER(LONGBLOB) v2 > NULL
+code=0 rows=21
+[0][0][0][B]
+[0][1][0][GI]
+[0][2][0][JHFFE]
+[0][3][0][FDHHDEDBHH]
+[0][4][0][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[0][5][0][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[0][6][0][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[1][0][1][B]
+[1][1][1][GI]
+[1][2][1][JHFFE]
+[1][3][1][FDHHDEDBHH]
+[1][4][1][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[1][5][1][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[1][6][1][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+[2][0][2][B]
+[2][1][2][GI]
+[2][2][2][JHFFE]
+[2][3][2][FDHHDEDBHH]
+[2][4][2][FEFJEICICEFFADGGIEBCCGIDFJECIJHBGJGJFCCBJEBBBCAGGCHFEAAIGDIGAAIBFIHHJBGEBGDADBIIHHIJEDDDIBHIFDFIFAIF]
+[2][5][2][DIEIIDGEIGAHICBIACDFGJAJBAAECEIGIDFFHFFFDDADDIHGECGEEADDAHBAHGAHGIIAFFIHAGBDAHDCAHJHFGDJIEEBJDGDEFBHDGJGHEJDHBJDIBDAGIIBGAAHCJGFBCFEDBGDIBGACBJFDFADJEDFACDCDJCIDECEHJFBGCCBJAECGEBCBFAGEICBHAHIGGDBGEFE]
+[2][6][2][DHDIHIGFJIFCHGDCFCDAJIDDAAJCEIGDAFCGCECIADFFHJBEIBBIFICGHIAFJCGJCHEBDIBFBAEDHFEDFJAGDGIBHFJIEFHGJHCEDAIBJDHIFDEDCFDIIFAEEGABDIBHCGCJDCHJJICEFIJHDBGCGJHAJBHFHIHCCHDJJBJFDHCIAFAJHBAECAIBHGHIFCDAGDBHGJDFIHGJIAFBIEFHCEFFCDEAGBBCAAHGCBCIAJCBDBCGGJHJEGBAGCFAFGIBHDGDHDCBCEHIJJAIDDCICCAAIGBFIFGBGIAAFEJFGFEEJFDDGJGGDECECJIBIIDDFEAIAEJGCJCBFDAGEAAEBGHFJAHFABGHHGDFBGJGEJFADJIGGGDCCBHABJHADDHGFIIDDEABFDBFEHJCECBCFAAJCBEIHAIJDCGDGCGDFFHCDEJCGCGGEIFBDHADJEAAGDBCAJGDCFABCJGGJCEGHAHFJEJCCAIHFCAEBCHHEHIHEGICGFCAHJAEFHAFIEA]
+
+FILTER(LONGBLOB) v2 <= NULL
+code=0 rows=3
+[0][7][0][NULL]
+[1][7][1][NULL]
+[2][7][2][NULL]
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test19.pl b/plugin/handler_socket/regtest/test_01_lib/test19.pl
new file mode 100644
index 00000000000..6c43267c927
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test19.pl
@@ -0,0 +1,190 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for filters
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use bigint;
+use hstest;
+
+my $numeric_types = [
+ [ 'TINYINT', -128, 127 ],
+ [ 'TINYINT UNSIGNED', 0, 255 ],
+ [ 'SMALLINT', -32768, 32768 ],
+ [ 'SMALLINT UNSIGNED', 0, 65535 ],
+ [ 'MEDIUMINT', -8388608, 8388607 ],
+ [ 'MEDIUMINT UNSIGNED', 0, 16777215 ],
+ [ 'INT', -2147483648, 2147483647 ],
+ [ 'INT UNSIGNED', 0, 4294967295 ],
+ [ 'BIGINT', -9223372036854775808, 9223372036854775807 ],
+ [ 'BIGINT UNSIGNED', 0, 18446744073709551615 ],
+ [ 'FLOAT', -32768, 32768 ],
+ [ 'DOUBLE', -2147483648, 2147483647 ],
+];
+my $datetime_types = [
+ [ 'DATE', '0000-00-00', '2011-01-01', '9999-12-31' ],
+ [ 'DATETIME', 0, '2011-01-01 18:30:25' ],
+ [ 'TIME', 0, '18:30:25' ],
+ [ 'YEAR(4)', 1901, 2011, 2155 ],
+ # [ 'TIMESTAMP', 0, 999999999 ], # DOES NOT WORK YET
+];
+my $string_types = [
+ [ 'CHAR(10)', undef, 1, 2, 5, 10 ],
+ [ 'VARCHAR(10)', undef, 1, 2, 5, 10 ],
+ [ 'BINARY(10)', undef, 1, 2, 5, 10 ],
+ [ 'VARBINARY(10)', undef, 1, 2, 5, 10 ],
+ [ 'CHAR(255)', undef, 1, 2, 5, 10, 100, 200, 255 ],
+ [ 'VARCHAR(255)', undef, 1, 2, 5, 10, 100, 200, 255 ],
+ [ 'VARCHAR(511)', undef, 1, 2, 5, 10, 100, 200, 511 ],
+ [ 'LONGTEXT', 500, 1, 2, 5, 10, 100, 200, 511 ], # NOT SUPPORTED YET
+ [ 'LONGBLOB', 500, 1, 2, 5, 10, 100, 200, 511 ], # NOT SUPPORTED YET
+# [ 'VARCHAR(4096)', 500, 1, 2, 5, 10, 100, 200, 255, 256, 4095 ],
+# [ 'VARCHAR(16383)', 500, 1, 2, 5, 10, 100, 200, 255, 256, 4095, 4096, 16383 ],
+# [ 'VARBINARY(16383)', 500, 1, 2, 5, 10, 100, 200, 255, 256, 4095, 4096, 16383 ],
+];
+
+for my $rec (@$numeric_types) {
+ my ($typ, $minval, $maxval) = @$rec;
+ my @vals = ();
+ push(@vals, 0);
+ push(@vals, $maxval);
+ if ($minval != 0) {
+ push(@vals, $minval);
+ }
+ my $v1 = $minval;
+ my $v2 = $maxval;
+ for (my $i = 0; $i < 3; ++$i) {
+ $v1 /= 3;
+ $v2 /= 3;
+ push(@vals, int($v1));
+ push(@vals, int($v2));
+ }
+ my %vm = map { $_ => 1 } @vals;
+ @vals = sort { $a <=> $b } keys %vm;
+ push(@vals, undef);
+ test_one($typ, undef, \@vals);
+}
+
+for my $rec (@$datetime_types) {
+ my ($typ, @vals) = @$rec;
+ push(@vals, undef);
+ test_one($typ, undef, \@vals);
+}
+
+for my $rec (@$string_types) {
+ my ($typ, $keylen, @vs) = @$rec;
+ my @vals = ();
+ srand(999);
+ for my $len (@vs) {
+ my $s = '';
+ my @arr = ();
+ # print "$len 1\n";
+ for (my $i = 0; $i < $len; ++$i) {
+ my $v = int(rand(10));
+ $arr[$i] = chr(65 + $v);
+ }
+ # print "2\n";
+ push(@vals, join('', @arr));
+ }
+ push(@vals, undef);
+ test_one($typ, $keylen, \@vals);
+}
+
+my $hs;
+
+sub test_one {
+ my ($typ, $keylen, $values) = @_;
+ print "\n$typ -------------------------------------------------\n\n";
+ my $keylen_str = '';
+ if (defined($keylen)) {
+ $keylen_str = "($keylen)";
+ }
+ my $dbh = hstest::init_testdb();
+ my $table = 'hstesttbl';
+ my $tablesize = 3;
+ $dbh->do(
+ "create table $table " .
+ "(k1 int not null, k2 int not null, " .
+ "v1 int not null, v2 $typ default null, " .
+ "primary key (k1, k2) ) engine = innodb");
+ my $sth = $dbh->prepare("insert into $table values (?,?,?,?)");
+ for (my $i = 0; $i < $tablesize; ++$i) {
+ my $j = 0;
+ for my $v (@$values) {
+ $sth->execute($i, $j, $i, $v);
+ ++$j;
+ }
+ }
+ $hs = hstest::get_hs_connection(undef, 9999);
+ my $dbname = $hstest::conf{dbname};
+ $hs->open_index(1, $dbname, $table, '', 'k1,k2,v1,v2', 'v2');
+ my $minval = $values->[0];
+ # select * ... where (k1, k2) >= ('', $minval)
+ exec_multi(
+ 4, "FILTER($typ) NO FILTER",
+ [ 1, '>=', [ '', $minval ], 1000, 0 ]
+ );
+ for my $v (@$values) {
+ my $vstr = defined($v) ? $v : 'NULL';
+ # select * ... where (k1, k2) >= ('', $minval) and v2 = $v
+ exec_multi(
+ 4, "FILTER($typ) v2 = $vstr",
+ [ 1, '>=', [ '', $minval ], 1000, 0, undef, undef, [ [ 'F', '=', 0, $v ] ] ]
+ );
+ # select * ... where (k1, k2) >= ('', $minval) and v2 != $v
+ exec_multi(
+ 4, "FILTER($typ) v2 != $vstr",
+ [ 1, '>=', [ '', $minval ], 1000, 0, undef, undef, [ [ 'F', '!=', 0, $v ] ] ]
+ );
+ # select * ... where (k1, k2) >= ('', $minval) and v2 >= $v
+ exec_multi(
+ 4, "FILTER($typ) v2 >= $vstr",
+ [ 1, '>=', [ '', $minval ], 1000, 0, undef, undef, [ [ 'F', '>=', 0, $v ] ] ]
+ );
+ # select * ... where (k1, k2) >= ('', $minval) and v2 < $v
+ exec_multi(
+ 4, "FILTER($typ) v2 < $vstr",
+ [ 1, '>=', [ '', $minval ], 1000, 0, undef, undef, [ [ 'F', '<', 0, $v ] ] ]
+ );
+ # select * ... where (k1, k2) >= ('', $minval) and v2 > $v
+ exec_multi(
+ 4, "FILTER($typ) v2 > $vstr",
+ [ 1, '>=', [ '', $minval ], 1000, 0, undef, undef, [ [ 'F', '>', 0, $v ] ] ]
+ );
+ # select * ... where (k1, k2) >= ('', $minval) and v2 <= $v
+ exec_multi(
+ 4, "FILTER($typ) v2 <= $vstr",
+ [ 1, '>=', [ '', $minval ], 1000, 0, undef, undef, [ [ 'F', '<=', 0, $v ] ] ]
+ );
+ }
+ undef $hs;
+}
+
+sub exec_multi {
+ my $width = shift(@_);
+ my $mess = shift(@_);
+ print "$mess\n";
+ my $mres = $hs->execute_multi(\@_);
+ for my $res (@$mres) {
+ my $code = shift(@$res);
+ my $nrows = $code == 0 ? scalar(@$res) / $width : 0;
+ print "code=$code rows=$nrows\n";
+ my $i = 0;
+ for my $fld (@$res) {
+ $fld = 'NULL' if !defined($fld);
+ print "[$fld]";
+ if (++$i >= $width) {
+ print "\n";
+ $i = 0;
+ }
+ }
+ print "\n";
+ }
+}
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test20.expected b/plugin/handler_socket/regtest/test_01_lib/test20.expected
new file mode 100644
index 00000000000..996f63870d2
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test20.expected
@@ -0,0 +1,2 @@
+open_index 1st r=1
+open_index 2nd r=0
diff --git a/plugin/handler_socket/regtest/test_01_lib/test20.pl b/plugin/handler_socket/regtest/test_01_lib/test20.pl
new file mode 100644
index 00000000000..139bbf9aba1
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test20.pl
@@ -0,0 +1,33 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for a bug that table mdl is not released when open_index is failed
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $dbname = $hstest::conf{dbname};
+my $table = 'hstesttbl';
+
+$dbh->do("drop table if exists $table");
+
+my $hs = hstest::get_hs_connection();
+my $r = $hs->open_index(1, $dbname, $table, '', 'k,v'); # fails
+print "open_index 1st r=$r\n";
+undef $hs;
+
+$dbh->do(
+ "create table $table (k varchar(30) primary key, v varchar(30) not null) " .
+ "engine = innodb");
+
+$hs = hstest::get_hs_connection();
+$r = $hs->open_index(1, $dbname, $table, '', 'k,v'); # success
+print "open_index 2nd r=$r\n";
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test21.expected b/plugin/handler_socket/regtest/test_01_lib/test21.expected
new file mode 100644
index 00000000000..1d78f805b6f
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test21.expected
@@ -0,0 +1,11 @@
+HS
+k10 v704-10
+k30 v52-30
+k40 v878-40
+k50 v682-50
+SQL
+k10 v704-10
+k30 v52-30
+k40 v878-40
+k50 v682-50
+END
diff --git a/plugin/handler_socket/regtest/test_01_lib/test21.pl b/plugin/handler_socket/regtest/test_01_lib/test21.pl
new file mode 100644
index 00000000000..413ea636400
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test21.pl
@@ -0,0 +1,58 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for 'IN'
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 100;
+$dbh->do(
+ "create table $table (k varchar(30) primary key, v varchar(30) not null) " .
+ "engine = innodb");
+srand(999);
+
+my %valmap = ();
+
+my $sth = $dbh->prepare("insert into $table values (?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "k" . $i;
+ my $v = "v" . int(rand(1000)) . "-" . $i;
+ $sth->execute($k, $v);
+ $valmap{$k} = $v;
+}
+
+my $hs = hstest::get_hs_connection();
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v');
+my $vs = [ 'k10', 'k20x', 'k30', 'k40', 'k50' ];
+# select k,v from $table where k in $vs
+my $r = $hs->execute_single(1, '=', [ '' ], 10000, 0, undef, undef, undef,
+ 0, $vs);
+shift(@$r);
+print "HS\n";
+my $len = scalar(@$r) / 2;
+for (my $i = 0; $i < $len; ++$i) {
+ my $k = $r->[$i * 2];
+ my $v = $r->[$i * 2 + 1];
+ print "$k $v\n";
+}
+
+print "SQL\n";
+my $aref = $dbh->selectall_arrayref(
+ "select k,v from $table where k in ('k10', 'k20x', 'k30', 'k40', 'k50') "
+ . "order by k");
+for my $row (@$aref) {
+ my ($k, $v) = @$row;
+ print "$k $v\n";
+}
+print "END\n";
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test22.expected b/plugin/handler_socket/regtest/test_01_lib/test22.expected
new file mode 100644
index 00000000000..5ad2bfae1f8
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test22.expected
@@ -0,0 +1,9 @@
+HS
+k10 v704-10 1
+k30 v52-30 1
+k50 v682-50 1
+SQL
+k10 v704-10 1
+k30 v52-30 1
+k50 v682-50 1
+END
diff --git a/plugin/handler_socket/regtest/test_01_lib/test22.pl b/plugin/handler_socket/regtest/test_01_lib/test22.pl
new file mode 100644
index 00000000000..cf029944292
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test22.pl
@@ -0,0 +1,61 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for 'IN' and filters
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 100;
+$dbh->do(
+ "create table $table (k varchar(30) primary key, " .
+ "v varchar(30) not null, v2 int not null) " .
+ "engine = innodb");
+srand(999);
+
+my %valmap = ();
+
+my $sth = $dbh->prepare("insert into $table values (?,?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "k" . $i;
+ my $v = "v" . int(rand(1000)) . "-" . $i;
+ my $v2 = ($i / 10) % 2;
+ $sth->execute($k, $v, $v2);
+ $valmap{$k} = $v;
+}
+
+my $hs = hstest::get_hs_connection();
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v,v2', 'v2');
+my $vs = [ 'k10', 'k20x', 'k30', 'k40', 'k50' ];
+# select k,v,v2 from $table where k in $vs
+my $r = $hs->execute_single(1, '=', [ '' ], 10000, 0, undef, undef,
+ [['F', '=', 0, '1']], 0, $vs);
+shift(@$r);
+print "HS\n";
+my $len = scalar(@$r) / 3;
+for (my $i = 0; $i < $len; ++$i) {
+ my $k = $r->[$i * 3];
+ my $v = $r->[$i * 3 + 1];
+ my $v2 = $r->[$i * 3 + 2];
+ print "$k $v $v2\n";
+}
+
+print "SQL\n";
+my $aref = $dbh->selectall_arrayref(
+ "select k,v,v2 from $table where k in ('k10', 'k20x', 'k30', 'k40', 'k50') "
+ . "and v2 = '1' order by k");
+for my $row (@$aref) {
+ my ($k, $v, $v2) = @$row;
+ print "$k $v $v2\n";
+}
+print "END\n";
+
diff --git a/plugin/handler_socket/regtest/test_01_lib/test23.expected b/plugin/handler_socket/regtest/test_01_lib/test23.expected
new file mode 100644
index 00000000000..16ed1884c4b
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test23.expected
@@ -0,0 +1,101 @@
+HS
+k0 v102-0 0
+k1 v635-1 0
+k10 MOD 1
+k11 v751-11 1
+k12 v367-12 1
+k13 v400-13 1
+k14 v397-14 1
+k15 v170-15 1
+k16 v719-16 1
+k17 v734-17 1
+k18 v587-18 1
+k19 v494-19 1
+k2 v803-2 0
+k20 v523-20 0
+k21 v954-21 0
+k22 v433-22 0
+k23 v820-23 0
+k24 v283-24 0
+k25 v837-25 0
+k26 v205-26 0
+k27 v415-27 0
+k28 v545-28 0
+k29 v583-29 0
+k3 v925-3 0
+k30 MOD 1
+k31 v323-31 1
+k32 v614-32 1
+k33 v679-33 1
+k34 v805-34 1
+k35 v451-35 1
+k36 v115-36 1
+k37 v269-37 1
+k38 v218-38 1
+k39 v617-39 1
+k4 v775-4 0
+k40 v878-40 0
+k41 v345-41 0
+k42 v512-42 0
+k43 v969-43 0
+k44 v408-44 0
+k45 v291-45 0
+k46 v858-46 0
+k47 v953-47 0
+k48 v710-48 0
+k49 v142-49 0
+k5 v537-5 0
+k50 MOD 1
+k51 v934-51 1
+k52 v621-52 1
+k53 v965-53 1
+k54 v574-54 1
+k55 v204-55 1
+k56 v298-56 1
+k57 v134-57 1
+k58 v983-58 1
+k59 v444-59 1
+k6 v592-6 0
+k60 v144-60 0
+k61 v152-61 0
+k62 v187-62 0
+k63 v215-63 0
+k64 v8-64 0
+k65 v697-65 0
+k66 v651-66 0
+k67 v280-67 0
+k68 v701-68 0
+k69 v537-69 0
+k7 v414-7 0
+k70 v413-70 1
+k71 v69-71 1
+k72 v86-72 1
+k73 v822-73 1
+k74 v670-74 1
+k75 v370-75 1
+k76 v806-76 1
+k77 v688-77 1
+k78 v26-78 1
+k79 v66-79 1
+k8 v590-8 0
+k80 v802-80 0
+k81 v171-81 0
+k82 v557-82 0
+k83 v847-83 0
+k84 v777-84 0
+k85 v730-85 0
+k86 v987-86 0
+k87 v115-87 0
+k88 v646-88 0
+k89 v496-89 0
+k9 v302-9 0
+k90 v120-90 1
+k91 v684-91 1
+k92 v374-92 1
+k93 v65-93 1
+k94 v370-94 1
+k95 v174-95 1
+k96 v828-96 1
+k97 v867-97 1
+k98 v759-98 1
+k99 v703-99 1
diff --git a/plugin/handler_socket/regtest/test_01_lib/test23.pl b/plugin/handler_socket/regtest/test_01_lib/test23.pl
new file mode 100644
index 00000000000..83c2194bfa6
--- /dev/null
+++ b/plugin/handler_socket/regtest/test_01_lib/test23.pl
@@ -0,0 +1,53 @@
+#!/usr/bin/perl
+
+# vim:sw=2:ai
+
+# test for 'IN', filters, and modifications
+
+BEGIN {
+ push @INC, "../common/";
+};
+
+use strict;
+use warnings;
+use hstest;
+
+my $dbh = hstest::init_testdb();
+my $table = 'hstesttbl';
+my $tablesize = 100;
+$dbh->do(
+ "create table $table (k varchar(30) primary key, " .
+ "v varchar(30) not null, v2 int not null) " .
+ "engine = innodb");
+srand(999);
+
+my %valmap = ();
+
+my $sth = $dbh->prepare("insert into $table values (?,?,?)");
+for (my $i = 0; $i < $tablesize; ++$i) {
+ my $k = "k" . $i;
+ my $v = "v" . int(rand(1000)) . "-" . $i;
+ my $v2 = ($i / 10) % 2;
+ $sth->execute($k, $v, $v2);
+ $valmap{$k} = $v;
+}
+
+my $hs = hstest::get_hs_connection(undef, 9999);
+my $dbname = $hstest::conf{dbname};
+$hs->open_index(1, $dbname, $table, '', 'k,v,v2', 'v2');
+$hs->open_index(2, $dbname, $table, '', 'v', 'v2');
+my $vs = [ 'k10', 'k20x', 'k30', 'k40', 'k50' ];
+# update $table set v = 'MOD' where k in $vs and v2 = '1'
+my $r = $hs->execute_single(2, '=', [ '' ], 10000, 0, 'U', [ 'MOD' ],
+ [['F', '=', 0, '1']], 0, $vs);
+$r = $hs->execute_single(1, '>=', [ '' ], 10000, 0);
+shift(@$r);
+print "HS\n";
+my $len = scalar(@$r) / 3;
+for (my $i = 0; $i < $len; ++$i) {
+ my $k = $r->[$i * 3];
+ my $v = $r->[$i * 3 + 1];
+ my $v2 = $r->[$i * 3 + 2];
+ print "$k $v $v2\n";
+}
+
diff --git a/regex/Makefile.am b/regex/Makefile.am
index 6e46e537c4b..7f4ace4a227 100644
--- a/regex/Makefile.am
+++ b/regex/Makefile.am
@@ -18,7 +18,9 @@
INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
noinst_LTLIBRARIES = libregex.la
LDADD= libregex.la $(top_builddir)/strings/libmystrings.la
-noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c my_regex.h
+internalincludedir = $(pkgincludedir)/private
+internalinclude_HEADERS = my_regex.h
+noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c
libregex_la_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c
noinst_PROGRAMS = re
re_SOURCES = split.c debug.c main.c
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index a62569843db..d0cbafccc82 100755
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -80,7 +80,10 @@ CONFIGURE_FILE(mysqldumpslow.sh
CONFIGURE_FILE(mysqlhotcopy.sh
${CMAKE_BINARY_DIR}/scripts/mysqlhotcopy.pl ESCAPE_QUOTES @ONLY)
-FOREACH(f mysqldumpslow.pl mysqlhotcopy.pl mysql_config.pl
+CONFIGURE_FILE(mytop.sh
+ ${CMAKE_BINARY_DIR}/scripts/mytop.pl ESCAPE_QUOTES @ONLY)
+
+FOREACH(f mysqldumpslow.pl mysqlhotcopy.pl mytop.pl mysql_config.pl
mysql_convert_table_format.pl mysql_install_db.pl
mysql_secure_installation.pl mysqld_multi.pl)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${f}
@@ -90,4 +93,4 @@ ENDFOREACH()
INSTALL(FILES fill_help_tables.sql mysql_system_tables.sql
mysql_system_tables_data.sql mysql_system_tables_fix.sql mysql_test_data_timezone.sql
DESTINATION share COMPONENT Server)
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql_fix_privilege_tables.sql DESTINATION share COMPONENT Server) \ No newline at end of file
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql_fix_privilege_tables.sql DESTINATION share COMPONENT Server)
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index f2bc4b6a82b..66f2b0165fa 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -33,6 +33,7 @@ bin_SCRIPTS = @server_scripts@ \
mysql_convert_table_format \
mysql_find_rows \
mysqlhotcopy \
+ mytop \
mysqldumpslow \
mysqld_multi
@@ -58,6 +59,7 @@ EXTRA_SCRIPTS = make_binary_distribution.sh \
mysql_convert_table_format.sh \
mysql_find_rows.sh \
mysqlhotcopy.sh \
+ mytop.sh \
mysqldumpslow.sh \
mysqld_multi.sh \
mysqld_safe.sh \
@@ -91,6 +93,7 @@ CLEANFILES = @server_scripts@ \
mysql_convert_table_format \
mysql_find_rows \
mysqlhotcopy \
+ mytop \
mysqldumpslow \
mysqld_multi \
convert-debug-for-diff \
@@ -114,7 +117,10 @@ mysqlbug: ${top_builddir}/config.status mysqlbug.sh
mysql_fix_privilege_tables.sql: mysql_system_tables.sql \
mysql_system_tables_fix.sql
@echo "Building $@";
- @cat mysql_system_tables.sql mysql_system_tables_fix.sql > $@
+ @echo "-- This file is automaticly generated from" > $@
+ @echo "-- mysql_system_tables.sql & mysql_system_tables_fix.sql" >> $@
+ @echo "" >> $@
+ @cat mysql_system_tables.sql mysql_system_tables_fix.sql >> $@
#
# Build mysql_fix_privilege_tables_sql.c from
diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh
index 828670d9408..070b396a34c 100644
--- a/scripts/make_binary_distribution.sh
+++ b/scripts/make_binary_distribution.sh
@@ -169,6 +169,7 @@ esac
VERSION_NAME=@VERSION@
case $VERSION_NAME in
*-ndb-* ) VERSION_NAME=`echo $VERSION_NAME | sed -e 's/[.0-9]*-ndb-//'` ;;
+ *-MariaDB-* ) VERSION_NAME=`echo $VERSION_NAME | sed -e 's/-MariaDB//'` ;;
esac
if [ x"$SHORT_PRODUCT_TAG" != x"" ] ; then
NEW_NAME=mariadb-$SHORT_PRODUCT_TAG-$VERSION_NAME-$PLATFORM$SUFFIX
@@ -284,7 +285,8 @@ if [ x"$BASE_SYSTEM" != x"netware" ] ; then
pkgplugindir=@pkgplugindir@ \
pkgsuppdir=@pkgsuppdir@ \
mandir=@mandir@ \
- infodir=@infodir@
+ infodir=@infodir@ \
+ libexecdir=@prefix@/libexec
# ----------------------------------------------------------------------
# Rename top directory, and set DEST to the new directory
@@ -300,7 +302,10 @@ if [ x"$BASE_SYSTEM" != x"netware" ] ; then
if [ -z "$gcclib" ] ; then
echo "Warning: Compiler doesn't tell libgcc.a!"
elif [ -f "$gcclib" ] ; then
+ {
+ mkdir -p $DEST/lib
$CP $gcclib $DEST/lib/libmygcc.a
+ }
else
echo "Warning: Compiler result '$gcclib' not found / no file!"
fi
@@ -459,6 +464,7 @@ copyfileto $BASE/bin $BIN_FILES
$CP netware/*.pl $BASE/scripts
$CP scripts/mysqlhotcopy $BASE/scripts/mysqlhotcopy.pl
+$CP scripts/mytop $BASE/scripts/mytop.pl
copyfileto $BASE/lib \
libmysql/.libs/libmysqlclient.a \
diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist
index 35299f771cd..6a782c09cdb 100755
--- a/scripts/make_win_bin_dist
+++ b/scripts/make_win_bin_dist
@@ -374,6 +374,7 @@ mysql_secure_installation.pl \
mysqld_multi.pl \
mysqldumpslow.pl \
mysqlhotcopy.pl \
+mytop.pl \
"
mkdir -p $DESTDIR/scripts
diff --git a/scripts/mysql_config.sh b/scripts/mysql_config.sh
index f1d46c0b2c0..ce61c09aa15 100644
--- a/scripts/mysql_config.sh
+++ b/scripts/mysql_config.sh
@@ -86,7 +86,7 @@ bindir='@bindir@'
# If installed, search for the compiled in directory first (might be "lib64")
pkglibdir='@pkglibdir@'
pkglibdir_rel=`echo $pkglibdir | sed -e "s;^$basedir/;;"`
-fix_path pkglibdir $pkglibdir_rel lib/mysql lib
+fix_path pkglibdir $pkglibdir_rel lib64/mysql lib64 lib/mysql lib
plugindir='@pkgplugindir@'
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 23eadd8312b..4da9a74ce40 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -425,9 +425,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:"
diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql
index bfa9e9fbd37..6676b73e0f7 100644
--- a/scripts/mysql_system_tables.sql
+++ b/scripts/mysql_system_tables.sql
@@ -30,7 +30,7 @@ set @had_db_table= @@warning_count != 0;
CREATE TABLE IF NOT EXISTS host ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Host privileges; Merged with database privileges';
-CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) unsigned DEFAULT 0 NOT NULL, plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL, auth_string TEXT NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges';
+CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) DEFAULT 0 NOT NULL, plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL, auth_string TEXT NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges';
-- Remember for later if user table already existed
set @had_user_table= @@warning_count != 0;
@@ -45,9 +45,9 @@ CREATE TABLE IF NOT EXISTS plugin ( name char(64) binary DEFAULT '' NOT NULL, dl
CREATE TABLE IF NOT EXISTS servers ( Server_name char(64) NOT NULL DEFAULT '', Host char(64) NOT NULL DEFAULT '', Db char(64) NOT NULL DEFAULT '', Username char(64) NOT NULL DEFAULT '', Password char(64) NOT NULL DEFAULT '', Port INT(4) NOT NULL DEFAULT '0', Socket char(64) NOT NULL DEFAULT '', Wrapper char(64) NOT NULL DEFAULT '', Owner char(64) NOT NULL DEFAULT '', PRIMARY KEY (Server_name)) CHARACTER SET utf8 comment='MySQL Foreign Servers table';
-CREATE TABLE IF NOT EXISTS tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges';
+CREATE TABLE IF NOT EXISTS tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp, Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges';
-CREATE TABLE IF NOT EXISTS columns_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges';
+CREATE TABLE IF NOT EXISTS columns_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges';
CREATE TABLE IF NOT EXISTS help_topic ( help_topic_id int unsigned not null, name char(64) not null, help_category_id smallint unsigned not null, description text not null, example text not null, url char(128) not null, primary key (help_topic_id), unique index (name) ) engine=MyISAM CHARACTER SET utf8 comment='help topics';
@@ -79,11 +79,11 @@ CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint sign
CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'IGNORE_BAD_TABLE_OPTIONS', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
-CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
+CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp, PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
-- Create general_log if CSV is enabled.
-SET @str = IF (@@have_csv = 'YES', 'CREATE TABLE IF NOT EXISTS general_log (event_time TIMESTAMP NOT NULL, user_host MEDIUMTEXT NOT NULL, thread_id INTEGER NOT NULL, server_id INTEGER UNSIGNED NOT NULL, command_type VARCHAR(64) NOT NULL, argument MEDIUMTEXT NOT NULL) engine=CSV CHARACTER SET utf8 comment="General log"', 'SET @dummy = 0');
+SET @str = IF (@@have_csv = 'YES', 'CREATE TABLE IF NOT EXISTS general_log (event_time TIMESTAMP(6) NOT NULL, user_host MEDIUMTEXT NOT NULL, thread_id INTEGER NOT NULL, server_id INTEGER UNSIGNED NOT NULL, command_type VARCHAR(64) NOT NULL, argument MEDIUMTEXT NOT NULL) engine=CSV CHARACTER SET utf8 comment="General log"', 'SET @dummy = 0');
PREPARE stmt FROM @str;
EXECUTE stmt;
@@ -91,7 +91,7 @@ DROP PREPARE stmt;
-- Create slow_log if CSV is enabled.
-SET @str = IF (@@have_csv = 'YES', 'CREATE TABLE IF NOT EXISTS slow_log (start_time TIMESTAMP NOT NULL, user_host MEDIUMTEXT NOT NULL, query_time TIME NOT NULL, lock_time TIME NOT NULL, rows_sent INTEGER NOT NULL, rows_examined INTEGER NOT NULL, db VARCHAR(512) NOT NULL, last_insert_id INTEGER NOT NULL, insert_id INTEGER NOT NULL, server_id INTEGER UNSIGNED NOT NULL, sql_text MEDIUMTEXT NOT NULL) engine=CSV CHARACTER SET utf8 comment="Slow log"', 'SET @dummy = 0');
+SET @str = IF (@@have_csv = 'YES', 'CREATE TABLE IF NOT EXISTS slow_log (start_time TIMESTAMP(6) NOT NULL, user_host MEDIUMTEXT NOT NULL, query_time TIME(6) NOT NULL, lock_time TIME(6) NOT NULL, rows_sent INTEGER NOT NULL, rows_examined INTEGER NOT NULL, db VARCHAR(512) NOT NULL, last_insert_id INTEGER NOT NULL, insert_id INTEGER NOT NULL, server_id INTEGER UNSIGNED NOT NULL, sql_text MEDIUMTEXT NOT NULL) engine=CSV CHARACTER SET utf8 comment="Slow log"', 'SET @dummy = 0');
PREPARE stmt FROM @str;
EXECUTE stmt;
diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql
index a50cffd0cec..89e2caf7975 100644
--- a/scripts/mysql_system_tables_fix.sql
+++ b/scripts/mysql_system_tables_fix.sql
@@ -237,7 +237,7 @@ ALTER TABLE func
SET @old_log_state = @@global.general_log;
SET GLOBAL general_log = 'OFF';
ALTER TABLE general_log
- MODIFY event_time TIMESTAMP NOT NULL,
+ MODIFY event_time TIMESTAMP(6) NOT NULL,
MODIFY user_host MEDIUMTEXT NOT NULL,
MODIFY thread_id INTEGER NOT NULL,
MODIFY server_id INTEGER UNSIGNED NOT NULL,
@@ -248,10 +248,10 @@ SET GLOBAL general_log = @old_log_state;
SET @old_log_state = @@global.slow_query_log;
SET GLOBAL slow_query_log = 'OFF';
ALTER TABLE slow_log
- MODIFY start_time TIMESTAMP NOT NULL,
+ MODIFY start_time TIMESTAMP(6) NOT NULL,
MODIFY user_host MEDIUMTEXT NOT NULL,
- MODIFY query_time TIME NOT NULL,
- MODIFY lock_time TIME NOT NULL,
+ MODIFY query_time TIME(6) NOT NULL,
+ MODIFY lock_time TIME(6) NOT NULL,
MODIFY rows_sent INTEGER NOT NULL,
MODIFY rows_examined INTEGER NOT NULL,
MODIFY db VARCHAR(512) NOT NULL,
@@ -341,8 +341,11 @@ UPDATE host SET Create_routine_priv=Create_priv, Alter_routine_priv=Alter_priv,
#
# Add max_user_connections resource limit
+# this is signed in MariaDB so that if one sets it's to -1 then the user
+# can't connect anymore.
#
-ALTER TABLE user ADD max_user_connections int(11) unsigned DEFAULT '0' NOT NULL AFTER max_connections;
+ALTER TABLE user ADD max_user_connections int(11) DEFAULT '0' NOT NULL AFTER max_connections;
+ALTER TABLE user MODIFY max_user_connections int(11) DEFAULT '0' NOT NULL AFTER max_connections;
#
# user.Create_user_priv
@@ -378,7 +381,7 @@ ALTER TABLE procs_priv
COLLATE utf8_general_ci NOT NULL AFTER Routine_name;
ALTER TABLE procs_priv
- MODIFY Timestamp timestamp(14) AFTER Proc_priv;
+ MODIFY Timestamp timestamp AFTER Proc_priv;
#
# proc
diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh
index 3cbc956ee01..5977a181c93 100644
--- a/scripts/mysqlhotcopy.sh
+++ b/scripts/mysqlhotcopy.sh
@@ -873,7 +873,7 @@ A sample log-pos table definition:
CREATE TABLE log_pos (
host varchar(60) NOT null,
- time_stamp timestamp(14) NOT NULL,
+ time_stamp timestamp NOT NULL,
log_file varchar(32) default NULL,
log_pos int(11) default NULL,
master_host varchar(60) NULL,
diff --git a/scripts/mytop.sh b/scripts/mytop.sh
new file mode 100755
index 00000000000..a36fddf7368
--- /dev/null
+++ b/scripts/mytop.sh
@@ -0,0 +1,2459 @@
+#!/usr/bin/perl -w
+#
+# $Id: mytop,v 1.90 2010/05/23 10:51:21 mark Exp $
+
+=pod
+
+=head1 NAME
+
+mytop - display MySQL server performance info like `top'
+
+=cut
+
+## most of the POD is at the bottom of the file
+
+use 5.005;
+use strict;
+use DBI;
+use Getopt::Long;
+use Socket;
+use List::Util qw(min max);
+use File::Basename;
+
+$main::VERSION = "1.9a";
+my $path_for_script= dirname($0);
+
+$|=1;
+$0 = 'mytop';
+
+my $WIN = ($^O eq 'MSWin32') ? 1 : 0;
+
+## Test for color support.
+
+eval { require Term::ANSIColor; };
+
+my $HAS_COLOR = $@ ? 0 : 1;
+
+$HAS_COLOR = 0 if $WIN;
+
+## Test of Time::HiRes support
+
+eval { require Time::HiRes };
+
+my $HAS_TIME = $@ ? 0 : 1;
+
+my $debug = 0;
+
+## Try to lower our priority (which, who, pri)
+
+setpriority(0,0,10) unless $WIN;
+
+## Prototypes
+
+sub Clear();
+sub GetData();
+sub GetQPS();
+sub FullQueryInfo($);
+sub Explain($);
+sub PrintTable(@);
+sub PrintHelp();
+sub Sum(@);
+sub commify($);
+sub make_short($);
+sub Hashes($);
+sub Execute($);
+sub StringOrRegex($);
+sub GetInnoDBStatus();
+sub GetCmdSummary();
+sub GetShowVariables();
+sub GetShowStatus();
+sub cmd_s;
+sub cmd_S;
+sub cmd_q;
+sub FindProg($);
+
+## Default Config Values
+
+my %config = (
+ batchmode => 0,
+ color => 1,
+ db => 'test',
+ delay => 5,
+ filter_user => qr/.?/,
+ filter_db => qr/.?/,
+ filter_host => qr/.?/,
+ filter_state => qr/.?/,
+ header => 1,
+ help => 0,
+ host => 'localhost',
+ idle => 1,
+ long => 120,
+ long_nums => 0,
+ mode => 'top',
+ prompt => 0,
+ pass => '',
+ port => 3306,
+ resolve => 0,
+ slow => 10, # slow query time
+ socket => '',
+ sort => 0, # default or reverse sort ("s")
+ user => 'root',
+ fullqueries => 0
+);
+
+my %qcache = (); ## The query cache--used for full query info support.
+my %ucache = (); ## The user cache--used for full killing by user
+my %dbcache = (); ## The db cache. This should be merged at some point.
+my %statcache = (); ## The show status cache for GetShowStatus()
+
+my (%STATUS, %OLD_STATUS); # header stuff.
+
+my $CLEAR = $WIN ? '': `clear`;
+
+## Term::ReadKey values
+
+my $RM_RESET = 0;
+my $RM_NOBLKRD = 3; ## using 4 traps Ctrl-C :-(
+
+# Add options from .my.cnf first
+
+my $my_print_defaults;
+if (!defined($my_print_defaults=my_which("my_print_defaults")))
+{
+ print "Warning: Can't find my_print_defaults. Please add it to your PATH!\n";
+ exit(1);
+}
+
+unshift @ARGV, split "\n", `$my_print_defaults client mytop`;
+
+## Read the user's config file, if it exists.
+
+my $config = "$ENV{HOME}/.mytop";
+
+if (-e $config)
+{
+ if (open CFG, "<$config")
+ {
+ while (<CFG>)
+ {
+ next if /^\s*$/; ## skip blanks
+ next if /^\s*#/; ## skip comments
+
+ chomp;
+
+ if (/(\S+)\s*=\s*(.*\S)/)
+ {
+ $config{lc $1} = $2 if exists $config{lc $1};
+ }
+ }
+ close CFG;
+ }
+}
+
+## Command-line args.
+
+use vars qw($opt_foo);
+
+Getopt::Long::Configure('no_ignore_case', 'bundling');
+
+GetOptions(
+ "color!" => \$config{color},
+ "user|u=s" => \$config{user},
+ "pass|password|p=s" => \$config{pass},
+ "database|db|d=s" => \$config{db},
+ "host|h=s" => \$config{host},
+ "port|P=i" => \$config{port},
+ "socket|S=s" => \$config{socket},
+ "delay|s=i" => \$config{delay},
+ "batch|batchmode|b" => \$config{batchmode},
+ "header!" => \$config{header},
+ "idle|i!" => \$config{idle},
+ "resolve|r!" => \$config{resolve},
+ "prompt!" => \$config{prompt},
+ "long=i" => \$config{long},
+ "long_nums!" => \$config{long_nums},
+ "mode|m=s" => \$config{mode},
+ "slow=i" => \$config{slow},
+ "sort=s" => \$config{sort},
+ "fullqueries|L!" => \$config{fullqueries}
+);
+
+## User may have put the port with the host.
+
+if ($config{host} =~ s/:(\d+)$//)
+{
+ $config{port} = $1;
+}
+
+## Don't use Term::ReadKey unless running interactively.
+
+if (not $config{batchmode})
+{
+ require Term::ReadKey;
+ Term::ReadKey->import();
+}
+
+## User may want to disable color.
+
+if ($HAS_COLOR and not $config{color})
+{
+ $HAS_COLOR = 0;
+}
+
+if ($HAS_COLOR)
+{
+ import Term::ANSIColor ':constants';
+}
+else
+{
+ *RESET = sub { };
+ *YELLOW = sub { };
+ *RED = sub { };
+ *MAGENTA = sub { };
+ *GREEN = sub { };
+ *BLUE = sub { };
+ *WHITE = sub { };
+ *BOLD = sub { };
+}
+
+my $RESET = RESET() || '';
+my $YELLOW = YELLOW() || '';
+my $RED = RED() || '';
+my $MAGENTA = MAGENTA() || '';
+my $GREEN = GREEN() || '';
+my $BLUE = BLUE() || '';
+my $WHITE = WHITE() || '';
+my $BOLD = BOLD() || '';
+
+## Connect
+
+my $dsn;
+
+## Socket takes precedence.
+
+$dsn ="DBI:mysql:database=$config{db};mysql_read_default_group=mytop;";
+
+if ($config{socket} and -S $config{socket})
+{
+ $dsn .= "mysql_socket=$config{socket}";
+}
+else
+{
+ $dsn .= "host=$config{host};port=$config{port}";
+}
+
+if ($config{prompt})
+{
+ print "Password: ";
+ ReadMode(2);
+ chomp($config{pass} = <STDIN>);
+ ReadMode(0);
+ print "\n";
+}
+
+my $dbh = DBI->connect($dsn, $config{user}, $config{pass},
+ { PrintError => 0 });
+
+if (not ref $dbh)
+{
+ my $Error = <<EODIE
+Cannot connect to MySQL server. Please check the:
+
+ * database you specified "$config{db}" (default is "test")
+ * username you specified "$config{user}" (default is "root")
+ * password you specified "$config{pass}" (default is "")
+ * hostname you specified "$config{host}" (default is "localhost")
+ * port you specified "$config{port}" (default is 3306)
+ * socket you specified "$config{socket}" (default is "")
+
+The options my be specified on the command-line or in a ~/.mytop
+config file. See the manual (perldoc mytop) for details.
+
+Here's the exact error from DBI. It might help you debug:
+
+$DBI::errstr
+
+EODIE
+;
+
+ die $Error;
+
+}
+
+ReadMode($RM_RESET) unless $config{batchmode};
+
+## Get static data
+
+my $db_version;
+my $db_release;
+my $server="MySQL";
+my $have_query_cache;
+
+my @variables = Hashes("show variables");
+
+foreach (@variables)
+{
+ if ($_->{Variable_name} eq "version")
+ {
+ $db_version = $_->{Value};
+ $db_version =~ /(\d+)/;
+ $db_release= $1;
+ $server="MariaDB" if ($db_version =~ /maria/i);
+ next;
+ }
+ if ($_->{Variable_name} eq "have_query_cache")
+ {
+# if ($_->{Value} eq 'YES')
+ if ($_->{Value} eq 'YES' or $_->{Value} eq 'DEMAND') # http://freshmeat.net/users/jerjones
+ {
+ $have_query_cache = 1;
+ }
+ else
+ {
+ $have_query_cache = 0;
+ }
+ next;
+ }
+}
+
+#########################################################################
+##
+## The main loop
+##
+#########################################################################
+
+ReadMode($RM_NOBLKRD) unless $config{batchmode};
+
+while (1)
+{
+ my $key;
+
+ if ($config{mode} eq 'qps')
+ {
+ GetQPS();
+ $key = ReadKey(1);
+
+ next unless $key;
+
+ if ($key =~ /t/i)
+ {
+ $config{mode} = 'top';
+ }
+ if ($key =~ /q/)
+ {
+ cmd_q();
+ }
+ next;
+ }
+ if ($config{mode} eq 'top')
+ {
+ GetData();
+ last if $config{batchmode};
+ $key = ReadKey($config{delay});
+ next unless $key;
+ }
+ elsif ($config{mode} eq 'cmd')
+ {
+ GetCmdSummary();
+ last if $config{batchmode};
+ $key = ReadKey($config{delay});
+ next unless $key;
+ }
+ elsif ($config{mode} eq 'innodb')
+ {
+ GetInnoDBStatus();
+ last if $config{batchmode};
+ $key = ReadKey($config{delay});
+ next unless $key;
+ }
+ elsif ($config{mode} eq 'status')
+ {
+ GetShowStatus();
+ last if $config{batchmode};
+ $key = ReadKey($config{delay});
+ next unless $key;
+ }
+
+ ##
+ ## keystroke command processing (if we get this far)
+ ##
+
+ # ! - Force past a replication error
+
+ if ($key eq 'r')
+ {
+ Execute("STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; START SLAVE;");
+ next;
+ }
+
+ # t - top
+
+ if ($key =~ /t/i)
+ {
+ $config{mode} = 'top';
+ }
+
+ ## q - quit
+
+ if ($key eq 'q')
+ {
+ cmd_q();
+ }
+
+ if ($key eq 'D')
+ {
+ require Data::Dumper;
+ print Data::Dumper::Dumper([\%config]);
+ ReadKey(0);
+ }
+
+ ## l - change long running hightling
+
+ if ($key eq 'l')
+ {
+ cmd_l();
+ next;
+ }
+
+ ## m - mode swtich to qps
+
+ if ($key eq 'm')
+ {
+ $config{mode} = 'qps';
+ Clear() unless $config{batchmode};
+ print "Queries Per Second [hit q to exit this mode]\n";
+ next;
+ }
+
+ ## M - mode swtich to qps
+
+ if ($key eq 'M')
+ {
+ $config{mode} = 'status';
+ Clear() unless $config{batchmode};
+ print "Queries Per Second [hit q to exit this mode]\n";
+ next;
+ }
+
+ ## c - mode swtich to command summary
+
+ if ($key eq 'c')
+ {
+ $config{mode} = 'cmd';
+ Clear() unless $config{batchmode};
+ print "Command Summary [hit q to exit this mode]\n";
+ next;
+ }
+
+ ## C - change Color on and off
+
+ if ($key eq 'C')
+ {
+ if ( $HAS_COLOR )
+ {
+ $HAS_COLOR = 0;
+ }
+ else
+ {
+ $HAS_COLOR = 1;
+ }
+ }
+
+ ## s - seconds of delay
+
+ if ($key eq 's')
+ {
+ cmd_s();
+ next;
+ }
+
+ # Change the SLOW query value
+
+ if ($key eq 'S')
+ {
+ cmd_S();
+ next;
+ }
+
+ ## R - resolve hostnames
+ if ($key eq 'R')
+ {
+ if ($config{resolve})
+ {
+ $config{resolve} = 0;
+ }
+ else
+ {
+ $config{resolve} = 1;
+ }
+ }
+
+ ## t - username based filter
+
+ if ($key eq 't')
+ {
+ ReadMode($RM_RESET);
+ print RED(), "Which state (blank for all, /.../ for regex): ", RESET();
+ $config{filter_state} = StringOrRegex(ReadLine(0));
+ ReadMode($RM_NOBLKRD);
+ next;
+ }
+
+ ## u - username based filter
+
+ if ($key eq 'u')
+ {
+ ReadMode($RM_RESET);
+ print RED(), "Which user (blank for all, /.../ for regex): ", RESET();
+ $config{filter_user} = StringOrRegex(ReadLine(0));
+ ReadMode($RM_NOBLKRD);
+ next;
+ }
+
+ ## d - database name based filter
+
+ if ($key eq 'd')
+ {
+ ReadMode($RM_RESET);
+ print RED(), "Which database (blank for all, /.../ for regex): ",
+ RESET();
+ $config{filter_db} = StringOrRegex(ReadLine(0));
+ ReadMode($RM_NOBLKRD);
+ next;
+ }
+
+ ## h - hostname based filter
+
+ if ($key eq 'h')
+ {
+ ReadMode($RM_RESET);
+ print RED(), "Which hostname (blank for all, /.../ for regex): ",
+ RESET();
+ $config{filter_host} = StringOrRegex(ReadLine(0));
+ ReadMode($RM_NOBLKRD);
+ next;
+ }
+
+ ## E - Show full Replication Error
+
+ if ($key eq 'E')
+ {
+ my($data) = Hashes('SHOW SLAVE STATUS');
+ Clear();
+ print "Error is: $data->{Last_Error}\n";
+ print RED(), "-- paused. press any key to resume --", RESET();
+ ReadKey(0);
+ next;
+ }
+ ## F - remove all filters
+
+ if ($key eq 'F')
+ {
+ $config{filter_host} = qr/.?/;
+ $config{filter_db} = qr/.?/;
+ $config{filter_user} = qr/.?/;
+ $config{filter_state} = qr/.?/;
+ print RED(), "-- display unfiltered --", RESET();
+ sleep 1;
+ next;
+ }
+
+ ## p - pause
+
+ if ($key eq 'p')
+ {
+ print RED(), "-- paused. press any key to resume --", RESET();
+ ReadKey(0);
+ next;
+ }
+
+ ## i - idle toggle
+
+ if ($key =~ /i/)
+ {
+ if ($config{idle})
+ {
+ $config{idle} = 0;
+ $config{sort} = 1;
+ print RED(), "-- idle (sleeping) processed filtered --", RESET();
+ sleep 1;
+ }
+ else
+ {
+ $config{idle} = 1;
+ $config{sort} = 0;
+ print RED(), "-- idle (sleeping) processed unfiltered --", RESET();
+ sleep 1;
+ }
+ }
+
+ ## I - InnoDB status
+
+ if ($key =~ 'I')
+ {
+ $config{mode} = 'innodb';
+ Clear() unless $config{batchmode};
+ print "InnoDB Status [hit q to exit this mode]\n";
+ next;
+ }
+
+ ## o - sort order
+
+ if ($key =~ /o/)
+ {
+ if ($config{sort})
+ {
+ $config{sort} = 0;
+ print RED(), "-- sort order reversed --", RESET();
+ sleep 1;
+ }
+ else
+ {
+ $config{sort} = 1;
+ print RED(), "-- sort order reversed --", RESET();
+ sleep 1;
+ }
+ }
+
+ ## ? - help
+
+ if ($key eq '?')
+ {
+ Clear();
+ PrintHelp();
+ ReadKey(0);
+ next;
+ }
+
+ ## k - kill
+
+ if ($key eq 'k')
+ {
+ ReadMode($RM_RESET);
+
+ print RED(), "Thread id to kill: ", RESET();
+ my $id = ReadLine(0);
+
+ $id =~ s/\s//g;
+
+ if ($id =~ /^\d+$/)
+ {
+ Execute("KILL $id");
+ }
+ else
+ {
+ print RED(), "-- invalid thread id --", RESET();
+ sleep 1;
+ }
+
+ ReadMode($RM_NOBLKRD);
+ next;
+ }
+
+ ## K - kill based on a username
+ if ($key =~ /K/)
+ {
+ ReadMode($RM_RESET);
+
+ print RED(), "User to kill: ", RESET();
+ my $user = ReadLine(0);
+
+ $user =~ s/\s//g;
+
+ if ($user =~ /^\S+$/)
+ {
+ for my $pid (keys %ucache)
+ {
+ next unless $ucache{$pid} eq $user;
+ Execute("KILL $pid");
+ select(undef, undef, undef, 0.2);
+ }
+ }
+ else
+ {
+ print RED(), "-- invalid thread id --", RESET();
+ sleep 1;
+ }
+
+ ReadMode($RM_NOBLKRD);
+ }
+
+ ## f - full info
+
+ if ($key =~ /f/)
+ {
+ ReadMode($RM_RESET);
+ print RED(), "Full query for which thread id: ", RESET();
+ my $id = ReadLine(0);
+ chomp $id;
+ FullQueryInfo($id);
+ ReadMode($RM_NOBLKRD);
+ print RED(), "-- paused. press any key to resume or (e) to explain --",
+ RESET();
+ my $key = ReadKey(0);
+
+ if ($key eq 'e')
+ {
+ Explain($id);
+ print RED(), "-- paused. press any key to resume --", RESET();
+ ReadKey(0);
+ }
+
+ next;
+ }
+
+ ## e - explain
+
+ if ($key =~ /e/)
+ {
+ ReadMode($RM_RESET);
+ print RED(), "Explain which query (id): ", RESET();
+ my $id = ReadLine(0);
+ chomp $id;
+ Explain($id);
+ ReadMode($RM_NOBLKRD);
+ print RED(), "-- paused. press any key to resume --", RESET();
+ ReadKey(0);
+ next;
+ }
+
+ ## r - reset status counters
+
+ if ($key =~ /r/)
+ {
+ Execute("FLUSH STATUS");
+ print RED(), "-- counters reset --", RESET();
+ sleep 1;
+ next;
+ }
+
+ ## H - header toggle
+
+ if ($key eq 'H')
+ {
+ if ($config{header})
+ {
+ $config{header} = 0;
+ }
+ else
+ {
+ $config{header}++;
+ }
+ }
+
+ ## # - magic debug key
+
+ if ($key eq '#')
+ {
+ $debug = 1;
+ }
+
+ if ($key eq 'V')
+ {
+ GetShowVariables();
+ print RED(), "-- paused. press any key to resume --", RESET();
+ ReadKey(0);
+ }
+
+ if ($key eq 'S')
+ {
+ $config{mode} = 'status';
+ }
+
+ ## L - full queries toggle
+
+ if ($key eq 'L')
+ {
+ if ($config{fullqueries})
+ {
+ $config{fullqueries} = 0;
+ print RED(), "-- full queries OFF --", RESET();
+ sleep 1;
+ }
+ else
+ {
+ $config{fullqueries} = 1;
+ print RED(), "-- full queries ON --", RESET();
+ sleep 1;
+ }
+ }
+
+}
+
+ReadMode($RM_RESET) unless $config{batchmode};
+
+exit;
+
+#######################################################################
+
+sub Clear()
+{
+ if (not $WIN)
+ {
+ print "$CLEAR"
+ }
+ else
+ {
+ print "\n" x 90; ## dumb hack for now. Anyone know how to
+ ## clear the screen in dos window on a Win32
+ ## system??
+ }
+}
+
+my $last_time;
+
+sub GetData()
+{
+ ## Get terminal info
+ my $now_time;
+ %qcache = (); ## recycle memory
+ %dbcache = ();
+
+ my ($width, $height, $wpx, $hpx, $lines_left);
+
+ if (not $config{batchmode})
+ {
+ ($width, $height, $wpx, $hpx) = GetTerminalSize();
+ $lines_left = $height - 2;
+ }
+ else
+ {
+ $height = 999_999; ## I hope you don't have more than that!
+ $lines_left = 999_999;
+ $width = 80;
+ }
+
+ ##
+ ## Header stuff.
+ ##
+ if ($config{header})
+ {
+ my @recs = "";
+ if ( $db_release > 4 )
+ {
+ @recs = Hashes("show global status");
+ }
+ else
+ {
+ @recs = Hashes("show status");
+ }
+
+ ## if the server died or we lost connectivity
+ if (not @recs)
+ {
+ ReadMode($RM_RESET);
+ exit 1;
+ }
+
+ ## get high-res or low-res time
+ my ($t_delta);
+
+ if ($HAS_TIME)
+ {
+ $now_time = Time::HiRes::gettimeofday();
+ }
+ else
+ {
+ $now_time = time;
+ }
+
+ if ($last_time and $last_time != $now_time)
+ {
+ $t_delta = $now_time - $last_time;
+ }
+
+ %OLD_STATUS = %STATUS;
+
+ # Set some status that may not exist in all versions
+ $STATUS{Handler_tmp_write}= 0;
+ $STATUS{Handler_tmp_update}= 0;
+ $STATUS{Rows_tmp_read}= 0;
+
+ foreach my $ref (@recs)
+ {
+ my $key = $ref->{Variable_name};
+ my $val = $ref->{Value};
+
+ $STATUS{$key} = $val;
+ }
+
+ ## Compute Key Cache Hit Stats
+
+ $STATUS{Key_read_requests} ||= 1; ## can't divide by zero next
+
+ my $cache_hits_percent = (100-($STATUS{Key_reads}/$STATUS{Key_read_requests}) * 100);
+ $cache_hits_percent = sprintf("%2.2f",$cache_hits_percent);
+
+ ## Query Cache info for <= Ver. 4.1
+ ##
+ ## mysql> show status like 'qcache%';
+ ## +-------------------------+----------+
+ ## | Variable_name | Value |
+ ## +-------------------------+----------+
+ ## | Qcache_queries_in_cache | 81 |
+ ## | Qcache_inserts | 4961668 |
+ ## | Qcache_hits | 1374170 |
+ ## | Qcache_not_cached | 5656249 |
+ ## | Qcache_free_memory | 33164800 |
+ ## | Qcache_free_blocks | 2 |
+ ## | Qcache_total_blocks | 168 |
+ ## +-------------------------+----------+
+ ##
+ ## Query Cache info for => Ver. 5.0
+ ##
+ ## mysql> show status like 'qcache%';
+ ## +-------------------------+------------+
+ ## | Variable_name | Value |
+ ## +-------------------------+------------+
+ ## | Qcache_free_blocks | 37652 |
+ ## | Qcache_free_memory | 110289712 |
+ ## | Qcache_hits | 1460617356 |
+ ## | Qcache_inserts | 390563495 |
+ ## | Qcache_lowmem_prunes | 6414172 |
+ ## | Qcache_not_cached | 93002420 |
+ ## | Qcache_queries_in_cache | 66558 |
+ ## | Qcache_total_blocks | 192031 |
+ ## +-------------------------+------------+
+
+ my $query_cache_hits = 0;
+ my $query_cache_hits_per_sec = 0;
+ my $now_query_cache_hits_per_sec = 0;
+
+ if ($have_query_cache)
+ {
+ $query_cache_hits = $STATUS{Qcache_hits};
+ $query_cache_hits_per_sec = $STATUS{Qcache_hits} / $STATUS{Uptime};
+
+ if (defined $last_time and $last_time != $now_time)
+ {
+ my $q_delta = $STATUS{Qcache_hits} - $OLD_STATUS{Qcache_hits};
+ $now_query_cache_hits_per_sec = sprintf "%.2f", $q_delta / $t_delta;
+ }
+ }
+
+ $last_time = $now_time;
+
+ ## Server Uptime in meaningful terms...
+
+ my $time = $STATUS{Uptime};
+ my ($d,$h,$m,$s) = (0, 0, 0, 0);
+
+ $d += int($time / (60*60*24)); $time -= $d * (60*60*24);
+ $h += int($time / (60*60)); $time -= $h * (60*60);
+ $m += int($time / (60)); $time -= $m * (60);
+ $s += int($time);
+
+ my $uptime = sprintf("%d+%02d:%02d:%02d", $d, $h, $m, $s);
+
+ ## Queries per second...
+
+ my $avg_queries_per_sec = sprintf("%.2f", $STATUS{Questions} / $STATUS{Uptime});
+ my $num_queries = $STATUS{Questions};
+
+ my @t = localtime(time);
+
+ my $current_time = sprintf "[%02d:%02d:%02d]", $t[2], $t[1], $t[0];
+
+ my $host_width = 50;
+ my $up_width = $width - $host_width - 1;
+ Clear() unless $config{batchmode};
+ print RESET();
+
+ printf "%-.${host_width}s %${up_width}s\n",
+ "$server on $config{host} ($db_version)",
+ "up $uptime $current_time";
+ $lines_left--;
+
+
+ printf " Queries: %-6s qps: %4.0f Slow: %7s Se/In/Up/De(%%): %02.0f/%02.0f/%02.0f/%02.0f\n",
+ make_short( $STATUS{Questions} ), # q total
+ $STATUS{Questions} / $STATUS{Uptime}, # qps, average
+ make_short( $STATUS{Slow_queries} ), # slow
+
+ # hmm. a Qcache hit is really a select and should be counted.
+ 100 * ($STATUS{Com_select} + ($STATUS{Qcache_hits}||0) ) / $STATUS{Questions},
+ 100 * ($STATUS{Com_insert} + $STATUS{Com_replace} ) / $STATUS{Questions},
+ 100 * ($STATUS{Com_update} ) / $STATUS{Questions},
+ 100 * $STATUS{Com_delete} / $STATUS{Questions};
+
+ $lines_left--;
+
+ if ($t_delta)
+ {
+ my $q_diff = ( $STATUS{Questions} - $OLD_STATUS{Questions} );
+# print("q_diff: $STATUS{Questions} - $OLD_STATUS{Questions} / $t_delta = $q_diff\n");
+
+ printf(" Sorts: %5.0f qps now: %4.0f Slow qps: %3.1f Threads: %4.0f (%4.0f/%4.0f) %02.0f/%02.0f/%02.0f/%02.0f\n",
+ ( $STATUS{Sort_rows} - $OLD_STATUS{Sort_rows} ) / $t_delta,
+ ( $STATUS{Questions} - $OLD_STATUS{Questions} ) / $t_delta,
+ ( # slow now (qps)
+ ($STATUS{Slow_queries} ) ?
+ ( $STATUS{Slow_queries} - $OLD_STATUS{Slow_queries} ) / $t_delta :
+ 0
+ ),
+ $STATUS{Threads_connected},
+ $STATUS{Threads_running},
+ $STATUS{Threads_cached},
+
+ (100 * ($STATUS{Com_select} - $OLD_STATUS{Com_select} +
+ ($STATUS{Qcache_hits}||0) - ($OLD_STATUS{Qcache_hits}||0)
+ ) ) / ($q_diff ),
+ (100 * ($STATUS{Com_insert} - $OLD_STATUS{Com_insert} +
+ $STATUS{Com_replace} - $OLD_STATUS{Com_replace}
+ ) ) / ($q_diff ),
+ (100 * ($STATUS{Com_update} - $OLD_STATUS{Com_update}) ) / ($q_diff ),
+ (100 * ($STATUS{Com_delete} - $OLD_STATUS{Com_delete}) ) / ($q_diff ),
+ );
+ }
+ else
+ {
+ print "\n";
+ }
+ $lines_left--;
+
+ if ($have_query_cache and $STATUS{Com_select} and $query_cache_hits)
+ {
+ printf(" Cache Hits: %-5s Hits/s: %4.1f Hits now: %5.1f Ratio: ",
+ make_short($STATUS{Qcache_hits}), # cache hits
+ $STATUS{Qcache_hits} / $STATUS{Uptime}, # hits / sec
+ ($t_delta) ? ($STATUS{Qcache_hits} - $OLD_STATUS{Qcache_hits}) / $t_delta : 0, # Hits Now
+ );
+
+ my($Ratio) = 100 * ($STATUS{Qcache_hits}) / ($STATUS{Qcache_hits} + $STATUS{Com_select} );
+ if ($HAS_COLOR)
+ {
+ print YELLOW() if ($Ratio < 80.0);
+ print RED() if ($Ratio < 50.0);
+ print MAGENTA() if ($Ratio < 20.0);
+ }
+ printf("%4.1f%% ",$Ratio);
+ if ($HAS_COLOR)
+ {
+ print RESET();
+ }
+
+ print " Ratio now: ";
+ my($Ratio_now) = ($t_delta) ? # ratio now
+ 100 * ($STATUS{Qcache_hits} - $OLD_STATUS{Qcache_hits} ) /
+ ( ($STATUS{Com_select} + $STATUS{Qcache_hits} -
+ ($OLD_STATUS{Qcache_hits} + $OLD_STATUS{Com_select})
+ ) || 1) : 0;
+ if ($HAS_COLOR)
+ {
+ print GREEN() if ($Ratio_now >= 80.0);
+ print YELLOW() if ($Ratio_now < 80.0);
+ print RED() if ($Ratio_now < 50.0);
+ print MAGENTA() if ($Ratio_now < 20.0);
+ }
+ printf("%4.1f%% \n",$Ratio_now);
+ if ($HAS_COLOR)
+ {
+ print RESET();
+ }
+ }
+ $lines_left--;
+
+ if ($t_delta)
+ {
+ printf(" Handler: (R/W/U/D) %5d/%5d/%5d/%5d Tmp: R/W/U: %5d/%5d/%5d\n",
+ ($STATUS{Handler_read_first}+$STATUS{Handler_read_key}+
+ $STATUS{Handler_read_next}+$STATUS{Handler_read_prev}+
+ $STATUS{Handler_read_rnd}+$STATUS{Handler_read_rnd_next} -
+ $OLD_STATUS{Handler_read_first}-$OLD_STATUS{Handler_read_key}-
+ $OLD_STATUS{Handler_read_next}-$OLD_STATUS{Handler_read_prev}-
+ $OLD_STATUS{Handler_read_rnd}-
+ $OLD_STATUS{Handler_read_rnd_next})/$t_delta,
+ ($STATUS{Handler_write} - $OLD_STATUS{Handler_write}) /
+ $t_delta,
+ ($STATUS{Handler_update} - $OLD_STATUS{Handler_update}) /
+ $t_delta,
+ ($STATUS{Handler_delete} - $OLD_STATUS{Handler_delete}) /
+ $t_delta,
+ ($STATUS{Rows_tmp_read} - $OLD_STATUS{Rows_tmp_read}) /
+ $t_delta,
+ ($STATUS{Handler_tmp_write}
+ -$OLD_STATUS{Handler_tmp_write})/$t_delta,
+ ($STATUS{Handler_tmp_update} -
+ $OLD_STATUS{Handler_tmp_update})/$t_delta);
+ }
+ else
+ {
+ print "\n";
+ }
+
+ $lines_left--;
+
+ printf(" MyISAM Key Efficiency: %2.1f%% Bps in/out: %5s/%5s ",
+ $cache_hits_percent,
+ make_short($STATUS{Bytes_received} / $STATUS{Uptime} ),
+ make_short($STATUS{Bytes_sent} / $STATUS{Uptime}));
+ printf("Now in/out: %5s/%5s",
+ make_short(($STATUS{Bytes_received} - $OLD_STATUS{Bytes_received}) / $t_delta ),
+ make_short(($STATUS{Bytes_sent} - $OLD_STATUS{Bytes_sent}) / $t_delta ))
+ if ($t_delta);
+ print "\n";
+
+ $lines_left--;
+
+ my($data) = Hashes('SHOW SLAVE STATUS');
+ if (defined($data->{Master_Host}))
+ {
+ print " Replication ";
+ if ($HAS_COLOR) {
+ print GREEN();
+ print RED() if ($data->{Slave_IO_Running} ne "Yes") ;
+ }
+ print "IO:$data->{Slave_IO_Running} ";
+ RESET() if ($HAS_COLOR);
+
+ if ($HAS_COLOR) {
+ print GREEN();
+ print RED() if ($data->{Slave_SQL_Running} ne "Yes") ;
+ }
+ print "SQL:$data->{Slave_SQL_Running} ";
+ print RESET() if ($HAS_COLOR);
+
+ my $SlaveDelay = $data->{Seconds_Behind_Master};
+ if ($SlaveDelay)
+ {
+ if ($HAS_COLOR) {
+ print GREEN();
+ print YELLOW() if ($SlaveDelay > 10);
+ print MAGENTA() if ($SlaveDelay > 120);
+ }
+ print "Delay: $SlaveDelay sec.";
+ } else {
+ my $free = $width - 35;
+ my $Err = substr $data->{Last_Error},0 ,$free;
+ printf(" ERR: %-${free}s", $Err) if ( $Err ne "" );
+ }
+ print WHITE() if ($HAS_COLOR);
+ print "\n";
+ $lines_left--;
+ }
+ print "\n";
+ }
+
+ if (not $config{batchmode} and not $config{header})
+ {
+ Clear();
+ print RESET();
+ }
+
+ ##
+ ## Threads
+ ##
+
+ my @sz = (9, 8, 15, 9, 6, 5, 6, 8);
+ my $used = scalar(@sz) + Sum(@sz);
+ my $state= $width <= 80 ? 6 : int(min(6+($width-80)/3, 15));
+ my $free = $width - $used - ($state - 6);
+ my $format= "%9s %8s %15s %9s %6s %5s %6s %${state}s %-.${free}s\n";
+ my $format2;
+ if ($config{fullqueries})
+ {
+ $format2 = "%9d %8.8s %15.15s %9.9s %6d %5.1f %6.6s %${state}.${state}s %-${free}s\n";
+ } else {
+ $format2 = "%9d %8.8s %15.15s %9.9s %6d %5.1f %6.6s %${state}.${state}s %-${free}.${free}s\n";
+ }
+ print BOLD() if ($HAS_COLOR);
+
+ printf $format,
+ 'Id','User','Host/IP','DB','Time', '%', 'Cmd', 'State', 'Query';
+
+ print RESET() if ($HAS_COLOR);
+
+ ## Id User Host DB
+ printf $format,
+ '--','----','-------','--','----', '-', '---', '-----', '----------';
+
+ $lines_left -= 2;
+
+ my $proc_cmd = "show full processlist";
+
+ my @data = Hashes($proc_cmd);
+
+ foreach my $thread (@data)
+ {
+ last if not $lines_left;
+
+ ## Drop Domain Name, unless it looks like an IP address. If
+ ## it's an IP, we'll strip the port number because it's rarely
+ ## interesting.
+
+ my $is_ip = 0;
+
+ if ($thread->{Host} =~ /^(\d{1,3}\.){3}(\d{1,3})(:\d+)?$/)
+ {
+ $thread->{Host} =~ s/:.*$//;
+ $is_ip = 1;
+ }
+ else
+ {
+ $thread->{Host} =~ s/^([^.]+).*/$1/;
+ }
+
+ ## Otherwise, look up the IP (if resolve is set) and strip the
+ ## name
+ if ($is_ip and $config{resolve})
+ {
+ $thread->{Host} =~ s/:\d+$//;
+ my $host = gethostbyaddr(inet_aton($thread->{Host}), AF_INET);
+# $host =~ s/^([^.]+).*/$1/;
+ $thread->{Host} = $host;
+ }
+
+ ## Fix possible undefs
+
+ $thread->{db} ||= '';
+ $thread->{Info} ||= '';
+ $thread->{Time} ||= 0 ;
+ $thread->{Id} ||= 0 ;
+ $thread->{User} ||= '';
+ $thread->{Command} ||= '';
+ $thread->{Host} ||= '';
+ $thread->{State} ||= "";
+ $thread->{Progress} ||= 0;
+
+ ## alter double hyphen comments so they don't break
+ ## the query when newlines are removed - http://freshmeat.net/users/jerjones
+ $thread->{Info} =~ s~\s--(.*)$~ /* $1 */ ~mg;
+
+ ## Normalize spaces -- mostly disabled for now. This can
+ ## break EXPLAIN if you try to explain a mangled query. It
+ ## may be re-enabled later as an option.
+
+ ## leading space removal
+ $thread->{Info} =~ s/^\s*//;
+
+ if (1)
+ {
+ ## remove newlines and carriage returns
+ $thread->{Info} =~ s/[\n\r]//g;
+
+ ## collpase whitespace
+ $thread->{Info} =~ s/\s+/ /g;
+ }
+
+ ## stow it in the cache
+
+ $qcache{$thread->{Id}} = $thread->{Info};
+ $dbcache{$thread->{Id}} = $thread->{db};
+ $ucache{$thread->{Id}} = $thread->{User};
+
+ }
+
+ ## Sort by idle time (closest thing to CPU usage I can think of).
+
+ my @sorted;
+
+ if (not $config{sort})
+ {
+ @sorted = sort { $a->{Time} <=> $b->{Time} } @data
+ }
+ else
+ {
+ @sorted = sort { $b->{Time} <=> $a->{Time} } @data
+ }
+
+ foreach my $thread (@sorted)
+ {
+ # Check to see if we can skip out. We skip out if we know the
+ # given line doesn't match.
+
+ next if (($thread->{Command} eq "Sleep")
+ and
+ (not $config{idle}));
+
+ next if (($thread->{Command} eq "Binlog Dump")
+ and
+ (not $config{idle}));
+
+ next if (($thread->{Command} eq "Daemon")
+ and
+ (not $config{idle}));
+
+ next if ($thread->{User} !~ $config{filter_user});
+ next if ($thread->{db} !~ $config{filter_db});
+ next if ($thread->{Host} !~ $config{filter_host});
+ next if ($thread->{State} !~ $config{filter_state});
+
+ # Otherwise, print.
+
+ my $smInfo;
+
+ if ($thread->{Info})
+ {
+ if ($config{fullqueries})
+ {
+ $smInfo = $thread->{Info};
+ } else {
+ $smInfo = substr $thread->{Info}, 0, $free;
+ }
+ }
+# if ($thread->{State})
+# {
+# $smInfo = substr $thread->{State}, 0, $free;
+# }
+ else
+ {
+ $smInfo = "";
+ }
+
+ if ($HAS_COLOR)
+ {
+ print YELLOW() if $thread->{Command} eq 'Query';
+ print WHITE() if $thread->{Command} eq 'Sleep';
+ print GREEN() if $thread->{Command} eq 'Connect';
+ print BOLD() if $thread->{Time} > $config{slow};
+ print MAGENTA() if $thread->{Time} > $config{long};
+ }
+
+ printf $format2,
+ $thread->{Id}, $thread->{User}, $thread->{Host}, $thread->{db},
+ $thread->{Time}, $thread->{Progress}, $thread->{Command}, $thread->{State}, $smInfo;
+
+ print RESET() if $HAS_COLOR;
+
+ $lines_left--;
+
+ last if $lines_left == 0;
+
+ }
+
+}
+
+###########################################################################
+
+my $questions;
+
+sub GetQPS()
+{
+ my($data) = Hashes('SHOW STATUS LIKE "Questions"');
+ my $num = $data->{Value};
+
+ if (not defined $questions) ## first time?
+ {
+ $questions = $num;
+ return;
+ }
+
+ my $qps = $num - $questions;
+ $questions = $num;
+ print "$qps\n";
+}
+
+###########################################################################
+
+sub GetQcacheSummary()
+{
+}
+
+###########################################################################
+
+sub GetInnoDBStatus()
+{
+ if (not $config{pager})
+ {
+ if (not $config{pager} = FindProg('less'))
+ {
+ $config{pager} = FindProg('more');
+ }
+ }
+
+ my @data = Hashes("SHOW INNODB STATUS");
+
+ open P, "|$config{pager}" or die "$!";
+ print keys %{$data[0]};
+ print $data[0]->{Status},"\n";
+ close P;
+}
+
+###########################################################################
+
+my %prev_data;
+
+sub GetCmdSummary()
+{
+ my ($width, $height, $wpx, $hpx, $lines_left);
+
+ if (not $config{batchmode})
+ {
+ ($width, $height, $wpx, $hpx) = GetTerminalSize();
+
+ $lines_left = $height - 2;
+ }
+ else
+ {
+ $height = 999_999; ## I hope you don't have more than that!
+ $lines_left = 999_999;
+ $width = 80;
+ }
+
+ # Variable_name and Value pairs come back...
+ my @data = Hashes("SHOW STATUS LIKE 'Com_%'");
+ my %cmd_data;
+ my %cmd_delta;
+ my %cmd_pct;
+ my %cmd_delta_pct;
+ my $total;
+ my $delta_total;
+
+ for my $item (@data)
+ {
+ next unless $item->{Value};
+ $item->{Variable_name} =~ s/^Com_//;
+ $item->{Variable_name} =~ s/_/ /g;
+ $cmd_data{$item->{Variable_name}} = $item->{Value};
+ $total += $item->{Value};
+ }
+
+ ## Populate other stats
+
+ for my $item (keys %cmd_data)
+ {
+ $cmd_delta{$item} = $cmd_data{$item} -
+ ($prev_data{$item} || $cmd_data{$item} - 1);
+
+ $delta_total += $cmd_delta{$item};
+
+ $cmd_pct{$item} = int(($cmd_data{$item} / $total) * 100);
+ }
+
+ for my $item (keys %cmd_data)
+ {
+ $cmd_delta_pct{$item} = int(($cmd_delta{$item} / $delta_total) * 100);
+ }
+
+
+ ## Display
+
+ Clear() unless $config{batchmode};
+ print RESET();
+ printf "%18s %10s %4s | %5s %4s\n", 'Command', 'Total', 'Pct', 'Last', 'Pct';
+ printf "%18s %10s %4s | %5s %4s\n", '-------', '-----', '---', '----', '---';
+ $lines_left -= 2;
+
+ for my $item (sort { $cmd_data{$b} <=> $cmd_data{$a} } keys %cmd_data)
+ {
+ printf "%18s %10d %4s | %5d %4s\n",
+ $item,
+ $cmd_data{$item},
+ $cmd_pct{$item} . "%",
+ $cmd_delta{$item},
+ $cmd_delta_pct{$item} . "%";
+
+ last if not $lines_left;
+ $lines_left -= 1;
+ }
+
+ %prev_data = %cmd_data;
+}
+
+###########################################################################
+
+sub GetShowVariables()
+{
+ if (not $config{pager})
+ {
+ if (not $config{pager} = FindProg('less'))
+ {
+ $config{pager} = FindProg('more');
+ }
+ }
+
+ my @rows = Hashes("SHOW VARIABLES");
+
+ open P, "|$config{pager}" or die "$!";
+
+ for my $row (@rows)
+ {
+ my $name = $row->{Variable_name};
+ my $value = $row->{Value};
+ printf P "%32s: %s\n", $name, $value;
+ }
+
+ close P;
+}
+
+###########################################################################
+
+sub GetShowStatus()
+{
+ Clear() unless $config{batchmode};
+ my @rows = Hashes("SHOW STATUS");
+
+ printf "%32s %10s %10s\n", 'Counter', 'Total', 'Change';
+ printf "%32s %10s %10s\n", '-------', '-----', '------';
+
+ for my $row (@rows)
+ {
+ my $name = $row->{Variable_name};
+ my $value = $row->{Value};
+ my $old = $statcache{$name};
+ my $delta = 0;
+
+ next if $name =~ m/^Com_/; ## skip Com_ stats
+ next if $value =~ m/^[^0-9]*$/; ## skip non-numeric
+
+ ## TODO: if Qcache is off, we should skip Qcache_ values
+
+ if ($HAS_COLOR and defined $old and $old =~ /^\d/)
+ {
+ if ($value > $old)
+ {
+ print YELLOW();
+ $delta = $value - $old;
+ }
+ elsif ($value < $old)
+ {
+ print RED();
+ $delta = $value - $old;
+ }
+
+ if (not $config{idle} and $value == $old)
+ {
+ # filter unchanging stats, maybe
+ print RESET();
+ next;
+ }
+ }
+
+ if ($delta != 0) {
+ printf "%32s: %10s %10s\n", $name, $value, $delta;
+ }
+ print RESET() if $HAS_COLOR;
+
+ $statcache{$name} = $value;
+ }
+
+}
+
+###########################################################################
+
+sub FullQueryInfo($)
+{
+ my $id = shift;
+
+ if (not exists $qcache{$id} or not defined $qcache{$id})
+ {
+ print "*** Invalid id. ***\n";
+ return;
+ }
+
+ my $sql = $qcache{$id};
+ print $CLEAR;
+ print "Thread $id was executing following query:\n\n";
+ print YELLOW(), $sql,"\n\n", RESET();
+}
+
+###########################################################################
+
+sub Explain($)
+{
+ my $id = shift;
+
+ if (not exists $qcache{$id} or not defined $qcache{$id})
+ {
+ print "*** Invalid id. ***\n";
+ return;
+ }
+
+ my $sql = $qcache{$id};
+ my $db = $dbcache{$id};
+
+ Execute("USE $db");
+ my @info = Hashes("EXPLAIN $sql");
+ print $CLEAR;
+ print "EXPLAIN $sql:\n\n";
+ PrintTable(@info);
+}
+
+###########################################################################
+
+sub PrintTable(@)
+{
+ my $cnt = 1;
+ my @cols = qw(table type possible_keys key key_len ref rows Extra);
+
+ for my $row (@_)
+ {
+ print "*** row $cnt ***\n";
+ for my $key (@cols)
+ {
+ my $val = $row->{$key} || 'NULL';
+ printf "%15s: %s\n", $key, $val;
+ }
+ $cnt++;
+ }
+}
+
+###########################################################################
+
+sub StringOrRegex($)
+{
+ my $input = shift;
+ chomp $input;
+ if (defined $input)
+ {
+ # regex, strip /.../ and use via qr//
+ if ($input =~ m{^/} and $input =~ m{/$})
+ {
+ $input =~ s{^/}{} if $config{filter_user};
+ $input =~ s{/$}{} if $config{filter_user};
+ $input = qr/$input/;
+ }
+
+
+ # reset to match anything
+ elsif ($input eq '')
+ {
+ $input = qr/.*/;
+ }
+
+ # string, build a simple regex
+ else
+ {
+ $input = '^' . $input . '$';
+ $input = qr/$input/;
+ }
+ }
+
+ # reset to match anything
+ else
+ {
+ $input = qr/.*/;
+ }
+ return $input;
+}
+
+###########################################################################
+
+sub cmd_l
+{
+ ReadMode($RM_RESET);
+
+ print RED(), "Seconds for long queries: ", RESET();
+ my $secs = ReadLine(0);
+
+ if ($secs =~ /^\s*(\d+)/)
+ {
+ $config{long} = $1;
+ if ($config{long} < 1)
+ {
+ $config{long} = 1;
+ }
+ }
+ ReadMode($RM_NOBLKRD);
+}
+
+sub cmd_s
+{
+ ReadMode($RM_RESET);
+
+ print RED(), "Seconds of Delay: ", RESET();
+ my $secs = ReadLine(0);
+
+ if ($secs =~ /^\s*(\d+)/)
+ {
+ $config{delay} = $1;
+ if ($config{delay} < 1)
+ {
+ $config{delay} = 1;
+ }
+ }
+ ReadMode($RM_NOBLKRD);
+}
+
+sub cmd_S
+{
+ ReadMode($RM_RESET);
+
+ print RED(), "Seconds for Slow queries: ", RESET();
+ my $secs = ReadLine(0);
+
+ if ($secs =~ /^\s*(\d+)/)
+ {
+ $config{slow} = $1;
+ if ($config{slow} < 1)
+ {
+ $config{slow} = 1;
+ }
+ }
+ ReadMode($RM_NOBLKRD);
+}
+
+sub cmd_q
+{
+ ReadMode($RM_RESET);
+ print "\n";
+ exit;
+}
+
+sub trim($)
+{
+ my $string = shift;
+ $string =~ s/^\s+//;
+ $string =~ s/\s+$//;
+ return $string;
+}
+
+###########################################################################
+
+sub PrintHelp()
+{
+ my $help = qq[
+Help for mytop version $main::VERSION by Mark Grennan <${YELLOW}Mark\@Grennan.com${RESET}>
+Origional work by Jeremy D. Zawodny <${YELLOW}Jeremy\@Zawodny.com${RESET}>
+
+ ? - display this screen
+ # - toggle short/long numbers (not yet implemented)
+ ! - force past replication error
+ c - command summary view (based on Com_* counters)
+ C - turn color on and off
+ d - show only a specific database
+ e - explain the query that a thread is running
+ E - display current replication error
+ f - show full query info for a given thread
+ F - unFilter the dispaly
+ h - show only a specifc host's connections
+ H - toggle the mytop header
+ i - toggle the display of idle (sleeping) threads
+ I - show innodb status
+ k - kill a thread
+ p - pause the display
+ l - change long running queries hightlighing
+ m - switch [mode] to qps (queries/sec) scrolling view
+ M - switch [mode] to status
+ o - reverse the sort order (toggle)
+ q - quit
+ r - reset the status counters (via FLUSH STATUS on your server)
+ R - change reverse IP lookup
+ s - change the delay between screen updates
+ S - change slow quiery hightlighting
+ t - switch to thread view (default)
+ u - show only a specific user
+ V - show variablesi
+ : - enter a command (not yet implemented)
+ L - show full queries (do not strip to terminal width)
+
+Base version from ${GREEN}http://www.mysqlfanboy.com/mytop${RESET}
+This version comes as part of the ${GREEN}MariaDB${RESET} distribution.
+];
+
+ print $help;
+}
+
+sub Sum(@)
+{
+ my $sum;
+ while (my $val = shift @_) { $sum += $val; }
+ return $sum;
+}
+
+## A useful routine from perlfaq
+
+sub commify($)
+{
+ local $_ = shift;
+ return 0 unless defined $_;
+ 1 while s/^([-+]?\d+)(\d{3})/$1,$2/;
+ return $_;
+}
+
+## Compact numeric representation (10,000 -> 10.0k)
+
+sub make_short($)
+{
+ my $number = shift;
+ return commify($number) if $config{long_nums};
+ my $n = 0;
+ while ($number > 1_025) { $number /= 1024; $n++; };
+ return sprintf "%.1f%s", $number, ('','k','M','G', 'T')[$n];
+}
+
+
+
+## Run a query and return the records has an array of hashes.
+
+sub Hashes($)
+{
+ my $sql = shift;
+ my @records;
+
+ if (my $sth = Execute($sql))
+ {
+ while (my $ref = $sth->fetchrow_hashref)
+ {
+ print "record\n" if $debug;
+ push @records, $ref;
+ }
+ }
+ return @records;
+}
+
+## Execute an SQL query and return the statement handle.
+
+sub Execute($)
+{
+ my $sql = shift;
+ my $sth = $dbh->prepare($sql);
+
+ if (not $sth) { ReadMode($RM_RESET); die $DBI::errstr; }
+
+ my $ReturnCode = $sth->execute;
+
+ if (not $ReturnCode)
+ {
+ if ($debug)
+ {
+ print "query failed\n";
+ sleep 10;
+ }
+ return undef;
+ }
+
+ return $sth;
+}
+
+sub FindProg($)
+{
+ my $prog = shift;
+ my $found = undef;
+ my @search_dirs = ("/bin", "/usr/bin", "/usr/sbin",
+ "/usr/local/bin", "/usr/local/sbin");
+
+ for (@search_dirs)
+ {
+ my $loc = "$_/$prog";
+ if (-e $loc)
+ {
+ $found = $loc;
+ last;
+ }
+ }
+ return $found;
+}
+
+####
+#### my_which is used, because we can't assume that every system has the
+#### which -command. my_which can take only one argument at a time.
+#### Return values: requested system command with the first found path,
+#### or undefined, if not found.
+####
+
+sub my_which
+{
+ my ($command) = @_;
+ my (@paths, $path);
+
+ return $command if (-f $command && -x $command);
+
+ # Check first if this is a source distribution, then if this binary
+ # distribution and last in the path
+
+ push @paths, "./extra";
+ push @paths, $path_for_script;
+ push @paths, split(':', $ENV{'PATH'});
+
+ foreach $path (@paths)
+ {
+ $path .= "/$command";
+ return $path if (-f $path && -x $path);
+ }
+ return undef();
+}
+
+=pod
+
+=head1 SYNOPSIS
+
+B<mytop> [options]
+
+=head1 AVAILABILITY
+
+Base version from B<http://www.mysqlfanboy.com/mytop>.
+
+This version comes as part of the B<MariaDB> distribution. See B<http://mariadb.org/>.
+
+And older (the original) version B<mytop> is available from
+http://jeremy.zawodny.com/mysql/mytop/ it B<might> also be on CPAN as
+well.
+
+=head1 REQUIREMENTS
+
+In order for B<mytop> to function properly, you must have the
+following:
+
+ * Perl 5.005 or newer
+ * Getopt::Long
+ * DBI and DBD::mysql
+ * Term::ReadKey from CPAN
+
+Most systems are likely to have all of those installed--except for
+Term::ReadKey. You will need to pick that up from the CPAN. You can
+pick up Term::ReadKey here:
+
+ http://search.cpan.org/search?dist=TermReadKey
+
+And you obviously need access to a MySQL server (version 3.22.x or
+3.23.x) with the necessary security to run the I<SHOW PROCESSLIST> and
+I<SHOW STATUS> commands.
+
+If you are a Windows user, using ActiveState's Perl, you can use PPM
+(the Perl Package Manager) to install the MySQL and Term::ReadKey
+modules.
+
+=head2 Optional Color Support
+
+In additon, if you want a color B<mytop> (recommended), install
+Term::ANSIColor from the CPAN:
+
+ http://search.cpan.org/search?dist=ANSIColor
+
+Once you do, B<mytop> will automatically use it. However, color is not
+yet working on Windows. Patches welcome. :-)
+
+=head2 Optional Hi-Res Timing
+
+If you want B<mytop> to provide more accurate real-time
+queries-per-second statistics, install the Time::HiRes module from
+CPAN. B<mytop> will automatically notice that you have it and use it
+rather than the standard timing mechanism.
+
+=head2 Platforms
+
+B<mytop> is known to work on:
+
+ * Linux (2.2.x, 2.4.x)
+ * FreeBSD (2.2, 3.x, 4.x)
+ * Mac OS X
+ * BSDI 4.x
+ * Solaris 2.x
+ * Windows NT 4.x (ActivePerl)
+
+If you find that it works on another platform, please let me
+know. Given that it is all Perl code, I expect it to be rather
+portable to Unix and Unix-like systems. Heck, it I<might> even work on
+Win32 systems.
+
+=head1 DESCRIPTION
+
+Help is always welcome in improving this software. Feel free to
+contact the author (see L<"AUTHOR"> below) with bug reports, fixes,
+suggestions, and comments. Additionally L<"BUGS"> will provide a list
+of things this software is not able to do yet.
+
+Having said that, here are the details on how it works and what you can
+do with it.
+
+=head2 The Basics
+
+B<mytop> was inspired by the system monitoring tool B<top>. I
+routinely use B<top> on Linux, FreeBSD, and Solaris. You are likely to
+notice features from each of them here.
+
+B<mytop> will connect to a MySQL server and periodically run the
+I<SHOW PROCESSLIST> and I<SHOW STATUS> commands and attempt to
+summarize the information from them in a useful format.
+
+=head2 The Display
+
+The B<mytop> display screen is really broken into two parts. The top 4
+lines (header) contain summary information about your MySQL
+server. For example, you might see something like:
+
+MySQL on localhost (4.0.13-log) up 1+11:13:00 [23:29:11]
+ Queries: 19.3M qps: 160 Slow: 1.0 Se/In/Up/De(%): 00/80/03/17
+ qps now: 219 Slow qps: 0.0 Threads: 1 ( 1/ 16) 00/74/00/25
+ Key Efficiency: 99.3% Bps in/out: 30.5k/162.8 Now in/out: 32.7k/ 3.3k
+
+The first line identifies the hostname of the server (localhost) and
+the version of MySQL it is running. The right had side shows the
+uptime of the MySQL server process in days+hours:minutes:seconds
+format (much like FreeBSD's top) as well as the current time.
+
+The second line displays the total number of queries the server has
+processed, the average number of queries per second, the number of
+slow queries, and the percentage of Select, Insert, Update, and Delete
+queries.
+
+The third real-time values. First is the number of queries per second,
+then the number of slow queries, followed by query precentages (like
+on the previous line).
+
+And the fourth line displays key buffer efficiency (how often keys are
+read from the buffer rather than disk) and the number of bytes that
+MySQL has sent and received, both over all and in the last cycle.
+
+You can toggle the header by hitting B<h> when running B<mytop>.
+
+The second part of the display lists as many threads as can fit on
+screen. By default they are sorted according to their idle time (least
+idle first). The display looks like:
+
+ Id User Host Dbase Time Cmd Query or State
+ -- ---- ---- ----- ---- --- --------------
+ 61 jzawodn localhost music 0 Query show processlist
+
+As you can see, the thread id, username, host from which the user is
+connecting, database to which the user is connected, number of seconds
+of idle time, the command the thread is executing, and the query info
+are all displayed.
+
+Often times the query info is what you are really interested in, so it
+is good to run B<mytop> in an xterm that is wider than the normal 80
+columns if possible.
+
+The thread display color-codes the threads if you have installed color
+support. The current color scheme only works well in a window with a
+dark (like black) background. The colors are selected according to the
+C<Command> column of the display:
+
+ Query - Yellow
+ Sleep - White
+ Connect - Green
+ Slow - Bright
+ Long - Magenta
+
+Those are purely arbitrary and will be customizable in a future
+release. If they annoy you just start B<mytop> with the B<--nocolor>
+flag or adjust your config file appropriately.
+
+=head2 Arguments
+
+B<mytop> handles long and short command-line arguments. Not all
+options have both long and short formats, however. The long arguments
+have two dashes `--'. Short arguments only have one '-'.
+
+=over
+
+=item B<-u> or B<-user> username
+
+Username to use when logging in to the MySQL server. Default: ``root''.
+
+=item B<-p> or B<-pass> or B<-password> password
+
+Password to use when logging in to the MySQL server. Default: none.
+
+=item B<-h> or B<--host> hostname[:port]
+
+Hostname of the MySQL server. The hostname may be followed by an
+option port number. Note that the port is specified separate from the
+host when using a config file. Default: ``localhost''.
+
+=item B<--port> or B<-P> port
+
+If you're running MySQL on a non-standard port, use this to specify
+the port number. Default: 3306.
+
+=item B<-s> or B<--delay> seconds
+
+How long between display refreshes. Default: 5
+
+=item B<-d> or B<--db> or B<--database> database
+
+Use if you'd like B<mytop> to connect to a specific database by
+default. Default: ``test''.
+
+=item B<-b> or B<--batch> or B<--batchmode>
+
+In batch mode, mytop runs only once, does not clear the screen, and
+places no limit on the number of lines it will print. This is suitable
+for running periodically (perhaps from cron) to capture the
+information into a file for later viewing. You might use batch mode in
+a CGI script to occasionally display your MySQL server status on the
+web.
+
+Default: unset.
+
+=item B<-S> or B<--socket> /path/to/socket
+
+If you're running B<mytop> on the same host as MySQL, you may wish to
+have it use the MySQL socket directly rather than a standard TCP/IP
+connection. If you do,just specify one.
+
+Note that specifying a socket will make B<mytop> ignore any host
+and/or port that you might have specified. If the socket does not
+exist (or the file specified is not a socket), this option will be
+ignored and B<mytop> will use the hostname and port number instead.
+
+Default: none.
+
+=item B<--header> or B<--noheader>
+
+Sepcify if you want the header to display or not. You can toggle this
+with the B<h> key while B<mytop> is running.
+
+Default: header.
+
+=item B<--color> or B<--nocolor>
+
+Specify if you want a color display. This has no effect if you don't
+have color support available.
+
+Default: If you have color support, B<mytop> will try color unless you
+tell it not to.
+
+=item B<-i> or B<--idle> or B<--noi> or B<--noidle>
+
+Specify if you want idle (sleeping) threads to appear in the list. If
+sleeping threads are omitted, the default sorting order is reversed so
+that the longest running queries appear at the top of the list.
+
+Default: idle.
+
+=item B<--prompt> or B<--noprompt>
+
+Specify if you want to be prompted to type in your database password.
+This provides a little bit more security since it not only prevents
+the password from viewable in a process list, but also doesn't require
+the password to be stored in plain text in your ~/.mytop config file.
+You will B<only> be prompted if a password has not been specified in
+your config file or through another command line option.
+
+Default: noprompt.
+
+=item B<--resolve>
+
+If you have skip-resolve set on MySQL (to keep it from doing a reverse
+DNS lookup on each inbound connection), mytop can replace IP addresses
+with hostnames but toggling this option.
+
+Default: noresolve
+
+=back
+
+Command-line arguments will always take precedence over config file
+options. That happens because the config file is read I<BEFORE> the
+command-line arguments are applied.
+
+=head2 Config File
+
+Instead of always using bulky command-line parameters, you can also
+use a config files for the default value of your options.
+
+mytop will first read the [client] and [mytop] sections from your
+my.cnf files. After that it will read the (C<~/.mytop>) file from your
+home directory (if present). These are read I<before> any of your
+command-line arguments are processed, so your command-line arguments
+will override directives in the config file.
+
+
+Here is a sample config file C<~/.mytop> which implements the defaults
+described above.
+
+ user=root
+ pass=
+ host=localhost
+ db=test
+ delay=5
+ port=3306
+ slow=10
+ socket=
+ batchmode=0
+ header=1
+ color=1
+ idle=1
+ long=120
+
+Using a config file will help to ensure that your database password
+isn't visible to users on the command-line. Just make sure that the
+permissions on C<~/.mytop> are such that others cannot read it (unless
+you want them to, of course).
+
+You may have white space on either side of the C<=> in lines of the
+config file.
+
+=head2 Shortcut Keys
+
+The following keys perform various actions while B<mytop> is
+running. Those which have not been implemented are listed as
+such. They are included to give the user idea of what is coming.
+
+=over
+
+=item B<?>
+
+Display help.
+
+=item B<c>
+
+Show "command counters" based on the Com_* values in SHOW STATUS.
+This is a new feature. Feedback welcome.
+
+=item B<C>
+
+Turn display color on and off. Default is on.
+
+=item B<d>
+
+Show only threads connected to a particular database.
+
+=item B<f>
+
+Given a thread id, display the entire query that thread was (and still
+may be) running.
+
+=item B<F>
+
+Disable all filtering (host, user, and db).
+
+=item B<h>
+
+Only show queries from a particular host.
+
+=item B<H>
+
+Toggle the header display. You can also specify either C<header=0> or
+C<header=1> in your config file to set the default behavior.
+
+=item B<i>
+
+Toggle the display of idle (sleeping) threads. If sleeping threads are
+filtered, the default sorting order is reversed so that the longest
+running queries appear at the top of the list.
+
+=item B<I>
+
+Switch to InnoDB Status mode. The output of "SHOW INNODB STATUS" will
+be displayed every cycle. In a future version, this may actually
+summarize that data rather than producing raw output.
+
+=item B<k>
+
+Kill a thread.
+
+=item B<m>
+
+Toggle modes. Currently this switches from `top' mode to `qps'
+(Queries Per Second Mode). In this mode, mytop will write out one
+integer per second. The number written reflects the number of queries
+executed by the server in the previous one second interval.
+
+More modes may be added in the future.
+
+=item B<o>
+
+Reverse the default sort order.
+
+=item B<p>
+
+Pause display.
+
+=item B<q>
+
+Quit B<mytop>
+
+=item B<r>
+
+Reset the server's status counters via a I<FLUSH STATUS> command.
+
+=item B<R>
+
+Togle IP reverse lookup. Default is on.
+
+=item B<s>
+
+Change the sleep time (number of seconds between display refreshes).
+
+=item B<S>
+
+Set the number of seconds a query will need to run before it is
+considered old and will be highlighted.
+
+=item B<u>
+
+Show only threads owned by a giver user.
+
+=back
+
+The B<s> key has a command-line counterpart: B<-s>.
+
+The B<h> key has two command-line counterparts: B<-header> and
+B<-noheader>.
+
+=head1 BUGS
+
+This is more of a BUGS + WishList.
+
+Some performance information is not available when talking to a
+version 3.22.x MySQL server. Additional information (about threads
+mostly) was added to the output of I<SHOW STATUS> in MySQL 3.23.x and
+B<mytop> makes use of it. If the information is not available, you
+will simply see zeros where the real numbers should be.
+
+Simply running this program will increase your overall counters (such
+as the number of queries run). But you may or may not view that as a
+bug.
+
+B<mytop> consumes too much CPU time when running (verified on older
+versions of Linux and FreeBSD). It's likely a problem related to
+Term::ReadKey. I haven't had time to investigate yet, so B<mytop> now
+automatically lowers its priority when you run it. You may also think
+about running B<mytop> on another workstation instead of your database
+server. However, C<mytop> on Solaris does B<not> have this problem.
+Newer versions of Linux and FreeBSD seem to have fixed this.
+
+You can't specify the maximum number of threads to list. If you have
+many threads and a tall xterm, B<mytop> will always try to display as
+many as it can fit.
+
+The size of most of the columns in the display has a small maximum
+width. If you have fairly long database/user/host names the display
+may appear odd. I have no good idea as to how best to deal with that
+yet. Suggestions are welcome.
+
+It'd be nice if you could just add B<mytop> configuration directives
+in your C<my.cnf> file instead of having a separate config file.
+
+You should be able to specify the columns you'd like to see in the
+display and the order in which they appear. If you only have one
+username that connects to your database, it's probably not worth
+having the User column appear, for example.
+
+=head1 AUTHOR
+
+mytop was developed and is maintained by Jeremy D. Zawodny
+(Jeremy@Zawodny.com).
+
+(Mark Grennan) After weeks and months of trying to get Jeremy's
+attention I desided to release my own update to mytop. I use it
+every day as a part of my job. Thanks Jeremy for creating mytop.
+I hope you find my updates as helpful as I have. I can be
+reached at (Mark@Grennan.com).
+
+=head1 DISCLAIMER
+
+While I use this software in my job at Yahoo!, I am solely responsible
+for it. Yahoo! does not necessarily support this software in any
+way. It is merely a personal idea which happened to be very useful in
+my job.
+
+=head1 RECRUITING
+
+If you hack Perl and grok MySQL, come work at Yahoo! Contact me for
+details. Or just send me your resume. Er, unless we just had layoffs,
+in which case we're not hiring. :-(
+
+=head1 SEE ALSO
+
+Please check the MySQL manual if you're not sure where some of the
+output of B<mytop> is coming from.
+
+=head1 COPYRIGHT
+
+Copyright (C) 2000-2010, Jeremy D. Zawodny.
+Copyright (C) 2010, Mark T. Grennan.
+
+=head1 CREDITS
+
+Fix a bug. Add a feature. See your name here!
+
+Many thanks go to these fine folks:
+
+=over
+
+=Item Jean Weisbuch
+
+Added --fullqueries and reading of .my.cnf
+
+=item Sami Ahlroos (sami@avis-net.de)
+
+Suggested the idle/noidle stuff.
+
+=item Jan Willamowius (jan@janhh.shnet.org)
+
+Mirnor bug report. Documentation fixes.
+
+=item Alex Osipov (alex@acky.net)
+
+Long command-line options, Unix socket support.
+
+=item Stephane Enten (tuf@grolier.fr)
+
+Suggested batch mode.
+
+=item Richard Ellerbrock (richarde@eskom.co.za)
+
+Bug reports and usability suggestions.
+
+=item William R. Mattil (wrm@newton.irngtx.tel.gte.com)
+
+Bug report about empty passwords not working.
+
+=item Benjamin Pflugmann (philemon@spin.de)
+
+Suggested -P command-line flag as well as other changes.
+
+=item Justin Mecham <justin@aspect.net>
+
+Suggested setting $0 to `mytop'.
+
+=item Thorsten Kunz <thorsten.kunz@de.tiscali.com>
+
+Provided a fix for cases when we try remove the domain name from the
+display even if it is actually an IP address.
+
+=item Sasha Pachev <sasha@mysql.com>
+
+Provided the idea of real-time queries per second in the main display.
+
+=item Paul DuBois <paul@snake.net>
+
+Pointed out some option-handling bugs.
+
+=item Mike Wexler <mwexler@tias.com>
+
+Suggested that we don't mangle (normalize) whitespace in query info by
+default.
+
+=item Mark Zweifel <markez@yahoo-inc.com>
+
+Make the --idle command-line argument negatable.
+
+=item Axel Schwenke <schwenke@jobpilot.de>
+
+Noticed the inccorect formula for query cache hit percentages in
+version 1.2.
+
+=item Steven Roussey <sroussey@network54.com>
+
+Supplied a patch to help filter binary junk in queries so that
+terminals don't freak out.
+
+=item jon r. luini <falcon@chime.com>
+
+Supplied a patch that formed the basis for C<-prompt> support. Sean
+Leach <sleach@wiggum.com> submitted a similar patch.
+
+=item Yogish Baliga <baliga@yahoo-inc.com>
+
+Supplied a patch that formed the basis for C<-resolve> support.
+
+=item Per Andreas Buer <perbu@linpro.no>
+
+Supplied an excellent patch to tidy up the top display. This includes
+showing most values in short form, such as 10k rather than 10000.
+
+=item Michael "Monty" Widenius <monty@askmonty.org>
+
+Fixed a couple of minor bugs that gave warnings on startup.
+Added support for MariaDB (show MariaDB at top and % done).
+Cut long server version names to display width.
+Made 'State' length dynamic.
+
+=back
+
+See the Changes file on the B<mytop> distribution page for more
+details on what has changed.
+
+=head1 LICENSE
+
+B<mytop> is licensed under the GNU General Public License version
+2. For the full license information, please visit
+http://www.gnu.org/copyleft/gpl.html
+
+=cut
+
+__END__
diff --git a/sql-bench/Makefile.am b/sql-bench/Makefile.am
index 93f9a61d9d4..bb4c30b65fe 100644
--- a/sql-bench/Makefile.am
+++ b/sql-bench/Makefile.am
@@ -22,6 +22,7 @@ benchdir = $(benchdir_root)/sql-bench
bench_SCRIPTS = test-ATIS test-connect test-create test-insert \
test-big-tables test-select test-wisconsin \
test-alter-table test-transactions \
+ test-table-elimination \
graph-compare-results \
bench-init.pl compare-results run-all-tests \
server-cfg crash-me copy-db innotest1 innotest1a \
@@ -31,6 +32,7 @@ CLEANFILES = $(bench_SCRIPTS)
EXTRA_SCRIPTS = test-ATIS.sh test-connect.sh test-create.sh \
test-insert.sh test-big-tables.sh test-select.sh \
test-alter-table.sh test-wisconsin.sh \
+ test-table-elimination.sh \
test-transactions.sh \
bench-init.pl.sh compare-results.sh server-cfg.sh \
run-all-tests.sh crash-me.sh copy-db.sh \
diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh
index 473a66933cc..4391a2afb40 100644
--- a/sql-bench/crash-me.sh
+++ b/sql-bench/crash-me.sh
@@ -40,7 +40,7 @@
# as such, and clarify ones such as "mediumint" with comments such as
# "3-byte int" or "same as xxx".
-$version="1.61";
+$version="1.62";
use Cwd;
use DBI;
@@ -620,6 +620,8 @@ check_reserved_words($dbh);
"numeric(9,2)","decimal(6,2)","dec(6,2)",
"bit", "bit(2)","bit varying(2)","float","float(8)","real",
"double precision", "date","time","timestamp",
+ "time(6)", "timestamp(6)",
+ "datetime", "datetime(6)",
"interval year", "interval year to month",
"interval month",
"interval day", "interval day to hour", "interval day to minute",
@@ -633,8 +635,7 @@ check_reserved_words($dbh);
"national char varying(20)","nchar varying(20)",
"national character varying(20)",
"timestamp with time zone");
-@odbc_types=("binary(1)","varbinary(1)","tinyint","bigint",
- "datetime");
+@odbc_types=("binary(1)","varbinary(1)","tinyint","bigint");
@extra_types=("blob","byte","long varbinary","image","text","text(10)",
"mediumtext",
"long varchar(1)", "varchar2(257)",
@@ -664,7 +665,7 @@ check_reserved_words($dbh);
foreach $types (@types)
{
print "\nSupported $types->[0] types\n";
- $tmp=@$types->[1];
+ $tmp= $types->[1];
foreach $use_type (@$tmp)
{
$type=$use_type;
@@ -747,10 +748,14 @@ if (($limits{'type_extra_float(2_arg)'} eq "yes" ||
$result="exact";
}
$prompt="Storage of float values";
- print "$prompt: $result\n";
save_config_data("storage_of_float", $result, $prompt);
}
+if (defined($limits{'storage_of_float'}))
+{
+ print "Storage of float values: $limits{'storage_of_float'}\n";
+}
+
try_and_report("Type for row id", "rowid",
["rowid",
"create table crash_q (a rowid)",
@@ -1062,7 +1067,7 @@ try_and_report("Automatic row id", "automatic_rowid",
foreach $types (@types)
{
print "\nSupported $types->[0] functions\n";
- $tmp=@$types->[1];
+ $tmp= $types->[1];
foreach $type (@$tmp)
{
if (defined($limits{"func_$types->[0]_$type->[1]"}))
@@ -1137,7 +1142,7 @@ if ($limits{'functions'} eq 'yes')
foreach $types (@group_types)
{
print "\nSupported $types->[0] group functions\n";
- $tmp=@$types->[1];
+ $tmp= $types->[1];
foreach $type (@$tmp)
{
check_and_report("Group function $type->[0]",
@@ -3133,8 +3138,11 @@ $0 takes the following options:
Wait this long before restarting server.
--verbose
---noverbose
Log into the result file queries performed for determination parameter value
+ This causes rows starting with ' ###' to be logged into the .cnf file
+
+--noverbose
+ Don't log '###' quries to the .cnf file.
EOF
exit(0);
@@ -4350,7 +4358,7 @@ sub save_config_data
my $last_line_was_empty=0;
foreach $line (split /\n/, $log{$key})
{
- print CONFIG_FILE " ###$line\n"
+ print CONFIG_FILE "$log_prefix$line\n"
unless ( ($last_line_was_empty eq 1)
&& ($line =~ /^\s+$/) );
$last_line_was_empty= ($line =~ /^\s+$/)?1:0;
@@ -4370,7 +4378,7 @@ sub add_log
{
my $key = shift;
my $line = shift;
- $log{$key} .= $line . "\n" if ($opt_verbose);;
+ $log{$key} .= $line . "\n" if ($opt_verbose);
}
sub save_all_config_data
@@ -4392,14 +4400,17 @@ sub save_all_config_data
$tmp="$key=$limits{$key}";
print CONFIG_FILE $tmp . ("\t" x (int((32-min(length($tmp),32)+7)/8)+1)) .
"# $prompts{$key}\n";
- my $line;
- my $last_line_was_empty=0;
- foreach $line (split /\n/, $log{$key})
- {
- print CONFIG_FILE " ###$line\n" unless
- ( ($last_line_was_empty eq 1) && ($line =~ /^\s*$/));
+ if ($opt_verbose)
+ {
+ my $line;
+ my $last_line_was_empty=0;
+ foreach $line (split /\n/, $log{$key})
+ {
+ print CONFIG_FILE "$log_prefix$line\n" unless
+ ( ($last_line_was_empty eq 1) && ($line =~ /^\s*$/));
$last_line_was_empty= ($line =~ /^\s*$/)?1:0;
- };
+ }
+ }
}
close CONFIG_FILE;
}
diff --git a/sql-bench/limits/mysql.cfg b/sql-bench/limits/mysql.cfg
index 76565cb16ff..1194898481d 100644
--- a/sql-bench/limits/mysql.cfg
+++ b/sql-bench/limits/mysql.cfg
@@ -1,4 +1,4 @@
-#This file is automaticly generated by crash-me 1.61
+#This file is automaticly generated by crash-me 1.62
NEG=yes # update of column= -column
Need_cast_for_null=no # Need to cast NULL for arithmetic
@@ -31,7 +31,7 @@ comment_--=yes # -- as comment (ANSI)
comment_/**/=yes # /* */ as comment
comment_//=no # // as comment
compute=no # Compute
-connections=101 # Simultaneous connections (installation default)
+connections=152 # Simultaneous connections (installation default)
constraint_check=syntax only # Column constraints
constraint_check_named=syntax only # Named constraints
constraint_check_table=syntax only # Table constraints
@@ -387,17 +387,17 @@ max_char_size=255 # max char() size
max_column_name=64 # column name length
max_columns=2599 # Columns in table
max_conditions=85660 # OR and AND in WHERE
-max_expressions=580 # simple expressions
+max_expressions=571 # simple expressions
max_index=+64 # max index
max_index_length=1000 # index length
max_index_name=64 # index name length
max_index_part_length=255 # max index part length
-max_index_parts=16 # index parts
+max_index_parts=32 # index parts
max_index_varchar_part_length=1000 # index varchar part length
max_row_length=65534 # max table row length (without blobs)
max_row_length_with_null=65502 # table row length with nulls (without blobs)
max_select_alias_name=+512 # select alias name length
-max_stack_expression=580 # stacked expressions
+max_stack_expression=571 # stacked expressions
max_table_alias_name=+512 # table alias name length
max_table_name=64 # table name length
max_text_size=1048543 # max text or blob size
@@ -422,7 +422,7 @@ null_in_unique=yes # null in unique index
null_num_expr=yes # Is 1+NULL = NULL
nulls_in_unique=yes # null combination in unique index
odbc_left_outer_join=yes # left outer join odbc style
-operating_system=Linux 2.6.8-my i686 # crash-me tested on
+operating_system=Linux 2.6.37.6-0.7-desktop x86_64 # crash-me tested on
order_by=yes # Order by
order_by_alias=yes # Order by alias
order_by_function=yes # Order by function
@@ -433,7 +433,7 @@ position_of_null_desc=last # Where is null values in sorted recordset (DESC)
primary_key_in_create=yes # primary key in create table
psm_functions=no # PSM functions (ANSI SQL)
psm_modules=no # PSM modules (ANSI SQL)
-psm_procedures=no # PSM procedures (ANSI SQL)
+psm_procedures=yes # PSM procedures (ANSI SQL)
psm_trigger=no # Triggers (ANSI SQL)
query_size=1048574 # query size
quote_ident_with_"=error # " as identifier quote (ANSI SQL)
@@ -485,7 +485,7 @@ reserved_word_ansi-92/99_column=yes # Keyword COLUMN
reserved_word_ansi-92/99_commit=no # Keyword COMMIT
reserved_word_ansi-92/99_completion=no # Keyword COMPLETION
reserved_word_ansi-92/99_connect=no # Keyword CONNECT
-reserved_word_ansi-92/99_connection=yes # Keyword CONNECTION
+reserved_word_ansi-92/99_connection=no # Keyword CONNECTION
reserved_word_ansi-92/99_constraint=yes # Keyword CONSTRAINT
reserved_word_ansi-92/99_constraints=no # Keyword CONSTRAINTS
reserved_word_ansi-92/99_continue=yes # Keyword CONTINUE
@@ -546,7 +546,7 @@ reserved_word_ansi-92/99_general=no # Keyword GENERAL
reserved_word_ansi-92/99_get=no # Keyword GET
reserved_word_ansi-92/99_global=no # Keyword GLOBAL
reserved_word_ansi-92/99_go=no # Keyword GO
-reserved_word_ansi-92/99_goto=yes # Keyword GOTO
+reserved_word_ansi-92/99_goto=no # Keyword GOTO
reserved_word_ansi-92/99_grant=yes # Keyword GRANT
reserved_word_ansi-92/99_group=yes # Keyword GROUP
reserved_word_ansi-92/99_having=yes # Keyword HAVING
@@ -933,7 +933,7 @@ reserved_word_extra_setuser=no # Keyword SETUSER
reserved_word_extra_share=no # Keyword SHARE
reserved_word_extra_show=yes # Keyword SHOW
reserved_word_extra_shutdown=no # Keyword SHUTDOWN
-reserved_word_extra_soname=yes # Keyword SONAME
+reserved_word_extra_soname=no # Keyword SONAME
reserved_word_extra_spatial=yes # Keyword SPATIAL
reserved_word_extra_sql_big_result=yes # Keyword SQL_BIG_RESULT
reserved_word_extra_sql_calc_found_rows=yes # Keyword SQL_CALC_FOUND_ROWS
@@ -983,7 +983,7 @@ select_limit3=yes # SELECT with LIMIT # OFFSET #
select_string_size=1048565 # constant string size in SELECT
select_table_update=yes # Update with sub select
select_without_from=yes # SELECT without FROM
-server_version=MySQL 5.0.7 beta valgrind max debug/ # server version
+server_version=MySQL 5.3.1 MariaDB beta valgrind max debug # server version
simple_joins=yes # ANSI SQL simple joins
sorted_group_by=yes # Group by always sorted
storage_of_float=round # Storage of float values
@@ -1063,7 +1063,6 @@ type_extra_varchar2(1_arg)=no # Type varchar2(1 arg)
type_extra_year=yes # Type year
type_odbc_bigint=yes # Type bigint
type_odbc_binary(1_arg)=yes # Type binary(1 arg)
-type_odbc_datetime=yes # Type datetime
type_odbc_tinyint=yes # Type tinyint
type_odbc_varbinary(1_arg)=yes # Type varbinary(1 arg)
type_sql_bit=yes # Type bit
@@ -1075,6 +1074,8 @@ type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
type_sql_character(1_arg)=yes # Type character(1 arg)
type_sql_character_varying(1_arg)=yes # Type character varying(1 arg)
type_sql_date=yes # Type date
+type_sql_datetime=yes # Type datetime
+type_sql_datetime(1_arg)=yes # Type datetime(1 arg)
type_sql_dec(2_arg)=yes # Type dec(2 arg)
type_sql_decimal(2_arg)=yes # Type decimal(2 arg)
type_sql_double_precision=yes # Type double precision
@@ -1104,7 +1105,9 @@ type_sql_numeric(2_arg)=yes # Type numeric(2 arg)
type_sql_real=yes # Type real
type_sql_smallint=yes # Type smallint
type_sql_time=yes # Type time
+type_sql_time(1_arg)=yes # Type time(1 arg)
type_sql_timestamp=yes # Type timestamp
+type_sql_timestamp(1_arg)=yes # Type timestamp(1 arg)
type_sql_timestamp_with_time_zone=no # Type timestamp with time zone
type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
union=yes # union
diff --git a/sql-bench/test-table-elimination.sh b/sql-bench/test-table-elimination.sh
index 338a7ceb4b5..5b494688bec 100755
--- a/sql-bench/test-table-elimination.sh
+++ b/sql-bench/test-table-elimination.sh
@@ -92,7 +92,7 @@ $dbh->do("create view elim_current_facts as $select_current_full_facts");
if ($opt_lock_tables)
{
- do_query($dbh,"LOCK TABLES elim_facts, elim_attr1, elim_attr2 WRITE");
+ do_query($dbh,"LOCK TABLES elim_current_facts WRITE, elim_facts WRITE, elim_attr1 WRITE, elim_attr2 WRITE");
}
if ($opt_fast && defined($server->{vacuum}))
@@ -199,12 +199,14 @@ if ($opt_lock_tables)
if ($opt_fast && defined($server->{vacuum}))
{
- $server->vacuum(0,\$dbh,["elim_facts", "elim_attr1", "elim_attr2"]);
+ $server->vacuum(1,\$dbh,"elim_facts");
+ $server->vacuum(1,\$dbh,"elim_attr1");
+ $server->vacuum(1,\$dbh,"elim_attr2");
}
if ($opt_lock_tables)
{
- do_query($dbh,"LOCK TABLES elim_facts, elim_attr1, elim_attr2 WRITE");
+ do_query($dbh,"LOCK TABLES elim_current_facts READ, elim_facts READ, elim_attr1 READ, elim_attr2 READ");
}
####
diff --git a/sql-common/client.c b/sql-common/client.c
index d9444a7d976..e18af7d85b4 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -127,6 +127,7 @@ const char *def_shared_memory_base_name= default_shared_memory_base_name;
static void mysql_close_free_options(MYSQL *mysql);
static void mysql_close_free(MYSQL *mysql);
static void mysql_prune_stmt_list(MYSQL *mysql);
+static int cli_report_progress(MYSQL *mysql, uchar *packet, uint length);
#if !(defined(__WIN__) || defined(__NETWARE__))
static int wait_for_data(my_socket fd, uint timeout);
@@ -691,6 +692,7 @@ cli_safe_read(MYSQL *mysql)
ulong len=0;
init_sigpipe_variables
+restart:
/* Don't give sigpipe errors if the client doesn't want them */
set_sigpipe(mysql);
if (net->vio != 0)
@@ -714,13 +716,27 @@ cli_safe_read(MYSQL *mysql)
{
if (len > 3)
{
- char *pos=(char*) net->read_pos+1;
- net->last_errno=uint2korr(pos);
+ uchar *pos= net->read_pos+1;
+ uint last_errno=uint2korr(pos);
+
+ if (last_errno == 65535 &&
+ (mysql->server_capabilities & CLIENT_PROGRESS))
+ {
+ if (cli_report_progress(mysql, pos+2, (uint) (len-3)))
+ {
+ /* Wrong packet */
+ set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
+ return (packet_error);
+ }
+ goto restart;
+ }
+ net->last_errno= last_errno;
+
pos+=2;
len-=2;
- if (protocol_41(mysql) && pos[0] == '#')
+ if (protocol_41(mysql) && (char) pos[0] == '#')
{
- strmake(net->sqlstate, pos+1, SQLSTATE_LENGTH);
+ strmake(net->sqlstate, (char*) pos+1, SQLSTATE_LENGTH);
pos+= SQLSTATE_LENGTH+1;
}
else
@@ -877,6 +893,40 @@ static void cli_flush_use_result(MYSQL *mysql)
}
+/*
+ Report progress to the client
+
+ RETURN VALUES
+ 0 ok
+ 1 error
+*/
+
+static int cli_report_progress(MYSQL *mysql, uchar *packet, uint length)
+{
+ uint stage, max_stage, proc_length;
+ double progress;
+ uchar *start= packet;
+
+ if (length < 5)
+ return 1; /* Wrong packet */
+
+ if (!(mysql->options.extension && mysql->options.extension->report_progress))
+ return 0; /* No callback, ignore packet */
+
+ packet++; /* Ignore number of strings */
+ stage= (uint) *packet++;
+ max_stage= (uint) *packet++;
+ progress= uint3korr(packet)/1000.0;
+ packet+= 3;
+ proc_length= net_field_length(&packet);
+ if (packet + proc_length > start + length)
+ return 1; /* Wrong packet */
+ (*mysql->options.extension->report_progress)(mysql, stage, max_stage,
+ progress, (char*) packet,
+ proc_length);
+ return 0;
+}
+
#ifdef __WIN__
static my_bool is_NT(void)
{
@@ -885,57 +935,6 @@ static my_bool is_NT(void)
}
#endif
-
-#ifdef CHECK_LICENSE
-/**
- Check server side variable 'license'.
-
- If the variable does not exist or does not contain 'Commercial',
- we're talking to non-commercial server from commercial client.
-
- @retval 0 success
- @retval !0 network error or the server is not commercial.
- Error code is saved in mysql->net.last_errno.
-*/
-
-static int check_license(MYSQL *mysql)
-{
- MYSQL_ROW row;
- MYSQL_RES *res;
- NET *net= &mysql->net;
- static const char query[]= "SELECT @@license";
- static const char required_license[]= STRINGIFY_ARG(LICENSE);
-
- if (mysql_real_query(mysql, query, sizeof(query)-1))
- {
- if (net->last_errno == ER_UNKNOWN_SYSTEM_VARIABLE)
- {
- set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
- ER(CR_WRONG_LICENSE), required_license);
- }
- return 1;
- }
- if (!(res= mysql_use_result(mysql)))
- return 1;
- row= mysql_fetch_row(res);
- /*
- If no rows in result set, or column value is NULL (none of these
- two is ever true for server variables now), or column value
- mismatch, set wrong license error.
- */
- if (!net->last_errno &&
- (!row || !row[0] ||
- strncmp(row[0], required_license, sizeof(required_license))))
- {
- set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
- ER(CR_WRONG_LICENSE), required_license);
- }
- mysql_free_result(res);
- return net->last_errno;
-}
-#endif /* CHECK_LICENSE */
-
-
/**************************************************************************
Shut down connection
**************************************************************************/
@@ -1052,14 +1051,17 @@ static int add_init_command(struct st_mysql_options *options, const char *cmd)
return 0;
}
-#define extension_set_string(OPTS, X, STR) \
- if ((OPTS)->extension) \
- my_free((OPTS)->extension->X, MYF(MY_ALLOW_ZERO_PTR)); \
- else \
+#define extension_set(OPTS, X, VAL) \
+ if (!(OPTS)->extension) \
(OPTS)->extension= (struct st_mysql_options_extention *) \
my_malloc(sizeof(struct st_mysql_options_extention), \
MYF(MY_WME | MY_ZEROFILL)); \
- (OPTS)->extension->X= my_strdup((STR), MYF(MY_WME));
+ (OPTS)->extension->X= VAL;
+
+#define extension_set_string(OPTS, X, STR) \
+ if ((OPTS)->extension) \
+ my_free((OPTS)->extension->X, MYF(MY_ALLOW_ZERO_PTR)); \
+ extension_set(OPTS, X, my_strdup((STR), MYF(MY_WME)));
void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group)
@@ -2988,11 +2990,6 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
if (mysql->client_flag & CLIENT_COMPRESS) /* We will use compression */
net->compress=1;
-#ifdef CHECK_LICENSE
- if (check_license(mysql))
- goto error;
-#endif
-
if (db && !mysql->db && mysql_select_db(mysql, db))
{
if (mysql->net.last_errno == CR_SERVER_LOST)
@@ -3748,6 +3745,15 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
case MYSQL_DEFAULT_AUTH:
extension_set_string(&mysql->options, default_auth, arg);
break;
+ case MYSQL_PROGRESS_CALLBACK:
+ if (!mysql->options.extension)
+ mysql->options.extension= (struct st_mysql_options_extention *)
+ my_malloc(sizeof(struct st_mysql_options_extention),
+ MYF(MY_WME | MY_ZEROFILL));
+ if (mysql->options.extension)
+ mysql->options.extension->report_progress=
+ (void (*)(const MYSQL *, uint, uint, double, const char *, uint)) arg;
+ break;
default:
DBUG_RETURN(1);
}
diff --git a/sql-common/client_plugin.c b/sql-common/client_plugin.c
index 0b1bdeae0be..9a90e3c93fd 100644
--- a/sql-common/client_plugin.c
+++ b/sql-common/client_plugin.c
@@ -55,8 +55,8 @@ struct st_client_plugin_int {
static my_bool initialized= 0;
static MEM_ROOT mem_root;
-static const char *plugin_declarations_sym __attribute__((unused)) =
- "_mysql_client_plugin_declaration_";
+#define plugin_declarations_sym "_mysql_client_plugin_declaration_"
+
static uint plugin_version[MYSQL_CLIENT_MAX_PLUGINS]=
{
0, /* these two are taken by Connector/C */
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index fcb9ece92f1..5ad037ab6c9 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -20,6 +20,7 @@
#include <m_ctype.h>
/* Windows version of localtime_r() is declared in my_ptrhead.h */
#include <my_pthread.h>
+#include <mysqld_error.h>
ulonglong log_10_int[20]=
{
@@ -83,7 +84,7 @@ my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
if (not_zero_date)
{
if ((((flags & TIME_NO_ZERO_IN_DATE) || !(flags & TIME_FUZZY_DATE)) &&
- (ltime->month == 0 || ltime->day == 0)) ||
+ (ltime->month == 0 || ltime->day == 0)) || ltime->neg ||
(!(flags & TIME_INVALID_DATES) &&
ltime->month && ltime->day > days_in_month[ltime->month-1] &&
(ltime->month != 2 || calc_days_in_year(ltime->year) != 366 ||
@@ -160,7 +161,7 @@ my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
enum enum_mysql_timestamp_type
str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
- uint flags, int *was_cut)
+ ulong flags, int *was_cut)
{
uint field_length, UNINIT_VAR(year_length), digits, i, number_of_fields;
uint date[MAX_DATE_PARTS], date_len[MAX_DATE_PARTS];
@@ -173,10 +174,17 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
my_bool found_delimitier= 0, found_space= 0;
uint frac_pos, frac_len;
DBUG_ENTER("str_to_datetime");
- DBUG_PRINT("ENTER",("str: %.*s",length,str));
+ DBUG_PRINT("enter",("str: %.*s",length,str));
LINT_INIT(field_length);
+ if (flags & TIME_TIME_ONLY)
+ {
+ enum enum_mysql_timestamp_type ret;
+ ret= str_to_time(str, length, l_time, flags, was_cut);
+ DBUG_RETURN(ret);
+ }
+
*was_cut= 0;
/* Skip space at start */
@@ -479,12 +487,13 @@ err:
work with times where the time arguments are in the above order.
RETURN
- 0 ok
- 1 error
+ MYSQL_TIMESTAMP_TIME
+ MYSQL_TIMESTAMP_ERROR
*/
-my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
- int *warning)
+enum enum_mysql_timestamp_type
+str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
+ ulong fuzzydate, int *warning)
{
ulong date[5];
ulonglong value;
@@ -503,7 +512,7 @@ my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
length--;
}
if (str == end)
- return 1;
+ return MYSQL_TIMESTAMP_ERROR;
/* Check first if this is a full TIMESTAMP */
if (length >= 12)
@@ -511,12 +520,13 @@ my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
int was_cut;
enum enum_mysql_timestamp_type
res= str_to_datetime(str, length, l_time,
- (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), &was_cut);
+ (fuzzydate & ~TIME_TIME_ONLY) | TIME_DATETIME_ONLY,
+ &was_cut);
if ((int) res >= (int) MYSQL_TIMESTAMP_ERROR)
{
if (was_cut)
*warning|= MYSQL_TIME_WARN_TRUNCATED;
- return res == MYSQL_TIMESTAMP_ERROR;
+ return res;
}
}
@@ -611,7 +621,7 @@ fractional:
((str[1] == '-' || str[1] == '+') &&
(end - str) > 2 &&
my_isdigit(&my_charset_latin1, str[2]))))
- return 1;
+ return MYSQL_TIMESTAMP_ERROR;
if (internal_format_positions[7] != 255)
{
@@ -634,7 +644,7 @@ fractional:
if (date[0] > UINT_MAX || date[1] > UINT_MAX ||
date[2] > UINT_MAX || date[3] > UINT_MAX ||
date[4] > UINT_MAX)
- return 1;
+ return MYSQL_TIMESTAMP_ERROR;
l_time->year= 0; /* For protocol::store_time */
l_time->month= 0;
@@ -646,8 +656,8 @@ fractional:
l_time->time_type= MYSQL_TIMESTAMP_TIME;
/* Check if the value is valid and fits into MYSQL_TIME range */
- if (check_time_range(l_time, warning))
- return 1;
+ if (check_time_range(l_time, 6, warning))
+ return MYSQL_TIMESTAMP_ERROR;
/* Check if there is garbage at end of the MYSQL_TIME specification */
if (str != end)
@@ -661,7 +671,7 @@ fractional:
}
} while (++str != end);
}
- return 0;
+ return MYSQL_TIMESTAMP_TIME;
}
@@ -671,6 +681,7 @@ fractional:
SYNOPSIS:
check_time_range()
time pointer to MYSQL_TIME value
+ uint dec
warning set MYSQL_TIME_WARN_OUT_OF_RANGE flag if the value is out of range
DESCRIPTION
@@ -683,24 +694,31 @@ fractional:
1 time value is invalid
*/
-int check_time_range(struct st_mysql_time *my_time, int *warning)
+int check_time_range(struct st_mysql_time *my_time, uint dec, int *warning)
{
longlong hour;
+ static ulong max_sec_part[TIME_SECOND_PART_DIGITS+1]= {000000, 900000, 990000,
+ 999000, 999900, 999990, 999999};
if (my_time->minute >= 60 || my_time->second >= 60)
return 1;
hour= my_time->hour + (24*my_time->day);
+
+ if (dec == AUTO_SEC_PART_DIGITS)
+ dec= TIME_SECOND_PART_DIGITS;
+
if (hour <= TIME_MAX_HOUR &&
(hour != TIME_MAX_HOUR || my_time->minute != TIME_MAX_MINUTE ||
- my_time->second != TIME_MAX_SECOND || !my_time->second_part))
+ my_time->second != TIME_MAX_SECOND ||
+ my_time->second_part <= max_sec_part[dec]))
return 0;
my_time->day= 0;
my_time->hour= TIME_MAX_HOUR;
my_time->minute= TIME_MAX_MINUTE;
my_time->second= TIME_MAX_SECOND;
- my_time->second_part= 0;
+ my_time->second_part= max_sec_part[dec];
*warning|= MYSQL_TIME_WARN_OUT_OF_RANGE;
return 0;
}
@@ -717,7 +735,7 @@ void my_init_time(void)
time_t seconds;
struct tm *l_time,tm_tmp;
MYSQL_TIME my_time;
- my_bool not_used;
+ uint not_used;
seconds= (time_t) time((time_t*) 0);
localtime_r(&seconds,&tm_tmp);
@@ -732,6 +750,7 @@ void my_init_time(void)
my_time.neg= 0;
my_time.second_part= 0;
my_time.time_type= MYSQL_TIMESTAMP_DATETIME;
+
my_system_gmt_sec(&my_time, &my_time_zone, &not_used); /* Init my_time_zone */
}
@@ -802,7 +821,11 @@ long calc_daynr(uint year,uint month,uint day)
t - time value to be converted
my_timezone - pointer to long where offset of system time zone
from UTC will be stored for caching
- in_dst_time_gap - set to true if time falls into spring time-gap
+ error_code - 0, if the conversion was successful;
+ ER_WARN_DATA_OUT_OF_RANGE, if t contains datetime value
+ which is out of TIMESTAMP range;
+ ER_WARN_INVALID_TIMESTAMP, if t represents value which
+ doesn't exists (falls into the spring time-gap).
NOTES
The idea is to cache the time zone offset from UTC (including daylight
@@ -816,8 +839,7 @@ long calc_daynr(uint year,uint month,uint day)
Time in UTC seconds since Unix Epoch representation.
*/
my_time_t
-my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone,
- my_bool *in_dst_time_gap)
+my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code)
{
uint loop;
time_t tmp= 0;
@@ -834,7 +856,11 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone,
memcpy(&tmp_time, t_src, sizeof(MYSQL_TIME));
if (!validate_timestamp_range(t))
+ {
+ *error_code= ER_WARN_DATA_OUT_OF_RANGE;
return 0;
+ }
+ *error_code= 0;
/*
Calculate the gmt time based on current time and timezone
@@ -980,7 +1006,7 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone,
else if (diff == -3600)
tmp-=t->minute*60 + t->second; /* Move to previous hour */
- *in_dst_time_gap= 1;
+ *error_code= ER_WARN_INVALID_TIMESTAMP;
}
*my_timezone= current_timezone;
@@ -999,7 +1025,10 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone,
larger then TIMESTAMP_MAX_VALUE, so another check will work.
*/
if (!IS_TIME_T_VALID_FOR_TIMESTAMP(tmp))
+ {
tmp= 0;
+ *error_code= ER_WARN_DATA_OUT_OF_RANGE;
+ }
return (my_time_t) tmp;
} /* my_system_gmt_sec */
@@ -1015,45 +1044,117 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type)
/*
+ Helper function for datetime formatting.
+ Format number as string, left-padded with 0.
+
+ The reason to use own formatting rather than sprintf() is performance - in a
+ datetime benchmark it helped to reduced the datetime formatting overhead
+ from ~30% down to ~4%.
+*/
+
+static char* fmt_number(uint val, char *out, uint digits)
+{
+ uint i;
+ for(i= 0; i < digits; i++)
+ {
+ out[digits-i-1]= '0' + val%10;
+ val/=10;
+ }
+ return out + digits;
+}
+
+
+/*
Functions to convert time/date/datetime value to a string,
using default format.
This functions don't check that given MYSQL_TIME structure members are
in valid range. If they are not, return value won't reflect any
- valid date either. Additionally, make_time doesn't take into
- account time->day member: it's assumed that days have been converted
- to hours already.
+ valid date either.
RETURN
number of characters written to 'to'
*/
-int my_time_to_str(const MYSQL_TIME *l_time, char *to)
+int my_time_to_str(const MYSQL_TIME *l_time, char *to, uint digits)
{
- uint extra_hours= 0;
- return my_sprintf(to, (to, "%s%02u:%02u:%02u",
- (l_time->neg ? "-" : ""),
- extra_hours+ l_time->hour,
- l_time->minute,
- l_time->second));
+ uint day= (l_time->year || l_time->month) ? 0 : l_time->day;
+ uint hour= day * 24 + l_time->hour;
+ char*pos= to;
+
+ if (digits == AUTO_SEC_PART_DIGITS)
+ digits= l_time->second_part ? TIME_SECOND_PART_DIGITS : 0;
+
+ DBUG_ASSERT(digits <= TIME_SECOND_PART_DIGITS);
+
+ if(l_time->neg)
+ *pos++= '-';
+
+ if(hour > 99)
+ /* Need more than 2 digits for hours in string representation. */
+ pos= longlong10_to_str((longlong)hour, pos, 10);
+ else
+ pos= fmt_number(hour, pos, 2);
+
+ *pos++= ':';
+ pos= fmt_number(l_time->minute, pos, 2);
+ *pos++= ':';
+ pos= fmt_number(l_time->second, pos, 2);
+
+ if (digits)
+ {
+ *pos++= '.';
+ pos= fmt_number((uint)sec_part_shift(l_time->second_part, digits),
+ pos, digits);
+ }
+
+ *pos= 0;
+ return (int) (pos-to);
}
+
int my_date_to_str(const MYSQL_TIME *l_time, char *to)
{
- return my_sprintf(to, (to, "%04u-%02u-%02u",
- l_time->year,
- l_time->month,
- l_time->day));
+ char *pos=to;
+ pos= fmt_number(l_time->year, pos, 4);
+ *pos++='-';
+ pos= fmt_number(l_time->month, pos, 2);
+ *pos++='-';
+ pos= fmt_number(l_time->day, pos, 2);
+ *pos= 0;
+ return (int)(pos - to);
}
-int my_datetime_to_str(const MYSQL_TIME *l_time, char *to)
+
+int my_datetime_to_str(const MYSQL_TIME *l_time, char *to, uint digits)
{
- return my_sprintf(to, (to, "%04u-%02u-%02u %02u:%02u:%02u",
- l_time->year,
- l_time->month,
- l_time->day,
- l_time->hour,
- l_time->minute,
- l_time->second));
+ char *pos= to;
+
+ if (digits == AUTO_SEC_PART_DIGITS)
+ digits= l_time->second_part ? TIME_SECOND_PART_DIGITS : 0;
+
+ DBUG_ASSERT(digits <= TIME_SECOND_PART_DIGITS);
+
+ pos= fmt_number(l_time->year, pos, 4);
+ *pos++='-';
+ pos= fmt_number(l_time->month, pos, 2);
+ *pos++='-';
+ pos= fmt_number(l_time->day, pos, 2);
+ *pos++=' ';
+ pos= fmt_number(l_time->hour, pos, 2);
+ *pos++= ':';
+ pos= fmt_number(l_time->minute, pos, 2);
+ *pos++= ':';
+ pos= fmt_number(l_time->second, pos, 2);
+
+ if (digits)
+ {
+ *pos++='.';
+ pos= fmt_number((uint) sec_part_shift(l_time->second_part, digits), pos,
+ digits);
+ }
+
+ *pos= 0;
+ return (int)(pos - to);
}
@@ -1064,19 +1165,22 @@ int my_datetime_to_str(const MYSQL_TIME *l_time, char *to)
SYNOPSIS
my_TIME_to_string()
+ RETURN
+ length of string
+
NOTE
The string must have at least MAX_DATE_STRING_REP_LENGTH bytes reserved.
*/
-int my_TIME_to_str(const MYSQL_TIME *l_time, char *to)
+int my_TIME_to_str(const MYSQL_TIME *l_time, char *to, uint digits)
{
switch (l_time->time_type) {
case MYSQL_TIMESTAMP_DATETIME:
- return my_datetime_to_str(l_time, to);
+ return my_datetime_to_str(l_time, to, digits);
case MYSQL_TIMESTAMP_DATE:
return my_date_to_str(l_time, to);
case MYSQL_TIMESTAMP_TIME:
- return my_time_to_str(l_time, to);
+ return my_time_to_str(l_time, to, digits);
case MYSQL_TIMESTAMP_NONE:
case MYSQL_TIMESTAMP_ERROR:
to[0]='\0';
@@ -1114,16 +1218,15 @@ int my_TIME_to_str(const MYSQL_TIME *l_time, char *to)
Datetime value in YYYYMMDDHHMMSS format.
*/
-longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
+longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
uint flags, int *was_cut)
{
long part1,part2;
*was_cut= 0;
- bzero((char*) time_res, sizeof(*time_res));
time_res->time_type=MYSQL_TIMESTAMP_DATE;
- if (nr == LL(0) || nr >= LL(10000101000000))
+ if (nr == 0 || nr >= 10000101000000LL || sec_part)
{
time_res->time_type=MYSQL_TIMESTAMP_DATETIME;
goto ok;
@@ -1173,22 +1276,87 @@ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
time_res->hour= (int) (part2/10000L); part2%=10000L;
time_res->minute=(int) part2 / 100;
time_res->second=(int) part2 % 100;
+ time_res->second_part= sec_part;
+ time_res->neg= 0;
if (time_res->year <= 9999 && time_res->month <= 12 &&
time_res->day <= 31 && time_res->hour <= 23 &&
time_res->minute <= 59 && time_res->second <= 59 &&
- !check_date(time_res, (nr != 0), flags, was_cut))
+ sec_part <= TIME_MAX_SECOND_PART &&
+ !check_date(time_res, nr || sec_part, flags, was_cut))
return nr;
/* Don't want to have was_cut get set if NO_ZERO_DATE was violated. */
- if (!nr && (flags & TIME_NO_ZERO_DATE))
- return LL(-1);
+ if (nr || !(flags & TIME_NO_ZERO_DATE))
+ *was_cut= 1;
+ return LL(-1);
err:
- *was_cut= 1;
+ {
+ /* reset everything except time_type */
+ enum enum_mysql_timestamp_type save= time_res->time_type;
+ bzero((char*) time_res, sizeof(*time_res));
+ time_res->time_type= save; /* Restore range */
+ *was_cut= 1; /* Found invalid date */
+ }
return LL(-1);
}
+/*
+ Convert a pair of integers to a MYSQL_TIME struct.
+
+ @param[in] nr a number to convert
+ @param[out] ltime Date to check.
+ @param[out] was_cut MYSQL_TIME_WARN_OUT_OF_RANGE if the value was
+ modified to fit in the valid range. Otherwise 0.
+
+ @details
+ Takes a number in the [-]HHHMMSS.uuuuuu,
+ YYMMDDHHMMSS.uuuuuu, or in the YYYYMMDDHHMMSS.uuuuuu formats.
+
+ @return
+ 0 time value is valid, but was possibly truncated
+ -1 time value is invalid
+*/
+int number_to_time(my_bool neg, longlong nr, ulong sec_part,
+ MYSQL_TIME *ltime, int *was_cut)
+{
+ if (nr > 9999999 && neg == 0)
+ {
+ if (number_to_datetime(nr, sec_part, ltime,
+ TIME_FUZZY_DATE | TIME_INVALID_DATES, was_cut) < 0)
+ return -1;
+
+ ltime->year= ltime->month= ltime->day= 0;
+ ltime->time_type= MYSQL_TIMESTAMP_TIME;
+ *was_cut= MYSQL_TIME_WARN_TRUNCATED;
+ return 0;
+ }
+
+ *was_cut= 0;
+ ltime->year= ltime->month= ltime->day= 0;
+ ltime->time_type= MYSQL_TIMESTAMP_TIME;
+
+ ltime->neg= neg;
+
+ if (nr > TIME_MAX_VALUE)
+ {
+ nr= TIME_MAX_VALUE;
+ sec_part= TIME_MAX_SECOND_PART;
+ *was_cut= MYSQL_TIME_WARN_OUT_OF_RANGE;
+ }
+ ltime->hour = (uint)(nr/100/100);
+ ltime->minute= nr/100%100;
+ ltime->second= nr%100;
+ ltime->second_part= sec_part;
+
+ if (ltime->minute < 60 && ltime->second < 60 && sec_part <= TIME_MAX_SECOND_PART)
+ return 0;
+
+ *was_cut= MYSQL_TIME_WARN_TRUNCATED;
+ return -1;
+}
+
/* Convert time value to integer in YYYYMMDDHHMMSS format */
@@ -1237,7 +1405,7 @@ ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *my_time)
DESCRIPTION
The function is used when we need to convert value of time item
to a number if it's used in numeric context, i. e.:
- SELECT NOW()+1, CURDATE()+0, CURTIMIE()+0;
+ SELECT NOW()+1, CURDATE()+0, CURTIME()+0;
SELECT ?+1;
NOTE
@@ -1264,3 +1432,41 @@ ulonglong TIME_to_ulonglong(const MYSQL_TIME *my_time)
return 0;
}
+double TIME_to_double(const MYSQL_TIME *my_time)
+{
+ double d= (double)TIME_to_ulonglong(my_time);
+
+ if (my_time->time_type == MYSQL_TIMESTAMP_DATE)
+ return d;
+
+ d+= my_time->second_part/(double)TIME_SECOND_PART_FACTOR;
+ return my_time->neg ? -d : d;
+}
+
+longlong pack_time(MYSQL_TIME *my_time)
+{
+ return ((((((my_time->year * 13ULL +
+ my_time->month) * 32ULL +
+ my_time->day) * 24ULL +
+ my_time->hour) * 60ULL +
+ my_time->minute) * 60ULL +
+ my_time->second) * 1000000ULL +
+ my_time->second_part) * (my_time->neg ? -1 : 1);
+}
+
+#define get_one(WHERE, FACTOR) WHERE= (ulong)(packed % FACTOR); packed/= FACTOR
+
+MYSQL_TIME *unpack_time(longlong packed, MYSQL_TIME *my_time)
+{
+ if ((my_time->neg= packed < 0))
+ packed= -packed;
+ get_one(my_time->second_part, 1000000ULL);
+ get_one(my_time->second, 60ULL);
+ get_one(my_time->minute, 60ULL);
+ get_one(my_time->hour, 24ULL);
+ get_one(my_time->day, 32ULL);
+ get_one(my_time->month, 13ULL);
+ my_time->year= (uint)packed;
+ my_time->time_type= MYSQL_TIMESTAMP_DATETIME;
+ return my_time;
+}
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 85eafa79a6c..9a620775c85 100755..100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -62,9 +62,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
signal_handler.cc
sql_repl.cc sql_select.cc sql_show.cc sql_state.c sql_string.cc
@@ -78,7 +81,12 @@ 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
+ gcalc_slicescan.cc gcalc_tools.cc
+ multi_range_read.cc
+ opt_subselect.cc
+ opt_index_cond_pushdown.cc
create_options.cc
+ sql_expression_cache.cc
${CMAKE_BINARY_DIR}/sql/sql_yacc.cc
${CMAKE_BINARY_DIR}/sql/sql_yacc.h
${CMAKE_BINARY_DIR}/include/mysqld_error.h
@@ -87,6 +95,7 @@ SET (SQL_SOURCE
${CMAKE_BINARY_DIR}/include/mysql_version.h
${CMAKE_BINARY_DIR}/sql/sql_builtin.cc
${CMAKE_BINARY_DIR}/sql/lex_hash.h)
+
ADD_LIBRARY(sql ${SQL_SOURCE})
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/win/cmake/dummy.in cmake_dummy.cc COPYONLY)
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 2df6c94927e..da853d135a0 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -47,7 +47,8 @@ mysqld_LDADD = libndb.la \
$(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \
$(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@
-noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
+internalincludedir = $(pkgincludedir)/private
+internalinclude_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
item_strfunc.h item_timefunc.h \
item_xmlfunc.h sql_plugin_services.h \
item_create.h item_subselect.h item_row.h \
@@ -56,15 +57,18 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
sql_map.h sql_string.h unireg.h \
sql_error.h field.h handler.h mysqld_suffix.h \
sql_profile.h \
+ gcalc_slicescan.h gcalc_tools.h \
ha_ndbcluster.h ha_ndbcluster_cond.h \
ha_ndbcluster_binlog.h ha_ndbcluster_tables.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 \
@@ -80,7 +84,11 @@ 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 \
+ gcalc_slicescan.h gcalc_tools.h plistsort.c
mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
@@ -94,8 +102,10 @@ 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 \
+ gcalc_slicescan.cc gcalc_tools.cc \
sql_prepare.cc sql_error.cc sql_locale.cc \
sql_update.cc sql_delete.cc uniques.cc sql_do.cc \
procedure.cc sql_test.cc \
@@ -103,7 +113,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 \
@@ -127,7 +138,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
@@ -156,7 +169,7 @@ EXTRA_DIST = udf_example.c udf_example.def $(BUILT_MAINT_SRC) \
nt_servc.cc nt_servc.h mysql_install_db.cc mysql_upgrade_service.cc \
message.mc message.h message.rc MSG00001.bin \
winservice.c winservice.h \
- CMakeLists.txt
+ CMakeLists.txt opt_range_mrr.cc
CLEANFILES = lex_hash.h sql_yacc.output link_sources
DISTCLEANFILES = $(EXTRA_PROGRAMS)
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
index 74f6256df25..585be68a7f6 100644
--- a/sql/debug_sync.cc
+++ b/sql/debug_sync.cc
@@ -1078,7 +1078,7 @@ static bool debug_sync_set_action(THD *thd, st_debug_sync_action *action)
point decremented it to 0. In this case the following happened:
- an error message was reported with my_error() and
- - the statement was killed with thd->killed= THD::KILL_QUERY.
+ - the statement was killed with thd->killed= KILL_QUERY.
If a statement reports an error, it must not call send_ok().
The calling functions will not call send_ok(), if we return TRUE
@@ -1852,7 +1852,7 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
{
if (!--action->hit_limit)
{
- thd->killed= THD::KILL_QUERY;
+ thd->killed= KILL_QUERY;
my_error(ER_DEBUG_SYNC_HIT_LIMIT, MYF(0));
}
DBUG_PRINT("debug_sync_exec", ("hit_limit: %lu at: '%s'",
@@ -1942,4 +1942,7 @@ bool debug_sync_set_action(THD *thd, const char *action_str, size_t len)
}
+#else /* defined(ENABLED_DEBUG_SYNC) */
+/* prevent linker/lib warning about file without public symbols */
+int debug_sync_dummy;
#endif /* defined(ENABLED_DEBUG_SYNC) */
diff --git a/sql/derror.cc b/sql/derror.cc
index 9f05c95157b..2aaef0e46d9 100644
--- a/sql/derror.cc
+++ b/sql/derror.cc
@@ -111,7 +111,7 @@ static bool check_error_mesg(const char *file_name, const char **errmsg)
it means that the error file doesn't contain all MySQL messages
and is probably from an older version of MySQL / MariaDB.
*/
- if (errmsg[ER_ERROR_LAST - ER_ERROR_FIRST][0] == 0)
+ if (errmsg[ER_LAST_MYSQL_ERROR_MESSAGE -1 - ER_ERROR_FIRST][0] == 0)
{
sql_print_error("Error message file '%s' is probably from and older "
"version of MariaDB / MYSQL as it doesn't contain all "
diff --git a/sql/discover.cc b/sql/discover.cc
index 56dc00cc5c4..92af5d56016 100644
--- a/sql/discover.cc
+++ b/sql/discover.cc
@@ -67,7 +67,7 @@ int readfrm(const char *name, uchar **frmdata, size_t *len)
error= 2;
if (my_fstat(file, &state, MYF(0)))
goto err;
- read_len= state.st_size;
+ read_len= (size_t)state.st_size;
// Read whole frm file
error= 3;
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index e4436afd057..e90e6ec4bf9 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -466,7 +466,7 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
DBUG_RETURN(TRUE);
starts_null= table->field[ET_FIELD_STARTS]->is_null();
- my_bool not_used= FALSE;
+ uint not_used;
if (!starts_null)
{
table->field[ET_FIELD_STARTS]->get_date(&time, TIME_NO_ZERO_DATE);
@@ -648,7 +648,7 @@ add_interval(MYSQL_TIME *ltime, const Time_zone *time_zone,
if (date_add_interval(ltime, scale, interval))
return 0;
- my_bool not_used;
+ uint not_used;
return time_zone->TIME_to_gmt_sec(ltime, &not_used);
}
@@ -929,7 +929,7 @@ Event_queue_element::compute_next_execution_time()
goto ret;
}
- time_now= (my_time_t) current_thd->query_start();
+ time_now= current_thd->query_start();
DBUG_PRINT("info",("NOW: [%lu]", (ulong) time_now));
@@ -1132,7 +1132,7 @@ err:
void
Event_queue_element::mark_last_executed(THD *thd)
{
- last_executed= (my_time_t) thd->query_start();
+ last_executed= thd->query_start();
last_executed_changed= TRUE;
execution_count++;
@@ -1192,7 +1192,7 @@ append_datetime(String *buf, Time_zone *time_zone, my_time_t secs,
*/
MYSQL_TIME time;
time_zone->gmt_sec_to_TIME(&time, secs);
- buf->append(dtime_buff, my_datetime_to_str(&time, dtime_buff));
+ buf->append(dtime_buff, my_datetime_to_str(&time, dtime_buff, 0));
buf->append(STRING_WITH_LEN("'"));
}
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 960b5933a99..73b8eaf473c 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -241,6 +241,9 @@ mysql_event_fill_row(THD *thd,
rs|= fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE);
rs|= fields[ET_FIELD_ORIGINATOR]->store((longlong)et->originator, TRUE);
+ if (!is_update)
+ rs|= fields[ET_FIELD_CREATED]->set_time();
+
/*
Change the SQL_MODE only if body was present in an ALTER EVENT and of course
always during CREATE EVENT.
@@ -287,7 +290,7 @@ mysql_event_fill_row(THD *thd,
my_tz_OFFSET0->gmt_sec_to_TIME(&time, et->starts);
fields[ET_FIELD_STARTS]->set_notnull();
- fields[ET_FIELD_STARTS]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ fields[ET_FIELD_STARTS]->store_time(&time);
}
if (!et->ends_null)
@@ -296,7 +299,7 @@ mysql_event_fill_row(THD *thd,
my_tz_OFFSET0->gmt_sec_to_TIME(&time, et->ends);
fields[ET_FIELD_ENDS]->set_notnull();
- fields[ET_FIELD_ENDS]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ fields[ET_FIELD_ENDS]->store_time(&time);
}
}
else if (et->execute_at)
@@ -315,8 +318,7 @@ mysql_event_fill_row(THD *thd,
my_tz_OFFSET0->gmt_sec_to_TIME(&time, et->execute_at);
fields[ET_FIELD_EXECUTE_AT]->set_notnull();
- fields[ET_FIELD_EXECUTE_AT]->
- store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ fields[ET_FIELD_EXECUTE_AT]->store_time(&time);
}
else
{
@@ -327,7 +329,7 @@ mysql_event_fill_row(THD *thd,
*/
}
- ((Field_timestamp *)fields[ET_FIELD_MODIFIED])->set_time();
+ rs|= fields[ET_FIELD_MODIFIED]->set_time();
if (et->comment.str)
{
@@ -697,8 +699,6 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
goto end;
}
- ((Field_timestamp *)table->field[ET_FIELD_CREATED])->set_time();
-
/*
mysql_event_fill_row() calls my_error() in case of error so no need to
handle it here
@@ -917,7 +917,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);
@@ -1104,8 +1108,7 @@ update_timing_fields_for_event(THD *thd,
my_tz_OFFSET0->gmt_sec_to_TIME(&time, last_executed);
fields[ET_FIELD_LAST_EXECUTED]->set_notnull();
- fields[ET_FIELD_LAST_EXECUTED]->store_time(&time,
- MYSQL_TIMESTAMP_DATETIME);
+ fields[ET_FIELD_LAST_EXECUTED]->store_time(&time);
}
if (update_status)
{
diff --git a/sql/event_parse_data.cc b/sql/event_parse_data.cc
index 695c6b8650c..5ae6db4ee13 100644
--- a/sql/event_parse_data.cc
+++ b/sql/event_parse_data.cc
@@ -112,7 +112,7 @@ Event_parse_data::init_name(THD *thd, sp_name *spn)
void
Event_parse_data::check_if_in_the_past(THD *thd, my_time_t ltime_utc)
{
- if (ltime_utc >= (my_time_t) thd->query_start())
+ if (ltime_utc >= thd->query_start())
return;
/*
@@ -200,7 +200,7 @@ Event_parse_data::check_dates(THD *thd, int previous_on_completion)
int
Event_parse_data::init_execute_at(THD *thd)
{
- my_bool not_used;
+ uint not_used;
MYSQL_TIME ltime;
my_time_t ltime_utc;
@@ -217,7 +217,7 @@ Event_parse_data::init_execute_at(THD *thd)
(starts_null && ends_null)));
DBUG_ASSERT(starts_null && ends_null);
- if ((not_used= item_execute_at->get_date(&ltime, TIME_NO_ZERO_DATE)))
+ if (item_execute_at->get_date(&ltime, TIME_NO_ZERO_DATE))
goto wrong_value;
ltime_utc= TIME_to_timestamp(thd,&ltime,&not_used);
@@ -370,7 +370,7 @@ wrong_value:
int
Event_parse_data::init_starts(THD *thd)
{
- my_bool not_used;
+ uint not_used;
MYSQL_TIME ltime;
my_time_t ltime_utc;
@@ -381,7 +381,7 @@ Event_parse_data::init_starts(THD *thd)
if (item_starts->fix_fields(thd, &item_starts))
goto wrong_value;
- if ((not_used= item_starts->get_date(&ltime, TIME_NO_ZERO_DATE)))
+ if (item_starts->get_date(&ltime, TIME_NO_ZERO_DATE))
goto wrong_value;
ltime_utc= TIME_to_timestamp(thd, &ltime, &not_used);
@@ -424,7 +424,7 @@ wrong_value:
int
Event_parse_data::init_ends(THD *thd)
{
- my_bool not_used;
+ uint not_used;
MYSQL_TIME ltime;
my_time_t ltime_utc;
@@ -436,7 +436,7 @@ Event_parse_data::init_ends(THD *thd)
goto error_bad_params;
DBUG_PRINT("info", ("convert to TIME"));
- if ((not_used= item_ends->get_date(&ltime, TIME_NO_ZERO_DATE)))
+ if (item_ends->get_date(&ltime, TIME_NO_ZERO_DATE))
goto error_bad_params;
ltime_utc= TIME_to_timestamp(thd, &ltime, &not_used);
diff --git a/sql/event_queue.cc b/sql/event_queue.cc
index b9585dc9c51..6016048aa9c 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;
@@ -518,14 +530,17 @@ Event_queue::empty_queue()
*/
void
-Event_queue::dbug_dump_queue(time_t now)
+Event_queue::dbug_dump_queue(my_time_t when)
{
#ifndef DBUG_OFF
+ my_time_t now= when;
Event_queue_element *et;
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 +607,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 */
@@ -604,9 +619,9 @@ Event_queue::get_top_for_execution_if_time(THD *thd,
time or until signaled. Release LOCK_queue while waiting.
*/
struct timespec top_time;
- set_timespec(top_time, next_activation_at - thd->query_start());
- cond_wait(thd, &top_time, queue_wait_msg, SCHED_FUNC, __LINE__);
+ set_timespec_time_nsec(top_time, next_activation_at*1000000000ULL);
+ cond_wait(thd, &top_time, queue_wait_msg, SCHED_FUNC, __LINE__);
continue;
}
@@ -634,10 +649,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_queue.h b/sql/event_queue.h
index 2870ecb4d0b..e1f814adf20 100644
--- a/sql/event_queue.h
+++ b/sql/event_queue.h
@@ -98,7 +98,7 @@ private:
void
- dbug_dump_queue(time_t now);
+ dbug_dump_queue(my_time_t now);
/* LOCK_event_queue is the mutex which protects the access to the queue. */
pthread_mutex_t LOCK_event_queue;
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index 374a3620b67..a14700000da 100755..100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -645,7 +645,7 @@ Event_scheduler::stop()
sql_print_information("Event Scheduler: Killing the scheduler thread, "
"thread id %lu",
scheduler_thd->thread_id);
- scheduler_thd->awake(THD::KILL_CONNECTION);
+ scheduler_thd->awake(KILL_CONNECTION);
pthread_mutex_unlock(&scheduler_thd->LOCK_thd_kill);
/* thd could be 0x0, when shutting down */
diff --git a/sql/field.cc b/sql/field.cc
index e9c6065287f..fa8ed5fdda9 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -49,6 +49,17 @@ template class List<Create_field>;
template class List_iterator<Create_field>;
#endif
+static const char *zero_timestamp="0000-00-00 00:00:00.000000";
+
+/* number of bytes to store second_part part of the TIMESTAMP(N) */
+static uint sec_part_bytes[MAX_DATETIME_PRECISION+1]= { 0, 1, 1, 2, 2, 3, 3 };
+
+/* number of bytes to store DATETIME(N) */
+static uint datetime_hires_bytes[MAX_DATETIME_PRECISION+1]= { 5, 6, 6, 7, 7, 7, 8 };
+
+/* number of bytes to store TIME(N) */
+static uint time_hires_bytes[MAX_DATETIME_PRECISION+1]= { 3, 4, 4, 5, 5, 5, 6 };
+
uchar Field_null::null[1]={1};
const char field_separator=',';
@@ -71,7 +82,7 @@ const char field_separator=',';
#define FIELDTYPE_TEAR_FROM (MYSQL_TYPE_BIT + 1)
#define FIELDTYPE_TEAR_TO (MYSQL_TYPE_NEWDECIMAL - 1)
#define FIELDTYPE_NUM (FIELDTYPE_TEAR_FROM + (255 - FIELDTYPE_TEAR_TO))
-inline int field_type2index (enum_field_types field_type)
+static inline int field_type2index (enum_field_types field_type)
{
return (field_type < FIELDTYPE_TEAR_FROM ?
field_type :
@@ -1051,6 +1062,21 @@ bool Field::type_can_have_key_part(enum enum_field_types type)
}
+void Field::make_sort_key(uchar *buff,uint length)
+{
+ if (maybe_null())
+ {
+ if (is_null())
+ {
+ bzero(buff, length + 1);
+ return;
+ }
+ *buff++= 1;
+ }
+ sort_string(buff, length);
+}
+
+
/**
Numeric fields base class constructor.
*/
@@ -1410,13 +1436,6 @@ int Field::store(const char *to, uint length, CHARSET_INFO *cs,
should be overridden. The other functions are just convenience
functions and hence should not be overridden.
- The value of <code>low_byte_first</code> is dependent on how the
- packed data is going to be used: for local use, e.g., temporary
- store on disk or in memory, use the native format since that is
- faster. For data that is going to be transfered to other machines
- (e.g., when writing data to the binary log), data should always be
- stored in little-endian format.
-
@note The default method for packing fields just copy the raw bytes
of the record into the destination, but never more than
<code>max_length</code> characters.
@@ -1434,15 +1453,9 @@ int Field::store(const char *to, uint length, CHARSET_INFO *cs,
is 1000. This information is sometimes needed to decide how to pack
the data.
- @param low_byte_first
- @c TRUE if integers should be stored little-endian, @c FALSE if
- native format should be used. Note that for little-endian machines,
- the value of this flag is a moot point since the native format is
- little-endian.
*/
uchar *
-Field::pack(uchar *to, const uchar *from, uint max_length,
- bool low_byte_first __attribute__((unused)))
+Field::pack(uchar *to, const uchar *from, uint max_length)
{
uint32 length= pack_length();
set_if_smaller(length, max_length);
@@ -1473,18 +1486,14 @@ Field::pack(uchar *to, const uchar *from, uint max_length,
@param param_data Real type and original pack length of the field
data
- @param low_byte_first
- If this flag is @c true, all composite entities (e.g., lengths)
- should be unpacked in little-endian format; otherwise, the entities
- are unpacked in native order.
-
@return New pointer into memory based on from + length of the data
+ @return 0 if wrong data
*/
const uchar *
-Field::unpack(uchar* to, const uchar *from, uint param_data,
- bool low_byte_first __attribute__((unused)))
+Field::unpack(uchar* to, const uchar *from, const uchar *from_end,
+ uint param_data)
{
- uint length=pack_length();
+ uint length=pack_length(), len;
int from_type= 0;
/*
If from length is > 255, it has encoded data in the upper bits. Need
@@ -1500,14 +1509,19 @@ Field::unpack(uchar* to, const uchar *from, uint param_data,
(length == param_data) ||
(from_type != real_type()))
{
+ if (from + length > from_end)
+ return 0; // Error in data
+
memcpy(to, from, length);
return from+length;
}
- uint len= (param_data && (param_data < length)) ?
- param_data : length;
+ len= (param_data && (param_data < length)) ? param_data : length;
- memcpy(to, from, param_data > length ? length : len);
+ if (from + len > from_end)
+ return 0; // Error in data
+
+ memcpy(to, from, len);
return from+len;
}
@@ -1580,17 +1594,19 @@ longlong Field::convert_decimal2longlong(const my_decimal *val,
i= 0;
*err= 1;
}
- else if (warn_if_overflow(my_decimal2int(E_DEC_ERROR &
- ~E_DEC_OVERFLOW & ~E_DEC_TRUNCATED,
- val, TRUE, &i)))
+ else if (warn_if_overflow(my_decimal2int((E_DEC_ERROR &
+ ~E_DEC_OVERFLOW &
+ ~E_DEC_TRUNCATED),
+ val, TRUE, &i)))
{
i= ~(longlong) 0;
*err= 1;
}
}
- else if (warn_if_overflow(my_decimal2int(E_DEC_ERROR &
- ~E_DEC_OVERFLOW & ~E_DEC_TRUNCATED,
- val, FALSE, &i)))
+ else if (warn_if_overflow(my_decimal2int((E_DEC_ERROR &
+ ~E_DEC_OVERFLOW &
+ ~E_DEC_TRUNCATED),
+ val, FALSE, &i)))
{
i= (val->sign() ? LONGLONG_MIN : LONGLONG_MAX);
*err= 1;
@@ -1708,8 +1724,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)
{
@@ -1721,9 +1737,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;
@@ -1744,16 +1766,6 @@ bool Field::get_date(MYSQL_TIME *ltime,uint fuzzydate)
return 0;
}
-bool Field::get_time(MYSQL_TIME *ltime)
-{
- char buff[40];
- String tmp(buff,sizeof(buff),&my_charset_bin),*res;
- if (!(res=val_str(&tmp)) ||
- str_to_time_with_warn(res->ptr(), res->length(), ltime))
- return 1;
- return 0;
-}
-
/**
This is called when storing a date in a string.
@@ -1761,11 +1773,11 @@ bool Field::get_time(MYSQL_TIME *ltime)
Needs to be changed if/when we want to support different time formats.
*/
-int Field::store_time(MYSQL_TIME *ltime, timestamp_type type_arg)
+int Field::store_time_dec(MYSQL_TIME *ltime, uint dec)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
char buff[MAX_DATE_STRING_REP_LENGTH];
- uint length= (uint) my_TIME_to_str(ltime, buff);
+ uint length= (uint) my_TIME_to_str(ltime, buff, dec);
return store(buff, length, &my_charset_bin);
}
@@ -2755,10 +2767,10 @@ int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
}
-int Field_new_decimal::store_time(MYSQL_TIME *ltime, timestamp_type t_type)
+int Field_new_decimal::store_time_dec(MYSQL_TIME *ltime, uint dec)
{
- my_decimal decimal_value;
- return store_value(date2my_decimal(ltime, &decimal_value));
+ my_decimal decimal_value;
+ return store_value(date2my_decimal(ltime, &decimal_value));
}
@@ -2926,13 +2938,11 @@ uint Field_new_decimal::is_equal(Create_field *new_field)
@return New pointer into memory based on from + length of the data
*/
const uchar *
-Field_new_decimal::unpack(uchar* to,
- const uchar *from,
- uint param_data,
- bool low_byte_first)
+Field_new_decimal::unpack(uchar* to, const uchar *from, const uchar *from_end,
+ uint param_data)
{
if (param_data == 0)
- return Field::unpack(to, from, param_data, low_byte_first);
+ return Field::unpack(to, from, from_end, param_data);
uint from_precision= (param_data & 0xff00) >> 8U;
uint from_decimal= param_data & 0x00ff;
@@ -2962,10 +2972,23 @@ Field_new_decimal::unpack(uchar* to,
decimal2bin(&dec_val, to, precision, decimals());
}
else
+ {
+ if (from + len > from_end)
+ return 0; // Wrong data
memcpy(to, from, len); // Sizes are the same, just copy the data.
+ }
return from+len;
}
+int Field_num::store_time_dec(MYSQL_TIME *ltime, uint dec)
+{
+ longlong v= TIME_to_ulonglong(ltime);
+ if (ltime->neg == 0)
+ return store(v, true);
+ return store(-v, false);
+}
+
+
/****************************************************************************
** tiny int
****************************************************************************/
@@ -3154,14 +3177,7 @@ int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
error= get_int(cs, from, len, &rnd, UINT_MAX16, INT_MIN16, INT_MAX16);
store_tmp= unsigned_flag ? (int) (ulonglong) rnd : (int) rnd;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int2store(ptr, store_tmp);
- }
- else
-#endif
- shortstore(ptr, (short) store_tmp);
+ int2store(ptr, store_tmp);
return error;
}
@@ -3206,14 +3222,7 @@ int Field_short::store(double nr)
else
res=(int16) (int) nr;
}
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int2store(ptr,res);
- }
- else
-#endif
- shortstore(ptr,res);
+ int2store(ptr,res);
return error;
}
@@ -3261,14 +3270,7 @@ int Field_short::store(longlong nr, bool unsigned_val)
else
res=(int16) nr;
}
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int2store(ptr,res);
- }
- else
-#endif
- shortstore(ptr,res);
+ int2store(ptr,res);
return error;
}
@@ -3277,12 +3279,7 @@ double Field_short::val_real(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
short j;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- j=sint2korr(ptr);
- else
-#endif
- shortget(j,ptr);
+ j=sint2korr(ptr);
return unsigned_flag ? (double) (unsigned short) j : (double) j;
}
@@ -3290,12 +3287,7 @@ longlong Field_short::val_int(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
short j;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- j=sint2korr(ptr);
- else
-#endif
- shortget(j,ptr);
+ j=sint2korr(ptr);
return unsigned_flag ? (longlong) (unsigned short) j : (longlong) j;
}
@@ -3310,12 +3302,7 @@ String *Field_short::val_str(String *val_buffer,
val_buffer->alloc(mlength);
char *to=(char*) val_buffer->ptr();
short j;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- j=sint2korr(ptr);
- else
-#endif
- shortget(j,ptr);
+ j=sint2korr(ptr);
if (unsigned_flag)
length=(uint) cs->cset->long10_to_str(cs, to, mlength, 10,
@@ -3338,18 +3325,8 @@ bool Field_short::send_binary(Protocol *protocol)
int Field_short::cmp(const uchar *a_ptr, const uchar *b_ptr)
{
short a,b;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- a=sint2korr(a_ptr);
- b=sint2korr(b_ptr);
- }
- else
-#endif
- {
- shortget(a,a_ptr);
- shortget(b,b_ptr);
- }
+ a=sint2korr(a_ptr);
+ b=sint2korr(b_ptr);
if (unsigned_flag)
return ((unsigned short) a < (unsigned short) b) ? -1 :
@@ -3359,24 +3336,11 @@ int Field_short::cmp(const uchar *a_ptr, const uchar *b_ptr)
void Field_short::sort_string(uchar *to,uint length __attribute__((unused)))
{
-#ifdef WORDS_BIGENDIAN
- if (!table->s->db_low_byte_first)
- {
- if (unsigned_flag)
- to[0] = ptr[0];
- else
- to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */
- to[1] = ptr[1];
- }
+ if (unsigned_flag)
+ to[0] = ptr[1];
else
-#endif
- {
- if (unsigned_flag)
- to[0] = ptr[1];
- else
- to[0] = (char) (ptr[1] ^ 128); /* Revers signbit */
- to[1] = ptr[0];
- }
+ to[0] = (char) (ptr[1] ^ 128); /* Revers signbit */
+ to[1] = ptr[0];
}
void Field_short::sql_type(String &res) const
@@ -3591,14 +3555,7 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
error= get_int(cs, from, len, &rnd, UINT_MAX32, INT_MIN32, INT_MAX32);
store_tmp= unsigned_flag ? (long) (ulonglong) rnd : (long) rnd;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int4store(ptr, store_tmp);
- }
- else
-#endif
- longstore(ptr, store_tmp);
+ int4store(ptr, store_tmp);
return error;
}
@@ -3643,14 +3600,7 @@ int Field_long::store(double nr)
if (error)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int4store(ptr,res);
- }
- else
-#endif
- longstore(ptr,res);
+ int4store(ptr,res);
return error;
}
@@ -3696,14 +3646,7 @@ int Field_long::store(longlong nr, bool unsigned_val)
if (error)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int4store(ptr,res);
- }
- else
-#endif
- longstore(ptr,res);
+ int4store(ptr,res);
return error;
}
@@ -3712,12 +3655,7 @@ double Field_long::val_real(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
int32 j;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- j=sint4korr(ptr);
- else
-#endif
- longget(j,ptr);
+ j=sint4korr(ptr);
return unsigned_flag ? (double) (uint32) j : (double) j;
}
@@ -3727,12 +3665,7 @@ longlong Field_long::val_int(void)
int32 j;
/* See the comment in Field_long::store(long long) */
DBUG_ASSERT(table->in_use == current_thd);
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- j=sint4korr(ptr);
- else
-#endif
- longget(j,ptr);
+ j=sint4korr(ptr);
return unsigned_flag ? (longlong) (uint32) j : (longlong) j;
}
@@ -3746,12 +3679,7 @@ String *Field_long::val_str(String *val_buffer,
val_buffer->alloc(mlength);
char *to=(char*) val_buffer->ptr();
int32 j;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- j=sint4korr(ptr);
- else
-#endif
- longget(j,ptr);
+ j=sint4korr(ptr);
if (unsigned_flag)
length=cs->cset->long10_to_str(cs,to,mlength, 10,(long) (uint32)j);
@@ -3773,18 +3701,8 @@ bool Field_long::send_binary(Protocol *protocol)
int Field_long::cmp(const uchar *a_ptr, const uchar *b_ptr)
{
int32 a,b;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- a=sint4korr(a_ptr);
- b=sint4korr(b_ptr);
- }
- else
-#endif
- {
- longget(a,a_ptr);
- longget(b,b_ptr);
- }
+ a=sint4korr(a_ptr);
+ b=sint4korr(b_ptr);
if (unsigned_flag)
return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0;
return (a < b) ? -1 : (a > b) ? 1 : 0;
@@ -3792,28 +3710,13 @@ int Field_long::cmp(const uchar *a_ptr, const uchar *b_ptr)
void Field_long::sort_string(uchar *to,uint length __attribute__((unused)))
{
-#ifdef WORDS_BIGENDIAN
- if (!table->s->db_low_byte_first)
- {
- if (unsigned_flag)
- to[0] = ptr[0];
- else
- to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */
- to[1] = ptr[1];
- to[2] = ptr[2];
- to[3] = ptr[3];
- }
+ if (unsigned_flag)
+ to[0] = ptr[3];
else
-#endif
- {
- if (unsigned_flag)
- to[0] = ptr[3];
- else
- to[0] = (char) (ptr[3] ^ 128); /* Revers signbit */
- to[1] = ptr[2];
- to[2] = ptr[1];
- to[3] = ptr[0];
- }
+ to[0] = (char) (ptr[3] ^ 128); /* Revers signbit */
+ to[1] = ptr[2];
+ to[2] = ptr[1];
+ to[3] = ptr[0];
}
@@ -3847,14 +3750,7 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
error= 1;
else
error= 0;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int8store(ptr,tmp);
- }
- else
-#endif
- longlongstore(ptr,tmp);
+ int8store(ptr,tmp);
return error;
}
@@ -3862,51 +3758,15 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
int Field_longlong::store(double nr)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- int error= 0;
+ bool error;
longlong res;
- nr= rint(nr);
- if (unsigned_flag)
- {
- if (nr < 0)
- {
- res=0;
- error= 1;
- }
- else if (nr >= (double) ULONGLONG_MAX)
- {
- res= ~(longlong) 0;
- error= 1;
- }
- else
- res=(longlong) double2ulonglong(nr);
- }
- else
- {
- if (nr <= (double) LONGLONG_MIN)
- {
- res= LONGLONG_MIN;
- error= (nr < (double) LONGLONG_MIN);
- }
- else if (nr >= (double) (ulonglong) LONGLONG_MAX)
- {
- res= LONGLONG_MAX;
- error= (nr > (double) LONGLONG_MAX);
- }
- else
- res=(longlong) nr;
- }
+ res= double_to_longlong(nr, unsigned_flag, &error);
+
if (error)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int8store(ptr,res);
- }
- else
-#endif
- longlongstore(ptr,res);
+ int8store(ptr,res);
return error;
}
@@ -3930,14 +3790,7 @@ int Field_longlong::store(longlong nr, bool unsigned_val)
}
}
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int8store(ptr,nr);
- }
- else
-#endif
- longlongstore(ptr,nr);
+ int8store(ptr,nr);
return error;
}
@@ -3946,14 +3799,7 @@ double Field_longlong::val_real(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
longlong j;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- j=sint8korr(ptr);
- }
- else
-#endif
- longlongget(j,ptr);
+ j=sint8korr(ptr);
/* The following is open coded to avoid a bug in gcc 3.3 */
if (unsigned_flag)
{
@@ -3968,12 +3814,7 @@ longlong Field_longlong::val_int(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
longlong j;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- j=sint8korr(ptr);
- else
-#endif
- longlongget(j,ptr);
+ j=sint8korr(ptr);
return j;
}
@@ -3987,12 +3828,7 @@ String *Field_longlong::val_str(String *val_buffer,
val_buffer->alloc(mlength);
char *to=(char*) val_buffer->ptr();
longlong j;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- j=sint8korr(ptr);
- else
-#endif
- longlongget(j,ptr);
+ j=sint8korr(ptr);
length=(uint) (cs->cset->longlong10_to_str)(cs,to,mlength,
unsigned_flag ? 10 : -10, j);
@@ -4013,18 +3849,8 @@ bool Field_longlong::send_binary(Protocol *protocol)
int Field_longlong::cmp(const uchar *a_ptr, const uchar *b_ptr)
{
longlong a,b;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- a=sint8korr(a_ptr);
- b=sint8korr(b_ptr);
- }
- else
-#endif
- {
- longlongget(a,a_ptr);
- longlongget(b,b_ptr);
- }
+ a=sint8korr(a_ptr);
+ b=sint8korr(b_ptr);
if (unsigned_flag)
return ((ulonglong) a < (ulonglong) b) ? -1 :
((ulonglong) a > (ulonglong) b) ? 1 : 0;
@@ -4033,36 +3859,17 @@ int Field_longlong::cmp(const uchar *a_ptr, const uchar *b_ptr)
void Field_longlong::sort_string(uchar *to,uint length __attribute__((unused)))
{
-#ifdef WORDS_BIGENDIAN
- if (!table->s->db_low_byte_first)
- {
- if (unsigned_flag)
- to[0] = ptr[0];
- else
- to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */
- to[1] = ptr[1];
- to[2] = ptr[2];
- to[3] = ptr[3];
- to[4] = ptr[4];
- to[5] = ptr[5];
- to[6] = ptr[6];
- to[7] = ptr[7];
- }
+ if (unsigned_flag)
+ to[0] = ptr[7];
else
-#endif
- {
- if (unsigned_flag)
- to[0] = ptr[7];
- else
- to[0] = (char) (ptr[7] ^ 128); /* Revers signbit */
- to[1] = ptr[6];
- to[2] = ptr[5];
- to[3] = ptr[4];
- to[4] = ptr[3];
- to[5] = ptr[2];
- to[6] = ptr[1];
- to[7] = ptr[0];
- }
+ to[0] = (char) (ptr[7] ^ 128); /* Revers signbit */
+ to[1] = ptr[6];
+ to[2] = ptr[5];
+ to[3] = ptr[4];
+ to[4] = ptr[3];
+ to[5] = ptr[2];
+ to[6] = ptr[1];
+ to[7] = ptr[0];
}
@@ -4079,43 +3886,6 @@ void Field_longlong::sql_type(String &res) const
Floating-point numbers
*/
-uchar *
-Field_real::pack(uchar *to, const uchar *from,
- uint max_length, bool low_byte_first)
-{
- DBUG_ENTER("Field_real::pack");
- DBUG_ASSERT(max_length >= pack_length());
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first != table->s->db_low_byte_first)
- {
- const uchar *dptr= from + pack_length();
- while (dptr-- > from)
- *to++ = *dptr;
- DBUG_RETURN(to);
- }
- else
-#endif
- DBUG_RETURN(Field::pack(to, from, max_length, low_byte_first));
-}
-
-const uchar *
-Field_real::unpack(uchar *to, const uchar *from,
- uint param_data, bool low_byte_first)
-{
- DBUG_ENTER("Field_real::unpack");
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first != table->s->db_low_byte_first)
- {
- const uchar *dptr= from + pack_length();
- while (dptr-- > from)
- *to++ = *dptr;
- DBUG_RETURN(from + pack_length());
- }
- else
-#endif
- DBUG_RETURN(Field::unpack(to, from, param_data, low_byte_first));
-}
-
/****************************************************************************
single precision float
****************************************************************************/
@@ -4140,17 +3910,21 @@ int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
int Field_float::store(double nr)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- int error= truncate(&nr, FLT_MAX);
- float j= (float)nr;
-
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
+ int error= truncate_double(&nr, field_length,
+ not_fixed ? NOT_FIXED_DEC : dec,
+ unsigned_flag, FLT_MAX);
+ if (error)
{
- float4store(ptr,j);
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ if (error < 0) // Wrong double value
+ {
+ error= 1;
+ set_null();
+ }
}
- else
-#endif
- memcpy_fixed(ptr,(uchar*) &j,sizeof(j));
+ float j= (float)nr;
+
+ float4store(ptr,j);
return error;
}
@@ -4166,28 +3940,14 @@ double Field_float::val_real(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
float j;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- float4get(j,ptr);
- }
- else
-#endif
- memcpy_fixed((uchar*) &j,ptr,sizeof(j));
+ float4get(j,ptr);
return ((double) j);
}
longlong Field_float::val_int(void)
{
float j;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- float4get(j,ptr);
- }
- else
-#endif
- memcpy_fixed((uchar*) &j,ptr,sizeof(j));
+ float4get(j,ptr);
return (longlong) rint(j);
}
@@ -4197,14 +3957,7 @@ String *Field_float::val_str(String *val_buffer,
{
ASSERT_COLUMN_MARKED_FOR_READ;
float nr;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- float4get(nr,ptr);
- }
- else
-#endif
- memcpy_fixed((uchar*) &nr,ptr,sizeof(nr));
+ float4get(nr,ptr);
uint to_length=max(field_length,70);
val_buffer->alloc(to_length);
@@ -4279,18 +4032,8 @@ String *Field_float::val_str(String *val_buffer,
int Field_float::cmp(const uchar *a_ptr, const uchar *b_ptr)
{
float a,b;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- float4get(a,a_ptr);
- float4get(b,b_ptr);
- }
- else
-#endif
- {
- memcpy_fixed(&a,a_ptr,sizeof(float));
- memcpy_fixed(&b,b_ptr,sizeof(float));
- }
+ float4get(a,a_ptr);
+ float4get(b,b_ptr);
return (a < b) ? -1 : (a > b) ? 1 : 0;
}
@@ -4299,14 +4042,7 @@ int Field_float::cmp(const uchar *a_ptr, const uchar *b_ptr)
void Field_float::sort_string(uchar *to,uint length __attribute__((unused)))
{
float nr;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- float4get(nr,ptr);
- }
- else
-#endif
- memcpy_fixed(&nr,ptr,sizeof(float));
+ float4get(nr,ptr);
uchar *tmp= to;
if (nr == (float) 0.0)
@@ -4402,16 +4138,20 @@ int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
int Field_double::store(double nr)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- int error= truncate(&nr, DBL_MAX);
-
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
+ int error= truncate_double(&nr, field_length,
+ not_fixed ? NOT_FIXED_DEC : dec,
+ unsigned_flag, DBL_MAX);
+ if (error)
{
- float8store(ptr,nr);
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ if (error < 0) // Wrong double value
+ {
+ error= 1;
+ set_null();
+ }
}
- else
-#endif
- doublestore(ptr,nr);
+
+ float8store(ptr,nr);
return error;
}
@@ -4426,28 +4166,31 @@ int Field_double::store(longlong nr, bool unsigned_val)
If a field has fixed length, truncate the double argument pointed to by 'nr'
appropriately.
Also ensure that the argument is within [-max_value; max_value] range.
+
+ return
+ 0 ok
+ -1 Illegal double value
+ 1 Value was truncated
*/
-int Field_real::truncate(double *nr, double max_value)
+int truncate_double(double *nr, uint field_length, uint dec,
+ bool unsigned_flag, double max_value)
{
- int error= 1;
+ int error= 0;
double res= *nr;
if (isnan(res))
{
- res= 0;
- set_null();
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- goto end;
+ *nr= 0;
+ return -1;
}
else if (unsigned_flag && res < 0)
{
- res= 0;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- goto end;
+ *nr= 0;
+ return 1;
}
- if (!not_fixed)
+ if (dec < NOT_FIXED_DEC)
{
uint order= field_length - dec;
uint step= array_elements(log_10) - 1;
@@ -4463,22 +4206,70 @@ int Field_real::truncate(double *nr, double max_value)
if (res < -max_value)
{
- res= -max_value;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ res= -max_value;
+ error= 1;
}
else if (res > max_value)
{
res= max_value;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ error= 1;
}
- else
- error= 0;
-end:
*nr= res;
return error;
}
+/*
+ Convert double to longlong / ulonglong.
+ If double is outside of range, adjust return value and set error.
+
+ SYNOPSIS
+ double_to_longlong()
+ nr Number to convert
+ unsigned_flag 1 if result is unsigned
+ error Will be set to 1 in case of overflow.
+*/
+
+longlong double_to_longlong(double nr, bool unsigned_flag, bool *error)
+{
+ longlong res;
+
+ *error= 0;
+
+ nr= rint(nr);
+ if (unsigned_flag)
+ {
+ if (nr < 0)
+ {
+ res= 0;
+ *error= 1;
+ }
+ else if (nr >= (double) ULONGLONG_MAX)
+ {
+ res= ~(longlong) 0;
+ *error= 1;
+ }
+ else
+ res= (longlong) double2ulonglong(nr);
+ }
+ else
+ {
+ if (nr <= (double) LONGLONG_MIN)
+ {
+ res= LONGLONG_MIN;
+ *error= (nr < (double) LONGLONG_MIN);
+ }
+ else if (nr >= (double) (ulonglong) LONGLONG_MAX)
+ {
+ res= LONGLONG_MAX;
+ *error= (nr > (double) LONGLONG_MAX);
+ }
+ else
+ res= (longlong) nr;
+ }
+ return res;
+}
+
int Field_real::store_decimal(const my_decimal *dm)
{
@@ -4487,18 +4278,17 @@ int Field_real::store_decimal(const my_decimal *dm)
return store(dbl);
}
+int Field_real::store_time_dec(MYSQL_TIME *ltime, uint dec)
+{
+ return store(TIME_to_double(ltime));
+}
+
+
double Field_double::val_real(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
double j;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- float8get(j,ptr);
- }
- else
-#endif
- doubleget(j,ptr);
+ float8get(j,ptr);
return j;
}
@@ -4507,28 +4297,11 @@ longlong Field_double::val_int(void)
ASSERT_COLUMN_MARKED_FOR_READ;
double j;
longlong res;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- float8get(j,ptr);
- }
- else
-#endif
- doubleget(j,ptr);
- /* Check whether we fit into longlong range */
- if (j <= (double) LONGLONG_MIN)
- {
- res= (longlong) LONGLONG_MIN;
- goto warn;
- }
- if (j >= (double) (ulonglong) LONGLONG_MAX)
- {
- res= (longlong) LONGLONG_MAX;
- goto warn;
- }
- return (longlong) rint(j);
+ bool error;
+ float8get(j,ptr);
-warn:
+ res= double_to_longlong(j, 0, &error);
+ if (error)
{
char buf[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
String tmp(buf, sizeof(buf), &my_charset_latin1), *str;
@@ -4550,19 +4323,20 @@ my_decimal *Field_real::val_decimal(my_decimal *decimal_value)
}
+bool Field_real::get_date(MYSQL_TIME *ltime,uint fuzzydate)
+{
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ double nr= val_real();
+ return double_to_datetime_with_warn(nr, ltime, fuzzydate, field_name);
+}
+
+
String *Field_double::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
ASSERT_COLUMN_MARKED_FOR_READ;
double nr;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- float8get(nr,ptr);
- }
- else
-#endif
- doubleget(nr,ptr);
+ float8get(nr,ptr);
uint to_length= DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE;
val_buffer->alloc(to_length);
@@ -4643,18 +4417,8 @@ bool Field_double::send_binary(Protocol *protocol)
int Field_double::cmp(const uchar *a_ptr, const uchar *b_ptr)
{
double a,b;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- float8get(a,a_ptr);
- float8get(b,b_ptr);
- }
- else
-#endif
- {
- doubleget(a, a_ptr);
- doubleget(b, b_ptr);
- }
+ float8get(a,a_ptr);
+ float8get(b,b_ptr);
return (a < b) ? -1 : (a > b) ? 1 : 0;
}
@@ -4666,14 +4430,7 @@ int Field_double::cmp(const uchar *a_ptr, const uchar *b_ptr)
void Field_double::sort_string(uchar *to,uint length __attribute__((unused)))
{
double nr;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- float8get(nr,ptr);
- }
- else
-#endif
- doubleget(nr,ptr);
+ float8get(nr,ptr);
change_double_for_sort(nr, to);
}
@@ -4761,12 +4518,12 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg,
const char *field_name_arg,
TABLE_SHARE *share,
CHARSET_INFO *cs)
- :Field_str(ptr_arg, MAX_DATETIME_WIDTH, null_ptr_arg, null_bit_arg,
+ :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, cs)
{
/* For 4.0 MYD and 4.0 InnoDB compatibility */
- flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
- if (!share->timestamp_field && unireg_check != NONE)
+ flags|= UNSIGNED_FLAG;
+ if (unireg_check != NONE && !share->timestamp_field)
{
/* This timestamp has auto-update */
share->timestamp_field= this;
@@ -4777,20 +4534,6 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg,
}
-Field_timestamp::Field_timestamp(bool maybe_null_arg,
- const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str((uchar*) 0, MAX_DATETIME_WIDTH,
- maybe_null_arg ? (uchar*) "": 0, 0,
- NONE, field_name_arg, cs)
-{
- /* For 4.0 MYD and 4.0 InnoDB compatibility */
- flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
- if (unireg_check != TIMESTAMP_DN_FIELD)
- flags|= ON_UPDATE_NOW_FLAG;
-}
-
-
/**
Get auto-set type for TIMESTAMP field.
@@ -4825,136 +4568,135 @@ timestamp_auto_set_type Field_timestamp::get_auto_set_type() const
}
}
+my_time_t Field_timestamp::get_timestamp(ulong *sec_part) const
+{
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ *sec_part= 0;
+ return sint4korr(ptr);
+}
-int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
+int Field_timestamp::store_TIME_with_warning(THD *thd, MYSQL_TIME *l_time,
+ const Lazy_string *str,
+ bool was_cut,
+ bool have_smth_to_conv)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- MYSQL_TIME l_time;
- my_time_t tmp= 0;
- int error;
- bool have_smth_to_conv;
- my_bool in_dst_time_gap;
- THD *thd= table ? table->in_use : current_thd;
-
- /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
- have_smth_to_conv= (str_to_datetime(from, len, &l_time,
- (thd->variables.sql_mode &
- MODE_NO_ZERO_DATE) |
- MODE_NO_ZERO_IN_DATE, &error) >
- MYSQL_TIMESTAMP_ERROR);
+ uint error = 0;
+ my_time_t timestamp;
- if (error || !have_smth_to_conv)
+ if (was_cut || !have_smth_to_conv)
{
error= 1;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
- from, len, MYSQL_TIMESTAMP_DATETIME, 1);
+ str, MYSQL_TIMESTAMP_DATETIME, 1);
}
-
/* Only convert a correct date (not a zero date) */
- if (have_smth_to_conv && l_time.month)
+ if (have_smth_to_conv && l_time->month)
{
- if (!(tmp= TIME_to_timestamp(thd, &l_time, &in_dst_time_gap)))
+ uint conversion_error;
+ timestamp= TIME_to_timestamp(thd, l_time, &conversion_error);
+ if (timestamp == 0 && l_time->second_part == 0)
+ conversion_error= ER_WARN_DATA_OUT_OF_RANGE;
+ if (conversion_error)
{
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE,
- from, len, MYSQL_TIMESTAMP_DATETIME, !error);
- error= 1;
- }
- else if (in_dst_time_gap)
- {
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_INVALID_TIMESTAMP,
- from, len, MYSQL_TIMESTAMP_DATETIME, !error);
+ set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, conversion_error,
+ str, MYSQL_TIMESTAMP_DATETIME, !error);
error= 1;
}
}
- store_timestamp(tmp);
+ else
+ {
+ timestamp= 0;
+ l_time->second_part= 0;
+ }
+ store_TIME(timestamp, l_time->second_part);
return error;
}
-int Field_timestamp::store(double nr)
+int Field_timestamp::store_time_dec(MYSQL_TIME *ltime, uint dec)
{
- int error= 0;
- if (nr < 0 || nr > 99991231235959.0)
- {
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE,
- nr, MYSQL_TIMESTAMP_DATETIME);
- nr= 0; // Avoid overflow on buff
- error= 1;
- }
- error|= Field_timestamp::store((longlong) rint(nr), FALSE);
- return error;
+ THD *thd= table->in_use;
+ int unused;
+ MYSQL_TIME l_time= *ltime;
+ Lazy_string_time str(ltime);
+ bool valid= !check_date(&l_time, pack_time(&l_time) != 0,
+ (thd->variables.sql_mode & MODE_NO_ZERO_DATE) |
+ MODE_NO_ZERO_IN_DATE, &unused);
+
+ return store_TIME_with_warning(thd, &l_time, &str, false, valid);
}
-int Field_timestamp::store(longlong nr, bool unsigned_val)
+int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
{
- ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
MYSQL_TIME l_time;
- my_time_t timestamp= 0;
int error;
- my_bool in_dst_time_gap;
- THD *thd= table ? table->in_use : current_thd;
+ int have_smth_to_conv;
+ Lazy_string_str str(from, len);
+ THD *thd= table->in_use;
/* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
- longlong tmp= number_to_datetime(nr, &l_time, (thd->variables.sql_mode &
+ have_smth_to_conv= (str_to_datetime(from, len, &l_time,
+ (thd->variables.sql_mode &
+ MODE_NO_ZERO_DATE) |
+ MODE_NO_ZERO_IN_DATE, &error) >
+ MYSQL_TIMESTAMP_ERROR);
+ return store_TIME_with_warning(thd, &l_time, &str, error, have_smth_to_conv);
+}
+
+
+int Field_timestamp::store(double nr)
+{
+ MYSQL_TIME l_time;
+ int error;
+ Lazy_string_double str(nr);
+ THD *thd= table->in_use;
+
+ longlong tmp= double_to_datetime(nr, &l_time, (thd->variables.sql_mode &
MODE_NO_ZERO_DATE) |
MODE_NO_ZERO_IN_DATE, &error);
- if (tmp == LL(-1))
- {
- error= 2;
- }
+ return store_TIME_with_warning(thd, &l_time, &str, error, tmp != -1);
+}
- if (!error && tmp)
- {
- if (!(timestamp= TIME_to_timestamp(thd, &l_time, &in_dst_time_gap)))
- {
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE,
- nr, MYSQL_TIMESTAMP_DATETIME, 1);
- error= 1;
- }
- if (in_dst_time_gap)
- {
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_INVALID_TIMESTAMP,
- nr, MYSQL_TIMESTAMP_DATETIME, 1);
- error= 1;
- }
- } else if (error)
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- WARN_DATA_TRUNCATED,
- nr, MYSQL_TIMESTAMP_DATETIME, 1);
- store_timestamp(timestamp);
- return error;
+int Field_timestamp::store(longlong nr, bool unsigned_val)
+{
+ MYSQL_TIME l_time;
+ int error;
+ Lazy_string_num str(nr);
+ THD *thd= table->in_use;
+
+ /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
+ longlong tmp= number_to_datetime(nr, 0, &l_time, (thd->variables.sql_mode &
+ MODE_NO_ZERO_DATE) |
+ MODE_NO_ZERO_IN_DATE, &error);
+ return store_TIME_with_warning(thd, &l_time, &str, error, tmp != LL(-1));
}
+
double Field_timestamp::val_real(void)
{
- ASSERT_COLUMN_MARKED_FOR_READ;
return (double) Field_timestamp::val_int();
}
+
longlong Field_timestamp::val_int(void)
{
- ASSERT_COLUMN_MARKED_FOR_READ;
- uint32 temp;
MYSQL_TIME time_tmp;
- THD *thd= table ? table->in_use : current_thd;
+ THD *thd= table->in_use;
thd->time_zone_used= 1;
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- temp=uint4korr(ptr);
- else
-#endif
- longget(temp,ptr);
+ ulong sec_part;
+ my_time_t temp= get_timestamp(&sec_part);
- if (temp == 0L) // No time
- return(0); /* purecov: inspected */
+ /*
+ Field_timestamp() and Field_timestamp_hres() shares this code.
+ This is why are also testing sec_part below.
+ */
+
+ if (temp == 0 && sec_part == 0)
+ return(0);
thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp, (my_time_t)temp);
@@ -4966,10 +4708,9 @@ longlong Field_timestamp::val_int(void)
String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
{
- ASSERT_COLUMN_MARKED_FOR_READ;
- uint32 temp, temp2;
+ uint32 temp2;
+ THD *thd= table->in_use;
MYSQL_TIME time_tmp;
- THD *thd= table ? table->in_use : current_thd;
char *to;
val_buffer->alloc(field_length+1);
@@ -4977,20 +4718,16 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
val_buffer->length(field_length);
thd->time_zone_used= 1;
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- temp=uint4korr(ptr);
- else
-#endif
- longget(temp,ptr);
+ ulong sec_part;
+ my_time_t temp= get_timestamp(&sec_part);
- if (temp == 0L)
+ if (temp == 0 && sec_part == 0)
{ /* Zero time is "000000" */
- val_ptr->set(STRING_WITH_LEN("0000-00-00 00:00:00"), &my_charset_bin);
+ val_ptr->set(zero_timestamp, field_length, &my_charset_bin);
return val_ptr;
}
val_buffer->set_charset(&my_charset_bin); // Safety
-
+
thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp,(my_time_t)temp);
temp= time_tmp.year % 100;
@@ -5039,16 +4776,11 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
bool Field_timestamp::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{
- long temp;
- THD *thd= table ? table->in_use : current_thd;
+ THD *thd= table->in_use;
thd->time_zone_used= 1;
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- temp=uint4korr(ptr);
- else
-#endif
- longget(temp,ptr);
- if (temp == 0L)
+ ulong sec_part;
+ my_time_t temp= get_timestamp(&sec_part);
+ if (temp == 0 && sec_part == 0)
{ /* Zero time is "000000" */
if (fuzzydate & TIME_NO_ZERO_DATE)
return 1;
@@ -5057,61 +4789,35 @@ bool Field_timestamp::get_date(MYSQL_TIME *ltime, uint fuzzydate)
else
{
thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)temp);
+ ltime->second_part= sec_part;
}
return 0;
}
-bool Field_timestamp::get_time(MYSQL_TIME *ltime)
-{
- return Field_timestamp::get_date(ltime,0);
-}
-
bool Field_timestamp::send_binary(Protocol *protocol)
{
- MYSQL_TIME tm;
- Field_timestamp::get_date(&tm, 0);
- return protocol->store(&tm);
+ MYSQL_TIME ltime;
+ Field_timestamp::get_date(&ltime, 0);
+ return protocol->store(&ltime, 0);
}
int Field_timestamp::cmp(const uchar *a_ptr, const uchar *b_ptr)
{
int32 a,b;
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- {
- a=sint4korr(a_ptr);
- b=sint4korr(b_ptr);
- }
- else
-#endif
- {
- longget(a,a_ptr);
- longget(b,b_ptr);
- }
+ a=sint4korr(a_ptr);
+ b=sint4korr(b_ptr);
return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0;
}
void Field_timestamp::sort_string(uchar *to,uint length __attribute__((unused)))
{
-#ifdef WORDS_BIGENDIAN
- if (!table || !table->s->db_low_byte_first)
- {
- to[0] = ptr[0];
- to[1] = ptr[1];
- to[2] = ptr[2];
- to[3] = ptr[3];
- }
- else
-#endif
- {
- to[0] = ptr[3];
- to[1] = ptr[2];
- to[2] = ptr[1];
- to[3] = ptr[0];
- }
+ to[0] = ptr[3];
+ to[1] = ptr[2];
+ to[2] = ptr[1];
+ to[3] = ptr[0];
}
@@ -5121,149 +4827,450 @@ void Field_timestamp::sql_type(String &res) const
}
-void Field_timestamp::set_time()
+int Field_timestamp::set_time()
{
- THD *thd= table ? table->in_use : current_thd;
- long tmp= (long) thd->query_start();
+ THD *thd= table->in_use;
set_notnull();
- store_timestamp(tmp);
+ store_TIME(thd->query_start(), 0);
+ return 0;
}
-/****************************************************************************
-** time type
-** In string context: HH:MM:SS
-** In number context: HHMMSS
-** Stored as a 3 byte unsigned int
-****************************************************************************/
+void Field_timestamp_hires::sql_type(String &res) const
+{
+ CHARSET_INFO *cs=res.charset();
+ res.length(cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
+ "timestamp(%u)", dec));
+}
-int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
+#ifdef NOT_USED
+static void store_native(ulonglong num, uchar *to, uint bytes)
+{
+ switch(bytes) {
+ case 1: *to= (uchar)num; break;
+ case 2: shortstore(to, (ushort)num); break;
+ case 3: int3store(to, num); /* Sic!*/ break;
+ case 4: longstore(to, (ulong)num); break;
+ case 8: longlongstore(to, num); break;
+ default: DBUG_ASSERT(0);
+ }
+}
+
+static longlong read_native(const uchar *from, uint bytes)
+{
+ switch(bytes) {
+ case 1: return from[0];
+ case 2: { uint16 tmp; shortget(tmp, from); return tmp; }
+ case 3: return uint3korr(from);
+ case 4: { uint32 tmp; longget(tmp, from); return tmp; }
+ case 8: { longlong tmp; longlongget(tmp, from); return tmp; }
+ default: DBUG_ASSERT(0); return 0;
+ }
+}
+#endif
+
+static void store_lowendian(ulonglong num, uchar *to, uint bytes)
+{
+ switch(bytes) {
+ case 1: *to= (uchar)num; break;
+ case 2: int2store(to, num); break;
+ case 3: int3store(to, num); break;
+ case 4: int4store(to, num); break;
+ case 8: int8store(to, num); break;
+ default: DBUG_ASSERT(0);
+ }
+}
+
+static longlong read_lowendian(const uchar *from, uint bytes)
+{
+ switch(bytes) {
+ case 1: return from[0];
+ case 2: return uint2korr(from);
+ case 3: return uint3korr(from);
+ case 4: return uint4korr(from);
+ case 8: return sint8korr(from);
+ default: DBUG_ASSERT(0); return 0;
+ }
+}
+
+static void store_bigendian(ulonglong num, uchar *to, uint bytes)
+{
+ switch(bytes) {
+ case 1: mi_int1store(to, num); break;
+ case 2: mi_int2store(to, num); break;
+ case 3: mi_int3store(to, num); break;
+ case 4: mi_int4store(to, num); break;
+ case 5: mi_int5store(to, num); break;
+ case 6: mi_int6store(to, num); break;
+ case 7: mi_int7store(to, num); break;
+ case 8: mi_int8store(to, num); break;
+ default: DBUG_ASSERT(0);
+ }
+}
+
+static longlong read_bigendian(const uchar *from, uint bytes)
+{
+ switch(bytes) {
+ case 1: return mi_uint1korr(from);
+ case 2: return mi_uint2korr(from);
+ case 3: return mi_uint3korr(from);
+ case 4: return mi_uint4korr(from);
+ case 5: return mi_uint5korr(from);
+ case 6: return mi_uint6korr(from);
+ case 7: return mi_uint7korr(from);
+ case 8: return mi_sint8korr(from);
+ default: DBUG_ASSERT(0); return 0;
+ }
+}
+
+void Field_timestamp_hires::store_TIME(my_time_t timestamp, ulong sec_part)
+{
+ mi_int4store(ptr, timestamp);
+ store_bigendian(sec_part_shift(sec_part, dec), ptr+4, sec_part_bytes[dec]);
+}
+
+my_time_t Field_timestamp_hires::get_timestamp(ulong *sec_part) const
+{
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ *sec_part= (long)sec_part_unshift(read_bigendian(ptr+4, sec_part_bytes[dec]), dec);
+ return mi_uint4korr(ptr);
+}
+
+double Field_timestamp_hires::val_real(void)
+{
+ MYSQL_TIME time_tmp;
+ THD *thd= table->in_use;
+
+ thd->time_zone_used= 1;
+ ulong sec_part;
+ my_time_t temp= get_timestamp(&sec_part);
+
+ if (temp == 0 && sec_part == 0)
+ return(0);
+
+ thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp, (my_time_t)temp);
+
+ return time_tmp.year * 1e10 + time_tmp.month * 1e8 +
+ time_tmp.day * 1e6 + time_tmp.hour * 1e4 +
+ time_tmp.minute * 1e2 + time_tmp.second + sec_part*1e-6;
+}
+
+String *Field_timestamp_hires::val_str(String *val_buffer, String *val_ptr)
+{
+ String *tmp= Field_timestamp::val_str(val_buffer, val_ptr);
+ ulong sec_part= (ulong)read_bigendian(ptr+4, sec_part_bytes[dec]);
+
+ if (tmp->ptr() == zero_timestamp)
+ return tmp;
+
+ char *buf= const_cast<char*>(tmp->ptr() + MAX_DATETIME_WIDTH);
+ for (int i=dec; i>0; i--, sec_part/=10)
+ buf[i]= (char)(sec_part % 10) + '0';
+ buf[0]= '.';
+ buf[dec+1]= 0;
+ return tmp;
+}
+
+
+my_decimal *Field_timestamp_hires::val_decimal(my_decimal *d)
{
MYSQL_TIME ltime;
- long tmp;
- int error= 0;
- int warning;
+ get_date(&ltime, 0);
+ longlong intg= TIME_to_ulonglong(&ltime);
+ return seconds2my_decimal(ltime.neg, intg, ltime.second_part, d);
+}
+
+int Field_timestamp_hires::store_decimal(const my_decimal *d)
+{
+ ulonglong nr;
+ ulong sec_part;
+ int error;
+ MYSQL_TIME ltime;
+ longlong tmp;
+ THD *thd= table->in_use;
+ Lazy_string_decimal str(d);
- if (str_to_time(from, len, &ltime, &warning))
+ if (my_decimal2seconds(d, &nr, &sec_part))
{
- tmp=0L;
+ tmp= -1;
error= 2;
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
- from, len, MYSQL_TIMESTAMP_TIME, 1);
}
else
- {
- if (warning & MYSQL_TIME_WARN_TRUNCATED)
- {
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- WARN_DATA_TRUNCATED,
- from, len, MYSQL_TIMESTAMP_TIME, 1);
- error= 1;
- }
- if (warning & MYSQL_TIME_WARN_OUT_OF_RANGE)
- {
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE,
- from, len, MYSQL_TIMESTAMP_TIME, !error);
- error= 1;
- }
- if (ltime.month)
- ltime.day=0;
- tmp=(ltime.day*24L+ltime.hour)*10000L+(ltime.minute*100+ltime.second);
- }
-
- if (ltime.neg)
- tmp= -tmp;
- int3store(ptr,tmp);
- return error;
+ tmp= number_to_datetime(nr, sec_part, &ltime, TIME_NO_ZERO_IN_DATE |
+ (thd->variables.sql_mode &
+ MODE_NO_ZERO_DATE), &error);
+
+ return store_TIME_with_warning(thd, &ltime, &str, error, tmp != -1);
}
+int Field_timestamp_hires::set_time()
+{
+ THD *thd= table->in_use;
+ set_notnull();
+ store_TIME(thd->query_start(), thd->query_start_sec_part());
+ return 0;
+}
-int Field_time::store_time(MYSQL_TIME *ltime, timestamp_type time_type)
+bool Field_timestamp_hires::send_binary(Protocol *protocol)
{
- long tmp= ((ltime->month ? 0 : ltime->day * 24L) + ltime->hour) * 10000L +
- (ltime->minute * 100 + ltime->second);
- if (ltime->neg)
- tmp= -tmp;
- return Field_time::store((longlong) tmp, FALSE);
+ MYSQL_TIME ltime;
+ Field_timestamp::get_date(&ltime, 0);
+ return protocol->store(&ltime, dec);
}
-int Field_time::store(double nr)
+int Field_timestamp_hires::cmp(const uchar *a_ptr, const uchar *b_ptr)
{
+ int32 a,b;
+ ulong a_sec_part, b_sec_part;
+ a= mi_uint4korr(a_ptr);
+ a_sec_part= (ulong)read_bigendian(a_ptr+4, sec_part_bytes[dec]);
+ b= mi_uint4korr(b_ptr);
+ b_sec_part= (ulong)read_bigendian(b_ptr+4, sec_part_bytes[dec]);
+ return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 :
+ a_sec_part < b_sec_part ? -1 : a_sec_part > b_sec_part ? 1 : 0;
+}
+
+
+void Field_timestamp_hires::sort_string(uchar *to,uint length)
+{
+ DBUG_ASSERT(length == Field_timestamp_hires::pack_length());
+ memcpy(to, ptr, length);
+}
+
+uint32 Field_timestamp_hires::pack_length() const
+{
+ return 4 + sec_part_bytes[dec];
+}
+
+void Field_timestamp_hires::make_field(Send_field *field)
+{
+ Field::make_field(field);
+ field->decimals= dec;
+}
+
+/*
+ Store string into a date/time field
+
+ RETURN
+ 0 ok
+ 1 Value was cut during conversion
+ 2 value was out of range
+ 3 Datetime value that was cut (warning level NOTE)
+ This is used by opt_range.cc:get_mm_leaf().
+*/
+int Field_temporal::store_TIME_with_warning(MYSQL_TIME *ltime,
+ const Lazy_string *str,
+ int was_cut, int have_smth_to_conv)
+{
+ MYSQL_ERROR::enum_warning_level trunc_level= MYSQL_ERROR::WARN_LEVEL_WARN;
+ int ret= 2;
+
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- long tmp;
- int error= 0;
- if (nr > (double)TIME_MAX_VALUE)
+
+ if (was_cut == 0 &&
+ have_smth_to_conv == 0 &&
+ temporal_type() != MYSQL_TIMESTAMP_TIME) // special case: zero date
+ was_cut= MYSQL_TIME_WARN_OUT_OF_RANGE;
+ else
+ if (!have_smth_to_conv)
{
- tmp= TIME_MAX_VALUE;
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME);
- error= 1;
+ bzero(ltime, sizeof(*ltime));
+ was_cut= MYSQL_TIME_WARN_TRUNCATED;
+ ret= 1;
}
- else if (nr < (double)-TIME_MAX_VALUE)
+ else if (!(was_cut & MYSQL_TIME_WARN_TRUNCATED) &&
+ temporal_type() == MYSQL_TIMESTAMP_DATE &&
+ (ltime->hour || ltime->minute || ltime->second || ltime->second_part))
{
- tmp= -TIME_MAX_VALUE;
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME);
- error= 1;
+ trunc_level= MYSQL_ERROR::WARN_LEVEL_NOTE;
+ was_cut|= MYSQL_TIME_WARN_TRUNCATED;
+ ret= 3;
}
- else
+ else if (!(was_cut & MYSQL_TIME_WARN_TRUNCATED) &&
+ temporal_type() == MYSQL_TIMESTAMP_TIME &&
+ (ltime->year || ltime->month))
{
- tmp=(long) floor(fabs(nr)); // Remove fractions
- if (nr < 0)
- tmp= -tmp;
- if (tmp % 100 > 59 || tmp/100 % 100 > 59)
- {
- tmp=0;
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE, nr,
- MYSQL_TIMESTAMP_TIME);
- error= 1;
- }
+ ltime->year= ltime->month= ltime->day= 0;
+ trunc_level= MYSQL_ERROR::WARN_LEVEL_NOTE;
+ was_cut|= MYSQL_TIME_WARN_TRUNCATED;
+ ret= 3;
}
- int3store(ptr,tmp);
- return error;
+
+ /*
+ error code logic:
+ MYSQL_TIME_WARN_TRUNCATED means that the value was not a date/time at all.
+ it will be stored as zero date/time.
+ MYSQL_TIME_WARN_OUT_OF_RANGE means that the value was a date/time,
+ that is, it was parsed as such, but the value was invalid.
+
+ Also, MYSQL_TIME_WARN_TRUNCATED is used when storing a DATETIME in
+ a DATE field and non-zero time part is thrown away.
+ */
+ if (was_cut & MYSQL_TIME_WARN_TRUNCATED)
+ set_datetime_warning(trunc_level, WARN_DATA_TRUNCATED,
+ str, temporal_type(), 1);
+ if (was_cut & MYSQL_TIME_WARN_OUT_OF_RANGE)
+ set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE,
+ str, temporal_type(), 1);
+
+ store_TIME(ltime);
+ return was_cut ? ret : 0;
}
-int Field_time::store(longlong nr, bool unsigned_val)
+int Field_temporal::store(const char *from,uint len,CHARSET_INFO *cs)
+{
+ MYSQL_TIME ltime;
+ int error;
+ enum enum_mysql_timestamp_type func_res;
+ THD *thd= table->in_use;
+ Lazy_string_str str(from, len);
+
+ func_res= str_to_datetime(from, len, &ltime,
+ (TIME_FUZZY_DATE |
+ (thd->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
+ MODE_INVALID_DATES))),
+ &error);
+ return store_TIME_with_warning(&ltime, &str, error, func_res > MYSQL_TIMESTAMP_ERROR);
+}
+
+
+int Field_temporal::store(double nr)
{
- ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- long tmp;
int error= 0;
- if (nr < (longlong) -TIME_MAX_VALUE && !unsigned_val)
- {
- tmp= -TIME_MAX_VALUE;
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE, nr,
- MYSQL_TIMESTAMP_TIME, 1);
- error= 1;
- }
- else if (nr > (longlong) TIME_MAX_VALUE || (nr < 0 && unsigned_val))
- {
- tmp= TIME_MAX_VALUE;
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE, nr,
- MYSQL_TIMESTAMP_TIME, 1);
- error= 1;
- }
- else
+ MYSQL_TIME ltime;
+ THD *thd= table->in_use;
+ Lazy_string_double str(nr);
+
+ longlong tmp= double_to_datetime(nr, &ltime,
+ (TIME_FUZZY_DATE |
+ (thd->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE |
+ MODE_NO_ZERO_DATE |
+ MODE_INVALID_DATES))), &error);
+ return store_TIME_with_warning(&ltime, &str, error, tmp != -1);
+}
+
+
+int Field_temporal::store(longlong nr, bool unsigned_val)
+{
+ int error;
+ MYSQL_TIME ltime;
+ longlong tmp;
+ THD *thd= table->in_use;
+ Lazy_string_num str(nr);
+
+ tmp= number_to_datetime(nr, 0, &ltime, (TIME_FUZZY_DATE |
+ (thd->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE |
+ MODE_NO_ZERO_DATE |
+ MODE_INVALID_DATES))), &error);
+
+ return store_TIME_with_warning(&ltime, &str, error, tmp != -1);
+}
+
+
+int Field_temporal::store_time_dec(MYSQL_TIME *ltime, uint dec)
+{
+ int error = 0, have_smth_to_conv= 1;
+ MYSQL_TIME l_time= *ltime;
+ Lazy_string_time str(ltime);
+ /*
+ We don't perform range checking here since values stored in TIME
+ structure always fit into DATETIME range.
+ */
+ have_smth_to_conv= !check_date(&l_time, pack_time(&l_time) != 0,
+ (TIME_FUZZY_DATE |
+ (current_thd->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
+ MODE_INVALID_DATES))), &error);
+ return store_TIME_with_warning(&l_time, &str, error, have_smth_to_conv);
+}
+
+my_decimal *Field_temporal::val_decimal(my_decimal *d)
+{
+ MYSQL_TIME ltime;
+ if (get_date(&ltime, TIME_FUZZY_DATE))
{
- tmp=(long) nr;
- if (tmp % 100 > 59 || tmp/100 % 100 > 59)
- {
- tmp=0;
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE, nr,
- MYSQL_TIMESTAMP_TIME, 1);
- error= 1;
- }
+ bzero(&ltime, sizeof(ltime));
+ ltime.time_type= mysql_type_to_time_type(type());
}
+ longlong intg= TIME_to_ulonglong(&ltime);
+ return seconds2my_decimal(ltime.neg, intg, ltime.second_part, d);
+}
+
+/****************************************************************************
+** time type
+** In string context: HH:MM:SS
+** In number context: HHMMSS
+** Stored as a 3 byte unsigned int
+****************************************************************************/
+
+void Field_time::store_TIME(MYSQL_TIME *ltime)
+{
+ long tmp= (ltime->day*24L+ltime->hour)*10000L +
+ (ltime->minute*100+ltime->second);
+ if (ltime->neg)
+ tmp= -tmp;
int3store(ptr,tmp);
- return error;
+}
+
+int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
+{
+ MYSQL_TIME ltime;
+ Lazy_string_str str(from, len);
+ int was_cut;
+ int have_smth_to_conv=
+ str_to_time(from, len, &ltime,
+ table->in_use->variables.sql_mode &
+ (MODE_NO_ZERO_DATE | MODE_NO_ZERO_IN_DATE |
+ MODE_INVALID_DATES),
+ &was_cut) > MYSQL_TIMESTAMP_ERROR;
+
+ return store_TIME_with_warning(&ltime, &str, was_cut, have_smth_to_conv);
}
+int Field_time::store_time_dec(MYSQL_TIME *ltime, uint dec)
+{
+ MYSQL_TIME l_time= *ltime;
+ Lazy_string_time str(ltime);
+ int was_cut= 0;
+
+ int have_smth_to_conv= !check_time_range(&l_time, decimals(), &was_cut);
+ return store_TIME_with_warning(&l_time, &str, was_cut, have_smth_to_conv);
+}
+
+
+int Field_time::store(double nr)
+{
+ MYSQL_TIME ltime;
+ Lazy_string_double str(nr);
+ int was_cut;
+ bool neg= nr < 0;
+ if (neg)
+ nr= -nr;
+ int have_smth_to_conv= !number_to_time(neg, (longlong)nr,
+ (ulong)((nr - floor(nr)) * TIME_SECOND_PART_FACTOR),
+ &ltime, &was_cut);
+
+ return store_TIME_with_warning(&ltime, &str, was_cut, have_smth_to_conv);
+}
+
+
+int Field_time::store(longlong nr, bool unsigned_val)
+{
+ MYSQL_TIME ltime;
+ Lazy_string_num str(nr);
+ int was_cut;
+ int have_smth_to_conv= !number_to_time(nr < 0, nr < 0 ? -nr : nr,
+ 0, &ltime, &was_cut);
+
+ return store_TIME_with_warning(&ltime, &str, was_cut, have_smth_to_conv);
+}
+
+
double Field_time::val_real(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
@@ -5289,7 +5296,6 @@ String *Field_time::val_str(String *val_buffer,
{
ASSERT_COLUMN_MARKED_FOR_READ;
MYSQL_TIME ltime;
- val_buffer->alloc(MAX_DATE_STRING_REP_LENGTH);
long tmp=(long) sint3korr(ptr);
ltime.neg= 0;
if (tmp < 0)
@@ -5297,11 +5303,19 @@ String *Field_time::val_str(String *val_buffer,
tmp= -tmp;
ltime.neg= 1;
}
+ ltime.year= ltime.month= 0;
ltime.day= (uint) 0;
ltime.hour= (uint) (tmp/10000);
ltime.minute= (uint) (tmp/100 % 100);
ltime.second= (uint) (tmp % 100);
- make_time((DATE_TIME_FORMAT*) 0, &ltime, val_buffer);
+ ltime.second_part= 0;
+
+ val_buffer->alloc(MAX_DATE_STRING_REP_LENGTH);
+ uint length= (uint) my_time_to_str(&ltime,
+ const_cast<char*>(val_buffer->ptr()), 0);
+ val_buffer->length(length);
+ val_buffer->set_charset(&my_charset_bin);
+
return val_buffer;
}
@@ -5315,8 +5329,8 @@ String *Field_time::val_str(String *val_buffer,
bool Field_time::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{
- THD *thd= table ? table->in_use : current_thd;
- if (!(fuzzydate & TIME_FUZZY_DATE))
+ THD *thd= table->in_use;
+ if (!(fuzzydate & (TIME_FUZZY_DATE|TIME_TIME_ONLY)))
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
@@ -5324,12 +5338,6 @@ bool Field_time::get_date(MYSQL_TIME *ltime, uint fuzzydate)
thd->row_count);
return 1;
}
- return Field_time::get_time(ltime);
-}
-
-
-bool Field_time::get_time(MYSQL_TIME *ltime)
-{
long tmp=(long) sint3korr(ptr);
ltime->neg=0;
if (tmp < 0)
@@ -5350,11 +5358,9 @@ bool Field_time::get_time(MYSQL_TIME *ltime)
bool Field_time::send_binary(Protocol *protocol)
{
- MYSQL_TIME tm;
- Field_time::get_time(&tm);
- tm.day= tm.hour/24; // Move hours to days
- tm.hour-= tm.day*24;
- return protocol->store_time(&tm);
+ MYSQL_TIME ltime;
+ Field_time::get_date(&ltime, TIME_TIME_ONLY);
+ return protocol->store_time(&ltime, 0);
}
@@ -5378,6 +5384,120 @@ void Field_time::sql_type(String &res) const
res.set_ascii(STRING_WITH_LEN("time"));
}
+int Field_time_hires::reset()
+{
+ store_bigendian(zero_point, ptr, Field_time_hires::pack_length());
+ return 0;
+}
+
+void Field_time_hires::store_TIME(MYSQL_TIME *ltime)
+{
+ ulonglong packed= sec_part_shift(pack_time(ltime), dec) + zero_point;
+ store_bigendian(packed, ptr, Field_time_hires::pack_length());
+}
+
+int Field_time_hires::store_decimal(const my_decimal *d)
+{
+ ulonglong nr;
+ ulong sec_part;
+ Lazy_string_decimal str(d);
+ MYSQL_TIME ltime;
+ int was_cut;
+ bool neg= my_decimal2seconds(d, &nr, &sec_part);
+
+ int have_smth_to_conv= !number_to_time(neg, nr, sec_part, &ltime, &was_cut);
+
+ return store_TIME_with_warning(&ltime, &str, was_cut, have_smth_to_conv);
+}
+
+uint32 Field_time_hires::pack_length() const
+{
+ return time_hires_bytes[dec];
+}
+
+longlong Field_time_hires::val_int(void)
+{
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ MYSQL_TIME ltime;
+ Field_time_hires::get_date(&ltime, TIME_TIME_ONLY);
+ longlong val= TIME_to_ulonglong_time(&ltime);
+ return ltime.neg ? -val : val;
+}
+
+double Field_time_hires::val_real(void)
+{
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ MYSQL_TIME ltime;
+ Field_time_hires::get_date(&ltime, TIME_TIME_ONLY);
+ return TIME_to_double(&ltime);
+}
+
+String *Field_time_hires::val_str(String *str,
+ String *unused __attribute__((unused)))
+{
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ MYSQL_TIME ltime;
+ Field_time_hires::get_date(&ltime, TIME_TIME_ONLY);
+ str->alloc(field_length+1);
+ str->length(my_time_to_str(&ltime, (char*) str->ptr(), dec));
+ str->set_charset(&my_charset_bin);
+ return str;
+}
+
+bool Field_time_hires::get_date(MYSQL_TIME *ltime, uint fuzzydate)
+{
+ uint32 len= pack_length();
+ longlong packed= read_bigendian(ptr, len);
+
+ packed= sec_part_unshift(packed - zero_point, dec);
+
+ unpack_time(packed, ltime);
+ /*
+ unpack_time() returns MYSQL_TIMESTAMP_DATETIME.
+ To get MYSQL_TIMESTAMP_TIME we few adjustments
+ */
+ ltime->time_type= MYSQL_TIMESTAMP_TIME;
+ ltime->hour+= (ltime->month*32+ltime->day)*24;
+ ltime->month= ltime->day= 0;
+ return fuzzydate & (TIME_FUZZY_DATE | TIME_TIME_ONLY) ? 0 : 1;
+}
+
+
+bool Field_time_hires::send_binary(Protocol *protocol)
+{
+ MYSQL_TIME ltime;
+ Field_time_hires::get_date(&ltime, TIME_TIME_ONLY);
+ return protocol->store_time(&ltime, dec);
+}
+
+
+int Field_time_hires::cmp(const uchar *a_ptr, const uchar *b_ptr)
+{
+ ulonglong a=read_bigendian(a_ptr, Field_time_hires::pack_length());
+ ulonglong b=read_bigendian(b_ptr, Field_time_hires::pack_length());
+ return (a < b) ? -1 : (a > b) ? 1 : 0;
+}
+
+void Field_time_hires::sort_string(uchar *to,uint length __attribute__((unused)))
+{
+ DBUG_ASSERT(length == Field_time_hires::pack_length());
+ memcpy(to, ptr, length);
+ to[0]^= 128;
+}
+
+void Field_time_hires::sql_type(String &res) const
+{
+ CHARSET_INFO *cs=res.charset();
+ res.length(cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
+ "time(%u)", dec));
+}
+
+void Field_time_hires::make_field(Send_field *field)
+{
+ Field::make_field(field);
+ field->decimals= dec;
+}
+
/****************************************************************************
** year type
** Save in a byte the year 0, 1901->2155
@@ -5453,6 +5573,17 @@ int Field_year::store(longlong nr, bool unsigned_val)
}
+int Field_year::store_time_dec(MYSQL_TIME *ltime, uint dec)
+{
+ Lazy_string_time str(ltime);
+ if (Field_year::store(ltime->year, 0))
+ return 1;
+
+ set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
+ &str, ltime->time_type, 1);
+ return 0;
+}
+
bool Field_year::send_binary(Protocol *protocol)
{
ASSERT_COLUMN_MARKED_FOR_READ;
@@ -5492,6 +5623,15 @@ String *Field_year::val_str(String *val_buffer,
}
+bool Field_year::get_date(MYSQL_TIME *ltime,uint fuzzydate)
+{
+ int tmp= (int) ptr[0];
+ if (tmp || field_length != 4)
+ tmp+= 1900;
+ return int_to_datetime_with_warn(tmp * 10000, ltime, fuzzydate, field_name);
+}
+
+
void Field_year::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
@@ -5507,102 +5647,12 @@ void Field_year::sql_type(String &res) const
** Stored as a 4 byte unsigned int
****************************************************************************/
-int Field_date::store(const char *from, uint len,CHARSET_INFO *cs)
-{
- ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- MYSQL_TIME l_time;
- uint32 tmp;
- int error;
- THD *thd= table ? table->in_use : current_thd;
-
- if (str_to_datetime(from, len, &l_time, TIME_FUZZY_DATE |
- (thd->variables.sql_mode &
- (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
- MODE_INVALID_DATES)),
- &error) <= MYSQL_TIMESTAMP_ERROR)
- {
- tmp= 0;
- error= 2;
- }
- else
- tmp=(uint32) l_time.year*10000L + (uint32) (l_time.month*100+l_time.day);
-
- if (error)
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
- from, len, MYSQL_TIMESTAMP_DATE, 1);
-
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- {
- int4store(ptr,tmp);
- }
- else
-#endif
- longstore(ptr,tmp);
- return error;
-}
-
-
-int Field_date::store(double nr)
-{
- longlong tmp;
- if (nr >= 19000000000000.0 && nr <= 99991231235959.0)
- nr=floor(nr/1000000.0); // Timestamp to date
- if (nr < 0.0 || nr > 99991231.0)
- {
- tmp= LL(0);
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE,
- nr, MYSQL_TIMESTAMP_DATE);
- }
- else
- tmp= (longlong) rint(nr);
-
- return Field_date::store(tmp, TRUE);
-}
-
-
-int Field_date::store(longlong nr, bool unsigned_val)
+void Field_date::store_TIME(MYSQL_TIME *ltime)
{
- ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- MYSQL_TIME not_used;
- int error;
- longlong initial_nr= nr;
- THD *thd= table ? table->in_use : current_thd;
-
- nr= number_to_datetime(nr, &not_used, (TIME_FUZZY_DATE |
- (thd->variables.sql_mode &
- (MODE_NO_ZERO_IN_DATE |
- MODE_NO_ZERO_DATE |
- MODE_INVALID_DATES))), &error);
-
- if (nr == LL(-1))
- {
- nr= 0;
- error= 2;
- }
-
- if (nr >= 19000000000000.0 && nr <= 99991231235959.0)
- nr= (longlong) floor(nr/1000000.0); // Timestamp to date
-
- if (error)
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- error == 2 ? ER_WARN_DATA_OUT_OF_RANGE :
- WARN_DATA_TRUNCATED, initial_nr,
- MYSQL_TIMESTAMP_DATETIME, 1);
-
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- {
- int4store(ptr, nr);
- }
- else
-#endif
- longstore(ptr, nr);
- return error;
+ uint tmp= ltime->year*10000L + ltime->month*100+ltime->day;
+ int4store(ptr,tmp);
}
-
bool Field_date::send_binary(Protocol *protocol)
{
longlong tmp= Field_date::val_int();
@@ -5618,12 +5668,7 @@ double Field_date::val_real(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
int32 j;
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- j=sint4korr(ptr);
- else
-#endif
- longget(j,ptr);
+ j=sint4korr(ptr);
return (double) (uint32) j;
}
@@ -5632,12 +5677,7 @@ longlong Field_date::val_int(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
int32 j;
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- j=sint4korr(ptr);
- else
-#endif
- longget(j,ptr);
+ j=sint4korr(ptr);
return (longlong) (uint32) j;
}
@@ -5647,67 +5687,38 @@ String *Field_date::val_str(String *val_buffer,
{
ASSERT_COLUMN_MARKED_FOR_READ;
MYSQL_TIME ltime;
- val_buffer->alloc(field_length);
int32 tmp;
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- tmp=sint4korr(ptr);
- else
-#endif
- longget(tmp,ptr);
+ tmp=sint4korr(ptr);
ltime.neg= 0;
ltime.year= (int) ((uint32) tmp/10000L % 10000);
ltime.month= (int) ((uint32) tmp/100 % 100);
ltime.day= (int) ((uint32) tmp % 100);
- make_date((DATE_TIME_FORMAT *) 0, &ltime, val_buffer);
- return val_buffer;
-}
+ val_buffer->alloc(MAX_DATE_STRING_REP_LENGTH);
+ uint length= (uint) my_date_to_str(&ltime,
+ const_cast<char*>(val_buffer->ptr()));
+ val_buffer->length(length);
+ val_buffer->set_charset(&my_charset_bin);
-bool Field_date::get_time(MYSQL_TIME *ltime)
-{
- bzero((char *)ltime, sizeof(MYSQL_TIME));
- return 0;
+ return val_buffer;
}
int Field_date::cmp(const uchar *a_ptr, const uchar *b_ptr)
{
int32 a,b;
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- {
- a=sint4korr(a_ptr);
- b=sint4korr(b_ptr);
- }
- else
-#endif
- {
- longget(a,a_ptr);
- longget(b,b_ptr);
- }
+ a=sint4korr(a_ptr);
+ b=sint4korr(b_ptr);
return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0;
}
void Field_date::sort_string(uchar *to,uint length __attribute__((unused)))
{
-#ifdef WORDS_BIGENDIAN
- if (!table || !table->s->db_low_byte_first)
- {
- to[0] = ptr[0];
- to[1] = ptr[1];
- to[2] = ptr[2];
- to[3] = ptr[3];
- }
- else
-#endif
- {
- to[0] = ptr[3];
- to[1] = ptr[2];
- to[2] = ptr[1];
- to[3] = ptr[0];
- }
+ to[0] = ptr[3];
+ to[1] = ptr[2];
+ to[2] = ptr[1];
+ to[3] = ptr[0];
}
void Field_date::sql_type(String &res) const
@@ -5722,153 +5733,10 @@ void Field_date::sql_type(String &res) const
** In number context: YYYYMMDD
****************************************************************************/
-/*
- Store string into a date field
-
- SYNOPSIS
- Field_newdate::store()
- from Date string
- len Length of date field
- cs Character set (not used)
-
- RETURN
- 0 ok
- 1 Value was cut during conversion
- 2 Wrong date string
- 3 Datetime value that was cut (warning level NOTE)
- This is used by opt_range.cc:get_mm_leaf(). Note that there is a
- nearly-identical class Field_date doesn't ever return 3 from its
- store function.
-*/
-
-int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
+void Field_newdate::store_TIME(MYSQL_TIME *ltime)
{
- ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- long tmp;
- MYSQL_TIME l_time;
- int error;
- THD *thd= table ? table->in_use : current_thd;
- enum enum_mysql_timestamp_type ret;
- if ((ret= str_to_datetime(from, len, &l_time,
- (TIME_FUZZY_DATE |
- (thd->variables.sql_mode &
- (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
- MODE_INVALID_DATES))),
- &error)) <= MYSQL_TIMESTAMP_ERROR)
- {
- tmp= 0;
- error= 2;
- }
- else
- {
- tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
- if (!error && (ret != MYSQL_TIMESTAMP_DATE) &&
- (l_time.hour || l_time.minute || l_time.second || l_time.second_part))
- error= 3; // Datetime was cut (note)
- }
-
- if (error)
- set_datetime_warning(error == 3 ? MYSQL_ERROR::WARN_LEVEL_NOTE :
- MYSQL_ERROR::WARN_LEVEL_WARN,
- WARN_DATA_TRUNCATED,
- from, len, MYSQL_TIMESTAMP_DATE, 1);
-
- int3store(ptr, tmp);
- return error;
-}
-
-
-int Field_newdate::store(double nr)
-{
- if (nr < 0.0 || nr > 99991231235959.0)
- {
- int3store(ptr,(int32) 0);
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- WARN_DATA_TRUNCATED, nr, MYSQL_TIMESTAMP_DATE);
- return 1;
- }
- return Field_newdate::store((longlong) rint(nr), FALSE);
-}
-
-
-int Field_newdate::store(longlong nr, bool unsigned_val)
-{
- ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- MYSQL_TIME l_time;
- longlong tmp;
- int error;
- THD *thd= table ? table->in_use : current_thd;
- if (number_to_datetime(nr, &l_time,
- (TIME_FUZZY_DATE |
- (thd->variables.sql_mode &
- (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
- MODE_INVALID_DATES))),
- &error) == LL(-1))
- {
- tmp= 0L;
- error= 2;
- }
- else
- tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
-
- if (!error && l_time.time_type != MYSQL_TIMESTAMP_DATE &&
- (l_time.hour || l_time.minute || l_time.second || l_time.second_part))
- error= 3;
-
- if (error)
- set_datetime_warning(error == 3 ? MYSQL_ERROR::WARN_LEVEL_NOTE :
- MYSQL_ERROR::WARN_LEVEL_WARN,
- error == 2 ?
- ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED,
- nr,MYSQL_TIMESTAMP_DATE, 1);
-
- int3store(ptr,tmp);
- return error;
-}
-
-
-int Field_newdate::store_time(MYSQL_TIME *ltime,timestamp_type time_type)
-{
- ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- long tmp;
- int error= 0;
- if (time_type == MYSQL_TIMESTAMP_DATE ||
- time_type == MYSQL_TIMESTAMP_DATETIME)
- {
- tmp=ltime->year*16*32+ltime->month*32+ltime->day;
- if (check_date(ltime, tmp != 0,
- (TIME_FUZZY_DATE |
- (current_thd->variables.sql_mode &
- (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
- MODE_INVALID_DATES))), &error))
- {
- char buff[MAX_DATE_STRING_REP_LENGTH];
- String str(buff, sizeof(buff), &my_charset_latin1);
- tmp= 0;
- make_date((DATE_TIME_FORMAT *) 0, ltime, &str);
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
- str.ptr(), str.length(), MYSQL_TIMESTAMP_DATE, 1);
- }
- if (!error && ltime->time_type != MYSQL_TIMESTAMP_DATE &&
- (ltime->hour || ltime->minute || ltime->second || ltime->second_part))
- {
- char buff[MAX_DATE_STRING_REP_LENGTH];
- String str(buff, sizeof(buff), &my_charset_latin1);
- make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str);
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_NOTE,
- WARN_DATA_TRUNCATED,
- str.ptr(), str.length(), MYSQL_TIMESTAMP_DATE, 1);
- error= 3;
- }
- }
- else
- {
- tmp=0;
- error= 1;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
- }
+ uint tmp= ltime->year*16*32 + ltime->month*32+ltime->day;
int3store(ptr,tmp);
- return error;
}
@@ -5933,14 +5801,11 @@ bool Field_newdate::get_date(MYSQL_TIME *ltime,uint fuzzydate)
ltime->year= (tmp >> 9);
ltime->time_type= MYSQL_TIMESTAMP_DATE;
ltime->hour= ltime->minute= ltime->second= ltime->second_part= ltime->neg= 0;
- return ((!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ?
- 1 : 0);
-}
-
-
-bool Field_newdate::get_time(MYSQL_TIME *ltime)
-{
- return Field_newdate::get_date(ltime,0);
+ if (!tmp)
+ return fuzzydate & TIME_NO_ZERO_DATE;
+ if (!ltime->month || !ltime->day)
+ return fuzzydate & TIME_NO_ZERO_IN_DATE;
+ return 0;
}
@@ -5974,150 +5839,20 @@ void Field_newdate::sql_type(String &res) const
** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int.
****************************************************************************/
-int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs)
-{
- ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- MYSQL_TIME time_tmp;
- int error;
- ulonglong tmp= 0;
- enum enum_mysql_timestamp_type func_res;
- THD *thd= table ? table->in_use : current_thd;
-
- func_res= str_to_datetime(from, len, &time_tmp,
- (TIME_FUZZY_DATE |
- (thd->variables.sql_mode &
- (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
- MODE_INVALID_DATES))),
- &error);
- if ((int) func_res > (int) MYSQL_TIMESTAMP_ERROR)
- tmp= TIME_to_ulonglong_datetime(&time_tmp);
- else
- error= 1; // Fix if invalid zero date
-
- if (error)
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE,
- from, len, MYSQL_TIMESTAMP_DATETIME, 1);
-
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- {
- int8store(ptr,tmp);
- }
- else
-#endif
- longlongstore(ptr,tmp);
- return error;
-}
-
-
-int Field_datetime::store(double nr)
-{
- int error= 0;
- if (nr < 0.0 || nr > 99991231235959.0)
- {
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_DATA_OUT_OF_RANGE,
- nr, MYSQL_TIMESTAMP_DATETIME);
- nr= 0.0;
- error= 1;
- }
- error|= Field_datetime::store((longlong) rint(nr), FALSE);
- return error;
-}
-
-
-int Field_datetime::store(longlong nr, bool unsigned_val)
+void Field_datetime::store_TIME(MYSQL_TIME *ltime)
{
- ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- MYSQL_TIME not_used;
- int error;
- longlong initial_nr= nr;
- THD *thd= table ? table->in_use : current_thd;
-
- nr= number_to_datetime(nr, &not_used, (TIME_FUZZY_DATE |
- (thd->variables.sql_mode &
- (MODE_NO_ZERO_IN_DATE |
- MODE_NO_ZERO_DATE |
- MODE_INVALID_DATES))), &error);
-
- if (nr == LL(-1))
- {
- nr= 0;
- error= 2;
- }
-
- if (error)
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- error == 2 ? ER_WARN_DATA_OUT_OF_RANGE :
- WARN_DATA_TRUNCATED, initial_nr,
- MYSQL_TIMESTAMP_DATETIME, 1);
-
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- {
- int8store(ptr,nr);
- }
- else
-#endif
- longlongstore(ptr,nr);
- return error;
-}
-
-
-int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type)
-{
- ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
- longlong tmp;
- int error= 0;
- /*
- We don't perform range checking here since values stored in TIME
- structure always fit into DATETIME range.
- */
- if (time_type == MYSQL_TIMESTAMP_DATE ||
- time_type == MYSQL_TIMESTAMP_DATETIME)
- {
- tmp=((ltime->year*10000L+ltime->month*100+ltime->day)*LL(1000000)+
- (ltime->hour*10000L+ltime->minute*100+ltime->second));
- if (check_date(ltime, tmp != 0,
- (TIME_FUZZY_DATE |
- (current_thd->variables.sql_mode &
- (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
- MODE_INVALID_DATES))), &error))
- {
- char buff[MAX_DATE_STRING_REP_LENGTH];
- String str(buff, sizeof(buff), &my_charset_latin1);
- tmp= 0;
- make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str);
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
- str.ptr(), str.length(), MYSQL_TIMESTAMP_DATETIME,1);
- }
- }
- else
- {
- tmp=0;
- error= 1;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
- }
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- {
- int8store(ptr,tmp);
- }
- else
-#endif
- longlongstore(ptr,tmp);
- return error;
+ ulonglong tmp= TIME_to_ulonglong_datetime(ltime);
+ int8store(ptr,tmp);
}
bool Field_datetime::send_binary(Protocol *protocol)
{
MYSQL_TIME tm;
Field_datetime::get_date(&tm, TIME_FUZZY_DATE);
- return protocol->store(&tm);
+ return protocol->store(&tm, 0);
}
-
-
+
+
double Field_datetime::val_real(void)
{
return (double) Field_datetime::val_int();
@@ -6127,12 +5862,7 @@ longlong Field_datetime::val_int(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
longlong j;
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- j=sint8korr(ptr);
- else
-#endif
- longlongget(j,ptr);
+ j=sint8korr(ptr);
return j;
}
@@ -6140,20 +5870,16 @@ longlong Field_datetime::val_int(void)
String *Field_datetime::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
- ASSERT_COLUMN_MARKED_FOR_READ;
val_buffer->alloc(field_length);
val_buffer->length(field_length);
+
+ ASSERT_COLUMN_MARKED_FOR_READ;
ulonglong tmp;
long part1,part2;
char *pos;
int part3;
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- tmp=sint8korr(ptr);
- else
-#endif
- longlongget(tmp,ptr);
+ tmp= Field_datetime::val_int();
/*
Avoid problem with slow longlong arithmetic and sprintf
@@ -6202,65 +5928,148 @@ bool Field_datetime::get_date(MYSQL_TIME *ltime, uint fuzzydate)
ltime->day= (int) (part1%100);
ltime->month= (int) (part1/100%100);
ltime->year= (int) (part1/10000);
- return (!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ? 1 : 0;
-}
-
-bool Field_datetime::get_time(MYSQL_TIME *ltime)
-{
- return Field_datetime::get_date(ltime,0);
+ if (!tmp)
+ return (fuzzydate & TIME_NO_ZERO_DATE) != 0;
+ if (!ltime->month || !ltime->day)
+ return !(fuzzydate & TIME_FUZZY_DATE);
+ return 0;
}
int Field_datetime::cmp(const uchar *a_ptr, const uchar *b_ptr)
{
longlong a,b;
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- {
- a=sint8korr(a_ptr);
- b=sint8korr(b_ptr);
- }
- else
-#endif
- {
- longlongget(a,a_ptr);
- longlongget(b,b_ptr);
- }
+ a=sint8korr(a_ptr);
+ b=sint8korr(b_ptr);
return ((ulonglong) a < (ulonglong) b) ? -1 :
((ulonglong) a > (ulonglong) b) ? 1 : 0;
}
void Field_datetime::sort_string(uchar *to,uint length __attribute__((unused)))
{
-#ifdef WORDS_BIGENDIAN
- if (!table || !table->s->db_low_byte_first)
+ to[0] = ptr[7];
+ to[1] = ptr[6];
+ to[2] = ptr[5];
+ to[3] = ptr[4];
+ to[4] = ptr[3];
+ to[5] = ptr[2];
+ to[6] = ptr[1];
+ to[7] = ptr[0];
+}
+
+
+void Field_datetime::sql_type(String &res) const
+{
+ res.set_ascii(STRING_WITH_LEN("datetime"));
+}
+
+void Field_datetime_hires::store_TIME(MYSQL_TIME *ltime)
+{
+ ulonglong packed= sec_part_shift(pack_time(ltime), dec);
+ store_bigendian(packed, ptr, pack_length());
+}
+
+int Field_datetime_hires::store_decimal(const my_decimal *d)
+{
+ ulonglong nr;
+ ulong sec_part;
+ int error;
+ MYSQL_TIME ltime;
+ longlong tmp;
+ THD *thd= table->in_use;
+ Lazy_string_decimal str(d);
+
+ if (my_decimal2seconds(d, &nr, &sec_part))
{
- to[0] = ptr[0];
- to[1] = ptr[1];
- to[2] = ptr[2];
- to[3] = ptr[3];
- to[4] = ptr[4];
- to[5] = ptr[5];
- to[6] = ptr[6];
- to[7] = ptr[7];
+ tmp= -1;
+ error= 2;
}
else
-#endif
- {
- to[0] = ptr[7];
- to[1] = ptr[6];
- to[2] = ptr[5];
- to[3] = ptr[4];
- to[4] = ptr[3];
- to[5] = ptr[2];
- to[6] = ptr[1];
- to[7] = ptr[0];
- }
+ tmp= number_to_datetime(nr, sec_part, &ltime, (TIME_FUZZY_DATE |
+ (thd->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE |
+ MODE_NO_ZERO_DATE |
+ MODE_INVALID_DATES))), &error);
+
+ return store_TIME_with_warning(&ltime, &str, error, tmp != -1);
+}
+
+bool Field_datetime_hires::send_binary(Protocol *protocol)
+{
+ MYSQL_TIME ltime;
+ Field_datetime_hires::get_date(&ltime, TIME_FUZZY_DATE);
+ return protocol->store(&ltime, dec);
}
-void Field_datetime::sql_type(String &res) const
+double Field_datetime_hires::val_real(void)
{
- res.set_ascii(STRING_WITH_LEN("datetime"));
+ MYSQL_TIME ltime;
+ Field_datetime_hires::get_date(&ltime, TIME_FUZZY_DATE);
+ return TIME_to_double(&ltime);
+}
+
+longlong Field_datetime_hires::val_int(void)
+{
+ MYSQL_TIME ltime;
+ Field_datetime_hires::get_date(&ltime, TIME_FUZZY_DATE);
+ return TIME_to_ulonglong_datetime(&ltime);
+}
+
+
+String *Field_datetime_hires::val_str(String *str,
+ String *unused __attribute__((unused)))
+{
+ MYSQL_TIME ltime;
+ Field_datetime_hires::get_date(&ltime, TIME_FUZZY_DATE);
+ str->alloc(field_length+1);
+ str->length(field_length);
+ my_datetime_to_str(&ltime, (char*) str->ptr(), dec);
+ str->set_charset(&my_charset_bin);
+ return str;
+}
+
+bool Field_datetime_hires::get_date(MYSQL_TIME *ltime, uint fuzzydate)
+{
+ ulonglong packed= read_bigendian(ptr, pack_length());
+ unpack_time(sec_part_unshift(packed, dec), ltime);
+ if (!packed)
+ return fuzzydate & TIME_NO_ZERO_DATE;
+ if (!ltime->month || !ltime->day)
+ return !(fuzzydate & TIME_FUZZY_DATE);
+ return 0;
+}
+
+uint32 Field_datetime_hires::pack_length() const
+{
+ return datetime_hires_bytes[dec];
+}
+
+int Field_datetime_hires::cmp(const uchar *a_ptr, const uchar *b_ptr)
+{
+ ulonglong a=read_bigendian(a_ptr, pack_length());
+ ulonglong b=read_bigendian(b_ptr, pack_length());
+ return a < b ? -1 : a > b ? 1 : 0;
+}
+
+void Field_datetime_hires::sort_string(uchar *to,
+ uint length __attribute__((unused)))
+{
+ DBUG_ASSERT(length == pack_length());
+ memcpy(to, ptr, length);
+}
+
+
+void Field_datetime_hires::sql_type(String &res) const
+{
+ CHARSET_INFO *cs=res.charset();
+ res.length(cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
+ "datetime(%u)", dec));
+}
+
+void Field_datetime_hires::make_field(Send_field *field)
+{
+ Field::make_field(field);
+ field->decimals= dec;
}
/****************************************************************************
@@ -6718,9 +6527,7 @@ void Field_string::sql_type(String &res) const
}
-uchar *Field_string::pack(uchar *to, const uchar *from,
- uint max_length,
- bool low_byte_first __attribute__((unused)))
+uchar *Field_string::pack(uchar *to, const uchar *from, uint max_length)
{
uint length= min(field_length,max_length);
uint local_char_length= max_length/field_charset->mbmaxlen;
@@ -6762,10 +6569,8 @@ uchar *Field_string::pack(uchar *to, const uchar *from,
@return New pointer into memory based on from + length of the data
*/
const uchar *
-Field_string::unpack(uchar *to,
- const uchar *from,
- uint param_data,
- bool low_byte_first __attribute__((unused)))
+Field_string::unpack(uchar *to, const uchar *from, const uchar *from_end,
+ uint param_data)
{
uint from_length, length;
@@ -6787,11 +6592,19 @@ Field_string::unpack(uchar *to,
*/
if (from_length > 255)
{
+ if (from + 2 > from_end)
+ return 0;
length= uint2korr(from);
from+= 2;
}
else
+ {
+ if (from + 1 > from_end)
+ return 0;
length= (uint) *from++;
+ }
+ if (from + length > from_end || length > field_length)
+ return 0;
memcpy(to, from, length);
// Pad the string with the pad character of the fields charset
@@ -7227,9 +7040,7 @@ uint32 Field_varstring::data_length()
Here the number of length bytes are depending on the given max_length
*/
-uchar *Field_varstring::pack(uchar *to, const uchar *from,
- uint max_length,
- bool low_byte_first __attribute__((unused)))
+uchar *Field_varstring::pack(uchar *to, const uchar *from, uint max_length)
{
uint length= length_bytes == 1 ? (uint) *from : uint2korr(from);
set_if_smaller(max_length, field_length);
@@ -7249,8 +7060,7 @@ uchar *Field_varstring::pack(uchar *to, const uchar *from,
uchar *
-Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length,
- bool low_byte_first __attribute__((unused)))
+Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length)
{
uint length= length_bytes == 1 ? (uint) *key : uint2korr(key);
uint local_char_length= ((field_charset->mbmaxlen > 1) ?
@@ -7286,9 +7096,9 @@ Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length,
Pointer to end of 'key' (To the next key part if multi-segment key)
*/
+#ifdef NOT_USED
const uchar *
-Field_varstring::unpack_key(uchar *to, const uchar *key, uint max_length,
- bool low_byte_first __attribute__((unused)))
+Field_varstring::unpack_key(uchar *to, const uchar *key, uint max_length)
{
/* get length of the blob key */
uint32 length= *key++;
@@ -7303,6 +7113,7 @@ Field_varstring::unpack_key(uchar *to, const uchar *key, uint max_length,
memcpy(ptr + length_bytes, key, length);
return key + length;
}
+#endif
/**
Create a packed key that will be used for storage in the index tree.
@@ -7315,9 +7126,8 @@ Field_varstring::unpack_key(uchar *to, const uchar *key, uint max_length,
end of key storage
*/
-uchar *
-Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
- bool low_byte_first __attribute__((unused)))
+uchar * Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from,
+ uint max_length)
{
/* Key length is always stored as 2 bytes */
uint length= uint2korr(from);
@@ -7348,13 +7158,16 @@ Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from, uint max_
@return New pointer into memory based on from + length of the data
*/
const uchar *
-Field_varstring::unpack(uchar *to, const uchar *from,
- uint param_data,
- bool low_byte_first __attribute__((unused)))
+Field_varstring::unpack(uchar *to, const uchar *from, const uchar *from_end,
+ uint param_data)
{
uint length;
uint l_bytes= (param_data && (param_data < field_length)) ?
(param_data <= 255) ? 1 : 2 : length_bytes;
+
+ if (from + l_bytes > from_end)
+ return 0; // Error in data
+
if (l_bytes == 1)
{
to[0]= *from++;
@@ -7369,7 +7182,11 @@ Field_varstring::unpack(uchar *to, const uchar *from,
to[1]= *from++;
}
if (length)
+ {
+ if (from + length > from_end || length > field_length)
+ return 0; // Error in data
memcpy(to+ length_bytes, from, length);
+ }
return from+length;
}
@@ -7576,103 +7393,15 @@ Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
}
-void Field_blob::store_length(uchar *i_ptr,
- uint i_packlength,
- uint32 i_number,
- bool low_byte_first)
-{
- switch (i_packlength) {
- case 1:
- i_ptr[0]= (uchar) i_number;
- break;
- case 2:
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first)
- {
- int2store(i_ptr,(unsigned short) i_number);
- }
- else
-#endif
- shortstore(i_ptr,(unsigned short) i_number);
- break;
- case 3:
- int3store(i_ptr,i_number);
- break;
- case 4:
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first)
- {
- int4store(i_ptr,i_number);
- }
- else
-#endif
- longstore(i_ptr,i_number);
- }
-}
-
-
-uint32 Field_blob::get_length(const uchar *pos, uint packlength_arg, bool low_byte_first)
+void Field_blob::store_length(uchar *i_ptr, uint i_packlength, uint32 i_number)
{
- switch (packlength_arg) {
- case 1:
- return (uint32) pos[0];
- case 2:
- {
- uint16 tmp;
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first)
- tmp=sint2korr(pos);
- else
-#endif
- shortget(tmp,pos);
- return (uint32) tmp;
- }
- case 3:
- return (uint32) uint3korr(pos);
- case 4:
- {
- uint32 tmp;
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first)
- tmp=uint4korr(pos);
- else
-#endif
- longget(tmp,pos);
- return (uint32) tmp;
- }
- }
- /* When expanding this, see also MAX_FIELD_BLOBLENGTH. */
- return 0; // Impossible
+ store_lowendian(i_number, i_ptr, i_packlength);
}
-/**
- Put a blob length field into a record buffer.
-
- Depending on the maximum length of a blob, its length field is
- put into 1 to 4 bytes. This is a property of the blob object,
- described by 'packlength'.
-
- @param pos Pointer into the record buffer.
- @param length The length value to put.
-*/
-
-void Field_blob::put_length(uchar *pos, uint32 length)
+uint32 Field_blob::get_length(const uchar *pos, uint packlength_arg)
{
- switch (packlength) {
- case 1:
- *pos= (char) length;
- break;
- case 2:
- int2store(pos, length);
- break;
- case 3:
- int3store(pos, length);
- break;
- case 4:
- int4store(pos, length);
- break;
- }
+ return (uint32)read_lowendian(pos, packlength_arg);
}
@@ -8011,20 +7740,7 @@ void Field_blob::sort_string(uchar *to,uint length)
length-= packlength;
pos= to+length;
- switch (packlength) {
- case 1:
- *pos= (char) blob_length;
- break;
- case 2:
- mi_int2store(pos, blob_length);
- break;
- case 3:
- mi_int3store(pos, blob_length);
- break;
- case 4:
- mi_int4store(pos, blob_length);
- break;
- }
+ store_bigendian(blob_length, pos, packlength);
}
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
@@ -8054,14 +7770,11 @@ void Field_blob::sql_type(String &res) const
}
}
-uchar *Field_blob::pack(uchar *to, const uchar *from,
- uint max_length, bool low_byte_first)
+uchar *Field_blob::pack(uchar *to, const uchar *from, uint max_length)
{
DBUG_ENTER("Field_blob::pack");
- DBUG_PRINT("enter", ("to: 0x%lx; from: 0x%lx;"
- " max_length: %u; low_byte_first: %d",
- (ulong) to, (ulong) from,
- max_length, low_byte_first));
+ DBUG_PRINT("enter", ("to: 0x%lx; from: 0x%lx; max_length: %u",
+ (ulong) to, (ulong) from, max_length));
DBUG_DUMP("record", from, table->s->reclength);
uchar *save= ptr;
ptr= (uchar*) from;
@@ -8072,7 +7785,7 @@ uchar *Field_blob::pack(uchar *to, const uchar *from,
length given is smaller than the actual length of the blob, we
just store the initial bytes of the blob.
*/
- store_length(to, packlength, min(length, max_length), low_byte_first);
+ store_length(to, packlength, min(length, max_length));
/*
Store the actual blob data, which will occupy 'length' bytes.
@@ -8105,20 +7818,21 @@ uchar *Field_blob::pack(uchar *to, const uchar *from,
@return New pointer into memory based on from + length of the data
*/
-const uchar *Field_blob::unpack(uchar *to,
- const uchar *from,
- uint param_data,
- bool low_byte_first)
+const uchar *Field_blob::unpack(uchar *to, const uchar *from,
+ const uchar *from_end, uint param_data)
{
DBUG_ENTER("Field_blob::unpack");
- DBUG_PRINT("enter", ("to: 0x%lx; from: 0x%lx;"
- " param_data: %u; low_byte_first: %d",
- (ulong) to, (ulong) from, param_data, low_byte_first));
+ DBUG_PRINT("enter", ("to: 0x%lx; from: 0x%lx; param_data: %u",
+ (ulong) to, (ulong) from, param_data));
uint const master_packlength=
param_data > 0 ? param_data & 0xFF : packlength;
- uint32 const length= get_length(from, master_packlength, low_byte_first);
+ if (from + master_packlength > from_end)
+ DBUG_RETURN(0); // Error in data
+ uint32 const length= get_length(from, master_packlength);
DBUG_DUMP("packed", from, length + master_packlength);
bitmap_set_bit(table->write_set, field_index);
+ if (from + master_packlength + length > from_end)
+ DBUG_RETURN(0);
store(reinterpret_cast<const char*>(from) + master_packlength,
length, field_charset);
DBUG_DUMP("record", to, table->s->reclength);
@@ -8173,8 +7887,7 @@ int Field_blob::pack_cmp(const uchar *b, uint key_length_arg,
/** Create a packed key that will be used for storage from a MySQL row. */
uchar *
-Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
- bool low_byte_first __attribute__((unused)))
+Field_blob::pack_key(uchar *to, const uchar *from, uint max_length)
{
uchar *save= ptr;
ptr= (uchar*) from;
@@ -8217,9 +7930,9 @@ Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
Pointer into 'from' past the last byte copied from packed key.
*/
+#ifdef NOT_USED
const uchar *
-Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
- bool low_byte_first __attribute__((unused)))
+Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length)
{
/* get length of the blob key */
uint32 length= *from++;
@@ -8227,7 +7940,7 @@ Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
length+= *from++ << 8;
/* put the length into the record buffer */
- put_length(to, length);
+ store_length(to, packlength, length);
/* put the address of the blob buffer or NULL */
if (length)
@@ -8238,13 +7951,12 @@ Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
/* point to first byte of next field in 'from' */
return from + length;
}
-
+#endif
/** Create a packed key that will be used for storage from a MySQL key. */
-uchar *
-Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
- bool low_byte_first __attribute__((unused)))
+uchar *Field_blob::pack_key_from_key_image(uchar *to, const uchar *from,
+ uint max_length)
{
uint length=uint2korr(from);
if (length > max_length)
@@ -8351,7 +8063,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
goto err;
// Check given WKB
uint32 wkb_type;
- if (length < SRID_SIZE + WKB_HEADER_SIZE + SIZEOF_STORED_DOUBLE*2)
+ if (length < SRID_SIZE + WKB_HEADER_SIZE + 4)
goto err;
wkb_type= uint4korr(from + SRID_SIZE + 1);
if (wkb_type < (uint32) Geometry::wkb_point ||
@@ -8395,39 +8107,7 @@ enum ha_base_keytype Field_enum::key_type() const
void Field_enum::store_type(ulonglong value)
{
- switch (packlength) {
- case 1: ptr[0]= (uchar) value; break;
- case 2:
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int2store(ptr,(unsigned short) value);
- }
- else
-#endif
- shortstore(ptr,(unsigned short) value);
- break;
- case 3: int3store(ptr,(long) value); break;
- case 4:
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int4store(ptr,value);
- }
- else
-#endif
- longstore(ptr,(long) value);
- break;
- case 8:
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int8store(ptr,value);
- }
- else
-#endif
- longlongstore(ptr,value); break;
- }
+ store_lowendian(value, ptr, packlength);
}
@@ -8513,46 +8193,7 @@ double Field_enum::val_real(void)
longlong Field_enum::val_int(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
- switch (packlength) {
- case 1:
- return (longlong) ptr[0];
- case 2:
- {
- uint16 tmp;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- tmp=sint2korr(ptr);
- else
-#endif
- shortget(tmp,ptr);
- return (longlong) tmp;
- }
- case 3:
- return (longlong) uint3korr(ptr);
- case 4:
- {
- uint32 tmp;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- tmp=uint4korr(ptr);
- else
-#endif
- longget(tmp,ptr);
- return (longlong) tmp;
- }
- case 8:
- {
- longlong tmp;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- tmp=sint8korr(ptr);
- else
-#endif
- longlongget(tmp,ptr);
- return tmp;
- }
- }
- return 0; // impossible
+ return read_lowendian(ptr, packlength);
}
@@ -9305,8 +8946,7 @@ void Field_bit::sql_type(String &res) const
uchar *
-Field_bit::pack(uchar *to, const uchar *from, uint max_length,
- bool low_byte_first __attribute__((unused)))
+Field_bit::pack(uchar *to, const uchar *from, uint max_length)
{
DBUG_ASSERT(max_length > 0);
uint length;
@@ -9353,8 +8993,8 @@ Field_bit::pack(uchar *to, const uchar *from, uint max_length,
@return New pointer into memory based on from + length of the data
*/
const uchar *
-Field_bit::unpack(uchar *to, const uchar *from, uint param_data,
- bool low_byte_first __attribute__((unused)))
+Field_bit::unpack(uchar *to, const uchar *from, const uchar *from_end,
+ uint param_data)
{
uint const from_len= (param_data >> 8U) & 0x00ff;
uint const from_bit_len= param_data & 0x00ff;
@@ -9365,6 +9005,9 @@ Field_bit::unpack(uchar *to, const uchar *from, uint param_data,
if (param_data == 0 ||
((from_bit_len == bit_len) && (from_len == bytes_in_rec)))
{
+ if (from + bytes_in_rec + test(bit_len) > from_end)
+ return 0; // Error in data
+
if (bit_len > 0)
{
/*
@@ -9389,10 +9032,16 @@ Field_bit::unpack(uchar *to, const uchar *from, uint param_data,
Lastly the odd bits need to be masked out if the bytes_in_rec > 0.
Otherwise stray bits can cause spurious values.
*/
+
+ uint len= from_len + ((from_bit_len > 0) ? 1 : 0);
uint new_len= (field_length + 7) / 8;
+
+ if (from + len > from_end || new_len < len)
+ return 0; // Error in data
+
char *value= (char *)my_alloca(new_len);
bzero(value, new_len);
- uint len= from_len + ((from_bit_len > 0) ? 1 : 0);
+
memcpy(value + (new_len - len), from, len);
/*
Mask out the unused bits in the partial byte.
@@ -9811,28 +9460,14 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
}
break;
case MYSQL_TYPE_TIMESTAMP:
- if (fld_length == NULL)
+ if (length > MAX_DATETIME_PRECISION)
{
- length= MAX_DATETIME_WIDTH;
- }
- else if (length != MAX_DATETIME_WIDTH)
- {
- /*
- We support only even TIMESTAMP lengths less or equal than 14
- and 19 as length of 4.1 compatible representation. Silently
- shrink it to MAX_DATETIME_COMPRESSED_WIDTH.
- */
- DBUG_ASSERT(MAX_DATETIME_COMPRESSED_WIDTH < UINT_MAX);
- if (length != UINT_MAX) /* avoid overflow; is safe because of min() */
- length= ((length+1)/2)*2;
- length= min(length, MAX_DATETIME_COMPRESSED_WIDTH);
+ my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
+ MAX_DATETIME_PRECISION);
+ DBUG_RETURN(TRUE);
}
- flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
- /*
- Since we silently rewrite down to MAX_DATETIME_COMPRESSED_WIDTH bytes,
- the parser should not raise errors unless bizzarely large.
- */
- max_field_charlength= UINT_MAX;
+ length+= MAX_DATETIME_WIDTH + (length ? 1 : 0);
+ flags|= UNSIGNED_FLAG;
if (fld_default_value)
{
@@ -9880,10 +9515,22 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
length= MAX_DATE_WIDTH;
break;
case MYSQL_TYPE_TIME:
- length= 10;
+ if (length > MAX_DATETIME_PRECISION)
+ {
+ my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
+ MAX_DATETIME_PRECISION);
+ DBUG_RETURN(TRUE);
+ }
+ length+= MIN_TIME_WIDTH + (length ? 1 : 0);
break;
case MYSQL_TYPE_DATETIME:
- length= MAX_DATETIME_WIDTH;
+ if (length > MAX_DATETIME_PRECISION)
+ {
+ my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
+ MAX_DATETIME_PRECISION);
+ DBUG_RETURN(TRUE);
+ }
+ length+= MAX_DATETIME_WIDTH + (length ? 1 : 0);
break;
case MYSQL_TYPE_SET:
{
@@ -10003,14 +9650,22 @@ uint32 calc_pack_length(enum_field_types type,uint32 length)
case MYSQL_TYPE_TINY : return 1;
case MYSQL_TYPE_SHORT : return 2;
case MYSQL_TYPE_INT24:
- case MYSQL_TYPE_NEWDATE:
- case MYSQL_TYPE_TIME: return 3;
+ case MYSQL_TYPE_NEWDATE: return 3;
+ case MYSQL_TYPE_TIME: return length > MIN_TIME_WIDTH
+ ? time_hires_bytes[length - 1 - MIN_TIME_WIDTH]
+ : 3;
case MYSQL_TYPE_TIMESTAMP:
+ return length > MAX_DATETIME_WIDTH
+ ? 4 + sec_part_bytes[length - 1 - MAX_DATETIME_WIDTH]
+ : 4;
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_LONG : return 4;
case MYSQL_TYPE_FLOAT : return sizeof(float);
case MYSQL_TYPE_DOUBLE: return sizeof(double);
case MYSQL_TYPE_DATETIME:
+ return length > MAX_DATETIME_WIDTH
+ ? datetime_hires_bytes[length - 1 - MAX_DATETIME_WIDTH]
+ : 8;
case MYSQL_TYPE_LONGLONG: return 8; /* Don't crash if no longlong */
case MYSQL_TYPE_NULL : return 0;
case MYSQL_TYPE_TINY_BLOB: return 1+portable_sizeof_char_ptr;
@@ -10182,9 +9837,12 @@ Field *make_field(TABLE_SHARE *share, uchar *ptr, uint32 field_length,
f_is_zerofill(pack_flag) != 0,
f_is_dec(pack_flag) == 0);
case MYSQL_TYPE_TIMESTAMP:
- return new Field_timestamp(ptr,field_length, null_pos, null_bit,
- unireg_check, field_name, share,
- field_charset);
+ {
+ uint dec= field_length > MAX_DATETIME_WIDTH ?
+ field_length - MAX_DATETIME_WIDTH - 1: 0;
+ return new_Field_timestamp(ptr, null_pos, null_bit, unireg_check,
+ field_name, share, dec, field_charset);
+ }
case MYSQL_TYPE_YEAR:
return new Field_year(ptr,field_length,null_pos,null_bit,
unireg_check, field_name);
@@ -10195,11 +9853,19 @@ Field *make_field(TABLE_SHARE *share, uchar *ptr, uint32 field_length,
return new Field_newdate(ptr,null_pos,null_bit,
unireg_check, field_name, field_charset);
case MYSQL_TYPE_TIME:
- return new Field_time(ptr,null_pos,null_bit,
- unireg_check, field_name, field_charset);
+ {
+ uint dec= field_length > MIN_TIME_WIDTH ?
+ field_length - MIN_TIME_WIDTH - 1: 0;
+ return new_Field_time(ptr, null_pos, null_bit, unireg_check,
+ field_name, dec, field_charset);
+ }
case MYSQL_TYPE_DATETIME:
- return new Field_datetime(ptr,null_pos,null_bit,
- unireg_check, field_name, field_charset);
+ {
+ uint dec= field_length > MAX_DATETIME_WIDTH ?
+ field_length - MAX_DATETIME_WIDTH - 1: 0;
+ return new_Field_datetime(ptr, null_pos, null_bit, unireg_check,
+ field_name, dec, field_charset);
+ }
case MYSQL_TYPE_NULL:
return new Field_null(ptr, field_length, unireg_check, field_name,
field_charset);
@@ -10383,7 +10049,7 @@ uint32 Field_blob::max_display_length()
0 otherwise
*/
-bool
+void
Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code,
int cuted_increment)
{
@@ -10397,9 +10063,7 @@ Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code,
thd->cuted_fields+= cuted_increment;
push_warning_printf(thd, level, code, ER(code), field_name,
thd->row_count);
- return 0;
}
- return level >= MYSQL_ERROR::WARN_LEVEL_WARN;
}
@@ -10409,7 +10073,6 @@ Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code,
@param level level of message (Note/Warning/Error)
@param code error code of message to be produced
@param str string value which we tried to save
- @param str_length length of string which we tried to save
@param ts_type type of datetime value (datetime/date/time)
@param cuted_increment whenever we should increase cut fields count or not
@@ -10417,80 +10080,42 @@ Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code,
This function will always produce some warning but won't increase cut
fields counter if count_cuted_fields ==FIELD_CHECK_IGNORE for current
thread.
-*/
-
-void
-Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
- const char *str, uint str_length,
- timestamp_type ts_type, int cuted_increment)
-{
- THD *thd= table ? table->in_use : current_thd;
- if ((thd->really_abort_on_warning() &&
- level >= MYSQL_ERROR::WARN_LEVEL_WARN) ||
- set_warning(level, code, cuted_increment))
- make_truncated_value_warning(thd, level, str, str_length, ts_type,
- field_name);
-}
-
-
-/**
- Produce warning or note about integer datetime value saved into field.
- @param level level of message (Note/Warning/Error)
- @param code error code of message to be produced
- @param nr numeric value which we tried to save
- @param ts_type type of datetime value (datetime/date/time)
- @param cuted_increment whenever we should increase cut fields count or not
-
- @note
- This function will always produce some warning but won't increase cut
- fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
- thread.
+ See also bug#2336
*/
-void
-Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
- longlong nr, timestamp_type ts_type,
- int cuted_increment)
+
+void Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level,
+ uint code, const Lazy_string *str,
+ timestamp_type ts_type, int cuted_increment)
{
- THD *thd= table ? table->in_use : current_thd;
- if (thd->really_abort_on_warning() ||
- set_warning(level, code, cuted_increment))
- {
- char str_nr[22];
- char *str_end= longlong10_to_str(nr, str_nr, -10);
- make_truncated_value_warning(thd, level, str_nr, (uint) (str_end - str_nr),
- ts_type, field_name);
- }
+ THD *thd= table->in_use;
+ if (thd->really_abort_on_warning() && level >= MYSQL_ERROR::WARN_LEVEL_WARN)
+ make_truncated_value_warning(thd, level, str, ts_type, field_name);
+ else
+ set_warning(level, code, cuted_increment);
}
-/**
- Produce warning or note about double datetime data saved into field.
-
- @param level level of message (Note/Warning/Error)
- @param code error code of message to be produced
- @param nr double value which we tried to save
- @param ts_type type of datetime value (datetime/date/time)
-
- @note
- This function will always produce some warning but won't increase cut
- fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
- thread.
+/*
+ @brief
+ Return possible keys for a field
+
+ @details
+ Return bit map of keys over this field which can be used by the range
+ optimizer. For a field of a generic table such keys are all keys that starts
+ from this field. For a field of a materialized derived table/view such keys
+ are all keys in which this field takes a part. This is less restrictive as
+ keys for a materialized derived table/view are generated on the fly from
+ present fields, thus the case when a field for the beginning of a key is
+ absent is impossible.
+
+ @return map of possible keys
*/
-void
-Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
- double nr, timestamp_type ts_type)
+key_map Field::get_possible_keys()
{
- THD *thd= table ? table->in_use : current_thd;
- if (thd->really_abort_on_warning() ||
- set_warning(level, code, 1))
- {
- /* DBL_DIG is enough to print '-[digits].E+###' */
- char str_nr[DBL_DIG + 8];
- uint str_len= my_sprintf(str_nr, (str_nr, "%g", nr));
- make_truncated_value_warning(thd, level, str_nr, str_len, ts_type,
- field_name);
- }
+ DBUG_ASSERT(table->pos_in_table_list);
+ return (table->pos_in_table_list->is_materialized_derived() ?
+ part_of_key : key_start);
}
diff --git a/sql/field.h b/sql/field.h
index 308ef788f9e..115a9519b7b 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -27,7 +27,6 @@
#endif
#define NOT_FIXED_DEC 31
-#define DATETIME_DEC 6
const uint32 max_field_size= (uint32) 4294967295U;
class Send_field;
@@ -38,6 +37,9 @@ struct ha_field_option_struct;
struct st_cache_field;
int field_conv(Field *to,Field *from);
+int truncate_double(double *nr, uint field_length, uint dec,
+ bool unsigned_flag, double max_value);
+longlong double_to_longlong(double nr, bool unsigned_flag, bool *error);
inline uint get_enum_pack_length(int elements)
{
@@ -203,7 +205,9 @@ public:
virtual int store(double nr)=0;
virtual int store(longlong nr, bool unsigned_val)=0;
virtual int store_decimal(const my_decimal *d)=0;
- virtual int store_time(MYSQL_TIME *ltime, timestamp_type t_type);
+ virtual int store_time_dec(MYSQL_TIME *ltime, uint dec);
+ int store_time(MYSQL_TIME *ltime)
+ { return store_time_dec(ltime, TIME_SECOND_PART_DIGITS); }
int store(const char *to, uint length, CHARSET_INFO *cs,
enum_check_fields check_level);
virtual double val_real(void)=0;
@@ -231,7 +235,6 @@ public:
virtual bool str_needs_quotes() { return FALSE; }
virtual Item_result result_type () const=0;
virtual Item_result cmp_type () const { return result_type(); }
- virtual Item_result cast_to_int_type () const { return result_type(); }
static bool type_can_have_key_part(enum_field_types);
static enum_field_types field_type_merge(enum_field_types, enum_field_types);
static Item_result result_merge_type(enum_field_types);
@@ -383,17 +386,10 @@ public:
return bytes;
}
+ void make_sort_key(uchar *buff, uint length);
virtual void make_field(Send_field *);
virtual void sort_string(uchar *buff,uint length)=0;
virtual bool optimize_range(uint idx, uint part);
- /*
- This should be true for fields which, when compared with constant
- items, can be casted to longlong. In this case we will at 'fix_fields'
- stage cast the constant items to longlongs and at the execution stage
- use field->val_int() for comparison. Used to optimize clauses like
- 'a_column BETWEEN date_const, date_const'.
- */
- virtual bool can_be_compared_as_longlong() const { return FALSE; }
virtual void free() {}
virtual Field *new_field(MEM_ROOT *root, struct st_table *new_table,
bool keep_type);
@@ -477,45 +473,33 @@ public:
}
virtual bool send_binary(Protocol *protocol);
- virtual uchar *pack(uchar *to, const uchar *from,
- uint max_length, bool low_byte_first);
+ virtual uchar *pack(uchar *to, const uchar *from, uint max_length);
/**
@overload Field::pack(uchar*, const uchar*, uint, bool)
*/
uchar *pack(uchar *to, const uchar *from)
{
DBUG_ENTER("Field::pack");
- uchar *result= this->pack(to, from, UINT_MAX, table->s->db_low_byte_first);
+ uchar *result= this->pack(to, from, UINT_MAX);
DBUG_RETURN(result);
}
virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, bool low_byte_first);
- /**
- @overload Field::unpack(uchar*, const uchar*, uint, bool)
- */
- const uchar *unpack(uchar* to, const uchar *from)
- {
- DBUG_ENTER("Field::unpack");
- const uchar *result= unpack(to, from, 0U, table->s->db_low_byte_first);
- DBUG_RETURN(result);
- }
-
- virtual uchar *pack_key(uchar* to, const uchar *from,
- uint max_length, bool low_byte_first)
+ const uchar *from_end, uint param_data=0);
+ virtual uchar *pack_key(uchar* to, const uchar *from, uint max_length)
{
- return pack(to, from, max_length, low_byte_first);
+ return pack(to, from, max_length);
}
- virtual uchar *pack_key_from_key_image(uchar* to, const uchar *from,
- uint max_length, bool low_byte_first)
+ virtual uchar *pack_key_from_key_image(uchar* to, const uchar *from, uint max_length)
{
- return pack(to, from, max_length, low_byte_first);
+ return pack(to, from, max_length);
}
- virtual const uchar *unpack_key(uchar* to, const uchar *from,
- uint max_length, bool low_byte_first)
+#ifdef NOT_USED
+ virtual const uchar *unpack_key(uchar* to, const uchar *from, uint max_length)
{
- return unpack(to, from, max_length, low_byte_first);
+ return unpack(to, from, from + max_length+2, max_length);
}
+#endif
virtual uint packed_col_length(const uchar *to, uint length)
{ return length;}
virtual uint max_packed_col_length(uint max_length)
@@ -534,7 +518,7 @@ public:
void copy_from_tmp(int offset);
uint fill_cache_field(struct st_cache_field *copy);
virtual bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
- virtual bool get_time(MYSQL_TIME *ltime);
+ bool get_time(MYSQL_TIME *ltime) { return get_date(ltime, TIME_TIME_ONLY); }
virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; }
virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
virtual bool has_charset(void) const { return FALSE; }
@@ -542,16 +526,12 @@ public:
virtual enum Derivation derivation(void) const
{ return DERIVATION_IMPLICIT; }
virtual void set_derivation(enum Derivation derivation_arg) { }
- bool set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code,
+ virtual int set_time() { return 1; }
+ void set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code,
int cuted_increment);
void set_datetime_warning(MYSQL_ERROR::enum_warning_level, uint code,
- const char *str, uint str_len,
- timestamp_type ts_type, int cuted_increment);
- void set_datetime_warning(MYSQL_ERROR::enum_warning_level, uint code,
- longlong nr, timestamp_type ts_type,
+ const Lazy_string *str, timestamp_type ts_type,
int cuted_increment);
- void set_datetime_warning(MYSQL_ERROR::enum_warning_level, const uint code,
- double nr, timestamp_type ts_type);
inline bool check_overflow(int op_result)
{
return (op_result == E_DEC_OVERFLOW);
@@ -593,8 +573,16 @@ public:
DBUG_ASSERT(0);
return GEOM_GEOMETRY;
}
+
+ key_map get_possible_keys();
+
/* 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);
@@ -639,75 +627,26 @@ private:
{ return 0; }
protected:
- /*
- Helper function to pack()/unpack() int32 values
- */
- static void handle_int32(uchar *to, const uchar *from,
- bool low_byte_first_from, bool low_byte_first_to)
+ uchar *pack_int(uchar *to, const uchar *from, size_t size)
{
- int32 val;
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first_from)
- val = sint4korr(from);
- else
-#endif
- longget(val, from);
-
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first_to)
- int4store(to, val);
- else
-#endif
- longstore(to, val);
+ memcpy(to, from, size);
+ return to + size;
}
- /*
- Helper function to pack()/unpack() int64 values
- */
- static void handle_int64(uchar* to, const uchar *from,
- bool low_byte_first_from, bool low_byte_first_to)
+ const uchar *unpack_int(uchar* to, const uchar *from, size_t size)
{
- int64 val;
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first_from)
- val = sint8korr(from);
- else
-#endif
- longlongget(val, from);
-
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first_to)
- int8store(to, val);
- else
-#endif
- longlongstore(to, val);
- }
-
- uchar *pack_int32(uchar *to, const uchar *from, bool low_byte_first_to)
- {
- handle_int32(to, from, table->s->db_low_byte_first, low_byte_first_to);
- return to + sizeof(int32);
- }
-
- const uchar *unpack_int32(uchar* to, const uchar *from,
- bool low_byte_first_from)
- {
- handle_int32(to, from, low_byte_first_from, table->s->db_low_byte_first);
- return from + sizeof(int32);
+ memcpy(to, from, size);
+ return from + size;
}
- uchar *pack_int64(uchar* to, const uchar *from, bool low_byte_first_to)
- {
- handle_int64(to, from, table->s->db_low_byte_first, low_byte_first_to);
- return to + sizeof(int64);
- }
-
- const uchar *unpack_int64(uchar* to, const uchar *from,
- bool low_byte_first_from)
- {
- handle_int64(to, from, low_byte_first_from, table->s->db_low_byte_first);
- return from + sizeof(int64);
- }
+ uchar *pack_int32(uchar *to, const uchar *from)
+ { return pack_int(to, from, 4); }
+ const uchar *unpack_int32(uchar* to, const uchar *from)
+ { return unpack_int(to, from, 4); }
+ uchar *pack_int64(uchar* to, const uchar *from)
+ { return pack_int(to, from, 8); }
+ const uchar *unpack_int64(uchar* to, const uchar *from)
+ { return unpack_int(to, from, 8); }
bool field_flags_are_binary()
{
@@ -725,7 +664,7 @@ public:
uchar null_bit_arg, utype unireg_check_arg,
const char *field_name_arg,
uint8 dec_arg, bool zero_arg, bool unsigned_arg);
- Item_result result_type () const { return REAL_RESULT; }
+ enum Item_result result_type () const { return INT_RESULT; }
void prepend_zeros(String *value);
void add_zerofill_and_unsigned(String &res) const;
friend class Create_field;
@@ -736,6 +675,7 @@ public:
int store_decimal(const my_decimal *);
my_decimal *val_decimal(my_decimal *);
uint is_equal(Create_field *new_field);
+ int store_time_dec(MYSQL_TIME *ltime, uint dec);
int check_int(CHARSET_INFO *cs, const char *str, int length,
const char *int_end, int error);
bool get_int(CHARSET_INFO *cs, const char *from, uint len,
@@ -770,9 +710,9 @@ 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); }
};
-
/* base class for Field_string, Field_varstring and Field_blob */
class Field_longstr :public Field_str
@@ -805,15 +745,13 @@ public:
field_name_arg, dec_arg, zero_arg, unsigned_arg),
not_fixed(dec_arg >= NOT_FIXED_DEC)
{}
+ Item_result result_type () const { return REAL_RESULT; }
int store_decimal(const my_decimal *);
+ int store_time_dec(MYSQL_TIME *ltime, uint dec);
+ bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
my_decimal *val_decimal(my_decimal *);
- int truncate(double *nr, double max_length);
uint32 max_display_length() { return field_length; }
uint size_of() const { return sizeof(*this); }
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, bool low_byte_first);
- virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length, bool low_byte_first);
};
@@ -842,15 +780,9 @@ public:
void overflow(bool negative);
bool zero_pack() const { return 0; }
void sql_type(String &str) const;
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, bool low_byte_first)
+ virtual uchar *pack(uchar* to, const uchar *from, uint max_length)
{
- return Field::unpack(to, from, param_data, low_byte_first);
- }
- virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length, bool low_byte_first)
- {
- return Field::pack(to, from, max_length, low_byte_first);
+ return Field::pack(to, from, max_length);
}
};
@@ -885,7 +817,7 @@ public:
int store(const char *to, uint length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
- int store_time(MYSQL_TIME *ltime, timestamp_type t_type);
+ int store_time_dec(MYSQL_TIME *ltime, uint dec);
int store_decimal(const my_decimal *);
double val_real(void);
longlong val_int(void);
@@ -903,8 +835,7 @@ public:
int compatible_field_size(uint field_metadata,
const Relay_log_info *rli, uint16 mflags);
uint is_equal(Create_field *new_field);
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, bool low_byte_first);
+ virtual const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, uint param_data);
static Field *create_from_item (Item *);
};
@@ -919,7 +850,6 @@ public:
unireg_check_arg, field_name_arg,
0, zero_arg,unsigned_arg)
{}
- enum Item_result result_type () const { return INT_RESULT; }
enum_field_types type() const { return MYSQL_TYPE_TINY;}
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; }
@@ -937,16 +867,17 @@ public:
void sql_type(String &str) const;
uint32 max_display_length() { return 4; }
- virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length, bool low_byte_first)
+ virtual uchar *pack(uchar* to, const uchar *from, uint max_length)
{
*to= *from;
return to + 1;
}
virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, bool low_byte_first)
+ const uchar *from_end, uint param_data)
{
+ if (from == from_end)
+ return 0;
*to= *from;
return from + 1;
}
@@ -968,7 +899,6 @@ public:
:Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, 0, 0, unsigned_arg)
{}
- enum Item_result result_type () const { return INT_RESULT; }
enum_field_types type() const { return MYSQL_TYPE_SHORT;}
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;}
@@ -986,44 +916,24 @@ public:
void sql_type(String &str) const;
uint32 max_display_length() { return 6; }
- virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length, bool low_byte_first)
+ virtual uchar *pack(uchar* to, const uchar *from, uint max_length)
{
int16 val;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- val = sint2korr(from);
- else
-#endif
- shortget(val, from);
-
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first)
- int2store(to, val);
- else
-#endif
- shortstore(to, val);
- return to + sizeof(val);
+ val = sint2korr(from);
+ int2store(to, val);
+ return to + 2;
}
virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, bool low_byte_first)
+ const uchar *from_end, uint param_data)
{
int16 val;
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first)
- val = sint2korr(from);
- else
-#endif
- shortget(val, from);
+ if (from +2 > from_end)
+ return 0;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- int2store(to, val);
- else
-#endif
- shortstore(to, val);
- return from + sizeof(val);
+ val = sint2korr(from);
+ int2store(to, val);
+ return from + 2;
}
};
@@ -1037,7 +947,6 @@ public:
unireg_check_arg, field_name_arg,
0, zero_arg,unsigned_arg)
{}
- enum Item_result result_type () const { return INT_RESULT; }
enum_field_types type() const { return MYSQL_TYPE_INT24;}
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_UINT24 : HA_KEYTYPE_INT24; }
@@ -1055,16 +964,9 @@ public:
void sql_type(String &str) const;
uint32 max_display_length() { return 8; }
- virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length, bool low_byte_first)
- {
- return Field::pack(to, from, max_length, low_byte_first);
- }
-
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, bool low_byte_first)
+ virtual uchar *pack(uchar* to, const uchar *from, uint max_length)
{
- return Field::unpack(to, from, param_data, low_byte_first);
+ return Field::pack(to, from, max_length);
}
};
@@ -1084,7 +986,6 @@ public:
:Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg,0,0,unsigned_arg)
{}
- enum Item_result result_type () const { return INT_RESULT; }
enum_field_types type() const { return MYSQL_TYPE_LONG;}
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; }
@@ -1102,21 +1003,21 @@ public:
void sql_type(String &str) const;
uint32 max_display_length() { return MY_INT32_NUM_DECIMAL_DIGITS; }
virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length __attribute__((unused)),
- bool low_byte_first)
+ uint max_length __attribute__((unused)))
{
- return pack_int32(to, from, low_byte_first);
+ return pack_int32(to, from);
}
virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data __attribute__((unused)),
- bool low_byte_first)
+ const uchar *from_end,
+ uint param_data __attribute__((unused)))
{
- return unpack_int32(to, from, low_byte_first);
+ if (from + 4 > from_end)
+ return 0;
+ return unpack_int32(to, from);
}
};
-#ifdef HAVE_LONG_LONG
class Field_longlong :public Field_num {
public:
Field_longlong(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
@@ -1133,7 +1034,6 @@ public:
:Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg,0,0,unsigned_arg)
{}
- enum Item_result result_type () const { return INT_RESULT; }
enum_field_types type() const { return MYSQL_TYPE_LONGLONG;}
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; }
@@ -1153,22 +1053,20 @@ public:
void sort_string(uchar *buff,uint length);
uint32 pack_length() const { return 8; }
void sql_type(String &str) const;
- bool can_be_compared_as_longlong() const { return TRUE; }
uint32 max_display_length() { return 20; }
virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length __attribute__((unused)),
- bool low_byte_first)
+ uint max_length __attribute__((unused)))
{
- return pack_int64(to, from, low_byte_first);
+ return pack_int64(to, from);
}
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data __attribute__((unused)),
- bool low_byte_first)
+ const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
+ uint param_data __attribute__((unused)))
{
- return unpack_int64(to, from, low_byte_first);
+ if (from + 8 > from_end)
+ return 0;
+ return unpack_int64(to, from);
}
};
-#endif
class Field_float :public Field_real {
@@ -1275,10 +1173,14 @@ public:
void sql_type(String &str) const;
uint size_of() const { return sizeof(*this); }
uint32 max_display_length() { return 4; }
+ void move_field_offset(my_ptrdiff_t ptr_diff) {}
};
class Field_timestamp :public Field_str {
+protected:
+ int store_TIME_with_warning(THD *, MYSQL_TIME *, const Lazy_string *,
+ bool, bool);
public:
Field_timestamp(uchar *ptr_arg, uint32 len_arg,
uchar *null_ptr_arg, uchar null_bit_arg,
@@ -1288,11 +1190,11 @@ public:
CHARSET_INFO *cs);
enum_field_types type() const { return MYSQL_TYPE_TIMESTAMP;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
- enum Item_result cmp_type () const { return INT_RESULT; }
+ enum Item_result cmp_type () const { return TIME_RESULT; }
int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
- int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
+ int store_time_dec(MYSQL_TIME *ltime, uint dec);
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
@@ -1301,9 +1203,9 @@ public:
void sort_string(uchar *buff,uint length);
uint32 pack_length() const { return 4; }
void sql_type(String &str) const;
- bool can_be_compared_as_longlong() const { return TRUE; }
bool zero_pack() const { return 0; }
- void set_time();
+ uint decimals() const { return 0; }
+ virtual int set_time();
virtual void set_default()
{
if (table->timestamp_field == this &&
@@ -1313,46 +1215,68 @@ public:
Field::set_default();
}
/* Get TIMESTAMP field value as seconds since begging of Unix Epoch */
- inline long get_timestamp(bool *null_value)
+ virtual my_time_t get_timestamp(ulong *sec_part) const;
+ virtual void store_TIME(my_time_t timestamp, ulong sec_part)
{
- if ((*null_value= is_null()))
- return 0;
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- return sint4korr(ptr);
-#endif
- long tmp;
- longget(tmp,ptr);
- return tmp;
- }
- inline void store_timestamp(my_time_t timestamp)
- {
-#ifdef WORDS_BIGENDIAN
- if (table && table->s->db_low_byte_first)
- {
- int4store(ptr,timestamp);
- }
- else
-#endif
- longstore(ptr,(uint32) timestamp);
+ int4store(ptr,timestamp);
}
bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
- bool get_time(MYSQL_TIME *ltime);
timestamp_auto_set_type get_auto_set_type() const;
uchar *pack(uchar *to, const uchar *from,
- uint max_length __attribute__((unused)), bool low_byte_first)
+ uint max_length __attribute__((unused)))
{
- return pack_int32(to, from, low_byte_first);
+ return pack_int32(to, from);
}
- const uchar *unpack(uchar* to, const uchar *from,
- uint param_data __attribute__((unused)),
- bool low_byte_first)
+ const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
+ uint param_data __attribute__((unused)))
{
- return unpack_int32(to, from, low_byte_first);
+ if (from + 4 > from_end)
+ return 0;
+ return unpack_int32(to, from);
}
};
+class Field_timestamp_hires :public Field_timestamp {
+ uint dec;
+public:
+ Field_timestamp_hires(uchar *ptr_arg,
+ uchar *null_ptr_arg, uchar null_bit_arg,
+ enum utype unireg_check_arg, const char *field_name_arg,
+ TABLE_SHARE *share, uint dec_arg, CHARSET_INFO *cs) :
+ Field_timestamp(ptr_arg, MAX_DATETIME_WIDTH + dec_arg + 1, null_ptr_arg,
+ null_bit_arg, unireg_check_arg, field_name_arg, share, cs),
+ dec(dec_arg)
+ {
+ DBUG_ASSERT(dec);
+ DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS);
+ }
+ void sql_type(String &str) const;
+ my_time_t get_timestamp(ulong *sec_part) const;
+ void store_TIME(my_time_t timestamp, ulong sec_part);
+ int store_decimal(const my_decimal *d);
+ my_decimal* val_decimal(my_decimal*);
+ double val_real(void);
+ String *val_str(String*,String *);
+ bool send_binary(Protocol *protocol);
+ int cmp(const uchar *,const uchar *);
+ void sort_string(uchar *buff,uint length);
+ uint decimals() const { return dec; }
+ int set_time();
+ enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
+ void make_field(Send_field *field);
+ uint32 pack_length() const;
+ uchar *pack(uchar *to, const uchar *from, uint max_length)
+ { return Field::pack(to, from, max_length); }
+ const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
+ uint param_data)
+ { return Field::unpack(to, from, from_end, param_data); }
+ uint size_of() const { return sizeof(*this); }
+ bool eq_def(Field *field)
+ { return Field_str::eq_def(field) && dec == field->decimals(); }
+};
+
+
class Field_year :public Field_tiny {
public:
Field_year(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
@@ -1365,80 +1289,95 @@ public:
int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
+ int store_time_dec(MYSQL_TIME *ltime, uint dec);
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
+ bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
bool send_binary(Protocol *protocol);
+ uint32 max_display_length() { return field_length; }
void sql_type(String &str) const;
- bool can_be_compared_as_longlong() const { return TRUE; }
};
-class Field_date :public Field_str {
+class Field_temporal: public Field_str {
+protected:
+ int store_TIME_with_warning(MYSQL_TIME *ltime, const Lazy_string *str,
+ int was_cut, int have_smth_to_conv);
+ virtual void store_TIME(MYSQL_TIME *ltime) = 0;
+ virtual timestamp_type temporal_type() = 0;
+public:
+ Field_temporal(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
+ uchar null_bit_arg, utype unireg_check_arg,
+ const char *field_name_arg, CHARSET_INFO *charset_arg)
+ :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
+ field_name_arg, charset_arg) { }
+ enum Item_result cmp_type () const { return TIME_RESULT; }
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr, bool unsigned_val);
+ int store_time_dec(MYSQL_TIME *ltime, uint dec);
+ my_decimal *val_decimal(my_decimal*);
+ bool eq_def(Field *field)
+ {
+ return (Field_str::eq_def(field) && decimals() == field->decimals());
+ }
+};
+
+class Field_date :public Field_temporal {
+ void store_TIME(MYSQL_TIME *ltime);
+ timestamp_type temporal_type()
+ { return MYSQL_TIMESTAMP_DATE; }
public:
Field_date(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
CHARSET_INFO *cs)
- :Field_str(ptr_arg, MAX_DATE_WIDTH, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, cs)
+ :Field_temporal(ptr_arg, MAX_DATE_WIDTH, null_ptr_arg, null_bit_arg,
+ unireg_check_arg, field_name_arg, cs)
{}
- Field_date(bool maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str((uchar*) 0, MAX_DATE_WIDTH, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, cs) {}
enum_field_types type() const { return MYSQL_TYPE_DATE;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
- enum Item_result cmp_type () const { return INT_RESULT; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, bool unsigned_val);
int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
- bool get_time(MYSQL_TIME *ltime);
+ uint decimals() const { return 0; }
bool send_binary(Protocol *protocol);
int cmp(const uchar *,const uchar *);
void sort_string(uchar *buff,uint length);
uint32 pack_length() const { return 4; }
void sql_type(String &str) const;
- bool can_be_compared_as_longlong() const { return TRUE; }
bool zero_pack() const { return 1; }
uchar *pack(uchar* to, const uchar *from,
- uint max_length __attribute__((unused)), bool low_byte_first)
+ uint max_length __attribute__((unused)))
{
- return pack_int32(to, from, low_byte_first);
+ return pack_int32(to, from);
}
- const uchar *unpack(uchar* to, const uchar *from,
- uint param_data __attribute__((unused)),
- bool low_byte_first)
+ const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
+ uint param_data __attribute__((unused)))
{
- return unpack_int32(to, from, low_byte_first);
+ if (from + 4 > from_end)
+ return 0;
+ return unpack_int32(to, from);
}
};
-class Field_newdate :public Field_str {
+class Field_newdate :public Field_temporal {
+ void store_TIME(MYSQL_TIME *ltime);
+ timestamp_type temporal_type() { return MYSQL_TIMESTAMP_DATE; }
public:
Field_newdate(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
CHARSET_INFO *cs)
- :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, cs)
+ :Field_temporal(ptr_arg, MAX_DATE_WIDTH, null_ptr_arg, null_bit_arg,
+ unireg_check_arg, field_name_arg, cs)
{}
- Field_newdate(bool maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str((uchar*) 0,10, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, cs) {}
enum_field_types type() const { return MYSQL_TYPE_DATE;}
enum_field_types real_type() const { return MYSQL_TYPE_NEWDATE; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; }
- enum Item_result cmp_type () const { return INT_RESULT; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, bool unsigned_val);
- int store_time(MYSQL_TIME *ltime, timestamp_type type);
int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
+ uint decimals() const { return 0; }
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
@@ -1447,75 +1386,89 @@ public:
void sort_string(uchar *buff,uint length);
uint32 pack_length() const { return 3; }
void sql_type(String &str) const;
- bool can_be_compared_as_longlong() const { return TRUE; }
bool zero_pack() const { return 1; }
bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
- bool get_time(MYSQL_TIME *ltime);
};
-class Field_time :public Field_str {
+class Field_time :public Field_temporal {
+ void store_TIME(MYSQL_TIME *ltime);
+ timestamp_type temporal_type()
+ { return MYSQL_TIMESTAMP_TIME; }
public:
- Field_time(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str(ptr_arg, 8, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, cs)
+ Field_time(uchar *ptr_arg, uint length_arg, uchar *null_ptr_arg,
+ uchar null_bit_arg, enum utype unireg_check_arg,
+ const char *field_name_arg, CHARSET_INFO *cs)
+ :Field_temporal(ptr_arg, length_arg, null_ptr_arg, null_bit_arg,
+ unireg_check_arg, field_name_arg, cs)
{}
- Field_time(bool maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str((uchar*) 0,8, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, cs) {}
enum_field_types type() const { return MYSQL_TYPE_TIME;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
- enum Item_result cmp_type () const { return INT_RESULT; }
- int store_time(MYSQL_TIME *ltime, timestamp_type type);
+ int store_time_dec(MYSQL_TIME *ltime, uint dec);
int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
- int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
+ uint decimals() const { return 0; }
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
bool send_binary(Protocol *protocol);
- bool get_time(MYSQL_TIME *ltime);
int cmp(const uchar *,const uchar *);
void sort_string(uchar *buff,uint length);
uint32 pack_length() const { return 3; }
void sql_type(String &str) const;
- bool can_be_compared_as_longlong() const { return TRUE; }
bool zero_pack() const { return 1; }
};
+class Field_time_hires :public Field_time {
+ uint dec;
+ longlong zero_point;
+ void store_TIME(MYSQL_TIME *ltime);
+public:
+ Field_time_hires(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
+ enum utype unireg_check_arg, const char *field_name_arg,
+ uint dec_arg, CHARSET_INFO *cs)
+ :Field_time(ptr_arg, MIN_TIME_WIDTH + dec_arg + 1, null_ptr_arg,
+ null_bit_arg, unireg_check_arg, field_name_arg, cs),
+ dec(dec_arg)
+ {
+ DBUG_ASSERT(dec);
+ DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS);
+ zero_point= sec_part_shift(
+ ((TIME_MAX_VALUE_SECONDS+1LL)*TIME_SECOND_PART_FACTOR), dec);
+ }
+ enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
+ uint decimals() const { return dec; }
+ int store_decimal(const my_decimal *d);
+ longlong val_int(void);
+ double val_real(void);
+ String *val_str(String*,String *);
+ int reset(void);
+ bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
+ bool send_binary(Protocol *protocol);
+ int cmp(const uchar *,const uchar *);
+ void sort_string(uchar *buff,uint length);
+ uint32 pack_length() const;
+ void sql_type(String &str) const;
+ void make_field(Send_field *);
+ uint size_of() const { return sizeof(*this); }
+};
-class Field_datetime :public Field_str {
+class Field_datetime :public Field_temporal {
+ void store_TIME(MYSQL_TIME *ltime);
+ timestamp_type temporal_type()
+ { return MYSQL_TIMESTAMP_DATETIME; }
public:
- Field_datetime(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str(ptr_arg, MAX_DATETIME_WIDTH, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, cs)
+ Field_datetime(uchar *ptr_arg, uint length_arg, uchar *null_ptr_arg,
+ uchar null_bit_arg, enum utype unireg_check_arg,
+ const char *field_name_arg, CHARSET_INFO *cs)
+ :Field_temporal(ptr_arg, length_arg, null_ptr_arg, null_bit_arg,
+ unireg_check_arg, field_name_arg, cs)
{}
- Field_datetime(bool maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str((uchar*) 0, MAX_DATETIME_WIDTH, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, cs) {}
enum_field_types type() const { return MYSQL_TYPE_DATETIME;}
-#ifdef HAVE_LONG_LONG
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
-#endif
- enum Item_result cmp_type () const { return INT_RESULT; }
- uint decimals() const { return DATETIME_DEC; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, bool unsigned_val);
- int store_time(MYSQL_TIME *ltime, timestamp_type type);
- int reset(void)
- {
- ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0;
- return 0;
- }
+ uint decimals() const { return 0; }
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
@@ -1524,24 +1477,101 @@ public:
void sort_string(uchar *buff,uint length);
uint32 pack_length() const { return 8; }
void sql_type(String &str) const;
- bool can_be_compared_as_longlong() const { return TRUE; }
bool zero_pack() const { return 1; }
bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
- bool get_time(MYSQL_TIME *ltime);
uchar *pack(uchar* to, const uchar *from,
- uint max_length __attribute__((unused)), bool low_byte_first)
+ uint max_length __attribute__((unused)))
{
- return pack_int64(to, from, low_byte_first);
+ return pack_int64(to, from);
}
- const uchar *unpack(uchar* to, const uchar *from,
- uint param_data __attribute__((unused)),
- bool low_byte_first)
+ const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
+ uint param_data __attribute__((unused)))
{
- return unpack_int64(to, from, low_byte_first);
+ if (from + 8 > from_end)
+ return 0;
+ return unpack_int64(to, from);
}
};
+class Field_datetime_hires :public Field_datetime {
+ void store_TIME(MYSQL_TIME *ltime);
+ uint dec;
+public:
+ Field_datetime_hires(uchar *ptr_arg, uchar *null_ptr_arg,
+ uchar null_bit_arg, enum utype unireg_check_arg,
+ const char *field_name_arg, uint dec_arg,
+ CHARSET_INFO *cs)
+ :Field_datetime(ptr_arg, MAX_DATETIME_WIDTH + dec_arg + 1,
+ null_ptr_arg, null_bit_arg, unireg_check_arg,
+ field_name_arg, cs), dec(dec_arg)
+ {
+ DBUG_ASSERT(dec);
+ DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS);
+ }
+ enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
+ uint decimals() const { return dec; }
+ void make_field(Send_field *field);
+ int store_decimal(const my_decimal *d);
+ double val_real(void);
+ longlong val_int(void);
+ String *val_str(String*,String *);
+ bool send_binary(Protocol *protocol);
+ int cmp(const uchar *,const uchar *);
+ void sort_string(uchar *buff,uint length);
+ uint32 pack_length() const;
+ void sql_type(String &str) const;
+ bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
+ uchar *pack(uchar *to, const uchar *from, uint max_length)
+ { return Field::pack(to, from, max_length); }
+ const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
+ uint param_data)
+ { return Field::unpack(to, from, from_end, param_data); }
+ uint size_of() const { return sizeof(*this); }
+};
+
+static inline Field_timestamp *
+new_Field_timestamp(uchar *ptr, uchar *null_ptr, uchar null_bit,
+ enum Field::utype unireg_check, const char *field_name,
+ TABLE_SHARE *share, uint dec, CHARSET_INFO *cs)
+{
+ if (dec==0)
+ return new Field_timestamp(ptr, MAX_DATETIME_WIDTH, null_ptr, null_bit,
+ unireg_check, field_name, share, cs);
+ if (dec == NOT_FIXED_DEC)
+ dec= MAX_DATETIME_PRECISION;
+ return new Field_timestamp_hires(ptr, null_ptr, null_bit, unireg_check,
+ field_name, share, dec, cs);
+}
+
+static inline Field_time *
+new_Field_time(uchar *ptr, uchar *null_ptr, uchar null_bit,
+ enum Field::utype unireg_check, const char *field_name,
+ uint dec, CHARSET_INFO *cs)
+{
+ if (dec == 0)
+ return new Field_time(ptr, MIN_TIME_WIDTH, null_ptr, null_bit,
+ unireg_check, field_name, cs);
+ if (dec == NOT_FIXED_DEC)
+ dec= MAX_DATETIME_PRECISION;
+ return new Field_time_hires(ptr, null_ptr, null_bit,
+ unireg_check, field_name, dec, cs);
+}
+
+static inline Field_datetime *
+new_Field_datetime(uchar *ptr, uchar *null_ptr, uchar null_bit,
+ enum Field::utype unireg_check,
+ const char *field_name, uint dec, CHARSET_INFO *cs)
+{
+ if (dec == 0)
+ return new Field_datetime(ptr, MAX_DATETIME_WIDTH, null_ptr, null_bit,
+ unireg_check, field_name, cs);
+ if (dec == NOT_FIXED_DEC)
+ dec= MAX_DATETIME_PRECISION;
+ return new Field_datetime_hires(ptr, null_ptr, null_bit,
+ unireg_check, field_name, dec, cs);
+}
+
class Field_string :public Field_longstr {
public:
bool can_alter_field_type;
@@ -1586,9 +1616,9 @@ public:
void sort_string(uchar *buff,uint length);
void sql_type(String &str) const;
virtual uchar *pack(uchar *to, const uchar *from,
- uint max_length, bool low_byte_first);
+ uint max_length);
virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, bool low_byte_first);
+ const uchar *from_end,uint param_data);
uint pack_length_from_metadata(uint field_metadata)
{
DBUG_PRINT("debug", ("field_metadata: 0x%04x", field_metadata));
@@ -1673,15 +1703,14 @@ public:
uint get_key_image(uchar *buff,uint length, imagetype type);
void set_key_image(const uchar *buff,uint length);
void sql_type(String &str) const;
- virtual uchar *pack(uchar *to, const uchar *from,
- uint max_length, bool low_byte_first);
- uchar *pack_key(uchar *to, const uchar *from, uint max_length, bool low_byte_first);
- uchar *pack_key_from_key_image(uchar* to, const uchar *from,
- uint max_length, bool low_byte_first);
+ virtual uchar *pack(uchar *to, const uchar *from, uint max_length);
+ uchar *pack_key(uchar *to, const uchar *from, uint max_length);
+ uchar *pack_key_from_key_image(uchar* to, const uchar *from, uint max_length);
virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, bool low_byte_first);
- const uchar *unpack_key(uchar* to, const uchar *from,
- uint max_length, bool low_byte_first);
+ const uchar *from_end, uint param_data);
+#ifdef NOT_USED
+ const uchar *unpack_key(uchar* to, const uchar *from, uint max_length);
+#endif
int pack_cmp(const uchar *a, const uchar *b, uint key_length,
bool insert_or_update);
int pack_cmp(const uchar *b, uint key_length,bool insert_or_update);
@@ -1789,14 +1818,7 @@ public:
int reset(void) { bzero(ptr, packlength+sizeof(uchar*)); return 0; }
void reset_fields() { bzero((uchar*) &value,sizeof(value)); }
uint32 get_field_buffer_size(void) { return value.alloced_length(); }
-#ifndef WORDS_BIGENDIAN
- static
-#endif
- void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number, bool low_byte_first);
- void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number)
- {
- store_length(i_ptr, i_packlength, i_number, table->s->db_low_byte_first);
- }
+ void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number);
inline void store_length(uint32 number)
{
store_length(ptr, packlength, number);
@@ -1810,38 +1832,37 @@ public:
@returns The length in the row plus the size of the data.
*/
- uint32 get_packed_size(const uchar *ptr_arg, bool low_byte_first)
- {return packlength + get_length(ptr_arg, packlength, low_byte_first);}
+ uint32 get_packed_size(const uchar *ptr_arg)
+ {return packlength + get_length(ptr_arg, packlength);}
inline uint32 get_length(uint row_offset= 0)
- { return get_length(ptr+row_offset, this->packlength, table->s->db_low_byte_first); }
- uint32 get_length(const uchar *ptr, uint packlength, bool low_byte_first);
+ { return get_length(ptr+row_offset, this->packlength); }
+ uint32 get_length(const uchar *ptr, uint packlength);
uint32 get_length(const uchar *ptr_arg)
- { return get_length(ptr_arg, this->packlength, table->s->db_low_byte_first); }
- void put_length(uchar *pos, uint32 length);
+ { return get_length(ptr_arg, this->packlength); }
inline void get_ptr(uchar **str)
- {
- memcpy_fixed((uchar*) str,ptr+packlength,sizeof(uchar*));
- }
+ {
+ memcpy_fixed((uchar*) str,ptr+packlength,sizeof(uchar*));
+ }
inline void get_ptr(uchar **str, uint row_offset)
- {
- memcpy_fixed((uchar*) str,ptr+packlength+row_offset,sizeof(char*));
- }
+ {
+ memcpy_fixed((uchar*) str,ptr+packlength+row_offset,sizeof(char*));
+ }
inline void set_ptr(uchar *length, uchar *data)
- {
- memcpy(ptr,length,packlength);
- memcpy_fixed(ptr+packlength,&data,sizeof(char*));
- }
+ {
+ memcpy(ptr,length,packlength);
+ memcpy_fixed(ptr+packlength,&data,sizeof(char*));
+ }
void set_ptr_offset(my_ptrdiff_t ptr_diff, uint32 length, uchar *data)
- {
- uchar *ptr_ofs= ADD_TO_PTR(ptr,ptr_diff,uchar*);
- store_length(ptr_ofs, packlength, length);
- memcpy_fixed(ptr_ofs+packlength,&data,sizeof(char*));
- }
+ {
+ uchar *ptr_ofs= ADD_TO_PTR(ptr,ptr_diff,uchar*);
+ store_length(ptr_ofs, packlength, length);
+ memcpy_fixed(ptr_ofs+packlength,&data,sizeof(char*));
+ }
inline void set_ptr(uint32 length, uchar *data)
- {
- set_ptr_offset(0, length, data);
- }
+ {
+ set_ptr_offset(0, length, data);
+ }
uint get_key_image(uchar *buff,uint length, imagetype type);
void set_key_image(const uchar *buff,uint length);
void sql_type(String &str) const;
@@ -1858,21 +1879,20 @@ public:
memcpy_fixed(ptr+packlength,&tmp,sizeof(char*));
return 0;
}
- virtual uchar *pack(uchar *to, const uchar *from,
- uint max_length, bool low_byte_first);
- uchar *pack_key(uchar *to, const uchar *from,
- uint max_length, bool low_byte_first);
- uchar *pack_key_from_key_image(uchar* to, const uchar *from,
- uint max_length, bool low_byte_first);
+ virtual uchar *pack(uchar *to, const uchar *from, uint max_length);
+ uchar *pack_key(uchar *to, const uchar *from, uint max_length);
+ uchar *pack_key_from_key_image(uchar* to, const uchar *from, uint max_length);
virtual const uchar *unpack(uchar *to, const uchar *from,
- uint param_data, bool low_byte_first);
- const uchar *unpack_key(uchar* to, const uchar *from,
- uint max_length, bool low_byte_first);
+ const uchar *from_end, uint param_data);
+#ifdef NOT_USED
+ const uchar *unpack_key(uchar* to, const uchar *from, uint max_length);
+#endif
int pack_cmp(const uchar *a, const uchar *b, uint key_length,
bool insert_or_update);
int pack_cmp(const uchar *b, uint key_length,bool insert_or_update);
uint packed_col_length(const uchar *col_ptr, uint length);
uint max_packed_col_length(uint max_length);
+ /* Set if we should convert constant item's with convert_const_item */
void free() { value.free(); }
inline void clear_temporary() { bzero((uchar*) &value,sizeof(value)); }
friend int field_conv(Field *to,Field *from);
@@ -1914,6 +1934,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*/
@@ -1938,7 +1959,6 @@ public:
Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type);
enum_field_types type() const { return MYSQL_TYPE_STRING; }
enum Item_result cmp_type () const { return INT_RESULT; }
- enum Item_result cast_to_int_type () const { return INT_RESULT; }
enum ha_base_keytype key_type() const;
int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr);
@@ -2068,10 +2088,9 @@ public:
int compatible_field_size(uint field_metadata,
const Relay_log_info *rli, uint16 mflags);
void sql_type(String &str) const;
- virtual uchar *pack(uchar *to, const uchar *from,
- uint max_length, bool low_byte_first);
+ virtual uchar *pack(uchar *to, const uchar *from, uint max_length);
virtual const uchar *unpack(uchar *to, const uchar *from,
- uint param_data, bool low_byte_first);
+ const uchar *from_end, uint param_data);
virtual void set_default();
Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 4bfab353dcc..a64b77bf500 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -117,6 +117,11 @@ static void do_outer_field_to_null_str(Copy_field *copy)
int
set_field_to_null(Field *field)
{
+ if (field->table->null_catch_flags & CHECK_ROW_FOR_NULLS_TO_REJECT)
+ {
+ field->table->null_catch_flags|= REJECT_ROW_DUE_TO_NULL_FIELDS;
+ return -1;
+ }
if (field->real_maybe_null())
{
field->set_null();
@@ -160,6 +165,11 @@ set_field_to_null(Field *field)
int
set_field_to_null_with_conversions(Field *field, bool no_conversions)
{
+ if (field->table->null_catch_flags & CHECK_ROW_FOR_NULLS_TO_REJECT)
+ {
+ field->table->null_catch_flags|= REJECT_ROW_DUE_TO_NULL_FIELDS;
+ return -1;
+ }
if (field->real_maybe_null())
{
field->set_null();
@@ -206,6 +216,14 @@ static void do_skip(Copy_field *copy __attribute__((unused)))
}
+/*
+ Copy: (NULLable field) -> (NULLable field)
+
+ note: if the record we're copying from is NULL-complemetned (i.e.
+ from_field->table->null_row==1), it will also have all NULLable columns to be
+ set to NULLs, so we dont need to check table->null_row here.
+*/
+
static void do_copy_null(Copy_field *copy)
{
if (*copy->from_null_ptr & copy->from_bit)
@@ -220,6 +238,10 @@ static void do_copy_null(Copy_field *copy)
}
}
+/*
+ Copy: (not-NULL field in table that can be NULL-complemented) -> (NULLable
+ field)
+*/
static void do_outer_field_null(Copy_field *copy)
{
@@ -236,7 +258,27 @@ static void do_outer_field_null(Copy_field *copy)
}
}
+/*
+ Copy: (not-NULL field in table that can be NULL-complemented) -> (not-NULL
+ field)
+*/
+static void do_copy_nullable_row_to_notnull(Copy_field *copy)
+{
+ if (*copy->null_row ||
+ (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
+ {
+ copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
+ WARN_DATA_TRUNCATED, 1);
+ copy->to_field->reset();
+ }
+ else
+ {
+ (copy->do_copy2)(copy);
+ }
+}
+
+/* Copy: (NULL-able field) -> (not NULL-able field) */
static void do_copy_not_null(Copy_field *copy)
{
if (*copy->from_null_ptr & copy->from_bit)
@@ -250,6 +292,7 @@ static void do_copy_not_null(Copy_field *copy)
}
+/* Copy: (non-NULLable field) -> (NULLable field) */
static void do_copy_maybe_null(Copy_field *copy)
{
*copy->to_null_ptr&= ~copy->to_bit;
@@ -367,6 +410,14 @@ static void do_field_decimal(Copy_field *copy)
}
+static void do_field_temporal(Copy_field *copy)
+{
+ MYSQL_TIME ltime;
+ copy->from_field->get_date(&ltime, TIME_FUZZY_DATE);
+ copy->to_field->store_time_dec(&ltime, copy->from_field->decimals());
+}
+
+
/**
string copy for single byte characters set when to string is shorter than
from string.
@@ -451,7 +502,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);
}
@@ -487,7 +539,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);
}
@@ -551,9 +604,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;
}
}
@@ -561,7 +614,7 @@ void Copy_field::set(uchar *to,Field *from)
/*
To do:
- If 'save\ is set to true and the 'from' is a blob field, do_copy is set to
+ If 'save' is set to true and the 'from' is a blob field, do_copy is set to
do_save_blob rather than do_conv_blob. The only differences between them
appears to be:
@@ -614,7 +667,15 @@ void Copy_field::set(Field *to,Field *from,bool save)
else if (to_field == to_field->table->next_number_field)
do_copy= do_copy_next_number;
else
- do_copy= do_copy_not_null;
+ {
+ if (!from_null_ptr)
+ {
+ null_row= &from->table->null_row;
+ do_copy= do_copy_nullable_row_to_notnull;
+ }
+ else
+ do_copy= do_copy_not_null;
+ }
}
}
else if (to_field->real_maybe_null())
@@ -638,13 +699,11 @@ void Copy_field::set(Field *to,Field *from,bool save)
Copy_field::Copy_func *
Copy_field::get_copy_func(Field *to,Field *from)
{
- bool compatible_db_low_byte_first= (to->table->s->db_low_byte_first ==
- from->table->s->db_low_byte_first);
if (to->flags & BLOB_FLAG)
{
if (!(from->flags & BLOB_FLAG) || from->charset() != to->charset())
return do_conv_blob;
- if (from_length != to_length || !compatible_db_low_byte_first)
+ if (from_length != to_length)
{
// Correct pointer to point at char pointer
to_ptr+= to_length - to->table->s->blob_ptr_size;
@@ -659,6 +718,16 @@ Copy_field::get_copy_func(Field *to,Field *from)
return do_field_int;
if (to->result_type() == DECIMAL_RESULT)
return do_field_decimal;
+ if (from->cmp_type() == TIME_RESULT)
+ {
+ /* If types are not 100 % identical then convert trough get_date() */
+ if (!to->eq_def(from) ||
+ ((to->table->in_use->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE)) &&
+ mysql_type_to_time_type(to->type()) != MYSQL_TIMESTAMP_TIME))
+ return do_field_temporal;
+ /* Do binary copy */
+ }
// Check if identical fields
if (from->result_type() == STRING_RESULT)
{
@@ -671,16 +740,7 @@ Copy_field::get_copy_func(Field *to,Field *from)
to->type() == MYSQL_TYPE_VARCHAR && !to->has_charset())
return do_field_varbinary_pre50;
- /*
- If we are copying date or datetime's we have to check the dates
- if we don't allow 'all' dates.
- */
- if (to->real_type() != from->real_type() ||
- !compatible_db_low_byte_first ||
- ((to->table->in_use->variables.sql_mode &
- (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) &&
- (to->type() == MYSQL_TYPE_DATE ||
- to->type() == MYSQL_TYPE_DATETIME)))
+ if (to->real_type() != from->real_type())
{
if (from->real_type() == MYSQL_TYPE_ENUM ||
from->real_type() == MYSQL_TYPE_SET)
@@ -706,12 +766,11 @@ Copy_field::get_copy_func(Field *to,Field *from)
if (((Field_varstring*) to)->length_bytes !=
((Field_varstring*) from)->length_bytes)
return do_field_string;
- else
- return (((Field_varstring*) to)->length_bytes == 1 ?
- (from->charset()->mbmaxlen == 1 ? do_varstring1 :
- do_varstring1_mb) :
- (from->charset()->mbmaxlen == 1 ? do_varstring2 :
- do_varstring2_mb));
+ return (((Field_varstring*) to)->length_bytes == 1 ?
+ (from->charset()->mbmaxlen == 1 ? do_varstring1 :
+ do_varstring1_mb) :
+ (from->charset()->mbmaxlen == 1 ? do_varstring2 :
+ do_varstring2_mb));
}
else if (to_length < from_length)
return (from->charset()->mbmaxlen == 1 ?
@@ -724,8 +783,7 @@ Copy_field::get_copy_func(Field *to,Field *from)
}
}
else if (to->real_type() != from->real_type() ||
- to_length != from_length ||
- !compatible_db_low_byte_first)
+ to_length != from_length)
{
if (to->real_type() == MYSQL_TYPE_DECIMAL ||
to->result_type() == STRING_RESULT)
@@ -736,7 +794,7 @@ Copy_field::get_copy_func(Field *to,Field *from)
}
else
{
- if (!to->eq_def(from) || !compatible_db_low_byte_first)
+ if (!to->eq_def(from))
{
if (to->real_type() == MYSQL_TYPE_DECIMAL)
return do_field_string;
@@ -769,14 +827,13 @@ int field_conv(Field *to,Field *from)
{
if (to->pack_length() == from->pack_length() &&
!(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) &&
+ to->decimals() == from->decimals() &&
to->real_type() != MYSQL_TYPE_ENUM &&
to->real_type() != MYSQL_TYPE_SET &&
to->real_type() != MYSQL_TYPE_BIT &&
(to->real_type() != MYSQL_TYPE_NEWDECIMAL ||
- ((to->field_length == from->field_length &&
- (((Field_num*)to)->dec == ((Field_num*)from)->dec)))) &&
+ to->field_length == from->field_length) &&
from->charset() == to->charset() &&
- to->table->s->db_low_byte_first == from->table->s->db_low_byte_first &&
(!(to->table->in_use->variables.sql_mode &
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) ||
(to->type() != MYSQL_TYPE_DATE &&
@@ -817,7 +874,22 @@ int field_conv(Field *to,Field *from)
((Field_enum *)(to))->store_type(0);
return 0;
}
- else if ((from->result_type() == STRING_RESULT &&
+ if (from->result_type() == REAL_RESULT)
+ return to->store(from->val_real());
+ if (from->result_type() == DECIMAL_RESULT)
+ {
+ my_decimal buff;
+ return to->store_decimal(from->val_decimal(&buff));
+ }
+ if (from->cmp_type() == TIME_RESULT)
+ {
+ MYSQL_TIME ltime;
+ if (from->get_date(&ltime, TIME_FUZZY_DATE))
+ return to->reset();
+ else
+ return to->store_time_dec(&ltime, from->decimals());
+ }
+ if ((from->result_type() == STRING_RESULT &&
(to->result_type() == STRING_RESULT ||
(from->real_type() != MYSQL_TYPE_ENUM &&
from->real_type() != MYSQL_TYPE_SET))) ||
@@ -834,13 +906,5 @@ int field_conv(Field *to,Field *from)
*/
return to->store(result.c_ptr_quick(),result.length(),from->charset());
}
- else if (from->result_type() == REAL_RESULT)
- return to->store(from->val_real());
- else if (from->result_type() == DECIMAL_RESULT)
- {
- my_decimal buff;
- return to->store_decimal(from->val_decimal(&buff));
- }
- else
- return to->store(from->val_int(), test(from->flags & UNSIGNED_FLAG));
+ return to->store(from->val_int(), test(from->flags & UNSIGNED_FLAG));
}
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 2ebfb59fa32..703264b7ef5 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -41,22 +41,16 @@ if (my_b_write((file),(uchar*) (from),param->ref_length)) \
/* functions defined in this file */
-static size_t char_array_size(uint fields, uint length);
-static uchar **make_char_array(uchar **old_pos, uint fields,
- uint length, myf my_flag);
static uchar *read_buffpek_from_file(IO_CACHE *buffer_file, uint count,
uchar *buf);
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
- uchar * *sort_keys, IO_CACHE *buffer_file,
+ uchar * *sort_keys, uchar *sort_keys_buf,
+ IO_CACHE *buffer_file,
IO_CACHE *tempfile,IO_CACHE *indexfile);
static int write_keys(SORTPARAM *param,uchar * *sort_keys,
uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
static void make_sortkey(SORTPARAM *param,uchar *to, uchar *ref_pos);
static void register_used_fields(SORTPARAM *param);
-static int merge_index(SORTPARAM *param,uchar *sort_buffer,
- BUFFPEK *buffpek,
- uint maxbuffer,IO_CACHE *tempfile,
- IO_CACHE *outfile);
static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count,
FILESORT_INFO *table_sort);
static uint suffix_length(ulong string_length);
@@ -65,7 +59,7 @@ static uint sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
uint sortlength, uint *plength);
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
- uchar *buff);
+ uchar *buff, uchar *buff_end);
/**
Sort a table.
Creates a set of pointers that can be used to read the rows
@@ -108,6 +102,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
{
int error;
ulong memavl, min_sort_memory;
+ ulong sort_buff_sz;
uint maxbuffer;
BUFFPEK *buffpek;
ha_rows records= HA_POS_ERROR;
@@ -146,8 +141,6 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
bzero((char*) &param,sizeof(param));
param.sort_length= sortlength(thd, sortorder, s_length, &multi_byte_charset);
param.ref_length= table->file->ref_length;
- param.addon_field= 0;
- param.addon_length= 0;
if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&
!table->fulltext_searched && !sort_positions)
{
@@ -218,45 +211,41 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
memavl= thd->variables.sortbuff_size;
min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
- while (memavl >= min_sort_memory)
+ set_if_bigger(min_sort_memory, sizeof(BUFFPEK*)*MERGEBUFF2);
+ if (!table_sort.sort_keys)
{
- ulong old_memavl;
- ulong keys= memavl/(param.rec_length+sizeof(char*));
- param.keys=(uint) min(records+1, keys);
-
- if (table_sort.sort_keys &&
- table_sort.sort_keys_size != char_array_size(param.keys,
- param.rec_length))
- {
- x_free((uchar*) table_sort.sort_keys);
- table_sort.sort_keys= NULL;
- table_sort.sort_keys_size= 0;
- }
- if ((table_sort.sort_keys=
- make_char_array(table_sort.sort_keys,
- param.keys, param.rec_length, MYF(0))))
+ while (memavl >= min_sort_memory)
{
- table_sort.sort_keys_size= char_array_size(param.keys, param.rec_length);
- break;
+ ulong old_memavl;
+ ulong keys= memavl/(param.rec_length+sizeof(char*));
+ table_sort.keys= (uint) min(records+1, keys);
+ sort_buff_sz= table_sort.keys*(param.rec_length+sizeof(char*));
+ set_if_bigger(sort_buff_sz, param.rec_length * MERGEBUFF2);
+ if ((table_sort.sort_keys=
+ (uchar**) my_malloc(sort_buff_sz, MYF(0))))
+ break;
+ old_memavl=memavl;
+ if ((memavl=memavl/4*3) < min_sort_memory &&
+ old_memavl > min_sort_memory)
+ memavl= min_sort_memory;
}
- old_memavl=memavl;
- if ((memavl=memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
- memavl= min_sort_memory;
}
+
sort_keys= table_sort.sort_keys;
+ param.keys= table_sort.keys - 1; /* TODO: check why we do this " - 1" */
if (memavl < min_sort_memory)
{
my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG));
goto err;
}
if (open_cached_file(&buffpek_pointers,mysql_tmpdir,TEMP_PREFIX,
- DISK_BUFFER_SIZE, MYF(MY_WME)))
+ DISK_BUFFER_SIZE, MYF(ME_ERROR | MY_WME)))
goto err;
- param.keys--; /* TODO: check why we do this */
param.sort_form= table;
param.end=(param.local_sortorder=sortorder)+s_length;
- if ((records=find_all_keys(&param,select,sort_keys, &buffpek_pointers,
+ if ((records=find_all_keys(&param,select,sort_keys,
+ (uchar *)(sort_keys+param.keys), &buffpek_pointers,
&tempfile, selected_records_file)) ==
HA_POS_ERROR)
goto err;
@@ -287,7 +276,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
/* Open cached file if it isn't open */
if (! my_b_inited(outfile) &&
open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
- MYF(MY_WME)))
+ MYF(ME_ERROR | MY_WME)))
goto err;
if (reinit_io_cache(outfile,WRITE_CACHE,0L,0,0))
goto err;
@@ -296,7 +285,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
Use also the space previously used by string pointers in sort_buffer
for temporary key storage.
*/
- param.keys= table_sort.sort_keys_size / param.rec_length;
+ param.keys=((param.keys*(param.rec_length+sizeof(char*))) /
+ param.rec_length-1);
maxbuffer--; // Offset from 0
if (merge_many_buff(&param,(uchar*) sort_keys,buffpek,&maxbuffer,
&tempfile))
@@ -319,7 +309,6 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
{
x_free((uchar*) sort_keys);
table_sort.sort_keys= 0;
- table_sort.sort_keys_size= 0;
x_free((uchar*) buffpek);
table_sort.buffpek= 0;
table_sort.buffpek_len= 0;
@@ -339,8 +328,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
}
}
if (error)
- my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT),
- MYF(ME_ERROR+ME_WAITTANG));
+ my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT), MYF(0));
else
statistic_add(thd->status_var.filesort_rows,
(ulong) records, &LOCK_status);
@@ -367,7 +355,6 @@ void filesort_free_buffers(TABLE *table, bool full)
{
x_free((uchar*) table->sort.sort_keys);
table->sort.sort_keys= 0;
- table->sort.sort_keys_size= 0;
}
if (table->sort.buffpek)
{
@@ -385,35 +372,6 @@ void filesort_free_buffers(TABLE *table, bool full)
}
}
-/** Make a array of string pointers. */
-
-static size_t char_array_size(uint fields, uint length)
-{
- return fields * (length + sizeof(uchar*));
-}
-
-
-static uchar **make_char_array(uchar **old_pos, uint fields,
- uint length, myf my_flag)
-{
- register uchar **pos;
- uchar *char_pos;
- DBUG_ENTER("make_char_array");
-
- if (old_pos ||
- (old_pos= (uchar**) my_malloc(char_array_size(fields, length), my_flag)))
- {
- pos=old_pos;
- char_pos= ((uchar*)(pos+fields)) -length;
- while (fields--)
- {
- *(pos++) = (char_pos+= length);
- }
- }
-
- DBUG_RETURN(old_pos);
-} /* make_char_array */
-
/** Read 'count' number of buffer pointers into memory. */
@@ -528,7 +486,7 @@ static void dbug_print_record(TABLE *table, bool print_rowid)
*/
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
- uchar **sort_keys,
+ uchar **sort_keys, uchar *sort_keys_buf,
IO_CACHE *buffpek_pointers,
IO_CACHE *tempfile, IO_CACHE *indexfile)
{
@@ -538,9 +496,10 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
my_off_t record;
TABLE *sort_form;
THD *thd= current_thd;
- volatile THD::killed_state *killed= &thd->killed;
+ volatile killed_state *killed= &thd->killed;
handler *file;
MY_BITMAP *save_read_set, *save_write_set, *save_vcol_set;
+ uchar *next_sort_key= sort_keys_buf;
DBUG_ENTER("find_all_keys");
DBUG_PRINT("info",("using: %s",
(select ? select->quick ? "ranges" : "where":
@@ -568,11 +527,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;
@@ -583,19 +537,28 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
/* Temporary set for register_used_fields and register_field_in_read_map */
sort_form->read_set= &sort_form->tmp_set;
register_used_fields(param);
- if (select && select->cond)
- select->cond->walk(&Item::register_field_in_read_map, 1,
- (uchar*) sort_form);
+ Item *sort_cond= !select ?
+ 0 : !select->pre_idx_push_select_cond ?
+ select->cond : select->pre_idx_push_select_cond;
+ if (sort_cond)
+ sort_cond->walk(&Item::register_field_in_read_map, 1, (uchar*) sort_form);
sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set,
&sort_form->tmp_set);
+
+ if (quick_select)
+ {
+ if (select->quick->reset())
+ DBUG_RETURN(HA_POS_ERROR);
+ }
+
for (;;)
{
if (quick_select)
{
if ((error= select->quick->get_next()))
break;
- if (!error)
+ if (!error && sort_form->vfield)
update_virtual_fields(thd, sort_form);
file->position(sort_form->record[0]);
DBUG_EXECUTE_IF("debug_filesort", dbug_print_record(sort_form, TRUE););
@@ -614,7 +577,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
else
{
error=file->ha_rnd_next(sort_form->record[0]);
- if (!error)
+ if (!error && sort_form->vfield)
update_virtual_fields(thd, sort_form);
if (!flag)
{
@@ -638,23 +601,56 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
}
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
}
+
+ bool write_record= false;
if (error == 0)
+ {
param->examined_rows++;
-
- if (error == 0 && (!select || select->skip_record(thd) > 0))
+ if (select && select->cond)
+ {
+ /*
+ If the condition 'select->cond' contains a subquery, restore the
+ original read/write sets of the table 'sort_form' because when
+ SQL_SELECT::skip_record evaluates this condition. it may include a
+ correlated subquery predicate, such that some field in the subquery
+ refers to 'sort_form'.
+
+ PSergey-todo: discuss the above with Timour.
+ */
+ MY_BITMAP *tmp_read_set= sort_form->read_set;
+ MY_BITMAP *tmp_write_set= sort_form->write_set;
+ MY_BITMAP *tmp_vcol_set= sort_form->vcol_set;
+
+ if (select->cond->with_subselect)
+ sort_form->column_bitmaps_set(save_read_set, save_write_set,
+ save_vcol_set);
+ write_record= (select->skip_record(thd) > 0);
+ if (select->cond->with_subselect)
+ sort_form->column_bitmaps_set(tmp_read_set,
+ tmp_write_set,
+ tmp_vcol_set);
+ }
+ else
+ write_record= true;
+ }
+
+ if (write_record)
{
if (idx == param->keys)
{
if (write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
DBUG_RETURN(HA_POS_ERROR);
idx=0;
+ next_sort_key= sort_keys_buf;
indexpos++;
}
- make_sortkey(param,sort_keys[idx++],ref_pos);
+ sort_keys[idx++]= next_sort_key;
+ make_sortkey(param, next_sort_key, ref_pos);
+ next_sort_key+= param->rec_length;
}
else
file->unlock_row();
-
+
/* It does not make sense to read more keys in case of a fatal error */
if (thd->is_error())
break;
@@ -787,21 +783,9 @@ static void make_sortkey(register SORTPARAM *param,
bool maybe_null=0;
if ((field=sort_field->field))
{ // Field
- if (field->maybe_null())
- {
- if (field->is_null())
- {
- if (sort_field->reverse)
- bfill(to,sort_field->length+1,(char) 255);
- else
- bzero((char*) to,sort_field->length+1);
- to+= sort_field->length+1;
- continue;
- }
- else
- *to++=1;
- }
- field->sort_string(to, sort_field->length);
+ field->make_sort_key(to, sort_field->length);
+ if ((maybe_null = field->maybe_null()))
+ to++;
}
else
{ // Item
@@ -876,25 +860,28 @@ static void make_sortkey(register SORTPARAM *param,
break;
}
case INT_RESULT:
+ case TIME_RESULT:
{
- longlong value= item->val_int_result();
+ longlong UNINIT_VAR(value);
+ if (sort_field->result_type == INT_RESULT)
+ value= item->val_int_result();
+ else
+ {
+ MYSQL_TIME buf;
+ if (item->get_date_result(&buf, TIME_FUZZY_DATE | TIME_INVALID_DATES))
+ DBUG_ASSERT(maybe_null && item->null_value);
+ else
+ value= pack_time(&buf);
+ }
if (maybe_null)
{
- *to++=1; /* purecov: inspected */
if (item->null_value)
{
- if (maybe_null)
- bzero((char*) to-1,sort_field->length+1);
- else
- {
- DBUG_PRINT("warning",
- ("Got null on something that shouldn't be null"));
- bzero((char*) to,sort_field->length);
- }
+ bzero((char*) to++, sort_field->length+1);
break;
}
+ *to++=1; /* purecov: inspected */
}
-#if SIZEOF_LONG_LONG > 4
to[7]= (uchar) value;
to[6]= (uchar) (value >> 8);
to[5]= (uchar) (value >> 16);
@@ -906,15 +893,6 @@ static void make_sortkey(register SORTPARAM *param,
to[0]= (uchar) (value >> 56);
else
to[0]= (uchar) (value >> 56) ^ 128; /* Reverse signbit */
-#else
- to[3]= (uchar) value;
- to[2]= (uchar) (value >> 8);
- to[1]= (uchar) (value >> 16);
- if (item->unsigned_flag) /* Fix sign */
- to[0]= (uchar) (value >> 24);
- else
- to[0]= (uchar) (value >> 24) ^ 128; /* Reverse signbit */
-#endif
break;
}
case DECIMAL_RESULT:
@@ -924,8 +902,7 @@ static void make_sortkey(register SORTPARAM *param,
{
if (item->null_value)
{
- bzero((char*)to, sort_field->length+1);
- to++;
+ bzero((char*) to++, sort_field->length+1);
break;
}
*to++=1;
@@ -960,8 +937,11 @@ static void make_sortkey(register SORTPARAM *param,
}
if (sort_field->reverse)
{ /* Revers key */
- if (maybe_null)
- to[-1]= ~to[-1];
+ if (maybe_null && (to[-1]= !to[-1]))
+ {
+ to+= sort_field->length; // don't waste the time reversing all 0's
+ continue;
+ }
length=sort_field->length;
while (length--)
{
@@ -1186,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)
@@ -1239,8 +1221,11 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
QUEUE queue;
qsort2_cmp cmp;
void *first_cmp_arg;
- volatile THD::killed_state *killed= &current_thd->killed;
- THD::killed_state not_killable;
+ element_count dupl_count= 0;
+ uchar *src;
+ killed_state not_killable;
+ uchar *unique_buff= param->unique_buff;
+ volatile killed_state *killed= &current_thd->killed;
DBUG_ENTER("merge_buffers");
status_var_increment(current_thd->status_var.filesort_merge_passes);
@@ -1248,23 +1233,28 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
if (param->not_killable)
{
killed= &not_killable;
- not_killable= THD::NOT_KILLED;
+ not_killable= NOT_KILLED;
}
error=0;
rec_length= param->rec_length;
res_length= param->res_length;
sort_length= param->sort_length;
- offset= rec_length-res_length;
+ uint dupl_count_ofs= rec_length-sizeof(element_count);
+ uint min_dupl_count= param->min_dupl_count;
+ bool check_dupl_count= flag && min_dupl_count;
+ offset= (rec_length-
+ (flag && min_dupl_count ? sizeof(dupl_count) : 0)-res_length);
+ uint wr_len= flag ? res_length : rec_length;
+ uint wr_offset= flag ? offset : 0;
maxcount= (ulong) (param->keys/((uint) (Tb-Fb) +1));
to_start_filepos= my_b_tell(to_file);
strpos= sort_buffer;
org_max_rows=max_rows= param->max_rows;
-
- /* The following will fire if there is not enough space in sort_buffer */
- DBUG_ASSERT(maxcount!=0);
- if (param->unique_buff)
+ set_if_bigger(maxcount, 1);
+
+ if (unique_buff)
{
cmp= param->compare;
first_cmp_arg= (void *) &param->cmp_context;
@@ -1275,7 +1265,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++)
{
@@ -1289,30 +1279,31 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
queue_insert(&queue, (uchar*) buffpek);
}
- if (param->unique_buff)
+ if (unique_buff)
{
/*
Called by Unique::get()
- Copy the first argument to param->unique_buff for unique removal.
+ Copy the first argument to unique_buff for unique removal.
Store it also in 'to_file'.
-
- This is safe as we know that there is always more than one element
- in each block to merge (This is guaranteed by the Unique:: algorithm
*/
buffpek= (BUFFPEK*) queue_top(&queue);
- memcpy(param->unique_buff, buffpek->key, rec_length);
- if (my_b_write(to_file, (uchar*) buffpek->key, rec_length))
- {
- error=1; goto err; /* purecov: inspected */
- }
+ memcpy(unique_buff, buffpek->key, rec_length);
+ if (min_dupl_count)
+ memcpy(&dupl_count, unique_buff+dupl_count_ofs,
+ sizeof(dupl_count));
buffpek->key+= rec_length;
- buffpek->mem_count--;
- if (!--max_rows)
+ if (! --buffpek->mem_count)
{
- error= 0; /* purecov: inspected */
- goto end; /* purecov: inspected */
+ if (!(error= (int) read_to_buffer(from_file, buffpek,
+ rec_length)))
+ {
+ VOID(queue_remove(&queue,0));
+ reuse_freed_buff(&queue, buffpek, rec_length);
+ }
+ else if (error == -1)
+ goto err; /* purecov: inspected */
}
- queue_replaced(&queue); // Top element has been used
+ queue_replace_top(&queue); // Top element has been used
}
else
cmp= 0; // Not unique
@@ -1326,27 +1317,50 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
for (;;)
{
buffpek= (BUFFPEK*) queue_top(&queue);
+ src= buffpek->key;
if (cmp) // Remove duplicates
{
- if (!(*cmp)(first_cmp_arg, &(param->unique_buff),
+ if (!(*cmp)(first_cmp_arg, &unique_buff,
(uchar**) &buffpek->key))
- goto skip_duplicate;
- memcpy(param->unique_buff, (uchar*) buffpek->key, rec_length);
- }
- if (flag == 0)
- {
- if (my_b_write(to_file,(uchar*) buffpek->key, rec_length))
- {
- error=1; goto err; /* purecov: inspected */
+ {
+ if (min_dupl_count)
+ {
+ element_count cnt;
+ memcpy(&cnt, (uchar *) buffpek->key+dupl_count_ofs, sizeof(cnt));
+ dupl_count+= cnt;
+ }
+ goto skip_duplicate;
+ }
+ if (min_dupl_count)
+ {
+ memcpy(unique_buff+dupl_count_ofs, &dupl_count,
+ sizeof(dupl_count));
}
+ src= unique_buff;
}
- else
+
+ /*
+ Do not write into the output file if this is the final merge called
+ for a Unique object used for intersection and dupl_count is less
+ than min_dupl_count.
+ If the Unique object is used to intersect N sets of unique elements
+ then for any element:
+ dupl_count >= N <=> the element is occurred in each of these N sets.
+ */
+ if (!check_dupl_count || dupl_count >= min_dupl_count)
{
- if (my_b_write(to_file, (uchar*) buffpek->key+offset, res_length))
+ if (my_b_write(to_file, src+wr_offset, wr_len))
{
error=1; goto err; /* purecov: inspected */
}
}
+ if (cmp)
+ {
+ memcpy(unique_buff, (uchar*) buffpek->key, rec_length);
+ if (min_dupl_count)
+ memcpy(&dupl_count, unique_buff+dupl_count_ofs,
+ sizeof(dupl_count));
+ }
if (!--max_rows)
{
error= 0; /* purecov: inspected */
@@ -1357,17 +1371,17 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
buffpek->key+= rec_length;
if (! --buffpek->mem_count)
{
- if (!(error= (int) read_to_buffer(from_file,buffpek,
+ 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);
@@ -1380,11 +1394,35 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
*/
if (cmp)
{
- if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (uchar**) &buffpek->key))
+ if (!(*cmp)(first_cmp_arg, &unique_buff, (uchar**) &buffpek->key))
{
- buffpek->key+= rec_length; // Remove duplicate
+ if (min_dupl_count)
+ {
+ element_count cnt;
+ memcpy(&cnt, (uchar *) buffpek->key+dupl_count_ofs, sizeof(cnt));
+ dupl_count+= cnt;
+ }
+ buffpek->key+= rec_length;
--buffpek->mem_count;
}
+
+ if (min_dupl_count)
+ memcpy(unique_buff+dupl_count_ofs, &dupl_count,
+ sizeof(dupl_count));
+
+ if (!check_dupl_count || dupl_count >= min_dupl_count)
+ {
+ src= unique_buff;
+ if (my_b_write(to_file, src+wr_offset, wr_len))
+ {
+ error=1; goto err; /* purecov: inspected */
+ }
+ if (!--max_rows)
+ {
+ error= 0;
+ goto end;
+ }
+ }
}
do
@@ -1397,7 +1435,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
max_rows-= buffpek->mem_count;
if (flag == 0)
{
- if (my_b_write(to_file,(uchar*) buffpek->key,
+ if (my_b_write(to_file, (uchar*) buffpek->key,
(rec_length*buffpek->mem_count)))
{
error= 1; goto err; /* purecov: inspected */
@@ -1406,19 +1444,25 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
else
{
register uchar *end;
- strpos= buffpek->key+offset;
- for (end= strpos+buffpek->mem_count*rec_length ;
- strpos != end ;
- strpos+= rec_length)
- {
- if (my_b_write(to_file, strpos, res_length))
+ src= buffpek->key+offset;
+ for (end= src+buffpek->mem_count*rec_length ;
+ src != end ;
+ src+= rec_length)
+ {
+ if (check_dupl_count)
+ {
+ memcpy((uchar *) &dupl_count, src+dupl_count_ofs, sizeof(dupl_count));
+ if (dupl_count < min_dupl_count)
+ continue;
+ }
+ if (my_b_write(to_file, src, wr_len))
{
error=1; goto err;
}
}
}
}
- while ((error=(int) read_to_buffer(from_file,buffpek, rec_length))
+ while ((error=(int) read_to_buffer(from_file, buffpek, rec_length))
!= -1 && error != 0);
end:
@@ -1432,7 +1476,7 @@ err:
/* Do a merge to output-file (save only positions) */
-static int merge_index(SORTPARAM *param, uchar *sort_buffer,
+int merge_index(SORTPARAM *param, uchar *sort_buffer,
BUFFPEK *buffpek, uint maxbuffer,
IO_CACHE *tempfile, IO_CACHE *outfile)
{
@@ -1504,9 +1548,7 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
}
else
{
- sortorder->result_type= sortorder->item->result_type();
- if (sortorder->item->result_as_longlong())
- sortorder->result_type= INT_RESULT;
+ sortorder->result_type= sortorder->item->cmp_type();
switch (sortorder->result_type) {
case STRING_RESULT:
sortorder->length=sortorder->item->max_length;
@@ -1524,12 +1566,9 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
sortorder->length+= sortorder->suffix_length;
}
break;
+ case TIME_RESULT:
case INT_RESULT:
-#if SIZEOF_LONG_LONG > 4
sortorder->length=8; // Size of intern longlong
-#else
- sortorder->length=4;
-#endif
break;
case DECIMAL_RESULT:
sortorder->length=
@@ -1604,6 +1643,7 @@ get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength)
Actually we need only the fields referred in the
result set. And for some of them it makes sense to use
the values directly from sorted fields.
+ But beware the case when item->cmp_type() != item->result_type()
*/
*plength= 0;
@@ -1674,7 +1714,8 @@ get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength)
*/
static void
-unpack_addon_fields(struct st_sort_addon_field *addon_field, uchar *buff)
+unpack_addon_fields(struct st_sort_addon_field *addon_field, uchar *buff,
+ uchar *buff_end)
{
Field *field;
SORT_ADDON_FIELD *addonf= addon_field;
@@ -1687,7 +1728,7 @@ unpack_addon_fields(struct st_sort_addon_field *addon_field, uchar *buff)
continue;
}
field->set_notnull();
- field->unpack(field->ptr, buff + addonf->offset);
+ field->unpack(field->ptr, buff + addonf->offset, buff_end, 0);
}
}
@@ -1738,3 +1779,4 @@ void change_double_for_sort(double nr,uchar *to)
}
}
}
+
diff --git a/sql/gcalc_slicescan.cc b/sql/gcalc_slicescan.cc
new file mode 100644
index 00000000000..d05ef7ed826
--- /dev/null
+++ b/sql/gcalc_slicescan.cc
@@ -0,0 +1,1996 @@
+/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved.
+ Copyright (C) 2011 Monty Program Ab.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+#include "mysql_priv.h"
+
+#ifdef HAVE_SPATIAL
+
+#include "gcalc_slicescan.h"
+
+
+#define PH_DATA_OFFSET 8
+#define coord_to_float(d) ((double) d)
+#define coord_eq(a, b) (a == b)
+
+typedef int (*sc_compare_func)(const void*, const void*);
+
+#define LS_LIST_ITEM Gcalc_dyn_list::Item
+#define LS_COMPARE_FUNC_DECL sc_compare_func compare,
+#define LS_COMPARE_FUNC_CALL(list_el1, list_el2) (*compare)(list_el1, list_el2)
+#define LS_NEXT(A) (A)->next
+#define LS_SET_NEXT(A,val) (A)->next= val
+#define LS_P_NEXT(A) &(A)->next
+#define LS_NAME sort_list
+#define LS_SCOPE static
+#define LS_STRUCT_NAME sort_list_stack_struct
+#include "plistsort.c"
+
+
+#define GCALC_COORD_MINUS 0x80000000
+#define FIRST_DIGIT(d) ((d) & 0x7FFFFFFF)
+#define GCALC_SIGN(d) ((d) & 0x80000000)
+
+static Gcalc_scan_iterator::point *eq_sp(const Gcalc_heap::Info *pi)
+{
+ GCALC_DBUG_ASSERT(pi->type == Gcalc_heap::nt_eq_node);
+ return (Gcalc_scan_iterator::point *) pi->eq_data;
+}
+
+
+static Gcalc_scan_iterator::intersection_info *i_data(const Gcalc_heap::Info *pi)
+{
+ GCALC_DBUG_ASSERT(pi->type == Gcalc_heap::nt_intersection);
+ return (Gcalc_scan_iterator::intersection_info *) pi->intersection_data;
+}
+
+
+#ifndef GCALC_DBUG_OFF
+
+int gcalc_step_counter= 0;
+
+void GCALC_DBUG_CHECK_COUNTER()
+{
+ if (++gcalc_step_counter == 0)
+ GCALC_DBUG_PRINT(("step_counter_0"));
+ else
+ GCALC_DBUG_PRINT(("%d step_counter", gcalc_step_counter));
+}
+
+
+const char *gcalc_ev_name(int ev)
+{
+ switch (ev)
+ {
+ case scev_none:
+ return "n";
+ case scev_thread:
+ return "t";
+ case scev_two_threads:
+ return "tt";
+ case scev_end:
+ return "e";
+ case scev_two_ends:
+ return "ee";
+ case scev_intersection:
+ return "i";
+ case scev_point:
+ return "p";
+ case scev_single_point:
+ return "sp";
+ default:;
+ };
+ GCALC_DBUG_ASSERT(0);
+ return "unk";
+}
+
+
+static int gcalc_pi_str(char *str, const Gcalc_heap::Info *pi, const char *postfix)
+{
+ return sprintf(str, "%s %d %d | %s %d %d%s",
+ GCALC_SIGN(pi->ix[0]) ? "-":"", FIRST_DIGIT(pi->ix[0]),pi->ix[1],
+ GCALC_SIGN(pi->iy[0]) ? "-":"", FIRST_DIGIT(pi->iy[0]),pi->iy[1],
+ postfix);
+
+}
+
+
+static void GCALC_DBUG_PRINT_PI(const Gcalc_heap::Info *pi)
+{
+ char buf[128];
+ int n_buf;
+ if (pi->type == Gcalc_heap::nt_intersection)
+ {
+ const Gcalc_scan_iterator::intersection_info *ic= i_data(pi);
+
+ GCALC_DBUG_PRINT(("intersection point %d %d",
+ ic->edge_a->thread, ic->edge_b->thread));
+ return;
+ }
+ if (pi->type == Gcalc_heap::nt_eq_node)
+ {
+ const Gcalc_scan_iterator::point *e= eq_sp(pi);
+ GCALC_DBUG_PRINT(("eq point %d", e->thread));
+ return;
+ }
+ n_buf= gcalc_pi_str(buf, pi, "");
+ buf[n_buf]= 0;
+ GCALC_DBUG_PRINT(("%s", buf));
+}
+
+
+static void GCALC_DBUG_PRINT_SLICE(const char *header,
+ const Gcalc_scan_iterator::point *slice)
+{
+ int nbuf;
+ char buf[1024];
+ nbuf= strlen(header);
+ strcpy(buf, header);
+ for (; slice; slice= slice->get_next())
+ {
+ int lnbuf= nbuf;
+ lnbuf+= sprintf(buf + lnbuf, "%d\t", slice->thread);
+ lnbuf+= sprintf(buf + lnbuf, "%s\t", gcalc_ev_name(slice->event));
+
+ lnbuf+= gcalc_pi_str(buf + lnbuf, slice->pi, "\t");
+ if (slice->is_bottom())
+ lnbuf+= sprintf(buf+lnbuf, "bt\t");
+ else
+ lnbuf+= gcalc_pi_str(buf+lnbuf, slice->next_pi, "\t");
+ buf[lnbuf]= 0;
+ GCALC_DBUG_PRINT(("%s", buf));
+ }
+}
+
+
+#else
+#define GCALC_DBUG_CHECK_COUNTER() do { } while(0)
+#define GCALC_DBUG_PRINT_PI(pi) do { } while(0)
+#define GCALC_DBUG_PRINT_SLICE(a, b) do { } while(0)
+#define GCALC_DBUG_PRINT_INTERSECTIONS(a) do { } while(0)
+#define GCALC_DBUG_PRINT_STATE(a) do { } while(0)
+#endif /*GCALC_DBUG_OFF*/
+
+
+Gcalc_dyn_list::Gcalc_dyn_list(size_t blk_size, size_t sizeof_item):
+ m_blk_size(blk_size - ALLOC_ROOT_MIN_BLOCK_SIZE),
+ m_sizeof_item(ALIGN_SIZE(sizeof_item)),
+ m_points_per_blk((m_blk_size - PH_DATA_OFFSET) / m_sizeof_item),
+ m_blk_hook(&m_first_blk),
+ m_free(NULL),
+ m_keep(NULL)
+{}
+
+
+void Gcalc_dyn_list::format_blk(void* block)
+{
+ Item *pi_end, *cur_pi, *first_pi;
+ GCALC_DBUG_ASSERT(m_free == NULL);
+ first_pi= cur_pi= (Item *)(((char *)block) + PH_DATA_OFFSET);
+ pi_end= ptr_add(first_pi, m_points_per_blk - 1);
+ do {
+ cur_pi= cur_pi->next= ptr_add(cur_pi, 1);
+ } while (cur_pi<pi_end);
+ cur_pi->next= m_free;
+ m_free= first_pi;
+}
+
+
+Gcalc_dyn_list::Item *Gcalc_dyn_list::alloc_new_blk()
+{
+ void *new_block= my_malloc(m_blk_size, MYF(MY_WME));
+ if (!new_block)
+ return NULL;
+ *m_blk_hook= new_block;
+ m_blk_hook= (void**)new_block;
+ format_blk(new_block);
+ return new_item();
+}
+
+
+static void free_blk_list(void *list)
+{
+ void *next_blk;
+ while (list)
+ {
+ next_blk= *((void **)list);
+ my_free(list, MYF(0));
+ list= next_blk;
+ }
+}
+
+
+void Gcalc_dyn_list::cleanup()
+{
+ *m_blk_hook= NULL;
+ free_blk_list(m_first_blk);
+ m_first_blk= NULL;
+ m_blk_hook= &m_first_blk;
+ m_free= NULL;
+}
+
+
+Gcalc_dyn_list::~Gcalc_dyn_list()
+{
+ cleanup();
+}
+
+
+void Gcalc_dyn_list::reset()
+{
+ *m_blk_hook= NULL;
+ if (m_first_blk)
+ {
+ free_blk_list(*((void **)m_first_blk));
+ m_blk_hook= (void**)m_first_blk;
+ m_free= NULL;
+ format_blk(m_first_blk);
+ }
+}
+
+
+/* Internal coordinate operations implementations */
+
+void gcalc_set_zero(Gcalc_internal_coord *d, int d_len)
+{
+ do
+ {
+ d[--d_len]= 0;
+ } while (d_len);
+}
+
+
+int gcalc_is_zero(const Gcalc_internal_coord *d, int d_len)
+{
+ do
+ {
+ if (d[--d_len] != 0)
+ return 0;
+ } while (d_len);
+ return 1;
+}
+
+
+#ifdef GCALC_CHECK_WITH_FLOAT
+static double *gcalc_coord_extent= NULL;
+
+long double gcalc_get_double(const Gcalc_internal_coord *d, int d_len)
+{
+ int n= 1;
+ long double res= (long double) FIRST_DIGIT(d[0]);
+ do
+ {
+ res*= (long double) GCALC_DIG_BASE;
+ res+= (long double) d[n];
+ } while(++n < d_len);
+
+ n= 0;
+ do
+ {
+ if ((n & 1) && gcalc_coord_extent)
+ res/= *gcalc_coord_extent;
+ } while(++n < d_len);
+
+ if (GCALC_SIGN(d[0]))
+ res*= -1.0;
+ return res;
+}
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+
+
+static void do_add(Gcalc_internal_coord *result, int result_len,
+ const Gcalc_internal_coord *a,
+ const Gcalc_internal_coord *b)
+{
+ int n_digit= result_len-1;
+ gcalc_digit_t carry= 0;
+
+ do
+ {
+ if ((result[n_digit]=
+ a[n_digit] + b[n_digit] + carry) >= GCALC_DIG_BASE)
+ {
+ carry= 1;
+ result[n_digit]-= GCALC_DIG_BASE;
+ }
+ else
+ carry= 0;
+ } while (--n_digit);
+
+ result[0]= (a[0] + FIRST_DIGIT(b[0]) + carry);
+
+ GCALC_DBUG_ASSERT(FIRST_DIGIT(result[0]) < GCALC_DIG_BASE);
+}
+
+
+static void do_sub(Gcalc_internal_coord *result, int result_len,
+ const Gcalc_internal_coord *a,
+ const Gcalc_internal_coord *b)
+{
+ int n_digit= result_len-1;
+ gcalc_digit_t carry= 0;
+ gcalc_digit_t cur_b, cur_a;
+
+ do
+ {
+ cur_b= b[n_digit] + carry;
+ cur_a= a[n_digit];
+ if (cur_a < cur_b)
+ {
+ carry= 1;
+ result[n_digit]= (GCALC_DIG_BASE - cur_b) + cur_a;
+ }
+ else
+ {
+ carry= 0;
+ result[n_digit]= cur_a - cur_b;
+ }
+ } while (--n_digit);
+
+
+ result[0]= a[0] - FIRST_DIGIT(b[0]) - carry;
+
+ GCALC_DBUG_ASSERT(FIRST_DIGIT(a[0]) >= FIRST_DIGIT(b[0]) + carry);
+ GCALC_DBUG_ASSERT(!gcalc_is_zero(result, result_len));
+}
+/*
+static void do_sub(Gcalc_internal_coord *result, int result_len,
+ const Gcalc_internal_coord *a,
+ const Gcalc_internal_coord *b)
+{
+ int n_digit= result_len-1;
+ gcalc_digit_t carry= 0;
+
+ do
+ {
+ if ((result[n_digit]= a[n_digit] - b[n_digit] - carry) < 0)
+ {
+ carry= 1;
+ result[n_digit]+= GCALC_DIG_BASE;
+ }
+ else
+ carry= 0;
+ } while (--n_digit);
+
+
+ result[0]= a[0] - FIRST_DIGIT(b[0]) - carry;
+
+ GCALC_DBUG_ASSERT(FIRST_DIGIT(a[0]) - FIRST_DIGIT(b[0]) - carry >= 0);
+ GCALC_DBUG_ASSERT(!gcalc_is_zero(result, result_len));
+}
+*/
+
+static int do_cmp(const Gcalc_internal_coord *a,
+ const Gcalc_internal_coord *b, int len)
+{
+ int n_digit= 1;
+
+ if ((FIRST_DIGIT(a[0]) != FIRST_DIGIT(b[0])))
+ return FIRST_DIGIT(a[0]) > FIRST_DIGIT(b[0]) ? 1 : -1;
+
+ do
+ {
+ if ((a[n_digit] != b[n_digit]))
+ return a[n_digit] > b[n_digit] ? 1 : -1;
+ } while (++n_digit < len);
+
+ return 0;
+}
+
+
+#ifdef GCALC_CHECK_WITH_FLOAT
+static int de_weak_check(long double a, long double b, long double ex)
+{
+ long double d= a - b;
+ if (d < ex && d > -ex)
+ return 1;
+
+ d/= fabsl(a) + fabsl(b);
+ if (d < ex && d > -ex)
+ return 1;
+ return 0;
+}
+
+static int de_check(long double a, long double b)
+{
+ return de_weak_check(a, b, (long double) 1e-9);
+}
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+
+
+void gcalc_mul_coord(Gcalc_internal_coord *result, int result_len,
+ const Gcalc_internal_coord *a, int a_len,
+ const Gcalc_internal_coord *b, int b_len)
+{
+ GCALC_DBUG_ASSERT(result_len == a_len + b_len);
+ GCALC_DBUG_ASSERT(a_len >= b_len);
+ int n_a, n_b, n_res;
+ gcalc_digit_t carry= 0;
+
+ gcalc_set_zero(result, result_len);
+
+ n_a= a_len - 1;
+ do
+ {
+ gcalc_coord2 cur_a= n_a ? a[n_a] : FIRST_DIGIT(a[0]);
+ n_b= b_len - 1;
+ do
+ {
+ gcalc_coord2 cur_b= n_b ? b[n_b] : FIRST_DIGIT(b[0]);
+ gcalc_coord2 mul= cur_a * cur_b + carry + result[n_a + n_b + 1];
+ result[n_a + n_b + 1]= mul % GCALC_DIG_BASE;
+ carry= (gcalc_digit_t) (mul / (gcalc_coord2) GCALC_DIG_BASE);
+ } while (n_b--);
+ if (carry)
+ {
+ for (n_res= n_a; (result[n_res]+= carry) >= GCALC_DIG_BASE;
+ n_res--)
+ {
+ result[n_res]-= GCALC_DIG_BASE;
+ carry= 1;
+ }
+ carry= 0;
+ }
+ } while (n_a--);
+ if (!gcalc_is_zero(result, result_len))
+ result[0]|= GCALC_SIGN(a[0] ^ b[0]);
+#ifdef GCALC_CHECK_WITH_FLOAT
+ GCALC_DBUG_ASSERT(de_check(gcalc_get_double(a, a_len) *
+ gcalc_get_double(b, b_len),
+ gcalc_get_double(result, result_len)));
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+}
+
+
+inline void gcalc_mul_coord1(Gcalc_coord1 result,
+ const Gcalc_coord1 a, const Gcalc_coord1 b)
+{
+ return gcalc_mul_coord(result, GCALC_COORD_BASE2,
+ a, GCALC_COORD_BASE, b, GCALC_COORD_BASE);
+}
+
+
+void gcalc_add_coord(Gcalc_internal_coord *result, int result_len,
+ const Gcalc_internal_coord *a,
+ const Gcalc_internal_coord *b)
+{
+ if (GCALC_SIGN(a[0]) == GCALC_SIGN(b[0]))
+ do_add(result, result_len, a, b);
+ else
+ {
+ int cmp_res= do_cmp(a, b, result_len);
+ if (cmp_res == 0)
+ gcalc_set_zero(result, result_len);
+ else if (cmp_res > 0)
+ do_sub(result, result_len, a, b);
+ else
+ do_sub(result, result_len, b, a);
+ }
+#ifdef GCALC_CHECK_WITH_FLOAT
+ GCALC_DBUG_ASSERT(de_check(gcalc_get_double(a, result_len) +
+ gcalc_get_double(b, result_len),
+ gcalc_get_double(result, result_len)));
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+}
+
+
+void gcalc_sub_coord(Gcalc_internal_coord *result, int result_len,
+ const Gcalc_internal_coord *a,
+ const Gcalc_internal_coord *b)
+{
+ if (GCALC_SIGN(a[0] ^ b[0]))
+ do_add(result, result_len, a, b);
+ else
+ {
+ int cmp_res= do_cmp(a, b, result_len);
+ if (cmp_res == 0)
+ gcalc_set_zero(result, result_len);
+ else if (cmp_res > 0)
+ do_sub(result, result_len, a, b);
+ else
+ {
+ do_sub(result, result_len, b, a);
+ result[0]^= GCALC_COORD_MINUS;
+ }
+ }
+#ifdef GCALC_CHECK_WITH_FLOAT
+ GCALC_DBUG_ASSERT(de_check(gcalc_get_double(a, result_len) -
+ gcalc_get_double(b, result_len),
+ gcalc_get_double(result, result_len)));
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+}
+
+
+inline void gcalc_sub_coord1(Gcalc_coord1 result,
+ const Gcalc_coord1 a, const Gcalc_coord1 b)
+{
+ return gcalc_sub_coord(result, GCALC_COORD_BASE, a, b);
+}
+
+
+int gcalc_cmp_coord(const Gcalc_internal_coord *a,
+ const Gcalc_internal_coord *b, int len)
+{
+ int n_digit= 0;
+ int result= 0;
+
+ do
+ {
+ if (a[n_digit] == b[n_digit])
+ {
+ n_digit++;
+ continue;
+ }
+ if (a[n_digit] > b[n_digit])
+ result= GCALC_SIGN(a[0]) ? -1 : 1;
+ else
+ result= GCALC_SIGN(b[0]) ? 1 : -1;
+ break;
+
+ } while (n_digit < len);
+
+#ifdef GCALC_CHECK_WITH_FLOAT
+ if (result == 0)
+ GCALC_DBUG_ASSERT(de_check(gcalc_get_double(a, len),
+ gcalc_get_double(b, len)));
+ else if (result == 1)
+ GCALC_DBUG_ASSERT(de_check(gcalc_get_double(a, len),
+ gcalc_get_double(b, len)) ||
+ gcalc_get_double(a, len) > gcalc_get_double(b, len));
+ else
+ GCALC_DBUG_ASSERT(de_check(gcalc_get_double(a, len),
+ gcalc_get_double(b, len)) ||
+ gcalc_get_double(a, len) < gcalc_get_double(b, len));
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+ return result;
+}
+
+
+#define gcalc_cmp_coord1(a, b) gcalc_cmp_coord(a, b, GCALC_COORD_BASE)
+
+int gcalc_set_double(Gcalc_internal_coord *c, double d, double ext)
+{
+ int sign;
+ double ds= d * ext;
+ if ((sign= ds < 0))
+ ds= -ds;
+ c[0]= (gcalc_digit_t) (ds / (double) GCALC_DIG_BASE);
+ c[1]= (gcalc_digit_t) (ds - ((double) c[0]) * (double) GCALC_DIG_BASE);
+ if (c[1] >= GCALC_DIG_BASE)
+ {
+ c[1]= 0;
+ c[0]++;
+ }
+ if (sign && (c[0] | c[1]))
+ c[0]|= GCALC_COORD_MINUS;
+#ifdef GCALC_CHECK_WITH_FLOAT
+ GCALC_DBUG_ASSERT(de_check(d, gcalc_get_double(c, 2)));
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+ return 0;
+}
+
+
+typedef gcalc_digit_t Gcalc_coord4[GCALC_COORD_BASE*4];
+typedef gcalc_digit_t Gcalc_coord5[GCALC_COORD_BASE*5];
+
+
+void Gcalc_scan_iterator::intersection_info::do_calc_t()
+{
+ Gcalc_coord1 a2_a1x, a2_a1y;
+ Gcalc_coord2 x1y2, x2y1;
+
+ gcalc_sub_coord1(a2_a1x, edge_b->pi->ix, edge_a->pi->ix);
+ gcalc_sub_coord1(a2_a1y, edge_b->pi->iy, edge_a->pi->iy);
+
+ GCALC_DBUG_ASSERT(!gcalc_is_zero(edge_a->dy, GCALC_COORD_BASE) ||
+ !gcalc_is_zero(edge_b->dy, GCALC_COORD_BASE));
+
+ gcalc_mul_coord1(x1y2, edge_a->dx, edge_b->dy);
+ gcalc_mul_coord1(x2y1, edge_a->dy, edge_b->dx);
+ gcalc_sub_coord(t_b, GCALC_COORD_BASE2, x1y2, x2y1);
+
+
+ gcalc_mul_coord1(x1y2, a2_a1x, edge_b->dy);
+ gcalc_mul_coord1(x2y1, a2_a1y, edge_b->dx);
+ gcalc_sub_coord(t_a, GCALC_COORD_BASE2, x1y2, x2y1);
+ t_calculated= 1;
+}
+
+
+void Gcalc_scan_iterator::intersection_info::do_calc_y()
+{
+ GCALC_DBUG_ASSERT(t_calculated);
+
+ Gcalc_coord3 a_tb, b_ta;
+
+ gcalc_mul_coord(a_tb, GCALC_COORD_BASE3,
+ t_b, GCALC_COORD_BASE2, edge_a->pi->iy, GCALC_COORD_BASE);
+ gcalc_mul_coord(b_ta, GCALC_COORD_BASE3,
+ t_a, GCALC_COORD_BASE2, edge_a->dy, GCALC_COORD_BASE);
+
+ gcalc_add_coord(y_exp, GCALC_COORD_BASE3, a_tb, b_ta);
+ y_calculated= 1;
+}
+
+
+void Gcalc_scan_iterator::intersection_info::do_calc_x()
+{
+ GCALC_DBUG_ASSERT(t_calculated);
+
+ Gcalc_coord3 a_tb, b_ta;
+
+ gcalc_mul_coord(a_tb, GCALC_COORD_BASE3,
+ t_b, GCALC_COORD_BASE2, edge_a->pi->ix, GCALC_COORD_BASE);
+ gcalc_mul_coord(b_ta, GCALC_COORD_BASE3,
+ t_a, GCALC_COORD_BASE2, edge_a->dx, GCALC_COORD_BASE);
+
+ gcalc_add_coord(x_exp, GCALC_COORD_BASE3, a_tb, b_ta);
+ x_calculated= 1;
+}
+
+
+static int cmp_node_isc(const Gcalc_heap::Info *node,
+ const Gcalc_heap::Info *isc)
+{
+ GCALC_DBUG_ASSERT(node->type == Gcalc_heap::nt_shape_node);
+ Gcalc_scan_iterator::intersection_info *inf= i_data(isc);
+ Gcalc_coord3 exp;
+ int result;
+
+ inf->calc_t();
+ inf->calc_y_exp();
+
+ gcalc_mul_coord(exp, GCALC_COORD_BASE3,
+ inf->t_b, GCALC_COORD_BASE2, node->iy, GCALC_COORD_BASE);
+
+ result= gcalc_cmp_coord(exp, inf->y_exp, GCALC_COORD_BASE3);
+#ifdef GCALC_CHECK_WITH_FLOAT
+ long double int_x, int_y;
+ isc->calc_xy_ld(&int_x, &int_y);
+ if (result < 0)
+ {
+ if (!de_check(int_y, node->y) && node->y > int_y)
+ GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscy %g < %LG", node->y, int_y));
+ }
+ else if (result > 0)
+ {
+ if (!de_check(int_y, node->y) && node->y < int_y)
+ GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscy %g > %LG", node->y, int_y));
+ }
+ else
+ {
+ if (!de_check(int_y, node->y))
+ GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscy %g == %LG", node->y, int_y));
+ }
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+ if (result)
+ goto exit;
+
+
+ inf->calc_x_exp();
+ gcalc_mul_coord(exp, GCALC_COORD_BASE3,
+ inf->t_b, GCALC_COORD_BASE2, node->ix, GCALC_COORD_BASE);
+
+ result= gcalc_cmp_coord(exp, inf->x_exp, GCALC_COORD_BASE3);
+#ifdef GCALC_CHECK_WITH_FLOAT
+ if (result < 0)
+ {
+ if (!de_check(int_x, node->x) && node->x > int_x)
+ GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscx failed %g < %LG",
+ node->x, int_x));
+ }
+ else if (result > 0)
+ {
+ if (!de_check(int_x, node->x) && node->x < int_x)
+ GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscx failed %g > %LG",
+ node->x, int_x));
+ }
+ else
+ {
+ if (!de_check(int_x, node->x))
+ GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscx failed %g == %LG",
+ node->x, int_x));
+ }
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+exit:
+ return result;
+}
+
+
+static int cmp_intersections(const Gcalc_heap::Info *i1,
+ const Gcalc_heap::Info *i2)
+{
+ Gcalc_scan_iterator::intersection_info *inf1= i_data(i1);
+ Gcalc_scan_iterator::intersection_info *inf2= i_data(i2);
+ Gcalc_coord5 exp_a, exp_b;
+ int result;
+
+ inf1->calc_t();
+ inf2->calc_t();
+
+ inf1->calc_y_exp();
+ inf2->calc_y_exp();
+
+ gcalc_mul_coord(exp_a, GCALC_COORD_BASE5,
+ inf1->y_exp, GCALC_COORD_BASE3, inf2->t_b, GCALC_COORD_BASE2);
+ gcalc_mul_coord(exp_b, GCALC_COORD_BASE5,
+ inf2->y_exp, GCALC_COORD_BASE3, inf1->t_b, GCALC_COORD_BASE2);
+
+ result= gcalc_cmp_coord(exp_a, exp_b, GCALC_COORD_BASE5);
+#ifdef GCALC_CHECK_WITH_FLOAT
+ long double x1, y1, x2, y2;
+ i1->calc_xy_ld(&x1, &y1);
+ i2->calc_xy_ld(&x2, &y2);
+
+ if (result < 0)
+ {
+ if (!de_check(y1, y2) && y2 > y1)
+ GCALC_DBUG_PRINT(("floatcheck cmp_intersections_y failed %LG < %LG",
+ y2, y1));
+ }
+ else if (result > 0)
+ {
+ if (!de_check(y1, y2) && y2 < y1)
+ GCALC_DBUG_PRINT(("floatcheck cmp_intersections_y failed %LG > %LG",
+ y2, y1));
+ }
+ else
+ {
+ if (!de_check(y1, y2))
+ GCALC_DBUG_PRINT(("floatcheck cmp_intersections_y failed %LG == %LG",
+ y2, y1));
+ }
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+
+ if (result != 0)
+ return result;
+
+
+ inf1->calc_x_exp();
+ inf2->calc_x_exp();
+ gcalc_mul_coord(exp_a, GCALC_COORD_BASE5,
+ inf1->x_exp, GCALC_COORD_BASE3, inf2->t_b, GCALC_COORD_BASE2);
+ gcalc_mul_coord(exp_b, GCALC_COORD_BASE5,
+ inf2->x_exp, GCALC_COORD_BASE3, inf1->t_b, GCALC_COORD_BASE2);
+
+ result= gcalc_cmp_coord(exp_a, exp_b, GCALC_COORD_BASE5);
+#ifdef GCALC_CHECK_WITH_FLOAT
+ if (result < 0)
+ {
+ if (!de_check(x1, x2) && x2 > x1)
+ GCALC_DBUG_PRINT(("floatcheck cmp_intersectionsx failed %LG < %LG",
+ x2, x1));
+ }
+ else if (result > 0)
+ {
+ if (!de_check(x1, x2) && x2 < x1)
+ GCALC_DBUG_PRINT(("floatcheck cmp_intersectionsx failed %LG > %LG",
+ x2, x1));
+ }
+ else
+ {
+ if (!de_check(x1, x2))
+ GCALC_DBUG_PRINT(("floatcheck cmp_intersectionsx failed %LG == %LG",
+ x2, x1));
+ }
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+ return result;
+}
+/* Internal coordinates implementation end */
+
+
+#define GCALC_SCALE_1 1e18
+
+static double find_scale(double extent)
+{
+ double scale= 1e-2;
+ while (scale < extent)
+ scale*= (double ) 10;
+ return GCALC_SCALE_1 / scale / 10;
+}
+
+
+void Gcalc_heap::set_extent(double xmin, double xmax, double ymin, double ymax)
+{
+ xmin= fabs(xmin);
+ xmax= fabs(xmax);
+ ymin= fabs(ymin);
+ ymax= fabs(ymax);
+
+ if (xmax < xmin)
+ xmax= xmin;
+ if (ymax < ymin)
+ ymax= ymin;
+
+ coord_extent= xmax > ymax ? xmax : ymax;
+ coord_extent= find_scale(coord_extent);
+#ifdef GCALC_CHECK_WITH_FLOAT
+ gcalc_coord_extent= &coord_extent;
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+}
+
+
+void Gcalc_heap::free_point_info(Gcalc_heap::Info *i,
+ Gcalc_dyn_list::Item **i_hook)
+{
+ if (m_hook == &i->next)
+ m_hook= i_hook;
+ *i_hook= i->next;
+ free_item(i);
+ m_n_points--;
+}
+
+
+Gcalc_heap::Info *Gcalc_heap::new_point_info(double x, double y,
+ gcalc_shape_info shape)
+{
+ Info *result= (Info *)new_item();
+ if (!result)
+ return NULL;
+ *m_hook= result;
+ m_hook= &result->next;
+ result->x= x;
+ result->y= y;
+ result->shape= shape;
+ result->top_node= 1;
+ result->type= nt_shape_node;
+ gcalc_set_double(result->ix, x, coord_extent);
+ gcalc_set_double(result->iy, y, coord_extent);
+
+ m_n_points++;
+ return result;
+}
+
+
+static Gcalc_heap::Info *new_intersection(
+ Gcalc_heap *heap, Gcalc_scan_iterator::intersection_info *ii)
+{
+ Gcalc_heap::Info *isc= (Gcalc_heap::Info *)heap->new_item();
+ if (!isc)
+ return 0;
+ isc->type= Gcalc_heap::nt_intersection;
+ isc->p1= ii->edge_a->pi;
+ isc->p2= ii->edge_a->next_pi;
+ isc->p3= ii->edge_b->pi;
+ isc->p4= ii->edge_b->next_pi;
+ isc->intersection_data= ii;
+ return isc;
+}
+
+
+static Gcalc_heap::Info *new_eq_point(
+ Gcalc_heap *heap, const Gcalc_heap::Info *p,
+ Gcalc_scan_iterator::point *edge)
+{
+ Gcalc_heap::Info *eqp= (Gcalc_heap::Info *)heap->new_item();
+ if (!eqp)
+ return 0;
+ eqp->type= Gcalc_heap::nt_eq_node;
+ eqp->node= p;
+ eqp->eq_data= edge;
+ return eqp;
+}
+
+
+void Gcalc_heap::Info::calc_xy(double *x, double *y) const
+{
+ double b0_x= p2->x - p1->x;
+ double b0_y= p2->y - p1->y;
+ double b1_x= p4->x - p3->x;
+ double b1_y= p4->y - p3->y;
+ double b0xb1= b0_x * b1_y - b0_y * b1_x;
+ double t= (p3->x - p1->x) * b1_y - (p3->y - p1->y) * b1_x;
+
+ t/= b0xb1;
+
+ *x= p1->x + b0_x * t;
+ *y= p1->y + b0_y * t;
+}
+
+
+#ifdef GCALC_CHECK_WITH_FLOAT
+void Gcalc_heap::Info::calc_xy_ld(long double *x, long double *y) const
+{
+ long double b0_x= ((long double) p2->x) - p1->x;
+ long double b0_y= ((long double) p2->y) - p1->y;
+ long double b1_x= ((long double) p4->x) - p3->x;
+ long double b1_y= ((long double) p4->y) - p3->y;
+ long double b0xb1= b0_x * b1_y - b0_y * b1_x;
+ long double ax= ((long double) p3->x) - p1->x;
+ long double ay= ((long double) p3->y) - p1->y;
+ long double t_a= ax * b1_y - ay * b1_x;
+ long double hx= (b0xb1 * (long double) p1->x + b0_x * t_a);
+ long double hy= (b0xb1 * (long double) p1->y + b0_y * t_a);
+
+ if (fabs(b0xb1) < 1e-15)
+ {
+ *x= p1->x;
+ *y= p1->y;
+ return;
+ }
+
+ *x= hx/b0xb1;
+ *y= hy/b0xb1;
+}
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+
+
+static int cmp_point_info(const Gcalc_heap::Info *i0,
+ const Gcalc_heap::Info *i1)
+{
+ int cmp_y= gcalc_cmp_coord1(i0->iy, i1->iy);
+ if (cmp_y)
+ return cmp_y;
+ return gcalc_cmp_coord1(i0->ix, i1->ix);
+}
+
+
+static inline void trim_node(Gcalc_heap::Info *node, Gcalc_heap::Info *prev_node)
+{
+ if (!node)
+ return;
+ node->top_node= 0;
+ GCALC_DBUG_ASSERT((node->left == prev_node) || (node->right == prev_node));
+ if (node->left == prev_node)
+ node->left= node->right;
+ node->right= NULL;
+ GCALC_DBUG_ASSERT(cmp_point_info(node, prev_node));
+}
+
+
+static int compare_point_info(const void *e0, const void *e1)
+{
+ const Gcalc_heap::Info *i0= (const Gcalc_heap::Info *)e0;
+ const Gcalc_heap::Info *i1= (const Gcalc_heap::Info *)e1;
+ return cmp_point_info(i0, i1) > 0;
+}
+
+
+void Gcalc_heap::prepare_operation()
+{
+ Info *cur;
+ GCALC_DBUG_ASSERT(m_hook);
+ *m_hook= NULL;
+ m_hook= NULL; /* just to check it's not called twice */
+ m_first= sort_list(compare_point_info, m_first, m_n_points);
+
+ /* TODO - move this to the 'normal_scan' loop */
+ for (cur= get_first(); cur; cur= cur->get_next())
+ {
+ trim_node(cur->left, cur);
+ trim_node(cur->right, cur);
+ }
+}
+
+
+void Gcalc_heap::reset()
+{
+ if (m_n_points)
+ {
+ free_list(m_first);
+ m_n_points= 0;
+ }
+ m_hook= &m_first;
+}
+
+
+int Gcalc_shape_transporter::int_single_point(gcalc_shape_info Info,
+ double x, double y)
+{
+ Gcalc_heap::Info *point= m_heap->new_point_info(x, y, Info);
+ if (!point)
+ return 1;
+ point->left= point->right= 0;
+ return 0;
+}
+
+
+int Gcalc_shape_transporter::int_add_point(gcalc_shape_info Info,
+ double x, double y)
+{
+ Gcalc_heap::Info *point;
+ Gcalc_dyn_list::Item **hook;
+
+ hook= m_heap->get_cur_hook();
+
+ if (!(point= m_heap->new_point_info(x, y, Info)))
+ return 1;
+ if (m_first)
+ {
+ if (cmp_point_info(m_prev, point) == 0)
+ {
+ /* Coinciding points, do nothing */
+ m_heap->free_point_info(point, hook);
+ return 0;
+ }
+ GCALC_DBUG_ASSERT(!m_prev || m_prev->x != x || m_prev->y != y);
+ m_prev->left= point;
+ point->right= m_prev;
+ }
+ else
+ m_first= point;
+ m_prev= point;
+ m_prev_hook= hook;
+ return 0;
+}
+
+
+void Gcalc_shape_transporter::int_complete()
+{
+ GCALC_DBUG_ASSERT(m_shape_started == 1 || m_shape_started == 3);
+
+ if (!m_first)
+ return;
+
+ /* simple point */
+ if (m_first == m_prev)
+ {
+ m_first->right= m_first->left= NULL;
+ return;
+ }
+
+ /* line */
+ if (m_shape_started == 1)
+ {
+ m_first->right= NULL;
+ m_prev->left= m_prev->right;
+ m_prev->right= NULL;
+ return;
+ }
+
+ /* polygon */
+ if (cmp_point_info(m_first, m_prev) == 0)
+ {
+ /* Coinciding points, remove the last one from the list */
+ m_prev->right->left= m_first;
+ m_first->right= m_prev->right;
+ m_heap->free_point_info(m_prev, m_prev_hook);
+ }
+ else
+ {
+ GCALC_DBUG_ASSERT(m_prev->x != m_first->x || m_prev->y != m_first->y);
+ m_first->right= m_prev;
+ m_prev->left= m_first;
+ }
+}
+
+
+inline void calc_dx_dy(Gcalc_scan_iterator::point *p)
+{
+ gcalc_sub_coord1(p->dx, p->next_pi->ix, p->pi->ix);
+ gcalc_sub_coord1(p->dy, p->next_pi->iy, p->pi->iy);
+ if (GCALC_SIGN(p->dx[0]))
+ {
+ p->l_border= &p->next_pi->ix;
+ p->r_border= &p->pi->ix;
+ }
+ else
+ {
+ p->r_border= &p->next_pi->ix;
+ p->l_border= &p->pi->ix;
+ }
+}
+
+
+Gcalc_scan_iterator::Gcalc_scan_iterator(size_t blk_size) :
+ Gcalc_dyn_list(blk_size, sizeof(point) > sizeof(intersection_info) ?
+ sizeof(point) :
+ sizeof(intersection_info))
+{
+ state.slice= NULL;
+ m_bottom_points= NULL;
+ m_bottom_hook= &m_bottom_points;
+}
+
+
+void Gcalc_scan_iterator::init(Gcalc_heap *points)
+{
+ GCALC_DBUG_ASSERT(points->ready());
+ GCALC_DBUG_ASSERT(!state.slice);
+
+ if (!(m_cur_pi= points->get_first()))
+ return;
+ m_heap= points;
+ state.event_position_hook= &state.slice;
+ state.event_end= NULL;
+#ifndef GCALC_DBUG_OFF
+ m_cur_thread= 0;
+#endif /*GCALC_DBUG_OFF*/
+ GCALC_SET_TERMINATED(killed, 0);
+}
+
+void Gcalc_scan_iterator::reset()
+{
+ state.slice= NULL;
+ m_bottom_points= NULL;
+ m_bottom_hook= &m_bottom_points;
+ Gcalc_dyn_list::reset();
+}
+
+
+int Gcalc_scan_iterator::point::cmp_dx_dy(const Gcalc_coord1 dx_a,
+ const Gcalc_coord1 dy_a,
+ const Gcalc_coord1 dx_b,
+ const Gcalc_coord1 dy_b)
+{
+ Gcalc_coord2 dx_a_dy_b;
+ Gcalc_coord2 dy_a_dx_b;
+ gcalc_mul_coord1(dx_a_dy_b, dx_a, dy_b);
+ gcalc_mul_coord1(dy_a_dx_b, dy_a, dx_b);
+
+ return gcalc_cmp_coord(dx_a_dy_b, dy_a_dx_b, GCALC_COORD_BASE2);
+}
+
+
+int Gcalc_scan_iterator::point::cmp_dx_dy(const Gcalc_heap::Info *p1,
+ const Gcalc_heap::Info *p2,
+ const Gcalc_heap::Info *p3,
+ const Gcalc_heap::Info *p4)
+{
+ Gcalc_coord1 dx_a, dy_a, dx_b, dy_b;
+ gcalc_sub_coord1(dx_a, p2->ix, p1->ix);
+ gcalc_sub_coord1(dy_a, p2->iy, p1->iy);
+ gcalc_sub_coord1(dx_b, p4->ix, p3->ix);
+ gcalc_sub_coord1(dy_b, p4->iy, p3->iy);
+ return cmp_dx_dy(dx_a, dy_a, dx_b, dy_b);
+}
+
+
+int Gcalc_scan_iterator::point::cmp_dx_dy(const point *p) const
+{
+ GCALC_DBUG_ASSERT(!is_bottom());
+ return cmp_dx_dy(dx, dy, p->dx, p->dy);
+}
+
+
+#ifdef GCALC_CHECK_WITH_FLOAT
+void Gcalc_scan_iterator::point::calc_x(long double *x, long double y,
+ long double ix) const
+{
+ long double ddy= gcalc_get_double(dy, GCALC_COORD_BASE);
+ if (fabsl(ddy) < (long double) 1e-20)
+ {
+ *x= ix;
+ }
+ else
+ *x= (ddy * (long double) pi->x + gcalc_get_double(dx, GCALC_COORD_BASE) *
+ (y - pi->y)) / ddy;
+}
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+
+
+static int compare_events(const void *e0, const void *e1)
+{
+ const Gcalc_scan_iterator::point *p0= (const Gcalc_scan_iterator::point *)e0;
+ const Gcalc_scan_iterator::point *p1= (const Gcalc_scan_iterator::point *)e1;
+ return p0->cmp_dx_dy(p1) > 0;
+}
+
+
+int Gcalc_scan_iterator::arrange_event(int do_sorting, int n_intersections)
+{
+ int ev_counter;
+ point *sp;
+ point **sp_hook;
+
+ ev_counter= 0;
+
+ *m_bottom_hook= NULL;
+ for (sp= m_bottom_points; sp; sp= sp->get_next())
+ sp->ev_next= sp->get_next();
+
+ for (sp= state.slice, sp_hook= &state.slice;
+ sp; sp_hook= sp->next_ptr(), sp= sp->get_next())
+ {
+ if (sp->event)
+ {
+ state.event_position_hook= sp_hook;
+ break;
+ }
+ }
+
+ for (sp= *(sp_hook= state.event_position_hook);
+ sp && sp->event; sp_hook= sp->next_ptr(), sp= sp->get_next())
+ {
+ ev_counter++;
+ if (sp->get_next() && sp->get_next()->event)
+ sp->ev_next= sp->get_next();
+ else
+ sp->ev_next= m_bottom_points;
+ }
+
+#ifndef GCALC_DBUG_OFF
+ {
+ point *cur_p= sp;
+ for (; cur_p; cur_p= cur_p->get_next())
+ GCALC_DBUG_ASSERT(!cur_p->event);
+ }
+#endif /*GCALC_DBUG_OFF*/
+
+ state.event_end= sp;
+
+ if (ev_counter == 2 && n_intersections == 1)
+ {
+ /* If we had only intersection, just swap the two points. */
+ sp= *state.event_position_hook;
+ *state.event_position_hook= sp->get_next();
+ sp->next= (*state.event_position_hook)->next;
+ (*state.event_position_hook)->next= sp;
+
+ /* The list of the events should be restored. */
+ (*state.event_position_hook)->ev_next= sp;
+ sp->ev_next= m_bottom_points;
+ }
+ else if (ev_counter == 2 && get_events()->event == scev_two_threads)
+ {
+ /* Do nothing. */
+ }
+ else if (ev_counter > 1 && do_sorting)
+ {
+ point *cur_p;
+ *sp_hook= NULL;
+ sp= (point *) sort_list(compare_events, *state.event_position_hook,
+ ev_counter);
+ /* Find last item in the list, it's changed after the sorting. */
+ for (cur_p= sp->get_next(); cur_p->get_next();
+ cur_p= cur_p->get_next())
+ {}
+ cur_p->next= state.event_end;
+ *state.event_position_hook= sp;
+ /* The list of the events should be restored. */
+ for (; sp && sp->event; sp= sp->get_next())
+ {
+ if (sp->get_next() && sp->get_next()->event)
+ sp->ev_next= sp->get_next();
+ else
+ sp->ev_next= m_bottom_points;
+ }
+ }
+
+#ifndef GCALC_DBUG_OFF
+ {
+ const event_point *ev= get_events();
+ for (; ev && ev->get_next(); ev= ev->get_next())
+ {
+ if (ev->is_bottom() || ev->get_next()->is_bottom())
+ break;
+ GCALC_DBUG_ASSERT(ev->cmp_dx_dy(ev->get_next()) <= 0);
+ }
+ }
+#endif /*GCALC_DBUG_OFF*/
+ return 0;
+}
+
+
+int Gcalc_heap::Info::equal_pi(const Info *pi) const
+{
+ if (type == nt_intersection)
+ return equal_intersection;
+ if (pi->type == nt_eq_node)
+ return 1;
+ if (type == nt_eq_node || pi->type == nt_intersection)
+ return 0;
+ return cmp_point_info(this, pi) == 0;
+}
+
+int Gcalc_scan_iterator::step()
+{
+ int result= 0;
+ int do_sorting= 0;
+ int n_intersections= 0;
+ point *sp;
+ GCALC_DBUG_ENTER("Gcalc_scan_iterator::step");
+ GCALC_DBUG_ASSERT(more_points());
+
+ if (GCALC_TERMINATED(killed))
+ GCALC_DBUG_RETURN(0xFFFF);
+
+ /* Clear the old event marks. */
+ if (m_bottom_points)
+ {
+ free_list((Gcalc_dyn_list::Item **) &m_bottom_points,
+ (Gcalc_dyn_list::Item **) m_bottom_hook);
+ m_bottom_points= NULL;
+ m_bottom_hook= &m_bottom_points;
+ }
+ for (sp= *state.event_position_hook;
+ sp != state.event_end; sp= sp->get_next())
+ sp->event= scev_none;
+
+//#ifndef GCALC_DBUG_OFF
+ state.event_position_hook= NULL;
+ state.pi= NULL;
+//#endif /*GCALC_DBUG_OFF*/
+
+ do
+ {
+#ifndef GCALC_DBUG_OFF
+ if (m_cur_pi->type == Gcalc_heap::nt_intersection &&
+ m_cur_pi->get_next()->type == Gcalc_heap::nt_intersection &&
+ m_cur_pi->equal_intersection)
+ GCALC_DBUG_ASSERT(cmp_intersections(m_cur_pi, m_cur_pi->get_next()) == 0);
+#endif /*GCALC_DBUG_OFF*/
+ GCALC_DBUG_CHECK_COUNTER();
+ GCALC_DBUG_PRINT_SLICE("step:", state.slice);
+ GCALC_DBUG_PRINT_PI(m_cur_pi);
+ if (m_cur_pi->type == Gcalc_heap::nt_shape_node)
+ {
+ if (m_cur_pi->is_top())
+ {
+ result= insert_top_node();
+ if (!m_cur_pi->is_bottom())
+ do_sorting++;
+ }
+ else if (m_cur_pi->is_bottom())
+ remove_bottom_node();
+ else
+ {
+ do_sorting++;
+ result= node_scan();
+ }
+ if (result)
+ GCALC_DBUG_RETURN(result);
+ state.pi= m_cur_pi;
+ }
+ else if (m_cur_pi->type == Gcalc_heap::nt_eq_node)
+ {
+ do_sorting++;
+ eq_scan();
+ }
+ else
+ {
+ /* nt_intersection */
+ do_sorting++;
+ n_intersections++;
+ intersection_scan();
+ if (!state.pi || state.pi->type == Gcalc_heap::nt_intersection)
+ state.pi= m_cur_pi;
+ }
+
+ m_cur_pi= m_cur_pi->get_next();
+ } while (m_cur_pi && state.pi->equal_pi(m_cur_pi));
+
+ GCALC_DBUG_RETURN(arrange_event(do_sorting, n_intersections));
+}
+
+
+static int node_on_right(const Gcalc_heap::Info *node,
+ const Gcalc_heap::Info *edge_a, const Gcalc_heap::Info *edge_b)
+{
+ Gcalc_coord1 a_x, a_y;
+ Gcalc_coord1 b_x, b_y;
+ Gcalc_coord2 ax_by, ay_bx;
+ int result;
+
+ gcalc_sub_coord1(a_x, node->ix, edge_a->ix);
+ gcalc_sub_coord1(a_y, node->iy, edge_a->iy);
+ gcalc_sub_coord1(b_x, edge_b->ix, edge_a->ix);
+ gcalc_sub_coord1(b_y, edge_b->iy, edge_a->iy);
+ gcalc_mul_coord1(ax_by, a_x, b_y);
+ gcalc_mul_coord1(ay_bx, a_y, b_x);
+ result= gcalc_cmp_coord(ax_by, ay_bx, GCALC_COORD_BASE2);
+#ifdef GCALC_CHECK_WITH_FLOAT
+ {
+ long double dx= gcalc_get_double(edge_b->ix, GCALC_COORD_BASE) -
+ gcalc_get_double(edge_a->ix, GCALC_COORD_BASE);
+ long double dy= gcalc_get_double(edge_b->iy, GCALC_COORD_BASE) -
+ gcalc_get_double(edge_a->iy, GCALC_COORD_BASE);
+ long double ax= gcalc_get_double(node->ix, GCALC_COORD_BASE) -
+ gcalc_get_double(edge_a->ix, GCALC_COORD_BASE);
+ long double ay= gcalc_get_double(node->iy, GCALC_COORD_BASE) -
+ gcalc_get_double(edge_a->iy, GCALC_COORD_BASE);
+ long double d= ax * dy - ay * dx;
+ if (result == 0)
+ GCALC_DBUG_ASSERT(de_check(d, 0.0));
+ else if (result < 0)
+ GCALC_DBUG_ASSERT(de_check(d, 0.0) || d < 0);
+ else
+ GCALC_DBUG_ASSERT(de_check(d, 0.0) || d > 0);
+ }
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+ return result;
+}
+
+
+static int cmp_tops(const Gcalc_heap::Info *top_node,
+ const Gcalc_heap::Info *edge_a, const Gcalc_heap::Info *edge_b)
+{
+ int cmp_res_a, cmp_res_b;
+
+ cmp_res_a= gcalc_cmp_coord1(edge_a->ix, top_node->ix);
+ cmp_res_b= gcalc_cmp_coord1(edge_b->ix, top_node->ix);
+
+ if (cmp_res_a <= 0 && cmp_res_b > 0)
+ return -1;
+ if (cmp_res_b <= 0 && cmp_res_a > 0)
+ return 1;
+ if (cmp_res_a == 0 && cmp_res_b == 0)
+ return 0;
+
+ return node_on_right(edge_a, top_node, edge_b);
+}
+
+
+int Gcalc_scan_iterator::insert_top_node()
+{
+ point *sp= state.slice;
+ point **prev_hook= &state.slice;
+ point *sp1= NULL;
+ point *sp0= new_slice_point();
+ int cmp_res;
+
+ GCALC_DBUG_ENTER("Gcalc_scan_iterator::insert_top_node");
+ if (!sp0)
+ GCALC_DBUG_RETURN(1);
+ sp0->pi= m_cur_pi;
+ sp0->next_pi= m_cur_pi->left;
+#ifndef GCALC_DBUG_OFF
+ sp0->thread= m_cur_thread++;
+#endif /*GCALC_DBUG_OFF*/
+ if (m_cur_pi->left)
+ {
+ calc_dx_dy(sp0);
+ if (m_cur_pi->right)
+ {
+ if (!(sp1= new_slice_point()))
+ GCALC_DBUG_RETURN(1);
+ sp1->event= sp0->event= scev_two_threads;
+ sp1->pi= m_cur_pi;
+ sp1->next_pi= m_cur_pi->right;
+#ifndef GCALC_DBUG_OFF
+ sp1->thread= m_cur_thread++;
+#endif /*GCALC_DBUG_OFF*/
+ calc_dx_dy(sp1);
+ /* We have two threads so should decide which one will be first */
+ cmp_res= cmp_tops(m_cur_pi, m_cur_pi->left, m_cur_pi->right);
+ if (cmp_res > 0)
+ {
+ point *tmp= sp0;
+ sp0= sp1;
+ sp1= tmp;
+ }
+ else if (cmp_res == 0)
+ {
+ /* Exactly same direction of the edges. */
+ cmp_res= gcalc_cmp_coord1(m_cur_pi->left->iy, m_cur_pi->right->iy);
+ if (cmp_res != 0)
+ {
+ if (cmp_res < 0)
+ {
+ if (add_eq_node(sp0->next_pi, sp1))
+ GCALC_DBUG_RETURN(1);
+ }
+ else
+ {
+ if (add_eq_node(sp1->next_pi, sp0))
+ GCALC_DBUG_RETURN(1);
+ }
+ }
+ else
+ {
+ cmp_res= gcalc_cmp_coord1(m_cur_pi->left->ix, m_cur_pi->right->ix);
+ if (cmp_res != 0)
+ {
+ if (cmp_res < 0)
+ {
+ if (add_eq_node(sp0->next_pi, sp1))
+ GCALC_DBUG_RETURN(1);
+ }
+ else
+ {
+ if (add_eq_node(sp1->next_pi, sp0))
+ GCALC_DBUG_RETURN(1);
+ }
+ }
+ }
+ }
+ }
+ else
+ sp0->event= scev_thread;
+ }
+ else
+ sp0->event= scev_single_point;
+
+
+ /* Check if we already have an event - then we'll place the node there */
+ for (; sp && !sp->event; prev_hook= sp->next_ptr(), sp=sp->get_next())
+ {}
+ if (!sp)
+ {
+ sp= state.slice;
+ prev_hook= &state.slice;
+ /* We need to find the place to insert. */
+ for (; sp; prev_hook= sp->next_ptr(), sp=sp->get_next())
+ {
+ if (sp->event || gcalc_cmp_coord1(*sp->r_border, m_cur_pi->ix) < 0)
+ continue;
+ cmp_res= node_on_right(m_cur_pi, sp->pi, sp->next_pi);
+ if (cmp_res == 0)
+ {
+ /* The top node lies on the edge. */
+ /* Nodes of that edge will be handled in other places. */
+ sp->event= scev_intersection;
+ }
+ else if (cmp_res < 0)
+ break;
+ }
+ }
+
+ if (sp0->event == scev_single_point)
+ {
+ /* Add single point to the bottom list. */
+ *m_bottom_hook= sp0;
+ m_bottom_hook= sp0->next_ptr();
+ state.event_position_hook= prev_hook;
+ }
+ else
+ {
+ *prev_hook= sp0;
+ sp0->next= sp;
+ if (add_events_for_node(sp0))
+ GCALC_DBUG_RETURN(1);
+
+ if (sp0->event == scev_two_threads)
+ {
+ *prev_hook= sp1;
+ sp1->next= sp;
+ if (add_events_for_node(sp1))
+ GCALC_DBUG_RETURN(1);
+
+ sp0->next= sp1;
+ *prev_hook= sp0;
+ }
+ }
+
+ GCALC_DBUG_RETURN(0);
+}
+
+
+void Gcalc_scan_iterator::remove_bottom_node()
+{
+ point *sp= state.slice;
+ point **sp_hook= &state.slice;
+ point *first_bottom_point= NULL;
+
+ GCALC_DBUG_ENTER("Gcalc_scan_iterator::remove_bottom_node");
+ for (; sp; sp= sp->get_next())
+ {
+ if (sp->next_pi == m_cur_pi)
+ {
+ *sp_hook= sp->get_next();
+ sp->pi= m_cur_pi;
+ sp->next_pi= NULL;
+ if (first_bottom_point)
+ {
+ first_bottom_point->event= sp->event= scev_two_ends;
+ break;
+ }
+ first_bottom_point= sp;
+ sp->event= scev_end;
+ state.event_position_hook= sp_hook;
+ }
+ else
+ sp_hook= sp->next_ptr();
+ }
+ GCALC_DBUG_ASSERT(first_bottom_point);
+ *m_bottom_hook= first_bottom_point;
+ m_bottom_hook= first_bottom_point->next_ptr();
+ if (sp)
+ {
+ *m_bottom_hook= sp;
+ m_bottom_hook= sp->next_ptr();
+ }
+
+ GCALC_DBUG_VOID_RETURN;
+}
+
+
+int Gcalc_scan_iterator::add_events_for_node(point *sp_node)
+{
+ point *sp= state.slice;
+ int cur_pi_r, sp_pi_r;
+
+ GCALC_DBUG_ENTER("Gcalc_scan_iterator::add_events_for_node");
+
+ /* Scan to the event point. */
+ for (; sp != sp_node; sp= sp->get_next())
+ {
+ GCALC_DBUG_ASSERT(!sp->is_bottom());
+ GCALC_DBUG_PRINT(("left cut_edge %d", sp->thread));
+ if (sp->next_pi == sp_node->next_pi ||
+ gcalc_cmp_coord1(*sp->r_border, *sp_node->l_border) < 0)
+ continue;
+ sp_pi_r= node_on_right(sp->next_pi, sp_node->pi, sp_node->next_pi);
+ if (sp_pi_r < 0)
+ continue;
+ cur_pi_r= node_on_right(sp_node->next_pi, sp->pi, sp->next_pi);
+ if (cur_pi_r > 0)
+ continue;
+ if (cur_pi_r == 0 && sp_pi_r == 0)
+ {
+ int cmp_res= cmp_point_info(sp->next_pi, sp_node->next_pi);
+ if (cmp_res > 0)
+ {
+ if (add_eq_node(sp_node->next_pi, sp))
+ GCALC_DBUG_RETURN(1);
+ }
+ else if (cmp_res < 0)
+ {
+ if (add_eq_node(sp->next_pi, sp_node))
+ GCALC_DBUG_RETURN(1);
+ }
+ continue;
+ }
+
+ if (cur_pi_r == 0)
+ {
+ if (add_eq_node(sp_node->next_pi, sp))
+ GCALC_DBUG_RETURN(1);
+ continue;
+ }
+ else if (sp_pi_r == 0)
+ {
+ if (add_eq_node(sp->next_pi, sp_node))
+ GCALC_DBUG_RETURN(1);
+ continue;
+ }
+
+ if (sp->event)
+ {
+#ifndef GCALC_DBUG_OFF
+ cur_pi_r= node_on_right(sp_node->pi, sp->pi, sp->next_pi);
+ GCALC_DBUG_ASSERT(cur_pi_r == 0);
+#endif /*GCALC_DBUG_OFF*/
+ continue;
+ }
+ cur_pi_r= node_on_right(sp_node->pi, sp->pi, sp->next_pi);
+ GCALC_DBUG_ASSERT(cur_pi_r >= 0);
+ //GCALC_DBUG_ASSERT(cur_pi_r > 0); /* Is it ever violated? */
+ if (cur_pi_r > 0 && add_intersection(sp, sp_node, m_cur_pi))
+ GCALC_DBUG_RETURN(1);
+ }
+
+ /* Scan to the end of the slice */
+ sp= sp->get_next();
+
+ for (; sp; sp= sp->get_next())
+ {
+ GCALC_DBUG_ASSERT(!sp->is_bottom());
+ GCALC_DBUG_PRINT(("right cut_edge %d", sp->thread));
+ if (sp->next_pi == sp_node->next_pi ||
+ gcalc_cmp_coord1(*sp_node->r_border, *sp->l_border) < 0)
+ continue;
+ sp_pi_r= node_on_right(sp->next_pi, sp_node->pi, sp_node->next_pi);
+ if (sp_pi_r > 0)
+ continue;
+ cur_pi_r= node_on_right(sp_node->next_pi, sp->pi, sp->next_pi);
+ if (cur_pi_r < 0)
+ continue;
+ if (cur_pi_r == 0 && sp_pi_r == 0)
+ {
+ int cmp_res= cmp_point_info(sp->next_pi, sp_node->next_pi);
+ if (cmp_res > 0)
+ {
+ if (add_eq_node(sp_node->next_pi, sp))
+ GCALC_DBUG_RETURN(1);
+ }
+ else if (cmp_res < 0)
+ {
+ if (add_eq_node(sp->next_pi, sp_node))
+ GCALC_DBUG_RETURN(1);
+ }
+ continue;
+ }
+ if (cur_pi_r == 0)
+ {
+ if (add_eq_node(sp_node->next_pi, sp))
+ GCALC_DBUG_RETURN(1);
+ continue;
+ }
+ else if (sp_pi_r == 0)
+ {
+ if (add_eq_node(sp->next_pi, sp_node))
+ GCALC_DBUG_RETURN(1);
+ continue;
+ }
+
+ if (sp->event)
+ {
+#ifndef GCALC_DBUG_OFF
+ cur_pi_r= node_on_right(sp_node->pi, sp->pi, sp->next_pi);
+ GCALC_DBUG_ASSERT(cur_pi_r == 0);
+#endif /*GCALC_DBUG_OFF*/
+ continue;
+ }
+ cur_pi_r= node_on_right(sp_node->pi, sp->pi, sp->next_pi);
+ GCALC_DBUG_ASSERT(cur_pi_r <= 0);
+ //GCALC_DBUG_ASSERT(cur_pi_r < 0); /* Is it ever violated? */
+ if (cur_pi_r < 0 && add_intersection(sp_node, sp, m_cur_pi))
+ GCALC_DBUG_RETURN(1);
+ }
+
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_scan_iterator::node_scan()
+{
+ point *sp= state.slice;
+ Gcalc_heap::Info *cur_pi= m_cur_pi;
+
+ GCALC_DBUG_ENTER("Gcalc_scan_iterator::node_scan");
+
+ /* Scan to the event point. */
+ /* Can be avoided if we add link to the sp to the Info. */
+ for (; sp->next_pi != cur_pi; sp= sp->get_next())
+ {}
+
+ GCALC_DBUG_PRINT(("node for %d", sp->thread));
+ /* Handle the point itself. */
+ sp->pi= cur_pi;
+ sp->next_pi= cur_pi->left;
+ sp->event= scev_point;
+ calc_dx_dy(sp);
+
+ GCALC_DBUG_RETURN(add_events_for_node(sp));
+}
+
+
+void Gcalc_scan_iterator::eq_scan()
+{
+ point *sp= eq_sp(m_cur_pi);
+ GCALC_DBUG_ENTER("Gcalc_scan_iterator::eq_scan");
+
+#ifndef GCALC_DBUG_OFF
+ {
+ point *cur_p= state.slice;
+ for (; cur_p && cur_p != sp; cur_p= cur_p->get_next())
+ {}
+ GCALC_DBUG_ASSERT(cur_p);
+ }
+#endif /*GCALC_DBUG_OFF*/
+ if (!sp->event)
+ {
+ sp->event= scev_intersection;
+ sp->ev_pi= m_cur_pi;
+ }
+
+ GCALC_DBUG_VOID_RETURN;
+}
+
+
+void Gcalc_scan_iterator::intersection_scan()
+{
+ intersection_info *ii= i_data(m_cur_pi);
+ GCALC_DBUG_ENTER("Gcalc_scan_iterator::intersection_scan");
+
+#ifndef GCALC_DBUG_OFF
+ {
+ point *sp= state.slice;
+ for (; sp && sp != ii->edge_a; sp= sp->get_next())
+ {}
+ GCALC_DBUG_ASSERT(sp);
+ for (; sp && sp != ii->edge_b; sp= sp->get_next())
+ {}
+ GCALC_DBUG_ASSERT(sp);
+ }
+#endif /*GCALC_DBUG_OFF*/
+
+ ii->edge_a->event= ii->edge_b->event= scev_intersection;
+ ii->edge_a->ev_pi= ii->edge_b->ev_pi= m_cur_pi;
+ free_item(ii);
+ m_cur_pi->intersection_data= NULL;
+
+ GCALC_DBUG_VOID_RETURN;
+}
+
+
+int Gcalc_scan_iterator::add_intersection(point *sp_a, point *sp_b,
+ Gcalc_heap::Info *pi_from)
+{
+ Gcalc_heap::Info *ii;
+ intersection_info *i_calc;
+ int cmp_res;
+ int skip_next= 0;
+
+ GCALC_DBUG_ENTER("Gcalc_scan_iterator::add_intersection");
+ if (!(i_calc= new_intersection_info(sp_a, sp_b)) ||
+ !(ii= new_intersection(m_heap, i_calc)))
+ GCALC_DBUG_RETURN(1);
+
+ ii->equal_intersection= 0;
+
+ for (;
+ pi_from->get_next() != sp_a->next_pi &&
+ pi_from->get_next() != sp_b->next_pi;
+ pi_from= pi_from->get_next())
+ {
+ Gcalc_heap::Info *cur= pi_from->get_next();
+ if (skip_next)
+ {
+ if (cur->type == Gcalc_heap::nt_intersection)
+ skip_next= cur->equal_intersection;
+ else
+ skip_next= 0;
+ continue;
+ }
+ if (cur->type == Gcalc_heap::nt_intersection)
+ {
+ cmp_res= cmp_intersections(cur, ii);
+ skip_next= cur->equal_intersection;
+ }
+ else if (cur->type == Gcalc_heap::nt_eq_node)
+ continue;
+ else
+ cmp_res= cmp_node_isc(cur, ii);
+ if (cmp_res == 0)
+ {
+ ii->equal_intersection= 1;
+ break;
+ }
+ else if (cmp_res > 0)
+ break;
+ }
+
+ /* Intersection inserted before the equal point. */
+ ii->next= pi_from->get_next();
+ pi_from->next= ii;
+
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_scan_iterator::add_eq_node(Gcalc_heap::Info *node, point *sp)
+{
+ Gcalc_heap::Info *en;
+
+ GCALC_DBUG_ENTER("Gcalc_scan_iterator::add_intersection");
+ en= new_eq_point(m_heap, node, sp);
+ if (!en)
+ GCALC_DBUG_RETURN(1);
+
+ /* eq_node iserted after teh equal point. */
+ en->next= node->get_next();
+ node->next= en;
+
+ GCALC_DBUG_RETURN(0);
+}
+
+
+void calc_t(Gcalc_coord2 t_a, Gcalc_coord2 t_b,
+ Gcalc_coord1 dxa, Gcalc_coord1 dxb,
+ const Gcalc_heap::Info *p1, const Gcalc_heap::Info *p2,
+ const Gcalc_heap::Info *p3, const Gcalc_heap::Info *p4)
+{
+ Gcalc_coord1 a2_a1x, a2_a1y;
+ Gcalc_coord2 x1y2, x2y1;
+ Gcalc_coord1 dya, dyb;
+
+ gcalc_sub_coord1(a2_a1x, p3->ix, p1->ix);
+ gcalc_sub_coord1(a2_a1y, p3->iy, p1->iy);
+
+ gcalc_sub_coord1(dxa, p2->ix, p1->ix);
+ gcalc_sub_coord1(dya, p2->iy, p1->iy);
+ gcalc_sub_coord1(dxb, p4->ix, p3->ix);
+ gcalc_sub_coord1(dyb, p4->iy, p3->iy);
+
+ gcalc_mul_coord1(x1y2, dxa, dyb);
+ gcalc_mul_coord1(x2y1, dya, dxb);
+ gcalc_sub_coord(t_b, GCALC_COORD_BASE2, x1y2, x2y1);
+
+
+ gcalc_mul_coord1(x1y2, a2_a1x, dyb);
+ gcalc_mul_coord1(x2y1, a2_a1y, dxb);
+ gcalc_sub_coord(t_a, GCALC_COORD_BASE2, x1y2, x2y1);
+}
+
+
+double Gcalc_scan_iterator::get_y() const
+{
+ if (state.pi->type == Gcalc_heap::nt_intersection)
+ {
+ Gcalc_coord1 dxa, dya;
+ Gcalc_coord2 t_a, t_b;
+ Gcalc_coord3 a_tb, b_ta, y_exp;
+ calc_t(t_a, t_b, dxa, dya,
+ state.pi->p1, state.pi->p2, state.pi->p3, state.pi->p4);
+
+
+ gcalc_mul_coord(a_tb, GCALC_COORD_BASE3,
+ t_b, GCALC_COORD_BASE2, state.pi->p1->iy, GCALC_COORD_BASE);
+ gcalc_mul_coord(b_ta, GCALC_COORD_BASE3,
+ t_a, GCALC_COORD_BASE2, dya, GCALC_COORD_BASE);
+
+ gcalc_add_coord(y_exp, GCALC_COORD_BASE3, a_tb, b_ta);
+
+ return (get_pure_double(y_exp, GCALC_COORD_BASE3) /
+ get_pure_double(t_b, GCALC_COORD_BASE2)) / m_heap->coord_extent;
+ }
+ else
+ return state.pi->y;
+}
+
+
+double Gcalc_scan_iterator::get_event_x() const
+{
+ if (state.pi->type == Gcalc_heap::nt_intersection)
+ {
+ Gcalc_coord1 dxa, dya;
+ Gcalc_coord2 t_a, t_b;
+ Gcalc_coord3 a_tb, b_ta, x_exp;
+ calc_t(t_a, t_b, dxa, dya,
+ state.pi->p1, state.pi->p2, state.pi->p3, state.pi->p4);
+
+
+ gcalc_mul_coord(a_tb, GCALC_COORD_BASE3,
+ t_b, GCALC_COORD_BASE2, state.pi->p1->ix, GCALC_COORD_BASE);
+ gcalc_mul_coord(b_ta, GCALC_COORD_BASE3,
+ t_a, GCALC_COORD_BASE2, dxa, GCALC_COORD_BASE);
+
+ gcalc_add_coord(x_exp, GCALC_COORD_BASE3, a_tb, b_ta);
+
+ return (get_pure_double(x_exp, GCALC_COORD_BASE3) /
+ get_pure_double(t_b, GCALC_COORD_BASE2)) / m_heap->coord_extent;
+ }
+ else
+ return state.pi->x;
+}
+
+double Gcalc_scan_iterator::get_h() const
+{
+ double cur_y= get_y();
+ double next_y;
+ if (state.pi->type == Gcalc_heap::nt_intersection)
+ {
+ double x;
+ state.pi->calc_xy(&x, &next_y);
+ }
+ else
+ next_y= state.pi->y;
+ return next_y - cur_y;
+}
+
+
+double Gcalc_scan_iterator::get_sp_x(const point *sp) const
+{
+ double dy;
+ if (sp->event & (scev_end | scev_two_ends | scev_point))
+ return sp->pi->x;
+ dy= sp->next_pi->y - sp->pi->y;
+ if (fabs(dy) < 1e-12)
+ return sp->pi->x;
+ return (sp->next_pi->x - sp->pi->x) * dy;
+}
+
+
+double Gcalc_scan_iterator::get_pure_double(const Gcalc_internal_coord *d,
+ int d_len)
+{
+ int n= 1;
+ long double res= (long double) FIRST_DIGIT(d[0]);
+ do
+ {
+ res*= (long double) GCALC_DIG_BASE;
+ res+= (long double) d[n];
+ } while(++n < d_len);
+
+ if (GCALC_SIGN(d[0]))
+ res*= -1.0;
+ return res;
+}
+
+
+#endif /* HAVE_SPATIAL */
diff --git a/sql/gcalc_slicescan.h b/sql/gcalc_slicescan.h
new file mode 100644
index 00000000000..55de497f1ee
--- /dev/null
+++ b/sql/gcalc_slicescan.h
@@ -0,0 +1,600 @@
+/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved.
+ Copyright (C) 2011 Monty Program Ab.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+#ifndef GCALC_SLICESCAN_INCLUDED
+#define GCALC_SLICESCAN_INCLUDED
+
+#ifndef DBUG_OFF
+// #define GCALC_CHECK_WITH_FLOAT
+#else
+#define GCALC_DBUG_OFF
+#endif /*DBUG_OFF*/
+
+#ifndef GCALC_DBUG_OFF
+#define GCALC_DBUG_PRINT(b) DBUG_PRINT("Gcalc", b)
+#define GCALC_DBUG_ENTER(a) DBUG_ENTER("Gcalc "a)
+#define GCALC_DBUG_RETURN(r) DBUG_RETURN(r)
+#define GCALC_DBUG_VOID_RETURN DBUG_VOID_RETURN
+#define GCALC_DBUG_ASSERT(r) DBUG_ASSERT(r)
+#else
+#define GCALC_DBUG_PRINT(b) do {} while(0)
+#define GCALC_DBUG_ENTER(a) do {} while(0)
+#define GCALC_DBUG_RETURN(r) return (r)
+#define GCALC_DBUG_VOID_RETURN do {} while(0)
+#define GCALC_DBUG_ASSERT(r) do {} while(0)
+#endif /*GCALC_DBUG_OFF*/
+
+#define GCALC_TERMINATED(state_var) (state_var && (*state_var))
+#define GCALC_SET_TERMINATED(state_var, val) state_var= val
+#define GCALC_DECL_TERMINATED_STATE(varname) \
+ volatile int *varname;
+
+/*
+ Gcalc_dyn_list class designed to manage long lists of same-size objects
+ with the possible efficiency.
+ It allocates fixed-size blocks of memory (blk_size specified at the time
+ of creation). When new object is added to the list, it occupies part of
+ this block until it's full. Then the new block is allocated.
+ Freed objects are chained to the m_free list, and if it's not empty, the
+ newly added object is taken from this list instead the block.
+*/
+
+class Gcalc_dyn_list
+{
+public:
+ class Item
+ {
+ public:
+ Item *next;
+ };
+
+ Gcalc_dyn_list(size_t blk_size, size_t sizeof_item);
+ ~Gcalc_dyn_list();
+ Item *new_item()
+ {
+ Item *result;
+ if (m_free)
+ {
+ result= m_free;
+ m_free= m_free->next;
+ }
+ else
+ result= alloc_new_blk();
+
+ return result;
+ }
+ inline void free_item(Item *item)
+ {
+ item->next= m_free;
+ m_free= item;
+ }
+ inline void free_list(Item **list, Item **hook)
+ {
+ *hook= m_free;
+ m_free= *list;
+ }
+
+ void free_list(Item *list)
+ {
+ Item **hook= &list;
+ while (*hook)
+ hook= &(*hook)->next;
+ free_list(&list, hook);
+ }
+
+ void reset();
+ void cleanup();
+
+protected:
+ size_t m_blk_size;
+ size_t m_sizeof_item;
+ unsigned int m_points_per_blk;
+ void *m_first_blk;
+ void **m_blk_hook;
+ Item *m_free;
+ Item *m_keep;
+
+ Item *alloc_new_blk();
+ void format_blk(void* block);
+ inline Item *ptr_add(Item *ptr, int n_items)
+ {
+ return (Item *)(((char*)ptr) + n_items * m_sizeof_item);
+ }
+};
+
+/* Internal Gcalc coordinates to provide the precise calculations */
+
+#define GCALC_DIG_BASE 1000000000
+typedef uint32 gcalc_digit_t;
+typedef unsigned long long gcalc_coord2;
+typedef gcalc_digit_t Gcalc_internal_coord;
+#define GCALC_COORD_BASE 2
+#define GCALC_COORD_BASE2 4
+#define GCALC_COORD_BASE3 6
+#define GCALC_COORD_BASE4 8
+#define GCALC_COORD_BASE5 10
+
+typedef gcalc_digit_t Gcalc_coord1[GCALC_COORD_BASE];
+typedef gcalc_digit_t Gcalc_coord2[GCALC_COORD_BASE*2];
+typedef gcalc_digit_t Gcalc_coord3[GCALC_COORD_BASE*3];
+
+
+void gcalc_mul_coord(Gcalc_internal_coord *result, int result_len,
+ const Gcalc_internal_coord *a, int a_len,
+ const Gcalc_internal_coord *b, int b_len);
+
+void gcalc_add_coord(Gcalc_internal_coord *result, int result_len,
+ const Gcalc_internal_coord *a,
+ const Gcalc_internal_coord *b);
+
+void gcalc_sub_coord(Gcalc_internal_coord *result, int result_len,
+ const Gcalc_internal_coord *a,
+ const Gcalc_internal_coord *b);
+
+int gcalc_cmp_coord(const Gcalc_internal_coord *a,
+ const Gcalc_internal_coord *b, int len);
+
+/* Internal coordinates declarations end. */
+
+
+typedef uint gcalc_shape_info;
+
+/*
+ Gcalc_heap represents the 'dynamic list' of Info objects, that
+ contain information about vertexes of all the shapes that take
+ part in some spatial calculation. Can become quite long.
+ After filled, the list is usually sorted and then walked through
+ in the slicescan algorithm.
+ The Gcalc_heap and the algorithm can only operate with two
+ kinds of shapes - polygon and polyline. So all the spatial
+ objects should be represented as sets of these two.
+*/
+
+class Gcalc_heap : public Gcalc_dyn_list
+{
+public:
+ enum node_type
+ {
+ nt_shape_node,
+ nt_intersection,
+ nt_eq_node
+ };
+ class Info : public Gcalc_dyn_list::Item
+ {
+ public:
+ node_type type;
+ union
+ {
+ struct
+ {
+ /* nt_shape_node */
+ gcalc_shape_info shape;
+ Info *left;
+ Info *right;
+ double x,y;
+ Gcalc_coord1 ix, iy;
+ int top_node;
+ };
+ struct
+ {
+ /* nt_intersection */
+ /* Line p1-p2 supposed to intersect line p3-p4 */
+ const Info *p1;
+ const Info *p2;
+ const Info *p3;
+ const Info *p4;
+ void *intersection_data;
+ int equal_intersection;
+ };
+ struct
+ {
+ /* nt_eq_node */
+ const Info *node;
+ void *eq_data;
+ };
+ };
+
+ bool is_bottom() const
+ { GCALC_DBUG_ASSERT(type == nt_shape_node); return !left; }
+ bool is_top() const
+ { GCALC_DBUG_ASSERT(type == nt_shape_node); return top_node; }
+ bool is_single_node() const
+ { return is_bottom() && is_top(); }
+
+ void calc_xy(double *x, double *y) const;
+ int equal_pi(const Info *pi) const;
+#ifdef GCALC_CHECK_WITH_FLOAT
+ void calc_xy_ld(long double *x, long double *y) const;
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+
+ Info *get_next() { return (Info *)next; }
+ const Info *get_next() const { return (const Info *)next; }
+ };
+
+ Gcalc_heap(size_t blk_size=8192) :
+ Gcalc_dyn_list(blk_size, sizeof(Info)),
+ m_hook(&m_first), m_n_points(0)
+ {}
+ void set_extent(double xmin, double xmax, double ymin, double ymax);
+ Info *new_point_info(double x, double y, gcalc_shape_info shape);
+ void free_point_info(Info *i, Gcalc_dyn_list::Item **i_hook);
+ Info *new_intersection(const Info *p1, const Info *p2,
+ const Info *p3, const Info *p4);
+ void prepare_operation();
+ inline bool ready() const { return m_hook == NULL; }
+ Info *get_first() { return (Info *)m_first; }
+ const Info *get_first() const { return (const Info *)m_first; }
+ Gcalc_dyn_list::Item **get_last_hook() { return m_hook; }
+ void reset();
+#ifdef GCALC_CHECK_WITH_FLOAT
+ long double get_double(const Gcalc_internal_coord *c) const;
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+ double coord_extent;
+ Gcalc_dyn_list::Item **get_cur_hook() { return m_hook; }
+
+private:
+ Gcalc_dyn_list::Item *m_first;
+ Gcalc_dyn_list::Item **m_hook;
+ int m_n_points;
+};
+
+
+/*
+ the spatial object has to be represented as a set of
+ simple polygones and polylines to be sent to the slicescan.
+
+ Gcalc_shape_transporter class and his descendants are used to
+ simplify storing the information about the shape into necessary structures.
+ This base class only fills the Gcalc_heap with the information about
+ shapes and vertices.
+
+ Normally the Gcalc_shape_transporter family object is sent as a parameter
+ to the 'get_shapes' method of an 'spatial' object so it can pass
+ the spatial information about itself. The virtual methods are
+ treating this data in a way the caller needs.
+*/
+
+class Gcalc_shape_transporter
+{
+private:
+ Gcalc_heap::Info *m_first;
+ Gcalc_heap::Info *m_prev;
+ Gcalc_dyn_list::Item **m_prev_hook;
+ int m_shape_started;
+ void int_complete();
+protected:
+ Gcalc_heap *m_heap;
+ int int_single_point(gcalc_shape_info Info, double x, double y);
+ int int_add_point(gcalc_shape_info Info, double x, double y);
+ void int_start_line()
+ {
+ DBUG_ASSERT(!m_shape_started);
+ m_shape_started= 1;
+ m_first= m_prev= NULL;
+ }
+ void int_complete_line()
+ {
+ DBUG_ASSERT(m_shape_started== 1);
+ int_complete();
+ m_shape_started= 0;
+ }
+ void int_start_ring()
+ {
+ DBUG_ASSERT(m_shape_started== 2);
+ m_shape_started= 3;
+ m_first= m_prev= NULL;
+ }
+ void int_complete_ring()
+ {
+ DBUG_ASSERT(m_shape_started== 3);
+ int_complete();
+ m_shape_started= 2;
+ }
+ void int_start_poly()
+ {
+ DBUG_ASSERT(!m_shape_started);
+ m_shape_started= 2;
+ }
+ void int_complete_poly()
+ {
+ DBUG_ASSERT(m_shape_started== 2);
+ m_shape_started= 0;
+ }
+ bool line_started() { return m_shape_started == 1; };
+public:
+ Gcalc_shape_transporter(Gcalc_heap *heap) :
+ m_shape_started(0), m_heap(heap) {}
+
+ virtual int single_point(double x, double y)=0;
+ virtual int start_line()=0;
+ virtual int complete_line()=0;
+ virtual int start_poly()=0;
+ virtual int complete_poly()=0;
+ virtual int start_ring()=0;
+ virtual int complete_ring()=0;
+ virtual int add_point(double x, double y)=0;
+ virtual int start_collection(int n_objects) { return 0; }
+ virtual int empty_shape() { return 0; }
+ int start_simple_poly()
+ {
+ return start_poly() || start_ring();
+ }
+ int complete_simple_poly()
+ {
+ return complete_ring() || complete_poly();
+ }
+ virtual ~Gcalc_shape_transporter() {}
+};
+
+
+enum Gcalc_scan_events
+{
+ scev_none= 0,
+ scev_point= 1, /* Just a new point in thread */
+ scev_thread= 2, /* Start of the new thread */
+ scev_two_threads= 4, /* A couple of new threads started */
+ scev_intersection= 8, /* Intersection happened */
+ scev_end= 16, /* Single thread finished */
+ scev_two_ends= 32, /* A couple of threads finished */
+ scev_single_point= 64 /* Got single point */
+};
+
+
+/*
+ Gcalc_scan_iterator incapsulates the slisescan algorithm.
+ It takes filled Gcalc_heap as an datasource. Then can be
+ iterated trought the vertexes and intersection points with
+ the step() method. After the 'step()' one usually observes
+ the current 'slice' to do the necessary calculations, like
+ looking for intersections, calculating the area, whatever.
+*/
+
+class Gcalc_scan_iterator : public Gcalc_dyn_list
+{
+public:
+ class point : public Gcalc_dyn_list::Item
+ {
+ public:
+ Gcalc_coord1 dx;
+ Gcalc_coord1 dy;
+ Gcalc_heap::Info *pi;
+ Gcalc_heap::Info *next_pi;
+ Gcalc_heap::Info *ev_pi;
+ const Gcalc_coord1 *l_border;
+ const Gcalc_coord1 *r_border;
+ point *ev_next;
+
+ Gcalc_scan_events event;
+
+ inline const point *c_get_next() const
+ { return (const point *)next; }
+ inline bool is_bottom() const { return !next_pi; }
+ gcalc_shape_info get_shape() const { return pi->shape; }
+ inline point *get_next() { return (point *)next; }
+ inline const point *get_next() const { return (const point *)next; }
+ /* Compare the dx_dy parameters regarding the horiz_dir */
+ /* returns -1 if less, 0 if equal, 1 if bigger */
+ static int cmp_dx_dy(const Gcalc_coord1 dx_a,
+ const Gcalc_coord1 dy_a,
+ const Gcalc_coord1 dx_b,
+ const Gcalc_coord1 dy_b);
+ static int cmp_dx_dy(const Gcalc_heap::Info *p1,
+ const Gcalc_heap::Info *p2,
+ const Gcalc_heap::Info *p3,
+ const Gcalc_heap::Info *p4);
+ int cmp_dx_dy(const point *p) const;
+ point **next_ptr() { return (point **) &next; }
+#ifndef GCALC_DBUG_OFF
+ unsigned int thread;
+#endif /*GCALC_DBUG_OFF*/
+#ifdef GCALC_CHECK_WITH_FLOAT
+ void calc_x(long double *x, long double y, long double ix) const;
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+ };
+
+ /* That class introduced mostly for the 'typecontrol' reason. */
+ /* only difference from the point classis the get_next() function. */
+ class event_point : public point
+ {
+ public:
+ inline const event_point *get_next() const
+ { return (const event_point*) ev_next; }
+ int simple_event() const
+ {
+ return !ev_next ? (event & (scev_point | scev_end)) :
+ (!ev_next->ev_next && event == scev_two_ends);
+ }
+ };
+
+ class intersection_info : public Gcalc_dyn_list::Item
+ {
+ public:
+ point *edge_a;
+ point *edge_b;
+
+ Gcalc_coord2 t_a;
+ Gcalc_coord2 t_b;
+ int t_calculated;
+ Gcalc_coord3 x_exp;
+ int x_calculated;
+ Gcalc_coord3 y_exp;
+ int y_calculated;
+ void calc_t()
+ {if (!t_calculated) do_calc_t(); }
+ void calc_y_exp()
+ { if (!y_calculated) do_calc_y(); }
+ void calc_x_exp()
+ { if (!x_calculated) do_calc_x(); }
+
+ void do_calc_t();
+ void do_calc_x();
+ void do_calc_y();
+ };
+
+
+ class slice_state
+ {
+ public:
+ point *slice;
+ point **event_position_hook;
+ point *event_end;
+ const Gcalc_heap::Info *pi;
+ };
+
+public:
+ Gcalc_scan_iterator(size_t blk_size= 8192);
+
+ GCALC_DECL_TERMINATED_STATE(killed)
+
+ void init(Gcalc_heap *points); /* Iterator can be reused */
+ void reset();
+ int step();
+
+ Gcalc_heap::Info *more_points() { return m_cur_pi; }
+ bool more_trapezoids()
+ { return m_cur_pi && m_cur_pi->next; }
+
+ const point *get_bottom_points() const
+ { return m_bottom_points; }
+ const point *get_event_position() const
+ { return *state.event_position_hook; }
+ const point *get_event_end() const
+ { return state.event_end; }
+ const event_point *get_events() const
+ { return (const event_point *)
+ (*state.event_position_hook == state.event_end ?
+ m_bottom_points : *state.event_position_hook); }
+ const point *get_b_slice() const { return state.slice; }
+ double get_h() const;
+ double get_y() const;
+ double get_event_x() const;
+ double get_sp_x(const point *sp) const;
+ int intersection_step() const
+ { return state.pi->type == Gcalc_heap::nt_intersection; }
+ const Gcalc_heap::Info *get_cur_pi() const
+ {
+ return state.pi;
+ }
+
+private:
+ Gcalc_heap *m_heap;
+ Gcalc_heap::Info *m_cur_pi;
+ slice_state state;
+
+#ifndef GCALC_DBUG_OFF
+ unsigned int m_cur_thread;
+#endif /*GCALC_DBUG_OFF*/
+
+ point *m_bottom_points;
+ point **m_bottom_hook;
+
+ int node_scan();
+ void eq_scan();
+ void intersection_scan();
+ void remove_bottom_node();
+ int insert_top_node();
+ int add_intersection(point *sp_a, point *sp_b,
+ Gcalc_heap::Info *pi_from);
+ int add_eq_node(Gcalc_heap::Info *node, point *sp);
+ int add_events_for_node(point *sp_node);
+
+ point *new_slice_point()
+ {
+ point *new_point= (point *)new_item();
+ return new_point;
+ }
+ intersection_info *new_intersection_info(point *a, point *b)
+ {
+ intersection_info *ii= (intersection_info *)new_item();
+ ii->edge_a= a;
+ ii->edge_b= b;
+ ii->t_calculated= ii->x_calculated= ii->y_calculated= 0;
+ return ii;
+ }
+ int arrange_event(int do_sorting, int n_intersections);
+ static double get_pure_double(const Gcalc_internal_coord *d, int d_len);
+};
+
+
+/*
+ Gcalc_trapezoid_iterator simplifies the calculations on
+ the current slice of the Gcalc_scan_iterator.
+ One can walk through the trapezoids formed between
+ previous and current slices.
+*/
+
+#ifdef TMP_BLOCK
+class Gcalc_trapezoid_iterator
+{
+protected:
+ const Gcalc_scan_iterator::point *sp0;
+ const Gcalc_scan_iterator::point *sp1;
+public:
+ Gcalc_trapezoid_iterator(const Gcalc_scan_iterator *scan_i) :
+ sp0(scan_i->get_b_slice()),
+ sp1(scan_i->get_t_slice())
+ {}
+
+ inline bool more() const { return sp1 && sp1->next; }
+
+ const Gcalc_scan_iterator::point *lt() const { return sp1; }
+ const Gcalc_scan_iterator::point *lb() const { return sp0; }
+ const Gcalc_scan_iterator::point *rb() const
+ {
+ const Gcalc_scan_iterator::point *result= sp0;
+ while ((result= result->c_get_next())->is_bottom())
+ {}
+ return result;
+ }
+ const Gcalc_scan_iterator::point *rt() const
+ { return sp1->c_get_next(); }
+
+ void operator++()
+ {
+ sp0= rb();
+ sp1= rt();
+ }
+};
+#endif /*TMP_BLOCK*/
+
+
+/*
+ Gcalc_point_iterator simplifies the calculations on
+ the current slice of the Gcalc_scan_iterator.
+ One can walk through the points on the current slice.
+*/
+
+class Gcalc_point_iterator
+{
+protected:
+ const Gcalc_scan_iterator::point *sp;
+public:
+ Gcalc_point_iterator(const Gcalc_scan_iterator *scan_i):
+ sp(scan_i->get_b_slice())
+ {}
+
+ inline bool more() const { return sp != NULL; }
+ inline void operator++() { sp= sp->c_get_next(); }
+ inline const Gcalc_scan_iterator::point *point() const { return sp; }
+ inline const Gcalc_heap::Info *get_pi() const { return sp->pi; }
+ inline gcalc_shape_info get_shape() const { return sp->get_shape(); }
+ inline void restart(const Gcalc_scan_iterator *scan_i)
+ { sp= scan_i->get_b_slice(); }
+};
+
+#endif /*GCALC_SLICESCAN_INCLUDED*/
+
diff --git a/sql/gcalc_tools.cc b/sql/gcalc_tools.cc
new file mode 100644
index 00000000000..729b322769c
--- /dev/null
+++ b/sql/gcalc_tools.cc
@@ -0,0 +1,1425 @@
+/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved.
+ Copyright (C) 2011 Monty Program Ab.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+#include "mysql_priv.h"
+
+#ifdef HAVE_SPATIAL
+
+#include "gcalc_tools.h"
+#include "spatial.h"
+
+#define float_to_coord(d) ((double) d)
+
+
+/*
+ Adds new shape to the relation.
+ After that it can be used as an argument of an operation.
+*/
+
+gcalc_shape_info Gcalc_function::add_new_shape(uint32 shape_id,
+ shape_type shape_kind)
+{
+ shapes_buffer.q_append((uint32) shape_kind);
+ return n_shapes++;
+}
+
+
+/*
+ Adds new operation to the constructed relation.
+ To construct the complex relation one has to specify operations
+ in prefix style.
+*/
+
+void Gcalc_function::add_operation(uint operation, uint32 n_operands)
+{
+ uint32 op_code= (uint32 ) operation + n_operands;
+ function_buffer.q_append(op_code);
+}
+
+
+/*
+ Sometimes the number of arguments is unknown at the moment the operation
+ is added. That allows to specify it later.
+*/
+
+void Gcalc_function::add_operands_to_op(uint32 operation_pos, uint32 n_operands)
+{
+ uint32 op_code= uint4korr(function_buffer.ptr() + operation_pos) + n_operands;
+ function_buffer.write_at_position(operation_pos, op_code);
+}
+
+
+/*
+ Just like the add_operation() but the result will be the inverted
+ value of an operation.
+*/
+
+void Gcalc_function::add_not_operation(op_type operation, uint32 n_operands)
+{
+ uint32 op_code= ((uint32) op_not | (uint32 ) operation) + n_operands;
+ function_buffer.q_append(op_code);
+}
+
+
+int Gcalc_function::single_shape_op(shape_type shape_kind, gcalc_shape_info *si)
+{
+ if (reserve_shape_buffer(1) || reserve_op_buffer(1))
+ return 1;
+ *si= add_new_shape(0, shape_kind);
+ add_operation(op_shape, *si);
+ return 0;
+}
+
+
+int Gcalc_function::repeat_expression(uint32 exp_pos)
+{
+ if (reserve_op_buffer(1))
+ return 1;
+ add_operation(op_repeat, exp_pos);
+ return 0;
+}
+
+
+/*
+ Specify how many arguments we're going to have.
+*/
+
+int Gcalc_function::reserve_shape_buffer(uint n_shapes)
+{
+ return shapes_buffer.reserve(n_shapes * 4, 512);
+}
+
+
+/*
+ Specify how many operations we're going to have.
+*/
+
+int Gcalc_function::reserve_op_buffer(uint n_ops)
+{
+ return function_buffer.reserve(n_ops * 4, 512);
+}
+
+
+int Gcalc_function::alloc_states()
+{
+ if (function_buffer.reserve((n_shapes+1) * 2 * sizeof(int)))
+ return 1;
+ i_states= (int *) (function_buffer.ptr() + ALIGN_SIZE(function_buffer.length()));
+ b_states= i_states + (n_shapes + 1);
+ return 0;
+}
+
+
+int Gcalc_function::count_internal(const char *cur_func, uint set_type,
+ const char **end)
+{
+ uint c_op= uint4korr(cur_func);
+ op_type next_func= (op_type) (c_op & op_any);
+ int mask= (c_op & op_not) ? 1:0;
+ uint n_ops= c_op & ~(op_any | op_not | v_mask);
+ uint n_shape= c_op & ~(op_any | op_not | v_mask); /* same as n_ops */
+ value v_state= (value) (c_op & v_mask);
+ int result= 0;
+ const char *sav_cur_func= cur_func;
+
+ // GCALC_DBUG_ENTER("Gcalc_function::count_internal");
+
+ cur_func+= 4;
+ if (next_func == op_shape)
+ {
+ if (set_type == 0)
+ result= i_states[n_shape] | b_states[n_shape];
+ else if (set_type == op_border)
+ result= b_states[n_shape];
+ else if (set_type == op_internals)
+ result= i_states[n_shape] && !b_states[n_shape];
+ goto exit;
+ }
+
+ if (next_func == op_false)
+ {
+ result= 0;
+ goto exit;
+ }
+
+ if (next_func == op_border || next_func == op_internals)
+ {
+ result= count_internal(cur_func, next_func, &cur_func);
+ goto exit;
+ }
+
+ if (next_func == op_repeat)
+ {
+ result= count_internal(function_buffer.ptr() + n_ops, set_type, 0);
+ goto exit;
+ }
+
+ if (n_ops == 0)
+ return mask;
+ //GCALC_DBUG_RETURN(mask);
+
+ result= count_internal(cur_func, set_type, &cur_func);
+
+ while (--n_ops)
+ {
+ int next_res= count_internal(cur_func, set_type, &cur_func);
+ switch (next_func)
+ {
+ case op_union:
+ result= result | next_res;
+ break;
+ case op_intersection:
+ result= result & next_res;
+ break;
+ case op_symdifference:
+ result= result ^ next_res;
+ break;
+ case op_difference:
+ result= result & !next_res;
+ break;
+ default:
+ GCALC_DBUG_ASSERT(FALSE);
+ };
+ }
+
+exit:
+ result^= mask;
+ if (v_state != v_empty)
+ {
+ switch (v_state)
+ {
+ case v_find_t:
+ if (result)
+ {
+ c_op= (c_op & ~v_mask) | v_t_found;
+ int4store(sav_cur_func, c_op);
+ };
+ break;
+ case v_find_f:
+ if (!result)
+ {
+ c_op= (c_op & ~v_mask) | v_f_found;
+ int4store(sav_cur_func, c_op);
+ };
+ break;
+ case v_t_found:
+ result= 1;
+ break;
+ case v_f_found:
+ result= 0;
+ break;
+ default:
+ GCALC_DBUG_ASSERT(0);
+ };
+ }
+
+ if (end)
+ *end= cur_func;
+ return result;
+ //GCALC_DBUG_RETURN(result);
+}
+
+
+void Gcalc_function::clear_i_states()
+{
+ for (uint i= 0; i < n_shapes; i++)
+ i_states[i]= 0;
+}
+
+
+void Gcalc_function::clear_b_states()
+{
+ for (uint i= 0; i < n_shapes; i++)
+ b_states[i]= 0;
+}
+
+
+/*
+ Clear the state of the object.
+*/
+
+void Gcalc_function::reset()
+{
+ n_shapes= 0;
+ shapes_buffer.length(0);
+ function_buffer.length(0);
+}
+
+
+int Gcalc_function::check_function(Gcalc_scan_iterator &scan_it)
+{
+ const Gcalc_scan_iterator::point *eq_start, *cur_eq;
+ const Gcalc_scan_iterator::event_point *events;
+ GCALC_DBUG_ENTER("Gcalc_function::check_function");
+
+ while (scan_it.more_points())
+ {
+ if (scan_it.step())
+ GCALC_DBUG_RETURN(-1);
+ events= scan_it.get_events();
+
+ /* these kinds of events don't change the function */
+ Gcalc_point_iterator pit(&scan_it);
+ clear_b_states();
+ clear_i_states();
+ /* Walk to the event, marking polygons we met */
+ for (; pit.point() != scan_it.get_event_position(); ++pit)
+ {
+ gcalc_shape_info si= pit.point()->get_shape();
+ if ((get_shape_kind(si) == Gcalc_function::shape_polygon))
+ invert_i_state(si);
+ }
+ if (events->simple_event())
+ {
+ if (events->event == scev_end)
+ set_b_state(events->get_shape());
+
+ if (count())
+ GCALC_DBUG_RETURN(1);
+ clear_b_states();
+ continue;
+ }
+
+ /* Check the status of the event point */
+ for (; events; events= events->get_next())
+ {
+ gcalc_shape_info si= events->get_shape();
+ if (events->event == scev_thread ||
+ events->event == scev_end ||
+ events->event == scev_single_point ||
+ (get_shape_kind(si) == Gcalc_function::shape_polygon))
+ set_b_state(si);
+ else if (get_shape_kind(si) == Gcalc_function::shape_line)
+ set_i_state(si);
+ }
+
+ if (count())
+ GCALC_DBUG_RETURN(1);
+
+ /* Set back states changed in the loop above. */
+ for (events= scan_it.get_events(); events; events= events->get_next())
+ {
+ gcalc_shape_info si= events->get_shape();
+ if (events->event == scev_thread ||
+ events->event == scev_end ||
+ events->event == scev_single_point ||
+ (get_shape_kind(si) == Gcalc_function::shape_polygon))
+ clear_b_state(si);
+ else if (get_shape_kind(si) == Gcalc_function::shape_line)
+ clear_i_state(si);
+ }
+
+ if (scan_it.get_event_position() == scan_it.get_event_end())
+ continue;
+
+ /* Check the status after the event */
+ eq_start= pit.point();
+ do
+ {
+ ++pit;
+ if (pit.point() != scan_it.get_event_end() &&
+ eq_start->cmp_dx_dy(pit.point()) == 0)
+ continue;
+ for (cur_eq= eq_start; cur_eq != pit.point();
+ cur_eq= cur_eq->get_next())
+ {
+ gcalc_shape_info si= cur_eq->get_shape();
+ if (get_shape_kind(si) == Gcalc_function::shape_polygon)
+ set_b_state(si);
+ else
+ invert_i_state(si);
+ }
+ if (count())
+ GCALC_DBUG_RETURN(1);
+
+ for (cur_eq= eq_start; cur_eq != pit.point(); cur_eq= cur_eq->get_next())
+ {
+ gcalc_shape_info si= cur_eq->get_shape();
+ if ((get_shape_kind(si) == Gcalc_function::shape_polygon))
+ {
+ clear_b_state(si);
+ invert_i_state(si);
+ }
+ else
+ invert_i_state(cur_eq->get_shape());
+ }
+ if (count())
+ GCALC_DBUG_RETURN(1);
+ eq_start= pit.point();
+ } while (pit.point() != scan_it.get_event_end());
+ }
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_operation_transporter::single_point(double x, double y)
+{
+ gcalc_shape_info si;
+ return m_fn->single_shape_op(Gcalc_function::shape_point, &si) ||
+ int_single_point(si, x, y);
+}
+
+
+int Gcalc_operation_transporter::start_line()
+{
+ int_start_line();
+ return m_fn->single_shape_op(Gcalc_function::shape_line, &m_si);
+}
+
+
+int Gcalc_operation_transporter::complete_line()
+{
+ int_complete_line();
+ return 0;
+}
+
+
+int Gcalc_operation_transporter::start_poly()
+{
+ int_start_poly();
+ return m_fn->single_shape_op(Gcalc_function::shape_polygon, &m_si);
+}
+
+
+int Gcalc_operation_transporter::complete_poly()
+{
+ int_complete_poly();
+ return 0;
+}
+
+
+int Gcalc_operation_transporter::start_ring()
+{
+ int_start_ring();
+ return 0;
+}
+
+
+int Gcalc_operation_transporter::complete_ring()
+{
+ int_complete_ring();
+ return 0;
+}
+
+
+int Gcalc_operation_transporter::add_point(double x, double y)
+{
+ return int_add_point(m_si, x, y);
+}
+
+
+int Gcalc_operation_transporter::start_collection(int n_objects)
+{
+ if (m_fn->reserve_shape_buffer(n_objects) || m_fn->reserve_op_buffer(1))
+ return 1;
+ m_fn->add_operation(Gcalc_function::op_union, n_objects);
+ return 0;
+}
+
+
+int Gcalc_operation_transporter::empty_shape()
+{
+ if (m_fn->reserve_op_buffer(1))
+ return 1;
+ m_fn->add_operation(Gcalc_function::op_false, 0);
+ return 0;
+}
+
+
+int Gcalc_result_receiver::start_shape(Gcalc_function::shape_type shape)
+{
+ GCALC_DBUG_ENTER("Gcalc_result_receiver::start_shape");
+ if (buffer.reserve(4*2, 512))
+ GCALC_DBUG_RETURN(1);
+ cur_shape= shape;
+ shape_pos= buffer.length();
+ buffer.length(shape_pos + ((shape == Gcalc_function::shape_point) ? 4:8));
+ n_points= 0;
+ shape_area= 0.0;
+
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_result_receiver::add_point(double x, double y)
+{
+ GCALC_DBUG_ENTER("Gcalc_result_receiver::add_point");
+ if (n_points && x == prev_x && y == prev_y)
+ GCALC_DBUG_RETURN(0);
+
+ if (!n_points++)
+ {
+ prev_x= first_x= x;
+ prev_y= first_y= y;
+ GCALC_DBUG_RETURN(0);
+ }
+
+ shape_area+= prev_x*y - prev_y*x;
+
+ if (buffer.reserve(8*2, 512))
+ GCALC_DBUG_RETURN(1);
+ buffer.q_append(prev_x);
+ buffer.q_append(prev_y);
+ prev_x= x;
+ prev_y= y;
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_result_receiver::complete_shape()
+{
+ GCALC_DBUG_ENTER("Gcalc_result_receiver::complete_shape");
+ if (n_points == 0)
+ {
+ buffer.length(shape_pos);
+ GCALC_DBUG_RETURN(0);
+ }
+ if (n_points == 1)
+ {
+ if (cur_shape != Gcalc_function::shape_point)
+ {
+ if (cur_shape == Gcalc_function::shape_hole)
+ {
+ buffer.length(shape_pos);
+ GCALC_DBUG_RETURN(0);
+ }
+ cur_shape= Gcalc_function::shape_point;
+ buffer.length(buffer.length()-4);
+ }
+ }
+ else
+ {
+ GCALC_DBUG_ASSERT(cur_shape != Gcalc_function::shape_point);
+ if (cur_shape == Gcalc_function::shape_hole)
+ {
+ shape_area+= prev_x*first_y - prev_y*first_x;
+ if (fabs(shape_area) < 1e-8)
+ {
+ buffer.length(shape_pos);
+ GCALC_DBUG_RETURN(0);
+ }
+ }
+
+ if ((cur_shape == Gcalc_function::shape_polygon ||
+ cur_shape == Gcalc_function::shape_hole) &&
+ prev_x == first_x && prev_y == first_y)
+ {
+ n_points--;
+ buffer.write_at_position(shape_pos+4, n_points);
+ goto do_complete;
+ }
+ buffer.write_at_position(shape_pos+4, n_points);
+ }
+
+ if (buffer.reserve(8*2, 512))
+ GCALC_DBUG_RETURN(1);
+ buffer.q_append(prev_x);
+ buffer.q_append(prev_y);
+
+do_complete:
+ buffer.write_at_position(shape_pos, (uint32) cur_shape);
+
+ if (!n_shapes++)
+ {
+ GCALC_DBUG_ASSERT(cur_shape != Gcalc_function::shape_hole);
+ common_shapetype= cur_shape;
+ }
+ else if (cur_shape == Gcalc_function::shape_hole)
+ {
+ ++n_holes;
+ }
+ else if (!collection_result && (cur_shape != common_shapetype))
+ {
+ collection_result= true;
+ }
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_result_receiver::single_point(double x, double y)
+{
+ return start_shape(Gcalc_function::shape_point) ||
+ add_point(x, y) ||
+ complete_shape();
+}
+
+
+int Gcalc_result_receiver::done()
+{
+ return 0;
+}
+
+
+void Gcalc_result_receiver::reset()
+{
+ buffer.length(0);
+ collection_result= FALSE;
+ n_shapes= n_holes= 0;
+}
+
+
+int Gcalc_result_receiver::get_result_typeid()
+{
+ if (!n_shapes || collection_result)
+ return Geometry::wkb_geometrycollection;
+
+ switch (common_shapetype)
+ {
+ case Gcalc_function::shape_polygon:
+ return (n_shapes - n_holes == 1) ?
+ Geometry::wkb_polygon : Geometry::wkb_multipolygon;
+ case Gcalc_function::shape_point:
+ return (n_shapes == 1) ? Geometry::wkb_point : Geometry::wkb_multipoint;
+ case Gcalc_function::shape_line:
+ return (n_shapes == 1) ? Geometry::wkb_linestring :
+ Geometry::wkb_multilinestring;
+ default:
+ GCALC_DBUG_ASSERT(0);
+ }
+ return 0;
+}
+
+
+int Gcalc_result_receiver::move_hole(uint32 dest_position, uint32 source_position,
+ uint32 *position_shift)
+{
+ char *ptr;
+ int source_len;
+ GCALC_DBUG_ENTER("Gcalc_result_receiver::move_hole");
+ GCALC_DBUG_PRINT(("ps %d %d", dest_position, source_position));
+
+ *position_shift= source_len= buffer.length() - source_position;
+
+ if (dest_position == source_position)
+ GCALC_DBUG_RETURN(0);
+
+ if (buffer.reserve(source_len, MY_ALIGN(source_len, 512)))
+ GCALC_DBUG_RETURN(1);
+
+ ptr= (char *) buffer.ptr();
+ memmove(ptr + dest_position + source_len, ptr + dest_position,
+ buffer.length() - dest_position);
+ memcpy(ptr + dest_position, ptr + buffer.length(), source_len);
+ GCALC_DBUG_RETURN(0);
+}
+
+
+Gcalc_operation_reducer::Gcalc_operation_reducer(size_t blk_size) :
+ Gcalc_dyn_list(blk_size, sizeof(res_point)),
+#ifndef GCALC_DBUG_OFF
+ n_res_points(0),
+#endif /*GCALC_DBUG_OFF*/
+ m_res_hook((Gcalc_dyn_list::Item **)&m_result),
+ m_first_active_thread(NULL)
+{}
+
+
+void Gcalc_operation_reducer::init(Gcalc_function *fn, modes mode)
+{
+ m_fn= fn;
+ m_mode= mode;
+ m_first_active_thread= NULL;
+ m_lines= NULL;
+ m_lines_hook= (Gcalc_dyn_list::Item **) &m_lines;
+ m_poly_borders= NULL;
+ m_poly_borders_hook= (Gcalc_dyn_list::Item **) &m_poly_borders;
+ GCALC_SET_TERMINATED(killed, 0);
+}
+
+
+Gcalc_operation_reducer::
+Gcalc_operation_reducer(Gcalc_function *fn, modes mode, size_t blk_size) :
+ Gcalc_dyn_list(blk_size, sizeof(res_point)),
+ m_res_hook((Gcalc_dyn_list::Item **)&m_result)
+{
+ init(fn, mode);
+}
+
+
+void Gcalc_operation_reducer::res_point::set(const Gcalc_scan_iterator *si)
+{
+ intersection_point= si->intersection_step();
+ pi= si->get_cur_pi();
+}
+
+
+Gcalc_operation_reducer::res_point *
+ Gcalc_operation_reducer::add_res_point(Gcalc_function::shape_type type)
+{
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::add_res_point");
+ res_point *result= (res_point *)new_item();
+ *m_res_hook= result;
+ result->prev_hook= m_res_hook;
+ m_res_hook= &result->next;
+ result->type= type;
+#ifndef GCALC_DBUG_OFF
+ result->point_n= n_res_points++;
+#endif /*GCALC_DBUG_OFF*/
+ GCALC_DBUG_RETURN(result);
+}
+
+int Gcalc_operation_reducer::add_line(int incoming, active_thread *t,
+ const Gcalc_scan_iterator::point *p)
+{
+ line *l= new_line();
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::add_line");
+ if (!l)
+ GCALC_DBUG_RETURN(1);
+ l->incoming= incoming;
+ l->t= t;
+ l->p= p;
+ *m_lines_hook= l;
+ m_lines_hook= &l->next;
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_operation_reducer::add_poly_border(int incoming,
+ active_thread *t, int prev_state, const Gcalc_scan_iterator::point *p)
+{
+ poly_border *b= new_poly_border();
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::add_poly_border");
+ if (!b)
+ GCALC_DBUG_RETURN(1);
+ b->incoming= incoming;
+ b->t= t;
+ b->prev_state= prev_state;
+ b->p= p;
+ *m_poly_borders_hook= b;
+ m_poly_borders_hook= &b->next;
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_operation_reducer::continue_range(active_thread *t,
+ const Gcalc_heap::Info *p,
+ const Gcalc_heap::Info *p_next)
+{
+ res_point *rp= add_res_point(t->rp->type);
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::continue_range");
+ if (!rp)
+ GCALC_DBUG_RETURN(1);
+ rp->glue= NULL;
+ rp->down= t->rp;
+ t->rp->up= rp;
+ rp->intersection_point= false;
+ rp->pi= p;
+ t->rp= rp;
+ t->p1= p;
+ t->p2= p_next;
+ GCALC_DBUG_RETURN(0);
+}
+
+
+inline int Gcalc_operation_reducer::continue_i_range(active_thread *t,
+ const Gcalc_heap::Info *ii)
+{
+ res_point *rp= add_res_point(t->rp->type);
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::continue_i_range");
+ if (!rp)
+ GCALC_DBUG_RETURN(1);
+ rp->glue= NULL;
+ rp->down= t->rp;
+ t->rp->up= rp;
+ rp->intersection_point= true;
+ rp->pi= ii;
+ t->rp= rp;
+ GCALC_DBUG_RETURN(0);
+}
+
+int Gcalc_operation_reducer::end_couple(active_thread *t0, active_thread *t1,
+ const Gcalc_heap::Info *p)
+{
+ res_point *rp0, *rp1;
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::end_couple");
+ GCALC_DBUG_ASSERT(t0->rp->type == t1->rp->type);
+ if (!(rp0= add_res_point(t0->rp->type)) ||
+ !(rp1= add_res_point(t0->rp->type)))
+ GCALC_DBUG_RETURN(1);
+ rp0->down= t0->rp;
+ rp1->down= t1->rp;
+ rp1->glue= rp0;
+ rp0->glue= rp1;
+ rp0->up= rp1->up= NULL;
+ t0->rp->up= rp0;
+ t1->rp->up= rp1;
+ rp0->intersection_point= rp1->intersection_point= false;
+ rp0->pi= rp1->pi= p;
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si)
+{
+ Gcalc_point_iterator pi(si);
+ int prev_state= 0;
+ int sav_prev_state;
+ active_thread *prev_range= NULL;
+ const Gcalc_scan_iterator::event_point *events;
+ const Gcalc_scan_iterator::point *eq_start;
+ active_thread **cur_t_hook= &m_first_active_thread;
+ active_thread **starting_t_hook;
+ active_thread *bottom_threads= NULL;
+ active_thread *eq_thread, *point_thread;;
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::count_slice");
+
+ m_fn->clear_i_states();
+ /* Walk to the event, remembering what is needed. */
+ for (; pi.point() != si->get_event_position();
+ ++pi, cur_t_hook= (active_thread **) &(*cur_t_hook)->next)
+ {
+ active_thread *cur_t= *cur_t_hook;
+ if (cur_t->enabled() &&
+ cur_t->rp->type == Gcalc_function::shape_polygon)
+ {
+ prev_state^= 1;
+ prev_range= prev_state ? cur_t : 0;
+ }
+ if (m_fn->get_shape_kind(pi.get_shape()) == Gcalc_function::shape_polygon)
+ m_fn->invert_i_state(pi.get_shape());
+ }
+
+ events= si->get_events();
+ if (events->simple_event())
+ {
+ active_thread *cur_t= *cur_t_hook;
+ switch (events->event)
+ {
+ case scev_point:
+ {
+ if (cur_t->enabled() &&
+ continue_range(cur_t, events->pi, events->next_pi))
+ GCALC_DBUG_RETURN(1);
+ break;
+ }
+ case scev_end:
+ {
+ if (cur_t->enabled() && end_line(cur_t, si))
+ GCALC_DBUG_RETURN(1);
+ *cur_t_hook= cur_t->get_next();
+ free_item(cur_t);
+ break;
+ }
+ case scev_two_ends:
+ {
+ if (cur_t->enabled() && cur_t->get_next()->enabled())
+ {
+ /* When two threads are ended here */
+ if (end_couple(cur_t, cur_t->get_next(), events->pi))
+ GCALC_DBUG_RETURN(1);
+ }
+ else if (cur_t->enabled() || cur_t->get_next()->enabled())
+ {
+ /* Rare case when edges of a polygon coincide */
+ if (end_line(cur_t->enabled() ? cur_t : cur_t->get_next(), si))
+ GCALC_DBUG_RETURN(1);
+ }
+ *cur_t_hook= cur_t->get_next()->get_next();
+ free_item(cur_t->next);
+ free_item(cur_t);
+ break;
+ }
+ default:
+ GCALC_DBUG_ASSERT(0);
+ }
+ GCALC_DBUG_RETURN(0);
+ }
+
+ starting_t_hook= cur_t_hook;
+ sav_prev_state= prev_state;
+
+ /* Walk through the event, collecting all the 'incoming' threads */
+ for (; events; events= events->get_next())
+ {
+ active_thread *cur_t= *cur_t_hook;
+
+ if (events->event == scev_single_point)
+ continue;
+
+ if (events->event == scev_thread ||
+ events->event == scev_two_threads)
+ {
+ active_thread *new_t= new_active_thread();
+ if (!new_t)
+ GCALC_DBUG_RETURN(1);
+ new_t->rp= NULL;
+ /* Insert into the main thread list before the current */
+ new_t->next= cur_t;
+ *cur_t_hook= new_t;
+ cur_t_hook= (active_thread **) &new_t->next;
+ }
+ else
+ {
+ if (events->is_bottom())
+ {
+ /* Move thread from the main list to the bottom_threads. */
+ *cur_t_hook= cur_t->get_next();
+ cur_t->next= bottom_threads;
+ bottom_threads= cur_t;
+ }
+ if (cur_t->enabled())
+ {
+ if (cur_t->rp->type == Gcalc_function::shape_line)
+ {
+ GCALC_DBUG_ASSERT(!prev_state);
+ add_line(1, cur_t, events);
+ }
+ else
+ {
+ add_poly_border(1, cur_t, prev_state, events);
+ prev_state^= 1;
+ }
+ if (!events->is_bottom())
+ {
+ active_thread *new_t= new_active_thread();
+ if (!new_t)
+ GCALC_DBUG_RETURN(1);
+ new_t->rp= NULL;
+ /* Replace the current thread with the new. */
+ new_t->next= cur_t->next;
+ *cur_t_hook= new_t;
+ cur_t_hook= (active_thread **) &new_t->next;
+ /* And move old to the bottom list */
+ cur_t->next= bottom_threads;
+ bottom_threads= cur_t;
+ }
+ }
+ else if (!events->is_bottom())
+ cur_t_hook= (active_thread **) &cur_t->next;
+ }
+ }
+ prev_state= sav_prev_state;
+ cur_t_hook= starting_t_hook;
+
+ eq_start= pi.point();
+ eq_thread= point_thread= *starting_t_hook;
+ m_fn->clear_b_states();
+ while (eq_start != si->get_event_end())
+ {
+ const Gcalc_scan_iterator::point *cur_eq;
+ int in_state, after_state;
+
+ ++pi;
+ point_thread= point_thread->get_next();
+
+ if (pi.point() != si->get_event_end() &&
+ eq_start->cmp_dx_dy(pi.point()) == 0)
+ continue;
+
+ for (cur_eq= eq_start; cur_eq != pi.point(); cur_eq= cur_eq->get_next())
+ m_fn->set_b_state(cur_eq->get_shape());
+ in_state= m_fn->count();
+
+ m_fn->clear_b_states();
+ for (cur_eq= eq_start; cur_eq != pi.point(); cur_eq= cur_eq->get_next())
+ {
+ gcalc_shape_info si= cur_eq->get_shape();
+ if ((m_fn->get_shape_kind(si) == Gcalc_function::shape_polygon))
+ m_fn->invert_i_state(si);
+ }
+ after_state= m_fn->count();
+ if (prev_state != after_state)
+ {
+ if (add_poly_border(0, eq_thread, prev_state, eq_start))
+ GCALC_DBUG_RETURN(1);
+ }
+ else if (!prev_state /* &&!after_state */ && in_state)
+ {
+ if (add_line(0, eq_thread, eq_start))
+ GCALC_DBUG_RETURN(1);
+ }
+
+ prev_state= after_state;
+ eq_start= pi.point();
+ eq_thread= point_thread;
+ }
+
+ if (!sav_prev_state && !m_poly_borders && !m_lines)
+ {
+ /* Check if we need to add the event point itself */
+ m_fn->clear_i_states();
+ /* b_states supposed to be clean already */
+ for (pi.restart(si); pi.point() != si->get_event_position(); ++pi)
+ {
+ if (m_fn->get_shape_kind(pi.get_shape()) == Gcalc_function::shape_polygon)
+ m_fn->invert_i_state(pi.get_shape());
+ }
+ for (events= si->get_events(); events; events= events->get_next())
+ m_fn->set_b_state(events->get_shape());
+
+ GCALC_DBUG_RETURN(m_fn->count() ? add_single_point(si) : 0);
+ }
+
+ if (m_poly_borders)
+ {
+ *m_poly_borders_hook= NULL;
+ while (m_poly_borders)
+ {
+ poly_border *pb1, *pb2;
+ pb1= m_poly_borders;
+ GCALC_DBUG_ASSERT(m_poly_borders->next);
+
+ pb2= get_pair_border(pb1);
+ /* Remove pb1 from the list. The pb2 already removed in get_pair_border. */
+ m_poly_borders= pb1->get_next();
+ if (connect_threads(pb1->incoming, pb2->incoming,
+ pb1->t, pb2->t, pb1->p, pb2->p,
+ prev_range, si, Gcalc_function::shape_polygon))
+ GCALC_DBUG_RETURN(1);
+
+ free_item(pb1);
+ free_item(pb2);
+ }
+ m_poly_borders_hook= (Gcalc_dyn_list::Item **) &m_poly_borders;
+ m_poly_borders= NULL;
+ }
+
+ if (m_lines)
+ {
+ *m_lines_hook= NULL;
+ if (m_lines->get_next() &&
+ !m_lines->get_next()->get_next())
+ {
+ if (connect_threads(m_lines->incoming, m_lines->get_next()->incoming,
+ m_lines->t, m_lines->get_next()->t,
+ m_lines->p, m_lines->get_next()->p,
+ NULL, si, Gcalc_function::shape_line))
+ GCALC_DBUG_RETURN(1);
+ }
+ else
+ {
+ for (line *cur_line= m_lines; cur_line; cur_line= cur_line->get_next())
+ {
+ if (cur_line->incoming)
+ {
+ if (end_line(cur_line->t, si))
+ GCALC_DBUG_RETURN(1);
+ }
+ else
+ start_line(cur_line->t, cur_line->p, si);
+ }
+ }
+ free_list(m_lines);
+ m_lines= NULL;
+ m_lines_hook= (Gcalc_dyn_list::Item **) &m_lines;
+ }
+
+ if (bottom_threads)
+ free_list(bottom_threads);
+
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_operation_reducer::add_single_point(const Gcalc_scan_iterator *si)
+{
+ res_point *rp= add_res_point(Gcalc_function::shape_point);
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::add_single_point");
+ if (!rp)
+ GCALC_DBUG_RETURN(1);
+ rp->glue= rp->up= rp->down= NULL;
+ rp->set(si);
+ GCALC_DBUG_RETURN(0);
+}
+
+
+Gcalc_operation_reducer::poly_border
+ *Gcalc_operation_reducer::get_pair_border(poly_border *b1)
+{
+ poly_border *prev_b= b1;
+ poly_border *result= b1->get_next();
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::get_pair_border");
+ if (b1->prev_state)
+ {
+ if (b1->incoming)
+ {
+ /* Find the first outgoing, otherwise the last one. */
+ while (result->incoming && result->get_next())
+ {
+ prev_b= result;
+ result= result->get_next();
+ }
+ }
+ else
+ {
+ /* Get the last one */
+ while (result->get_next())
+ {
+ prev_b= result;
+ result= result->get_next();
+ }
+ }
+ }
+ else /* !b1->prev_state */
+ {
+ if (b1->incoming)
+ {
+ /* Get the next incoming, otherwise the last one. */
+ while (!result->incoming && result->get_next())
+ {
+ prev_b= result;
+ result= result->get_next();
+ }
+ }
+ else
+ {
+ /* Just pick the next one */
+ }
+ }
+ /* Delete the result from the list. */
+ prev_b->next= result->next;
+ GCALC_DBUG_RETURN(result);
+}
+
+
+int Gcalc_operation_reducer::connect_threads(
+ int incoming_a, int incoming_b,
+ active_thread *ta, active_thread *tb,
+ const Gcalc_scan_iterator::point *pa, const Gcalc_scan_iterator::point *pb,
+ active_thread *prev_range,
+ const Gcalc_scan_iterator *si, Gcalc_function::shape_type s_t)
+{
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::connect_threads");
+ GCALC_DBUG_PRINT(("incoming %d %d", incoming_a, incoming_b));
+ if (incoming_a && incoming_b)
+ {
+ res_point *rpa, *rpb;
+ GCALC_DBUG_ASSERT(ta->rp->type == tb->rp->type);
+ if (!(rpa= add_res_point(ta->rp->type)) ||
+ !(rpb= add_res_point(ta->rp->type)))
+ GCALC_DBUG_RETURN(1);
+ rpa->down= ta->rp;
+ rpb->down= tb->rp;
+ rpb->glue= rpa;
+ rpa->glue= rpb;
+ rpa->up= rpb->up= NULL;
+ ta->rp->up= rpa;
+ tb->rp->up= rpb;
+ rpa->set(si);
+ rpb->set(si);
+ ta->rp= tb->rp= NULL;
+ GCALC_DBUG_RETURN(0);
+ }
+ if (!incoming_a)
+ {
+ GCALC_DBUG_ASSERT(!incoming_b);
+
+ res_point *rp0, *rp1;
+ if (!(rp0= add_res_point(s_t)) || !(rp1= add_res_point(s_t)))
+ GCALC_DBUG_RETURN(1);
+ rp0->glue= rp1;
+ rp1->glue= rp0;
+ rp0->set(si);
+ rp1->set(si);
+ rp0->down= rp1->down= NULL;
+ ta->rp= rp0;
+ tb->rp= rp1;
+ ta->p1= pa->pi;
+ ta->p2= pa->next_pi;
+
+ tb->p1= pb->pi;
+ tb->p2= pb->next_pi;
+
+ if (prev_range)
+ {
+ rp0->outer_poly= prev_range->thread_start;
+ tb->thread_start= prev_range->thread_start;
+ /* Chack if needed */
+ ta->thread_start= prev_range->thread_start;
+ }
+ else
+ {
+ rp0->outer_poly= 0;
+ ta->thread_start= rp0;
+ /* Chack if needed */
+ tb->thread_start= rp0;
+ }
+ GCALC_DBUG_RETURN(0);
+ }
+ /* else, if only ta is incoming */
+
+ GCALC_DBUG_ASSERT(tb != ta);
+ tb->rp= ta->rp;
+ tb->thread_start= ta->thread_start;
+ if (Gcalc_scan_iterator::point::
+ cmp_dx_dy(ta->p1, ta->p2, pb->pi, pb->next_pi) != 0)
+ {
+ if (si->intersection_step() ?
+ continue_i_range(tb, si->get_cur_pi()) :
+ continue_range(tb, si->get_cur_pi(), pb->next_pi))
+ GCALC_DBUG_RETURN(1);
+ }
+ tb->p1= pb->pi;
+ tb->p2= pb->next_pi;
+
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_operation_reducer::start_line(active_thread *t,
+ const Gcalc_scan_iterator::point *p,
+ const Gcalc_scan_iterator *si)
+{
+ res_point *rp= add_res_point(Gcalc_function::shape_line);
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::start_line");
+ if (!rp)
+ GCALC_DBUG_RETURN(1);
+ rp->glue= rp->down= NULL;
+ rp->set(si);
+ t->rp= rp;
+ t->p1= p->pi;
+ t->p2= p->next_pi;
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_operation_reducer::end_line(active_thread *t,
+ const Gcalc_scan_iterator *si)
+{
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::end_line");
+ GCALC_DBUG_ASSERT(t->rp->type == Gcalc_function::shape_line);
+ res_point *rp= add_res_point(Gcalc_function::shape_line);
+ if (!rp)
+ GCALC_DBUG_RETURN(1);
+ rp->glue= rp->up= NULL;
+ rp->down= t->rp;
+ rp->set(si);
+ t->rp->up= rp;
+ t->rp= NULL;
+
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_operation_reducer::count_all(Gcalc_heap *hp)
+{
+ Gcalc_scan_iterator si;
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::count_all");
+ si.init(hp);
+ GCALC_SET_TERMINATED(si.killed, killed);
+ while (si.more_points())
+ {
+ if (si.step())
+ GCALC_DBUG_RETURN(1);
+ if (count_slice(&si))
+ GCALC_DBUG_RETURN(1);
+ }
+ GCALC_DBUG_RETURN(0);
+}
+
+inline void Gcalc_operation_reducer::free_result(res_point *res)
+{
+ if ((*res->prev_hook= res->next))
+ {
+ res->get_next()->prev_hook= res->prev_hook;
+ }
+ free_item(res);
+}
+
+
+inline int Gcalc_operation_reducer::get_single_result(res_point *res,
+ Gcalc_result_receiver *storage)
+{
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::get_single_result");
+ if (res->intersection_point)
+ {
+ double x, y;
+ res->pi->calc_xy(&x, &y);
+ if (storage->single_point(x,y))
+ GCALC_DBUG_RETURN(1);
+ }
+ else
+ if (storage->single_point(res->pi->x, res->pi->y))
+ GCALC_DBUG_RETURN(1);
+ free_result(res);
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_operation_reducer::get_result_thread(res_point *cur,
+ Gcalc_result_receiver *storage,
+ int move_upward,
+ res_point *first_poly_node)
+{
+ res_point *next;
+ bool glue_step= false;
+ double x, y;
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::get_result_thread");
+ while (cur)
+ {
+ if (!glue_step)
+ {
+ if (cur->intersection_point)
+ {
+ cur->pi->calc_xy(&x, &y);
+ }
+ else
+ {
+ x= cur->pi->x;
+ y= cur->pi->y;
+ }
+ if (storage->add_point(x, y))
+ GCALC_DBUG_RETURN(1);
+ }
+
+ next= move_upward ? cur->up : cur->down;
+ if (!next && !glue_step)
+ {
+ next= cur->glue;
+ move_upward^= 1;
+ glue_step= true;
+ if (next)
+ next->glue= NULL;
+ }
+ else
+ glue_step= false;
+
+ cur->first_poly_node= first_poly_node;
+ free_result(cur);
+ cur= next;
+ }
+ GCALC_DBUG_RETURN(0);
+}
+
+
+int Gcalc_operation_reducer::get_polygon_result(res_point *cur,
+ Gcalc_result_receiver *storage,
+ res_point *first_poly_node)
+{
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::get_polygon_result");
+ res_point *glue= cur->glue;
+ glue->up->down= NULL;
+ free_result(glue);
+ GCALC_DBUG_RETURN(get_result_thread(cur, storage, 1, first_poly_node) ||
+ storage->complete_shape());
+}
+
+
+int Gcalc_operation_reducer::get_line_result(res_point *cur,
+ Gcalc_result_receiver *storage)
+{
+ res_point *next;
+ res_point *cur_orig= cur;
+ int move_upward= 1;
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::get_line_result");
+ if (cur->glue)
+ {
+ /* Here we have to find the beginning of the line */
+ next= cur->up;
+ move_upward= 1;
+ while (next)
+ {
+ cur= next;
+ next= move_upward ? next->up : next->down;
+ if (!next)
+ {
+ next= cur->glue;
+ if (next == cur_orig)
+ {
+ /* It's the line loop */
+ cur= cur_orig;
+ cur->glue->glue= NULL;
+ move_upward= 1;
+ break;
+ }
+ move_upward^= 1;
+ }
+ }
+ }
+
+ GCALC_DBUG_RETURN(get_result_thread(cur, storage, move_upward, 0) ||
+ storage->complete_shape());
+}
+
+
+int Gcalc_operation_reducer::get_result(Gcalc_result_receiver *storage)
+{
+ poly_instance *polygons= NULL;
+
+ GCALC_DBUG_ENTER("Gcalc_operation_reducer::get_result");
+ *m_res_hook= NULL;
+
+ /* This is to workaround an old gcc's bug */
+ if (m_res_hook == (Gcalc_dyn_list::Item **) &m_result)
+ goto done;
+
+ while (m_result)
+ {
+ Gcalc_function::shape_type shape= m_result->type;
+ if (shape == Gcalc_function::shape_point)
+ {
+ if (get_single_result(m_result, storage))
+ GCALC_DBUG_RETURN(1);
+ continue;
+ }
+ if (shape == Gcalc_function::shape_polygon)
+ {
+ if (m_result->outer_poly)
+ {
+ uint32 insert_position, hole_position, position_shift;
+ poly_instance *cur_poly;
+ insert_position= m_result->outer_poly->first_poly_node->poly_position;
+ GCALC_DBUG_ASSERT(insert_position);
+ hole_position= storage->position();
+ storage->start_shape(Gcalc_function::shape_hole);
+ if (get_polygon_result(m_result, storage,
+ m_result->outer_poly->first_poly_node) ||
+ storage->move_hole(insert_position, hole_position,
+ &position_shift))
+ GCALC_DBUG_RETURN(1);
+ for (cur_poly= polygons;
+ cur_poly && *cur_poly->after_poly_position >= insert_position;
+ cur_poly= cur_poly->get_next())
+ *cur_poly->after_poly_position+= position_shift;
+ }
+ else
+ {
+ uint32 *poly_position= &m_result->poly_position;
+ poly_instance *p= new_poly();
+ p->after_poly_position= poly_position;
+ p->next= polygons;
+ polygons= p;
+ storage->start_shape(Gcalc_function::shape_polygon);
+ if (get_polygon_result(m_result, storage, m_result))
+ GCALC_DBUG_RETURN(1);
+ *poly_position= storage->position();
+ }
+ }
+ else
+ {
+ storage->start_shape(shape);
+ if (get_line_result(m_result, storage))
+ GCALC_DBUG_RETURN(1);
+ }
+ }
+
+done:
+ m_res_hook= (Gcalc_dyn_list::Item **)&m_result;
+ storage->done();
+ GCALC_DBUG_RETURN(0);
+}
+
+
+void Gcalc_operation_reducer::reset()
+{
+ free_list((Gcalc_heap::Item **) &m_result, m_res_hook);
+ m_res_hook= (Gcalc_dyn_list::Item **)&m_result;
+ free_list(m_first_active_thread);
+}
+
+#endif /*HAVE_SPATIAL*/
+
diff --git a/sql/gcalc_tools.h b/sql/gcalc_tools.h
new file mode 100644
index 00000000000..eed9be0803f
--- /dev/null
+++ b/sql/gcalc_tools.h
@@ -0,0 +1,347 @@
+/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved.
+ Copyright (C) 2011 Monty Program Ab.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+#ifndef GCALC_TOOLS_INCLUDED
+#define GCALC_TOOLS_INCLUDED
+
+#include "gcalc_slicescan.h"
+
+
+/*
+ The Gcalc_function class objects are used to check for a binary relation.
+ The relation can be constructed with the prefix notation using predicates as
+ op_not (as !A)
+ op_union ( A || B || C... )
+ op_intersection ( A && B && C ... )
+ op_symdifference ( A+B+C+... == 1 )
+ op_difference ( A && !(B||C||..))
+ with the calls of the add_operation(operation, n_operands) method.
+ The relation is calculated over a set of shapes, that in turn have
+ to be added with the add_new_shape() method. All the 'shapes' can
+ be set to 0 with clear_shapes() method and single value
+ can be changed with the invert_state() method.
+ Then the value of the relation can be calculated with the count() method.
+ Frequently used method is find_function(Gcalc_scan_iterator it) that
+ iterates through the 'it' until the relation becomes TRUE.
+*/
+
+class Gcalc_function
+{
+private:
+ String shapes_buffer;
+ String function_buffer;
+ int *i_states;
+ int *b_states;
+ uint32 cur_object_id;
+ uint n_shapes;
+ int count_internal(const char *cur_func, uint set_type,
+ const char **end);
+public:
+ enum value
+ {
+ v_empty= 0x0000000,
+ v_find_t= 0x1000000,
+ v_find_f= 0x2000000,
+ v_t_found= 0x3000000,
+ v_f_found= 0x4000000,
+ v_mask= 0x7000000
+ };
+ enum op_type
+ {
+ op_not= 0x80000000,
+ op_shape= 0x00000000,
+ op_union= 0x10000000,
+ op_intersection= 0x20000000,
+ op_symdifference= 0x30000000,
+ op_difference= 0x40000000,
+ op_repeat= 0x50000000,
+ op_border= 0x60000000,
+ op_internals= 0x70000000,
+ op_false= 0x08000000,
+ op_any= 0x78000000 /* The mask to get any of the operations */
+ };
+ enum shape_type
+ {
+ shape_point= 0,
+ shape_line= 1,
+ shape_polygon= 2,
+ shape_hole= 3
+ };
+ Gcalc_function() : n_shapes(0) {}
+ gcalc_shape_info add_new_shape(uint32 shape_id, shape_type shape_kind);
+ /*
+ Adds the leaf operation that returns the shape value.
+ Also adds the shape to the list of operands.
+ */
+ int single_shape_op(shape_type shape_kind, gcalc_shape_info *si);
+ void add_operation(uint operation, uint32 n_operands);
+ void add_not_operation(op_type operation, uint32 n_operands);
+ uint32 get_next_expression_pos() { return function_buffer.length(); }
+ void add_operands_to_op(uint32 operation_pos, uint32 n_operands);
+ int repeat_expression(uint32 exp_pos);
+ void set_cur_obj(uint32 cur_obj) { cur_object_id= cur_obj; }
+ int reserve_shape_buffer(uint n_shapes);
+ int reserve_op_buffer(uint n_ops);
+ uint get_nshapes() const { return n_shapes; }
+ shape_type get_shape_kind(gcalc_shape_info si) const
+ {
+ return (shape_type) uint4korr(shapes_buffer.ptr() + (si*4));
+ }
+
+ void set_states(int *shape_states) { i_states= shape_states; }
+ int alloc_states();
+ void invert_i_state(gcalc_shape_info shape) { i_states[shape]^= 1; }
+ void set_i_state(gcalc_shape_info shape) { i_states[shape]= 1; }
+ void clear_i_state(gcalc_shape_info shape) { i_states[shape]= 0; }
+ void set_b_state(gcalc_shape_info shape) { b_states[shape]= 1; }
+ void clear_b_state(gcalc_shape_info shape) { b_states[shape]= 0; }
+ int get_state(gcalc_shape_info shape)
+ { return i_states[shape] | b_states[shape]; }
+ int get_i_state(gcalc_shape_info shape) { return i_states[shape]; }
+ int get_b_state(gcalc_shape_info shape) { return b_states[shape]; }
+ int count()
+ { return count_internal(function_buffer.ptr(), 0, 0); }
+ void clear_i_states();
+ void clear_b_states();
+ void reset();
+
+ int check_function(Gcalc_scan_iterator &scan_it);
+};
+
+
+/*
+ Gcalc_operation_transporter class extends the Gcalc_shape_transporter.
+ In addition to the parent's functionality, it fills the Gcalc_function
+ object so it has the function that determines the proper shape.
+ For example Multipolyline will be represented as an union of polylines.
+*/
+
+class Gcalc_operation_transporter : public Gcalc_shape_transporter
+{
+protected:
+ Gcalc_function *m_fn;
+ gcalc_shape_info m_si;
+public:
+ Gcalc_operation_transporter(Gcalc_function *fn, Gcalc_heap *heap) :
+ Gcalc_shape_transporter(heap), m_fn(fn) {}
+
+ int single_point(double x, double y);
+ int start_line();
+ int complete_line();
+ int start_poly();
+ int complete_poly();
+ int start_ring();
+ int complete_ring();
+ int add_point(double x, double y);
+ int start_collection(int n_objects);
+ int empty_shape();
+};
+
+
+/*
+ When we calculate the result of an spatial operation like
+ Union or Intersection, we receive vertexes of the result
+ one-by-one, and probably need to treat them in variative ways.
+ So, the Gcalc_result_receiver class designed to get these
+ vertexes and construct shapes/objects out of them.
+ and to store the result in an appropriate format
+*/
+
+class Gcalc_result_receiver
+{
+ String buffer;
+ uint32 n_points;
+ Gcalc_function::shape_type common_shapetype;
+ bool collection_result;
+ uint32 n_shapes;
+ uint32 n_holes;
+
+ Gcalc_function::shape_type cur_shape;
+ uint32 shape_pos;
+ double first_x, first_y, prev_x, prev_y;
+ double shape_area;
+public:
+ Gcalc_result_receiver() : collection_result(FALSE), n_shapes(0), n_holes(0)
+ {}
+ int start_shape(Gcalc_function::shape_type shape);
+ int add_point(double x, double y);
+ int complete_shape();
+ int single_point(double x, double y);
+ int done();
+ void reset();
+
+ const char *result() { return buffer.ptr(); }
+ uint length() { return buffer.length(); }
+ int get_nshapes() { return n_shapes; }
+ int get_nholes() { return n_holes; }
+ int get_result_typeid();
+ uint32 position() { return buffer.length(); }
+ int move_hole(uint32 dest_position, uint32 source_position,
+ uint32 *position_shift);
+};
+
+
+/*
+ Gcalc_operation_reducer class incapsulates the spatial
+ operation functionality. It analyses the slices generated by
+ the slicescan and calculates the shape of the result defined
+ by some Gcalc_function.
+*/
+
+class Gcalc_operation_reducer : public Gcalc_dyn_list
+{
+public:
+ enum modes
+ {
+ /* Numeric values important here - careful with changing */
+ default_mode= 0,
+ prefer_big_with_holes= 1,
+ polygon_selfintersections_allowed= 2, /* allowed in the result */
+ line_selfintersections_allowed= 4 /* allowed in the result */
+ };
+
+ Gcalc_operation_reducer(size_t blk_size=8192);
+ void init(Gcalc_function *fn, modes mode= default_mode);
+ Gcalc_operation_reducer(Gcalc_function *fn, modes mode= default_mode,
+ size_t blk_size=8192);
+ GCALC_DECL_TERMINATED_STATE(killed)
+ int count_slice(Gcalc_scan_iterator *si);
+ int count_all(Gcalc_heap *hp);
+ int get_result(Gcalc_result_receiver *storage);
+ void reset();
+
+#ifndef GCALC_DBUG_OFF
+ int n_res_points;
+#endif /*GCALC_DBUG_OFF*/
+ class res_point : public Gcalc_dyn_list::Item
+ {
+ public:
+ int intersection_point;
+ union
+ {
+ const Gcalc_heap::Info *pi;
+ res_point *first_poly_node;
+ };
+ union
+ {
+ res_point *outer_poly;
+ uint32 poly_position;
+ };
+ res_point *up;
+ res_point *down;
+ res_point *glue;
+ Gcalc_function::shape_type type;
+ Gcalc_dyn_list::Item **prev_hook;
+#ifndef GCALC_DBUG_OFF
+ int point_n;
+#endif /*GCALC_DBUG_OFF*/
+ void set(const Gcalc_scan_iterator *si);
+ res_point *get_next() { return (res_point *)next; }
+ };
+
+ class active_thread : public Gcalc_dyn_list::Item
+ {
+ public:
+ res_point *rp;
+ res_point *thread_start;
+
+ const Gcalc_heap::Info *p1, *p2;
+ res_point *enabled() { return rp; }
+ active_thread *get_next() { return (active_thread *)next; }
+ };
+
+ class poly_instance : public Gcalc_dyn_list::Item
+ {
+ public:
+ uint32 *after_poly_position;
+ poly_instance *get_next() { return (poly_instance *)next; }
+ };
+
+ class line : public Gcalc_dyn_list::Item
+ {
+ public:
+ active_thread *t;
+ int incoming;
+ const Gcalc_scan_iterator::point *p;
+ line *get_next() { return (line *)next; }
+ };
+
+ class poly_border : public Gcalc_dyn_list::Item
+ {
+ public:
+ active_thread *t;
+ int incoming;
+ int prev_state;
+ const Gcalc_scan_iterator::point *p;
+ poly_border *get_next() { return (poly_border *)next; }
+ };
+
+ line *m_lines;
+ Gcalc_dyn_list::Item **m_lines_hook;
+ poly_border *m_poly_borders;
+ Gcalc_dyn_list::Item **m_poly_borders_hook;
+ line *new_line() { return (line *) new_item(); }
+ poly_border *new_poly_border() { return (poly_border *) new_item(); }
+ int add_line(int incoming, active_thread *t,
+ const Gcalc_scan_iterator::point *p);
+ int add_poly_border(int incoming, active_thread *t, int prev_state,
+ const Gcalc_scan_iterator::point *p);
+
+protected:
+ Gcalc_function *m_fn;
+ Gcalc_dyn_list::Item **m_res_hook;
+ res_point *m_result;
+ int m_mode;
+
+ res_point *result_heap;
+ active_thread *m_first_active_thread;
+
+ res_point *add_res_point(Gcalc_function::shape_type type);
+ active_thread *new_active_thread() { return (active_thread *)new_item(); }
+
+ poly_instance *new_poly() { return (poly_instance *) new_item(); }
+
+private:
+ int start_line(active_thread *t, const Gcalc_scan_iterator::point *p,
+ const Gcalc_scan_iterator *si);
+ int end_line(active_thread *t, const Gcalc_scan_iterator *si);
+ int connect_threads(int incoming_a, int incoming_b,
+ active_thread *ta, active_thread *tb,
+ const Gcalc_scan_iterator::point *pa,
+ const Gcalc_scan_iterator::point *pb,
+ active_thread *prev_range,
+ const Gcalc_scan_iterator *si,
+ Gcalc_function::shape_type s_t);
+ int add_single_point(const Gcalc_scan_iterator *si);
+ poly_border *get_pair_border(poly_border *b1);
+ int continue_range(active_thread *t, const Gcalc_heap::Info *p,
+ const Gcalc_heap::Info *p_next);
+ int continue_i_range(active_thread *t,
+ const Gcalc_heap::Info *ii);
+ int end_couple(active_thread *t0, active_thread *t1, const Gcalc_heap::Info *p);
+ int get_single_result(res_point *res, Gcalc_result_receiver *storage);
+ int get_result_thread(res_point *cur, Gcalc_result_receiver *storage,
+ int move_upward, res_point *first_poly_node);
+ int get_polygon_result(res_point *cur, Gcalc_result_receiver *storage,
+ res_point *first_poly_node);
+ int get_line_result(res_point *cur, Gcalc_result_receiver *storage);
+
+ void free_result(res_point *res);
+};
+
+#endif /*GCALC_TOOLS_INCLUDED*/
+
diff --git a/sql/gstream.cc b/sql/gstream.cc
index 25bf599ff4e..f0a8fdad27c 100644
--- a/sql/gstream.cc
+++ b/sql/gstream.cc
@@ -42,6 +42,29 @@ enum Gis_read_stream::enum_tok_types Gis_read_stream::get_next_toc_type()
}
+bool Gis_read_stream::lookup_next_word(LEX_STRING *res)
+{
+ const char *cur= m_cur;
+
+ skip_space();
+ res->str= (char*) cur;
+ /* The following will also test for \0 */
+ if ((cur >= m_limit) || !my_isvar_start(&my_charset_bin, *cur))
+ return 1;
+
+ /*
+ We can't combine the following increment with my_isvar() because
+ my_isvar() is a macro that would cause side effects
+ */
+ cur++;
+ while ((cur < m_limit) && my_isvar(&my_charset_bin, *cur))
+ cur++;
+
+ res->length= (uint32) (cur - res->str);
+ return 0;
+}
+
+
bool Gis_read_stream::get_next_word(LEX_STRING *res)
{
skip_space();
diff --git a/sql/gstream.h b/sql/gstream.h
index 1ef90ad5bf0..d3a40f4e7e0 100644
--- a/sql/gstream.h
+++ b/sql/gstream.h
@@ -39,6 +39,7 @@ public:
}
enum enum_tok_types get_next_toc_type();
+ bool lookup_next_word(LEX_STRING *res);
bool get_next_word(LEX_STRING *);
bool get_next_number(double *);
bool check_next_symbol(char);
@@ -57,6 +58,14 @@ public:
m_cur++;
return 0;
}
+ /* Returns the next notempty character. */
+ char next_symbol()
+ {
+ skip_space();
+ if (m_cur >= m_limit)
+ return 0; /* EOL meet. */
+ return *m_cur;
+ }
void set_error_msg(const char *msg);
// caller should free this pointer
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 140931f94f1..fa27a13bcd0 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -8690,6 +8690,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,
@@ -9062,6 +9064,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_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 63da0aabcb1..930d1c867f5 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -1866,7 +1866,7 @@ static void ndb_binlog_query(THD *thd, Cluster_schema *schema)
else
thd->server_id= schema->any_value;
thd->db= schema->db;
- int errcode = query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode = query_error_code(thd, thd->killed == NOT_KILLED);
thd->binlog_query(THD::STMT_QUERY_TYPE, schema->query,
schema->query_length, FALSE,
schema->name[0] == 0 || thd->db[0] == 0,
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index bc337ac51bb..6fcbd56ae38 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -270,7 +270,6 @@ void ha_partition::init_handler_variables()
m_extra_prepare_for_update= FALSE;
m_extra_cache_part_id= NO_CURRENT_PART_ID;
m_handler_status= handler_not_initialized;
- m_low_byte_first= 1;
m_part_field_array= NULL;
m_ordered_rec_buffer= NULL;
m_top_entry= NO_CURRENT_PART_ID;
@@ -417,18 +416,11 @@ bool ha_partition::initialize_partition(MEM_ROOT *mem_root)
Verify that all partitions have the same table_flags.
*/
check_table_flags= m_file[0]->ha_table_flags();
- m_low_byte_first= m_file[0]->low_byte_first();
m_pkey_is_clustered= TRUE;
file_array= m_file;
do
{
file= *file_array;
- if (m_low_byte_first != file->low_byte_first())
- {
- // Cannot have handlers with different endian
- my_error(ER_MIX_HANDLER_ERROR, MYF(0));
- DBUG_RETURN(1);
- }
if (!file->primary_key_is_clustered())
m_pkey_is_clustered= FALSE;
if (check_table_flags != file->ha_table_flags())
@@ -1313,7 +1305,7 @@ int ha_partition::prepare_new_partition(TABLE *tbl,
DBUG_RETURN(0);
error_external_lock:
- VOID(file->close());
+ VOID(file->ha_close());
error_open:
VOID(file->ha_delete_table(part_name));
error_create:
@@ -1359,7 +1351,7 @@ void ha_partition::cleanup_new_partition(uint part_count)
while ((part_count > 0) && (*file))
{
(*file)->ha_external_lock(thd, F_UNLCK);
- (*file)->close();
+ (*file)->ha_close();
/* Leave the (*file)->ha_delete_table(part_name) to the ddl-log */
@@ -2821,7 +2813,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
err_handler:
DEBUG_SYNC(ha_thd(), "partition_open_error");
while (file-- != m_file)
- (*file)->close();
+ (*file)->ha_close();
err_alloc:
bitmap_free(&m_bulk_insert_started);
if (!m_is_clone_of)
@@ -2907,7 +2899,7 @@ int ha_partition::close(void)
repeat:
do
{
- (*file)->close();
+ (*file)->ha_close();
} while (*(++file));
if (first && m_added_file && m_added_file[0])
@@ -3911,6 +3903,8 @@ int ha_partition::rnd_next(uchar *buf)
int result= HA_ERR_END_OF_FILE;
uint part_id= m_part_spec.start_part;
DBUG_ENTER("ha_partition::rnd_next");
+
+ /* upper level will increment this once again at end of call */
decrement_statistics(&SSV::ha_read_rnd_next_count);
if (NO_CURRENT_PART_ID == part_id)
@@ -4163,7 +4157,7 @@ bool ha_partition::init_record_priority_queue()
m_start_key.key= (const uchar*)ptr;
/* Initialize priority queue, initialized to reading forward. */
if (init_queue(&m_queue, used_parts, (uint) PARTITION_BYTES_IN_POS,
- 0, key_rec_cmp, (void*)m_curr_key_info))
+ 0, key_rec_cmp, (void*)m_curr_key_info, 0, 0))
{
my_free(m_ordered_rec_buffer, MYF(0));
m_ordered_rec_buffer= NULL;
@@ -4219,6 +4213,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)
{
@@ -5025,7 +5020,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;
uchar *part_rec_buf_ptr= m_ordered_rec_buffer;
DBUG_ENTER("ha_partition::handle_ordered_index_scan");
@@ -5058,6 +5053,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,
@@ -5111,7 +5112,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;
@@ -5183,7 +5184,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)",
@@ -5195,7 +5196,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);
@@ -5227,7 +5228,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);
@@ -5239,7 +5240,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/ha_partition.h b/sql/ha_partition.h
index c33216047b3..05461c12525 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -112,7 +112,6 @@ private:
for this since the MySQL Server sometimes allocating the handler object
without freeing them.
*/
- ulong m_low_byte_first;
enum enum_handler_status
{
handler_not_initialized= 0,
@@ -885,6 +884,10 @@ public:
*/
virtual ulong index_flags(uint inx, uint part, bool all_parts) const
{
+ /*
+ The following code is not safe if you are using different
+ storage engines or different index types per partition.
+ */
return m_file[0]->index_flags(inx, part, all_parts);
}
@@ -911,12 +914,6 @@ public:
virtual uint max_supported_key_part_length() const;
/*
- All handlers in a partitioned table must have the same low_byte_first
- */
- virtual bool low_byte_first() const
- { return m_low_byte_first; }
-
- /*
The extra record buffer length is the maximum needed by all handlers.
The minimum record length is the maximum of all involved handlers.
*/
diff --git a/sql/handler.cc b/sql/handler.cc
index 86e584d4e1f..ca6a958f2c5 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -79,6 +79,8 @@ TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
static TYPELIB known_extensions= {0,"known_exts", NULL, NULL};
uint known_extensions_id= 0;
+static int commit_one_phase_2(THD *thd, bool all, THD_TRANS *trans,
+ bool is_real_trans);
static plugin_ref ha_default_plugin(THD *thd)
@@ -343,6 +345,7 @@ int ha_init_errors(void)
SETMSG(HA_ERR_AUTOINC_READ_FAILED, ER(ER_AUTOINC_READ_FAILED));
SETMSG(HA_ERR_AUTOINC_ERANGE, ER(ER_WARN_DATA_OUT_OF_RANGE));
SETMSG(HA_ERR_TOO_MANY_CONCURRENT_TRXS, ER(ER_TOO_MANY_CONCURRENT_TRXS));
+ SETMSG(HA_ERR_DISK_FULL, ER(ER_DISK_FULL));
SETMSG(HA_ERR_TABLE_IN_FK_CHECK, "Table being used in foreign key check");
/* Register the error messages for use with my_error(). */
@@ -597,6 +600,23 @@ void ha_drop_database(char* path)
}
+static my_bool checkpoint_state_handlerton(THD *unused1, plugin_ref plugin,
+ void *disable)
+{
+ handlerton *hton= plugin_data(plugin, handlerton *);
+ if (hton->state == SHOW_OPTION_YES && hton->checkpoint_state)
+ hton->checkpoint_state(hton, (int) *(bool*) disable);
+ return FALSE;
+}
+
+
+void ha_checkpoint_state(bool disable)
+{
+ plugin_foreach(NULL, checkpoint_state_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, &disable);
+}
+
+
+
static my_bool closecon_handlerton(THD *thd, plugin_ref plugin,
void *unused)
{
@@ -1078,7 +1098,7 @@ ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list,
*/
int ha_commit_trans(THD *thd, bool all)
{
- int error= 0, cookie= 0;
+ int error= 0, cookie;
/*
'all' means that this is either an explicit commit issued by
user, or an implicit commit issued by a DDL.
@@ -1093,7 +1113,8 @@ int ha_commit_trans(THD *thd, bool all)
*/
bool is_real_trans= all || thd->transaction.all.ha_list == 0;
Ha_trx_info *ha_info= trans->ha_list;
- my_xid xid= thd->transaction.xid_state.xid.get_my_xid();
+ bool need_prepare_ordered, need_commit_ordered;
+ my_xid xid;
DBUG_ENTER("ha_commit_trans");
/* Just a random warning to test warnings pushed during autocommit. */
@@ -1132,89 +1153,114 @@ int ha_commit_trans(THD *thd, bool all)
DBUG_RETURN(2);
}
#ifdef USING_TRANSACTIONS
- if (ha_info)
+ if (!ha_info)
{
- uint rw_ha_count;
- bool rw_trans;
+ /* Free resources and perform other cleanup even for 'empty' transactions. */
+ if (is_real_trans)
+ thd->transaction.cleanup();
+ DBUG_RETURN(0);
+ }
- DBUG_EXECUTE_IF("crash_commit_before", DBUG_SUICIDE(););
+ DBUG_EXECUTE_IF("crash_commit_before", DBUG_SUICIDE(););
- /* Close all cursors that can not survive COMMIT */
- if (is_real_trans) /* not a statement commit */
- thd->stmt_map.close_transient_cursors();
+ /* Close all cursors that can not survive COMMIT */
+ if (is_real_trans) /* not a statement commit */
+ thd->stmt_map.close_transient_cursors();
- rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, ha_info, all);
- /* rw_trans is TRUE when we in a transaction changing data */
- rw_trans= is_real_trans && (rw_ha_count > 0);
+ uint rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, ha_info, all);
+ /* rw_trans is TRUE when we in a transaction changing data */
+ bool rw_trans= is_real_trans && (rw_ha_count > 0);
- if (rw_trans &&
- wait_if_global_read_lock(thd, 0, 0))
- {
- ha_rollback_trans(thd, all);
- DBUG_RETURN(1);
- }
+ if (rw_trans &&
+ wait_if_global_read_lock(thd, 0, 0))
+ {
+ ha_rollback_trans(thd, all);
+ DBUG_RETURN(1);
+ }
- if (rw_trans &&
- opt_readonly &&
- !(thd->security_ctx->master_access & SUPER_ACL) &&
- !thd->slave_thread)
- {
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
- ha_rollback_trans(thd, all);
- error= 1;
- goto end;
- }
+ if (rw_trans &&
+ opt_readonly &&
+ !(thd->security_ctx->master_access & SUPER_ACL) &&
+ !thd->slave_thread)
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
+ goto err;
+ }
- if (!trans->no_2pc && (rw_ha_count > 1))
- {
- for (; ha_info && !error; ha_info= ha_info->next())
- {
- int err;
- handlerton *ht= ha_info->ht();
- /*
- Do not call two-phase commit if this particular
- transaction is read-only. This allows for simpler
- implementation in engines that are always read-only.
- */
- if (! ha_info->is_trx_read_write())
- continue;
- /*
- Sic: we know that prepare() is not NULL since otherwise
- trans->no_2pc would have been set.
- */
- if ((err= ht->prepare(ht, thd, all)))
- {
- my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
- error= 1;
- }
- status_var_increment(thd->status_var.ha_prepare_count);
- }
- DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE(););
- if (error || (is_real_trans && xid &&
- (error= !(cookie= tc_log->log_xid(thd, xid)))))
- {
- ha_rollback_trans(thd, all);
- error= 1;
- goto end;
- }
- DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_SUICIDE(););
- }
- error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0;
- DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_SUICIDE(););
- if (cookie)
- if(tc_log->unlog(cookie, xid))
- {
- error= 2;
- goto end;
- }
+ if (trans->no_2pc || (rw_ha_count <= 1))
+ {
+ error= ha_commit_one_phase(thd, all);
DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE(););
-end:
- if (rw_trans)
- start_waiting_global_read_lock(thd);
+ goto end;
}
- /* Free resources and perform other cleanup even for 'empty' transactions. */
- else if (is_real_trans)
- thd->transaction.cleanup();
+
+ need_prepare_ordered= FALSE;
+ need_commit_ordered= FALSE;
+ xid= thd->transaction.xid_state.xid.get_my_xid();
+
+ for (Ha_trx_info *hi= ha_info; hi; hi= hi->next())
+ {
+ int err;
+ handlerton *ht= hi->ht();
+ /*
+ Do not call two-phase commit if this particular
+ transaction is read-only. This allows for simpler
+ implementation in engines that are always read-only.
+ */
+ if (! hi->is_trx_read_write())
+ continue;
+ /*
+ Sic: we know that prepare() is not NULL since otherwise
+ trans->no_2pc would have been set.
+ */
+ err= ht->prepare(ht, thd, all);
+ status_var_increment(thd->status_var.ha_prepare_count);
+ if (err)
+ my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
+
+ if (err)
+ goto err;
+
+ need_prepare_ordered|= (ht->prepare_ordered != NULL);
+ need_commit_ordered|= (ht->commit_ordered != NULL);
+ }
+ DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE(););
+
+ if (!is_real_trans)
+ {
+ error= commit_one_phase_2(thd, all, trans, is_real_trans);
+ DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE(););
+ goto end;
+ }
+
+ cookie= tc_log->log_and_order(thd, xid, all, need_prepare_ordered,
+ need_commit_ordered);
+ if (!cookie)
+ goto err;
+
+ DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_SUICIDE(););
+
+ error= commit_one_phase_2(thd, all, trans, is_real_trans) ? 2 : 0;
+ DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE(););
+
+ DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_SUICIDE(););
+ if (tc_log->unlog(cookie, xid))
+ {
+ error= 2; /* Error during commit */
+ goto end;
+ }
+
+ DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE(););
+ goto end;
+
+ /* Come here if error and we need to rollback. */
+err:
+ error= 1; /* Transaction was rolled back */
+ ha_rollback_trans(thd, all);
+
+end:
+ if (rw_trans)
+ start_waiting_global_read_lock(thd);
#endif /* USING_TRANSACTIONS */
DBUG_RETURN(error);
}
@@ -1225,7 +1271,6 @@ end:
*/
int ha_commit_one_phase(THD *thd, bool all)
{
- int error=0;
THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
/*
"real" is a nick name for a transaction for which a commit will
@@ -1235,8 +1280,16 @@ int ha_commit_one_phase(THD *thd, bool all)
enclosing 'all' transaction is rolled back.
*/
bool is_real_trans=all || thd->transaction.all.ha_list == 0;
- Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
DBUG_ENTER("ha_commit_one_phase");
+ DBUG_RETURN(commit_one_phase_2(thd, all, trans, is_real_trans));
+}
+
+static int
+commit_one_phase_2(THD *thd, bool all, THD_TRANS *trans, bool is_real_trans)
+{
+ int error= 0;
+ Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
+ DBUG_ENTER("commit_one_phase_2");
#ifdef USING_TRANSACTIONS
if (ha_info)
{
@@ -1260,7 +1313,7 @@ int ha_commit_one_phase(THD *thd, bool all)
{
#ifdef HAVE_QUERY_CACHE
if (thd->transaction.changed_tables)
- query_cache.invalidate(thd->transaction.changed_tables);
+ query_cache.invalidate(thd, thd->transaction.changed_tables);
#endif
thd->variables.tx_isolation=thd->session_tx_isolation;
}
@@ -1352,13 +1405,12 @@ int ha_rollback_trans(THD *thd, bool all)
the error log; but we don't want users to wonder why they have this
message in the error log, so we don't send it.
- We don't have to test for thd->killed == THD::KILL_SYSTEM_THREAD as
+ We don't have to test for thd->killed == KILL_SYSTEM_THREAD as
it doesn't matter if a warning is pushed to a system thread or not:
No one will see it...
*/
if (is_real_trans && thd->transaction.all.modified_non_trans_table &&
- !thd->slave_thread && thd->killed != THD::KILL_CONNECTION &&
- thd->killed != THD::KILL_SERVER)
+ !thd->slave_thread && thd->killed < KILL_CONNECTION)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
@@ -1859,7 +1911,16 @@ int ha_start_consistent_snapshot(THD *thd)
{
bool warn= true;
+ /*
+ Holding the LOCK_commit_ordered mutex ensures that we get the same
+ snapshot for all engines (including the binary log). This allows us
+ among other things to do backups with
+ START TRANSACTION WITH CONSISTENT SNAPSHOT and
+ have a consistent binlog position.
+ */
+ pthread_mutex_lock(&LOCK_commit_ordered);
plugin_foreach(thd, snapshot_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, &warn);
+ pthread_mutex_unlock(&LOCK_commit_ordered);
/*
Same idea as when one wants to CREATE TABLE in one engine which does not
@@ -2113,7 +2174,7 @@ THD *handler::ha_thd(void) const
Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
*/
int handler::ha_open(TABLE *table_arg, const char *name, int mode,
- int test_if_locked)
+ uint test_if_locked)
{
int error;
DBUG_ENTER("handler::ha_open");
@@ -2157,11 +2218,22 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode,
dup_ref=ref+ALIGN_SIZE(ref_length);
cached_table_flags= table_flags();
}
- rows_read= rows_changed= 0;
- memset(index_rows_read, 0, sizeof(index_rows_read));
+ reset_statistics();
+ internal_tmp_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
DBUG_RETURN(error);
}
+int handler::ha_close()
+{
+ DBUG_ENTER("ha_close");
+ /*
+ Increment global statistics for temporary tables.
+ In_use is 0 for tables that was closed from the table cache.
+ */
+ if (table->in_use)
+ status_var_add(table->in_use->status_var.rows_tmp_read, rows_tmp_read);
+ DBUG_RETURN(close());
+}
/* Initialize handler for random reading, with error handling */
@@ -2504,7 +2576,7 @@ int handler::update_auto_increment()
/*
first test if the query was aborted due to strict mode constraints
*/
- if (thd->killed == THD::KILL_BAD_DATA)
+ if (killed_mask_hard(thd->killed) == KILL_BAD_DATA)
DBUG_RETURN(HA_ERR_AUTOINC_ERANGE);
/*
@@ -2565,8 +2637,9 @@ int handler::update_auto_increment()
void handler::column_bitmaps_signal()
{
DBUG_ENTER("column_bitmaps_signal");
- DBUG_PRINT("info", ("read_set: 0x%lx write_set: 0x%lx", (long) table->read_set,
- (long) table->write_set));
+ if (table)
+ DBUG_PRINT("info", ("read_set: 0x%lx write_set: 0x%lx",
+ (long) table->read_set, (long) table->write_set));
DBUG_VOID_RETURN;
}
@@ -2643,6 +2716,7 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment,
void handler::ha_release_auto_increment()
{
+ DBUG_ENTER("ha_release_auto_increment");
release_auto_increment();
insert_id_for_cur_row= 0;
auto_inc_interval_for_cur_row.replace(0, 0, 0);
@@ -2656,6 +2730,7 @@ void handler::ha_release_auto_increment()
*/
table->in_use->auto_inc_intervals_forced.empty();
}
+ DBUG_VOID_RETURN;
}
@@ -2716,6 +2791,11 @@ void handler::print_error(int error, myf errflag)
case ENOENT:
textno=ER_FILE_NOT_FOUND;
break;
+ case ENOSPC:
+ case HA_ERR_DISK_FULL:
+ textno= ER_DISK_FULL;
+ SET_FATAL_ERROR; // Ensure error is logged
+ break;
case HA_ERR_KEY_NOT_FOUND:
case HA_ERR_NO_ACTIVE_RECORD:
case HA_ERR_END_OF_FILE:
@@ -2728,6 +2808,12 @@ void handler::print_error(int error, myf errflag)
SET_FATAL_ERROR;
textno=ER_KEY_NOT_FOUND;
break;
+ case HA_ERR_ABORTED_BY_USER:
+ {
+ DBUG_ASSERT(table->in_use->killed);
+ table->in_use->send_kill_message();
+ DBUG_VOID_RETURN;
+ }
case HA_ERR_WRONG_MRG_TABLE_DEF:
textno=ER_WRONG_MRG_TABLE;
break;
@@ -2779,15 +2865,15 @@ void handler::print_error(int error, myf errflag)
str.length(max_length-4);
str.append(STRING_WITH_LEN("..."));
}
- my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table_share->table_name.str,
- str.c_ptr_safe(), key_nr+1);
+ my_error(ER_FOREIGN_DUPLICATE_KEY, errflag, table_share->table_name.str,
+ str.c_ptr_safe(), key_nr+1);
DBUG_VOID_RETURN;
}
textno= ER_DUP_KEY;
break;
}
case HA_ERR_NULL_IN_SPATIAL:
- my_error(ER_CANT_CREATE_GEOMETRY_OBJECT, MYF(0));
+ my_error(ER_CANT_CREATE_GEOMETRY_OBJECT, errflag);
DBUG_VOID_RETURN;
case HA_ERR_FOUND_DUPP_UNIQUE:
textno=ER_DUP_UNIQUE;
@@ -2857,21 +2943,21 @@ void handler::print_error(int error, myf errflag)
{
String str;
get_error_message(error, &str);
- my_error(ER_ROW_IS_REFERENCED_2, MYF(0), str.c_ptr_safe());
+ my_error(ER_ROW_IS_REFERENCED_2, errflag, str.c_ptr_safe());
DBUG_VOID_RETURN;
}
case HA_ERR_NO_REFERENCED_ROW:
{
String str;
get_error_message(error, &str);
- my_error(ER_NO_REFERENCED_ROW_2, MYF(0), str.c_ptr_safe());
+ my_error(ER_NO_REFERENCED_ROW_2, errflag, str.c_ptr_safe());
DBUG_VOID_RETURN;
}
case HA_ERR_TABLE_DEF_CHANGED:
textno=ER_TABLE_DEF_CHANGED;
break;
case HA_ERR_NO_SUCH_TABLE:
- my_error(ER_NO_SUCH_TABLE, MYF(0), table_share->db.str,
+ my_error(ER_NO_SUCH_TABLE, errflag, table_share->db.str,
table_share->table_name.str);
DBUG_VOID_RETURN;
case HA_ERR_RBR_LOGGING_FAILED:
@@ -2883,7 +2969,7 @@ void handler::print_error(int error, myf errflag)
uint key_nr= get_dup_key(error);
if ((int) key_nr >= 0)
ptr= table->key_info[key_nr].name;
- my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
+ my_error(ER_DROP_INDEX_FK, errflag, ptr);
DBUG_VOID_RETURN;
}
case HA_ERR_TABLE_NEEDS_UPGRADE:
@@ -2913,12 +2999,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.c_ptr(),
+ my_error(ER_GET_TEMPORARY_ERRMSG, errflag, error, str.c_ptr(),
engine);
else
{
SET_FATAL_ERROR;
- my_error(ER_GET_ERRMSG, MYF(0), error, str.c_ptr(), engine);
+ my_error(ER_GET_ERRMSG, errflag, error, str.c_ptr(), engine);
}
}
else
@@ -2926,15 +3012,19 @@ void handler::print_error(int error, myf errflag)
DBUG_VOID_RETURN;
}
}
- if (fatal_error && (debug_assert_if_crashed_table ||
- global_system_variables.log_warnings > 1))
+ if (fatal_error)
{
- /*
- Log error to log before we crash or if extended warnings are requested
- */
- errflag|= ME_NOREFRESH;
- }
-
+ /* Ensure this becomes a true error */
+ errflag&= ~(ME_JUST_WARNING | ME_JUST_INFO);
+ if ((debug_assert_if_crashed_table ||
+ global_system_variables.log_warnings > 1))
+ {
+ /*
+ Log error to log before we crash or if extended warnings are requested
+ */
+ errflag|= ME_NOREFRESH;
+ }
+ }
my_error(textno, errflag, table_share->table_name.str, error);
DBUG_ASSERT(!fatal_error || !debug_assert_if_crashed_table);
DBUG_VOID_RETURN;
@@ -3197,7 +3287,7 @@ int handler::rename_table(const char * from, const char * to)
void handler::drop_table(const char *name)
{
- close();
+ ha_close();
delete_table(name);
}
@@ -3509,6 +3599,9 @@ handler::ha_delete_table(const char *name)
Drop table in the engine: public interface.
@sa handler::drop_table()
+
+ The difference between this and delete_table() is that the table is open in
+ drop_table().
*/
void
@@ -3713,6 +3806,7 @@ void handler::update_global_table_stats()
TABLE_STATS * table_stats;
status_var_add(table->in_use->status_var.rows_read, rows_read);
+ DBUG_ASSERT(rows_tmp_read == 0);
if (!table->in_use->userstat_running)
{
@@ -4345,133 +4439,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.
@@ -4601,7 +4568,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)
@@ -4610,6 +4577,44 @@ 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;
+}
+
+
+/**
+ ICP callback - to be called by an engine to check the pushed condition
+*/
+extern "C" enum icp_result handler_index_cond_check(void* h_arg)
+{
+ handler *h= (handler*)h_arg;
+ THD *thd= h->table->in_use;
+ enum icp_result res;
+
+ if (thd_killed(thd))
+ return ICP_ABORTED_BY_USER;
+
+ if (h->end_range && h->compare_key2(h->end_range) > 0)
+ return ICP_OUT_OF_RANGE;
+ h->increment_statistics(&SSV::ha_icp_attempts);
+ if ((res= h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH) ==
+ ICP_MATCH)
+ h->increment_statistics(&SSV::ha_icp_match);
+ return res;
+}
+
int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
@@ -4796,7 +4801,8 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table)
/** @brief
Write table maps for all (manually or automatically) locked tables
- to the binary log.
+ to the binary log. Also, if binlog_annotate_row_events is ON,
+ write Annotate_rows event before the first table map.
SYNOPSIS
write_locked_table_maps()
@@ -4833,6 +4839,9 @@ static int write_locked_table_maps(THD *thd)
locks[0]= thd->extra_lock;
locks[1]= thd->lock;
locks[2]= thd->locked_tables;
+ my_bool with_annotate= thd->variables.binlog_annotate_row_events &&
+ thd->query() && thd->query_length();
+
for (uint i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
{
MYSQL_LOCK const *const lock= locks[i];
@@ -4850,7 +4859,8 @@ static int write_locked_table_maps(THD *thd)
check_table_binlog_row_based(thd, table))
{
int const has_trans= table->file->has_transactions();
- int const error= thd->binlog_write_table_map(table, has_trans);
+ int const error= thd->binlog_write_table_map(table, has_trans,
+ &with_annotate);
/*
If an error occurs, it is the responsibility of the caller to
roll back the transaction.
@@ -4949,6 +4959,9 @@ int handler::ha_reset()
/* reset the bitmaps to point to defaults */
table->default_column_bitmaps();
pushed_cond= NULL;
+ /* Reset information about pushed engine conditions */
+ cancel_pushed_idx_cond();
+ /* Reset information about pushed index conditions */
DBUG_RETURN(reset());
}
diff --git a/sql/handler.h b/sql/handler.h
index 16bf3daa08c..f9435b66084 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1,5 +1,6 @@
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright 2009-2011 Monty Program Ab
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -140,6 +141,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.
@@ -155,6 +159,18 @@
#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 */
+/*
+ Data is clustered on this key. This means that when you read the key
+ you also get the row data without any additional disk reads.
+*/
+#define HA_CLUSTERED_INDEX 512
+
+/*
bits in alter_table_flags:
*/
/*
@@ -207,12 +223,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
@@ -771,12 +781,113 @@ struct handlerton
NOTE 'all' is also false in auto-commit mode where 'end of statement'
and 'real commit' mean the same event.
*/
- int (*commit)(handlerton *hton, THD *thd, bool all);
+ int (*commit)(handlerton *hton, THD *thd, bool all);
+ /*
+ The commit_ordered() method is called prior to the commit() method, after
+ the transaction manager has decided to commit (not rollback) the
+ transaction. Unlike commit(), commit_ordered() is called only when the
+ full transaction is committed, not for each commit of statement
+ transaction in a multi-statement transaction.
+
+ Not that like prepare(), commit_ordered() is only called when 2-phase
+ commit takes place. Ie. when no binary log and only a single engine
+ participates in a transaction, one commit() is called, no
+ commit_ordered(). So engines must be prepared for this.
+
+ The calls to commit_ordered() in multiple parallel transactions is
+ guaranteed to happen in the same order in every participating
+ handler. This can be used to ensure the same commit order among multiple
+ handlers (eg. in table handler and binlog). So if transaction T1 calls
+ into commit_ordered() of handler A before T2, then T1 will also call
+ commit_ordered() of handler B before T2.
+
+ Engines that implement this method should during this call make the
+ transaction visible to other transactions, thereby making the order of
+ transaction commits be defined by the order of commit_ordered() calls.
+
+ The intention is that commit_ordered() should do the minimal amount of
+ work that needs to happen in consistent commit order among handlers. To
+ preserve ordering, calls need to be serialised on a global mutex, so
+ doing any time-consuming or blocking operations in commit_ordered() will
+ limit scalability.
+
+ Handlers can rely on commit_ordered() calls to be serialised (no two
+ calls can run in parallel, so no extra locking on the handler part is
+ required to ensure this).
+
+ Note that commit_ordered() can be called from a different thread than the
+ one handling the transaction! So it can not do anything that depends on
+ thread local storage, in particular it can not call my_error() and
+ friends (instead it can store the error code and delay the call of
+ my_error() to the commit() method).
+
+ Similarly, since commit_ordered() returns void, any return error code
+ must be saved and returned from the commit() method instead.
+
+ The commit_ordered method is optional, and can be left unset if not
+ needed in a particular handler (then there will be no ordering guarantees
+ wrt. other engines and binary log).
+ */
+ void (*commit_ordered)(handlerton *hton, THD *thd, bool all);
int (*rollback)(handlerton *hton, THD *thd, bool all);
int (*prepare)(handlerton *hton, THD *thd, bool all);
+ /*
+ The prepare_ordered method is optional. If set, it will be called after
+ successful prepare() in all handlers participating in 2-phase
+ commit. Like commit_ordered(), it is called only when the full
+ transaction is committed, not for each commit of statement transaction.
+
+ The calls to prepare_ordered() among multiple parallel transactions are
+ ordered consistently with calls to commit_ordered(). This means that
+ calls to prepare_ordered() effectively define the commit order, and that
+ each handler will see the same sequence of transactions calling into
+ prepare_ordered() and commit_ordered().
+
+ Thus, prepare_ordered() can be used to define commit order for handlers
+ that need to do this in the prepare step (like binlog). It can also be
+ used to release transaction's locks early in an order consistent with the
+ order transactions will be eventually committed.
+
+ Like commit_ordered(), prepare_ordered() calls are serialised to maintain
+ ordering, so the intention is that they should execute fast, with only
+ the minimal amount of work needed to define commit order. Handlers can
+ rely on this serialisation, and do not need to do any extra locking to
+ avoid two prepare_ordered() calls running in parallel.
+
+ Like commit_ordered(), prepare_ordered() is not guaranteed to be called
+ in the context of the thread handling the rest of the transaction. So it
+ cannot invoke code that relies on thread local storage, in particular it
+ cannot call my_error().
+
+ prepare_ordered() cannot cause a rollback by returning an error, all
+ possible errors must be handled in prepare() (the prepare_ordered()
+ method returns void). In case of some fatal error, a record of the error
+ must be made internally by the engine and returned from commit() later.
+
+ Note that for user-level XA SQL commands, no consistent ordering among
+ prepare_ordered() and commit_ordered() is guaranteed (as that would
+ require blocking all other commits for an indefinite time).
+
+ When 2-phase commit is not used (eg. only one engine (and no binlog) in
+ transaction), neither prepare() nor prepare_ordered() is called.
+ */
+ void (*prepare_ordered)(handlerton *hton, THD *thd, bool all);
int (*recover)(handlerton *hton, XID *xid_list, uint len);
int (*commit_by_xid)(handlerton *hton, XID *xid);
int (*rollback_by_xid)(handlerton *hton, XID *xid);
+ /*
+ "Disable or enable checkpointing internal to the storage engine. This is
+ used for FLUSH TABLES WITH READ LOCK AND DISABLE CHECKPOINT to ensure that
+ the engine will never start any recovery from a time between
+ FLUSH TABLES ... ; UNLOCK TABLES.
+
+ While checkpointing is disabled, the engine should pause any background
+ write activity (such as tablespace checkpointing) that require consistency
+ between different files (such as transaction log and tablespace files) for
+ crash recovery to succeed. The idea is to use this to make safe
+ multi-volume LVM snapshot backups.
+ */
+ int (*checkpoint_state)(handlerton *hton, bool disabled);
void *(*create_cursor_read_view)(handlerton *hton, THD *thd);
void (*set_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
void (*close_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
@@ -1149,6 +1260,244 @@ 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, range_id_t 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, range_id_t range_info);
+} RANGE_SEQ_IF;
+
+typedef bool (*SKIP_INDEX_TUPLE_FUNC) (range_seq_t seq, range_id_t 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)
+ {
+ /* In edge cases add_io_cnt may be zero */
+ if (add_io_cnt > 0)
+ {
+ double io_count_sum= io_count + add_io_cnt;
+ avg_io_cost= (io_count * avg_io_cost +
+ add_io_cnt * add_avg_cost) / io_count_sum;
+ io_count= io_count_sum;
+ }
+ }
+
+ /*
+ 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
+
+/*
+ The following bits are reserved for use by MRR implementation. The intended
+ use scenario:
+
+ * sql layer calls handler->multi_range_read_info[_const]()
+ - MRR implementation figures out what kind of scan it will perform, saves
+ the result in *mrr_mode parameter.
+ * sql layer remembers what was returned in *mrr_mode
+
+ * the optimizer picks the query plan (which may or may not include the MRR
+ scan that was estimated by the multi_range_read_info[_const] call)
+
+ * if the query is an EXPLAIN statement, sql layer will call
+ handler->multi_range_read_explain_info(mrr_mode) to get a text description
+ of the picked MRR scan; the description will be a part of EXPLAIN output.
+*/
+#define HA_MRR_IMPLEMENTATION_FLAG1 512
+#define HA_MRR_IMPLEMENTATION_FLAG2 1024
+#define HA_MRR_IMPLEMENTATION_FLAG3 2048
+#define HA_MRR_IMPLEMENTATION_FLAG4 4096
+#define HA_MRR_IMPLEMENTATION_FLAG5 8192
+#define HA_MRR_IMPLEMENTATION_FLAG6 16384
+
+#define HA_MRR_IMPLEMENTATION_FLAGS \
+ (512 | 1024 | 2048 | 4096 | 8192 | 16384)
/*
This is a buffer area that the handler can use to store rows.
@@ -1159,8 +1508,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;
@@ -1191,14 +1540,21 @@ 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)
{}
};
+extern "C" enum icp_result handler_index_cond_check(void* h_arg);
+
uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map);
/*
bitmap with first N+1 bits set
@@ -1234,17 +1590,31 @@ 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;
KEY_PART_INFO *range_key_part;
int key_compare_result_on_equal;
bool eq_range;
+ bool internal_tmp_table; /* If internal tmp table */
+
+ /*
+ TRUE <=> the engine guarantees that returned records are within the range
+ being scanned.
+ */
+ bool in_range_check_pushed_down;
uint errkey; /* Last dup key */
uint key_used_on_scan;
@@ -1258,6 +1628,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
@@ -1281,6 +1653,7 @@ public:
*/
/* Statistics variables */
ulonglong rows_read;
+ ulonglong rows_tmp_read;
ulonglong rows_changed;
/* One bigger than needed to avoid to test if key == MAX_KEY */
ulonglong index_rows_read[MAX_KEY+1];
@@ -1297,11 +1670,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), end_range(NULL), in_range_check_pushed_down(FALSE),
+ key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
ref_length(sizeof(my_off_t)),
ft_handler(0), inited(NONE),
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();
@@ -1320,7 +1696,7 @@ public:
}
/* ha_ methods: pubilc wrappers for private virtual API */
- int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
+ int ha_open(TABLE *table, const char *name, int mode, uint test_if_locked);
int ha_index_init(uint idx, bool sorted)
{
int result;
@@ -1330,6 +1706,7 @@ public:
{
inited= INDEX;
active_index= idx;
+ end_range= NULL;
}
DBUG_RETURN(result);
}
@@ -1339,6 +1716,7 @@ public:
DBUG_ASSERT(inited==INDEX);
inited= NONE;
active_index= MAX_KEY;
+ end_range= NULL;
DBUG_RETURN(index_end());
}
/* This is called after index_init() if we need to do a index scan */
@@ -1349,6 +1727,7 @@ public:
DBUG_ENTER("ha_rnd_init");
DBUG_ASSERT(inited==NONE || (inited==RND && scan));
inited= (result= rnd_init(scan)) ? NONE: RND;
+ end_range= NULL;
DBUG_RETURN(result);
}
int ha_rnd_end()
@@ -1356,6 +1735,7 @@ public:
DBUG_ENTER("ha_rnd_end");
DBUG_ASSERT(inited==RND);
inited=NONE;
+ end_range= NULL;
DBUG_RETURN(rnd_end());
}
int ha_rnd_init_with_error(bool scan) __attribute__ ((warn_unused_result));
@@ -1442,7 +1822,7 @@ public:
uint get_dup_key(int error);
void reset_statistics()
{
- rows_read= rows_changed= 0;
+ rows_read= rows_changed= rows_tmp_read= 0;
bzero(index_rows_read, sizeof(index_rows_read));
}
virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
@@ -1527,7 +1907,7 @@ public:
*/
uint get_index(void) const
{ return inited == INDEX ? active_index : MAX_KEY; }
- virtual int close(void)=0;
+ int ha_close(void);
/**
@retval 0 Bulk update used by handler
@@ -1603,10 +1983,18 @@ protected:
virtual int index_last(uchar * buf)
{ return HA_ERR_WRONG_COMMAND; }
virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);
+ virtual int close(void)=0;
+ inline void update_rows_read()
+ {
+ if (likely(!internal_tmp_table))
+ rows_read++;
+ else
+ rows_tmp_read++;
+ }
inline void update_index_statistics()
{
index_rows_read[active_index]++;
- rows_read++;
+ update_rows_read();
}
public:
@@ -1622,16 +2010,53 @@ 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);
+ /*
+ 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 *mrr_mode, COST_VECT *cost);
+ virtual ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
+ uint *mrr_mode, COST_VECT *cost);
+ virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
+ uint n_ranges, uint mrr_mode,
+ HANDLER_BUFFER *buf);
+ virtual int multi_range_read_next(range_id_t *range_info);
+ /*
+ Return string representation of the MRR plan.
+
+ This is intended to be used for EXPLAIN, via the following scenario:
+ 1. SQL layer calls handler->multi_range_read_info().
+ 1.1. Storage engine figures out whether it will use some non-default
+ MRR strategy, sets appropritate bits in *mrr_mode, and returns
+ control to SQL layer
+ 2. SQL layer remembers the returned mrr_mode
+ 3. SQL layer compares various options and choses the final query plan. As
+ a part of that, it makes a choice of whether to use the MRR strategy
+ picked in 1.1
+ 4. EXPLAIN code converts the query plan to its text representation. If MRR
+ strategy is part of the plan, it calls
+ multi_range_read_explain_info(mrr_mode) to get a text representation of
+ the picked MRR strategy.
+
+ @param mrr_mode Mode which was returned by multi_range_read_info[_const]
+ @param str INOUT string to be printed for EXPLAIN
+ @param str_end End of the string buffer. The function is free to put the
+ string into [str..str_end] memory range.
+ */
+ virtual int multi_range_read_explain_info(uint mrr_mode, char *str,
+ size_t size)
+ { return 0; }
- 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);
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)
@@ -1830,7 +2255,6 @@ public:
virtual uint max_supported_key_part_length() const { return 255; }
virtual uint min_record_length(uint options) const { return 1; }
- virtual bool low_byte_first() const { return 1; }
virtual uint checksum() const { return 0; }
virtual bool is_crashed() const { return 0; }
virtual bool auto_repair(int error) const { return 0; }
@@ -1910,9 +2334,28 @@ public:
/*
- @retval TRUE Primary key (if there is one) is clustered
- key covering all fields
- @retval FALSE otherwise
+ Check if the primary key (if there is one) is a clustered and a
+ reference key. This means:
+
+ - Data is stored together with the primary key (no secondary lookup
+ needed to find the row data). The optimizer uses this to find out
+ the cost of fetching data.
+ - The primary key is part of each secondary key and is used
+ to find the row data in the primary index when reading trough
+ secondary indexes.
+ - When doing a HA_KEYREAD_ONLY we get also all the primary key parts
+ into the row. This is critical property used by index_merge.
+
+ All the above is usually true for engines that store the row
+ data in the primary key index (e.g. in a b-tree), and use the primary
+ key value as a position(). InnoDB is an example of such an engine.
+
+ For such a clustered primary key, the following should also hold:
+ index_flags() should contain HA_CLUSTERED_INDEX
+ table_flags() should contain HA_TABLE_SCAN_ON_INDEX
+
+ @retval TRUE yes
+ @retval FALSE No.
*/
virtual bool primary_key_is_clustered() { return FALSE; }
virtual int cmp_ref(const uchar *ref1, const uchar *ref2)
@@ -1953,6 +2396,14 @@ 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; }
+ /** Reset information about pushed index conditions */
+ virtual void cancel_pushed_idx_cond()
+ {
+ pushed_idx_cond= NULL;
+ pushed_idx_cond_keyno= MAX_KEY;
+ in_range_check_pushed_down= false;
+ }
virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes)
{ return COMPATIBLE_DATA_NO; }
@@ -1972,6 +2423,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 { }
@@ -2012,6 +2475,7 @@ private:
*/
virtual int open(const char *name, int mode, uint test_if_locked)=0;
+ /* Note: ha_index_read_idx_map() may buypass index_init() */
virtual int index_init(uint idx, bool sorted) { return 0; }
virtual int index_end() { return 0; }
/**
@@ -2168,8 +2632,15 @@ public:
/* XXX to be removed, see ha_partition::partition_ht() */
virtual handlerton *partition_ht() const
{ return ht; }
+ inline int ha_write_tmp_row(uchar *buf);
+ inline int ha_update_tmp_row(const uchar * old_data, uchar * new_data);
+
+ friend enum icp_result handler_index_cond_check(void* h_arg);
};
+#include "multi_range_read.h"
+
+bool key_uses_partial_cols(TABLE *table, uint keyno);
/* Some extern variables used with handlers */
@@ -2228,6 +2699,7 @@ int ha_panic(enum ha_panic_function flag);
void ha_close_connection(THD* thd);
bool ha_flush_logs(handlerton *db_type);
void ha_drop_database(char* path);
+void ha_checkpoint_state(bool disable);
int ha_create_table(THD *thd, const char *path,
const char *db, const char *table_name,
HA_CREATE_INFO *create_info,
diff --git a/sql/item.cc b/sql/item.cc
index 4f0f837f462..2e023168f34 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -30,6 +30,19 @@
const String my_null_string("NULL", 4, default_charset_info);
+static int save_field_in_field(Field *from, bool *null_value,
+ Field *to, bool no_conversions);
+
+
+/**
+ Compare two Items for List<Item>::add_unique()
+*/
+
+bool cmp_items(Item *a, Item *b)
+{
+ return a->eq(b, FALSE);
+}
+
/****************************************************************************/
/* Hybrid_type_traits {_real} */
@@ -196,10 +209,12 @@ bool Item::val_bool()
case STRING_RESULT:
return val_real() != 0.0;
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
return 0; // Wrong (but safe)
}
+ return 0; // Wrong (but safe)
}
@@ -234,6 +249,21 @@ String *Item::val_string_from_decimal(String *str)
}
+String *Item::val_string_from_date(String *str)
+{
+ MYSQL_TIME ltime;
+ if (get_date(&ltime, TIME_FUZZY_DATE) ||
+ str->alloc(MAX_DATE_STRING_REP_LENGTH))
+ {
+ null_value= 1;
+ return (String *) 0;
+ }
+ str->length(my_TIME_to_str(&ltime, const_cast<char*>(str->ptr()), decimals));
+ str->set_charset(&my_charset_bin);
+ return str;
+}
+
+
my_decimal *Item::val_decimal_from_real(my_decimal *decimal_value)
{
double nr= val_real();
@@ -330,7 +360,7 @@ int Item::save_time_in_field(Field *field)
if (get_time(&ltime))
return set_field_to_null_with_conversions(field, 0);
field->set_notnull();
- return field->store_time(&ltime, MYSQL_TIMESTAMP_TIME);
+ return field->store_time_dec(&ltime, decimals);
}
@@ -340,7 +370,7 @@ int Item::save_date_in_field(Field *field)
if (get_date(&ltime, TIME_FUZZY_DATE))
return set_field_to_null_with_conversions(field, 0);
field->set_notnull();
- return field->store_time(&ltime, MYSQL_TIMESTAMP_DATETIME);
+ return field->store_time_dec(&ltime, decimals);
}
@@ -376,16 +406,18 @@ 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;
- maybe_null=null_value=with_sum_func=unsigned_flag=0;
+ maybe_null=null_value=with_sum_func=with_field=unsigned_flag=0;
in_rollup= 0;
decimals= 0; max_length= 0;
with_subselect= 0;
cmp_context= IMPOSSIBLE_RESULT;
+ /* Initially this item is not attached to any JOIN_TAB. */
+ join_tab_idx= MAX_TABLES;
/* Put item in free list so that we can free all items at end */
THD *thd= current_thd;
@@ -414,19 +446,22 @@ Item::Item():
tables.
*/
Item::Item(THD *thd, Item *item):
+ join_tab_idx(item->join_tab_idx),
+ is_expensive_cache(-1),
rsize(0),
str_value(item->str_value),
name(item->name),
orig_name(item->orig_name),
max_length(item->max_length),
name_length(item->name_length),
- marker(item->marker),
decimals(item->decimals),
+ marker(item->marker),
maybe_null(item->maybe_null),
in_rollup(item->in_rollup),
null_value(item->null_value),
unsigned_flag(item->unsigned_flag),
with_sum_func(item->with_sum_func),
+ with_field(item->with_field),
fixed(item->fixed),
is_autogenerated_name(item->is_autogenerated_name),
with_subselect(item->with_subselect),
@@ -465,11 +500,40 @@ void Item::print_item_w_name(String *str, enum_query_type query_type)
}
+void Item::print_value(String *str)
+{
+ char buff[MAX_FIELD_WIDTH];
+ String *ptr, tmp(buff,sizeof(buff),str->charset());
+ ptr= val_str(&tmp);
+ if (!ptr)
+ str->append("NULL");
+ else
+ {
+ switch (result_type()) {
+ case STRING_RESULT:
+ append_unescaped(str, ptr->ptr(), ptr->length());
+ break;
+ case DECIMAL_RESULT:
+ case REAL_RESULT:
+ case INT_RESULT:
+ str->append(*ptr);
+ break;
+ case ROW_RESULT:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0);
+ }
+ }
+}
+
+
void Item::cleanup()
{
DBUG_ENTER("Item::cleanup");
+ DBUG_PRINT("enter", ("this: %p", this));
fixed=0;
marker= 0;
+ join_tab_idx= MAX_TABLES;
if (orig_name)
name= orig_name;
DBUG_VOID_RETURN;
@@ -507,6 +571,45 @@ void Item::rename(char *new_name)
name= new_name;
}
+Item_result Item::cmp_type() const
+{
+ switch (field_type()) {
+ case MYSQL_TYPE_DECIMAL:
+ case MYSQL_TYPE_NEWDECIMAL:
+ return DECIMAL_RESULT;
+ case MYSQL_TYPE_TINY:
+ case MYSQL_TYPE_SHORT:
+ case MYSQL_TYPE_LONG:
+ case MYSQL_TYPE_LONGLONG:
+ case MYSQL_TYPE_INT24:
+ case MYSQL_TYPE_YEAR:
+ case MYSQL_TYPE_BIT:
+ return INT_RESULT;
+ case MYSQL_TYPE_FLOAT:
+ case MYSQL_TYPE_DOUBLE:
+ return REAL_RESULT;
+ case MYSQL_TYPE_NULL:
+ case MYSQL_TYPE_VARCHAR:
+ case MYSQL_TYPE_TINY_BLOB:
+ case MYSQL_TYPE_MEDIUM_BLOB:
+ case MYSQL_TYPE_LONG_BLOB:
+ case MYSQL_TYPE_BLOB:
+ case MYSQL_TYPE_VAR_STRING:
+ case MYSQL_TYPE_STRING:
+ case MYSQL_TYPE_ENUM:
+ case MYSQL_TYPE_SET:
+ case MYSQL_TYPE_GEOMETRY:
+ return STRING_RESULT;
+ case MYSQL_TYPE_TIMESTAMP:
+ case MYSQL_TYPE_DATE:
+ case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_NEWDATE:
+ return TIME_RESULT;
+ };
+ DBUG_ASSERT(0);
+ return (Item_result)-1;
+}
/**
Traverse item tree possibly transforming it (replacing items).
@@ -545,6 +648,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)
+{
+ 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))
+ 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)
@@ -553,7 +686,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;
}
@@ -565,7 +698,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;
}
@@ -587,7 +720,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()
@@ -605,20 +739,32 @@ 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;
}
bool Item_ident::remove_dependence_processor(uchar * arg)
{
DBUG_ENTER("Item_ident::remove_dependence_processor");
- if (depended_from == (st_select_lex *) arg)
+ if (get_depended_from() == (st_select_lex *) arg)
depended_from= 0;
context= &((st_select_lex *) arg)->context;
DBUG_RETURN(0);
}
+bool Item_ident::collect_outer_ref_processor(uchar *param)
+{
+ Collect_deps_prm *prm= (Collect_deps_prm *)param;
+ if (depended_from &&
+ depended_from->nest_level_base == prm->nest_level_base &&
+ depended_from->nest_level < prm->nest_level)
+ prm->parameters->add_unique(this, &cmp_items);
+ return FALSE;
+}
+
+
/**
Store the pointer to this item field into a list if not already there.
@@ -654,6 +800,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.
@@ -717,6 +873,23 @@ bool Item_field::register_field_in_bitmap(uchar *arg)
return 0;
}
+
+/*
+ Mark field in write_map
+
+ NOTES
+ This is used by UPDATE to register underlying fields of used view fields.
+*/
+
+bool Item_field::register_field_in_write_map(uchar *arg)
+{
+ TABLE *table= (TABLE *) arg;
+ if (field->table == table || !table)
+ bitmap_set_bit(field->table->write_set, field->field_index);
+ return 0;
+}
+
+
bool Item::check_cols(uint c)
{
if (c != 1)
@@ -794,6 +967,21 @@ void Item::set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs)
}
+void Item::set_name_for_rollback(THD *thd, const char *str, uint length,
+ CHARSET_INFO *cs)
+{
+ char *old_name, *new_name;
+ old_name= name;
+ set_name(str, length, cs);
+ new_name= name;
+ if (old_name != new_name)
+ {
+ name= old_name;
+ thd->change_item_tree((Item **) &name, (Item *) new_name);
+ }
+}
+
+
/**
@details
This function is called when:
@@ -955,7 +1143,47 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const
bool Item::get_date(MYSQL_TIME *ltime,uint fuzzydate)
{
- if (result_type() == STRING_RESULT)
+ if (field_type() == MYSQL_TYPE_TIME)
+ fuzzydate|= TIME_TIME_ONLY;
+
+ switch (result_type()) {
+ case INT_RESULT:
+ {
+ longlong value= val_int();
+ if (field_type() == MYSQL_TYPE_YEAR)
+ {
+ if (max_length == 2)
+ {
+ if (value < 70)
+ value+= 2000;
+ else if (value <= 1900)
+ value+= 1900;
+ }
+ value*= 10000; /* make it YYYYMMHH */
+ }
+ if (null_value || int_to_datetime_with_warn(value, ltime, fuzzydate,
+ field_name_or_null()))
+ goto err;
+ break;
+ }
+ case REAL_RESULT:
+ {
+ double value= val_real();
+ if (null_value || double_to_datetime_with_warn(value, ltime, fuzzydate,
+ field_name_or_null()))
+ goto err;
+ break;
+ }
+ case DECIMAL_RESULT:
+ {
+ my_decimal value, *res;
+ if (!(res= val_decimal(&value)) ||
+ decimal_to_datetime_with_warn(res, ltime, fuzzydate,
+ field_name_or_null()))
+ goto err;
+ break;
+ }
+ case STRING_RESULT:
{
char buff[40];
String tmp(buff,sizeof(buff), &my_charset_bin),*res;
@@ -963,25 +1191,12 @@ bool Item::get_date(MYSQL_TIME *ltime,uint fuzzydate)
str_to_datetime_with_warn(res->ptr(), res->length(),
ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
goto err;
+ break;
}
- else
- {
- int was_cut;
- longlong value= val_int();
-
- if (null_value)
- goto err;
-
- if (number_to_datetime(value, ltime, fuzzydate, &was_cut) == LL(-1))
- {
- char buff[22], *end;
- end= longlong10_to_str(value, buff, -10);
- make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- buff, (int) (end-buff), MYSQL_TIMESTAMP_NONE,
- NullS);
- goto err;
- }
+ default:
+ DBUG_ASSERT(0);
}
+
return 0;
err:
@@ -989,23 +1204,20 @@ err:
return 1;
}
-/**
- Get time of first argument.\
-
- As a extra convenience the time structure is reset on error!
-*/
-
-bool Item::get_time(MYSQL_TIME *ltime)
+bool Item::get_seconds(ulonglong *sec, ulong *sec_part)
{
- char buff[40];
- String tmp(buff,sizeof(buff),&my_charset_bin),*res;
- if (!(res=val_str(&tmp)) ||
- str_to_time_with_warn(res->ptr(), res->length(), ltime))
- {
- bzero((char*) ltime,sizeof(*ltime));
- return 1;
+ if (decimals == 0)
+ { // optimize for an important special case
+ longlong val= val_int();
+ bool neg= val < 0 && !unsigned_flag;
+ *sec= neg ? -val : val;
+ *sec_part= 0;
+ return neg;
}
- return 0;
+ my_decimal tmp, *dec= val_decimal(&tmp);
+ if (!dec)
+ return 0;
+ return my_decimal2seconds(dec, sec, sec_part);
}
CHARSET_INFO *Item::default_charset()
@@ -1031,6 +1243,7 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions)
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
ulong sql_mode= thd->variables.sql_mode;
thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
+ thd->variables.sql_mode|= MODE_INVALID_DATES;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
res= save_in_field(field, no_conversions);
thd->count_cuted_fields= tmp;
@@ -1443,7 +1656,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 ||
@@ -1469,6 +1682,11 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
*/
Item_aggregate_ref *item_ref;
uint el= fields.elements;
+ /*
+ If this is an item_ref, get the original item
+ This is a safety measure if this is called for things that is
+ already a reference.
+ */
Item *real_itm= real_item();
ref_pointer_array[el]= real_itm;
@@ -1866,6 +2084,7 @@ Item_field::Item_field(Field *f)
if this item is to be reused
*/
orig_table_name= orig_field_name= "";
+ with_field= 1;
}
@@ -1914,6 +2133,7 @@ Item_field::Item_field(THD *thd, Name_resolution_context *context_arg,
name= (char*) orig_field_name;
}
set_field(f);
+ with_field= 1;
}
@@ -1928,6 +2148,7 @@ Item_field::Item_field(Name_resolution_context *context_arg,
collation.set(DERIVATION_IMPLICIT);
if (select && select->parsing_place != IN_HAVING)
select->select_n_where_fields++;
+ with_field= 1;
}
/**
@@ -1944,6 +2165,7 @@ Item_field::Item_field(THD *thd, Item_field *item)
any_privileges(item->any_privileges)
{
collation.set(DERIVATION_IMPLICIT);
+ with_field= 1;
}
void Item_field::set_field(Field *field_par)
@@ -1981,10 +2203,15 @@ 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;
}
+bool Item_field::update_table_bitmaps_processor(uchar *arg)
+{
+ update_table_bitmaps();
+ return FALSE;
+}
const char *Item_ident::full_name() const
{
@@ -2131,16 +2358,12 @@ bool Item_field::get_date_result(MYSQL_TIME *ltime,uint fuzzydate)
return 0;
}
-bool Item_field::get_time(MYSQL_TIME *ltime)
+void Item_field::save_result(Field *to)
{
- if ((null_value=field->is_null()) || field->get_time(ltime))
- {
- bzero((char*) ltime,sizeof(*ltime));
- return 1;
- }
- return 0;
+ save_field_in_field(result_field, &null_value, to, TRUE);
}
+
double Item_field::val_result()
{
if ((null_value=result_field->is_null()))
@@ -2183,10 +2406,12 @@ bool Item_field::val_bool_result()
case STRING_RESULT:
return result_field->val_real() != 0.0;
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
return 0; // Shut up compiler
}
+ return 0;
}
@@ -2230,7 +2455,32 @@ table_map Item_field::used_tables() const
{
if (field->table->const_table)
return 0; // const item
- return (depended_from ? OUTER_REF_TABLE_BIT : field->table->map);
+ return (get_depended_from() ? OUTER_REF_TABLE_BIT : field->table->map);
+}
+
+table_map Item_field::all_used_tables() const
+{
+ return (get_depended_from() ? OUTER_REF_TABLE_BIT : field->table->map);
+}
+
+void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ if (new_parent == get_depended_from())
+ depended_from= NULL;
+ if (context)
+ {
+ 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;
+ }
}
@@ -2467,7 +2717,7 @@ my_decimal *Item_float::val_decimal(my_decimal *decimal_value)
void Item_string::print(String *str, enum_query_type query_type)
{
- if (query_type == QT_ORDINARY && is_cs_specified())
+ if (query_type != QT_IS && is_cs_specified())
{
str->append('_');
str->append(collation.collation->csname);
@@ -2475,7 +2725,7 @@ void Item_string::print(String *str, enum_query_type query_type)
str->append('\'');
- if (query_type == QT_ORDINARY ||
+ if (query_type != QT_IS ||
my_charset_same(str_value.charset(), system_charset_info))
{
str_value.print(str);
@@ -2503,18 +2753,19 @@ void Item_string::print(String *str, enum_query_type query_type)
double
-double_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end)
+double_from_string_with_check(CHARSET_INFO *cs, const char *cptr,
+ const char *end)
{
int error;
- char *org_end;
+ char *end_of_num= (char*) end;
double tmp;
- org_end= 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)))
+ tmp= my_strntod(cs, (char*) cptr, end - cptr, &end_of_num, &error);
+ if (error || (end != end_of_num &&
+ !check_if_only_end_space(cs, end_of_num, end)))
{
char buff[80];
- strmake(buff, cptr, min(sizeof(buff)-1, (size_t) (org_end-cptr)));
+ strmake(buff, cptr, min(sizeof(buff)-1, (size_t) (end-cptr)));
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE",
@@ -2529,26 +2780,27 @@ 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.ptr() +
str_value.length());
}
longlong
-longlong_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end)
+longlong_from_string_with_check(CHARSET_INFO *cs, const char *cptr,
+ const char *end)
{
int err;
longlong tmp;
- char *org_end= end;
+ char *end_of_num= (char*) end;
- tmp= (*(cs->cset->strtoll10))(cs, cptr, &end, &err);
+ tmp= (*(cs->cset->strtoll10))(cs, cptr, &end_of_num, &err);
/*
TODO: Give error if we wanted a signed integer and we got an unsigned
one
*/
if (!current_thd->no_errors &&
(err > 0 ||
- (end != org_end && !check_if_only_end_space(cs, end, org_end))))
+ (end != end_of_num && !check_if_only_end_space(cs, end_of_num, end))))
{
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
@@ -2567,7 +2819,7 @@ longlong Item_string::val_int()
{
DBUG_ASSERT(fixed == 1);
return longlong_from_string_with_check(str_value.charset(), str_value.ptr(),
- (char *) str_value.ptr()+ str_value.length());
+ str_value.ptr()+ str_value.length());
}
@@ -2747,19 +2999,19 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type,
if (value.time.year > 9999 || value.time.month > 12 ||
value.time.day > 31 ||
(time_type != MYSQL_TIMESTAMP_TIME && value.time.hour > 23) ||
- value.time.minute > 59 || value.time.second > 59)
+ value.time.minute > 59 || value.time.second > 59 ||
+ value.time.second_part > TIME_MAX_SECOND_PART)
{
- char buff[MAX_DATE_STRING_REP_LENGTH];
- uint length= my_TIME_to_str(&value.time, buff);
+ Lazy_string_time str(&value.time);
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- buff, length, time_type, 0);
+ &str, time_type, 0);
set_zero_time(&value.time, MYSQL_TIMESTAMP_ERROR);
}
state= TIME_VALUE;
maybe_null= 0;
max_length= max_length_arg;
- decimals= 0;
+ decimals= tm->second_part > 0 ? TIME_SECOND_PART_DIGITS : 0;
DBUG_VOID_RETURN;
}
@@ -2846,10 +3098,12 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
case REAL_RESULT:
set_double(*(double*)entry->value);
item_type= Item::REAL_ITEM;
+ param_type= MYSQL_TYPE_DOUBLE;
break;
case INT_RESULT:
set_int(*(longlong*)entry->value, MY_INT64_NUM_DECIMAL_DIGITS);
item_type= Item::INT_ITEM;
+ param_type= MYSQL_TYPE_LONGLONG;
break;
case STRING_RESULT:
{
@@ -2872,6 +3126,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
charset of connection, so we have to set it later.
*/
item_type= Item::STRING_ITEM;
+ param_type= MYSQL_TYPE_VARCHAR;
if (set_str((const char *)entry->value, entry->length))
DBUG_RETURN(1);
@@ -2887,9 +3142,12 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
my_decimal_precision_to_length_no_truncation(ent_value->precision(),
decimals, unsigned_flag);
item_type= Item::DECIMAL_ITEM;
+ param_type= MYSQL_TYPE_NEWDECIMAL;
break;
}
- default:
+ case ROW_RESULT:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
set_null();
}
@@ -2951,7 +3209,7 @@ int Item_param::save_in_field(Field *field, bool no_conversions)
case DECIMAL_VALUE:
return field->store_decimal(&decimal_value);
case TIME_VALUE:
- field->store_time(&value.time, value.time.time_type);
+ field->store_time_dec(&value.time, decimals);
return 0;
case STRING_VALUE:
case LONG_DATA_VALUE:
@@ -2967,21 +3225,6 @@ int Item_param::save_in_field(Field *field, bool no_conversions)
}
-bool Item_param::get_time(MYSQL_TIME *res)
-{
- if (state == TIME_VALUE)
- {
- *res= value.time;
- return 0;
- }
- /*
- If parameter value isn't supplied assertion will fire in val_str()
- which is called from Item::get_time().
- */
- return Item::get_time(res);
-}
-
-
bool Item_param::get_date(MYSQL_TIME *res, uint fuzzydate)
{
if (state == TIME_VALUE)
@@ -3111,7 +3354,8 @@ String *Item_param::val_str(String* str)
{
if (str->reserve(MAX_DATE_STRING_REP_LENGTH))
break;
- str->length((uint) my_TIME_to_str(&value.time, (char*) str->ptr()));
+ str->length((uint) my_TIME_to_str(&value.time, (char*) str->ptr(),
+ decimals));
str->set_charset(&my_charset_bin);
return str;
}
@@ -3163,7 +3407,7 @@ const String *Item_param::query_val_str(THD *thd, String* str) const
buf= str->c_ptr_quick();
ptr= buf;
*ptr++= '\'';
- ptr+= (uint) my_TIME_to_str(&value.time, ptr);
+ ptr+= (uint) my_TIME_to_str(&value.time, ptr, decimals);
*ptr++= '\'';
str->length((uint32) (ptr - buf));
break;
@@ -3358,6 +3602,7 @@ Item_param::set_param_type_and_swap_value(Item_param *src)
/****************************************************************************
Item_copy
****************************************************************************/
+
Item_copy *Item_copy::create (Item *item)
{
switch (item->result_type())
@@ -3371,7 +3616,9 @@ Item_copy *Item_copy::create (Item *item)
new Item_copy_uint (item) : new Item_copy_int (item);
case DECIMAL_RESULT:
return new Item_copy_decimal (item);
- default:
+ case TIME_RESULT:
+ case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT (0);
}
/* should not happen */
@@ -3444,8 +3691,7 @@ void Item_copy_int::copy()
null_value=item->null_value;
}
-static int save_int_value_in_field (Field *field, longlong nr,
- bool null_value, bool unsigned_flag);
+static int save_int_value_in_field (Field *, longlong, bool, bool);
int Item_copy_int::save_in_field(Field *field, bool no_conversions)
{
@@ -3599,6 +3845,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);
@@ -3646,7 +3901,7 @@ String* Item_ref_null_helper::val_str(String* s)
bool Item_ref_null_helper::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{
- return (owner->was_null|= null_value= (*ref)->get_date(ltime, fuzzydate));
+ return (owner->was_null|= null_value= (*ref)->get_date_result(ltime, fuzzydate));
}
@@ -3662,7 +3917,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)
{
@@ -3671,9 +3926,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,
@@ -3683,6 +3940,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;
}
@@ -3966,6 +4224,34 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
}
+/*
+ @brief
+ Whether a table belongs to an outer select.
+
+ @param table table to check
+ @param select current select
+
+ @details
+ Try to find select the table belongs to by ascending the derived tables chain.
+*/
+
+static
+bool is_outer_table(TABLE_LIST *table, SELECT_LEX *select)
+{
+ DBUG_ASSERT(table->select_lex != select);
+ TABLE_LIST *tl;
+
+ for (tl= select->master_unit()->derived;
+ tl && tl->is_merged_derived();
+ select= tl->select_lex, tl= select->master_unit()->derived)
+ {
+ if (tl->select_lex == table->select_lex)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
/**
Resolve the name of an outer select column reference.
@@ -4232,8 +4518,9 @@ 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);
+
return 0;
}
else
@@ -4404,7 +4691,9 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (!outer_fixed && cached_table && cached_table->select_lex &&
context->select_lex &&
- cached_table->select_lex != context->select_lex)
+ cached_table->select_lex != context->select_lex &&
+ !context->select_lex->is_merged_child_of(cached_table->select_lex) &&
+ is_outer_table(cached_table, context->select_lex))
{
int ret;
if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
@@ -4547,6 +4836,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.
@@ -4598,13 +4888,14 @@ Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
/**
- Check whether a field can be substituted by an equal item.
+ Check whether a field item can be substituted for an equal item
- The function checks whether a substitution of the field
- occurrence for an equal item is valid.
+ @details
+ The function checks whether a substitution of a field item for
+ an equal item is valid.
- @param arg *arg != NULL <-> the field is in the context where
- substitution for an equal item is valid
+ @param arg *arg != NULL <-> the field is in the context
+ where substitution for an equal item is valid
@note
The following statement is not always true:
@@ -4629,7 +4920,10 @@ Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
bool Item_field::subst_argument_checker(uchar **arg)
{
- return (result_type() != STRING_RESULT) || (*arg);
+ return *arg &&
+ (*arg == (uchar *) Item::ANY_SUBST ||
+ result_type() != STRING_RESULT ||
+ (field->flags & BINARY_FLAG));
}
@@ -4666,6 +4960,7 @@ static void convert_zerofill_number_to_string(Item **item, Field_num *field)
Set a pointer to the multiple equality the field reference belongs to
(if any).
+ @details
The function looks for a multiple equality containing the field item
among those referenced by arg.
In the case such equality exists the function does the following.
@@ -4710,12 +5005,8 @@ Item *Item_field::equal_fields_propagator(uchar *arg)
item= this;
else if (field && (field->flags & ZEROFILL_FLAG) && IS_NUM(field->type()))
{
- /*
- We don't need to zero-fill timestamp columns here because they will be
- first converted to a string (in date/time format) and compared as such if
- compared with another string.
- */
- if (item && field->type() != FIELD_TYPE_TIMESTAMP && cmp_context != INT_RESULT)
+ if (item && field->type() != FIELD_TYPE_TIMESTAMP &&
+ cmp_context != INT_RESULT)
convert_zerofill_number_to_string(&item, (Field_num *)field);
else
item= this;
@@ -4742,7 +5033,9 @@ bool Item_field::set_no_const_sub(uchar *arg)
Replace an Item_field for an equal Item_field that evaluated earlier
(if any).
- The function returns a pointer to an item that is taken from
+ @details
+ If this->item_equal points to some item and coincides with arg then
+ the function returns a pointer to an item that is taken from
the very beginning of the item_equal list which the Item_field
object refers to (belongs to) unless item_equal contains a constant
item. In this case the function returns this constant item,
@@ -4750,12 +5043,12 @@ bool Item_field::set_no_const_sub(uchar *arg)
If the Item_field object does not refer any Item_equal object
'this' is returned .
- @param arg a dummy parameter, is not used here
+ @param arg NULL or points to so some item of the Item_equal type
@note
This function is supposed to be called as a callback parameter in calls
- of the thransformer method.
+ of the transformer method.
@return
- pointer to a replacement Item_field if there is a better equal item or
@@ -4765,7 +5058,8 @@ bool Item_field::set_no_const_sub(uchar *arg)
Item *Item_field::replace_equal_field(uchar *arg)
{
- if (item_equal)
+ REPLACE_EQUAL_FIELD_ARG* param= (REPLACE_EQUAL_FIELD_ARG*)arg;
+ if (item_equal && item_equal == param->item_equal)
{
Item *const_item= item_equal->get_const();
if (const_item)
@@ -4775,8 +5069,11 @@ Item *Item_field::replace_equal_field(uchar *arg)
return this;
return const_item;
}
- Item_field *subst= item_equal->get_first();
- if (subst && field->table != subst->field->table && !field->eq(subst->field))
+ Item_field *subst=
+ (Item_field *)(item_equal->get_first(param->context_tab, this));
+ if (subst)
+ subst= (Item_field *) (subst->real_item());
+ if (subst && !field->eq(subst->field))
return subst;
}
return this;
@@ -4834,25 +5131,12 @@ enum_field_types Item::field_type() const
case DECIMAL_RESULT: return MYSQL_TYPE_NEWDECIMAL;
case REAL_RESULT: return MYSQL_TYPE_DOUBLE;
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
return MYSQL_TYPE_VARCHAR;
}
-}
-
-
-bool Item::is_datetime()
-{
- switch (field_type())
- {
- case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_DATETIME:
- case MYSQL_TYPE_TIMESTAMP:
- return TRUE;
- default:
- break;
- }
- return FALSE;
+ return MYSQL_TYPE_VARCHAR;
}
@@ -4954,6 +5238,10 @@ Field *Item::make_string_field(TABLE *table)
{
Field *field;
DBUG_ASSERT(collation.collation);
+ /*
+ Note: the following check is repeated in
+ subquery_types_allow_materialization():
+ */
if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB)
field= new Field_blob(max_length, maybe_null, name,
collation.collation);
@@ -5032,16 +5320,19 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
break;
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_DATE:
- field= new Field_newdate(maybe_null, name, &my_charset_bin);
+ field= new Field_newdate(0, null_ptr, 0, Field::NONE, name, &my_charset_bin);
break;
case MYSQL_TYPE_TIME:
- field= new Field_time(maybe_null, name, &my_charset_bin);
+ field= new_Field_time(0, null_ptr, 0, Field::NONE, name,
+ decimals, &my_charset_bin);
break;
case MYSQL_TYPE_TIMESTAMP:
- field= new Field_timestamp(maybe_null, name, &my_charset_bin);
+ field= new_Field_timestamp(0, null_ptr, 0,
+ Field::NONE, name, 0, decimals, &my_charset_bin);
break;
case MYSQL_TYPE_DATETIME:
- field= new Field_datetime(maybe_null, name, &my_charset_bin);
+ field= new_Field_datetime(0, null_ptr, 0, Field::NONE, name,
+ decimals, &my_charset_bin);
break;
case MYSQL_TYPE_YEAR:
field= new Field_year((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
@@ -5105,47 +5396,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);
}
@@ -5256,12 +5569,6 @@ int Item_string::save_in_field(Field *field, bool no_conversions)
}
-int Item_uint::save_in_field(Field *field, bool no_conversions)
-{
- /* Item_int::save_in_field handles both signed and unsigned. */
- return Item_int::save_in_field(field, no_conversions);
-}
-
static int save_int_value_in_field (Field *field, longlong nr,
bool null_value, bool unsigned_flag)
{
@@ -5278,6 +5585,22 @@ int Item_int::save_in_field(Field *field, bool no_conversions)
}
+void Item_datetime::set(longlong packed)
+{
+ unpack_time(packed, &ltime);
+}
+
+int Item_datetime::save_in_field(Field *field, bool no_conversions)
+{
+ field->set_notnull();
+ return field->store_time_dec(&ltime, decimals);
+}
+
+longlong Item_datetime::val_int()
+{
+ return TIME_to_ulonglong(&ltime);
+}
+
int Item_decimal::save_in_field(Field *field, bool no_conversions)
{
field->set_notnull();
@@ -5295,7 +5618,9 @@ bool Item_int::eq(const Item *arg, bool binary_cmp) const
a basic constant.
*/
Item *item= (Item*) arg;
- return item->val_int() == value && item->unsigned_flag == unsigned_flag;
+ return (item->val_int() == value &&
+ ((longlong) value >= 0 ||
+ (item->unsigned_flag == unsigned_flag)));
}
return FALSE;
}
@@ -5639,7 +5964,10 @@ bool Item::send(Protocol *protocol, String *buffer)
{
String *res;
if ((res=val_str(buffer)))
+ {
+ DBUG_ASSERT(!null_value);
result= protocol->store(res->ptr(),res->length(),res->charset());
+ }
else
{
DBUG_ASSERT(null_value);
@@ -5700,13 +6028,13 @@ bool Item::send(Protocol *protocol, String *buffer)
case MYSQL_TYPE_TIMESTAMP:
{
MYSQL_TIME tm;
- get_date(&tm, TIME_FUZZY_DATE);
+ get_date(&tm, TIME_FUZZY_DATE | sql_mode_for_dates());
if (!null_value)
{
if (f_type == MYSQL_TYPE_DATE)
return protocol->store_date(&tm);
else
- result= protocol->store(&tm);
+ result= protocol->store(&tm, decimals);
}
break;
}
@@ -5715,7 +6043,7 @@ bool Item::send(Protocol *protocol, String *buffer)
MYSQL_TIME tm;
get_time(&tm);
if (!null_value)
- result= protocol->store_time(&tm);
+ result= protocol->store_time(&tm, decimals);
break;
}
}
@@ -5796,17 +6124,7 @@ void Item_field::print(String *str, enum_query_type query_type)
{
if (field && field->table->const_table)
{
- char buff[MAX_FIELD_WIDTH];
- String tmp(buff,sizeof(buff),str->charset());
- field->val_str(&tmp);
- if (field->is_null())
- str->append("NULL");
- else
- {
- str->append('\'');
- str->append(tmp);
- str->append('\'');
- }
+ print_value(str);
return;
}
Item_ident::print(str, query_type);
@@ -5818,7 +6136,7 @@ Item_ref::Item_ref(Name_resolution_context *context_arg,
const char *field_name_arg,
bool alias_name_used_arg)
:Item_ident(context_arg, NullS, table_name_arg, field_name_arg),
- result_field(0), ref(item)
+ result_field(0), ref(item), reference_trough_name(0)
{
alias_name_used= alias_name_used_arg;
/*
@@ -5828,11 +6146,41 @@ 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())
+ {
+ List_iterator<TABLE_LIST> li(sel->leaf_tables);
+ TABLE_LIST *tbl;
+ while ((tbl= li++))
+ {
+ 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)
:Item_ident(view_arg, field_name_arg),
- result_field(NULL), ref(item)
+ result_field(NULL), ref(item), reference_trough_name(0)
{
alias_name_used= alias_name_used_arg;
/*
@@ -5915,6 +6263,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
if (!ref || ref == not_found_item)
{
+ DBUG_ASSERT(reference_trough_name != 0);
if (!(ref= resolve_ref_in_select_and_group(thd, this,
context->select_lex)))
goto error; /* Some error occurred (e.g. ambiguous names). */
@@ -6065,7 +6414,7 @@ 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);
/*
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
@@ -6101,6 +6450,19 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
last_checked_context->select_lex->nest_level);
}
}
+ else if (ref_type() != VIEW_REF)
+ {
+ /*
+ 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);
/*
@@ -6146,6 +6508,7 @@ void Item_ref::set_properties()
split_sum_func() doesn't try to change the reference.
*/
with_sum_func= (*ref)->with_sum_func;
+ with_field= (*ref)->with_field;
unsigned_flag= (*ref)->unsigned_flag;
fixed= 1;
if (alias_name_used)
@@ -6162,10 +6525,100 @@ void Item_ref::cleanup()
DBUG_ENTER("Item_ref::cleanup");
Item_ident::cleanup();
result_field= 0;
+ if (reference_trough_name)
+ {
+ /* We have to reset the reference as it may been freed */
+ ref= 0;
+ }
DBUG_VOID_RETURN;
}
+/**
+ Transform an Item_ref object with a transformer callback function.
+
+ The function first applies the transform method to the item
+ referenced by this Item_reg object. If this returns a new item the
+ old item is substituted for a new one. After this the transformer
+ is applied to the Item_ref object.
+
+ @param transformer the transformer callback function to be applied to
+ the nodes of the tree of the object
+ @param argument parameter to be passed to the transformer
+
+ @return Item returned as the result of transformation of the Item_ref object
+ @retval !NULL The transformation was successful
+ @retval NULL Out of memory error
+*/
+
+Item* Item_ref::transform(Item_transformer transformer, uchar *arg)
+{
+ DBUG_ASSERT(!current_thd->is_stmt_prepare());
+ DBUG_ASSERT((*ref) != NULL);
+
+ /* Transform the object we are referencing. */
+ Item *new_item= (*ref)->transform(transformer, arg);
+ if (!new_item)
+ return NULL;
+
+ /*
+ 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 (*ref != new_item)
+ current_thd->change_item_tree(ref, new_item);
+
+ /* Transform the item ref object. */
+ return (this->*transformer)(arg);
+}
+
+
+/**
+ Compile an Item_ref object with a processor and a transformer
+ callback functions.
+
+ First the function applies the analyzer to the Item_ref object. Then
+ if the analizer succeeeds we first applies the compile method to the
+ object the Item_ref object is referencing. If this returns a new
+ item the old item is substituted for a new one. After this the
+ transformer is applied to the Item_ref object itself.
+ The compile function is not called if the analyzer returns NULL
+ in the parameter arg_p.
+
+ @param analyzer the analyzer callback function to be applied to the
+ nodes of the tree of the object
+ @param[in,out] arg_p parameter to be passed to the processor
+ @param transformer the transformer callback function to be applied to the
+ nodes of the tree of the object
+ @param arg_t parameter to be passed to the transformer
+
+ @return Item returned as the result of transformation of the Item_ref object
+*/
+
+Item* Item_ref::compile(Item_analyzer analyzer, uchar **arg_p,
+ Item_transformer transformer, uchar *arg_t)
+{
+ /* Analyze this Item object. */
+ if (!(this->*analyzer)(arg_p))
+ return NULL;
+
+ /* Compile the Item we are referencing. */
+ DBUG_ASSERT((*ref) != NULL);
+ if (*arg_p)
+ {
+ uchar *arg_v= *arg_p;
+ Item *new_item= (*ref)->compile(analyzer, &arg_v, transformer, arg_t);
+ if (new_item && *ref != new_item)
+ current_thd->change_item_tree(ref, new_item);
+ }
+
+ /* Transform this Item object. */
+ return (this->*transformer)(arg_t);
+}
+
+
void Item_ref::print(String *str, enum_query_type query_type)
{
if (ref)
@@ -6272,7 +6725,8 @@ bool Item_ref::val_bool_result()
case STRING_RESULT:
return result_field->val_real() != 0.0;
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
}
@@ -6280,6 +6734,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);
@@ -6341,7 +6814,19 @@ my_decimal *Item_ref::val_decimal(my_decimal *decimal_value)
int Item_ref::save_in_field(Field *to, bool no_conversions)
{
int res;
- DBUG_ASSERT(!result_field);
+ if (result_field)
+ {
+ if (result_field->is_null())
+ {
+ null_value= 1;
+ res= set_field_to_null_with_conversions(to, no_conversions);
+ return res;
+ }
+ to->set_notnull();
+ res= field_conv(to, result_field);
+ null_value= 0;
+ return res;
+ }
res= (*ref)->save_in_field(to, no_conversions);
null_value= (*ref)->null_value;
return res;
@@ -6397,6 +6882,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();
@@ -6449,6 +6941,390 @@ bool Item_direct_ref::get_date(MYSQL_TIME *ltime,uint fuzzydate)
}
+Item_cache_wrapper::~Item_cache_wrapper()
+{
+ DBUG_ASSERT(expr_cache == 0);
+}
+
+
+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;
+ with_field= orig_item->with_field;
+ unsigned_flag= orig_item->unsigned_flag;
+ name= item_arg->name;
+ name_length= item_arg->name_length;
+ with_subselect= orig_item->with_subselect;
+
+ if ((expr_value= Item_cache::get_cache(orig_item)))
+ expr_value->setup(orig_item);
+
+ fixed= 1;
+}
+
+
+/**
+ Initialize the cache if it is needed
+*/
+
+void Item_cache_wrapper::init_on_demand()
+{
+ if (!expr_cache->is_inited())
+ {
+ orig_item->get_cache_parameters(parameters);
+ expr_cache->init();
+ }
+}
+
+
+void Item_cache_wrapper::print(String *str, enum_query_type query_type)
+{
+ str->append(func_name());
+ if (expr_cache)
+ {
+ init_on_demand();
+ expr_cache->print(str, query_type);
+ }
+ else
+ str->append(STRING_WITH_LEN("<<DISABLED>>"));
+ str->append('(');
+ 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()
+{
+ DBUG_ENTER("Item_cache_wrapper::cleanup");
+ Item_result_field::cleanup();
+ delete expr_cache;
+ expr_cache= 0;
+ /* expr_value is Item so it will be destroyed from list of Items */
+ expr_value= 0;
+ parameters.empty();
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ 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)
+{
+ DBUG_ENTER("Item_cache_wrapper::set_cache");
+ DBUG_ASSERT(expr_cache == 0);
+ expr_cache= new Expression_cache_tmptable(thd, parameters, 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;
+ init_on_demand();
+ 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)));
+}
+
+
+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 .
@@ -6463,6 +7339,7 @@ bool Item_direct_ref::get_date(MYSQL_TIME *ltime,uint fuzzydate)
bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
{
+ DBUG_ASSERT(1);
/* view fild reference must be defined */
DBUG_ASSERT(*ref);
/* (*ref)->check_cols() will be made in Item_direct_ref::fix_fields */
@@ -6486,7 +7363,11 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
((*ref)->fix_fields(thd, ref)))
return TRUE;
- return Item_direct_ref::fix_fields(thd, reference);
+ if (Item_direct_ref::fix_fields(thd, reference))
+ return TRUE;
+ if (view->table && view->table->maybe_null)
+ maybe_null= TRUE;
+ return FALSE;
}
/*
@@ -6517,6 +7398,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 (get_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 (get_depended_from() == new_parent)
+ depended_from= NULL;
+}
+
+
/**
Mark references from inner selects used in group by clause
@@ -6584,6 +7482,138 @@ bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const
return FALSE;
}
+
+Item_equal *Item_direct_view_ref::find_item_equal(COND_EQUAL *cond_equal)
+{
+ Item* field_item= real_item();
+ if (field_item->type() != FIELD_ITEM)
+ return NULL;
+ return ((Item_field *) field_item)->find_item_equal(cond_equal);
+}
+
+
+/**
+ Check whether a reference to field item can be substituted for an equal item
+
+ @details
+ The function checks whether a substitution of a reference to field item for
+ an equal item is valid.
+
+ @param arg *arg != NULL <-> the reference is in the context
+ where substitution for an equal item is valid
+
+ @note
+ See also the note for Item_field::subst_argument_checker
+
+ @retval
+ TRUE substitution is valid
+ @retval
+ FALSE otherwise
+*/
+bool Item_direct_view_ref::subst_argument_checker(uchar **arg)
+{
+ bool res= FALSE;
+ if (*arg)
+ {
+ Item *item= real_item();
+ if (item->type() == FIELD_ITEM &&
+ (*arg == (uchar *) Item::ANY_SUBST ||
+ result_type() != STRING_RESULT ||
+ (((Item_field *) item)->field->flags & BINARY_FLAG)))
+ res= TRUE;
+ }
+ /* Block any substitution into the wrapped object */
+ if (*arg)
+ *arg= NULL;
+ return res;
+}
+
+
+/**
+ Set a pointer to the multiple equality the view field reference belongs to
+ (if any).
+
+ @details
+ The function looks for a multiple equality containing this item of the type
+ Item_direct_view_ref among those referenced by arg.
+ In the case such equality exists the function does the following.
+ If the found multiple equality contains a constant, then the item
+ is substituted for this constant, otherwise the function sets a pointer
+ to the multiple equality in the item.
+
+ @param arg reference to list of multiple equalities where
+ the item (this object) is to be looked for
+
+ @note
+ This function is supposed to be called as a callback parameter in calls
+ of the compile method.
+
+ @note
+ The function calls Item_field::equal_fields_propagator for the field item
+ this->real_item() to do the job. Then it takes the pointer to equal_item
+ from this field item and assigns it to this->item_equal.
+
+ @return
+ - pointer to the replacing constant item, if the field item was substituted
+ - pointer to the field item, otherwise.
+*/
+
+Item *Item_direct_view_ref::equal_fields_propagator(uchar *arg)
+{
+ Item *field_item= real_item();
+ if (field_item->type() != FIELD_ITEM)
+ return this;
+ Item *item= field_item->equal_fields_propagator(arg);
+ set_item_equal(field_item->get_item_equal());
+ field_item->set_item_equal(NULL);
+ if (item != field_item)
+ return item;
+ return this;
+}
+
+
+/**
+ Replace an Item_direct_view_ref for an equal Item_field evaluated earlier
+ (if any).
+
+ @details
+ If this->item_equal points to some item and coincides with arg then
+ the function returns a pointer to a field item that is referred to by the
+ first element of the item_equal list which the Item_direct_view_ref
+ object belongs to unless item_equal contains a constant item. In this
+ case the function returns this constant item (if the substitution does
+ not require conversion).
+ If the Item_direct_view_item object does not refer any Item_equal object
+ 'this' is returned .
+
+ @param arg NULL or points to so some item of the Item_equal type
+
+ @note
+ This function is supposed to be called as a callback parameter in calls
+ of the transformer method.
+
+ @note
+ The function calls Item_field::replace_equal_field for the field item
+ this->real_item() to do the job.
+
+ @return
+ - pointer to a replacement Item_field if there is a better equal item or
+ a pointer to a constant equal item;
+ - this - otherwise.
+*/
+
+Item *Item_direct_view_ref::replace_equal_field(uchar *arg)
+{
+ Item *field_item= real_item();
+ if (field_item->type() != FIELD_ITEM)
+ return this;
+ field_item->set_item_equal(item_equal);
+ Item *item= field_item->replace_equal_field(arg);
+ field_item->set_item_equal(0);
+ return item != field_item ? item : this;
+}
+
+
bool Item_default_value::eq(const Item *item, bool binary_cmp) const
{
return item->type() == DEFAULT_VALUE_ITEM &&
@@ -6930,6 +7960,8 @@ Item_result item_cmp_type(Item_result a,Item_result b)
return INT_RESULT;
else if (a == ROW_RESULT || b == ROW_RESULT)
return ROW_RESULT;
+ else if (a == TIME_RESULT || b == TIME_RESULT)
+ return TIME_RESULT;
if ((a == INT_RESULT || a == DECIMAL_RESULT) &&
(b == INT_RESULT || b == DECIMAL_RESULT))
return DECIMAL_RESULT;
@@ -6943,11 +7975,20 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
Item *new_item= NULL;
if (item->basic_const_item())
return; // Can't be better
- Item_result res_type=item_cmp_type(comp_item->result_type(),
- item->result_type());
+ Item_result res_type=item_cmp_type(comp_item->cmp_type(), item->cmp_type());
char *name=item->name; // Alloced by sql_alloc
switch (res_type) {
+ case TIME_RESULT:
+ {
+ bool is_null;
+ Item **ref_copy= ref;
+ /* the following call creates a constant and puts it in new_item */
+ get_datetime_value(thd, &ref_copy, &new_item, comp_item, &is_null);
+ if (is_null)
+ new_item= new Item_null(name);
+ break;
+ }
case STRING_RESULT:
{
char buff[MAX_FIELD_WIDTH];
@@ -7022,8 +8063,9 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
(Item*) new Item_decimal(name, result, length, decimals));
break;
}
- default:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
+ break;
}
if (new_item)
thd->change_item_tree(ref, new_item);
@@ -7043,6 +8085,9 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
@note We only use this on the range optimizer/partition pruning,
because in some cases we can't store the value in the field
without some precision/character loss.
+
+ @todo rewrite it to use Arg_comparator (currently it's a simplified and
+ incomplete version of it)
*/
int stored_field_cmp_to_item(THD *thd, Field *field, Item *item)
@@ -7098,6 +8143,25 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item)
field_val= field->val_decimal(&field_buf);
return my_decimal_cmp(field_val, item_val);
}
+ /*
+ We have to check field->cmp_type() instead of res_type,
+ as result_type() - and thus res_type - can never be TIME_RESULT (yet).
+ */
+ if (field->cmp_type() == TIME_RESULT)
+ {
+ MYSQL_TIME field_time, item_time;
+ if (field->type() == MYSQL_TYPE_TIME)
+ {
+ field->get_time(&field_time);
+ item->get_time(&item_time);
+ }
+ else
+ {
+ field->get_date(&field_time, TIME_FUZZY_DATE | TIME_INVALID_DATES);
+ item->get_date(&item_time, TIME_FUZZY_DATE | TIME_INVALID_DATES);
+ }
+ return my_time_compare(&field_time, &item_time);
+ }
double result= item->val_real();
if (item->null_value)
return 0;
@@ -7137,11 +8201,13 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
return new Item_cache_str(item);
case ROW_RESULT:
return new Item_cache_row();
- default:
- // should never be in real life
+ case TIME_RESULT:
+ return new Item_cache_temporal(item->field_type());
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
- return 0;
+ break;
}
+ return 0; // Impossible
}
void Item_cache::store(Item *item)
@@ -7154,6 +8220,11 @@ void Item_cache::store(Item *item)
void Item_cache::print(String *str, enum_query_type query_type)
{
+ if (value_cached)
+ {
+ print_value(str);
+ return;
+ }
str->append(STRING_WITH_LEN("<cache>("));
if (example)
example->print(str, query_type);
@@ -7162,6 +8233,20 @@ void Item_cache::print(String *str, enum_query_type query_type)
str->append(')');
}
+/**
+ Assign to this cache NULL value if it is possible
+*/
+
+void Item_cache::set_null()
+{
+ if (maybe_null)
+ {
+ null_value= TRUE;
+ value_cached= TRUE;
+ }
+}
+
+
bool Item_cache_int::cache_value()
{
if (!example)
@@ -7174,21 +8259,14 @@ bool Item_cache_int::cache_value()
}
-void Item_cache_int::store_longlong(Item *item, longlong val_arg)
-{
- /* An explicit values is given, save it. */
- value_cached= TRUE;
- value= val_arg;
- null_value= item->null_value;
- unsigned_flag= item->unsigned_flag;
-}
-
-
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_int(value, unsigned_flag, default_charset());
return str;
}
@@ -7197,8 +8275,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;
}
@@ -7206,19 +8287,117 @@ 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;
}
+
+int Item_cache_int::save_in_field(Field *field, bool no_conversions)
+{
+ int error;
+ if ((!value_cached && !cache_value()) || null_value)
+ return set_field_to_null_with_conversions(field, no_conversions);
+
+ field->set_notnull();
+ error= field->store(value, unsigned_flag);
+
+ return error ? error : field->table->in_use->is_error() ? 1 : 0;
+}
+
+
+String *Item_cache_temporal::val_str(String *str)
+{
+ DBUG_ASSERT(fixed == 1);
+ if ((!value_cached && !cache_value()) || null_value)
+ {
+ null_value= true;
+ return NULL;
+ }
+ return val_string_from_date(str);
+}
+
+
+bool Item_cache_temporal::cache_value()
+{
+ if (!example)
+ return false;
+ value_cached= true;
+
+ MYSQL_TIME ltime;
+ if (example->get_date_result(&ltime, TIME_FUZZY_DATE))
+ value=0;
+ else
+ value= pack_time(&ltime);
+ null_value= example->null_value;
+ return true;
+}
+
+
+bool Item_cache_temporal::get_date(MYSQL_TIME *ltime, uint fuzzydate)
+{
+ Lazy_string_num str(value);
+
+ if (!value_cached && !cache_value())
+ {
+ bzero((char*) ltime,sizeof(*ltime));
+ return 1;
+ }
+
+ unpack_time(value, ltime);
+ ltime->time_type= mysql_type_to_time_type(field_type());
+ if (ltime->time_type == MYSQL_TIMESTAMP_TIME)
+ {
+ ltime->hour+= (ltime->month*32+ltime->day)*24;
+ ltime->month= ltime->day= 0;
+ }
+ return 0;
+
+}
+
+
+int Item_cache_temporal::save_in_field(Field *field, bool no_conversions)
+{
+ int error;
+ if ((!value_cached && !cache_value()) || null_value)
+ return set_field_to_null_with_conversions(field, no_conversions);
+
+ field->set_notnull();
+
+ MYSQL_TIME ltime;
+ unpack_time(value, &ltime);
+ ltime.time_type= mysql_type_to_time_type(field_type());
+ error= field->store_time_dec(&ltime, decimals);
+
+
+ return error ? error : field->table->in_use->is_error() ? 1 : 0;
+}
+
+
+void Item_cache_temporal::store_packed(longlong val_arg, Item *example)
+{
+ /* An explicit values is given, save it. */
+ store(example);
+ value_cached= true;
+ value= val_arg;
+ null_value= false;
+}
+
+
bool Item_cache_real::cache_value()
{
if (!example)
@@ -7233,16 +8412,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);
}
@@ -7250,8 +8435,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;
}
@@ -7260,8 +8448,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;
}
@@ -7282,8 +8473,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;
}
@@ -7292,8 +8486,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;
}
@@ -7301,8 +8498,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);
@@ -7312,8 +8512,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;
}
@@ -7348,12 +8551,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);
}
@@ -7361,21 +8565,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;
}
@@ -7383,20 +8590,21 @@ 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())
- return 0;
+ if ((!value_cached && !cache_value()) || null_value)
+ return set_field_to_null_with_conversions(field, no_conversions);
+
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;
@@ -7510,6 +8718,20 @@ void Item_cache_row::bring_value()
}
+/**
+ Assign to this cache NULL value if it is possible
+*/
+
+void Item_cache_row::set_null()
+{
+ Item_cache::set_null();
+ if (!values)
+ return;
+ for (uint i= 0; i < item_count; i++)
+ values[i]->set_null();
+};
+
+
Item_type_holder::Item_type_holder(THD *thd, Item *item)
:Item(thd, item), enum_set_typelib(0), fld_type(get_real_type(item))
{
@@ -7550,12 +8772,14 @@ Item_result Item_type_holder::result_type() const
enum_field_types Item_type_holder::get_real_type(Item *item)
{
+ if (item->type() == REF_ITEM)
+ item= item->real_item();
switch(item->type())
{
case FIELD_ITEM:
{
/*
- Item_fields::field_type ask Field_type() but sometimes field return
+ Item_field::field_type ask Field_type() but sometimes field return
a different type, like for enum/set, so we need to ask real type.
*/
Field *field= ((Item_field *) item)->field;
@@ -7597,7 +8821,8 @@ enum_field_types Item_type_holder::get_real_type(Item *item)
case DECIMAL_RESULT:
return MYSQL_TYPE_NEWDECIMAL;
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
return MYSQL_TYPE_VAR_STRING;
}
@@ -7635,7 +8860,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
item->max_length, item->decimals));
fld_type= Field::field_type_merge(fld_type, get_real_type(item));
{
- int item_decimals= item->decimals;
+ uint item_decimals= item->decimals;
/* fix variable decimals which always is NOT_FIXED_DEC */
if (Field::result_merge_type(fld_type) == INT_RESULT)
item_decimals= 0;
@@ -7856,13 +9081,13 @@ void Item_type_holder::get_full_info(Item *item)
DBUG_ASSERT((enum_set_typelib &&
get_real_type(item) == MYSQL_TYPE_NULL) ||
(!enum_set_typelib &&
- item->type() == Item::FIELD_ITEM &&
- (get_real_type(item) == MYSQL_TYPE_ENUM ||
- get_real_type(item) == MYSQL_TYPE_SET) &&
- ((Field_enum*)((Item_field *) item)->field)->typelib));
+ item->real_item()->type() == Item::FIELD_ITEM &&
+ (get_real_type(item->real_item()) == MYSQL_TYPE_ENUM ||
+ get_real_type(item->real_item()) == MYSQL_TYPE_SET) &&
+ ((Field_enum*)((Item_field *) item->real_item())->field)->typelib));
if (!enum_set_typelib)
{
- enum_set_typelib= ((Field_enum*)((Item_field *) item)->field)->typelib;
+ enum_set_typelib= ((Field_enum*)((Item_field *) item->real_item())->field)->typelib;
}
}
}
@@ -7924,6 +9149,65 @@ void view_error_processor(THD *thd, void *data)
((TABLE_LIST *)data)->hide_view_error(thd);
}
+
+st_select_lex *Item_ident::get_depended_from() const
+{
+ st_select_lex *dep;
+ if ((dep= depended_from))
+ for ( ; dep->merged_into; dep= dep->merged_into) ;
+ return dep;
+}
+
+
+table_map Item_ref::used_tables() const
+{
+ return get_depended_from() ? OUTER_REF_TABLE_BIT : (*ref)->used_tables();
+}
+
+
+void Item_ref::update_used_tables()
+{
+ if (!get_depended_from())
+ (*ref)->update_used_tables();
+ maybe_null|= (*ref)->maybe_null;
+}
+
+void Item_direct_view_ref::update_used_tables()
+{
+ Item_ref::update_used_tables();
+ if (view->table && view->table->maybe_null)
+ maybe_null= TRUE;
+}
+
+table_map Item_direct_view_ref::used_tables() const
+{
+ return get_depended_from() ?
+ OUTER_REF_TABLE_BIT :
+ ((view->is_merged_derived() || view->merged || !view->table) ?
+ (*ref)->used_tables() :
+ view->table->map);
+}
+
+table_map Item_direct_view_ref::not_null_tables() const
+{
+ return get_depended_from() ?
+ 0 :
+ ((view->is_merged_derived() || view->merged || !view->table) ?
+ (*ref)->not_null_tables() :
+ view->table->map);
+}
+
+/*
+ we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
+*/
+table_map Item_ref_null_helper::used_tables() const
+{
+ return (get_depended_from() ?
+ OUTER_REF_TABLE_BIT :
+ (*ref)->used_tables() | RAND_TABLE_BIT);
+}
+
+
#ifndef DBUG_OFF
/* Debugger help function */
diff --git a/sql/item.h b/sql/item.h
index cacf0f43229..1e35c7839de 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
-
+ Copyright (c) 2009-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
@@ -18,6 +18,10 @@
#pragma interface /* gcc class implementation */
#endif
+C_MODE_START
+#include <ma_dyncol.h>
+C_MODE_END
+
inline
bool trace_unsupported_func(const char *where, const char *processor_name)
{
@@ -436,6 +440,16 @@ typedef enum monotonicity_info
class sp_rcontext;
+class Item_equal;
+
+struct st_join_table* const NO_PARTICULAR_TAB= (struct st_join_table*)0x1;
+
+typedef struct replace_equal_field_arg
+{
+ Item_equal *item_equal;
+ struct st_join_table *context_tab;
+} REPLACE_EQUAL_FIELD_ARG;
+
class Settable_routine_parameter
{
public:
@@ -471,6 +485,17 @@ public:
};
+struct st_dyncall_create_def
+{
+ Item *num, *value;
+ CHARSET_INFO *cs;
+ uint len, frac;
+ DYNAMIC_COLUMN_TYPE type;
+};
+
+typedef struct st_dyncall_create_def DYNCALL_CREATE_DEF;
+
+
typedef bool (Item::*Item_processor) (uchar *arg);
/*
Analyzer function
@@ -487,10 +512,25 @@ typedef bool (Item::*Item_analyzer) (uchar **argp);
typedef Item* (Item::*Item_transformer) (uchar *arg);
typedef void (*Cond_traverser) (const Item *item, void *arg);
+class Item_equal;
+class COND_EQUAL;
+
+class st_select_lex_unit;
class Item {
Item(const Item &); /* Prevent use of these */
void operator=(Item &);
+ /**
+ The index in the JOIN::join_tab array of the JOIN_TAB this Item is attached
+ to. Items are attached (or 'pushed') to JOIN_TABs during optimization by the
+ make_cond_for_table procedure. During query execution, this item is
+ evaluated when the join loop reaches the corresponding JOIN_TAB.
+
+ If the value of join_tab_idx >= MAX_TABLES, this means that there is no
+ corresponding JOIN_TAB.
+ */
+ uint join_tab_idx;
+
public:
static void *operator new(size_t size) throw ()
{ return sql_alloc(size); }
@@ -506,12 +546,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;
@@ -538,14 +582,18 @@ public:
calls.
*/
uint name_length; /* Length of name */
+ uint decimals;
int8 marker;
- uint8 decimals;
bool maybe_null; /* If item may be null */
bool in_rollup; /* If used in GROUP BY list
of a query with ROLLUP */
bool null_value; /* if item is null */
bool unsigned_flag;
- bool with_sum_func;
+ bool with_sum_func; /* True if item contains a sum func */
+ /**
+ True if any item except Item_sum_func contains a field. Set during parsing.
+ */
+ bool with_field;
bool fixed; /* If item fixed with fix_fields */
bool is_autogenerated_name; /* indicate was name of this Item
autogenerated or set by user */
@@ -573,6 +621,8 @@ public:
} /*lint -e1509 */
void set_name(const char *str, uint length, CHARSET_INFO *cs);
void set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs);
+ void set_name_for_rollback(THD *thd, const char *str, uint length,
+ CHARSET_INFO *cs);
void rename(char *new_name);
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
virtual void cleanup();
@@ -580,6 +630,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
@@ -600,11 +656,20 @@ public:
{ return save_in_field(field, 1); }
virtual bool send(Protocol *protocol, String *str);
virtual bool eq(const Item *, bool binary_cmp) const;
+ /* result_type() of an item specifies how the value should be returned */
virtual Item_result result_type() const { return REAL_RESULT; }
- virtual Item_result cast_to_int_type() const { return result_type(); }
+ /* ... while cmp_type() specifies how it should be compared */
+ virtual Item_result cmp_type() const;
+ virtual Item_result cast_to_int_type() const { return cmp_type(); }
virtual enum_field_types string_field_type() const;
virtual enum_field_types field_type() const;
virtual enum Type type() const =0;
+ /*
+ real_type() is the type of base item. This is same as type() for
+ most items, except Item_ref() and Item_cache_wrapper() where it
+ shows the type for the underlaying item.
+ */
+ virtual enum Type real_type() const { return type(); }
/*
Return information about function monotonicity. See comment for
@@ -742,10 +807,22 @@ 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);
String *val_string_from_decimal(String *str);
+ String *val_string_from_date(String *str);
my_decimal *val_decimal_from_real(my_decimal *decimal_value);
my_decimal *val_decimal_from_int(my_decimal *decimal_value);
my_decimal *val_decimal_from_string(my_decimal *decimal_value);
@@ -762,6 +839,8 @@ public:
/* This is also used to create fields in CREATE ... SELECT: */
virtual Field *tmp_table_field(TABLE *t_arg) { return 0; }
virtual const char *full_name() const { return name ? name : "???"; }
+ const char *field_name_or_null()
+ { return real_item()->type() == Item::FIELD_ITEM ? name : NULL; }
/*
*result* family of methods is analog of *val* family (see above) but
@@ -776,13 +855,18 @@ public:
{ return val_decimal(val); }
virtual bool val_bool_result() { return val_bool(); }
virtual bool is_null_result() { return is_null(); }
-
+ /*
+ Returns 1 if result type and collation for val_str() can change between
+ calls
+ */
+ virtual bool dynamic_result() { return 0; }
/*
Bitmap of tables used by item
(note: if you need to check dependencies on individual columns, check out
class Field_enumerator)
*/
virtual table_map used_tables() const { return (table_map) 0L; }
+ virtual table_map all_used_tables() const { return used_tables(); }
/*
Return table map of tables that can't be NULL tables (tables that are
used in a context where if they would contain a NULL row generated
@@ -837,6 +921,7 @@ public:
}
void print_item_w_name(String *, enum_query_type query_type);
+ void print_value(String *);
virtual void update_used_tables() {}
virtual void split_sum_func(THD *thd, Item **ref_pointer_array,
List<Item> &fields) {}
@@ -844,7 +929,9 @@ public:
void split_sum_func2(THD *thd, Item **ref_pointer_array, List<Item> &fields,
Item **ref, bool skip_registered);
virtual bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
- virtual bool get_time(MYSQL_TIME *ltime);
+ bool get_time(MYSQL_TIME *ltime)
+ { return get_date(ltime, TIME_TIME_ONLY | TIME_FUZZY_DATE); }
+ bool get_seconds(ulonglong *sec, ulong *sec_part);
virtual bool get_date_result(MYSQL_TIME *ltime,uint fuzzydate)
{ return get_date(ltime,fuzzydate); }
/*
@@ -934,13 +1021,25 @@ 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; }
virtual bool is_expensive_processor(uchar *arg) { return 0; }
virtual bool register_field_in_read_map(uchar *arg) { return 0; }
+ virtual bool register_field_in_write_map(uchar *arg) { return 0; }
virtual bool enumerate_field_refs_processor(uchar *arg) { return 0; }
virtual bool mark_as_eliminated_processor(uchar *arg) { return 0; }
+ virtual bool eliminate_subselect_processor(uchar *arg) { return 0; }
+ virtual bool set_fake_select_as_master_processor(uchar *arg) { return 0; }
+ virtual bool update_table_bitmaps_processor(uchar *arg) { return 0; }
+ virtual bool view_used_tables_processor(uchar *arg) { return 0; }
+ virtual bool eval_not_null_tables(uchar *opt_arg) { return 0; }
+ virtual bool is_subquery_processor (uchar *opt_arg) { return 0; }
+ virtual bool limit_index_condition_pushdown_processor(uchar *opt_arg)
+ {
+ return FALSE;
+ }
/* To call bool function for all arguments */
struct bool_func_call_args
@@ -956,6 +1055,7 @@ public:
(this->*(info->bool_function))();
return FALSE;
}
+
/*
The next function differs from the previous one that a bitmap to be updated
is passed as uchar *arg.
@@ -1028,12 +1128,23 @@ public:
return FALSE;
}
+ /*
+ The enumeration Subst_constraint is currently used only in implementations
+ of the virtual function subst_argument_checker.
+ */
+ enum Subst_constraint
+ {
+ NO_SUBST= 0, /* No substitution for a field is allowed */
+ ANY_SUBST, /* Any substitution for a field is allowed */
+ IDENTITY_SUBST /* Substitution for a field is allowed if any two
+ different values of the field type are not equal */
+ };
+
virtual bool subst_argument_checker(uchar **arg)
- {
- if (*arg)
- *arg= NULL;
- return TRUE;
+ {
+ return (*arg != NULL);
}
+
/*
@brief
Processor used to check acceptability of an item in the defining
@@ -1054,6 +1165,7 @@ public:
virtual Item *equal_fields_propagator(uchar * arg) { return this; }
virtual bool set_no_const_sub(uchar *arg) { return FALSE; }
+ /* arg points to REPLACE_EQUAL_FIELD_ARG object */
virtual Item *replace_equal_field(uchar * arg) { return this; }
/*
Check if an expression value has allowed arguments, like DATE/DATETIME
@@ -1064,6 +1176,17 @@ public:
{
return FALSE;
}
+ struct Collect_deps_prm
+ {
+ List<Item> *parameters;
+ /* unit from which we count nest_level */
+ st_select_lex_unit *nest_level_base;
+ int nest_level;
+ };
+ /**
+ Collect outer references
+ */
+ virtual bool collect_outer_ref_processor(uchar *arg) {return FALSE; }
/**
Find a function of a given type
@@ -1112,6 +1235,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()
{
@@ -1129,24 +1254,82 @@ public:
{
return 0;
}
+
/*
- result_as_longlong() must return TRUE for Items representing DATE/TIME
- functions and DATE/TIME table fields.
- Those Items have result_type()==STRING_RESULT (and not INT_RESULT), but
- their values should be compared as integers (because the integer
- representation is more precise than the string one).
+ 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 result_as_longlong() { return FALSE; }
- bool is_datetime();
+ 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);
+ virtual Item *get_cached_item() { return NULL; }
+
+ virtual Item_equal *get_item_equal() { return NULL; }
+ virtual void set_item_equal(Item_equal *item_eq) {};
+ virtual Item_equal *find_item_equal(COND_EQUAL *cond_equal) { return NULL; }
+ /**
+ Set the join tab index to the minimal (left-most) JOIN_TAB to which this
+ Item is attached. The number is an index is depth_first_tab() traversal
+ order.
+ */
+ virtual void set_join_tab_idx(uint join_tab_idx_arg)
+ {
+ if (join_tab_idx_arg < join_tab_idx)
+ join_tab_idx= join_tab_idx_arg;
+ }
+ virtual uint get_join_tab_idx() { return join_tab_idx; }
+
+ table_map view_used_tables(TABLE_LIST *view)
+ {
+ view->view_used_tables= 0;
+ walk(&Item::view_used_tables_processor, 0, (uchar *) view);
+ return view->view_used_tables;
+ }
+
+ /**
+ Collect and add to the list cache parameters for this Item.
+
+ @note Now implemented only for subqueries and in_optimizer,
+ if we need it for general function then this method should
+ be defined for Item_func.
+ */
+ virtual void get_cache_parameters(List<Item> &parameters) { };
+
+ virtual void mark_as_condition_AND_part(TABLE_LIST *embedding) {};
};
+/**
+ Compare two Items for List<Item>::add_unique()
+*/
+
+bool cmp_items(Item *a, Item *b);
+
+
/*
- Class to be used to enumerate all field references in an item tree.
+ 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
@@ -1163,7 +1346,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 */
};
@@ -1519,6 +1702,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);
@@ -1526,10 +1722,15 @@ public:
Item_ident(TABLE_LIST *view_arg, const char *field_name_arg);
const char *full_name() const;
void cleanup();
+ st_select_lex *get_depended_from() const;
bool remove_dependence_processor(uchar * arg);
virtual void print(String *str, enum_query_type query_type);
virtual bool change_context_processor(uchar *cntx)
{ context= (Name_resolution_context *)cntx; return FALSE; }
+ /**
+ Collect outer references
+ */
+ virtual bool collect_outer_ref_processor(uchar *arg);
friend bool insert_fields(THD *thd, Name_resolution_context *context,
const char *db_name,
const char *table_name, List_iterator<Item> *it,
@@ -1558,9 +1759,6 @@ public:
};
-class Item_equal;
-class COND_EQUAL;
-
class Item_field :public Item_ident
{
protected:
@@ -1601,6 +1799,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);
@@ -1610,17 +1809,19 @@ 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);
table_map used_tables() const;
+ table_map all_used_tables() const;
enum Item_result result_type () const
{
return field->result_type();
}
Item_result cast_to_int_type() const
{
- return field->cast_to_int_type();
+ return field->cmp_type();
}
enum_field_types field_type() const
{
@@ -1635,23 +1836,42 @@ public:
Field *tmp_table_field(TABLE *t_arg) { return result_field; }
bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
bool get_date_result(MYSQL_TIME *ltime,uint fuzzydate);
- bool get_time(MYSQL_TIME *ltime);
bool is_null() { return field->is_null(); }
void update_null_value();
+ void update_table_bitmaps()
+ {
+ if (field && field->table)
+ {
+ TABLE *tab= field->table;
+ tab->covering_keys.intersect(field->part_of_key);
+ tab->merge_keys.merge(field->part_of_key);
+ if (tab->read_set)
+ bitmap_fast_test_and_set(tab->read_set, field->field_index);
+ if (field->vcol_info)
+ tab->mark_virtual_col(field);
+ }
+ }
+ void update_used_tables()
+ {
+ update_table_bitmaps();
+ if (field && field->table)
+ maybe_null|= field->maybe_null();
+ }
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_write_map(uchar *arg);
bool register_field_in_bitmap(uchar *arg);
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool vcol_in_partition_func_processor(uchar *bool_arg);
bool check_vcol_func_processor(uchar *arg) { return FALSE;}
bool enumerate_field_refs_processor(uchar *arg);
+ bool update_table_bitmaps_processor(uchar *arg);
void cleanup();
- bool result_as_longlong()
- {
- return field->can_be_compared_as_longlong();
- }
+ Item_equal *get_item_equal() { return item_equal; }
+ void set_item_equal(Item_equal *item_eq) { item_equal= item_eq; }
Item_equal *find_item_equal(COND_EQUAL *cond_equal);
bool subst_argument_checker(uchar **arg);
Item *equal_fields_propagator(uchar *arg);
@@ -1801,6 +2021,7 @@ public:
Item_param(uint pos_in_query_arg);
enum Item_result result_type () const { return item_result_type; }
+ enum Item_result cast_to_int_type() const { return item_result_type; }
enum Type type() const { return item_type; }
enum_field_types field_type() const { return param_type; }
@@ -1808,7 +2029,6 @@ public:
longlong val_int();
my_decimal *val_decimal(my_decimal*);
String *val_str(String*);
- bool get_time(MYSQL_TIME *tm);
bool get_date(MYSQL_TIME *tm, uint fuzzydate);
int save_in_field(Field *field, bool no_conversions);
@@ -1909,18 +2129,28 @@ class Item_uint :public Item_int
{
public:
Item_uint(const char *str_arg, uint length);
- Item_uint(ulonglong i) :Item_int((ulonglong) i, 10) {}
+ Item_uint(ulonglong i) :Item_int(i, 10) {}
Item_uint(const char *str_arg, longlong i, uint length);
double val_real()
{ DBUG_ASSERT(fixed == 1); return ulonglong2double((ulonglong)value); }
String *val_str(String*);
Item *clone_item() { return new Item_uint(name, value, max_length); }
- int save_in_field(Field *field, bool no_conversions);
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;}
+};
+
+
+class Item_datetime :public Item_int
+{
+protected:
+ MYSQL_TIME ltime;
+public:
+ Item_datetime() :Item_int(0) { unsigned_flag=0; }
+ int save_in_field(Field *field, bool no_conversions);
+ longlong val_int();
+ double val_real() { return (double)val_int(); }
+ void set(longlong packed);
};
@@ -2167,9 +2397,11 @@ private:
longlong
-longlong_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end);
+longlong_from_string_with_check(CHARSET_INFO *cs, const char *cptr,
+ const char *end);
double
-double_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end);
+double_from_string_with_check(CHARSET_INFO *cs, const char *cptr,
+ const char *end);
class Item_static_string_func :public Item_string
{
@@ -2214,10 +2446,11 @@ class Item_return_date_time :public Item_partition_func_safe_string
{
enum_field_types date_time_field_type;
public:
- Item_return_date_time(const char *name_arg, enum_field_types field_type_arg)
- :Item_partition_func_safe_string(name_arg, 0, &my_charset_bin),
+ Item_return_date_time(const char *name_arg, uint length_arg,
+ enum_field_types field_type_arg)
+ :Item_partition_func_safe_string(name_arg, length_arg, &my_charset_bin),
date_time_field_type(field_type_arg)
- { }
+ { decimals= 0; }
enum_field_types field_type() const { return date_time_field_type; }
};
@@ -2348,11 +2581,12 @@ public:
enum Ref_Type { REF, DIRECT_REF, VIEW_REF, OUTER_REF, AGGREGATE_REF };
Field *result_field; /* Save result here */
Item **ref;
+ bool reference_trough_name;
Item_ref(Name_resolution_context *context_arg,
const char *db_arg, const char *table_name_arg,
const char *field_name_arg)
:Item_ident(context_arg, db_arg, table_name_arg, field_name_arg),
- result_field(0), ref(0) {}
+ result_field(0), ref(0), reference_trough_name(1) {}
/*
This constructor is used in two scenarios:
A) *item = NULL
@@ -2377,11 +2611,15 @@ public:
Item_ref(THD *thd, Item_ref *item)
:Item_ident(thd, item), result_field(item->result_field), ref(item->ref) {}
enum Type type() const { return REF_ITEM; }
+ enum Type real_type() const { return ref ? (*ref)->type() :
+ REF_ITEM; }
bool eq(const Item *item, bool binary_cmp) const
{
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 *);
@@ -2398,6 +2636,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(); }
@@ -2405,20 +2644,16 @@ public:
Field *get_tmp_table_field()
{ return result_field ? result_field : (*ref)->get_tmp_table_field(); }
Item *get_tmp_table_item(THD *thd);
- table_map used_tables() const
- {
- return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables();
- }
- void update_used_tables()
- {
- if (!depended_from)
- (*ref)->update_used_tables();
- }
+ table_map used_tables() const;
+ void update_used_tables();
bool const_item() const
{
return (*ref)->const_item();
}
- table_map not_null_tables() const { return (*ref)->not_null_tables(); }
+ table_map not_null_tables() const
+ {
+ return depended_from ? 0 : (*ref)->not_null_tables();
+ }
void set_result_field(Field *field) { result_field= field; }
bool is_result_field() { return 1; }
void save_in_result_field(bool no_conversions)
@@ -2430,10 +2665,18 @@ 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;
}
+ Item* transform(Item_transformer, uchar *arg);
+ Item* compile(Item_analyzer analyzer, uchar **arg_p,
+ Item_transformer transformer, uchar *arg_t);
+ bool enumerate_field_refs_processor(uchar *arg)
+ { return (*ref)->enumerate_field_refs_processor(arg); }
void no_rows_in_result()
{
(*ref)->no_rows_in_result();
@@ -2443,10 +2686,6 @@ public:
(*ref)->restore_to_before_no_rows_in_result();
}
virtual void print(String *str, enum_query_type query_type);
- bool result_as_longlong()
- {
- return (*ref)->result_as_longlong();
- }
void cleanup();
Item_field *filed_for_view_update()
{ return (*ref)->filed_for_view_update(); }
@@ -2483,11 +2722,6 @@ public:
{
return trace_unsupported_by_check_vcol_func_processor("ref");
}
- bool get_time(MYSQL_TIME *ltime)
- {
- DBUG_ASSERT(fixed);
- return (*ref)->get_time(ltime);
- }
};
@@ -2514,6 +2748,7 @@ public:
alias_name_used_arg)
{}
+ void save_val(Field *to);
double val_real();
longlong val_int();
String *val_str(String* tmp);
@@ -2524,24 +2759,204 @@ public:
virtual Ref_Type ref_type() { return DIRECT_REF; }
};
+
+/**
+ This class is the same as Item_direct_ref but created to wrap Item_ident
+ before fix_fields() call
+*/
+
+class Item_direct_ref_to_ident :public Item_direct_ref
+{
+ Item_ident *ident;
+public:
+ Item_direct_ref_to_ident(Item_ident *item)
+ :Item_direct_ref(item->context, (Item**)&item, item->table_name, item->field_name,
+ FALSE)
+ {
+ ident= item;
+ ref= (Item**)&ident;
+ }
+
+ bool fix_fields(THD *thd, Item **it)
+ {
+ DBUG_ASSERT(ident->type() == FIELD_ITEM || ident->type() == REF_ITEM);
+ if ((!ident->fixed && ident->fix_fields(thd, ref)) ||
+ ident->check_cols(1))
+ return TRUE;
+ set_properties();
+ return FALSE;
+ }
+
+ virtual void print(String *str, enum_query_type query_type)
+ { ident->print(str, query_type); }
+
+};
+
+
+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;
+
+ List<Item> parameters;
+
+ Item *check_cache();
+ void cache();
+ void init_on_demand();
+
+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; }
+ enum Type real_type() const { return orig_item->type(); }
+
+ bool set_cache(THD *thd);
+
+ 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 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();
+ maybe_null|= orig_item->maybe_null;
+ }
+ 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); }
+ 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();
+ }
+ virtual bool is_expensive() { return orig_item->is_expensive(); }
+ bool is_expensive_processor(uchar *arg)
+ { return orig_item->is_expensive_processor(arg); }
+ bool check_vcol_func_processor(uchar *arg)
+ {
+ return trace_unsupported_by_check_vcol_func_processor("cache");
+ }
+};
+
+
/*
Class for view fields, the same as Item_direct_ref, but call fix_fields
of reference if it is not called yet
*/
class Item_direct_view_ref :public Item_direct_ref
{
+ Item_equal *item_equal;
+ TABLE_LIST *view;
+ TABLE *null_ref_table;
+
+ bool check_null_ref()
+ {
+ if (null_ref_table == NULL)
+ {
+ null_ref_table= view->get_real_join_table();
+ }
+ if (null_ref_table->null_row)
+ {
+ null_value= 1;
+ return TRUE;
+ }
+ return FALSE;
+ }
public:
Item_direct_view_ref(Name_resolution_context *context_arg, Item **item,
- const char *table_name_arg,
- const char *field_name_arg)
- :Item_direct_ref(context_arg, item, table_name_arg, field_name_arg) {}
- /* Constructor need to process subselect with temporary tables (see Item) */
- Item_direct_view_ref(THD *thd, Item_direct_ref *item)
- :Item_direct_ref(thd, item) {}
- Item_direct_view_ref(TABLE_LIST *view_arg, Item **item,
- const char *field_name_arg)
- :Item_direct_ref(view_arg, item, field_name_arg)
- {}
+ const char *table_name_arg,
+ const char *field_name_arg,
+ TABLE_LIST *view_arg)
+ :Item_direct_ref(context_arg, item, table_name_arg, field_name_arg),
+ item_equal(0), view(view_arg),
+ null_ref_table(NULL) {}
bool fix_fields(THD *, Item **);
bool eq(const Item *item, bool binary_cmp) const;
@@ -2552,6 +2967,111 @@ public:
return item;
}
virtual Ref_Type ref_type() { return VIEW_REF; }
+ Item_equal *get_item_equal() { return item_equal; }
+ void set_item_equal(Item_equal *item_eq) { item_equal= item_eq; }
+ Item_equal *find_item_equal(COND_EQUAL *cond_equal);
+ bool subst_argument_checker(uchar **arg);
+ Item *equal_fields_propagator(uchar *arg);
+ Item *replace_equal_field(uchar *arg);
+ table_map used_tables() const;
+ table_map not_null_tables() const;
+ void update_used_tables();
+ bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
+ {
+ return (*ref)->walk(processor, walk_subquery, arg) ||
+ (this->*processor)(arg);
+ }
+ bool view_used_tables_processor(uchar *arg)
+ {
+ TABLE_LIST *view_arg= (TABLE_LIST *) arg;
+ if (view_arg == view)
+ view_arg->view_used_tables|= (*ref)->used_tables();
+ return 0;
+ }
+ void save_val(Field *to)
+ {
+ if (check_null_ref())
+ to->set_null();
+ else
+ Item_direct_ref::save_val(to);
+ }
+ double val_real()
+ {
+ if (check_null_ref())
+ return 0;
+ else
+ return Item_direct_ref::val_real();
+ }
+ longlong val_int()
+ {
+ if (check_null_ref())
+ return 0;
+ else
+ return Item_direct_ref::val_int();
+ }
+ String *val_str(String* tmp)
+ {
+ if (check_null_ref())
+ return NULL;
+ else
+ return Item_direct_ref::val_str(tmp);
+ }
+ my_decimal *val_decimal(my_decimal *tmp)
+ {
+ if (check_null_ref())
+ return NULL;
+ else
+ return Item_direct_ref::val_decimal(tmp);
+ }
+ bool val_bool()
+ {
+ if (check_null_ref())
+ return 0;
+ else
+ return Item_direct_ref::val_bool();
+ }
+ bool is_null()
+ {
+ if (check_null_ref())
+ return 1;
+ else
+ return Item_direct_ref::is_null();
+ }
+ bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
+ {
+ if (check_null_ref())
+ {
+ bzero((char*) ltime,sizeof(*ltime));
+ return 1;
+ }
+ return Item_direct_ref::get_date(ltime, fuzzydate);
+ }
+ bool send(Protocol *protocol, String *buffer)
+ {
+ if (check_null_ref())
+ return protocol->store_null();
+ return Item_direct_ref::send(protocol, buffer);
+ }
+ void save_org_in_field(Field *field)
+ {
+ if (check_null_ref())
+ field->set_null();
+ else
+ Item_direct_ref::save_val(field);
+ }
+ void save_in_result_field(bool no_conversions)
+ {
+ if (check_null_ref())
+ result_field->set_null();
+ else
+ Item_direct_ref::save_in_result_field(no_conversions);
+ }
+
+ void cleanup()
+ {
+ null_ref_table= NULL;
+ Item_direct_ref::cleanup();
+ }
};
@@ -2601,6 +3121,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;
@@ -2633,6 +3154,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);
@@ -2640,15 +3162,7 @@ public:
bool val_bool();
bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
virtual void print(String *str, enum_query_type query_type);
- /*
- we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
- */
- table_map used_tables() const
- {
- return (depended_from ?
- OUTER_REF_TABLE_BIT :
- (*ref)->used_tables() | RAND_TABLE_BIT);
- }
+ table_map used_tables() const;
};
/*
@@ -2895,6 +3409,28 @@ 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.
+*/
+
+/*
+ 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:
@@ -2951,9 +3487,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);
@@ -3131,6 +3668,13 @@ private:
};
+/**
+ @todo
+ Implement the is_null() method for this class. Currently calling is_null()
+ on any Item_cache object resolves to Item::is_null(), which reutns FALSE
+ for any value.
+*/
+
class Item_cache: public Item_basic_constant
{
protected:
@@ -3156,7 +3700,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):
@@ -3164,6 +3709,7 @@ public:
value_cached(0)
{
fixed= 1;
+ maybe_null= 1;
null_value= 1;
}
@@ -3210,6 +3756,22 @@ public:
virtual void store(Item *item);
virtual bool cache_value()= 0;
+ bool is_null() { return null_value; }
+ virtual bool is_expensive()
+ {
+ DBUG_ASSERT(example);
+ if (value_cached)
+ return false;
+ return example->is_expensive();
+ }
+ bool is_expensive_processor(uchar *arg)
+ {
+ DBUG_ASSERT(example);
+ if (value_cached)
+ return false;
+ return example->is_expensive_processor(arg);
+ }
+ virtual void set_null();
};
@@ -3218,28 +3780,54 @@ class Item_cache_int: public Item_cache
protected:
longlong value;
public:
- Item_cache_int(): Item_cache(),
+ Item_cache_int(): Item_cache(MYSQL_TYPE_LONGLONG),
value(0) {}
Item_cache_int(enum_field_types field_type_arg):
Item_cache(field_type_arg), value(0) {}
- virtual void store(Item *item){ Item_cache::store(item); }
- void store_longlong(Item *item, longlong val_arg);
double val_real();
longlong val_int();
String* val_str(String *str);
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type() const { return INT_RESULT; }
- bool result_as_longlong() { return TRUE; }
bool cache_value();
+ int save_in_field(Field *field, bool no_conversions);
};
+class Item_cache_temporal: public Item_cache_int
+{
+public:
+ Item_cache_temporal(enum_field_types field_type_arg):
+ Item_cache_int(field_type_arg)
+ {
+ if (mysql_type_to_time_type(cached_field_type) == MYSQL_TIMESTAMP_ERROR)
+ cached_field_type= MYSQL_TYPE_DATETIME;
+ }
+
+ String* val_str(String *str);
+ bool cache_value();
+ bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
+ int save_in_field(Field *field, bool no_conversions);
+ void store_packed(longlong val_arg, Item *example);
+ /*
+ Having a clone_item method tells optimizer that this object
+ is a constant and need not be optimized further.
+ Important when storing packed datetime values.
+ */
+ Item *clone_item()
+ {
+ Item_cache_temporal *item= new Item_cache_temporal(cached_field_type);
+ item->store_packed(value, example);
+ return item;
+ }
+};
+
class Item_cache_real: public Item_cache
{
double value;
public:
- Item_cache_real(): Item_cache(),
+ Item_cache_real(): Item_cache(MYSQL_TYPE_DOUBLE),
value(0) {}
double val_real();
@@ -3256,7 +3844,7 @@ class Item_cache_decimal: public Item_cache
protected:
my_decimal decimal_value;
public:
- Item_cache_decimal(): Item_cache() {}
+ Item_cache_decimal(): Item_cache(MYSQL_TYPE_NEWDECIMAL) {}
double val_real();
longlong val_int();
@@ -3358,6 +3946,7 @@ public:
DBUG_VOID_RETURN;
}
bool cache_value();
+ virtual void set_null();
};
@@ -3404,7 +3993,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 798756ed9ef..f09ca08cc84 100644
--- a/sql/item_buff.cc
+++ b/sql/item_buff.cc
@@ -29,11 +29,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);
@@ -119,14 +123,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 0480f66854c..1aaedf3a6ad 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -30,11 +30,6 @@
#include <m_ctype.h>
#include "sql_select.h"
-static bool convert_constant_item(THD *, Item_field *, Item **);
-static longlong
-get_year_value(THD *thd, Item ***item_arg, Item **cache_arg,
- Item *warn_item, bool *is_null);
-
static Item_result item_store_type(Item_result a, Item *item,
my_bool unsigned_flag)
{
@@ -77,6 +72,30 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
}
+/**
+ find an temporal type (item) that others will be converted to
+ for the purpose of comparison.
+
+ this is the type that will be used in warnings like
+ "Incorrect <<TYPE>> value".
+*/
+Item *find_date_time_item(Item **args, uint nargs, uint col)
+{
+ Item *date_arg= 0, **arg, **arg_end;
+ for (arg= args, arg_end= args + nargs; arg != arg_end ; arg++)
+ {
+ Item *item= arg[0]->element_index(col);
+ if (item->cmp_type() != TIME_RESULT)
+ continue;
+ if (item->field_type() == MYSQL_TYPE_DATETIME)
+ return item;
+ if (!date_arg)
+ date_arg= item;
+ }
+ return date_arg;
+}
+
+
/*
Compare row signature of two expressions
@@ -139,10 +158,10 @@ static int cmp_row_type(Item* item1, Item* item2)
static int agg_cmp_type(Item_result *type, Item **items, uint nitems)
{
uint i;
- type[0]= items[0]->result_type();
+ type[0]= items[0]->cmp_type();
for (i= 1 ; i < nitems ; i++)
{
- type[0]= item_cmp_type(type[0], items[i]->result_type());
+ type[0]= item_cmp_type(type[0], items[i]->cmp_type());
/*
When aggregating types of two row expressions we have to check
that they have the same cardinality and that each component
@@ -208,7 +227,7 @@ static uint collect_cmp_types(Item **items, uint nitems, bool skip_nulls= FALSE)
{
uint i;
uint found_types;
- Item_result left_result= items[0]->result_type();
+ Item_result left_result= items[0]->cmp_type();
DBUG_ASSERT(nitems > 1);
found_types= 0;
for (i= 1; i < nitems ; i++)
@@ -216,11 +235,11 @@ static uint collect_cmp_types(Item **items, uint nitems, bool skip_nulls= FALSE)
if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
continue; // Skip NULL constant items
if ((left_result == ROW_RESULT ||
- items[i]->result_type() == ROW_RESULT) &&
+ items[i]->cmp_type() == ROW_RESULT) &&
cmp_row_type(items[0], items[i]))
return 0;
found_types|= 1<< (uint)item_cmp_type(left_result,
- items[i]->result_type());
+ items[i]->cmp_type());
}
/*
Even if all right-hand items are NULLs and we are skipping them all, we need
@@ -421,12 +440,29 @@ longlong Item_func_nop_all::val_int()
1 Item was replaced with an integer version of the item
*/
-static bool convert_constant_item(THD *thd, Item_field *field_item,
+static bool convert_const_to_int(THD *thd, Item_field *field_item,
Item **item)
{
Field *field= field_item->field;
int result= 0;
+ /*
+ We don't need to convert an integer to an integer,
+ pretend it's already converted.
+
+ But we still convert it if it is compared with a Field_year,
+ as YEAR(2) may change the value of an integer when converting it
+ to an integer (say, 0 to 70).
+
+ As a special hack, to avoid reevaluation of stored routines
+ where 5.2 didn't reevaluate them, we "convert" for BIGINT too.
+ In 5.5 it isn't necessary, as it caches constant expressions correctly.
+ */
+ if ((*item)->cmp_type() == INT_RESULT &&
+ field_item->field_type() != MYSQL_TYPE_YEAR &&
+ field_item->field_type() != MYSQL_TYPE_LONGLONG)
+ return 1;
+
if ((*item)->const_item())
{
TABLE *table= field->table;
@@ -448,14 +484,12 @@ static bool convert_constant_item(THD *thd, Item_field *field_item,
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
/*
- Store the value of the field/constant if it references an outer field
- because the call to save_in_field below overrides that value.
- Don't save field value if no data has been read yet.
- Outer constant values are always saved.
+ Store the value of the field/constant because the call to save_in_field
+ below overrides that value. Don't save field value if no data has been
+ read yet.
*/
- bool save_field_value= (field_item->depended_from &&
- (field_item->const_item() ||
- !(field->table->status & STATUS_NO_RECORD)));
+ bool save_field_value= (field_item->const_item() ||
+ !(field->table->status & STATUS_NO_RECORD));
if (save_field_value)
orig_field_val= field->val_int();
if (!(*item)->is_null() && !(*item)->save_in_field(field, 1))
@@ -485,7 +519,6 @@ static bool convert_constant_item(THD *thd, Item_field *field_item,
void Item_bool_func2::fix_length_and_dec()
{
max_length= 1; // Function returns 0 or 1
- THD *thd;
/*
As some compare functions are generated after sql_yacc,
@@ -506,7 +539,6 @@ void Item_bool_func2::fix_length_and_dec()
to the collation of A.
*/
-
DTCollation coll;
if (args[0]->result_type() == STRING_RESULT &&
args[1]->result_type() == STRING_RESULT &&
@@ -515,48 +547,28 @@ void Item_bool_func2::fix_length_and_dec()
args[0]->cmp_context= args[1]->cmp_context=
item_cmp_type(args[0]->result_type(), args[1]->result_type());
- // Make a special case of compare with fields to get nicer DATE comparisons
- if (functype() == LIKE_FUNC) // Disable conversion in case of LIKE function.
- {
- set_cmp_func();
- return;
- }
+ /*
+ Make a special case of compare with fields to get nicer comparisons
+ of bigint numbers with constant string.
+ This directly contradicts the manual (number and a string should
+ be compared as doubles), but seems to provide more
+ "intuitive" behavior in some cases (but less intuitive in others).
- thd= current_thd;
- if (!thd->lex->is_ps_or_view_context_analysis())
+ But disable conversion in case of LIKE function.
+ */
+ THD *thd= current_thd;
+ if (functype() != LIKE_FUNC && !thd->lex->is_ps_or_view_context_analysis())
{
- if (args[0]->real_item()->type() == FIELD_ITEM)
+ int field;
+ if (args[field= 0]->real_item()->type() == FIELD_ITEM ||
+ args[field= 1]->real_item()->type() == FIELD_ITEM)
{
- Item_field *field_item= (Item_field*) (args[0]->real_item());
- if (field_item->field->can_be_compared_as_longlong() &&
- !(field_item->is_datetime() &&
- args[1]->result_type() == STRING_RESULT))
- {
- if (convert_constant_item(thd, field_item, &args[1]))
- {
- cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
- INT_RESULT); // Works for all types.
- args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
- return;
- }
- }
- }
- if (args[1]->real_item()->type() == FIELD_ITEM)
- {
- Item_field *field_item= (Item_field*) (args[1]->real_item());
- if (field_item->field->can_be_compared_as_longlong() &&
- !(field_item->is_datetime() &&
- args[0]->result_type() == STRING_RESULT))
- {
- if (convert_constant_item(thd, field_item, &args[0]))
- {
- cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
- INT_RESULT); // Works for all types.
- args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
- return;
- }
- }
+ Item_field *field_item= (Item_field*) (args[field]->real_item());
+ if ((field_item->field_type() == MYSQL_TYPE_LONGLONG ||
+ field_item->field_type() == MYSQL_TYPE_YEAR) &&
+ convert_const_to_int(thd, field_item, &args[!field]))
+ args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
}
}
set_cmp_func();
@@ -570,6 +582,8 @@ int Arg_comparator::set_compare_func(Item_result_field *item, Item_result type)
[is_owner_equal_func()];
switch (type) {
+ case TIME_RESULT:
+ break;
case ROW_RESULT:
{
uint n= (*a)->cols();
@@ -663,8 +677,9 @@ int Arg_comparator::set_compare_func(Item_result_field *item, Item_result type)
}
break;
}
- default:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
+ break;
}
return 0;
}
@@ -678,12 +693,14 @@ int Arg_comparator::set_compare_func(Item_result_field *item, Item_result type)
@param[in] warn_name Field name for issuing the warning
@param[out] l_time The MYSQL_TIME objects is initialized.
- Parses a date provided in the string str into a MYSQL_TIME object. If the
- string contains an incorrect date or doesn't correspond to a date at all
- then a warning is issued. The warn_type and the warn_name arguments are used
- as the name and the type of the field when issuing the warning. If any input
- was discarded (trailing or non-timestamp-y characters), return value will be
- TRUE.
+ Parses a date provided in the string str into a MYSQL_TIME object.
+ The date is used for comparison, that is fuzzy dates are allowed
+ independently of sql_mode.
+ If the string contains an incorrect date or doesn't correspond to a date at
+ all then a warning is issued. The warn_type and the warn_name arguments are
+ used as the name and the type of the field when issuing the warning. If any
+ input was discarded (trailing or non-timestamp-y characters), return value
+ will be TRUE.
@return Status flag
@retval FALSE Success.
@@ -696,16 +713,15 @@ bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
bool value;
int error;
enum_mysql_timestamp_type timestamp_type;
+ int flags= TIME_FUZZY_DATE | MODE_INVALID_DATES;
+
+ if (warn_type == MYSQL_TIMESTAMP_TIME)
+ flags|= TIME_TIME_ONLY;
timestamp_type=
- str_to_datetime(str->ptr(), str->length(), l_time,
- (TIME_FUZZY_DATE | MODE_INVALID_DATES |
- (thd->variables.sql_mode &
- (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))),
- &error);
-
- if (timestamp_type == MYSQL_TIMESTAMP_DATETIME ||
- timestamp_type == MYSQL_TIMESTAMP_DATE)
+ str_to_datetime(str->ptr(), str->length(), l_time, flags, &error);
+
+ if (timestamp_type > MYSQL_TIMESTAMP_ERROR)
/*
Do not return yet, we may still want to throw a "trailing garbage"
warning.
@@ -727,264 +743,31 @@ bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
/**
- @brief Convert date provided in a string to the int representation.
-
- @param[in] thd thread handle
- @param[in] str a string to convert
- @param[in] warn_type type of the timestamp for issuing the warning
- @param[in] warn_name field name for issuing the warning
- @param[out] error_arg could not extract a DATE or DATETIME
+ Prepare the comparator (set the comparison function) for comparing
+ items *a1 and *a2 in the context of 'type'.
- @details Convert date provided in the string str to the int
- representation. If the string contains wrong date or doesn't
- contain it at all then a warning is issued. The warn_type and
- the warn_name arguments are used as the name and the type of the
- field when issuing the warning.
+ @param[in] owner_arg Item, peforming the comparison (e.g. Item_func_eq)
+ @param[in,out] a1 first argument to compare
+ @param[in,out] a2 second argument to compare
+ @param[in] type type context to compare in
- @return
- converted value. 0 on error and on zero-dates -- check 'failure'
+ Both *a1 and *a2 can be replaced by this method - typically by constant
+ items, holding the cached converted value of the original (constant) item.
*/
-static ulonglong get_date_from_str(THD *thd, String *str,
- timestamp_type warn_type,
- const char *warn_name, bool *error_arg)
-{
- MYSQL_TIME l_time;
- *error_arg= get_mysql_time_from_str(thd, str, warn_type, warn_name, &l_time);
-
- if (*error_arg)
- return 0;
- return TIME_to_ulonglong_datetime(&l_time);
-}
-
-
-/*
- Check whether compare_datetime() can be used to compare items.
-
- SYNOPSIS
- Arg_comparator::can_compare_as_dates()
- a, b [in] items to be compared
- const_value [out] converted value of the string constant, if any
-
- DESCRIPTION
- Check several cases when the DATE/DATETIME comparator should be used.
- The following cases are checked:
- 1. Both a and b is a DATE/DATETIME field/function returning string or
- int result.
- 2. Only a or b is a DATE/DATETIME field/function returning string or
- int result and the other item (b or a) is an item with string result.
- If the second item is a constant one then it's checked to be
- convertible to the DATE/DATETIME type. If the constant can't be
- converted to a DATE/DATETIME then the compare_datetime() comparator
- isn't used and the warning about wrong DATE/DATETIME value is issued.
- In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
- the comparison is handled by other comparators.
- If the datetime comparator can be used and one the operands of the
- comparison is a string constant that was successfully converted to a
- DATE/DATETIME type then the result of the conversion is returned in the
- const_value if it is provided. If there is no constant or
- compare_datetime() isn't applicable then the *const_value remains
- unchanged.
-
- RETURN
- the found type of date comparison
-*/
-
-enum Arg_comparator::enum_date_cmp_type
-Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value)
-{
- enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
- Item *str_arg= 0, *date_arg= 0;
-
- if (a->type() == Item::ROW_ITEM || b->type() == Item::ROW_ITEM)
- return CMP_DATE_DFLT;
-
- if (a->is_datetime())
- {
- if (b->is_datetime())
- cmp_type= CMP_DATE_WITH_DATE;
- else if (b->result_type() == STRING_RESULT)
- {
- cmp_type= CMP_DATE_WITH_STR;
- date_arg= a;
- str_arg= b;
- }
- }
- else if (b->is_datetime() && a->result_type() == STRING_RESULT)
- {
- cmp_type= CMP_STR_WITH_DATE;
- date_arg= b;
- str_arg= a;
- }
-
- if (cmp_type != CMP_DATE_DFLT)
- {
- THD *thd= current_thd;
- /*
- Do not cache GET_USER_VAR() function as its const_item() may return TRUE
- for the current thread but it still may change during the execution.
- Don't use cache while in the context analysis mode only (i.e. for
- EXPLAIN/CREATE VIEW and similar queries). Cache is useless in such
- cases and can cause problems. For example evaluating subqueries can
- confuse storage engines since in context analysis mode tables
- aren't locked.
- */
- if (!thd->lex->is_ps_or_view_context_analysis() &&
- cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item() &&
- (str_arg->type() != Item::FUNC_ITEM ||
- ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
- {
- ulonglong value;
- bool error;
- String tmp, *str_val= 0;
- timestamp_type t_type= (date_arg->field_type() == MYSQL_TYPE_DATE ?
- MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME);
-
- str_val= str_arg->val_str(&tmp);
- if (str_arg->null_value)
- return CMP_DATE_DFLT;
- value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
- if (error)
- return CMP_DATE_DFLT;
- if (const_value)
- *const_value= value;
- }
- }
- return cmp_type;
-}
-
-/*
- Retrieves correct TIME value from the given item.
-
- SYNOPSIS
- get_time_value()
- thd thread handle
- item_arg [in/out] item to retrieve TIME value from
- cache_arg [in/out] pointer to place to store the cache item to
- warn_item [in] unused
- is_null [out] TRUE <=> the item_arg is null
-
- DESCRIPTION
- Retrieves the correct TIME value from given item for comparison by the
- compare_datetime() function.
- If item's result can be compared as longlong then its int value is used
- and a value returned by get_time function is used otherwise.
- If an item is a constant one then its value is cached and it isn't
- get parsed again. An Item_cache_int object is used for for cached values.
- It seamlessly substitutes the original item. The cache item is marked as
- non-constant to prevent re-caching it again.
-
- RETURN
- obtained value
-*/
-
-longlong
-get_time_value(THD *thd, Item ***item_arg, Item **cache_arg,
- Item *warn_item, bool *is_null)
-{
- longlong value;
- Item *item= **item_arg;
- MYSQL_TIME ltime;
-
- if (item->result_as_longlong())
- {
- value= item->val_int();
- *is_null= item->null_value;
- }
- else
- {
- *is_null= item->get_time(&ltime);
- value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(&ltime) : 0;
- }
- /*
- Do not cache GET_USER_VAR() function as its const_item() may return TRUE
- for the current thread but it still may change during the execution.
- */
- if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
- ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
- {
- Query_arena backup;
- Query_arena *save_arena= thd->switch_to_arena_for_cached_items(&backup);
- Item_cache_int *cache= new Item_cache_int();
- if (save_arena)
- thd->set_query_arena(save_arena);
-
- /* Mark the cache as non-const to prevent re-caching. */
- cache->set_used_tables(1);
- cache->store_longlong(item, value);
- *cache_arg= cache;
- *item_arg= cache_arg;
- }
- return value;
-}
-
int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
Item **a1, Item **a2,
Item_result type)
{
- ulonglong const_value= (ulonglong)-1;
thd= current_thd;
owner= owner_arg;
set_null= set_null && owner_arg;
a= a1;
b= a2;
- thd= current_thd;
-
- if (can_compare_as_dates(*a, *b, &const_value))
- {
- a_type= (*a)->field_type();
- b_type= (*b)->field_type();
- a_cache= 0;
- b_cache= 0;
- if (const_value != (ulonglong)-1)
- {
- /*
- cache_converted_constant can't be used here because it can't
- correctly convert a DATETIME value from string to int representation.
- */
- Query_arena backup;
- Query_arena *save_arena= thd->switch_to_arena_for_cached_items(&backup);
- Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME);
- if (save_arena)
- thd->set_query_arena(save_arena);
-
- /* Mark the cache as non-const to prevent re-caching. */
- cache->set_used_tables(1);
- if (!(*a)->is_datetime())
- {
- cache->store_longlong((*a), const_value);
- a_cache= cache;
- a= (Item **)&a_cache;
- }
- else
- {
- cache->store_longlong((*b), const_value);
- b_cache= cache;
- b= (Item **)&b_cache;
- }
- }
- is_nulls_eq= is_owner_equal_func();
- func= &Arg_comparator::compare_datetime;
- get_value_a_func= &get_datetime_value;
- get_value_b_func= &get_datetime_value;
- return 0;
- }
- else if (type == STRING_RESULT && (*a)->field_type() == MYSQL_TYPE_TIME &&
- (*b)->field_type() == MYSQL_TYPE_TIME)
- {
- /* Compare TIME values as integers. */
- a_cache= 0;
- b_cache= 0;
- is_nulls_eq= is_owner_equal_func();
- func= &Arg_comparator::compare_datetime;
- get_value_a_func= &get_time_value;
- get_value_b_func= &get_time_value;
- return 0;
- }
- else if (type == STRING_RESULT &&
- (*a)->result_type() == STRING_RESULT &&
- (*b)->result_type() == STRING_RESULT)
+ if (type == STRING_RESULT &&
+ (*a)->result_type() == STRING_RESULT &&
+ (*b)->result_type() == STRING_RESULT)
{
DTCollation coll;
coll.set((*a)->collation.collation);
@@ -992,8 +775,10 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
b, 1, MY_COLL_CMP_CONV, 1))
return 1;
}
- else if (try_year_cmp_func(type))
- return 0;
+ if (type == INT_RESULT &&
+ (*a)->field_type() == MYSQL_TYPE_YEAR &&
+ (*b)->field_type() == MYSQL_TYPE_YEAR)
+ type= TIME_RESULT;
a= cache_converted_constant(thd, a, &a_cache, type);
b= cache_converted_constant(thd, b, &b_cache, type);
@@ -1001,45 +786,6 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
}
-/*
- Helper function to call from Arg_comparator::set_cmp_func()
-*/
-
-bool Arg_comparator::try_year_cmp_func(Item_result type)
-{
- if (type == ROW_RESULT)
- return FALSE;
-
- bool a_is_year= (*a)->field_type() == MYSQL_TYPE_YEAR;
- bool b_is_year= (*b)->field_type() == MYSQL_TYPE_YEAR;
-
- if (!a_is_year && !b_is_year)
- return FALSE;
-
- if (a_is_year && b_is_year)
- {
- get_value_a_func= &get_year_value;
- get_value_b_func= &get_year_value;
- }
- else if (a_is_year && (*b)->is_datetime())
- {
- get_value_a_func= &get_year_value;
- get_value_b_func= &get_datetime_value;
- }
- else if (b_is_year && (*a)->is_datetime())
- {
- get_value_b_func= &get_year_value;
- get_value_a_func= &get_datetime_value;
- }
- else
- return FALSE;
-
- is_nulls_eq= is_owner_equal_func();
- func= &Arg_comparator::compare_datetime;
-
- return TRUE;
-}
-
/**
Convert and cache a constant.
@@ -1061,9 +807,14 @@ Item** Arg_comparator::cache_converted_constant(THD *thd_arg, Item **value,
Item **cache_item,
Item_result type)
{
- /* Don't need cache if doing context analysis only. */
+ /*
+ Don't need cache if doing context analysis only.
+ Also, get_datetime_value creates Item_cache internally.
+ Unless fixed, we should not do it here.
+ */
if (!thd->lex->is_ps_or_view_context_analysis() &&
- (*value)->const_item() && type != (*value)->result_type())
+ (*value)->const_item() && type != (*value)->result_type() &&
+ type != TIME_RESULT)
{
Item_cache *cache= Item_cache::get_cache(*value, type);
cache->setup(*value);
@@ -1081,112 +832,88 @@ void Arg_comparator::set_datetime_cmp_func(Item_result_field *owner_arg,
owner= owner_arg;
a= a1;
b= b1;
- a_type= (*a)->field_type();
- b_type= (*b)->field_type();
a_cache= 0;
b_cache= 0;
- is_nulls_eq= FALSE;
- func= &Arg_comparator::compare_datetime;
- get_value_a_func= &get_datetime_value;
- get_value_b_func= &get_datetime_value;
+ func= comparator_matrix[TIME_RESULT][is_owner_equal_func()];
}
-
-/*
+/**
Retrieves correct DATETIME value from given item.
- SYNOPSIS
- get_datetime_value()
- thd thread handle
- item_arg [in/out] item to retrieve DATETIME value from
- cache_arg [in/out] pointer to place to store the caching item to
- warn_item [in] item for issuing the conversion warning
- is_null [out] TRUE <=> the item_arg is null
+ @param[in] thd thread handle
+ @param[in,out] item_arg item to retrieve DATETIME value from
+ @param[in,out] cache_arg pointer to place to store the caching item to
+ @param[in] warn_item item for issuing the conversion warning
+ @param[out] is_null TRUE <=> the item_arg is null
- DESCRIPTION
+ @details
Retrieves the correct DATETIME value from given item for comparison by the
compare_datetime() function.
- If item's result can be compared as longlong then its int value is used
- and its string value is used otherwise. Strings are always parsed and
- converted to int values by the get_date_from_str() function.
- This allows us to compare correctly string dates with missed insignificant
- zeros. If an item is a constant one then its value is cached and it isn't
- get parsed again. An Item_cache_int object is used for caching values. It
- seamlessly substitutes the original item. The cache item is marked as
- non-constant to prevent re-caching it again. In order to compare
- correctly DATE and DATETIME items the result of the former are treated as
- a DATETIME with zero time (00:00:00).
- RETURN
- obtained value
+ If the value should be compared as time (TIME_RESULT), it's retrieved as
+ MYSQL_TIME. Otherwise it's read as a number/string and converted to time.
+ Constant items are cached, so the convertion is only done once for them.
+
+ Note the f_type behavior: if the item can be compared as time, then
+ f_type is this item's field_type(). Otherwise it's field_type() of
+ warn_item (which is the other operand of the comparison operator).
+ This logic provides correct string/number to date/time conversion
+ depending on the other operand (when comparing a string with a date, it's
+ parsed as a date, when comparing a string with a time it's parsed as a time)
+
+ If the item is a constant it is replaced by the Item_cache_int, that
+ holds the packed datetime value.
+
+ @return
+ MYSQL_TIME value, packed in a longlong, suitable for comparison.
*/
longlong
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
Item *warn_item, bool *is_null)
{
- longlong value= 0;
- String buf, *str= 0;
+ longlong UNINIT_VAR(value);
Item *item= **item_arg;
+ enum_field_types f_type= item->cmp_type() == TIME_RESULT ?
+ item->field_type() : warn_item->field_type();
- if (item->result_as_longlong())
+ if (item->result_type() == INT_RESULT && item->cmp_type() == TIME_RESULT)
{
+ /* it's our Item_cache_int, as created below */
value= item->val_int();
- *is_null= item->null_value;
- enum_field_types f_type= item->field_type();
- /*
- Item_date_add_interval may return MYSQL_TYPE_STRING as the result
- field type. To detect that the DATE value has been returned we
- compare it with 100000000L - any DATE value should be less than it.
- Don't shift cached DATETIME values up for the second time.
- */
- if (f_type == MYSQL_TYPE_DATE ||
- (f_type != MYSQL_TYPE_DATETIME && value < 100000000L))
- value*= 1000000L;
}
else
{
- str= item->val_str(&buf);
- *is_null= item->null_value;
+ MYSQL_TIME ltime;
+ uint fuzzydate= TIME_FUZZY_DATE | TIME_INVALID_DATES;
+ if (f_type == MYSQL_TYPE_TIME)
+ fuzzydate|= TIME_TIME_ONLY;
+ if (item->get_date(&ltime, fuzzydate))
+ value= 0; /* invalid date */
+ else
+ value= pack_time(&ltime);
}
- if (*is_null)
+ if ((*is_null= item->null_value))
return ~(ulonglong) 0;
- /*
- Convert strings to the integer DATE/DATETIME representation.
- Even if both dates provided in strings we can't compare them directly as
- strings as there is no warranty that they are correct and do not miss
- some insignificant zeros.
- */
- if (str)
+ if (cache_arg && item->const_item() && item->type() != Item::CACHE_ITEM)
{
- bool error;
- enum_field_types f_type= warn_item->field_type();
- timestamp_type t_type= f_type ==
- MYSQL_TYPE_DATE ? MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME;
- value= (longlong) get_date_from_str(thd, str, t_type, warn_item->name, &error);
/*
- If str did not contain a valid date according to the current
- SQL_MODE, get_date_from_str() has already thrown a warning,
- and we don't want to throw NULL on invalid date (see 5.2.6
- "SQL modes" in the manual), so we're done here.
+ cache the packed datetime value in the Item_cache object.
+ Because the packed datetime value is longlong, we use Item_cache_int,
+ and it has result_type() == INT_RESULT.
+ But we create it to have field_type() == MYSQL_TYPE_TIME (or
+ MYSQL_TIMESTAMP_DATE or MYSQL_TYPE_DATETIME), and thus it will have
+ cmp_type() == TIME_RESULT.
+ As no other item can have this combination of cmp_type() and
+ result_type(), it allows us to identify our cache items.
*/
- }
- /*
- Do not cache GET_USER_VAR() function as its const_item() may return TRUE
- for the current thread but it still may change during the execution.
- */
- if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
- ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
- {
Query_arena backup;
Query_arena *save_arena= thd->switch_to_arena_for_cached_items(&backup);
- Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME);
+ Item_cache_temporal *cache= new Item_cache_temporal(f_type);
if (save_arena)
thd->set_query_arena(save_arena);
-
- /* Mark the cache as non-const to prevent re-caching. */
- cache->set_used_tables(1);
- cache->store_longlong(item, value);
+
+ cache->store_packed(value, item);
*cache_arg= cache;
*item_arg= cache_arg;
}
@@ -1195,67 +922,6 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
/*
- Retrieves YEAR value of 19XX-00-00 00:00:00 form from given item.
-
- SYNOPSIS
- get_year_value()
- thd thread handle
- item_arg [in/out] item to retrieve YEAR value from
- cache_arg [in/out] pointer to place to store the caching item to
- warn_item [in] item for issuing the conversion warning
- is_null [out] TRUE <=> the item_arg is null
-
- DESCRIPTION
- Retrieves the YEAR value of 19XX form from given item for comparison by the
- compare_datetime() function.
- Converts year to DATETIME of form YYYY-00-00 00:00:00 for the compatibility
- with the get_datetime_value function result.
-
- RETURN
- obtained value
-*/
-
-static longlong
-get_year_value(THD *thd, Item ***item_arg, Item **cache_arg,
- Item *warn_item, bool *is_null)
-{
- longlong value= 0;
- Item *item= **item_arg;
-
- value= item->val_int();
- *is_null= item->null_value;
- if (*is_null)
- return ~(ulonglong) 0;
-
- /*
- Coerce value to the 19XX form in order to correctly compare
- YEAR(2) & YEAR(4) types.
- Here we are converting all item values but YEAR(4) fields since
- 1) YEAR(4) already has a regular YYYY form and
- 2) we don't want to convert zero/bad YEAR(4) values to the
- value of 2000.
- */
- Item *real_item= item->real_item();
- Field *field= NULL;
- if (real_item->type() == Item::FIELD_ITEM)
- field= ((Item_field *)real_item)->field;
- else if (real_item->type() == Item::CACHE_ITEM)
- field= ((Item_cache *)real_item)->field();
- if (!(field && field->type() == MYSQL_TYPE_YEAR && field->field_length == 4))
- {
- if (value < 70)
- value+= 100;
- if (value <= 1900)
- value+= 1900;
- }
- /* Convert year to DATETIME of form YYYY-00-00 00:00:00 (YYYY0000000000). */
- value*= 10000000000LL;
-
- return value;
-}
-
-
-/*
Compare items values as dates.
SYNOPSIS
@@ -1267,18 +933,9 @@ get_year_value(THD *thd, Item ***item_arg, Item **cache_arg,
with help of the get_datetime_value() function.
RETURN
- If is_nulls_eq is TRUE:
- 1 if items are equal or both are null
- 0 otherwise
- If is_nulls_eq is FALSE:
-1 a < b or at least one item is null
0 a == b
1 a > b
- See the table:
- is_nulls_eq | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
- a_is_null | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
- b_is_null | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
- result | 1 | 0 | 0 |0/1|-1 |-1 |-1 |-1/0/1|
*/
int Arg_comparator::compare_datetime()
@@ -1286,34 +943,40 @@ int Arg_comparator::compare_datetime()
bool a_is_null, b_is_null;
longlong a_value, b_value;
+ if (set_null)
+ owner->null_value= 1;
+
/* Get DATE/DATETIME/TIME value of the 'a' item. */
- a_value= (*get_value_a_func)(thd, &a, &a_cache, *b, &a_is_null);
- if (!is_nulls_eq && a_is_null)
- {
- if (set_null)
- owner->null_value= 1;
+ a_value= get_datetime_value(thd, &a, &a_cache, *b, &a_is_null);
+ if (a_is_null)
return -1;
- }
/* Get DATE/DATETIME/TIME value of the 'b' item. */
- b_value= (*get_value_b_func)(thd, &b, &b_cache, *a, &b_is_null);
- if (a_is_null || b_is_null)
- {
- if (set_null)
- owner->null_value= is_nulls_eq ? 0 : 1;
- return is_nulls_eq ? (a_is_null == b_is_null) : -1;
- }
+ b_value= get_datetime_value(thd, &b, &b_cache, *a, &b_is_null);
+ if (b_is_null)
+ return -1;
/* Here we have two not-NULL values. */
if (set_null)
owner->null_value= 0;
/* Compare values. */
- if (is_nulls_eq)
- return (a_value == b_value);
- return a_value < b_value ? -1 : (a_value > b_value ? 1 : 0);
+ return a_value < b_value ? -1 : a_value > b_value ? 1 : 0;
}
+int Arg_comparator::compare_e_datetime()
+{
+ bool a_is_null, b_is_null;
+ longlong a_value, b_value;
+
+ /* Get DATE/DATETIME/TIME value of the 'a' item. */
+ a_value= get_datetime_value(thd, &a, &a_cache, *b, &a_is_null);
+
+ /* Get DATE/DATETIME/TIME value of the 'b' item. */
+ b_value= get_datetime_value(thd, &b, &b_cache, *a, &b_is_null);
+ return a_is_null || b_is_null ? a_is_null == b_is_null
+ : a_value == b_value;
+}
int Arg_comparator::compare_string()
{
@@ -1689,7 +1352,7 @@ int Arg_comparator::compare_e_row()
void Item_func_truth::fix_length_and_dec()
{
- maybe_null= 0;
+ set_persist_maybe_null(0);
null_value= 0;
decimals= 0;
max_length= 1;
@@ -1740,6 +1403,36 @@ longlong Item_func_truth::val_int()
}
+bool Item_in_optimizer::is_top_level_item()
+{
+ return ((Item_in_subselect *)args[1])->is_top_level_item();
+}
+
+
+void Item_in_optimizer::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ /* This will re-calculate attributes of our Item_in_subselect: */
+ Item_bool_func::fix_after_pullout(new_parent, ref);
+
+ /* Then, re-calculate not_null_tables_cache: */
+ eval_not_null_tables(NULL);
+}
+
+
+bool Item_in_optimizer::eval_not_null_tables(uchar *opt_arg)
+{
+ not_null_tables_cache= 0;
+ if (is_top_level_item())
+ {
+ /*
+ It is possible to determine NULL-rejectedness of the left arguments
+ of IN only if it is a top-level predicate.
+ */
+ not_null_tables_cache= args[0]->not_null_tables();
+ }
+ return FALSE;
+}
+
bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
{
if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
@@ -1749,6 +1442,7 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
cache->setup(args[0]);
if (cache->cols() == 1)
{
+ DBUG_ASSERT(args[0]->type() != ROW_ITEM);
if ((used_tables_cache= args[0]->used_tables()))
cache->set_used_tables(OUTER_REF_TABLE_BIT);
else
@@ -1759,6 +1453,14 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
uint n= cache->cols();
for (uint i= 0; i < n; i++)
{
+ /* Check that the expression (part of row) do not contain a subquery */
+ if (args[0]->element_index(i)->walk(&Item::is_subquery_processor,
+ FALSE, NULL))
+ {
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0),
+ "SUBQUERY in ROW in left expression of IN/ALL/ANY");
+ return 1;
+ }
if (args[0]->element_index(i)->used_tables())
((Item_cache *)cache->element_index(i))->set_used_tables(OUTER_REF_TABLE_BIT);
else
@@ -1766,10 +1468,14 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
}
used_tables_cache= args[0]->used_tables();
}
- not_null_tables_cache= args[0]->not_null_tables();
+ eval_not_null_tables(NULL);
with_sum_func= args[0]->with_sum_func;
+ with_field= args[0]->with_field;
if ((const_item_cache= args[0]->const_item()))
+ {
cache->store(args[0]);
+ cache->cache_value();
+ }
return 0;
}
@@ -1794,8 +1500,8 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
maybe_null=1;
with_subselect= 1;
with_sum_func= with_sum_func || args[1]->with_sum_func;
+ with_field= with_field || args[1]->with_field;
used_tables_cache|= args[1]->used_tables();
- not_null_tables_cache|= args[1]->not_null_tables();
const_item_cache&= args[1]->const_item();
fixed= 1;
return FALSE;
@@ -1803,6 +1509,65 @@ 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");
+ if (args[1]->type() != Item::SUBSELECT_ITEM)
+ DBUG_RETURN(this); // MAX/MIN transformed => do nothing
+
+ if (expr_cache)
+ DBUG_RETURN(expr_cache);
+
+ if (args[1]->expr_cache_is_needed(thd) &&
+ (expr_cache= set_expr_cache(thd)))
+ DBUG_RETURN(expr_cache);
+
+ DBUG_RETURN(this);
+}
+
+
+
+/**
+ Collect and add to the list cache parameters for this Item.
+
+ @param parameters The list where to add parameters
+*/
+
+void Item_in_optimizer::get_cache_parameters(List<Item> &parameters)
+{
+ /* Add left expression to the list of the parameters of the subquery */
+ if (args[0]->cols() == 1)
+ parameters.add_unique(args[0], &cmp_items);
+ else
+ {
+ for (uint i= 0; i < args[0]->cols(); i++)
+ {
+ parameters.add_unique(args[0]->element_index(i), &cmp_items);
+ }
+ }
+ args[1]->get_cache_parameters(parameters);
+}
+
+
+/*
The implementation of optimized \<outer expression\> [NOT] IN \<subquery\>
predicates. The implementation works as follows.
@@ -1872,13 +1637,22 @@ 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;
DBUG_ASSERT(fixed == 1);
cache->store(args[0]);
cache->cache_value();
-
+
+ if (args[1]->type() != Item::SUBSELECT_ITEM)
+ {
+ /* MAX/MIN transformed => pass through */
+ longlong res= args[1]->val_int();
+ null_value= args[1]->null_value;
+ return (res);
+ }
+
if (cache->null_value)
{
/*
@@ -1973,6 +1747,7 @@ void Item_in_optimizer::cleanup()
Item_bool_func::cleanup();
if (!save_cache)
cache= 0;
+ expr_cache= 0;
DBUG_VOID_RETURN;
}
@@ -1984,6 +1759,94 @@ 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);
+
+ if (args[1]->type() != Item::SUBSELECT_ITEM)
+ {
+ /* MAX/MIN transformed => pass through */
+ new_item= args[1]->transform(transformer, argument);
+ if (!new_item)
+ return 0;
+ if (args[1] != new_item)
+ current_thd->change_item_tree(args + 1, new_item);
+ }
+ else
+ {
+ /*
+ 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];
+ current_thd->change_item_tree(&in_arg->left_expr, args[0]);
+ }
+ return (this->*transformer)(argument);
+}
+
+
+bool Item_in_optimizer::is_expensive_processor(uchar *arg)
+{
+ return args[0]->is_expensive_processor(arg) ||
+ args[1]->is_expensive_processor(arg);
+}
+
+
+bool Item_in_optimizer::is_expensive()
+{
+ return args[0]->is_expensive() || args[1]->is_expensive();
+}
+
+
longlong Item_func_eq::val_int()
{
DBUG_ASSERT(fixed == 1);
@@ -1997,7 +1860,8 @@ longlong Item_func_eq::val_int()
void Item_func_equal::fix_length_and_dec()
{
Item_bool_func2::fix_length_and_dec();
- maybe_null=null_value=0;
+ set_persist_maybe_null(0);
+ null_value= 0;
}
longlong Item_func_equal::val_int()
@@ -2137,11 +2001,12 @@ void Item_func_interval::fix_length_and_dec()
}
}
}
- maybe_null= 0;
+ set_persist_maybe_null(0);
max_length= 2;
used_tables_cache|= row->used_tables();
not_null_tables_cache= row->not_null_tables();
with_sum_func= with_sum_func || row->with_sum_func;
+ with_field= with_field || row->with_field;
const_item_cache&= row->const_item();
}
@@ -2274,6 +2139,16 @@ bool Item_func_between::fix_fields(THD *thd, Item **ref)
thd->lex->current_select->between_count++;
+
+ return 0;
+}
+
+
+bool Item_func_between::eval_not_null_tables(uchar *opt_arg)
+{
+ if (Item_func_opt_neg::eval_not_null_tables(NULL))
+ return 1;
+
/* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
if (pred_level && !negated)
return 0;
@@ -2282,19 +2157,23 @@ bool Item_func_between::fix_fields(THD *thd, Item **ref)
not_null_tables_cache= (args[0]->not_null_tables() |
(args[1]->not_null_tables() &
args[2]->not_null_tables()));
-
return 0;
-}
+}
+
+void Item_func_between::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ /* This will re-calculate attributes of the arguments */
+ Item_func_opt_neg::fix_after_pullout(new_parent, ref);
+ /* Then, re-calculate not_null_tables_cache according to our special rules */
+ eval_not_null_tables(NULL);
+}
void Item_func_between::fix_length_and_dec()
{
- max_length= 1;
- int i;
- bool datetime_found= FALSE;
- int time_items_found= 0;
- compare_as_dates= TRUE;
THD *thd= current_thd;
+ max_length= 1;
+ compare_as_dates= 0;
/*
As some compare functions are generated after sql_yacc,
@@ -2309,81 +2188,80 @@ void Item_func_between::fix_length_and_dec()
return;
/*
- Detect the comparison of DATE/DATETIME items.
- At least one of items should be a DATE/DATETIME item and other items
- should return the STRING result.
+ When comparing as date/time, we need to convert non-temporal values
+ (e.g. strings) to MYSQL_TIME. get_datetime_value() does it
+ automatically when one of the operands is a date/time. But here we
+ may need to compare two strings as dates (str1 BETWEEN str2 AND date).
+ For this to work, we need to know what date/time type we compare
+ strings as.
*/
- if (cmp_type == STRING_RESULT)
- {
- for (i= 0; i < 3; i++)
- {
- if (args[i]->is_datetime())
- {
- datetime_found= TRUE;
- continue;
- }
- if (args[i]->field_type() == MYSQL_TYPE_TIME &&
- args[i]->result_as_longlong())
- time_items_found++;
- }
- }
- if (!datetime_found)
- compare_as_dates= FALSE;
+ if (cmp_type == TIME_RESULT)
+ compare_as_dates= find_date_time_item(args, 3, 0);
- if (compare_as_dates)
- {
- ge_cmp.set_datetime_cmp_func(this, args, args + 1);
- le_cmp.set_datetime_cmp_func(this, args, args + 2);
- }
- else if (time_items_found == 3)
- {
- /* Compare TIME items as integers. */
- cmp_type= INT_RESULT;
- }
- else if (args[0]->real_item()->type() == FIELD_ITEM &&
- thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
- thd->lex->sql_command != SQLCOM_SHOW_CREATE)
+ /* See the comment about the similar block in Item_bool_func2 */
+ if (args[0]->real_item()->type() == FIELD_ITEM &&
+ !thd->lex->is_ps_or_view_context_analysis())
{
Item_field *field_item= (Item_field*) (args[0]->real_item());
- if (field_item->field->can_be_compared_as_longlong())
+ if (field_item->field_type() == MYSQL_TYPE_LONGLONG ||
+ field_item->field_type() == MYSQL_TYPE_YEAR)
{
/*
- The following can't be recoded with || as convert_constant_item
+ The following can't be recoded with || as convert_const_to_int
changes the argument
*/
- if (convert_constant_item(thd, field_item, &args[1]))
- cmp_type=INT_RESULT; // Works for all types.
- if (convert_constant_item(thd, field_item, &args[2]))
- cmp_type=INT_RESULT; // Works for all types.
+ if (convert_const_to_int(thd, field_item, &args[1]))
+ cmp_type=INT_RESULT;
+ if (convert_const_to_int(thd, field_item, &args[2]))
+ cmp_type=INT_RESULT;
}
}
}
longlong Item_func_between::val_int()
-{ // ANSI BETWEEN
+{
DBUG_ASSERT(fixed == 1);
- if (compare_as_dates)
+
+ switch (cmp_type) {
+ case TIME_RESULT:
{
- int ge_res, le_res;
+ THD *thd= current_thd;
+ longlong value, a, b;
+ Item *cache, **ptr;
+ bool value_is_null, a_is_null, b_is_null;
- ge_res= ge_cmp.compare();
- if ((null_value= args[0]->null_value))
+ ptr= &args[0];
+ value= get_datetime_value(thd, &ptr, &cache, compare_as_dates,
+ &value_is_null);
+ if (ptr != &args[0])
+ thd->change_item_tree(&args[0], *ptr);
+
+ if ((null_value= value_is_null))
return 0;
- le_res= le_cmp.compare();
- if (!args[1]->null_value && !args[2]->null_value)
- return (longlong) ((ge_res >= 0 && le_res <=0) != negated);
- else if (args[1]->null_value)
- {
- null_value= le_res > 0; // not null if false range.
- }
+ ptr= &args[1];
+ a= get_datetime_value(thd, &ptr, &cache, compare_as_dates, &a_is_null);
+ if (ptr != &args[1])
+ thd->change_item_tree(&args[1], *ptr);
+
+ ptr= &args[2];
+ b= get_datetime_value(thd, &ptr, &cache, compare_as_dates, &b_is_null);
+ if (ptr != &args[2])
+ thd->change_item_tree(&args[2], *ptr);
+
+ if (!a_is_null && !b_is_null)
+ return (longlong) ((value >= a && value <= b) != negated);
+ if (a_is_null && b_is_null)
+ null_value=1;
+ else if (a_is_null)
+ null_value= value <= b; // not null if false range.
else
- {
- null_value= ge_res < 0;
- }
+ null_value= value >= a;
+ break;
}
- else if (cmp_type == STRING_RESULT)
+
+ case STRING_RESULT:
{
String *value,*a,*b;
value=args[0]->val_str(&value0);
@@ -2407,8 +2285,9 @@ longlong Item_func_between::val_int()
// Set to not null if false range.
null_value= sortcmp(value,a,cmp_collation.collation) >= 0;
}
+ break;
}
- else if (cmp_type == INT_RESULT)
+ case INT_RESULT:
{
longlong value=args[0]->val_int(), a, b;
if ((null_value=args[0]->null_value))
@@ -2427,8 +2306,9 @@ longlong Item_func_between::val_int()
{
null_value= value >= a;
}
+ break;
}
- else if (cmp_type == DECIMAL_RESULT)
+ case DECIMAL_RESULT:
{
my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
a_buf, *a_dec, b_buf, *b_dec;
@@ -2445,8 +2325,9 @@ longlong Item_func_between::val_int()
null_value= (my_decimal_cmp(dec, b_dec) <= 0);
else
null_value= (my_decimal_cmp(dec, a_dec) >= 0);
+ break;
}
- else
+ case REAL_RESULT:
{
double value= args[0]->val_real(),a,b;
if ((null_value=args[0]->null_value))
@@ -2465,6 +2346,13 @@ longlong Item_func_between::val_int()
{
null_value= value >= a;
}
+ break;
+ }
+ case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0);
+ null_value= 1;
+ return 0;
}
return (longlong) (!null_value && negated);
}
@@ -2515,7 +2403,8 @@ Item_func_ifnull::fix_length_and_dec()
decimals= 0;
break;
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
cached_field_type= agg_field_type(args, 2);
@@ -2645,6 +2534,16 @@ Item_func_if::fix_fields(THD *thd, Item **ref)
if (Item_func::fix_fields(thd, ref))
return 1;
+ return 0;
+}
+
+
+bool
+Item_func_if::eval_not_null_tables(uchar *opt_arg)
+{
+ if (Item_func::eval_not_null_tables(NULL))
+ return 1;
+
not_null_tables_cache= (args[1]->not_null_tables() &
args[2]->not_null_tables());
@@ -2652,6 +2551,15 @@ Item_func_if::fix_fields(THD *thd, Item **ref)
}
+void Item_func_if::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ /* This will re-calculate attributes of the arguments */
+ Item_func::fix_after_pullout(new_parent, ref);
+ /* Then, re-calculate not_null_tables_cache according to our special rules */
+ eval_not_null_tables(NULL);
+}
+
+
void
Item_func_if::fix_length_and_dec()
{
@@ -2764,7 +2672,7 @@ void
Item_func_nullif::fix_length_and_dec()
{
Item_bool_func2::fix_length_and_dec();
- maybe_null=1;
+ set_persist_maybe_null(1);
if (args[0]) // Only false if EOM
{
max_length=args[0]->max_length;
@@ -2899,7 +2807,7 @@ Item *Item_func_case::find_item(String *str)
{
if (args[i]->real_item()->type() == NULL_ITEM)
continue;
- cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
+ cmp_type= item_cmp_type(left_result_type, args[i]->cmp_type());
DBUG_ASSERT(cmp_type != ROW_RESULT);
DBUG_ASSERT(cmp_items[(uint)cmp_type]);
if (!(value_added_map & (1<<(uint)cmp_type)))
@@ -3064,7 +2972,7 @@ void Item_func_case::fix_length_and_dec()
{
uint i;
agg[0]= args[first_expr_num];
- left_result_type= agg[0]->result_type();
+ left_result_type= agg[0]->cmp_type();
for (nagg= 0; nagg < ncases/2 ; nagg++)
agg[nagg+1]= args[nagg*2];
@@ -3082,7 +2990,8 @@ void Item_func_case::fix_length_and_dec()
found_types |= (1 << item_cmp_type(left_result_type, STRING_RESULT));
}
- for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
+ Item *date_arg= 0;
+ for (i= 0; i <= (uint)TIME_RESULT; i++)
{
if (found_types & (1 << i) && !cmp_items[i])
{
@@ -3090,8 +2999,12 @@ void Item_func_case::fix_length_and_dec()
if ((Item_result)i == STRING_RESULT &&
agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1))
return;
+
+ if ((Item_result)i == TIME_RESULT)
+ date_arg= find_date_time_item(args, arg_count, 0);
+
if (!(cmp_items[i]=
- cmp_item::get_comparator((Item_result)i,
+ cmp_item::get_comparator((Item_result)i, date_arg,
cmp_collation.collation)))
return;
}
@@ -3180,7 +3093,7 @@ void Item_func_case::cleanup()
uint i;
DBUG_ENTER("Item_func_case::cleanup");
Item_func::cleanup();
- for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
+ for (i= 0; i <= (uint)TIME_RESULT; i++)
{
delete cmp_items[i];
cmp_items[i]= 0;
@@ -3236,6 +3149,21 @@ double Item_func_coalesce::real_op()
}
+bool Item_func_coalesce::get_date(MYSQL_TIME *ltime,uint fuzzydate)
+{
+ DBUG_ASSERT(fixed == 1);
+ null_value= 0;
+ for (uint i= 0; i < arg_count; i++)
+ {
+ bool res= args[i]->get_date(ltime, fuzzydate);
+ if (!args[i]->null_value)
+ return res;
+ }
+ null_value=1;
+ return 1;
+}
+
+
my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
@@ -3255,6 +3183,14 @@ void Item_func_coalesce::fix_length_and_dec()
{
cached_field_type= agg_field_type(args, arg_count);
agg_result_type(&hybrid_type, args, arg_count);
+ Item_result cmp_type;
+ agg_cmp_type(&cmp_type, args, arg_count);
+ ///< @todo let result_type() return TIME_RESULT and remove this special case
+ if (cmp_type == TIME_RESULT)
+ {
+ count_real_length();
+ return;
+ }
switch (hybrid_type) {
case STRING_RESULT:
count_only_length();
@@ -3272,7 +3208,8 @@ void Item_func_coalesce::fix_length_and_dec()
decimals= 0;
break;
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
}
@@ -3587,7 +3524,7 @@ uchar *in_decimal::get_value(Item *item)
}
-cmp_item* cmp_item::get_comparator(Item_result type,
+cmp_item* cmp_item::get_comparator(Item_result type, Item *warn_item,
CHARSET_INFO *cs)
{
switch (type) {
@@ -3601,7 +3538,9 @@ cmp_item* cmp_item::get_comparator(Item_result type,
return new cmp_item_row;
case DECIMAL_RESULT:
return new cmp_item_decimal;
- default:
+ case TIME_RESULT:
+ return new cmp_item_datetime(warn_item);
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
break;
}
@@ -3665,10 +3604,13 @@ void cmp_item_row::store_value(Item *item)
for (uint i=0; i < n; i++)
{
if (!comparators[i])
+ {
+ DBUG_ASSERT(item->element_index(i)->cmp_type() != TIME_RESULT);
if (!(comparators[i]=
- cmp_item::get_comparator(item->element_index(i)->result_type(),
+ cmp_item::get_comparator(item->element_index(i)->result_type(), 0,
item->element_index(i)->collation.collation)))
break; // new failed
+ }
comparators[i]->store_value(item->element_index(i));
item->null_value|= item->element_index(i)->null_value;
}
@@ -3842,11 +3784,22 @@ bool Item_func_in::nulls_in_row()
bool
Item_func_in::fix_fields(THD *thd, Item **ref)
{
- Item **arg, **arg_end;
if (Item_func_opt_neg::fix_fields(thd, ref))
return 1;
+ return 0;
+}
+
+
+bool
+Item_func_in::eval_not_null_tables(uchar *opt_arg)
+{
+ Item **arg, **arg_end;
+
+ if (Item_func_opt_neg::eval_not_null_tables(NULL))
+ return 1;
+
/* not_null_tables_cache == union(T1(e),union(T1(ei))) */
if (pred_level && negated)
return 0;
@@ -3860,6 +3813,14 @@ Item_func_in::fix_fields(THD *thd, Item **ref)
}
+void Item_func_in::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ /* This will re-calculate attributes of the arguments */
+ Item_func_opt_neg::fix_after_pullout(new_parent, ref);
+ /* Then, re-calculate not_null_tables_cache according to our special rules */
+ eval_not_null_tables(NULL);
+}
+
static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
{
return cs->coll->strnncollsp(cs,
@@ -3867,20 +3828,17 @@ static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
(uchar *) y->ptr(),y->length(), 0);
}
-
void Item_func_in::fix_length_and_dec()
{
Item **arg, **arg_end;
bool const_itm= 1;
THD *thd= current_thd;
- bool datetime_found= FALSE;
/* TRUE <=> arguments values will be compared as DATETIMEs. */
- bool compare_as_datetime= FALSE;
Item *date_arg= 0;
uint found_types= 0;
uint type_cnt= 0, i;
Item_result cmp_type= STRING_RESULT;
- left_result_type= args[0]->result_type();
+ left_result_type= args[0]->cmp_type();
if (!(found_types= collect_cmp_types(args, arg_count, true)))
return;
@@ -3892,7 +3850,7 @@ void Item_func_in::fix_length_and_dec()
break;
}
}
- for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
+ for (i= 0; i <= (uint)TIME_RESULT; i++)
{
if (found_types & 1 << i)
{
@@ -3907,16 +3865,12 @@ void Item_func_in::fix_length_and_dec()
agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
return;
arg_types_compatible= TRUE;
- }
- if (type_cnt == 1)
- {
- /*
- When comparing rows create the row comparator object beforehand to ease
- the DATETIME comparison detection procedure.
- */
+
if (cmp_type == ROW_RESULT)
{
+ uint cols= args[0]->cols();
cmp_item_row *cmp= 0;
+
if (const_itm && !nulls_in_row())
{
array= new in_row(arg_count-1, 0);
@@ -3928,66 +3882,20 @@ void Item_func_in::fix_length_and_dec()
return;
cmp_items[ROW_RESULT]= cmp;
}
- cmp->n= args[0]->cols();
+ cmp->n= cols;
cmp->alloc_comparators();
- }
- /* All DATE/DATETIME fields/functions has the STRING result type. */
- if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
- {
- uint col, cols= args[0]->cols();
- for (col= 0; col < cols; col++)
+ for (uint col= 0; col < cols; col++)
{
- bool skip_column= FALSE;
- /*
- Check that all items to be compared has the STRING result type and at
- least one of them is a DATE/DATETIME item.
- */
- for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++)
+ date_arg= find_date_time_item(args, arg_count, col);
+ if (date_arg)
{
- Item *itm= ((cmp_type == STRING_RESULT) ? arg[0] :
- arg[0]->element_index(col));
- if (itm->result_type() != STRING_RESULT)
- {
- skip_column= TRUE;
- break;
- }
- else if (itm->is_datetime())
- {
- datetime_found= TRUE;
- /*
- Internally all DATE/DATETIME values are converted to the DATETIME
- type. So try to find a DATETIME item to issue correct warnings.
- */
- if (!date_arg)
- date_arg= itm;
- else if (itm->field_type() == MYSQL_TYPE_DATETIME)
- {
- date_arg= itm;
- /* All arguments are already checked to have the STRING result. */
- if (cmp_type == STRING_RESULT)
- break;
- }
- }
- }
- if (skip_column)
- continue;
- if (datetime_found)
- {
- if (cmp_type == ROW_RESULT)
- {
- cmp_item **cmp= 0;
- if (array)
- cmp= ((in_row*)array)->tmp.comparators + col;
- else
- cmp= ((cmp_item_row*)cmp_items[ROW_RESULT])->comparators + col;
- *cmp= new cmp_item_datetime(date_arg);
- /* Reset variables for the next column. */
- date_arg= 0;
- datetime_found= FALSE;
- }
+ cmp_item **cmp= 0;
+ if (array)
+ cmp= ((in_row*)array)->tmp.comparators + col;
else
- compare_as_datetime= TRUE;
+ cmp= ((cmp_item_row*)cmp_items[ROW_RESULT])->comparators + col;
+ *cmp= new cmp_item_datetime(date_arg);
}
}
}
@@ -3998,61 +3906,61 @@ void Item_func_in::fix_length_and_dec()
*/
if (type_cnt == 1 && const_itm && !nulls_in_row())
{
- if (compare_as_datetime)
- array= new in_datetime(date_arg, arg_count - 1);
- else
+ /*
+ IN must compare INT columns and constants as int values (the same
+ way as equality does).
+ So we must check here if the column on the left and all the constant
+ values on the right can be compared as integers and adjust the
+ comparison type accordingly.
+
+ See the comment about the similar block in Item_bool_func2
+ */
+ if (args[0]->real_item()->type() == FIELD_ITEM &&
+ !thd->lex->is_ps_or_view_context_analysis() && cmp_type != INT_RESULT)
{
- /*
- IN must compare INT columns and constants as int values (the same
- way as equality does).
- So we must check here if the column on the left and all the constant
- values on the right can be compared as integers and adjust the
- comparison type accordingly.
- */
- if (args[0]->real_item()->type() == FIELD_ITEM &&
- thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
- thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
- cmp_type != INT_RESULT)
+ Item_field *field_item= (Item_field*) (args[0]->real_item());
+ if (field_item->field_type() == MYSQL_TYPE_LONGLONG ||
+ field_item->field_type() == MYSQL_TYPE_YEAR)
{
- Item_field *field_item= (Item_field*) (args[0]->real_item());
- if (field_item->field->can_be_compared_as_longlong())
+ bool all_converted= TRUE;
+ for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
{
- bool all_converted= TRUE;
- for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
- {
- if (!convert_constant_item (thd, field_item, &arg[0]))
- all_converted= FALSE;
- }
- if (all_converted)
- cmp_type= INT_RESULT;
+ if (!convert_const_to_int(thd, field_item, &arg[0]))
+ all_converted= FALSE;
}
+ if (all_converted)
+ cmp_type= INT_RESULT;
}
- switch (cmp_type) {
- case STRING_RESULT:
- array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
- cmp_collation.collation);
- break;
- case INT_RESULT:
- array= new in_longlong(arg_count-1);
- break;
- case REAL_RESULT:
- array= new in_double(arg_count-1);
- break;
- case ROW_RESULT:
- /*
- The row comparator was created at the beginning but only DATETIME
- items comparators were initialized. Call store_value() to setup
- others.
- */
- ((in_row*)array)->tmp.store_value(args[0]);
- break;
- case DECIMAL_RESULT:
- array= new in_decimal(arg_count - 1);
- break;
- default:
- DBUG_ASSERT(0);
- return;
- }
+ }
+ switch (cmp_type) {
+ case STRING_RESULT:
+ array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
+ cmp_collation.collation);
+ break;
+ case INT_RESULT:
+ array= new in_longlong(arg_count-1);
+ break;
+ case REAL_RESULT:
+ array= new in_double(arg_count-1);
+ break;
+ case ROW_RESULT:
+ /*
+ The row comparator was created at the beginning but only DATETIME
+ items comparators were initialized. Call store_value() to setup
+ others.
+ */
+ ((in_row*)array)->tmp.store_value(args[0]);
+ break;
+ case DECIMAL_RESULT:
+ array= new in_decimal(arg_count - 1);
+ break;
+ case TIME_RESULT:
+ date_arg= find_date_time_item(args, arg_count, 0);
+ array= new in_datetime(date_arg, arg_count - 1);
+ break;
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0);
+ break;
}
if (array && !(thd->is_fatal_error)) // If not EOM
{
@@ -4071,23 +3979,21 @@ void Item_func_in::fix_length_and_dec()
}
else
{
- if (compare_as_datetime)
- cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
- else
+ for (i= 0; i <= (uint) TIME_RESULT; i++)
{
- for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
+ if (found_types & (1 << i) && !cmp_items[i])
{
- if (found_types & (1 << i) && !cmp_items[i])
- {
- if ((Item_result)i == STRING_RESULT &&
- agg_arg_charsets(cmp_collation, args, arg_count,
- MY_COLL_CMP_CONV, 1))
- return;
- if (!cmp_items[i] && !(cmp_items[i]=
- cmp_item::get_comparator((Item_result)i,
- cmp_collation.collation)))
- return;
- }
+ if ((Item_result)i == STRING_RESULT &&
+ agg_arg_charsets(cmp_collation, args, arg_count,
+ MY_COLL_CMP_CONV, 1))
+ return;
+ if ((Item_result)i == TIME_RESULT)
+ date_arg= find_date_time_item(args, arg_count, 0);
+
+ if (!cmp_items[i] && !(cmp_items[i]=
+ cmp_item::get_comparator((Item_result)i, date_arg,
+ cmp_collation.collation)))
+ return;
}
}
}
@@ -4165,7 +4071,7 @@ longlong Item_func_in::val_int()
have_null= TRUE;
continue;
}
- Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
+ Item_result cmp_type= item_cmp_type(left_result_type, args[i]->cmp_type());
in_item= cmp_items[(uint)cmp_type];
DBUG_ASSERT(in_item);
if (!(value_added_map & (1 << (uint)cmp_type)))
@@ -4254,6 +4160,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
#endif
not_null_tables_cache= used_tables_cache= 0;
const_item_cache= 1;
+
/*
and_table_cache is the value that Item_cond_or() returns for
not_null_tables()
@@ -4279,7 +4186,6 @@ Item_cond::fix_fields(THD *thd, Item **ref)
*/
while ((item=li++))
{
- table_map tmp_table_map;
while (item->type() == Item::COND_ITEM &&
((Item_cond*) item)->functype() == functype() &&
!((Item_cond*) item)->list.is_empty())
@@ -4317,12 +4223,14 @@ Item_cond::fix_fields(THD *thd, Item **ref)
and_tables_cache= (table_map) 0;
else
{
- tmp_table_map= item->not_null_tables();
+ table_map tmp_table_map= item->not_null_tables();
not_null_tables_cache|= tmp_table_map;
and_tables_cache&= tmp_table_map;
const_item_cache= FALSE;
- }
+ }
+
with_sum_func= with_sum_func || item->with_sum_func;
+ with_field= with_field || item->with_field;
with_subselect|= item->with_subselect;
if (item->maybe_null)
maybe_null=1;
@@ -4333,6 +4241,62 @@ Item_cond::fix_fields(THD *thd, Item **ref)
return FALSE;
}
+
+bool
+Item_cond::eval_not_null_tables(uchar *opt_arg)
+{
+ Item *item;
+ List_iterator<Item> li(list);
+ not_null_tables_cache= (table_map) 0;
+ and_tables_cache= ~(table_map) 0;
+ while ((item=li++))
+ {
+ table_map tmp_table_map;
+ 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;
+ }
+ }
+ return 0;
+}
+
+
+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);
@@ -4503,6 +4467,8 @@ void Item_cond::update_used_tables()
item->update_used_tables();
used_tables_cache|= item->used_tables();
const_item_cache&= item->const_item();
+ if (!persistent_maybe_null && item->maybe_null)
+ maybe_null= 1;
}
}
@@ -4542,6 +4508,17 @@ void Item_cond::neg_arguments(THD *thd)
}
+void Item_cond_and::mark_as_condition_AND_part(TABLE_LIST *embedding)
+{
+ List_iterator<Item> li(list);
+ Item *item;
+ while ((item=li++))
+ {
+ item->mark_as_condition_AND_part(embedding);
+ }
+}
+
+
/**
Evaluation of AND(expr, expr, expr ...).
@@ -4644,12 +4621,6 @@ Item *and_expressions(Item *a, Item *b, Item **org_item)
longlong Item_func_isnull::val_int()
{
DBUG_ASSERT(fixed == 1);
- /*
- Handle optimization if the argument can't be null
- This has to be here because of the test in update_used_tables().
- */
- if (!used_tables_cache && !with_subselect)
- return cached_value;
return args[0]->is_null() ? 1: 0;
}
@@ -4657,12 +4628,6 @@ longlong Item_is_not_null_test::val_int()
{
DBUG_ASSERT(fixed == 1);
DBUG_ENTER("Item_is_not_null_test::val_int");
- if (!used_tables_cache && !with_subselect)
- {
- owner->was_null|= (!cached_value);
- DBUG_PRINT("info", ("cached: %ld", (long) cached_value));
- DBUG_RETURN(cached_value);
- }
if (args[0]->is_null())
{
DBUG_PRINT("info", ("null"));
@@ -4678,20 +4643,9 @@ longlong Item_is_not_null_test::val_int()
*/
void Item_is_not_null_test::update_used_tables()
{
+ args[0]->update_used_tables();
if (!args[0]->maybe_null)
- {
used_tables_cache= 0; /* is always true */
- cached_value= (longlong) 1;
- }
- else
- {
- args[0]->update_used_tables();
- if (!(used_tables_cache=args[0]->used_tables()) && !with_subselect)
- {
- /* Remember if the value is always NULL or never NULL */
- cached_value= (longlong) !args[0]->is_null();
- }
- }
}
@@ -4741,7 +4695,7 @@ longlong Item_func_like::val_int()
Item_func::optimize_type Item_func_like::select_optimize() const
{
- if (args[1]->const_item())
+ if (args[1]->const_item() && !args[1]->is_expensive())
{
String* res2= args[1]->val_str((String *)&cmp.value2);
const char *ptr2;
@@ -4828,7 +4782,8 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
We could also do boyer-more for non-const items, but as we would have to
recompute the tables for each row it's not worth it.
*/
- if (args[1]->const_item() && !use_strnxfrm(collation.collation))
+ if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
+ !args[1]->is_expensive())
{
String* res2 = args[1]->val_str(&cmp.value2);
if (!res2)
@@ -4944,6 +4899,7 @@ Item_func_regex::fix_fields(THD *thd, Item **ref)
args[1]->fix_fields(thd, args + 1)) || args[1]->check_cols(1))
return TRUE; /* purecov: inspected */
with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func;
+ with_field= args[0]->with_field || args[1]->with_field;
with_subselect|= args[0]->with_subselect | args[1]->with_subselect;
max_length= 1;
decimals= 0;
@@ -4972,7 +4928,7 @@ Item_func_regex::fix_fields(THD *thd, Item **ref)
int comp_res= regcomp(TRUE);
if (comp_res == -1)
{ // Will always return NULL
- maybe_null=1;
+ set_persist_maybe_null(1);
fixed= 1;
return FALSE;
}
@@ -4982,7 +4938,7 @@ Item_func_regex::fix_fields(THD *thd, Item **ref)
maybe_null= args[0]->maybe_null;
}
else
- maybe_null=1;
+ set_persist_maybe_null(1);
fixed= 1;
return FALSE;
}
@@ -5268,23 +5224,21 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
very fast to use.
*/
-longlong Item_cond_xor::val_int()
+longlong Item_func_xor::val_int()
{
DBUG_ASSERT(fixed == 1);
- List_iterator<Item> li(list);
- Item *item;
- int result=0;
- null_value=0;
- while ((item=li++))
+ int result= 0;
+ null_value= false;
+ for (uint i= 0; i < arg_count; i++)
{
- result^= (item->val_int() != 0);
- if (item->null_value)
+ result^= (args[i]->val_int() != 0);
+ if (args[i]->null_value)
{
- null_value=1;
+ null_value= true;
return 0;
}
}
- return (longlong) result;
+ return result;
}
/**
@@ -5347,6 +5301,33 @@ Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
return item;
}
+/**
+ XOR can be negated by negating one of the operands:
+
+ NOT (a XOR b) => (NOT a) XOR b
+ => a XOR (NOT b)
+
+ @param thd Thread handle
+ @return New negated item
+*/
+Item *Item_func_xor::neg_transformer(THD *thd)
+{
+ Item *neg_operand;
+ Item_func_xor *new_item;
+ if ((neg_operand= args[0]->neg_transformer(thd)))
+ // args[0] has neg_tranformer
+ new_item= new(thd->mem_root) Item_func_xor(neg_operand, args[1]);
+ else if ((neg_operand= args[1]->neg_transformer(thd)))
+ // args[1] has neg_tranformer
+ new_item= new(thd->mem_root) Item_func_xor(args[0], neg_operand);
+ else
+ {
+ neg_operand= new(thd->mem_root) Item_func_not(args[0]);
+ new_item= new(thd->mem_root) Item_func_xor(neg_operand, args[1]);
+ }
+ return new_item;
+}
+
/**
a IS NULL -> a IS NOT NULL.
@@ -5391,7 +5372,7 @@ Item *Item_func_nop_all::neg_transformer(THD *thd)
/* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
Item_func_not_all *new_item= new Item_func_not_all(args[0]);
Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
- allany->func= allany->func_creator(FALSE);
+ allany->create_comp_func(FALSE);
allany->all= !allany->all;
allany->upper_item= new_item;
return new_item;
@@ -5403,7 +5384,7 @@ Item *Item_func_not_all::neg_transformer(THD *thd)
Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
allany->all= !allany->all;
- allany->func= allany->func_creator(TRUE);
+ allany->create_comp_func(TRUE);
allany->upper_item= new_item;
return new_item;
}
@@ -5452,43 +5433,94 @@ Item *Item_bool_rowready_func2::negated_item()
return 0;
}
-Item_equal::Item_equal(Item_field *f1, Item_field *f2)
- : Item_bool_func(), const_item(0), eval_item(0), cond_false(0),
- compare_as_dates(FALSE)
-{
- const_item_cache= 0;
- fields.push_back(f1);
- fields.push_back(f2);
-}
-Item_equal::Item_equal(Item *c, Item_field *f)
- : Item_bool_func(), eval_item(0), cond_false(0)
+/**
+ Construct a minimal multiple equality item
+
+ @param f1 the first equal item
+ @param f2 the second equal item
+ @param with_const_item TRUE if the first item is constant
+
+ @details
+ The constructor builds a new item equal object for the equality f1=f2.
+ One of the equal items can be constant. If this is the case it is passed
+ always as the first parameter and the parameter with_const_item serves
+ as an indicator of this case.
+ Currently any non-constant parameter items must point to an item of the
+ of the type Item_field or Item_direct_view_ref(Item_field).
+*/
+
+Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_item)
+ : Item_bool_func(), eval_item(0), cond_false(0), context_field(NULL)
{
const_item_cache= 0;
- fields.push_back(f);
- const_item= c;
- compare_as_dates= f->is_datetime();
+ with_const= with_const_item;
+ equal_items.push_back(f1);
+ equal_items.push_back(f2);
+ compare_as_dates= with_const_item && f2->cmp_type() == TIME_RESULT;
+ upper_levels= NULL;
}
+/**
+ Copy constructor for a multiple equality
+
+ @param item_equal source item for the constructor
+
+ @details
+ The function creates a copy of an Item_equal object.
+ This constructor is used when an item belongs to a multiple equality
+ of an upper level (an upper AND/OR level or an upper level of a nested
+ outer join).
+*/
+
Item_equal::Item_equal(Item_equal *item_equal)
- : Item_bool_func(), eval_item(0), cond_false(0)
+ : Item_bool_func(), eval_item(0), cond_false(0), context_field(NULL)
{
const_item_cache= 0;
- List_iterator_fast<Item_field> li(item_equal->fields);
- Item_field *item;
+ List_iterator_fast<Item> li(item_equal->equal_items);
+ Item *item;
while ((item= li++))
{
- fields.push_back(item);
+ equal_items.push_back(item);
}
- const_item= item_equal->const_item;
+ with_const= item_equal->with_const;
compare_as_dates= item_equal->compare_as_dates;
cond_false= item_equal->cond_false;
+ upper_levels= item_equal->upper_levels;
}
-void Item_equal::compare_const(Item *c)
+/**
+ @brief
+ Add a constant item to the Item_equal object
+
+ @param[in] c the constant to add
+ @param[in] f item from the list equal_items the item c is equal to
+ (this parameter is optional)
+
+ @details
+ The method adds the constant item c to the equal_items list. If the list
+ doesn't have any constant item yet the item c is just put in the front
+ the list. Otherwise the value of c is compared with the value of the
+ constant item from equal_items. If they are not equal cond_false is set
+ to TRUE. This serves as an indicator that this Item_equal is always FALSE.
+ The optional parameter f is used to adjust the flag compare_as_dates.
+*/
+
+void Item_equal::add_const(Item *c, Item *f)
{
+ if (cond_false)
+ return;
+ if (!with_const)
+ {
+ with_const= TRUE;
+ if (f)
+ compare_as_dates= f->cmp_type() == TIME_RESULT;
+ equal_items.push_front(c);
+ return;
+ }
+ Item *const_item= get_const();
if (compare_as_dates)
{
cmp.set_datetime_cmp_func(this, &c, &const_item);
@@ -5506,64 +5538,28 @@ void Item_equal::compare_const(Item *c)
}
-void Item_equal::add(Item *c, Item_field *f)
-{
- if (cond_false)
- return;
- if (!const_item)
- {
- DBUG_ASSERT(f);
- const_item= c;
- compare_as_dates= f->is_datetime();
- return;
- }
- compare_const(c);
-}
-
-
-void Item_equal::add(Item *c)
-{
- if (cond_false)
- return;
- if (!const_item)
- {
- const_item= c;
- return;
- }
- compare_const(c);
-}
-
-void Item_equal::add(Item_field *f)
-{
- fields.push_back(f);
-}
-
-uint Item_equal::members()
-{
- return fields.elements;
-}
-
-
/**
- Check whether a field is referred in the multiple equality.
-
- The function checks whether field is occurred in the Item_equal object .
+ @brief
+ Check whether a field is referred to in the multiple equality
@param field field whose occurrence is to be checked
+ @details
+ The function checks whether field is referred to by one of the
+ items from the equal_items list.
+
@retval
- 1 if nultiple equality contains a reference to field
+ 1 if multiple equality contains a reference to field
@retval
0 otherwise
*/
bool Item_equal::contains(Field *field)
{
- List_iterator_fast<Item_field> it(fields);
- Item_field *item;
- while ((item= it++))
+ Item_equal_fields_iterator it(*this);
+ while (it++)
{
- if (field->eq(item->field))
+ if (field->eq(it.get_curr_field()))
return 1;
}
return 0;
@@ -5571,87 +5567,221 @@ bool Item_equal::contains(Field *field)
/**
- Join members of another Item_equal object.
+ @brief
+ Join members of another Item_equal object
- The function actually merges two multiple equalities.
- After this operation the Item_equal object additionally contains
- the field items of another item of the type Item_equal.
- If the optional constant items are not equal the cond_false flag is
- set to 1.
@param item multiple equality whose members are to be joined
+
+ @details
+ The function actually merges two multiple equalities. After this operation
+ the Item_equal object additionally contains the field items of another item of
+ the type Item_equal.
+ If the optional constant items are not equal the cond_false flag is set to TRUE.
+
+ @notes
+ The function is called for any equality f1=f2 such that f1 and f2 are items
+ of the type Item_field or Item_direct_view_ref(Item_field), and, f1->field is
+ referred to in the list this->equal_items, while the list item->equal_items
+ contains a reference to f2->field.
*/
void Item_equal::merge(Item_equal *item)
{
- fields.concat(&item->fields);
- Item *c= item->const_item;
+ Item *c= item->get_const();
+ if (c)
+ item->equal_items.pop();
+ equal_items.concat(&item->equal_items);
if (c)
{
/*
- The flag cond_false will be set to 1 after this, if
+ The flag cond_false will be set to TRUE after this if
the multiple equality already contains a constant and its
- value is not equal to the value of c.
+ value is not equal to the value of c.
*/
- add(c);
+ add_const(c);
}
cond_false|= item->cond_false;
}
/**
- Order field items in multiple equality according to a sorting criteria.
+ @brief
+ Merge members of another Item_equal object into this one
+
+ @param item multiple equality whose members are to be merged
- The function perform ordering of the field items in the Item_equal
- object according to the criteria determined by the cmp callback parameter.
- If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
- placed after item_fiel2.
+ @details
+ If the Item_equal 'item' happened to have some elements of the list
+ of equal items belonging to 'this' object then the function merges
+ the equal items from 'item' into this list.
+ If both lists contains constants and they are different then
+ the value of the cond_false flag is set to TRUE.
- The function sorts field items by the exchange sort algorithm.
+ @retval
+ 1 the lists of equal items in 'item' and 'this' contain common elements
+ @retval
+ 0 otherwise
+
+ @notes
+ The method 'merge' just joins the list of equal items belonging to 'item'
+ to the list of equal items belonging to this object assuming that the lists
+ are disjoint. It would be more correct to call the method 'join'.
+ The method 'merge_with_check' really merges two lists of equal items if they
+ have common members.
+*/
+
+bool Item_equal::merge_with_check(Item_equal *item)
+{
+ bool intersected= FALSE;
+ Item_equal_fields_iterator_slow fi(*this);
+ while (fi++)
+ {
+ if (item->contains(fi.get_curr_field()))
+ {
+ fi.remove();
+ intersected= TRUE;
+ }
+ }
+ if (intersected)
+ item->merge(this);
+ return intersected;
+}
+
+
+/**
+ @brief
+ Merge this object into a list of Item_equal objects
+
+ @param list the list of Item_equal objects to merge into
+
+ @details
+ If the list of equal items from 'this' object contains common members
+ with the lists of equal items belonging to Item_equal objects from 'list'
+ then all involved Item_equal objects e1,...,ek are merged into one
+ Item equal that replaces e1,...,ek in the 'list'. Otherwise this
+ Item_equal is joined to the 'list'.
+*/
+
+void Item_equal::merge_into_list(List<Item_equal> *list)
+{
+ Item_equal *item;
+ List_iterator<Item_equal> it(*list);
+ Item_equal *merge_into= NULL;
+ while((item= it++))
+ {
+ if (!merge_into)
+ {
+ if (merge_with_check(item))
+ merge_into= item;
+ }
+ else
+ {
+ if (item->merge_with_check(merge_into))
+ it.remove();
+ }
+ }
+ if (!merge_into)
+ list->push_back(this);
+}
+
+
+/**
+ @brief
+ Order equal items of the multiple equality according to a sorting criteria
+
+ @param compare function to compare items from the equal_items list
+ @param arg context extra parameter for the cmp function
+
+ @details
+ The function performs ordering of the items from the equal_items list
+ according to the criteria determined by the cmp callback parameter.
+ If cmp(item1,item2,arg)<0 than item1 must be placed after item2.
+
+ @notes
+ The function sorts equal items by the bubble sort algorithm.
The list of field items is looked through and whenever two neighboring
members follow in a wrong order they are swapped. This is performed
again and again until we get all members in a right order.
-
- @param compare function to compare field item
- @param arg context extra parameter for the cmp function
*/
void Item_equal::sort(Item_field_cmpfunc compare, void *arg)
{
- exchange_sort<Item_field>(&fields, compare, arg);
+ bubble_sort<Item>(&equal_items, compare, arg);
}
/**
- Check appearance of new constant items in the multiple equality object.
+ @brief
+ Check appearance of new constant items in the multiple equality object
- The function checks appearance of new constant items among
- the members of multiple equalities. Each new constant item is
- compared with the designated constant item if there is any in the
- multiple equality. If there is none the first new constant item
- becomes designated.
+ @details
+ The function checks appearance of new constant items among the members
+ of the equal_items list. Each new constant item is compared with
+ the constant item from the list if there is any. If there is none the first
+ new constant item is placed at the very beginning of the list and
+ with_const is set to TRUE. If it happens that the compared constant items
+ are unequal then the flag cond_false is set to TRUE.
+
+ @notes
+ Currently this function is called only after substitution of constant tables.
*/
void Item_equal::update_const()
{
- List_iterator<Item_field> it(fields);
+ List_iterator<Item> it(equal_items);
+ if (with_const)
+ it++;
Item *item;
while ((item= it++))
{
- if (item->const_item())
+ if (item->const_item() && !item->is_expensive())
{
- it.remove();
- add(item);
- }
+ if (item == equal_items.head())
+ with_const= TRUE;
+ else
+ {
+ it.remove();
+ add_const(item);
+ }
+ }
}
}
+
+/**
+ @brief
+ Fix fields in a completely built multiple equality
+
+ @param thd currently not used thread handle
+ @param ref not used
+
+ @details
+ This function is called once the multiple equality has been built out of
+ the WHERE/ON condition and no new members are expected to be added to the
+ equal_items list anymore.
+ As any implementation of the virtual fix_fields method the function
+ calculates the cached values of not_null_tables_cache, used_tables_cache,
+ const_item_cache and calls fix_length_and_dec().
+ Additionally the function sets a reference to the Item_equal object in
+ the non-constant items of the equal_items list unless such a reference has
+ been already set.
+
+ @notes
+ Currently this function is called only in the function
+ build_equal_items_for_cond.
+
+ @retval
+ FALSE always
+*/
+
bool Item_equal::fix_fields(THD *thd, Item **ref)
-{
- List_iterator_fast<Item_field> li(fields);
+{
+ DBUG_ASSERT(fixed == 0);
+ Item_equal_fields_iterator it(*this);
Item *item;
not_null_tables_cache= used_tables_cache= 0;
const_item_cache= 0;
- while ((item= li++))
+ while ((item= it++))
{
table_map tmp_table_map;
used_tables_cache|= item->used_tables();
@@ -5659,62 +5789,98 @@ bool Item_equal::fix_fields(THD *thd, Item **ref)
not_null_tables_cache|= tmp_table_map;
DBUG_ASSERT(!item->with_sum_func && !item->with_subselect);
if (item->maybe_null)
- maybe_null=1;
+ maybe_null= 1;
+ if (!item->get_item_equal())
+ item->set_item_equal(this);
}
fix_length_and_dec();
fixed= 1;
- return 0;
+ return FALSE;
}
+
+/**
+ Update the value of the used table attribute and other attributes
+ */
+
void Item_equal::update_used_tables()
{
- List_iterator_fast<Item_field> li(fields);
- Item *item;
not_null_tables_cache= used_tables_cache= 0;
if ((const_item_cache= cond_false))
return;
+ Item_equal_fields_iterator it(*this);
+ Item *item;
const_item_cache= 1;
- while ((item=li++))
+ while ((item= it++))
{
item->update_used_tables();
used_tables_cache|= item->used_tables();
const_item_cache&= item->const_item();
+ if (!persistent_maybe_null && item->maybe_null)
+ maybe_null= 1;
}
}
+
+
+/**
+ @brief
+ Evaluate multiple equality
+
+ @details
+ The function evaluate multiple equality to a boolean value.
+ The function ignores non-constant items from the equal_items list.
+ The function returns 1 if all constant items from the list are equal.
+ It returns 0 if there are unequal constant items in the list or
+ one of the constant items is evaluated to NULL.
+
+ @notes
+ Currently this function can be called only at the optimization
+ stage after the constant table substitution, since all Item_equals
+ are eliminated before the execution stage.
+
+ @retval
+ 0 multiple equality is always FALSE or NULL
+ 1 otherwise
+*/
+
longlong Item_equal::val_int()
{
- Item_field *item_field;
if (cond_false)
return 0;
- List_iterator_fast<Item_field> it(fields);
- Item *item= const_item ? const_item : it++;
- if ((null_value= item->is_null()))
- return 0;
+ Item *item= get_const();
+ Item_equal_fields_iterator it(*this);
+ if (!item)
+ item= it++;
eval_item->store_value(item);
- while ((item_field= it++))
+ if ((null_value= item->null_value))
+ return 0;
+ while ((item= it++))
{
+ Field *field= it.get_curr_field();
/* Skip fields of non-const tables. They haven't been read yet */
- if (item_field->field->table->const_table)
+ if (field->table->const_table)
{
- if ((null_value= item_field->is_null()) || eval_item->cmp(item_field))
+ if (eval_item->cmp(item) || (null_value= item->null_value))
return 0;
}
}
return 1;
}
+
void Item_equal::fix_length_and_dec()
{
- Item *item= get_first();
- eval_item= cmp_item::get_comparator(item->result_type(),
+ Item *item= get_first(NO_PARTICULAR_TAB, NULL);
+ eval_item= cmp_item::get_comparator(item->cmp_type(), item,
item->collation.collation);
}
+
bool Item_equal::walk(Item_processor processor, bool walk_subquery, uchar *arg)
{
- List_iterator_fast<Item_field> it(fields);
Item *item;
+ Item_equal_fields_iterator it(*this);
while ((item= it++))
{
if (item->walk(processor, walk_subquery, arg))
@@ -5723,12 +5889,13 @@ bool Item_equal::walk(Item_processor processor, bool walk_subquery, uchar *arg)
return Item_func::walk(processor, walk_subquery, arg);
}
+
Item *Item_equal::transform(Item_transformer transformer, uchar *arg)
{
DBUG_ASSERT(!current_thd->is_stmt_prepare());
- List_iterator<Item_field> it(fields);
Item *item;
+ Item_equal_fields_iterator it(*this);
while ((item= it++))
{
Item *new_item= item->transform(transformer, arg);
@@ -5747,19 +5914,20 @@ Item *Item_equal::transform(Item_transformer transformer, uchar *arg)
return Item_func::transform(transformer, arg);
}
+
void Item_equal::print(String *str, enum_query_type query_type)
{
+ if (cond_false)
+ {
+ str->append('0');
+ return;
+ }
str->append(func_name());
str->append('(');
- List_iterator_fast<Item_field> it(fields);
+ List_iterator_fast<Item> it(equal_items);
Item *item;
- if (const_item)
- const_item->print(str, query_type);
- else
- {
- item= it++;
- item->print(str, query_type);
- }
+ item= it++;
+ item->print(str, query_type);
while ((item= it++))
{
str->append(',');
@@ -5769,3 +5937,153 @@ void Item_equal::print(String *str, enum_query_type query_type)
str->append(')');
}
+
+CHARSET_INFO *Item_equal::compare_collation()
+{
+ Item_equal_fields_iterator it(*this);
+ Item *item= it++;
+ return item->collation.collation;
+}
+
+
+/*
+ @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* Item_equal::get_first(JOIN_TAB *context, Item *field_item)
+{
+ Item_equal_fields_iterator it(*this);
+ Item *item;
+ if (!field_item)
+ return (it++);
+ Field *field= ((Item_field *) (field_item->real_item()))->field;
+
+ /*
+ 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.
+ */
+
+ TABLE_LIST *emb_nest;
+ if (context != NO_PARTICULAR_TAB)
+ emb_nest= context->emb_sj_nest;
+ else
+ emb_nest= 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 for
+ - a constant item
+ - a field from the same semi-join
+ Find the first of such items:
+ */
+ while ((item= it++))
+ {
+ if (item->const_item() ||
+ it.get_curr_field()->table->pos_in_table_list->embedding == emb_nest)
+ {
+ /*
+ If we found given field then return NULL to avoid unnecessary
+ substitution.
+ */
+ return (item != field_item) ? item : NULL;
+ }
+ }
+ }
+ else
+ {
+ /*
+ The field is not in SJ-Materialization nest. We must return the first
+ field in the join order. The field may be inside a semi-join nest, i.e
+ a join order may look like this:
+
+ SJ-Mat(it1 it2) ot1 ot2
+
+ where we're looking what to substitute ot2.col for. In this case we must
+ still return it1.col, here's a proof why:
+
+ First let's note that either it1.col or it2.col participates in
+ subquery's IN-equality. It can't be otherwise, because materialization is
+ only applicable to uncorrelated subqueries, so the only way we could
+ infer "it1.col=ot1.col" is from the IN-equality. Ok, so IN-eqality has
+ it1.col or it2.col on its inner side. it1.col is first such item in the
+ join order, so it's not possible for SJ-Mat to be
+ SJ-Materialization-lookup, it is SJ-Materialization-Scan. The scan part
+ of this strategy will unpack value of it1.col=it2.col into it1.col
+ (that's the first equal item inside the subquery), and we'll be able to
+ get it from there. qed.
+ */
+
+ return equal_items.head();
+ }
+ // Shouldn't get here.
+ DBUG_ASSERT(0);
+ return NULL;
+}
+
+
+longlong Item_func_dyncol_exists::val_int()
+{
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String tmp(buff, sizeof(buff), &my_charset_bin);
+ DYNAMIC_COLUMN col;
+ String *str;
+ ulonglong num;
+ enum enum_dyncol_func_result rc;
+
+ num= args[1]->val_int();
+ str= args[0]->val_str(&tmp);
+ if (args[0]->null_value || args[1]->null_value || num > UINT_MAX16)
+ goto null;
+ col.length= str->length();
+ /* We do not change the string, so could do this trick */
+ col.str= (char *)str->ptr();
+ rc= dynamic_column_exists(&col, (uint) num);
+ if (rc < 0)
+ {
+ dynamic_column_error_message(rc);
+ goto null;
+ }
+ null_value= FALSE;
+ return rc == ER_DYNCOL_YES;
+
+null:
+ null_value= TRUE;
+ return 0;
+}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 7239079c56f..de67d260c76 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+ Copyright (c) 2009-2011, Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,39 +27,29 @@ class Arg_comparator;
typedef int (Arg_comparator::*arg_cmp_func)();
-typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
+typedef int (*Item_field_cmpfunc)(Item *f1, Item *f2, void *arg);
class Arg_comparator: public Sql_alloc
{
Item **a, **b;
arg_cmp_func func;
Item_result_field *owner;
+ bool set_null; // TRUE <=> set owner->null_value
Arg_comparator *comparators; // used only for compare_row()
double precision;
/* Fields used in DATE/DATETIME comparison. */
THD *thd;
- enum_field_types a_type, b_type; // Types of a and b items
Item *a_cache, *b_cache; // Cached values of a and b items
- bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
- bool set_null; // TRUE <=> set owner->null_value
// when one of arguments is NULL.
- enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
- CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
- longlong (*get_value_a_func)(THD *thd, Item ***item_arg, Item **cache_arg,
- Item *warn_item, bool *is_null);
- longlong (*get_value_b_func)(THD *thd, Item ***item_arg, Item **cache_arg,
- Item *warn_item, bool *is_null);
- bool try_year_cmp_func(Item_result type);
public:
DTCollation cmp_collation;
/* Allow owner function to use string buffers. */
String value1, value2;
- Arg_comparator(): comparators(0), thd(0), a_cache(0), b_cache(0), set_null(TRUE),
- get_value_a_func(0), get_value_b_func(0) {};
- Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), comparators(0), thd(0),
- a_cache(0), b_cache(0), set_null(TRUE),
- get_value_a_func(0), get_value_b_func(0) {};
+ Arg_comparator(): set_null(TRUE), comparators(0), thd(0),
+ a_cache(0), b_cache(0) {};
+ Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), set_null(TRUE),
+ comparators(0), thd(0), a_cache(0), b_cache(0) {};
int set_compare_func(Item_result_field *owner, Item_result type);
inline int set_compare_func(Item_result_field *owner_arg)
@@ -75,8 +66,8 @@ public:
{
set_null= set_null_arg;
return set_cmp_func(owner_arg, a1, a2,
- item_cmp_type((*a1)->result_type(),
- (*a2)->result_type()));
+ item_cmp_type((*a1)->cmp_type(),
+ (*a2)->cmp_type()));
}
inline int compare() { return (this->*func)(); }
@@ -99,14 +90,12 @@ public:
int compare_real_fixed();
int compare_e_real_fixed();
int compare_datetime(); // compare args[0] & args[1] as DATETIMEs
-
- static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b,
- ulonglong *const_val_arg);
+ int compare_e_datetime();
Item** cache_converted_constant(THD *thd, Item **value, Item **cache,
Item_result type);
void set_datetime_cmp_func(Item_result_field *owner_arg, Item **a1, Item **b1);
- static arg_cmp_func comparator_matrix [5][2];
+ static arg_cmp_func comparator_matrix [6][2];
inline bool is_owner_equal_func()
{
return (owner->type() == Item::FUNC_ITEM &&
@@ -242,6 +231,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 +242,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)
{ with_subselect= true; }
bool fix_fields(THD *, Item **);
@@ -264,6 +254,16 @@ 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);
+ bool is_expensive_processor(uchar *arg);
+ bool is_expensive();
+ void set_join_tab_idx(uint join_tab_idx_arg)
+ { args[1]->set_join_tab_idx(join_tab_idx_arg); }
+ virtual void get_cache_parameters(List<Item> &parameters);
+ bool is_top_level_item();
+ bool eval_not_null_tables(uchar *opt_arg);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
};
class Comp_creator
@@ -384,6 +384,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();
@@ -402,7 +403,30 @@ public:
}
Item *neg_transformer(THD *thd);
virtual Item *negated_item();
- bool subst_argument_checker(uchar **arg) { return TRUE; }
+ bool subst_argument_checker(uchar **arg)
+ {
+ return (*arg != NULL);
+ }
+};
+
+/**
+ XOR inherits from Item_bool_func2 because it is not optimized yet.
+ Later, when XOR is optimized, it needs to inherit from
+ Item_cond instead. See WL#5800.
+*/
+class Item_func_xor :public Item_bool_func2
+{
+public:
+ Item_func_xor(Item *i1, Item *i2) :Item_bool_func2(i1, i2) {}
+ enum Functype functype() const { return XOR_FUNC; }
+ const char *func_name() const { return "xor"; }
+ longlong val_int();
+ void top_level_item() {}
+ Item *neg_transformer(THD *thd);
+ bool subst_argument_checker(uchar **arg)
+ {
+ return (*arg != NULL);
+ }
};
class Item_func_not :public Item_bool_func
@@ -475,8 +499,8 @@ public:
show(0)
{}
virtual void top_level_item() { abort_on_null= 1; }
+ bool is_top_level_item() { return abort_on_null; }
table_map not_null_tables() const { return 0; }
- bool top_level() { return abort_on_null; }
longlong val_int();
enum Functype functype() const { return NOT_ALL_FUNC; }
const char *func_name() const { return "<not>"; }
@@ -504,13 +528,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
@@ -632,9 +666,7 @@ public:
Item_result cmp_type;
String value0,value1,value2;
/* TRUE <=> arguments will be compared as dates. */
- bool compare_as_dates;
- /* Comparators used for DATE/DATETIME comparison. */
- Arg_comparator ge_cmp, le_cmp;
+ Item *compare_as_dates;
Item_func_between(Item *a, Item *b, Item *c)
:Item_func_opt_neg(a, b, c), compare_as_dates(FALSE) {}
longlong val_int();
@@ -647,6 +679,8 @@ public:
bool is_bool_func() { return 1; }
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
uint decimal_precision() const { return 1; }
+ bool eval_not_null_tables(uchar *opt_arg);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
};
@@ -707,6 +741,7 @@ public:
const char *func_name() const { return "coalesce"; }
table_map not_null_tables() const { return 0; }
enum_field_types field_type() const { return cached_field_type; }
+ bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
};
@@ -722,6 +757,11 @@ public:
my_decimal *decimal_op(my_decimal *);
enum_field_types field_type() const;
void fix_length_and_dec();
+ void update_used_tables()
+ {
+ Item_func_coalesce::update_used_tables();
+ maybe_null|= args[1]->maybe_null;
+ }
const char *func_name() const { return "ifnull"; }
Field *tmp_table_field(TABLE *table);
uint decimal_precision() const;
@@ -744,8 +784,15 @@ public:
enum_field_types field_type() const { return cached_field_type; }
bool fix_fields(THD *, Item **);
void fix_length_and_dec();
+ void update_used_tables()
+ {
+ Item_func::update_used_tables();
+ maybe_null|= args[1]->maybe_null || args[2]->maybe_null;
+ }
uint decimal_precision() const;
const char *func_name() const { return "if"; }
+ bool eval_not_null_tables(uchar *opt_arg);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
};
@@ -912,6 +959,16 @@ public:
lval_cache(0) {};
void set(uint pos,Item *item);
uchar *get_value(Item *item);
+ Item* create_item()
+ {
+ return new Item_datetime();
+ }
+ void value_to_item(uint pos, Item *item)
+ {
+ packed_longlong *val= reinterpret_cast<packed_longlong*>(base)+pos;
+ Item_datetime *dt= reinterpret_cast<Item_datetime*>(item);
+ dt->set(val->val);
+ }
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
};
@@ -971,7 +1028,8 @@ public:
virtual int cmp(Item *item)= 0;
// for optimized IN with row
virtual int compare(cmp_item *item)= 0;
- static cmp_item* get_comparator(Item_result type, CHARSET_INFO *cs);
+ static cmp_item* get_comparator(Item_result type, Item * warn_item,
+ CHARSET_INFO *cs);
virtual cmp_item *make_same()= 0;
virtual void store_value_by_template(cmp_item *tmpl, Item *item)
{
@@ -1167,7 +1225,7 @@ class Item_func_case :public Item_func
Item_result cmp_type;
DTCollation cmp_collation;
enum_field_types cached_field_type;
- cmp_item *cmp_items[5]; /* For all result types */
+ cmp_item *cmp_items[6]; /* For all result types */
cmp_item *case_item;
public:
Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
@@ -1194,6 +1252,12 @@ public:
my_decimal *val_decimal(my_decimal *);
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec();
+ void update_used_tables()
+ {
+ Item_func::update_used_tables();
+ if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
+ maybe_null= 1;
+ }
uint decimal_precision() const;
table_map not_null_tables() const { return 0; }
enum Item_result result_type () const { return cached_result_type; }
@@ -1257,7 +1321,7 @@ public:
Item_int_func::cleanup();
delete array;
array= 0;
- for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
+ for (i= 0; i <= (uint)TIME_RESULT; i++)
{
delete cmp_items[i];
cmp_items[i]= 0;
@@ -1272,6 +1336,8 @@ public:
bool nulls_in_row();
bool is_bool_func() { return 1; }
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
+ bool eval_not_null_tables(uchar *opt_arg);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
};
class cmp_item_row :public cmp_item
@@ -1307,36 +1373,29 @@ public:
class Item_func_isnull :public Item_bool_func
{
-protected:
- longlong cached_value;
public:
Item_func_isnull(Item *a) :Item_bool_func(a) {}
longlong val_int();
enum Functype functype() const { return ISNULL_FUNC; }
void fix_length_and_dec()
{
- decimals=0; max_length=1; maybe_null=0;
+ decimals=0; max_length=1; set_persist_maybe_null(0);
update_used_tables();
}
const char *func_name() const { return "isnull"; }
/* Optimize case of not_null_column IS NULL */
virtual void update_used_tables()
{
+ args[0]->update_used_tables();
if (!args[0]->maybe_null)
{
used_tables_cache= 0; /* is always false */
const_item_cache= 1;
- cached_value= (longlong) 0;
}
else
{
- args[0]->update_used_tables();
- if ((const_item_cache= !(used_tables_cache= args[0]->used_tables()) &&
- !with_subselect))
- {
- /* Remember if the value is always NULL or never NULL */
- cached_value= (longlong) args[0]->is_null();
- }
+ used_tables_cache= args[0]->used_tables();
+ const_item_cache= args[0]->const_item();
}
}
table_map not_null_tables() const { return 0; }
@@ -1381,7 +1440,7 @@ public:
enum Functype functype() const { return ISNOTNULL_FUNC; }
void fix_length_and_dec()
{
- decimals=0; max_length=1; maybe_null=0;
+ decimals=0; max_length=1; set_persist_maybe_null(0);
}
const char *func_name() const { return "isnotnull"; }
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
@@ -1452,6 +1511,12 @@ public:
void cleanup();
longlong val_int();
bool fix_fields(THD *thd, Item **ref);
+ void update_used_tables()
+ {
+ Item_bool_func::update_used_tables();
+ if (regex_is_const)
+ maybe_null= 1;
+ }
const char *func_name() const { return "regexp"; }
virtual inline void print(String *str, enum_query_type query_type)
@@ -1517,7 +1582,13 @@ public:
DBUG_ASSERT(nlist->elements);
list.prepand(nlist);
}
+ void add_at_end(List<Item> *nlist)
+ {
+ DBUG_ASSERT(nlist->elements);
+ list.concat(nlist);
+ }
bool fix_fields(THD *, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
enum Type type() const { return COND_ITEM; }
List<Item>* argument_list() { return &list; }
@@ -1538,8 +1609,10 @@ public:
bool subst_argument_checker(uchar **arg) { return TRUE; }
Item *compile(Item_analyzer analyzer, uchar **arg_p,
Item_transformer transformer, uchar *arg_t);
+ bool eval_not_null_tables(uchar *opt_arg);
};
+template <template<class> class LI, class T> class Item_equal_iterator;
/*
The class Item_equal is used to represent conjunctions of equality
@@ -1618,44 +1691,99 @@ public:
class Item_equal: public Item_bool_func
{
- List<Item_field> fields; /* list of equal field items */
- Item *const_item; /* optional constant item equal to fields items */
+ /*
+ The list of equal items. Currently the list can contain:
+ - Item_fields items for references to table columns
+ - Item_direct_view_ref items for references to view columns
+ - one const item
+
+ If the list contains a constant item this item is always first in the list.
+ The list contains at least two elements.
+ Currently all Item_fields/Item_direct_view_ref items in the list should
+ refer to table columns with equavalent type definitions. In particular
+ if these are string columns they should have the same charset/collation.
+
+ Use objects of the companion class Item_equal_fields_iterator to iterate
+ over all items from the list of the Item_field/Item_direct_view_ref classes.
+ */
+ List<Item> equal_items;
+ /*
+ TRUE <-> one of the items is a const item.
+ Such item is always first in in the equal_items list
+ */
+ bool with_const;
+ /*
+ The field eval_item is used when this item is evaluated
+ with the method val_int()
+ */
cmp_item *eval_item;
- Arg_comparator cmp;
+ /*
+ This initially is set to FALSE. It becomes TRUE when this item is evaluated
+ as being always false. If the flag is TRUE the contents of the list
+ the equal_items should be ignored.
+ */
bool cond_false;
+ /*
+ compare_as_dates=TRUE <-> constants equal to fields from equal_items
+ must be compared as datetimes and not as strings.
+ compare_as_dates can be TRUE only if with_const=TRUE
+ */
bool compare_as_dates;
+ /*
+ The comparator used to compare constants equal to fields from equal_items
+ as datetimes. The comparator is used only if compare_as_dates=TRUE
+ */
+ Arg_comparator cmp;
+
+ /*
+ For Item_equal objects inside an OR clause: one of the fields that were
+ used in the original equality.
+ */
+ Item_field *context_field;
+
public:
+
+ COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
+
inline Item_equal()
- : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
+ : Item_bool_func(), with_const(FALSE), eval_item(0), cond_false(0),
+ context_field(NULL)
{ const_item_cache=0 ;}
- Item_equal(Item_field *f1, Item_field *f2);
- Item_equal(Item *c, Item_field *f);
+ Item_equal(Item *f1, Item *f2, bool with_const_item);
Item_equal(Item_equal *item_equal);
- inline Item* get_const() { return const_item; }
- void compare_const(Item *c);
- void add(Item *c, Item_field *f);
- void add(Item *c);
- void add(Item_field *f);
- uint members();
+ /* Currently the const item is always the first in the list of equal items */
+ inline Item* get_const() { return with_const ? equal_items.head() : NULL; }
+ void add_const(Item *c, Item *f = NULL);
+ /** Add a non-constant item to the multiple equality */
+ void add(Item *f) { equal_items.push_back(f); }
bool contains(Field *field);
- Item_field* get_first() { return fields.head(); }
- uint n_fields() { return fields.elements; }
+ Item* get_first(struct st_join_table *context, Item *field);
+ /** Get number of field items / references to field items in this object */
+ uint n_field_items() { return equal_items.elements-test(with_const); }
void merge(Item_equal *item);
+ bool merge_with_check(Item_equal *equal_item);
+ void merge_into_list(List<Item_equal> *list);
void update_const();
enum Functype functype() const { return MULT_EQUAL_FUNC; }
longlong val_int();
const char *func_name() const { return "multiple equal"; }
optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
void sort(Item_field_cmpfunc compare, void *arg);
- friend class Item_equal_iterator;
void fix_length_and_dec();
bool fix_fields(THD *thd, Item **ref);
void update_used_tables();
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
Item *transform(Item_transformer transformer, uchar *arg);
virtual void print(String *str, enum_query_type query_type);
- CHARSET_INFO *compare_collation()
- { return fields.head()->collation.collation; }
+ CHARSET_INFO *compare_collation();
+
+ void set_context_field(Item_field *ctx_field) { context_field= ctx_field; }
+ friend class Item_equal_iterator<List_iterator_fast,Item>;
+ friend class Item_equal_iterator<List_iterator,Item>;
+ friend Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
+ Item_equal *item_equal);
+ friend bool setup_sj_materialization_part1(struct st_join_table *tab);
+ friend bool setup_sj_materialization_part2(struct st_join_table *tab);
};
class COND_EQUAL: public Sql_alloc
@@ -1673,23 +1801,83 @@ public:
};
-class Item_equal_iterator : public List_iterator_fast<Item_field>
+/*
+ The template Item_equal_iterator is used to define classes
+ Item_equal_fields_iterator and Item_equal_fields_iterator_slow.
+ These are helper classes for the class Item equal
+ Both classes are used to iterate over references to table/view columns
+ from the list of equal items that included in an Item_equal object.
+ The second class supports the operation of removal of the current member
+ from the list when performing an iteration.
+*/
+
+template <template<class> class LI, class T> class Item_equal_iterator
+ : public LI<T>
{
+protected:
+ Item_equal *item_equal;
+ Item *curr_item;
public:
- inline Item_equal_iterator(Item_equal &item_equal)
- :List_iterator_fast<Item_field> (item_equal.fields)
- {}
- inline Item_field* operator++(int)
+ Item_equal_iterator<LI,T>(Item_equal &item_eq)
+ :LI<T> (item_eq.equal_items)
+ {
+ curr_item= NULL;
+ item_equal= &item_eq;
+ if (item_eq.with_const)
+ {
+ LI<T> *list_it= this;
+ curr_item= (*list_it)++;
+ }
+ }
+ Item* operator++(int)
{
- Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
- return item;
+ LI<T> *list_it= this;
+ curr_item= (*list_it)++;
+ return curr_item;
}
- inline void rewind(void)
+ void rewind(void)
{
- List_iterator_fast<Item_field>::rewind();
+ LI<T> *list_it= this;
+ list_it->rewind();
+ if (item_equal->with_const)
+ curr_item= (*list_it)++;
+ }
+ Field *get_curr_field()
+ {
+ Item_field *item= (Item_field *) (curr_item->real_item());
+ return item->field;
+ }
+};
+
+
+class Item_equal_fields_iterator
+ :public Item_equal_iterator<List_iterator_fast,Item >
+{
+public:
+ Item_equal_fields_iterator(Item_equal &item_eq)
+ :Item_equal_iterator<List_iterator_fast,Item>(item_eq)
+ { }
+ Item ** ref()
+ {
+ return List_iterator_fast<Item>::ref();
}
};
+
+class Item_equal_fields_iterator_slow
+ :public Item_equal_iterator<List_iterator,Item >
+{
+public:
+ Item_equal_fields_iterator_slow(Item_equal &item_eq)
+ :Item_equal_iterator<List_iterator,Item>(item_eq)
+ { }
+ void remove()
+ {
+ List_iterator<Item>::remove();
+ }
+};
+
+
class Item_cond_and :public Item_cond
{
public:
@@ -1713,6 +1901,7 @@ public:
return item;
}
Item *neg_transformer(THD *thd);
+ void mark_as_condition_AND_part(TABLE_LIST *embedding);
};
inline bool is_cond_and(Item *item)
@@ -1754,25 +1943,6 @@ inline bool is_cond_or(Item *item)
return (cond_item->functype() == Item_func::COND_OR_FUNC);
}
-/*
- XOR is Item_cond, not an Item_int_func because we could like to
- optimize (a XOR b) later on. It's low prio, though
-*/
-
-class Item_cond_xor :public Item_cond
-{
-public:
- Item_cond_xor() :Item_cond() {}
- Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,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() {}
-};
-
-
/* Some useful inline functions */
inline Item *and_conds(Item *a, Item *b)
@@ -1786,3 +1956,11 @@ Item *and_expressions(Item *a, Item *b, Item **org_item);
bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
const char *warn_name, MYSQL_TIME *l_time);
+
+class Item_func_dyncol_exists :public Item_bool_func
+{
+public:
+ Item_func_dyncol_exists(Item *str, Item *num) :Item_bool_func(str, num) {}
+ longlong val_int();
+ const char *func_name() const { return "column_exists"; }
+};
diff --git a/sql/item_create.cc b/sql/item_create.cc
index a5dc3eeb5ad..70b9b1754f3 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -30,6 +30,69 @@
/*
=============================================================================
+ HELPER FUNCTIONS
+=============================================================================
+*/
+
+static const char* item_name(Item *a, String *str)
+{
+ if (a->name)
+ return a->name;
+ str->length(0);
+ a->print(str, QT_ORDINARY);
+ return str->c_ptr_safe();
+}
+
+
+static void wrong_precision_error(uint errcode, Item *a,
+ ulonglong number, ulong maximum)
+{
+ char buff[1024];
+ String buf(buff, sizeof(buff), system_charset_info);
+
+ my_error(errcode, MYF(0), (uint) min(number, UINT_MAX32),
+ item_name(a, &buf), maximum);
+}
+
+
+/**
+ Get precision and scale for a declaration
+
+ return
+ 0 ok
+ 1 error
+*/
+
+bool get_length_and_scale(ulonglong length, ulonglong decimals,
+ ulong *out_length, uint *out_decimals,
+ uint max_precision, uint max_scale,
+ Item *a)
+{
+ if (length > (ulonglong) max_precision)
+ {
+ wrong_precision_error(ER_TOO_BIG_PRECISION, a, length, max_precision);
+ return 1;
+ }
+ if (decimals > (ulonglong) max_scale)
+ {
+ wrong_precision_error(ER_TOO_BIG_SCALE, a, decimals, max_scale);
+ return 1;
+ }
+
+ *out_length= (ulong) length;
+ *out_decimals= (uint) decimals;
+ my_decimal_trim(out_length, out_decimals);
+
+ if (*out_length < *out_decimals)
+ {
+ my_error(ER_M_BIGGER_THAN_D, MYF(0), "");
+ return 1;
+ }
+ return 0;
+}
+
+/*
+=============================================================================
LOCAL DECLARATIONS
=============================================================================
*/
@@ -512,6 +575,19 @@ protected:
#ifdef HAVE_SPATIAL
+class Create_func_mbr_contains : public Create_func_arg2
+{
+ public:
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_mbr_contains s_singleton;
+
+ protected:
+ Create_func_mbr_contains() {}
+ virtual ~Create_func_mbr_contains() {}
+};
+
+
class Create_func_contains : public Create_func_arg2
{
public:
@@ -752,6 +828,19 @@ protected:
#ifdef HAVE_SPATIAL
+class Create_func_mbr_disjoint : public Create_func_arg2
+{
+ public:
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_mbr_disjoint s_singleton;
+
+ protected:
+ Create_func_mbr_disjoint() {}
+ virtual ~Create_func_mbr_disjoint() {}
+};
+
+
class Create_func_disjoint : public Create_func_arg2
{
public:
@@ -763,6 +852,19 @@ protected:
Create_func_disjoint() {}
virtual ~Create_func_disjoint() {}
};
+
+
+class Create_func_distance : public Create_func_arg2
+{
+ public:
+ virtual Item* create_2_arg(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_distance s_singleton;
+
+ protected:
+ Create_func_distance() {}
+ virtual ~Create_func_distance() {}
+};
#endif
@@ -836,6 +938,19 @@ protected:
#ifdef HAVE_SPATIAL
+class Create_func_mbr_equals : public Create_func_arg2
+{
+ public:
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_mbr_equals s_singleton;
+
+ protected:
+ Create_func_mbr_equals() {}
+ virtual ~Create_func_mbr_equals() {}
+};
+
+
class Create_func_equals : public Create_func_arg2
{
public:
@@ -1164,6 +1279,19 @@ protected:
#ifdef HAVE_SPATIAL
+class Create_func_mbr_intersects : public Create_func_arg2
+{
+ public:
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_mbr_intersects s_singleton;
+
+ protected:
+ Create_func_mbr_intersects() {}
+ virtual ~Create_func_mbr_intersects() {}
+};
+
+
class Create_func_intersects : public Create_func_arg2
{
public:
@@ -1175,7 +1303,72 @@ protected:
Create_func_intersects() {}
virtual ~Create_func_intersects() {}
};
-#endif
+
+
+class Create_func_intersection : public Create_func_arg2
+{
+public:
+ virtual Item* create_2_arg(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_intersection s_singleton;
+
+protected:
+ Create_func_intersection() {}
+ virtual ~Create_func_intersection() {}
+};
+
+
+class Create_func_difference : public Create_func_arg2
+{
+public:
+ virtual Item* create_2_arg(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_difference s_singleton;
+
+protected:
+ Create_func_difference() {}
+ virtual ~Create_func_difference() {}
+};
+
+
+class Create_func_union : public Create_func_arg2
+{
+public:
+ virtual Item* create_2_arg(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_union s_singleton;
+
+protected:
+ Create_func_union() {}
+ virtual ~Create_func_union() {}
+};
+
+
+class Create_func_symdifference : public Create_func_arg2
+{
+public:
+ virtual Item* create_2_arg(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_symdifference s_singleton;
+
+protected:
+ Create_func_symdifference() {}
+ virtual ~Create_func_symdifference() {}
+};
+
+
+class Create_func_buffer : public Create_func_arg2
+{
+public:
+ virtual Item* create_2_arg(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_buffer s_singleton;
+
+protected:
+ Create_func_buffer() {}
+ virtual ~Create_func_buffer() {}
+};
+#endif /*HAVE_SPATIAL*/
class Create_func_is_free_lock : public Create_func_arg1
@@ -1607,6 +1800,19 @@ protected:
#ifdef HAVE_SPATIAL
+class Create_func_mbr_overlaps : public Create_func_arg2
+{
+ public:
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_mbr_overlaps s_singleton;
+
+ protected:
+ Create_func_mbr_overlaps() {}
+ virtual ~Create_func_mbr_overlaps() {}
+};
+
+
class Create_func_overlaps : public Create_func_arg2
{
public:
@@ -2202,6 +2408,19 @@ protected:
#ifdef HAVE_SPATIAL
+class Create_func_mbr_within : public Create_func_arg2
+{
+ public:
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_mbr_within s_singleton;
+
+ protected:
+ Create_func_mbr_within() {}
+ virtual ~Create_func_mbr_within() {}
+};
+
+
class Create_func_within : public Create_func_arg2
{
public:
@@ -2893,6 +3112,16 @@ Create_func_connection_id::create_builder(THD *thd)
#ifdef HAVE_SPATIAL
+Create_func_mbr_contains Create_func_mbr_contains::s_singleton;
+
+Item*
+Create_func_mbr_contains::create_2_arg(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_spatial_mbr_rel(arg1, arg2,
+ Item_func::SP_CONTAINS_FUNC);
+}
+
+
Create_func_contains Create_func_contains::s_singleton;
Item*
@@ -3125,6 +3354,16 @@ Create_func_dimension::create_1_arg(THD *thd, Item *arg1)
#ifdef HAVE_SPATIAL
+Create_func_mbr_disjoint Create_func_mbr_disjoint::s_singleton;
+
+Item*
+Create_func_mbr_disjoint::create_2_arg(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_spatial_mbr_rel(arg1, arg2,
+ Item_func::SP_DISJOINT_FUNC);
+}
+
+
Create_func_disjoint Create_func_disjoint::s_singleton;
Item*
@@ -3133,6 +3372,15 @@ Create_func_disjoint::create_2_arg(THD *thd, Item *arg1, Item *arg2)
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_DISJOINT_FUNC);
}
+
+
+Create_func_distance Create_func_distance::s_singleton;
+
+Item*
+Create_func_distance::create_2_arg(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_distance(arg1, arg2);
+}
#endif
@@ -3228,6 +3476,16 @@ Create_func_envelope::create_1_arg(THD *thd, Item *arg1)
#ifdef HAVE_SPATIAL
+Create_func_mbr_equals Create_func_mbr_equals::s_singleton;
+
+Item*
+Create_func_mbr_equals::create_2_arg(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_spatial_mbr_rel(arg1, arg2,
+ Item_func::SP_EQUALS_FUNC);
+}
+
+
Create_func_equals Create_func_equals::s_singleton;
Item*
@@ -3623,6 +3881,16 @@ Create_func_interiorringn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
#ifdef HAVE_SPATIAL
+Create_func_mbr_intersects Create_func_mbr_intersects::s_singleton;
+
+Item*
+Create_func_mbr_intersects::create_2_arg(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_spatial_mbr_rel(arg1, arg2,
+ Item_func::SP_INTERSECTS_FUNC);
+}
+
+
Create_func_intersects Create_func_intersects::s_singleton;
Item*
@@ -3631,7 +3899,56 @@ Create_func_intersects::create_2_arg(THD *thd, Item *arg1, Item *arg2)
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_INTERSECTS_FUNC);
}
-#endif
+
+
+Create_func_intersection Create_func_intersection::s_singleton;
+
+Item*
+Create_func_intersection::create_2_arg(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_spatial_operation(arg1, arg2,
+ Gcalc_function::op_intersection);
+}
+
+
+Create_func_difference Create_func_difference::s_singleton;
+
+Item*
+Create_func_difference::create_2_arg(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_spatial_operation(arg1, arg2,
+ Gcalc_function::op_difference);
+}
+
+
+Create_func_union Create_func_union::s_singleton;
+
+Item*
+Create_func_union::create_2_arg(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_spatial_operation(arg1, arg2,
+ Gcalc_function::op_union);
+}
+
+
+Create_func_symdifference Create_func_symdifference::s_singleton;
+
+Item*
+Create_func_symdifference::create_2_arg(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_spatial_operation(arg1, arg2,
+ Gcalc_function::op_symdifference);
+}
+
+
+Create_func_buffer Create_func_buffer::s_singleton;
+
+Item*
+Create_func_buffer::create_2_arg(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_buffer(arg1, arg2);
+}
+#endif /*HAVE_SPATAI*/
Create_func_is_free_lock Create_func_is_free_lock::s_singleton;
@@ -4091,6 +4408,16 @@ Create_func_ord::create_1_arg(THD *thd, Item *arg1)
#ifdef HAVE_SPATIAL
+Create_func_mbr_overlaps Create_func_mbr_overlaps::s_singleton;
+
+Item*
+Create_func_mbr_overlaps::create_2_arg(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_spatial_mbr_rel(arg1, arg2,
+ Item_func::SP_OVERLAPS_FUNC);
+}
+
+
Create_func_overlaps Create_func_overlaps::s_singleton;
Item*
@@ -4643,6 +4970,16 @@ Create_func_weekofyear::create_1_arg(THD *thd, Item *arg1)
#ifdef HAVE_SPATIAL
+Create_func_mbr_within Create_func_mbr_within::s_singleton;
+
+Item*
+Create_func_mbr_within::create_2_arg(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_spatial_mbr_rel(arg1, arg2,
+ Item_func::SP_WITHIN_FUNC);
+}
+
+
Create_func_within Create_func_within::s_singleton;
Item*
@@ -4776,6 +5113,7 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("BIN") }, BUILDER(Create_func_bin)},
{ { C_STRING_WITH_LEN("BIT_COUNT") }, BUILDER(Create_func_bit_count)},
{ { C_STRING_WITH_LEN("BIT_LENGTH") }, BUILDER(Create_func_bit_length)},
+ { { C_STRING_WITH_LEN("BUFFER") }, GEOM_BUILDER(Create_func_buffer)},
{ { C_STRING_WITH_LEN("CEIL") }, BUILDER(Create_func_ceiling)},
{ { C_STRING_WITH_LEN("CEILING") }, BUILDER(Create_func_ceiling)},
{ { C_STRING_WITH_LEN("CENTROID") }, GEOM_BUILDER(Create_func_centroid)},
@@ -4803,7 +5141,7 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("DES_DECRYPT") }, BUILDER(Create_func_des_decrypt)},
{ { C_STRING_WITH_LEN("DES_ENCRYPT") }, BUILDER(Create_func_des_encrypt)},
{ { C_STRING_WITH_LEN("DIMENSION") }, GEOM_BUILDER(Create_func_dimension)},
- { { C_STRING_WITH_LEN("DISJOINT") }, GEOM_BUILDER(Create_func_disjoint)},
+ { { C_STRING_WITH_LEN("DISJOINT") }, GEOM_BUILDER(Create_func_mbr_disjoint)},
{ { C_STRING_WITH_LEN("ELT") }, BUILDER(Create_func_elt)},
{ { C_STRING_WITH_LEN("ENCODE") }, BUILDER(Create_func_encode)},
{ { C_STRING_WITH_LEN("ENCRYPT") }, BUILDER(Create_func_encrypt)},
@@ -4840,7 +5178,7 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("INET_NTOA") }, BUILDER(Create_func_inet_ntoa)},
{ { C_STRING_WITH_LEN("INSTR") }, BUILDER(Create_func_instr)},
{ { C_STRING_WITH_LEN("INTERIORRINGN") }, GEOM_BUILDER(Create_func_interiorringn)},
- { { C_STRING_WITH_LEN("INTERSECTS") }, GEOM_BUILDER(Create_func_intersects)},
+ { { C_STRING_WITH_LEN("INTERSECTS") }, GEOM_BUILDER(Create_func_mbr_intersects)},
{ { C_STRING_WITH_LEN("ISCLOSED") }, GEOM_BUILDER(Create_func_isclosed)},
{ { C_STRING_WITH_LEN("ISEMPTY") }, GEOM_BUILDER(Create_func_isempty)},
{ { C_STRING_WITH_LEN("ISNULL") }, BUILDER(Create_func_isnull)},
@@ -4869,13 +5207,13 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("MAKETIME") }, BUILDER(Create_func_maketime)},
{ { C_STRING_WITH_LEN("MAKE_SET") }, BUILDER(Create_func_make_set)},
{ { C_STRING_WITH_LEN("MASTER_POS_WAIT") }, BUILDER(Create_func_master_pos_wait)},
- { { C_STRING_WITH_LEN("MBRCONTAINS") }, GEOM_BUILDER(Create_func_contains)},
- { { C_STRING_WITH_LEN("MBRDISJOINT") }, GEOM_BUILDER(Create_func_disjoint)},
- { { C_STRING_WITH_LEN("MBREQUAL") }, GEOM_BUILDER(Create_func_equals)},
- { { C_STRING_WITH_LEN("MBRINTERSECTS") }, GEOM_BUILDER(Create_func_intersects)},
- { { C_STRING_WITH_LEN("MBROVERLAPS") }, GEOM_BUILDER(Create_func_overlaps)},
+ { { C_STRING_WITH_LEN("MBRCONTAINS") }, GEOM_BUILDER(Create_func_mbr_contains)},
+ { { C_STRING_WITH_LEN("MBRDISJOINT") }, GEOM_BUILDER(Create_func_mbr_disjoint)},
+ { { C_STRING_WITH_LEN("MBREQUAL") }, GEOM_BUILDER(Create_func_mbr_equals)},
+ { { C_STRING_WITH_LEN("MBRINTERSECTS") }, GEOM_BUILDER(Create_func_mbr_intersects)},
+ { { C_STRING_WITH_LEN("MBROVERLAPS") }, GEOM_BUILDER(Create_func_mbr_overlaps)},
{ { C_STRING_WITH_LEN("MBRTOUCHES") }, GEOM_BUILDER(Create_func_touches)},
- { { C_STRING_WITH_LEN("MBRWITHIN") }, GEOM_BUILDER(Create_func_within)},
+ { { C_STRING_WITH_LEN("MBRWITHIN") }, GEOM_BUILDER(Create_func_mbr_within)},
{ { C_STRING_WITH_LEN("MD5") }, BUILDER(Create_func_md5)},
{ { C_STRING_WITH_LEN("MLINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
{ { C_STRING_WITH_LEN("MLINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
@@ -4898,7 +5236,7 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("OCT") }, BUILDER(Create_func_oct)},
{ { C_STRING_WITH_LEN("OCTET_LENGTH") }, BUILDER(Create_func_length)},
{ { C_STRING_WITH_LEN("ORD") }, BUILDER(Create_func_ord)},
- { { C_STRING_WITH_LEN("OVERLAPS") }, GEOM_BUILDER(Create_func_overlaps)},
+ { { C_STRING_WITH_LEN("OVERLAPS") }, GEOM_BUILDER(Create_func_mbr_overlaps)},
{ { C_STRING_WITH_LEN("PERIOD_ADD") }, BUILDER(Create_func_period_add)},
{ { C_STRING_WITH_LEN("PERIOD_DIFF") }, BUILDER(Create_func_period_diff)},
{ { C_STRING_WITH_LEN("PI") }, BUILDER(Create_func_pi)},
@@ -4933,6 +5271,64 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("STARTPOINT") }, GEOM_BUILDER(Create_func_startpoint)},
{ { C_STRING_WITH_LEN("STRCMP") }, BUILDER(Create_func_strcmp)},
{ { C_STRING_WITH_LEN("STR_TO_DATE") }, BUILDER(Create_func_str_to_date)},
+ { { C_STRING_WITH_LEN("ST_AREA") }, GEOM_BUILDER(Create_func_area)},
+ { { C_STRING_WITH_LEN("ST_ASBINARY") }, GEOM_BUILDER(Create_func_as_wkb)},
+ { { C_STRING_WITH_LEN("ST_ASTEXT") }, GEOM_BUILDER(Create_func_as_wkt)},
+ { { C_STRING_WITH_LEN("ST_ASWKB") }, GEOM_BUILDER(Create_func_as_wkb)},
+ { { C_STRING_WITH_LEN("ST_ASWKT") }, GEOM_BUILDER(Create_func_as_wkt)},
+ { { C_STRING_WITH_LEN("ST_BUFFER") }, GEOM_BUILDER(Create_func_buffer)},
+ { { C_STRING_WITH_LEN("ST_CENTROID") }, GEOM_BUILDER(Create_func_centroid)},
+ { { C_STRING_WITH_LEN("ST_CONTAINS") }, GEOM_BUILDER(Create_func_contains)},
+ { { C_STRING_WITH_LEN("ST_CROSSES") }, GEOM_BUILDER(Create_func_crosses)},
+ { { C_STRING_WITH_LEN("ST_DIFFERENCE") }, GEOM_BUILDER(Create_func_difference)},
+ { { C_STRING_WITH_LEN("ST_DIMENSION") }, GEOM_BUILDER(Create_func_dimension)},
+ { { C_STRING_WITH_LEN("ST_DISJOINT") }, GEOM_BUILDER(Create_func_disjoint)},
+ { { C_STRING_WITH_LEN("ST_DISTANCE") }, GEOM_BUILDER(Create_func_distance)},
+ { { C_STRING_WITH_LEN("ST_ENDPOINT") }, GEOM_BUILDER(Create_func_endpoint)},
+ { { C_STRING_WITH_LEN("ST_ENVELOPE") }, GEOM_BUILDER(Create_func_envelope)},
+ { { C_STRING_WITH_LEN("ST_EQUALS") }, GEOM_BUILDER(Create_func_equals)},
+ { { C_STRING_WITH_LEN("ST_EXTERIORRING") }, GEOM_BUILDER(Create_func_exteriorring)},
+ { { C_STRING_WITH_LEN("ST_GEOMCOLLFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("ST_GEOMCOLLFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("ST_GEOMETRYCOLLECTIONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("ST_GEOMETRYCOLLECTIONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("ST_GEOMETRYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("ST_GEOMETRYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("ST_GEOMETRYN") }, GEOM_BUILDER(Create_func_geometryn)},
+ { { C_STRING_WITH_LEN("ST_GEOMETRYTYPE") }, GEOM_BUILDER(Create_func_geometry_type)},
+ { { C_STRING_WITH_LEN("ST_GEOMFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("ST_GEOMFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("ST_EQUALS") }, GEOM_BUILDER(Create_func_equals)},
+ { { C_STRING_WITH_LEN("ST_INTERIORRINGN") }, GEOM_BUILDER(Create_func_interiorringn)},
+ { { C_STRING_WITH_LEN("ST_INTERSECTS") }, GEOM_BUILDER(Create_func_intersects)},
+ { { C_STRING_WITH_LEN("ST_INTERSECTION") }, GEOM_BUILDER(Create_func_intersection)},
+ { { C_STRING_WITH_LEN("ST_ISCLOSED") }, GEOM_BUILDER(Create_func_isclosed)},
+ { { C_STRING_WITH_LEN("ST_ISEMPTY") }, GEOM_BUILDER(Create_func_isempty)},
+ { { C_STRING_WITH_LEN("ST_ISSIMPLE") }, GEOM_BUILDER(Create_func_issimple)},
+ { { C_STRING_WITH_LEN("ST_LENGTH") }, GEOM_BUILDER(Create_func_glength)},
+ { { C_STRING_WITH_LEN("ST_LINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("ST_LINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("ST_LINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("ST_LINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("ST_NUMGEOMETRIES") }, GEOM_BUILDER(Create_func_numgeometries)},
+ { { C_STRING_WITH_LEN("ST_NUMINTERIORRINGS") }, GEOM_BUILDER(Create_func_numinteriorring)},
+ { { C_STRING_WITH_LEN("ST_NUMPOINTS") }, GEOM_BUILDER(Create_func_numpoints)},
+ { { C_STRING_WITH_LEN("ST_OVERLAPS") }, GEOM_BUILDER(Create_func_overlaps)},
+ { { C_STRING_WITH_LEN("ST_POINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("ST_POINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("ST_POINTN") }, GEOM_BUILDER(Create_func_pointn)},
+ { { C_STRING_WITH_LEN("ST_POLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("ST_POLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("ST_POLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("ST_POLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("ST_SRID") }, GEOM_BUILDER(Create_func_srid)},
+ { { C_STRING_WITH_LEN("ST_STARTPOINT") }, GEOM_BUILDER(Create_func_startpoint)},
+ { { C_STRING_WITH_LEN("ST_SYMDIFFERENCE") }, GEOM_BUILDER(Create_func_symdifference)},
+ { { C_STRING_WITH_LEN("ST_TOUCHES") }, GEOM_BUILDER(Create_func_touches)},
+ { { C_STRING_WITH_LEN("ST_UNION") }, GEOM_BUILDER(Create_func_union)},
+ { { C_STRING_WITH_LEN("ST_WITHIN") }, GEOM_BUILDER(Create_func_within)},
+ { { C_STRING_WITH_LEN("ST_X") }, GEOM_BUILDER(Create_func_x)},
+ { { C_STRING_WITH_LEN("ST_Y") }, GEOM_BUILDER(Create_func_y)},
{ { C_STRING_WITH_LEN("SUBSTRING_INDEX") }, BUILDER(Create_func_substr_index)},
{ { C_STRING_WITH_LEN("SUBTIME") }, BUILDER(Create_func_subtime)},
{ { C_STRING_WITH_LEN("TAN") }, BUILDER(Create_func_tan)},
@@ -5057,6 +5453,17 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
CHARSET_INFO *cs)
{
Item *UNINIT_VAR(res);
+ ulonglong length= 0, decimals= 0;
+ int error;
+
+ /*
+ We don't have to check for error here as sql_yacc.yy has guaranteed
+ that the values are in range of ulonglong
+ */
+ if (c_len)
+ length= (ulonglong) my_strtoll10(c_len, NULL, &error);
+ if (c_dec)
+ decimals= (ulonglong) my_strtoll10(c_dec, NULL, &error);
switch (cast_type) {
case ITEM_CAST_BINARY:
@@ -5072,62 +5479,50 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
res= new (thd->mem_root) Item_date_typecast(a);
break;
case ITEM_CAST_TIME:
- res= new (thd->mem_root) Item_time_typecast(a);
- break;
- case ITEM_CAST_DATETIME:
- res= new (thd->mem_root) Item_datetime_typecast(a);
- break;
- case ITEM_CAST_DECIMAL:
- {
- ulong len= 0;
- uint dec= 0;
-
- if (c_len)
+ if (decimals > MAX_DATETIME_PRECISION)
{
- ulong decoded_size;
- errno= 0;
- decoded_size= strtoul(c_len, NULL, 10);
- if (errno != 0)
- {
- my_error(ER_TOO_BIG_PRECISION, MYF(0), INT_MAX, a->name,
- static_cast<ulong>(DECIMAL_MAX_PRECISION));
- return NULL;
- }
- len= decoded_size;
- }
-
- if (c_dec)
- {
- ulong decoded_size;
- errno= 0;
- decoded_size= strtoul(c_dec, NULL, 10);
- if ((errno != 0) || (decoded_size > UINT_MAX))
- {
- my_error(ER_TOO_BIG_SCALE, MYF(0), INT_MAX, a->name,
- static_cast<ulong>(DECIMAL_MAX_SCALE));
- return NULL;
- }
- dec= decoded_size;
- }
- my_decimal_trim(&len, &dec);
- if (len < dec)
- {
- my_error(ER_M_BIGGER_THAN_D, MYF(0), "");
+ wrong_precision_error(ER_TOO_BIG_PRECISION, a, decimals,
+ MAX_DATETIME_PRECISION);
return 0;
}
- if (len > DECIMAL_MAX_PRECISION)
+ res= new (thd->mem_root) Item_time_typecast(a, (uint) decimals);
+ break;
+ case ITEM_CAST_DATETIME:
+ if (decimals > MAX_DATETIME_PRECISION)
{
- my_error(ER_TOO_BIG_PRECISION, MYF(0), static_cast<int>(len), a->name,
- static_cast<ulong>(DECIMAL_MAX_PRECISION));
+ wrong_precision_error(ER_TOO_BIG_PRECISION, a, decimals,
+ MAX_DATETIME_PRECISION);
return 0;
}
- if (dec > DECIMAL_MAX_SCALE)
+ res= new (thd->mem_root) Item_datetime_typecast(a, (uint) decimals);
+ break;
+ case ITEM_CAST_DECIMAL:
+ {
+ ulong len;
+ uint dec;
+ if (get_length_and_scale(length, decimals, &len, &dec,
+ DECIMAL_MAX_PRECISION, DECIMAL_MAX_SCALE,
+ a))
+ return NULL;
+ res= new (thd->mem_root) Item_decimal_typecast(a, len, dec);
+ break;
+ }
+ case ITEM_CAST_DOUBLE:
+ {
+ ulong len;
+ uint dec;
+
+ if (!c_len)
{
- my_error(ER_TOO_BIG_SCALE, MYF(0), dec, a->name,
- static_cast<ulong>(DECIMAL_MAX_SCALE));
- return 0;
+ length= DBL_DIG+7;
+ decimals= NOT_FIXED_DEC;
}
- res= new (thd->mem_root) Item_decimal_typecast(a, len, dec);
+ else if (get_length_and_scale(length, decimals, &len, &dec,
+ DECIMAL_MAX_PRECISION, NOT_FIXED_DEC-1,
+ a))
+ return NULL;
+ res= new (thd->mem_root) Item_double_typecast(a, (uint) length,
+ (uint) decimals);
break;
}
case ITEM_CAST_CHAR:
@@ -5136,15 +5531,15 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
CHARSET_INFO *real_cs= (cs ? cs : thd->variables.collation_connection);
if (c_len)
{
- ulong decoded_size;
- errno= 0;
- decoded_size= strtoul(c_len, NULL, 10);
- if ((errno != 0) || (decoded_size > MAX_FIELD_BLOBLENGTH))
+ if (length > MAX_FIELD_BLOBLENGTH)
{
- my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), "cast as char", MAX_FIELD_BLOBLENGTH);
+ char buff[1024];
+ String buf(buff, sizeof(buff), system_charset_info);
+ my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), item_name(a, &buf),
+ MAX_FIELD_BLOBLENGTH);
return NULL;
}
- len= (int) decoded_size;
+ len= (int) length;
}
res= new (thd->mem_root) Item_char_typecast(a, len, real_cs);
break;
@@ -5158,3 +5553,95 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
}
return res;
}
+
+
+static List<Item> *create_func_dyncol_prepare(THD *thd,
+ DYNCALL_CREATE_DEF **dfs,
+ List<DYNCALL_CREATE_DEF> &list)
+{
+ DYNCALL_CREATE_DEF *def;
+ List_iterator_fast<DYNCALL_CREATE_DEF> li(list);
+ List<Item> *args= new (thd->mem_root) List<Item>;
+
+ *dfs= (DYNCALL_CREATE_DEF *)alloc_root(thd->mem_root,
+ sizeof(DYNCALL_CREATE_DEF) *
+ list.elements);
+
+ if (!args || !*dfs)
+ return NULL;
+
+ for (uint i= 0; (def= li++) ;)
+ {
+ dfs[0][i++]= *def;
+ args->push_back(def->num);
+ args->push_back(def->value);
+ }
+ return args;
+}
+
+Item *create_func_dyncol_create(THD *thd, List<DYNCALL_CREATE_DEF> &list)
+{
+ List<Item> *args;
+ DYNCALL_CREATE_DEF *dfs;
+ if (!(args= create_func_dyncol_prepare(thd, &dfs, list)))
+ return NULL;
+
+ return new (thd->mem_root) Item_func_dyncol_create(*args, dfs);
+}
+
+
+Item *create_func_dyncol_add(THD *thd, Item *str,
+ List<DYNCALL_CREATE_DEF> &list)
+{
+ List<Item> *args;
+ DYNCALL_CREATE_DEF *dfs;
+
+ if (!(args= create_func_dyncol_prepare(thd, &dfs, list)))
+ return NULL;
+
+ args->push_back(str);
+
+ return new (thd->mem_root) Item_func_dyncol_add(*args, dfs);
+}
+
+
+
+Item *create_func_dyncol_delete(THD *thd, Item *str, List<Item> &nums)
+{
+ DYNCALL_CREATE_DEF *dfs;
+ Item *num;
+ List_iterator_fast<Item> it(nums);
+ List<Item> *args= new (thd->mem_root) List<Item>;
+
+ dfs= (DYNCALL_CREATE_DEF *)alloc_root(thd->mem_root,
+ sizeof(DYNCALL_CREATE_DEF) *
+ nums.elements);
+ if (!args || !dfs)
+ return NULL;
+
+ for (uint i= 0; (num= it++); i++)
+ {
+ dfs[i].num= num;
+ dfs[i].value= new Item_null();
+ dfs[i].type= DYN_COL_INT;
+ args->push_back(dfs[i].num);
+ args->push_back(dfs[i].value);
+ }
+
+ args->push_back(str);
+
+ return new (thd->mem_root) Item_func_dyncol_add(*args, dfs);
+}
+
+
+Item *create_func_dyncol_get(THD *thd, Item *str, Item *num,
+ Cast_target cast_type,
+ const char *c_len, const char *c_dec,
+ CHARSET_INFO *cs)
+{
+ Item *res;
+
+ if (!(res= new (thd->mem_root) Item_dyncol_get(str, num)))
+ return res; // Return NULL
+ return create_func_cast(thd, res, cast_type, c_len, c_dec, cs);
+}
diff --git a/sql/item_create.h b/sql/item_create.h
index ebe6c4942ff..693b77bb739 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -166,5 +166,15 @@ Item *
create_func_cast(THD *thd, Item *a, Cast_target cast_type,
const char *len, const char *dec,
CHARSET_INFO *cs);
+
+Item *create_func_dyncol_create(THD *thd, List<DYNCALL_CREATE_DEF> &list);
+Item *create_func_dyncol_add(THD *thd, Item *str,
+ List<DYNCALL_CREATE_DEF> &list);
+Item *create_func_dyncol_delete(THD *thd, Item *str, List<Item> &nums);
+Item *create_func_dyncol_get(THD *thd, Item *num, Item *str,
+ Cast_target cast_type,
+ const char *c_len, const char *c_dec,
+ CHARSET_INFO *cs);
+
#endif
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 9656f52b671..f3a5c08d621 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -79,13 +79,14 @@ void Item_func::set_arguments(List<Item> &list)
{
*(save_args++)= item;
with_sum_func|=item->with_sum_func;
+ with_field|= item->with_field;
}
}
list.empty(); // Fields are used
}
Item_func::Item_func(List<Item> &list)
- :allowed_arg_cols(1)
+ :allowed_arg_cols(1), persistent_maybe_null(0)
{
set_arguments(list);
}
@@ -93,6 +94,7 @@ Item_func::Item_func(List<Item> &list)
Item_func::Item_func(THD *thd, Item_func *item)
:Item_result_field(thd, item),
allowed_arg_cols(item->allowed_arg_cols),
+ persistent_maybe_null(0),
arg_count(item->arg_count),
used_tables_cache(item->used_tables_cache),
not_null_tables_cache(item->not_null_tables_cache),
@@ -129,6 +131,7 @@ Item_func::Item_func(THD *thd, Item_func *item)
Sets as a side effect the following class variables:
maybe_null Set if any argument may return NULL
with_sum_func Set if any of the arguments contains a sum function
+ with_field Set if any of the arguments contains or is a field
used_tables_cache Set to union of the tables used by arguments
str_value.charset If this is a string function, set this to the
@@ -196,8 +199,8 @@ Item_func::fix_fields(THD *thd, Item **ref)
maybe_null=1;
with_sum_func= with_sum_func || item->with_sum_func;
+ with_field= with_field || item->with_field;
used_tables_cache|= item->used_tables();
- not_null_tables_cache|= item->not_null_tables();
const_item_cache&= item->const_item();
with_subselect|= item->with_subselect;
}
@@ -225,6 +228,44 @@ Item_func::quick_fix_field()
}
+bool
+Item_func::eval_not_null_tables(uchar *opt_arg)
+{
+ Item **arg,**arg_end;
+ not_null_tables_cache= 0;
+ if (arg_count)
+ {
+ for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
+ {
+ not_null_tables_cache|= (*arg)->not_null_tables();
+ }
+ }
+ return FALSE;
+}
+
+
+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)
{
@@ -324,6 +365,8 @@ Item *Item_func::transform(Item_transformer transformer, uchar *argument)
the old item is substituted for a new one.
After this the transformer is applied to the root node
of the Item_func object.
+ The compile function is not called if the analyzer returns NULL
+ in the parameter arg_p.
@param analyzer the analyzer callback function to be applied to the
nodes of the tree of the object
@@ -341,7 +384,7 @@ Item *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
{
if (!(this->*analyzer)(arg_p))
return 0;
- if (arg_count)
+ if (*arg_p && arg_count)
{
Item **arg,**arg_end;
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
@@ -349,7 +392,7 @@ Item *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
/*
The same parameter value of arg_p must be passed
to analyze any argument of the condition formula.
- */
+ */
uchar *arg_v= *arg_p;
Item *new_item= (*arg)->compile(analyzer, &arg_v, transformer, arg_t);
if (new_item && *arg != new_item)
@@ -381,6 +424,8 @@ void Item_func::update_used_tables()
args[i]->update_used_tables();
used_tables_cache|=args[i]->used_tables();
const_item_cache&=args[i]->const_item();
+ if (!persistent_maybe_null && args[i]->maybe_null)
+ maybe_null= 1;
}
}
@@ -475,7 +520,8 @@ Field *Item_func::tmp_table_field(TABLE *table)
field= Field_new_decimal::create_from_item(this);
break;
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
// This case should never be chosen
DBUG_ASSERT(0);
field= 0;
@@ -486,12 +532,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)
{
@@ -681,8 +727,8 @@ void Item_num_op::find_num_type(void)
DBUG_ENTER("Item_num_op::find_num_type");
DBUG_PRINT("info", ("name %s", func_name()));
DBUG_ASSERT(arg_count == 2);
- Item_result r0= args[0]->result_type();
- Item_result r1= args[1]->result_type();
+ Item_result r0= args[0]->cast_to_int_type();
+ Item_result r1= args[1]->cast_to_int_type();
if (r0 == REAL_RESULT || r1 == REAL_RESULT ||
r0 == STRING_RESULT || r1 ==STRING_RESULT)
@@ -691,7 +737,8 @@ void Item_num_op::find_num_type(void)
max_length= float_length(decimals);
hybrid_type= REAL_RESULT;
}
- else if (r0 == DECIMAL_RESULT || r1 == DECIMAL_RESULT)
+ else if (r0 == DECIMAL_RESULT || r1 == DECIMAL_RESULT ||
+ r0 == TIME_RESULT || r1 == TIME_RESULT)
{
hybrid_type= DECIMAL_RESULT;
result_precision();
@@ -722,7 +769,7 @@ void Item_func_num1::find_num_type()
{
DBUG_ENTER("Item_func_num1::find_num_type");
DBUG_PRINT("info", ("name %s", func_name()));
- switch (hybrid_type= args[0]->result_type()) {
+ switch (hybrid_type= args[0]->cast_to_int_type()) {
case INT_RESULT:
unsigned_flag= args[0]->unsigned_flag;
break;
@@ -731,9 +778,12 @@ void Item_func_num1::find_num_type()
hybrid_type= REAL_RESULT;
max_length= float_length(decimals);
break;
+ case TIME_RESULT:
+ hybrid_type= DECIMAL_RESULT;
case DECIMAL_RESULT:
break;
- default:
+ case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
DBUG_PRINT("info", ("Type: %s",
@@ -790,7 +840,9 @@ String *Item_func_numhybrid::val_str(String *str)
}
case STRING_RESULT:
return str_op(&str_value);
- default:
+ case TIME_RESULT:
+ case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
return str;
@@ -825,7 +877,9 @@ double Item_func_numhybrid::val_real()
return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
&end_not_used, &err_not_used) : 0.0);
}
- default:
+ case TIME_RESULT:
+ case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
return 0.0;
@@ -860,7 +914,9 @@ longlong Item_func_numhybrid::val_int()
CHARSET_INFO *cs= res->charset();
return (*(cs->cset->strtoll10))(cs, res->ptr(), &end, &err_not_used);
}
- default:
+ case TIME_RESULT:
+ case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
return 0;
@@ -898,7 +954,8 @@ my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
break;
}
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
return val;
@@ -957,21 +1014,32 @@ longlong Item_func_signed::val_int()
longlong value;
int error;
- if (args[0]->cast_to_int_type() != STRING_RESULT ||
- args[0]->result_as_longlong())
+ if (args[0]->cast_to_int_type() != STRING_RESULT)
+ {
+ value= args[0]->val_int();
+ null_value= args[0]->null_value;
+ return value;
+ }
+ else if (args[0]->dynamic_result())
{
+ /* We come here when argument has an unknown type */
+ args[0]->unsigned_flag= 0; // Mark that we want to have a signed value
value= args[0]->val_int();
null_value= args[0]->null_value;
+ if (!null_value && args[0]->unsigned_flag && value < 0)
+ goto err; // Warn about overflow
return value;
}
value= val_int_from_str(&error);
if (value < 0 && error == 0)
- {
- push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
- "Cast to signed converted positive out-of-range integer to "
- "it's negative complement");
- }
+ goto err;
+ return value;
+
+err:
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ "Cast to signed converted positive out-of-range integer to "
+ "it's negative complement");
return value;
}
@@ -999,19 +1067,35 @@ longlong Item_func_unsigned::val_int()
value= 0;
return value;
}
- else if (args[0]->cast_to_int_type() != STRING_RESULT ||
- args[0]->result_as_longlong())
+ else if (args[0]->dynamic_result())
{
+ /* We come here when argument has an unknown type */
+ args[0]->unsigned_flag= 1; // Mark that we want to have an unsigned value
value= args[0]->val_int();
null_value= args[0]->null_value;
+ if (!null_value && args[0]->unsigned_flag == 0 && value < 0)
+ goto err; // Warn about overflow
+ return value;
+ }
+ else if (args[0]->cast_to_int_type() != STRING_RESULT)
+ {
+ value= args[0]->val_int();
+ null_value= args[0]->null_value;
+ if (!null_value && args[0]->unsigned_flag == 0 && value < 0)
+ goto err; // Warn about overflow
return value;
}
value= val_int_from_str(&error);
if (error < 0)
- push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
- "Cast to unsigned converted negative integer to it's "
- "positive complement");
+ goto err;
+
+ return value;
+
+err:
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ "Cast to unsigned converted negative integer to it's "
+ "positive complement");
return value;
}
@@ -1109,6 +1193,51 @@ void Item_decimal_typecast::print(String *str, enum_query_type query_type)
}
+double Item_double_typecast::val_real()
+{
+ int error;
+ double tmp= args[0]->val_real();
+ if ((null_value= args[0]->null_value))
+ return 0.0;
+
+ if ((error= truncate_double(&tmp, max_length, decimals, 0, DBL_MAX)))
+ {
+ push_warning_printf(current_thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_DATA_OUT_OF_RANGE,
+ ER(ER_WARN_DATA_OUT_OF_RANGE),
+ name, 1);
+ if (error < 0)
+ {
+ null_value= 1; // Illegal value
+ tmp= 0.0;
+ }
+ }
+ return tmp;
+}
+
+
+void Item_double_typecast::print(String *str, enum_query_type query_type)
+{
+ char len_buf[20*3 + 1];
+ char *end;
+
+ str->append(STRING_WITH_LEN("cast("));
+ args[0]->print(str, query_type);
+ str->append(STRING_WITH_LEN(" as double"));
+ if (decimals != NOT_FIXED_DEC)
+ {
+ str->append('(');
+ end= int10_to_str(max_length, len_buf,10);
+ str->append(len_buf, (uint32) (end - len_buf));
+ str->append(',');
+ end= int10_to_str(decimals, len_buf,10);
+ str->append(len_buf, (uint32) (end - len_buf));
+ str->append(')');
+ }
+ str->append(')');
+}
+
double Item_func_plus::real_op()
{
double value= args[0]->val_real() + args[1]->val_real();
@@ -1341,7 +1470,7 @@ void Item_func_div::fix_length_and_dec()
DBUG_ENTER("Item_func_div::fix_length_and_dec");
prec_increment= current_thd->variables.div_precincrement;
Item_num_op::fix_length_and_dec();
- switch(hybrid_type) {
+ switch (hybrid_type) {
case REAL_RESULT:
{
decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment;
@@ -1364,10 +1493,13 @@ void Item_func_div::fix_length_and_dec()
case DECIMAL_RESULT:
result_precision();
break;
- default:
+ case STRING_RESULT:
+ case ROW_RESULT:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
- maybe_null= 1; // devision by zero
+ set_persist_maybe_null(1); // devision by zero
DBUG_VOID_RETURN;
}
@@ -1402,7 +1534,7 @@ void Item_func_int_div::fix_length_and_dec()
max_length=args[0]->max_length -
(argtype == DECIMAL_RESULT || argtype == INT_RESULT ?
args[0]->decimals : 0);
- maybe_null=1;
+ set_persist_maybe_null(1);
unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag;
}
@@ -1483,7 +1615,7 @@ void Item_func_mod::result_precision()
void Item_func_mod::fix_length_and_dec()
{
Item_num_op::fix_length_and_dec();
- maybe_null= 1;
+ set_persist_maybe_null(1);
unsigned_flag= args[0]->unsigned_flag;
}
@@ -1834,7 +1966,7 @@ void Item_func_int_val::find_num_type()
{
DBUG_ENTER("Item_func_int_val::find_num_type");
DBUG_PRINT("info", ("name %s", func_name()));
- switch(hybrid_type= args[0]->result_type())
+ switch (hybrid_type= args[0]->cast_to_int_type())
{
case STRING_RESULT:
case REAL_RESULT:
@@ -1842,6 +1974,7 @@ void Item_func_int_val::find_num_type()
max_length= float_length(decimals);
break;
case INT_RESULT:
+ case TIME_RESULT:
case DECIMAL_RESULT:
/*
-2 because in most high position can't be used any digit for longlong
@@ -1858,7 +1991,8 @@ void Item_func_int_val::find_num_type()
hybrid_type= INT_RESULT;
}
break;
- default:
+ case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
DBUG_PRINT("info", ("Type: %s",
@@ -1987,7 +2121,7 @@ void Item_func_round::fix_length_and_dec()
}
val1= args[1]->val_int();
- if ((null_value= args[1]->is_null()))
+ if ((null_value= args[1]->null_value))
return;
val1_unsigned= args[1]->unsigned_flag;
@@ -2037,7 +2171,9 @@ void Item_func_round::fix_length_and_dec()
unsigned_flag);
break;
}
- default:
+ case ROW_RESULT:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); /* This result type isn't handled */
}
}
@@ -2245,10 +2381,10 @@ double Item_func_units::val_real()
void Item_func_min_max::fix_length_and_dec()
{
int max_int_part=0;
- bool datetime_found= FALSE;
decimals=0;
max_length=0;
maybe_null=0;
+ thd= current_thd;
cmp_type=args[0]->result_type();
for (uint i=0 ; i < arg_count ; i++)
@@ -2257,85 +2393,87 @@ void Item_func_min_max::fix_length_and_dec()
set_if_bigger(decimals, args[i]->decimals);
set_if_bigger(max_int_part, args[i]->decimal_int_part());
if (args[i]->maybe_null)
- maybe_null=1;
- cmp_type=item_cmp_type(cmp_type,args[i]->result_type());
- if (args[i]->result_type() != ROW_RESULT && args[i]->is_datetime())
- {
- datetime_found= TRUE;
- if (!datetime_item || args[i]->field_type() == MYSQL_TYPE_DATETIME)
- datetime_item= args[i];
- }
+ maybe_null= 1;
+ cmp_type= item_cmp_type(cmp_type,args[i]->result_type());
}
if (cmp_type == STRING_RESULT)
- {
agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
- if (datetime_found)
- {
- thd= current_thd;
- compare_as_dates= TRUE;
- }
- }
else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT))
max_length= my_decimal_precision_to_length_no_truncation(max_int_part +
decimals, decimals,
unsigned_flag);
else if (cmp_type == REAL_RESULT)
max_length= float_length(decimals);
- cached_field_type= agg_field_type(args, arg_count);
+
+ compare_as_dates= find_date_time_item(args, arg_count, 0);
+ if (compare_as_dates)
+ {
+ cached_field_type= compare_as_dates->field_type();
+ if (mysql_type_to_time_type(cached_field_type) == MYSQL_TIMESTAMP_DATE)
+ decimals= 0;
+ else
+ set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
+ }
+ else
+ cached_field_type= agg_field_type(args, arg_count);
}
/*
Compare item arguments in the DATETIME context.
- SYNOPSIS
- cmp_datetimes()
- value [out] found least/greatest DATE/DATETIME value
-
DESCRIPTION
Compare item arguments as DATETIME values and return the index of the
least/greatest argument in the arguments array.
- The correct integer DATE/DATETIME value of the found argument is
+ The correct DATE/DATETIME value of the found argument is
stored to the value pointer, if latter is provided.
RETURN
- 0 If one of arguments is NULL or there was a execution error
- # index of the least/greatest argument
+ 1 If one of arguments is NULL or there was a execution error
+ 0 Otherwise
*/
-uint Item_func_min_max::cmp_datetimes(ulonglong *value)
+bool Item_func_min_max::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
longlong UNINIT_VAR(min_max);
- uint min_max_idx= 0;
+ DBUG_ASSERT(fixed == 1);
+
+ /*
+ just like ::val_int() method of an string item can be called,
+ for example, SELECT CONCAT("10", "12") + 1,
+ ::get_date() can be called for non-temporal values,
+ for example, SELECT MONTH(GREATEST("2011-11-21", "2010-10-09"))
+
+ */
+ if (!compare_as_dates)
+ return Item_func::get_date(ltime, fuzzy_date);
+
+ null_value= 0;
for (uint i=0; i < arg_count ; i++)
{
Item **arg= args + i;
bool is_null;
- longlong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null);
+ longlong res= get_datetime_value(thd, &arg, 0, compare_as_dates, &is_null);
- /* Check if we need to stop (because of error or KILL) and stop the loop */
- if (thd->is_error())
+ /* Check if we need to stop (because of error or KILL) and stop the loop */
+ if (thd->is_error() || args[i]->null_value)
{
null_value= 1;
- return 0;
+ return 1;
}
- if ((null_value= args[i]->null_value))
- return 0;
if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0)
- {
min_max= res;
- min_max_idx= i;
- }
}
- if (value)
+ unpack_time(min_max, ltime);
+ if (compare_as_dates->field_type() == MYSQL_TYPE_DATE)
{
- *value= min_max;
- if (datetime_item->field_type() == MYSQL_TYPE_DATE)
- *value/= 1000000L;
+ ltime->time_type= MYSQL_TIMESTAMP_DATE;
+ ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
}
- return min_max_idx;
+
+ return 0;
}
@@ -2343,46 +2481,14 @@ String *Item_func_min_max::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
if (compare_as_dates)
- {
- String *str_res;
- uint min_max_idx= cmp_datetimes(NULL);
- if (null_value)
- return 0;
- str_res= args[min_max_idx]->val_str(str);
- if (args[min_max_idx]->null_value)
- {
- // check if the call to val_str() above returns a NULL value
- null_value= 1;
- return NULL;
- }
- str_res->set_charset(collation.collation);
- return str_res;
- }
+ return val_string_from_date(str);
switch (cmp_type) {
case INT_RESULT:
- {
- longlong nr=val_int();
- if (null_value)
- return 0;
- str->set_int(nr, unsigned_flag, &my_charset_bin);
- return str;
- }
+ return val_string_from_int(str);
case DECIMAL_RESULT:
- {
- my_decimal dec_buf, *dec_val= val_decimal(&dec_buf);
- if (null_value)
- return 0;
- my_decimal2string(E_DEC_FATAL_ERROR, dec_val, 0, 0, 0, str);
- return str;
- }
+ return val_string_from_decimal(str);
case REAL_RESULT:
- {
- double nr= val_real();
- if (null_value)
- return 0; /* purecov: inspected */
- str->set_real(nr,decimals,&my_charset_bin);
- return str;
- }
+ return val_string_from_real(str);
case STRING_RESULT:
{
String *UNINIT_VAR(res);
@@ -2408,9 +2514,9 @@ String *Item_func_min_max::val_str(String *str)
return res;
}
case ROW_RESULT:
- default:
- // This case should never be chosen
- DBUG_ASSERT(0);
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0); // This case should never be chosen
return 0;
}
return 0; // Keep compiler happy
@@ -2423,9 +2529,11 @@ double Item_func_min_max::val_real()
double value=0.0;
if (compare_as_dates)
{
- ulonglong result= 0;
- (void)cmp_datetimes(&result);
- return (double)result;
+ MYSQL_TIME ltime;
+ if (get_date(&ltime, TIME_FUZZY_DATE))
+ return 0;
+
+ return TIME_to_double(&ltime);
}
for (uint i=0; i < arg_count ; i++)
{
@@ -2450,9 +2558,11 @@ longlong Item_func_min_max::val_int()
longlong value=0;
if (compare_as_dates)
{
- ulonglong result= 0;
- (void)cmp_datetimes(&result);
- return (longlong)result;
+ MYSQL_TIME ltime;
+ if (get_date(&ltime, TIME_FUZZY_DATE))
+ return 0;
+
+ return TIME_to_ulonglong(&ltime);
}
for (uint i=0; i < arg_count ; i++)
{
@@ -2478,10 +2588,11 @@ my_decimal *Item_func_min_max::val_decimal(my_decimal *dec)
if (compare_as_dates)
{
- ulonglong value= 0;
- (void)cmp_datetimes(&value);
- ulonglong2decimal(value, dec);
- return dec;
+ MYSQL_TIME ltime;
+ if (get_date(&ltime, TIME_FUZZY_DATE))
+ return 0;
+
+ return date2my_decimal(&ltime, dec);
}
for (uint i=0; i < arg_count ; i++)
{
@@ -2670,7 +2781,7 @@ longlong Item_func_field::val_int()
void Item_func_field::fix_length_and_dec()
{
- maybe_null=0; max_length=3;
+ set_persist_maybe_null(0); max_length=3;
cmp_type= args[0]->result_type();
for (uint i=1; i < arg_count ; i++)
cmp_type= item_cmp_type(cmp_type, args[i]->result_type());
@@ -2918,6 +3029,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
if (item->maybe_null)
func->maybe_null=1;
func->with_sum_func= func->with_sum_func || item->with_sum_func;
+ func->with_field= func->with_field || item->with_field;
func->with_subselect|= item->with_subselect;
used_tables_cache|=item->used_tables();
const_item_cache&=item->const_item();
@@ -2964,15 +3076,14 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
if (arguments[i]->const_item())
{
- switch (arguments[i]->result_type())
- {
+ switch (arguments[i]->result_type()) {
case STRING_RESULT:
case DECIMAL_RESULT:
{
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;
}
@@ -2991,9 +3102,9 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
to+= ALIGN_SIZE(sizeof(double));
break;
case ROW_RESULT:
- default:
- // This case should never be chosen
- DBUG_ASSERT(0);
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0); // This case should never be chosen
break;
}
}
@@ -3066,9 +3177,9 @@ bool udf_handler::get_arguments()
}
break;
case ROW_RESULT:
- default:
- // This case should never be chosen
- DBUG_ASSERT(0);
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0); // This case should never be chosen
break;
}
}
@@ -3689,9 +3800,9 @@ longlong Item_func_benchmark::val_int()
(void) args[1]->val_decimal(&tmp_decimal);
break;
case ROW_RESULT:
- default:
- // This case should never be chosen
- DBUG_ASSERT(0);
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0); // This case should never be chosen
return 0;
}
}
@@ -3869,6 +3980,21 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref)
entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
cached_result_type= args[0]->result_type();
+ if (thd->lex->current_select)
+ {
+ /*
+ When this function is used in a derived table/view force the derived
+ table to be materialized to preserve possible side-effect of setting a
+ user variable.
+ */
+ SELECT_LEX_UNIT *unit= thd->lex->current_select->master_unit();
+ TABLE_LIST *derived;
+ for (derived= unit->derived;
+ derived;
+ derived= derived->select_lex->master_unit()->derived)
+ derived->set_materialized_derived();
+ }
+
return FALSE;
}
@@ -4045,6 +4171,7 @@ double user_var_entry::val_real(bool *null_value)
case STRING_RESULT:
return my_atof(value); // This is null terminated
case ROW_RESULT:
+ case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // Impossible
break;
@@ -4077,6 +4204,7 @@ longlong user_var_entry::val_int(bool *null_value) const
return my_strtoll10(value, (char**) 0, &error);// String is null terminated
}
case ROW_RESULT:
+ case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // Impossible
break;
@@ -4111,6 +4239,7 @@ String *user_var_entry::val_str(bool *null_value, String *str,
str= 0; // EOM error
break;
case ROW_RESULT:
+ case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // Impossible
break;
@@ -4139,6 +4268,7 @@ my_decimal *user_var_entry::val_decimal(bool *null_value, my_decimal *val)
str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val);
break;
case ROW_RESULT:
+ case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // Impossible
break;
@@ -4178,8 +4308,9 @@ Item_func_set_user_var::check(bool use_result_field)
{
save_result.vint= use_result_field ? result_field->val_int() :
args[0]->val_int();
- unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
- args[0]->unsigned_flag;
+ unsigned_flag= (use_result_field ?
+ ((Field_num*)result_field)->unsigned_flag:
+ args[0]->unsigned_flag);
break;
}
case STRING_RESULT:
@@ -4196,9 +4327,9 @@ Item_func_set_user_var::check(bool use_result_field)
break;
}
case ROW_RESULT:
- default:
- // This case should never be chosen
- DBUG_ASSERT(0);
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0); // This case should never be chosen
break;
}
DBUG_RETURN(FALSE);
@@ -4231,9 +4362,9 @@ void Item_func_set_user_var::save_item_result(Item *item)
save_result.vdec= item->val_decimal_result(&decimal_buff);
break;
case ROW_RESULT:
- default:
- // Should never happen
- DBUG_ASSERT(0);
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0); // This case should never be chosen
break;
}
DBUG_VOID_RETURN;
@@ -4299,9 +4430,9 @@ Item_func_set_user_var::update()
break;
}
case ROW_RESULT:
- default:
- // This case should never be chosen
- DBUG_ASSERT(0);
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0); // This case should never be chosen
break;
}
DBUG_RETURN(res);
@@ -4716,7 +4847,7 @@ void Item_func_get_user_var::fix_length_and_dec()
{
THD *thd=current_thd;
int error;
- maybe_null=1;
+ set_persist_maybe_null(1);
decimals=NOT_FIXED_DEC;
max_length=MAX_BLOB_WIDTH;
@@ -4734,7 +4865,7 @@ void Item_func_get_user_var::fix_length_and_dec()
max_length= var_entry->length;
collation.set(var_entry->collation);
- switch(m_cached_result_type) {
+ switch (m_cached_result_type) {
case REAL_RESULT:
max_length= DBL_DIG + 8;
break;
@@ -4750,8 +4881,9 @@ void Item_func_get_user_var::fix_length_and_dec()
decimals= DECIMAL_MAX_SCALE;
break;
case ROW_RESULT: // Keep compiler happy
- default:
- DBUG_ASSERT(0);
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0); // This case should never be chosen
break;
}
}
@@ -4921,7 +5053,7 @@ void Item_func_get_system_var::update_null_value()
void Item_func_get_system_var::fix_length_and_dec()
{
char *cptr;
- maybe_null= TRUE;
+ set_persist_maybe_null(1);
max_length= 0;
if (var->check_type(var_type))
@@ -4939,12 +5071,16 @@ void Item_func_get_system_var::fix_length_and_dec()
switch (var->show_type())
{
case SHOW_LONG:
- case SHOW_INT:
case SHOW_HA_ROWS:
unsigned_flag= TRUE;
max_length= MY_INT64_NUM_DECIMAL_DIGITS;
decimals=0;
break;
+ case SHOW_INT:
+ unsigned_flag= FALSE;
+ max_length= MY_INT64_NUM_DECIMAL_DIGITS;
+ decimals=0;
+ break;
case SHOW_LONGLONG:
unsigned_flag= TRUE;
max_length= MY_INT64_NUM_DECIMAL_DIGITS;
@@ -5085,7 +5221,7 @@ longlong Item_func_get_system_var::val_int()
switch (var->show_type())
{
- case SHOW_INT: get_sys_var_safe (uint);
+ case SHOW_INT: get_sys_var_safe (int);
case SHOW_LONG: get_sys_var_safe (ulong);
case SHOW_LONGLONG: get_sys_var_safe (ulonglong);
case SHOW_HA_ROWS: get_sys_var_safe (ha_rows);
@@ -5448,7 +5584,7 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref)
DBUG_ASSERT(fixed == 0);
Item *UNINIT_VAR(item); // Safe as arg_count is > 1
- maybe_null=1;
+ set_persist_maybe_null(1);
join_key=0;
/*
@@ -5782,7 +5918,7 @@ longlong Item_func_row_count::val_int()
Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, sp_name *name)
:Item_func(), context(context_arg), m_name(name), m_sp(NULL), sp_result_field(NULL)
{
- maybe_null= 1;
+ set_persist_maybe_null(1);
m_name->init_qname(current_thd);
dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE));
dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
@@ -5793,7 +5929,7 @@ Item_func_sp::Item_func_sp(Name_resolution_context *context_arg,
sp_name *name, List<Item> &list)
:Item_func(list), context(context_arg), m_name(name), m_sp(NULL),sp_result_field(NULL)
{
- maybe_null= 1;
+ set_persist_maybe_null(1);
m_name->init_qname(current_thd);
dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE));
dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
@@ -5921,6 +6057,19 @@ Item_func_sp::init_result_field(THD *thd)
/**
+ @note
+ Deterministic stored procedures are considered inexpensive.
+ Consequently such procedures may be evaluated during optimization,
+ if they are constant (checked by the optimizer).
+*/
+
+bool Item_func_sp::is_expensive()
+{
+ return !(m_sp->m_chistics->detistic);
+}
+
+
+/**
@brief Initialize local members with values from the Field interface.
@note called from Item::fix_fields.
@@ -5934,7 +6083,7 @@ void Item_func_sp::fix_length_and_dec()
decimals= sp_result_field->decimals();
max_length= sp_result_field->field_length;
collation.set(sp_result_field->charset());
- maybe_null= 1;
+ set_persist_maybe_null(1);
unsigned_flag= test(sp_result_field->flags & UNSIGNED_FLAG);
DBUG_VOID_RETURN;
diff --git a/sql/item_func.h b/sql/item_func.h
index 5d0569f56b2..2db8ab76ffe 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -38,6 +38,8 @@ protected:
0 means get this number from first argument
*/
uint allowed_arg_cols;
+ /* maybe_null can't be changed by parameters or used table state */
+ bool persistent_maybe_null;
public:
uint arg_count;
table_map used_tables_cache, not_null_tables_cache;
@@ -45,7 +47,7 @@ public:
enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
GE_FUNC,GT_FUNC,FT_FUNC,
LIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC,
- COND_AND_FUNC, COND_OR_FUNC, COND_XOR_FUNC,
+ COND_AND_FUNC, COND_OR_FUNC, XOR_FUNC,
BETWEEN, IN_FUNC, MULT_EQUAL_FUNC,
INTERVAL_FUNC, ISNOTNULLTEST_FUNC,
SP_EQUALS_FUNC, SP_DISJOINT_FUNC,SP_INTERSECTS_FUNC,
@@ -63,26 +65,29 @@ public:
enum Type type() const { return FUNC_ITEM; }
virtual enum Functype functype() const { return UNKNOWN_FUNC; }
Item_func(void):
- allowed_arg_cols(1), arg_count(0)
+ allowed_arg_cols(1), persistent_maybe_null(0), arg_count(0)
{
with_sum_func= 0;
+ with_field= 0;
}
Item_func(Item *a):
- allowed_arg_cols(1), arg_count(1)
+ allowed_arg_cols(1), persistent_maybe_null(0), arg_count(1)
{
args= tmp_arg;
args[0]= a;
with_sum_func= a->with_sum_func;
+ with_field= a->with_field;
}
Item_func(Item *a,Item *b):
- allowed_arg_cols(1), arg_count(2)
+ allowed_arg_cols(1), persistent_maybe_null(0), arg_count(2)
{
args= tmp_arg;
args[0]= a; args[1]= b;
with_sum_func= a->with_sum_func || b->with_sum_func;
+ with_field= a->with_field || b->with_field;
}
Item_func(Item *a,Item *b,Item *c):
- allowed_arg_cols(1)
+ allowed_arg_cols(1), persistent_maybe_null(0)
{
arg_count= 0;
if ((args= (Item**) sql_alloc(sizeof(Item*)*3)))
@@ -90,10 +95,11 @@ public:
arg_count= 3;
args[0]= a; args[1]= b; args[2]= c;
with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func;
+ with_field= a->with_field || b->with_field || c->with_field;
}
}
Item_func(Item *a,Item *b,Item *c,Item *d):
- allowed_arg_cols(1)
+ allowed_arg_cols(1), persistent_maybe_null(0)
{
arg_count= 0;
if ((args= (Item**) sql_alloc(sizeof(Item*)*4)))
@@ -102,10 +108,12 @@ public:
args[0]= a; args[1]= b; args[2]= c; args[3]= d;
with_sum_func= a->with_sum_func || b->with_sum_func ||
c->with_sum_func || d->with_sum_func;
+ with_field= a->with_field || b->with_field ||
+ c->with_field || d->with_field;
}
}
Item_func(Item *a,Item *b,Item *c,Item *d,Item* e):
- allowed_arg_cols(1)
+ allowed_arg_cols(1), persistent_maybe_null(0)
{
arg_count= 5;
if ((args= (Item**) sql_alloc(sizeof(Item*)*5)))
@@ -113,12 +121,15 @@ public:
args[0]= a; args[1]= b; args[2]= c; args[3]= d; args[4]= e;
with_sum_func= a->with_sum_func || b->with_sum_func ||
c->with_sum_func || d->with_sum_func || e->with_sum_func ;
+ with_field= a->with_field || b->with_field ||
+ c->with_field || d->with_field || e->with_field;
}
}
Item_func(List<Item> &list);
// 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;
@@ -183,8 +194,9 @@ 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 eval_not_null_tables(uchar *opt_arg);
+ // bool is_expensive_processor(uchar *arg);
+ // virtual bool is_expensive() { return 0; }
inline double fix_result(double value)
{
if (isfinite(value))
@@ -244,6 +256,21 @@ public:
}
/*
+ By default only substitution for a field whose two different values
+ are never equal is allowed in the arguments of a function.
+ This is overruled for the direct arguments of comparison functions.
+ */
+ bool subst_argument_checker(uchar **arg)
+ {
+ if (*arg)
+ {
+ *arg= (uchar *) Item::IDENTITY_SUBST;
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /*
We assume the result of any function that has a TIMESTAMP argument to be
timezone-dependent, since a TIMESTAMP value in both numeric and string
contexts is interpreted according to the current timezone.
@@ -275,6 +302,11 @@ public:
info.bool_function= &Item::restore_to_before_no_rows_in_result;
walk(&Item::call_bool_func_processor, FALSE, (uchar*) &info);
}
+ inline void set_persist_maybe_null(bool mb_null)
+ {
+ maybe_null= mb_null;
+ persistent_maybe_null= 1;
+ }
};
@@ -300,6 +332,8 @@ class Item_func_numhybrid: public Item_func
protected:
Item_result hybrid_type;
public:
+ Item_func_numhybrid() :Item_func(), hybrid_type(REAL_RESULT)
+ {}
Item_func_numhybrid(Item *a) :Item_func(a), hybrid_type(REAL_RESULT)
{}
Item_func_numhybrid(Item *a,Item *b)
@@ -453,7 +487,7 @@ class Item_decimal_typecast :public Item_func
public:
Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a)
{
- decimals= dec;
+ decimals= (uint8) dec;
max_length= my_decimal_precision_to_length_no_truncation(len, dec,
unsigned_flag);
}
@@ -463,12 +497,29 @@ public:
my_decimal *val_decimal(my_decimal*);
enum Item_result result_type () const { return DECIMAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
- void fix_length_and_dec() {};
+ void fix_length_and_dec() {}
const char *func_name() const { return "decimal_typecast"; }
virtual void print(String *str, enum_query_type query_type);
};
+class Item_double_typecast :public Item_real_func
+{
+public:
+ Item_double_typecast(Item *a, int len, int dec) :Item_real_func(a)
+ {
+ decimals= (uint8) dec;
+ max_length= (uint32) len;
+ }
+ double val_real();
+ enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
+ void fix_length_and_dec() { set_persist_maybe_null(1); }
+ const char *func_name() const { return "double_typecast"; }
+ virtual void print(String *str, enum_query_type query_type);
+};
+
+
+
class Item_func_additive_op :public Item_num_op
{
public:
@@ -603,7 +654,7 @@ class Item_dec_func :public Item_real_func
void fix_length_and_dec()
{
decimals=NOT_FIXED_DEC; max_length=float_length(decimals);
- maybe_null=1;
+ set_persist_maybe_null(1);
}
};
@@ -828,25 +879,21 @@ class Item_func_min_max :public Item_func
Item_result cmp_type;
String tmp_value;
int cmp_sign;
- /* TRUE <=> arguments should be compared in the DATETIME context. */
- bool compare_as_dates;
/* An item used for issuing warnings while string to DATETIME conversion. */
- Item *datetime_item;
+ Item *compare_as_dates;
THD *thd;
protected:
enum_field_types cached_field_type;
public:
Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list),
- cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg), compare_as_dates(FALSE),
- datetime_item(0) {}
+ cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg), compare_as_dates(FALSE) {}
double val_real();
longlong val_int();
String *val_str(String *);
my_decimal *val_decimal(my_decimal *);
+ bool get_date(MYSQL_TIME *res, uint fuzzy_date);
void fix_length_and_dec();
enum Item_result result_type () const { return cmp_type; }
- bool result_as_longlong() { return compare_as_dates; };
- uint cmp_datetimes(ulonglong *value);
enum_field_types field_type() const { return cached_field_type; }
};
@@ -931,7 +978,7 @@ public:
Item_func_coercibility(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "coercibility"; }
- void fix_length_and_dec() { max_length=10; maybe_null= 0; }
+ void fix_length_and_dec() { max_length=10; set_persist_maybe_null(0); }
table_map not_null_tables() const { return 0; }
};
@@ -1093,7 +1140,7 @@ public:
{}
longlong val_int();
const char *func_name() const { return "benchmark"; }
- void fix_length_and_dec() { max_length=1; maybe_null=0; }
+ void fix_length_and_dec() { max_length=1; set_persist_maybe_null(0); }
virtual void print(String *str, enum_query_type query_type);
bool check_vcol_func_processor(uchar *int_arg)
{
@@ -1128,6 +1175,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)
@@ -1345,7 +1393,7 @@ public:
double val_real() { DBUG_ASSERT(fixed == 1); null_value= 1; return 0.0; }
longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
enum Item_result result_type () const { return STRING_RESULT; }
- void fix_length_and_dec() { maybe_null=1; max_length=0; }
+ void fix_length_and_dec() { set_persist_maybe_null(1); max_length=0; }
};
#endif /* HAVE_DLOPEN */
@@ -1366,7 +1414,7 @@ class Item_func_get_lock :public Item_int_func
Item_func_get_lock(Item *a,Item *b) :Item_int_func(a,b) {}
longlong val_int();
const char *func_name() const { return "get_lock"; }
- void fix_length_and_dec() { max_length=1; maybe_null=1;}
+ void fix_length_and_dec() { max_length=1; set_persist_maybe_null(1);}
bool check_vcol_func_processor(uchar *int_arg)
{
return trace_unsupported_by_check_vcol_func_processor(func_name());
@@ -1380,7 +1428,7 @@ public:
Item_func_release_lock(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "release_lock"; }
- void fix_length_and_dec() { max_length=1; maybe_null=1;}
+ void fix_length_and_dec() { max_length=1; set_persist_maybe_null(1);}
bool check_vcol_func_processor(uchar *int_arg)
{
return trace_unsupported_by_check_vcol_func_processor(func_name());
@@ -1397,7 +1445,7 @@ public:
Item_master_pos_wait(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {}
longlong val_int();
const char *func_name() const { return "master_pos_wait"; }
- void fix_length_and_dec() { max_length=21; maybe_null=1;}
+ void fix_length_and_dec() { max_length=21; set_persist_maybe_null(1);}
bool check_vcol_func_processor(uchar *int_arg)
{
return trace_unsupported_by_check_vcol_func_processor(func_name());
@@ -1613,7 +1661,8 @@ public:
Item_func_inet_aton(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "inet_aton"; }
- void fix_length_and_dec() { decimals= 0; max_length= 21; maybe_null= 1; unsigned_flag= 1;}
+ void fix_length_and_dec()
+ { decimals= 0; max_length= 21; set_persist_maybe_null(1); unsigned_flag= 1; }
};
@@ -1645,6 +1694,7 @@ public:
table= 0; // required by Item_func_match::eq()
DBUG_VOID_RETURN;
}
+ bool is_expensive_processor(uchar *arg) { return TRUE; }
enum Functype functype() const { return FT_FUNC; }
const char *func_name() const { return "match"; }
void update_used_tables() {}
@@ -1681,17 +1731,11 @@ public:
Item_func_is_free_lock(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "is_free_lock"; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
+ void fix_length_and_dec()
+ { decimals= 0; max_length= 1; set_persist_maybe_null(1); }
bool check_vcol_func_processor(uchar *int_arg)
{
-#if 0
- DBUG_ENTER("Item_func_is_free_lock::check_vcol_func_processor");
- DBUG_PRINT("info",
- ("check_vcol_func_processor returns TRUE: unsupported function"));
- DBUG_RETURN(TRUE);
-#else
return trace_unsupported_by_check_vcol_func_processor(func_name());
-#endif
}
};
@@ -1702,7 +1746,8 @@ public:
Item_func_is_used_lock(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "is_used_lock"; }
- void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;}
+ void fix_length_and_dec()
+ { decimals= 0; max_length= 10; set_persist_maybe_null(1);}
bool check_vcol_func_processor(uchar *int_arg)
{
return trace_unsupported_by_check_vcol_func_processor(func_name());
@@ -1715,7 +1760,7 @@ enum Cast_target
{
ITEM_CAST_BINARY, ITEM_CAST_SIGNED_INT, ITEM_CAST_UNSIGNED_INT,
ITEM_CAST_DATE, ITEM_CAST_TIME, ITEM_CAST_DATETIME, ITEM_CAST_CHAR,
- ITEM_CAST_DECIMAL
+ ITEM_CAST_DECIMAL, ITEM_CAST_DOUBLE
};
@@ -1725,7 +1770,7 @@ public:
Item_func_row_count() :Item_int_func() {}
longlong val_int();
const char *func_name() const { return "row_count"; }
- void fix_length_and_dec() { decimals= 0; maybe_null=0; }
+ void fix_length_and_dec() { decimals= 0; set_persist_maybe_null(0); }
bool check_vcol_func_processor(uchar *int_arg)
{
@@ -1760,6 +1805,10 @@ private:
bool execute();
bool execute_impl(THD *thd);
bool init_result_field(THD *thd);
+
+protected:
+ bool is_expensive_processor(uchar *arg)
+ { return is_expensive(); }
public:
@@ -1833,7 +1882,7 @@ public:
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec(void);
- bool is_expensive() { return 1; }
+ bool is_expensive();
inline Field *get_sp_result_field()
{
@@ -1843,6 +1892,10 @@ public:
{
return trace_unsupported_by_check_vcol_func_processor(func_name());
}
+ bool limit_index_condition_pushdown_processor(uchar *opt_arg)
+ {
+ return TRUE;
+ }
};
@@ -1852,7 +1905,7 @@ public:
Item_func_found_rows() :Item_int_func() {}
longlong val_int();
const char *func_name() const { return "found_rows"; }
- void fix_length_and_dec() { decimals= 0; maybe_null=0; }
+ void fix_length_and_dec() { decimals= 0; set_persist_maybe_null(0); }
bool check_vcol_func_processor(uchar *int_arg)
{
return trace_unsupported_by_check_vcol_func_processor(func_name());
@@ -1876,4 +1929,3 @@ public:
return trace_unsupported_by_check_vcol_func_processor(func_name());
}
};
-
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index 24e994cfc0e..ba330ba3b96 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -29,9 +29,15 @@
#endif
#include "mysql_priv.h"
+/*
+ It is necessary to include set_var.h instead of item.h because there
+ are dependencies on include order for set_var.h and item.h. This
+ will be resolved later.
+*/
#ifdef HAVE_SPATIAL
#include <m_ctype.h>
+
Field *Item_geometry_func::tmp_table_field(TABLE *t_arg)
{
Field *result;
@@ -45,8 +51,8 @@ void Item_geometry_func::fix_length_and_dec()
{
collation.set(&my_charset_bin);
decimals=0;
- max_length= max_field_size;
- maybe_null= 1;
+ max_length= (uint32) 4294967295U;
+ set_persist_maybe_null(1);
}
@@ -137,8 +143,9 @@ String *Item_func_as_wkt::val_str(String *str)
void Item_func_as_wkt::fix_length_and_dec()
{
+ collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
max_length=MAX_BLOB_WIDTH;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
@@ -363,8 +370,8 @@ String *Item_func_point::val_str(String *str)
uint32 srid= 0;
if ((null_value= (args[0]->null_value ||
- args[1]->null_value ||
- str->realloc(4/*SRID*/ + 1 + 4 + SIZEOF_STORED_DOUBLE*2))))
+ args[1]->null_value ||
+ str->realloc(4/*SRID*/ + 1 + 4 + SIZEOF_STORED_DOUBLE * 2))))
return 0;
str->set_charset(&my_charset_bin);
@@ -511,7 +518,33 @@ err:
Functions for spatial relations
*/
-longlong Item_func_spatial_rel::val_int()
+const char *Item_func_spatial_mbr_rel::func_name() const
+{
+ switch (spatial_rel) {
+ case SP_CONTAINS_FUNC:
+ return "mbrcontains";
+ case SP_WITHIN_FUNC:
+ return "mbrwithin";
+ case SP_EQUALS_FUNC:
+ return "mbrequals";
+ case SP_DISJOINT_FUNC:
+ return "mbrdisjoint";
+ case SP_INTERSECTS_FUNC:
+ return "mbrintersects";
+ case SP_TOUCHES_FUNC:
+ return "mbrtouches";
+ case SP_CROSSES_FUNC:
+ return "mbrcrosses";
+ case SP_OVERLAPS_FUNC:
+ return "mbroverlaps";
+ default:
+ DBUG_ASSERT(0); // Should never happened
+ return "mbrsp_unknown";
+ }
+}
+
+
+longlong Item_func_spatial_mbr_rel::val_int()
{
DBUG_ASSERT(fixed == 1);
String *res1= args[0]->val_str(&cmp.value1);
@@ -556,6 +589,746 @@ longlong Item_func_spatial_rel::val_int()
}
+Item_func_spatial_rel::Item_func_spatial_rel(Item *a,Item *b,
+ enum Functype sp_rel) :
+ Item_bool_func2(a,b), collector()
+{
+ spatial_rel = sp_rel;
+}
+
+
+Item_func_spatial_rel::~Item_func_spatial_rel()
+{
+}
+
+
+const char *Item_func_spatial_rel::func_name() const
+{
+ switch (spatial_rel) {
+ case SP_CONTAINS_FUNC:
+ return "st_contains";
+ case SP_WITHIN_FUNC:
+ return "st_within";
+ case SP_EQUALS_FUNC:
+ return "st_equals";
+ case SP_DISJOINT_FUNC:
+ return "st_disjoint";
+ case SP_INTERSECTS_FUNC:
+ return "st_intersects";
+ case SP_TOUCHES_FUNC:
+ return "st_touches";
+ case SP_CROSSES_FUNC:
+ return "st_crosses";
+ case SP_OVERLAPS_FUNC:
+ return "st_overlaps";
+ default:
+ DBUG_ASSERT(0); // Should never happened
+ return "sp_unknown";
+ }
+}
+
+
+static double count_edge_t(const Gcalc_heap::Info *ea,
+ const Gcalc_heap::Info *eb,
+ const Gcalc_heap::Info *v,
+ double &ex, double &ey, double &vx, double &vy,
+ double &e_sqrlen)
+{
+ ex= eb->x - ea->x;
+ ey= eb->y - ea->y;
+ vx= v->x - ea->x;
+ vy= v->y - ea->y;
+ e_sqrlen= ex * ex + ey * ey;
+ return (ex * vx + ey * vy) / e_sqrlen;
+}
+
+
+static double distance_to_line(double ex, double ey, double vx, double vy,
+ double e_sqrlen)
+{
+ return fabs(vx * ey - vy * ex) / sqrt(e_sqrlen);
+}
+
+
+static double distance_points(const Gcalc_heap::Info *a,
+ const Gcalc_heap::Info *b)
+{
+ double x= a->x - b->x;
+ double y= a->y - b->y;
+ return sqrt(x * x + y * y);
+}
+
+
+#define GIS_ZERO 0.00000000001
+
+longlong Item_func_spatial_rel::val_int()
+{
+ DBUG_ENTER("Item_func_spatial_rel::val_int");
+ DBUG_ASSERT(fixed == 1);
+ String *res1;
+ String *res2;
+ Geometry_buffer buffer1, buffer2;
+ Geometry *g1, *g2;
+ int result= 0;
+ int mask= 0;
+ uint shape_a, shape_b;
+ MBR umbr, mbr1, mbr2;
+ const char *c_end;
+
+ res1= args[0]->val_str(&tmp_value1);
+ res2= args[1]->val_str(&tmp_value2);
+ Gcalc_operation_transporter trn(&func, &collector);
+
+ if (func.reserve_op_buffer(1))
+ DBUG_RETURN(0);
+
+ if ((null_value=
+ (args[0]->null_value || args[1]->null_value ||
+ !(g1= Geometry::construct(&buffer1, res1->ptr(), res1->length())) ||
+ !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length())))))
+ goto exit;
+
+ g1->get_mbr(&mbr1, &c_end);
+ g2->get_mbr(&mbr2, &c_end);
+
+ umbr= mbr1;
+ umbr.add_mbr(&mbr2);
+ collector.set_extent(umbr.xmin, umbr.xmax, umbr.ymin, umbr.ymax);
+
+ mbr1.buffer(1e-5);
+
+ switch (spatial_rel) {
+ case SP_CONTAINS_FUNC:
+ if (!mbr1.contains(&mbr2))
+ goto exit;
+ mask= 1;
+ func.add_operation(Gcalc_function::op_difference, 2);
+ /* Mind the g2 goes first. */
+ null_value= g2->store_shapes(&trn) || g1->store_shapes(&trn);
+ break;
+ case SP_WITHIN_FUNC:
+ mbr2.buffer(2e-5);
+ if (!mbr1.within(&mbr2))
+ goto exit;
+ mask= 1;
+ func.add_operation(Gcalc_function::op_difference, 2);
+ null_value= g1->store_shapes(&trn) || g2->store_shapes(&trn);
+ break;
+ case SP_EQUALS_FUNC:
+ if (!mbr1.contains(&mbr2))
+ goto exit;
+ mask= 1;
+ func.add_operation(Gcalc_function::op_symdifference, 2);
+ null_value= g1->store_shapes(&trn) || g2->store_shapes(&trn);
+ break;
+ case SP_DISJOINT_FUNC:
+ mask= 1;
+ func.add_operation(Gcalc_function::op_intersection, 2);
+ null_value= g1->store_shapes(&trn) || g2->store_shapes(&trn);
+ break;
+ case SP_INTERSECTS_FUNC:
+ if (!mbr1.intersects(&mbr2))
+ goto exit;
+ func.add_operation(Gcalc_function::op_intersection, 2);
+ null_value= g1->store_shapes(&trn) || g2->store_shapes(&trn);
+ break;
+ case SP_OVERLAPS_FUNC:
+ case SP_CROSSES_FUNC:
+ func.add_operation(Gcalc_function::op_intersection, 2);
+ func.add_operation(Gcalc_function::v_find_t |
+ Gcalc_function::op_intersection, 2);
+ shape_a= func.get_next_expression_pos();
+ if ((null_value= g1->store_shapes(&trn)))
+ break;
+ shape_b= func.get_next_expression_pos();
+ if ((null_value= g2->store_shapes(&trn)))
+ break;
+ func.add_operation(Gcalc_function::v_find_t |
+ Gcalc_function::op_intersection, 2);
+ func.add_operation(Gcalc_function::v_find_t |
+ Gcalc_function::op_difference, 2);
+ func.repeat_expression(shape_a);
+ func.repeat_expression(shape_b);
+ func.add_operation(Gcalc_function::v_find_t |
+ Gcalc_function::op_difference, 2);
+ func.repeat_expression(shape_b);
+ func.repeat_expression(shape_a);
+ break;
+ case SP_TOUCHES_FUNC:
+ func.add_operation(Gcalc_function::op_intersection, 2);
+ func.add_operation(Gcalc_function::v_find_f |
+ Gcalc_function::op_not |
+ Gcalc_function::op_intersection, 2);
+ func.add_operation(Gcalc_function::op_internals, 1);
+ shape_a= func.get_next_expression_pos();
+ if ((null_value= g1->store_shapes(&trn)))
+ break;
+ func.add_operation(Gcalc_function::op_internals, 1);
+ shape_b= func.get_next_expression_pos();
+ if ((null_value= g2->store_shapes(&trn)))
+ break;
+ func.add_operation(Gcalc_function::v_find_t |
+ Gcalc_function::op_intersection, 2);
+ func.add_operation(Gcalc_function::op_border, 1);
+ func.repeat_expression(shape_a);
+ func.add_operation(Gcalc_function::op_border, 1);
+ func.repeat_expression(shape_b);
+ break;
+ default:
+ DBUG_ASSERT(FALSE);
+ break;
+ }
+
+ if (null_value)
+ goto exit;
+
+ collector.prepare_operation();
+ scan_it.init(&collector);
+ scan_it.killed= (int *) &(current_thd->killed);
+
+ if (func.alloc_states())
+ goto exit;
+
+ result= func.check_function(scan_it) ^ mask;
+
+exit:
+ collector.reset();
+ func.reset();
+ scan_it.reset();
+ DBUG_RETURN(result);
+}
+
+
+Item_func_spatial_operation::~Item_func_spatial_operation()
+{
+}
+
+
+String *Item_func_spatial_operation::val_str(String *str_value)
+{
+ DBUG_ENTER("Item_func_spatial_operation::val_str");
+ DBUG_ASSERT(fixed == 1);
+ String *res1= args[0]->val_str(&tmp_value1);
+ String *res2= args[1]->val_str(&tmp_value2);
+ Geometry_buffer buffer1, buffer2;
+ Geometry *g1, *g2;
+ uint32 srid= 0;
+ Gcalc_operation_transporter trn(&func, &collector);
+ MBR mbr1, mbr2;
+ const char *c_end;
+
+ if (func.reserve_op_buffer(1))
+ DBUG_RETURN(0);
+ func.add_operation(spatial_op, 2);
+
+ if ((null_value=
+ (args[0]->null_value || args[1]->null_value ||
+ !(g1= Geometry::construct(&buffer1, res1->ptr(), res1->length())) ||
+ !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length())))))
+ {
+ str_value= 0;
+ goto exit;
+ }
+
+ g1->get_mbr(&mbr1, &c_end);
+ g2->get_mbr(&mbr2, &c_end);
+ mbr1.add_mbr(&mbr2);
+ collector.set_extent(mbr1.xmin, mbr1.xmax, mbr1.ymin, mbr1.ymax);
+
+ if ((null_value= g1->store_shapes(&trn) || g2->store_shapes(&trn)))
+ {
+ str_value= 0;
+ goto exit;
+ }
+
+ collector.prepare_operation();
+ if (func.alloc_states())
+ goto exit;
+
+ operation.init(&func);
+
+ if (operation.count_all(&collector) ||
+ operation.get_result(&res_receiver))
+ goto exit;
+
+
+ str_value->set_charset(&my_charset_bin);
+ if (str_value->reserve(SRID_SIZE, 512))
+ goto exit;
+ str_value->length(0);
+ str_value->q_append(srid);
+
+ if (!Geometry::create_from_opresult(&buffer1, str_value, res_receiver))
+ goto exit;
+
+exit:
+ collector.reset();
+ func.reset();
+ res_receiver.reset();
+ DBUG_RETURN(str_value);
+}
+
+
+const char *Item_func_spatial_operation::func_name() const
+{
+ switch (spatial_op) {
+ case Gcalc_function::op_intersection:
+ return "st_intersection";
+ case Gcalc_function::op_difference:
+ return "st_difference";
+ case Gcalc_function::op_union:
+ return "st_union";
+ case Gcalc_function::op_symdifference:
+ return "st_symdifference";
+ default:
+ DBUG_ASSERT(0); // Should never happen
+ return "sp_unknown";
+ }
+}
+
+
+static const int SINUSES_CALCULATED= 32;
+static double n_sinus[SINUSES_CALCULATED+1]=
+{
+ 0,
+ 0.04906767432741802,
+ 0.0980171403295606,
+ 0.1467304744553618,
+ 0.1950903220161283,
+ 0.2429801799032639,
+ 0.2902846772544623,
+ 0.3368898533922201,
+ 0.3826834323650898,
+ 0.4275550934302821,
+ 0.4713967368259976,
+ 0.5141027441932217,
+ 0.5555702330196022,
+ 0.5956993044924334,
+ 0.6343932841636455,
+ 0.6715589548470183,
+ 0.7071067811865475,
+ 0.7409511253549591,
+ 0.773010453362737,
+ 0.8032075314806448,
+ 0.8314696123025452,
+ 0.8577286100002721,
+ 0.8819212643483549,
+ 0.9039892931234433,
+ 0.9238795325112867,
+ 0.9415440651830208,
+ 0.9569403357322089,
+ 0.970031253194544,
+ 0.9807852804032304,
+ 0.989176509964781,
+ 0.9951847266721968,
+ 0.9987954562051724,
+ 1
+};
+
+
+static void get_n_sincos(int n, double *sinus, double *cosinus)
+{
+ DBUG_ASSERT(n > 0 && n < SINUSES_CALCULATED*2+1);
+ if (n < (SINUSES_CALCULATED + 1))
+ {
+ *sinus= n_sinus[n];
+ *cosinus= n_sinus[SINUSES_CALCULATED - n];
+ }
+ else
+ {
+ n-= SINUSES_CALCULATED;
+ *sinus= n_sinus[SINUSES_CALCULATED - n];
+ *cosinus= -n_sinus[n];
+ }
+}
+
+
+static int fill_half_circle(Gcalc_shape_transporter *trn, double x, double y,
+ double ax, double ay)
+{
+ double n_sin, n_cos;
+ double x_n, y_n;
+ for (int n = 1; n < (SINUSES_CALCULATED * 2 - 1); n++)
+ {
+ get_n_sincos(n, &n_sin, &n_cos);
+ x_n= ax * n_cos - ay * n_sin;
+ y_n= ax * n_sin + ay * n_cos;
+ if (trn->add_point(x_n + x, y_n + y))
+ return 1;
+ }
+ return 0;
+}
+
+
+static int fill_gap(Gcalc_shape_transporter *trn,
+ double x, double y,
+ double ax, double ay, double bx, double by, double d,
+ bool *empty_gap)
+{
+ double ab= ax * bx + ay * by;
+ double cosab= ab / (d * d) + GIS_ZERO;
+ double n_sin, n_cos;
+ double x_n, y_n;
+ int n=1;
+
+ *empty_gap= true;
+ for (;;)
+ {
+ get_n_sincos(n++, &n_sin, &n_cos);
+ if (n_cos <= cosab)
+ break;
+ *empty_gap= false;
+ x_n= ax * n_cos - ay * n_sin;
+ y_n= ax * n_sin + ay * n_cos;
+ if (trn->add_point(x_n + x, y_n + y))
+ return 1;
+ }
+ return 0;
+}
+
+
+/*
+ Calculates the vector (p2,p1) and
+ negatively orthogonal to it with the length of d.
+ The result is (ex,ey) - the vector, (px,py) - the orthogonal.
+*/
+
+static void calculate_perpendicular(
+ double x1, double y1, double x2, double y2, double d,
+ double *ex, double *ey,
+ double *px, double *py)
+{
+ double q;
+ *ex= x1 - x2;
+ *ey= y1 - y2;
+ q= d / sqrt((*ex) * (*ex) + (*ey) * (*ey));
+ *px= (*ey) * q;
+ *py= -(*ex) * q;
+}
+
+
+int Item_func_buffer::Transporter::single_point(double x, double y)
+{
+ if (buffer_op == Gcalc_function::op_difference)
+ {
+ m_fn->add_operation(Gcalc_function::op_false, 0);
+ return 0;
+ }
+
+ m_nshapes= 0;
+ return add_point_buffer(x, y);
+}
+
+
+int Item_func_buffer::Transporter::add_edge_buffer(
+ double x3, double y3, bool round_p1, bool round_p2)
+{
+ Gcalc_operation_transporter trn(m_fn, m_heap);
+ double e1_x, e1_y, e2_x, e2_y, p1_x, p1_y, p2_x, p2_y;
+ double e1e2;
+ double sin1, cos1;
+ double x_n, y_n;
+ bool empty_gap1, empty_gap2;
+
+ ++m_nshapes;
+ if (trn.start_simple_poly())
+ return 1;
+
+ calculate_perpendicular(x1, y1, x2, y2, m_d, &e1_x, &e1_y, &p1_x, &p1_y);
+ calculate_perpendicular(x3, y3, x2, y2, m_d, &e2_x, &e2_y, &p2_x, &p2_y);
+
+ e1e2= e1_x * e2_y - e2_x * e1_y;
+ sin1= n_sinus[1];
+ cos1= n_sinus[31];
+ if (e1e2 < 0)
+ {
+ empty_gap2= false;
+ x_n= x2 + p2_x * cos1 - p2_y * sin1;
+ y_n= y2 + p2_y * cos1 + p2_x * sin1;
+ if (fill_gap(&trn, x2, y2, -p1_x,-p1_y, p2_x,p2_y, m_d, &empty_gap1) ||
+ trn.add_point(x2 + p2_x, y2 + p2_y) ||
+ trn.add_point(x_n, y_n))
+ return 1;
+ }
+ else
+ {
+ x_n= x2 - p2_x * cos1 - p2_y * sin1;
+ y_n= y2 - p2_y * cos1 + p2_x * sin1;
+ if (trn.add_point(x_n, y_n) ||
+ trn.add_point(x2 - p2_x, y2 - p2_y) ||
+ fill_gap(&trn, x2, y2, -p2_x, -p2_y, p1_x, p1_y, m_d, &empty_gap2))
+ return 1;
+ empty_gap1= false;
+ }
+ if ((!empty_gap2 && trn.add_point(x2 + p1_x, y2 + p1_y)) ||
+ trn.add_point(x1 + p1_x, y1 + p1_y))
+ return 1;
+
+ if (round_p1 && fill_half_circle(&trn, x1, y1, p1_x, p1_y))
+ return 1;
+
+ if (trn.add_point(x1 - p1_x, y1 - p1_y) ||
+ (!empty_gap1 && trn.add_point(x2 - p1_x, y2 - p1_y)))
+ return 1;
+ return trn.complete_simple_poly();
+}
+
+
+int Item_func_buffer::Transporter::add_last_edge_buffer()
+{
+ Gcalc_operation_transporter trn(m_fn, m_heap);
+ double e1_x, e1_y, p1_x, p1_y;
+
+ ++m_nshapes;
+ if (trn.start_simple_poly())
+ return 1;
+
+ calculate_perpendicular(x1, y1, x2, y2, m_d, &e1_x, &e1_y, &p1_x, &p1_y);
+
+ if (trn.add_point(x1 + p1_x, y1 + p1_y) ||
+ trn.add_point(x1 - p1_x, y1 - p1_y) ||
+ trn.add_point(x2 - p1_x, y2 - p1_y) ||
+ fill_half_circle(&trn, x2, y2, -p1_x, -p1_y) ||
+ trn.add_point(x2 + p1_x, y2 + p1_y))
+ return 1;
+ return trn.complete_simple_poly();
+}
+
+
+int Item_func_buffer::Transporter::add_point_buffer(double x, double y)
+{
+ Gcalc_operation_transporter trn(m_fn, m_heap);
+
+ m_nshapes++;
+ if (trn.start_simple_poly())
+ return 1;
+ if (trn.add_point(x - m_d, y) ||
+ fill_half_circle(&trn, x, y, -m_d, 0.0) ||
+ trn.add_point(x + m_d, y) ||
+ fill_half_circle(&trn, x, y, m_d, 0.0))
+ return 1;
+ return trn.complete_simple_poly();
+}
+
+
+int Item_func_buffer::Transporter::start_line()
+{
+ if (buffer_op == Gcalc_function::op_difference)
+ {
+ m_fn->add_operation(Gcalc_function::op_false, 0);
+ skip_line= TRUE;
+ return 0;
+ }
+
+ m_nshapes= 0;
+
+ if (m_fn->reserve_op_buffer(2))
+ return 1;
+ last_shape_pos= m_fn->get_next_expression_pos();
+ m_fn->add_operation(buffer_op, 0);
+ m_npoints= 0;
+ int_start_line();
+ return 0;
+}
+
+
+int Item_func_buffer::Transporter::start_poly()
+{
+ m_nshapes= 1;
+
+ if (m_fn->reserve_op_buffer(2))
+ return 1;
+ last_shape_pos= m_fn->get_next_expression_pos();
+ m_fn->add_operation(buffer_op, 0);
+ return Gcalc_operation_transporter::start_poly();
+}
+
+
+int Item_func_buffer::Transporter::complete_poly()
+{
+ if (Gcalc_operation_transporter::complete_poly())
+ return 1;
+ m_fn->add_operands_to_op(last_shape_pos, m_nshapes);
+ return 0;
+}
+
+
+int Item_func_buffer::Transporter::start_ring()
+{
+ m_npoints= 0;
+ return Gcalc_operation_transporter::start_ring();
+}
+
+
+int Item_func_buffer::Transporter::start_collection(int n_objects)
+{
+ if (m_fn->reserve_op_buffer(1))
+ return 1;
+ m_fn->add_operation(Gcalc_function::op_union, n_objects);
+ return 0;
+}
+
+
+int Item_func_buffer::Transporter::add_point(double x, double y)
+{
+ if (skip_line)
+ return 0;
+
+ if (m_npoints && x == x2 && y == y2)
+ return 0;
+
+ ++m_npoints;
+
+ if (m_npoints == 1)
+ {
+ x00= x;
+ y00= y;
+ }
+ else if (m_npoints == 2)
+ {
+ x01= x;
+ y01= y;
+ }
+ else if (add_edge_buffer(x, y, (m_npoints == 3) && line_started(), false))
+ return 1;
+
+ x1= x2;
+ y1= y2;
+ x2= x;
+ y2= y;
+
+ return line_started() ? 0 : Gcalc_operation_transporter::add_point(x, y);
+}
+
+
+int Item_func_buffer::Transporter::complete()
+{
+ if (m_npoints)
+ {
+ if (m_npoints == 1)
+ {
+ if (add_point_buffer(x2, y2))
+ return 1;
+ }
+ else if (m_npoints == 2)
+ {
+ if (add_edge_buffer(x1, y1, true, true))
+ return 1;
+ }
+ else if (line_started())
+ {
+ if (add_last_edge_buffer())
+ return 1;
+ }
+ else
+ {
+ if (x2 != x00 || y2 != y00)
+ {
+ if (add_edge_buffer(x00, y00, false, false))
+ return 1;
+ x1= x2;
+ y1= y2;
+ x2= x00;
+ y2= y00;
+ }
+ if (add_edge_buffer(x01, y01, false, false))
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+int Item_func_buffer::Transporter::complete_line()
+{
+ if (!skip_line)
+ {
+ if (complete())
+ return 1;
+ int_complete_line();
+ m_fn->add_operands_to_op(last_shape_pos, m_nshapes);
+ }
+ skip_line= FALSE;
+ return 0;
+}
+
+
+int Item_func_buffer::Transporter::complete_ring()
+{
+ return complete() ||
+ Gcalc_operation_transporter::complete_ring();
+}
+
+
+String *Item_func_buffer::val_str(String *str_value)
+{
+ DBUG_ENTER("Item_func_buffer::val_str");
+ DBUG_ASSERT(fixed == 1);
+ String *obj= args[0]->val_str(&tmp_value);
+ double dist= args[1]->val_real();
+ Geometry_buffer buffer;
+ Geometry *g;
+ uint32 srid= 0;
+ String *str_result= NULL;
+ Transporter trn(&func, &collector, dist);
+ MBR mbr;
+ const char *c_end;
+
+ null_value= 1;
+ if (args[0]->null_value || args[1]->null_value ||
+ !(g= Geometry::construct(&buffer, obj->ptr(), obj->length())) ||
+ g->get_mbr(&mbr, &c_end))
+ goto mem_error;
+
+ if (dist > 0.0)
+ mbr.buffer(dist);
+ collector.set_extent(mbr.xmin, mbr.xmax, mbr.ymin, mbr.ymax);
+ /*
+ If the distance given is 0, the Buffer function is in fact NOOP,
+ so it's natural just to return the argument1.
+ Besides, internal calculations here can't handle zero distance anyway.
+ */
+ if (fabs(dist) < GIS_ZERO)
+ {
+ null_value= 0;
+ str_result= obj;
+ goto mem_error;
+ }
+
+ if (g->store_shapes(&trn))
+ goto mem_error;
+
+ collector.prepare_operation();
+ if (func.alloc_states())
+ goto mem_error;
+ operation.init(&func);
+ operation.killed= (int *) &(current_thd->killed);
+
+ if (operation.count_all(&collector) ||
+ operation.get_result(&res_receiver))
+ goto mem_error;
+
+
+ str_value->set_charset(&my_charset_bin);
+ if (str_value->reserve(SRID_SIZE, 512))
+ goto mem_error;
+ str_value->length(0);
+ str_value->q_append(srid);
+
+ if (!Geometry::create_from_opresult(&buffer, str_value, res_receiver))
+ goto mem_error;
+
+ null_value= 0;
+ str_result= str_value;
+mem_error:
+ collector.reset();
+ func.reset();
+ res_receiver.reset();
+ DBUG_RETURN(str_result);
+}
+
+
longlong Item_func_isempty::val_int()
{
DBUG_ASSERT(fixed == 1);
@@ -569,21 +1342,63 @@ longlong Item_func_isempty::val_int()
}
-/**
- @todo
- Ramil or Holyfoot, add real IsSimple calculation
-*/
longlong Item_func_issimple::val_int()
{
- DBUG_ASSERT(fixed == 1);
- String tmp;
String *swkb= args[0]->val_str(&tmp);
Geometry_buffer buffer;
+ Gcalc_operation_transporter trn(&func, &collector);
+ Geometry *g;
+ int result= 1;
+ const Gcalc_scan_iterator::event_point *ev;
+ MBR mbr;
+ const char *c_end;
+
+ DBUG_ENTER("Item_func_issimple::val_int");
+ DBUG_ASSERT(fixed == 1);
- null_value= args[0]->null_value ||
- !(Geometry::construct(&buffer, swkb->ptr(), swkb->length()));
- /* TODO: Ramil or Holyfoot, add real IsSimple calculation */
- return 0;
+ if ((null_value= args[0]->null_value) ||
+ !(g= Geometry::construct(&buffer, swkb->ptr(), swkb->length())))
+ DBUG_RETURN(0);
+
+ g->get_mbr(&mbr, &c_end);
+ collector.set_extent(mbr.xmin, mbr.xmax, mbr.ymin, mbr.ymax);
+
+ if (g->get_class_info()->m_type_id == Geometry::wkb_point)
+ DBUG_RETURN(1);
+
+ if (g->store_shapes(&trn))
+ goto mem_error;
+
+ collector.prepare_operation();
+ scan_it.init(&collector);
+
+ while (scan_it.more_points())
+ {
+ if (scan_it.step())
+ goto mem_error;
+
+ ev= scan_it.get_events();
+ if (ev->simple_event())
+ continue;
+
+ if ((ev->event == scev_thread || ev->event == scev_single_point) &&
+ !ev->get_next())
+ continue;
+
+ if (ev->event == scev_two_threads && !ev->get_next()->get_next())
+ continue;
+
+ result= 0;
+ break;
+ }
+
+ collector.reset();
+ func.reset();
+ scan_it.reset();
+ DBUG_RETURN(result);
+mem_error:
+ null_value= 1;
+ DBUG_RETURN(0);
}
@@ -731,12 +1546,13 @@ double Item_func_glength::val_real()
String *swkb= args[0]->val_str(&value);
Geometry_buffer buffer;
Geometry *geom;
+ const char *end;
null_value= (!swkb ||
!(geom= Geometry::construct(&buffer,
swkb->ptr(),
swkb->length())) ||
- geom->geom_length(&res));
+ geom->geom_length(&res, &end));
return res;
}
@@ -755,4 +1571,169 @@ longlong Item_func_srid::val_int()
return (longlong) (uint4korr(swkb->ptr()));
}
+
+double Item_func_distance::val_real()
+{
+ bool cur_point_edge;
+ const Gcalc_scan_iterator::point *evpos;
+ const Gcalc_heap::Info *cur_point, *dist_point;
+ const Gcalc_scan_iterator::event_point *ev;
+ double t, distance, cur_distance;
+ double x1, x2, y1, y2;
+ double ex, ey, vx, vy, e_sqrlen;
+ uint obj2_si;
+ Gcalc_operation_transporter trn(&func, &collector);
+
+ DBUG_ENTER("Item_func_distance::val_real");
+ DBUG_ASSERT(fixed == 1);
+ String *res1= args[0]->val_str(&tmp_value1);
+ String *res2= args[1]->val_str(&tmp_value2);
+ Geometry_buffer buffer1, buffer2;
+ Geometry *g1, *g2;
+ MBR mbr1, mbr2;
+ const char *c_end;
+
+
+ if ((null_value= (args[0]->null_value || args[1]->null_value ||
+ !(g1= Geometry::construct(&buffer1, res1->ptr(), res1->length())) ||
+ !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length())))))
+ goto mem_error;
+
+ g1->get_mbr(&mbr1, &c_end);
+ g2->get_mbr(&mbr2, &c_end);
+ mbr1.add_mbr(&mbr2);
+ collector.set_extent(mbr1.xmin, mbr1.xmax, mbr1.ymin, mbr1.ymax);
+
+ if ((g1->get_class_info()->m_type_id == Geometry::wkb_point) &&
+ (g2->get_class_info()->m_type_id == Geometry::wkb_point))
+ {
+ if (((Gis_point *) g1)->get_xy(&x1, &y1) ||
+ ((Gis_point *) g2)->get_xy(&x2, &y2))
+ goto mem_error;
+ ex= x2 - x1;
+ ey= y2 - y1;
+ DBUG_RETURN(sqrt(ex * ex + ey * ey));
+ }
+
+ if (func.reserve_op_buffer(1))
+ goto mem_error;
+ func.add_operation(Gcalc_function::op_intersection, 2);
+
+ if (g1->store_shapes(&trn))
+ goto mem_error;
+ obj2_si= func.get_nshapes();
+ if (g2->store_shapes(&trn) || func.alloc_states())
+ goto mem_error;
+
+ if (obj2_si == 0 || func.get_nshapes() == obj2_si)
+ {
+ distance= 0.0;
+ null_value= 1;
+ goto exit;
+ }
+
+
+ collector.prepare_operation();
+ scan_it.init(&collector);
+
+ distance= DBL_MAX;
+ while (scan_it.more_points())
+ {
+ if (scan_it.step())
+ goto mem_error;
+ evpos= scan_it.get_event_position();
+ ev= scan_it.get_events();
+
+ if (ev->simple_event())
+ {
+ cur_point= ev->pi;
+ goto count_distance;
+ }
+ /*
+ handling intersection we only need to check if it's the intersecion
+ of objects 1 and 2. In this case distance is 0
+ */
+ cur_point= NULL;
+
+ /*
+ having these events we need to check for possible intersection
+ of objects
+ scev_thread | scev_two_threads | scev_single_point
+ */
+ func.clear_i_states();
+ for (Gcalc_point_iterator pit(&scan_it); pit.point() != evpos; ++pit)
+ {
+ gcalc_shape_info si= pit.point()->get_shape();
+ if ((func.get_shape_kind(si) == Gcalc_function::shape_polygon))
+ func.invert_i_state(si);
+ }
+
+ func.clear_b_states();
+ for (; ev; ev= ev->get_next())
+ {
+ if (ev->event != scev_intersection)
+ cur_point= ev->pi;
+ func.set_b_state(ev->get_shape());
+ if (func.count())
+ {
+ /* Point of one object is inside the other - intersection found */
+ distance= 0;
+ goto exit;
+ }
+ }
+
+ if (!cur_point)
+ continue;
+
+count_distance:
+ if (cur_point->shape >= obj2_si)
+ continue;
+ cur_point_edge= !cur_point->is_bottom();
+
+ for (dist_point= collector.get_first(); dist_point; dist_point= dist_point->get_next())
+ {
+ /* We only check vertices of object 2 */
+ if (dist_point->type != Gcalc_heap::nt_shape_node ||
+ dist_point->shape < obj2_si)
+ continue;
+
+ /* if we have an edge to check */
+ if (dist_point->left)
+ {
+ t= count_edge_t(dist_point, dist_point->left, cur_point,
+ ex, ey, vx, vy, e_sqrlen);
+ if ((t>0.0) && (t<1.0))
+ {
+ cur_distance= distance_to_line(ex, ey, vx, vy, e_sqrlen);
+ if (distance > cur_distance)
+ distance= cur_distance;
+ }
+ }
+ if (cur_point_edge)
+ {
+ t= count_edge_t(cur_point, cur_point->left, dist_point,
+ ex, ey, vx, vy, e_sqrlen);
+ if ((t>0.0) && (t<1.0))
+ {
+ cur_distance= distance_to_line(ex, ey, vx, vy, e_sqrlen);
+ if (distance > cur_distance)
+ distance= cur_distance;
+ }
+ }
+ cur_distance= distance_points(cur_point, dist_point);
+ if (distance > cur_distance)
+ distance= cur_distance;
+ }
+ }
+exit:
+ collector.reset();
+ func.reset();
+ scan_it.reset();
+ DBUG_RETURN(distance);
+mem_error:
+ null_value= 1;
+ DBUG_RETURN(0);
+}
+
+
#endif /*HAVE_SPATIAL*/
diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h
index 0bcd933e52b..eae6f425f4d 100644
--- a/sql/item_geofunc.h
+++ b/sql/item_geofunc.h
@@ -1,4 +1,8 @@
-/* Copyright (c) 2003, 2011, Oracle and/or its affiliates.
+#ifndef ITEM_GEOFUNC_INCLUDED
+#define ITEM_GEOFUNC_INCLUDED
+
+/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved.
+ Copyright (C) 2011 Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -10,8 +14,8 @@
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 */
+ along with this program; if not, write to the Free Software Foundation,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
/* This file defines all spatial functions */
@@ -22,6 +26,9 @@
#pragma interface /* gcc class implementation */
#endif
+#include "gcalc_slicescan.h"
+#include "gcalc_tools.h"
+
class Item_geometry_func: public Item_str_func
{
public:
@@ -41,7 +48,7 @@ class Item_func_geometry_from_text: public Item_geometry_func
public:
Item_func_geometry_from_text(Item *a) :Item_geometry_func(a) {}
Item_func_geometry_from_text(Item *a, Item *srid) :Item_geometry_func(a, srid) {}
- const char *func_name() const { return "geometryfromtext"; }
+ const char *func_name() const { return "st_geometryfromtext"; }
String *val_str(String *);
};
@@ -50,7 +57,7 @@ class Item_func_geometry_from_wkb: public Item_geometry_func
public:
Item_func_geometry_from_wkb(Item *a): Item_geometry_func(a) {}
Item_func_geometry_from_wkb(Item *a, Item *srid): Item_geometry_func(a, srid) {}
- const char *func_name() const { return "geometryfromwkb"; }
+ const char *func_name() const { return "st_geometryfromwkb"; }
String *val_str(String *);
};
@@ -58,7 +65,7 @@ class Item_func_as_wkt: public Item_str_func
{
public:
Item_func_as_wkt(Item *a): Item_str_func(a) {}
- const char *func_name() const { return "astext"; }
+ const char *func_name() const { return "st_astext"; }
String *val_str(String *);
void fix_length_and_dec();
};
@@ -67,7 +74,7 @@ class Item_func_as_wkb: public Item_geometry_func
{
public:
Item_func_as_wkb(Item *a): Item_geometry_func(a) {}
- const char *func_name() const { return "aswkb"; }
+ const char *func_name() const { return "st_aswkb"; }
String *val_str(String *);
enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
};
@@ -77,11 +84,12 @@ class Item_func_geometry_type: public Item_str_func
public:
Item_func_geometry_type(Item *a): Item_str_func(a) {}
String *val_str(String *);
- const char *func_name() const { return "geometrytype"; }
+ const char *func_name() const { return "st_geometrytype"; }
void fix_length_and_dec()
{
- max_length=20; // "GeometryCollection" is the most long
- maybe_null= 1;
+ // "GeometryCollection" is the longest
+ max_length= 20;
+ set_persist_maybe_null(1);
};
};
@@ -89,7 +97,7 @@ class Item_func_centroid: public Item_geometry_func
{
public:
Item_func_centroid(Item *a): Item_geometry_func(a) {}
- const char *func_name() const { return "centroid"; }
+ const char *func_name() const { return "st_centroid"; }
String *val_str(String *);
Field::geometry_type get_geometry_type() const;
};
@@ -98,7 +106,7 @@ class Item_func_envelope: public Item_geometry_func
{
public:
Item_func_envelope(Item *a): Item_geometry_func(a) {}
- const char *func_name() const { return "envelope"; }
+ const char *func_name() const { return "st_envelope"; }
String *val_str(String *);
Field::geometry_type get_geometry_type() const;
};
@@ -108,7 +116,7 @@ class Item_func_point: public Item_geometry_func
public:
Item_func_point(Item *a, Item *b): Item_geometry_func(a, b) {}
Item_func_point(Item *a, Item *b, Item *srid): Item_geometry_func(a, b, srid) {}
- const char *func_name() const { return "point"; }
+ const char *func_name() const { return "st_point"; }
String *val_str(String *);
Field::geometry_type get_geometry_type() const;
};
@@ -124,11 +132,11 @@ public:
switch (decomp_func)
{
case SP_STARTPOINT:
- return "startpoint";
+ return "st_startpoint";
case SP_ENDPOINT:
- return "endpoint";
+ return "st_endpoint";
case SP_EXTERIORRING:
- return "exteriorring";
+ return "st_exteriorring";
default:
DBUG_ASSERT(0); // Should never happened
return "spatial_decomp_unknown";
@@ -148,11 +156,11 @@ public:
switch (decomp_func_n)
{
case SP_POINTN:
- return "pointn";
+ return "st_pointn";
case SP_GEOMETRYN:
- return "geometryn";
+ return "st_geometryn";
case SP_INTERIORRINGN:
- return "interiorringn";
+ return "st_interiorringn";
default:
DBUG_ASSERT(0); // Should never happened
return "spatial_decomp_n_unknown";
@@ -191,84 +199,164 @@ public:
}
}
- const char *func_name() const { return "multipoint"; }
+ const char *func_name() const { return "st_multipoint"; }
};
+
/*
Spatial relations
*/
-class Item_func_spatial_rel: public Item_bool_func2
+class Item_func_spatial_mbr_rel: public Item_bool_func2
{
enum Functype spatial_rel;
public:
- Item_func_spatial_rel(Item *a,Item *b, enum Functype sp_rel) :
+ Item_func_spatial_mbr_rel(Item *a,Item *b, enum Functype sp_rel) :
Item_bool_func2(a,b) { spatial_rel = sp_rel; }
longlong val_int();
enum Functype functype() const
{
- switch (spatial_rel) {
- case SP_CONTAINS_FUNC:
- return SP_WITHIN_FUNC;
- case SP_WITHIN_FUNC:
- return SP_CONTAINS_FUNC;
- default:
- return spatial_rel;
- }
+ return spatial_rel;
}
enum Functype rev_functype() const { return spatial_rel; }
- const char *func_name() const
- {
- switch (spatial_rel) {
- case SP_CONTAINS_FUNC:
- return "contains";
- case SP_WITHIN_FUNC:
- return "within";
- case SP_EQUALS_FUNC:
- return "equals";
- case SP_DISJOINT_FUNC:
- return "disjoint";
- case SP_INTERSECTS_FUNC:
- return "intersects";
- case SP_TOUCHES_FUNC:
- return "touches";
- case SP_CROSSES_FUNC:
- return "crosses";
- case SP_OVERLAPS_FUNC:
- return "overlaps";
- default:
- DBUG_ASSERT(0); // Should never happened
- return "sp_unknown";
- }
+ const char *func_name() const;
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ Item_func::print(str, query_type);
}
+ void fix_length_and_dec() { set_persist_maybe_null(1); }
+ bool is_null() { (void) val_int(); return null_value; }
+};
+
+class Item_func_spatial_rel: public Item_bool_func2
+{
+ enum Functype spatial_rel;
+ Gcalc_heap collector;
+ Gcalc_scan_iterator scan_it;
+ Gcalc_function func;
+ String tmp_value1,tmp_value2;
+public:
+ Item_func_spatial_rel(Item *a,Item *b, enum Functype sp_rel);
+ virtual ~Item_func_spatial_rel();
+ longlong val_int();
+ enum Functype functype() const
+ {
+ return spatial_rel;
+ }
+ enum Functype rev_functype() const { return spatial_rel; }
+ const char *func_name() const;
virtual inline void print(String *str, enum_query_type query_type)
{
Item_func::print(str, query_type);
}
- void fix_length_and_dec() { maybe_null= 1; }
+ void fix_length_and_dec() { set_persist_maybe_null(1); }
bool is_null() { (void) val_int(); return null_value; }
};
+
+/*
+ Spatial operations
+*/
+
+class Item_func_spatial_operation: public Item_geometry_func
+{
+public:
+ Gcalc_function::op_type spatial_op;
+ Gcalc_heap collector;
+ Gcalc_function func;
+
+ Gcalc_result_receiver res_receiver;
+ Gcalc_operation_reducer operation;
+ String tmp_value1,tmp_value2;
+public:
+ Item_func_spatial_operation(Item *a,Item *b, Gcalc_function::op_type sp_op) :
+ Item_geometry_func(a, b), spatial_op(sp_op)
+ {}
+ virtual ~Item_func_spatial_operation();
+ String *val_str(String *);
+ const char *func_name() const;
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ Item_func::print(str, query_type);
+ }
+};
+
+
+class Item_func_buffer: public Item_geometry_func
+{
+protected:
+ class Transporter : public Gcalc_operation_transporter
+ {
+ int m_npoints;
+ double m_d;
+ double x1,y1,x2,y2;
+ double x00,y00,x01,y01;
+ int add_edge_buffer(double x3, double y3, bool round_p1, bool round_p2);
+ int add_last_edge_buffer();
+ int add_point_buffer(double x, double y);
+ int complete();
+ int m_nshapes;
+ Gcalc_function::op_type buffer_op;
+ int last_shape_pos;
+ bool skip_line;
+
+ public:
+ Transporter(Gcalc_function *fn, Gcalc_heap *heap, double d) :
+ Gcalc_operation_transporter(fn, heap), m_npoints(0), m_d(d),
+ m_nshapes(0), buffer_op((d > 0.0) ? Gcalc_function::op_union :
+ Gcalc_function::op_difference),
+ skip_line(FALSE)
+ {}
+ int single_point(double x, double y);
+ int start_line();
+ int complete_line();
+ int start_poly();
+ int complete_poly();
+ int start_ring();
+ int complete_ring();
+ int add_point(double x, double y);
+
+ int start_collection(int n_objects);
+ };
+ Gcalc_heap collector;
+ Gcalc_function func;
+
+ Gcalc_result_receiver res_receiver;
+ Gcalc_operation_reducer operation;
+ String tmp_value;
+
+public:
+ Item_func_buffer(Item *obj, Item *distance):
+ Item_geometry_func(obj, distance) {}
+ const char *func_name() const { return "st_buffer"; }
+ String *val_str(String *);
+};
+
+
class Item_func_isempty: public Item_bool_func
{
public:
Item_func_isempty(Item *a): Item_bool_func(a) {}
longlong val_int();
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
- const char *func_name() const { return "isempty"; }
- void fix_length_and_dec() { maybe_null= 1; }
+ const char *func_name() const { return "st_isempty"; }
+ void fix_length_and_dec() { set_persist_maybe_null(1); }
};
class Item_func_issimple: public Item_bool_func
{
+ Gcalc_heap collector;
+ Gcalc_function func;
+ Gcalc_scan_iterator scan_it;
+ String tmp;
public:
Item_func_issimple(Item *a): Item_bool_func(a) {}
longlong val_int();
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
- const char *func_name() const { return "issimple"; }
- void fix_length_and_dec() { maybe_null= 1; }
+ const char *func_name() const { return "st_issimple"; }
+ void fix_length_and_dec() { set_persist_maybe_null(1); }
};
class Item_func_isclosed: public Item_bool_func
@@ -277,8 +365,8 @@ public:
Item_func_isclosed(Item *a): Item_bool_func(a) {}
longlong val_int();
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
- const char *func_name() const { return "isclosed"; }
- void fix_length_and_dec() { maybe_null= 1; }
+ const char *func_name() const { return "st_isclosed"; }
+ void fix_length_and_dec() { set_persist_maybe_null(1); }
};
class Item_func_dimension: public Item_int_func
@@ -287,8 +375,8 @@ class Item_func_dimension: public Item_int_func
public:
Item_func_dimension(Item *a): Item_int_func(a) {}
longlong val_int();
- const char *func_name() const { return "dimension"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ const char *func_name() const { return "st_dimension"; }
+ void fix_length_and_dec() { max_length= 10; set_persist_maybe_null(1); }
};
class Item_func_x: public Item_real_func
@@ -297,11 +385,11 @@ class Item_func_x: public Item_real_func
public:
Item_func_x(Item *a): Item_real_func(a) {}
double val_real();
- const char *func_name() const { return "x"; }
+ const char *func_name() const { return "st_x"; }
void fix_length_and_dec()
{
Item_real_func::fix_length_and_dec();
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
};
@@ -312,11 +400,11 @@ class Item_func_y: public Item_real_func
public:
Item_func_y(Item *a): Item_real_func(a) {}
double val_real();
- const char *func_name() const { return "y"; }
+ const char *func_name() const { return "st_y"; }
void fix_length_and_dec()
{
Item_real_func::fix_length_and_dec();
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
};
@@ -327,8 +415,8 @@ class Item_func_numgeometries: public Item_int_func
public:
Item_func_numgeometries(Item *a): Item_int_func(a) {}
longlong val_int();
- const char *func_name() const { return "numgeometries"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ const char *func_name() const { return "st_numgeometries"; }
+ void fix_length_and_dec() { max_length= 10; set_persist_maybe_null(1); }
};
@@ -338,8 +426,8 @@ class Item_func_numinteriorring: public Item_int_func
public:
Item_func_numinteriorring(Item *a): Item_int_func(a) {}
longlong val_int();
- const char *func_name() const { return "numinteriorrings"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ const char *func_name() const { return "st_numinteriorrings"; }
+ void fix_length_and_dec() { max_length= 10; set_persist_maybe_null(1); }
};
@@ -349,8 +437,8 @@ class Item_func_numpoints: public Item_int_func
public:
Item_func_numpoints(Item *a): Item_int_func(a) {}
longlong val_int();
- const char *func_name() const { return "numpoints"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ const char *func_name() const { return "st_numpoints"; }
+ void fix_length_and_dec() { max_length= 10; set_persist_maybe_null(1); }
};
@@ -360,11 +448,11 @@ class Item_func_area: public Item_real_func
public:
Item_func_area(Item *a): Item_real_func(a) {}
double val_real();
- const char *func_name() const { return "area"; }
+ const char *func_name() const { return "st_area"; }
void fix_length_and_dec()
{
Item_real_func::fix_length_and_dec();
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
};
@@ -375,11 +463,11 @@ class Item_func_glength: public Item_real_func
public:
Item_func_glength(Item *a): Item_real_func(a) {}
double val_real();
- const char *func_name() const { return "glength"; }
+ const char *func_name() const { return "st_length"; }
void fix_length_and_dec()
{
Item_real_func::fix_length_and_dec();
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
};
@@ -391,7 +479,21 @@ public:
Item_func_srid(Item *a): Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "srid"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ void fix_length_and_dec() { max_length= 10; set_persist_maybe_null(1); }
+};
+
+
+class Item_func_distance: public Item_real_func
+{
+ String tmp_value1;
+ String tmp_value2;
+ Gcalc_heap collector;
+ Gcalc_function func;
+ Gcalc_scan_iterator scan_it;
+public:
+ Item_func_distance(Item *a, Item *b): Item_real_func(a, b) {}
+ double val_real();
+ const char *func_name() const { return "st_distance"; }
};
#define GEOM_NEW(thd, obj_constructor) new (thd->mem_root) obj_constructor
@@ -400,5 +502,6 @@ public:
#define GEOM_NEW(thd, obj_constructor) NULL
-#endif
+#endif /*HAVE_SPATIAL*/
+#endif /*ITEM_GEOFUNC_INCLUDED*/
diff --git a/sql/item_row.cc b/sql/item_row.cc
index 5296f866248..d9d3e359338 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -68,7 +68,8 @@ bool Item_row::fix_fields(THD *thd, Item **ref)
Item **arg, **arg_end;
for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++)
{
- if ((*arg)->fix_fields(thd, arg))
+ if (!(*arg)->fixed &&
+ (*arg)->fix_fields(thd, arg))
return TRUE;
// we can't assign 'item' before, because fix_fields() can change arg
Item *item= *arg;
@@ -88,6 +89,7 @@ bool Item_row::fix_fields(THD *thd, Item **ref)
}
maybe_null|= item->maybe_null;
with_sum_func= with_sum_func || item->with_sum_func;
+ with_field= with_field || item->with_field;
with_subselect|= item->with_subselect;
}
fixed= 1;
@@ -95,6 +97,22 @@ bool Item_row::fix_fields(THD *thd, Item **ref)
}
+bool
+Item_row::eval_not_null_tables(uchar *opt_arg)
+{
+ Item **arg,**arg_end;
+ not_null_tables_cache= 0;
+ if (arg_count)
+ {
+ for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++)
+ {
+ not_null_tables_cache|= (*arg)->not_null_tables();
+ }
+ }
+ return FALSE;
+}
+
+
void Item_row::cleanup()
{
DBUG_ENTER("Item_row::cleanup");
@@ -122,14 +140,32 @@ void Item_row::update_used_tables()
{
used_tables_cache= 0;
const_item_cache= 1;
+ maybe_null= 0;
for (uint i= 0; i < arg_count; i++)
{
items[i]->update_used_tables();
used_tables_cache|= items[i]->used_tables();
const_item_cache&= items[i]->const_item();
+ maybe_null|= items[i]->maybe_null;
}
}
+
+void Item_row::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ used_tables_cache= 0;
+ const_item_cache= 1;
+ not_null_tables_cache= 0;
+ for (uint i= 0; i < arg_count; i++)
+ {
+ items[i]->fix_after_pullout(new_parent, &items[i]);
+ used_tables_cache|= items[i]->used_tables();
+ const_item_cache&= items[i]->const_item();
+ not_null_tables_cache|= items[i]->not_null_tables();
+ }
+}
+
+
bool Item_row::check_cols(uint c)
{
if (c != arg_count)
diff --git a/sql/item_row.h b/sql/item_row.h
index 15dadb3d01c..6366ccba102 100644
--- a/sql/item_row.h
+++ b/sql/item_row.h
@@ -62,17 +62,20 @@ 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; };
bool const_item() const { return const_item_cache; };
enum Item_result result_type() const { return ROW_RESULT; }
+ Item_result cmp_type() const { return ROW_RESULT; }
void update_used_tables();
table_map not_null_tables() const { return not_null_tables_cache; }
virtual void print(String *str, enum_query_type query_type);
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
Item *transform(Item_transformer transformer, uchar *arg);
+ bool eval_not_null_tables(uchar *opt_arg);
uint cols() { return arg_count; }
Item* element_index(uint i) { return items[i]; }
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 06542bcd291..71526c433ed 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -272,7 +272,7 @@ String *Item_func_aes_decrypt::val_str(String *str)
void Item_func_aes_decrypt::fix_length_and_dec()
{
max_length=args[0]->max_length;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
@@ -435,7 +435,7 @@ void Item_func_concat::fix_length_and_dec()
if (max_result_length >= MAX_BLOB_WIDTH)
{
max_result_length= MAX_BLOB_WIDTH;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
max_length= (ulong) max_result_length;
}
@@ -795,7 +795,7 @@ void Item_func_concat_ws::fix_length_and_dec()
if (max_result_length >= MAX_BLOB_WIDTH)
{
max_result_length= MAX_BLOB_WIDTH;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
max_length= (ulong) max_result_length;
}
@@ -997,7 +997,7 @@ void Item_func_replace::fix_length_and_dec()
if (max_result_length >= MAX_BLOB_WIDTH)
{
max_result_length= MAX_BLOB_WIDTH;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
max_length= (ulong) max_result_length;
@@ -1081,7 +1081,7 @@ void Item_func_insert::fix_length_and_dec()
if (max_result_length >= MAX_BLOB_WIDTH)
{
max_result_length= MAX_BLOB_WIDTH;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
max_length= (ulong) max_result_length;
}
@@ -2186,7 +2186,7 @@ void Item_func_elt::fix_length_and_dec()
set_if_bigger(max_length,args[i]->max_length);
set_if_bigger(decimals,args[i]->decimals);
}
- maybe_null=1; // NULL if wrong first arg
+ set_persist_maybe_null(1); // NULL if wrong first arg
}
@@ -2255,6 +2255,7 @@ void Item_func_make_set::fix_length_and_dec()
not_null_tables_cache&= item->not_null_tables();
const_item_cache&= item->const_item();
with_sum_func= with_sum_func || item->with_sum_func;
+ with_field= with_field || item->with_field;
}
@@ -2422,14 +2423,14 @@ void Item_func_repeat::fix_length_and_dec()
if (max_result_length >= MAX_BLOB_WIDTH)
{
max_result_length= MAX_BLOB_WIDTH;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
max_length= (ulong) max_result_length;
}
else
{
max_length= MAX_BLOB_WIDTH;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
}
@@ -2514,14 +2515,14 @@ void Item_func_rpad::fix_length_and_dec()
if (length >= MAX_BLOB_WIDTH)
{
length= MAX_BLOB_WIDTH;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
max_length= (ulong) length;
}
else
{
max_length= MAX_BLOB_WIDTH;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
}
@@ -2633,14 +2634,14 @@ void Item_func_lpad::fix_length_and_dec()
if (length >= MAX_BLOB_WIDTH)
{
length= MAX_BLOB_WIDTH;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
max_length= (ulong) length;
}
else
{
max_length= MAX_BLOB_WIDTH;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
}
@@ -3034,16 +3035,16 @@ String *Item_load_file::val_str(String *str)
func_name(), current_thd->variables.max_allowed_packet);
goto err;
}
- if (tmp_value.alloc(stat_info.st_size))
+ if (tmp_value.alloc((size_t)stat_info.st_size))
goto err;
if ((file = my_open(file_name->ptr(), O_RDONLY, MYF(0))) < 0)
goto err;
- if (my_read(file, (uchar*) tmp_value.ptr(), stat_info.st_size, MYF(MY_NABP)))
+ if (my_read(file, (uchar*) tmp_value.ptr(), (size_t)stat_info.st_size, MYF(MY_NABP)))
{
my_close(file, MYF(0));
goto err;
}
- tmp_value.length(stat_info.st_size);
+ tmp_value.length((uint32)stat_info.st_size);
my_close(file, MYF(0));
null_value = 0;
DBUG_RETURN(&tmp_value);
@@ -3531,3 +3532,768 @@ String *Item_func_uuid::val_str(String *str)
return str;
}
+
+
+Item_func_dyncol_create::Item_func_dyncol_create(List<Item> &args,
+ DYNCALL_CREATE_DEF *dfs)
+ : Item_str_func(args), defs(dfs), vals(0), nums(0)
+{
+ DBUG_ASSERT((args.elements & 0x1) == 0); // even number of arguments
+}
+
+
+bool Item_func_dyncol_create::fix_fields(THD *thd, Item **ref)
+{
+ bool res= Item_func::fix_fields(thd, ref); // no need Item_str_func here
+ vals= (DYNAMIC_COLUMN_VALUE *) alloc_root(thd->mem_root,
+ sizeof(DYNAMIC_COLUMN_VALUE) *
+ (arg_count / 2));
+ nums= (uint *) alloc_root(thd->mem_root,
+ sizeof(uint) * (arg_count / 2));
+ return res || vals == 0 || nums == 0;
+}
+
+
+void Item_func_dyncol_create::fix_length_and_dec()
+{
+ set_persist_maybe_null(1);
+ collation.set(&my_charset_bin);
+ decimals= 0;
+}
+
+void Item_func_dyncol_create::prepare_arguments()
+{
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String *res, tmp(buff, sizeof(buff), &my_charset_bin);
+ uint column_count= (arg_count / 2);
+ uint i;
+ my_decimal dtmp, *dres;
+
+ /* get values */
+ for (i= 0; i < column_count; i++)
+ {
+ uint valpos= i * 2 + 1;
+ DYNAMIC_COLUMN_TYPE type= defs[i].type;
+ if (type == DYN_COL_NULL) // auto detect
+ {
+ /*
+ We don't have a default here to ensure we get a warning if
+ one adds a new not handled MYSQL_TYPE_...
+ */
+ switch (args[valpos]->field_type()) {
+ case MYSQL_TYPE_DECIMAL:
+ case MYSQL_TYPE_NEWDECIMAL:
+ type= DYN_COL_DECIMAL;
+ break;
+ case MYSQL_TYPE_TINY:
+ case MYSQL_TYPE_SHORT:
+ case MYSQL_TYPE_LONG:
+ case MYSQL_TYPE_LONGLONG:
+ case MYSQL_TYPE_INT24:
+ case MYSQL_TYPE_YEAR:
+ case MYSQL_TYPE_BIT:
+ type= args[valpos]->unsigned_flag ? DYN_COL_UINT : DYN_COL_INT;
+ break;
+ case MYSQL_TYPE_FLOAT:
+ case MYSQL_TYPE_DOUBLE:
+ type= DYN_COL_DOUBLE;
+ break;
+ case MYSQL_TYPE_NULL:
+ type= DYN_COL_NULL;
+ break;
+ case MYSQL_TYPE_TIMESTAMP:
+ case MYSQL_TYPE_DATETIME:
+ type= DYN_COL_DATETIME;
+ break;
+ case MYSQL_TYPE_DATE:
+ case MYSQL_TYPE_NEWDATE:
+ type= DYN_COL_DATE;
+ break;
+ case MYSQL_TYPE_TIME:
+ type= DYN_COL_TIME;
+ break;
+ case MYSQL_TYPE_VARCHAR:
+ case MYSQL_TYPE_ENUM:
+ case MYSQL_TYPE_SET:
+ case MYSQL_TYPE_TINY_BLOB:
+ case MYSQL_TYPE_MEDIUM_BLOB:
+ case MYSQL_TYPE_LONG_BLOB:
+ case MYSQL_TYPE_BLOB:
+ case MYSQL_TYPE_VAR_STRING:
+ case MYSQL_TYPE_STRING:
+ case MYSQL_TYPE_GEOMETRY:
+ type= DYN_COL_STRING;
+ break;
+ }
+ }
+ nums[i]= (uint) args[i * 2]->val_int();
+ vals[i].type= type;
+ switch (type) {
+ case DYN_COL_NULL:
+ DBUG_ASSERT(args[valpos]->field_type() == MYSQL_TYPE_NULL);
+ break;
+ case DYN_COL_INT:
+ vals[i].x.long_value= args[valpos]->val_int();
+ break;
+ case DYN_COL_UINT:
+ vals[i].x.ulong_value= args[valpos]->val_int();
+ break;
+ case DYN_COL_DOUBLE:
+ vals[i].x.double_value= args[valpos]->val_real();
+ break;
+ case DYN_COL_STRING:
+ res= args[valpos]->val_str(&tmp);
+ if (res &&
+ (vals[i].x.string.value.str= my_strndup(res->ptr(), res->length(),
+ MYF(MY_WME))))
+ {
+ vals[i].x.string.value.length= res->length();
+ vals[i].x.string.charset= res->charset();
+ }
+ else
+ {
+ args[valpos]->null_value= 1; // In case of out of memory
+ vals[i].x.string.value.str= NULL;
+ vals[i].x.string.value.length= 0; // just to be safe
+ }
+ break;
+ case DYN_COL_DECIMAL:
+ if ((dres= args[valpos]->val_decimal(&dtmp)))
+ {
+ dynamic_column_prepare_decimal(&vals[i]);
+ DBUG_ASSERT(vals[i].x.decimal.value.len == dres->len);
+ vals[i].x.decimal.value.intg= dres->intg;
+ vals[i].x.decimal.value.frac= dres->frac;
+ vals[i].x.decimal.value.sign= dres->sign();
+ memcpy(vals[i].x.decimal.buffer, dres->buf,
+ sizeof(vals[i].x.decimal.buffer));
+ }
+ else
+ {
+ dynamic_column_prepare_decimal(&vals[i]); // just to be safe
+ DBUG_ASSERT(args[valpos]->null_value);
+ }
+ break;
+ case DYN_COL_DATETIME:
+ args[valpos]->get_date(&vals[i].x.time_value, TIME_FUZZY_DATE);
+ break;
+ case DYN_COL_DATE:
+ args[valpos]->get_date(&vals[i].x.time_value, TIME_FUZZY_DATE);
+ break;
+ case DYN_COL_TIME:
+ args[valpos]->get_time(&vals[i].x.time_value);
+ break;
+ default:
+ DBUG_ASSERT(0);
+ vals[i].type= DYN_COL_NULL;
+ }
+ if (vals[i].type != DYN_COL_NULL && args[valpos]->null_value)
+ {
+ if (vals[i].type == DYN_COL_STRING)
+ my_free(vals[i].x.string.value.str, MYF(MY_ALLOW_ZERO_PTR));
+ vals[i].type= DYN_COL_NULL;
+ }
+ }
+}
+
+void Item_func_dyncol_create::cleanup_arguments()
+{
+ uint column_count= (arg_count / 2);
+ uint i;
+
+ for (i= 0; i < column_count; i++)
+ {
+ if (vals[i].type == DYN_COL_STRING)
+ my_free(vals[i].x.string.value.str, MYF(MY_ALLOW_ZERO_PTR));
+ }
+}
+
+String *Item_func_dyncol_create::val_str(String *str)
+{
+ DYNAMIC_COLUMN col;
+ String *res;
+ uint column_count= (arg_count / 2);
+ enum enum_dyncol_func_result rc;
+ DBUG_ASSERT((arg_count & 0x1) == 0); // even number of arguments
+
+ prepare_arguments();
+
+ if ((rc= dynamic_column_create_many(&col, column_count, nums, vals)))
+ {
+ dynamic_column_error_message(rc);
+ dynamic_column_column_free(&col);
+ res= NULL;
+ null_value= TRUE;
+ }
+ else
+ {
+ /* Move result from DYNAMIC_COLUMN to str_value */
+ char *ptr;
+ size_t length, alloc_length;
+ dynamic_column_reassociate(&col, &ptr, &length, &alloc_length);
+ str_value.reassociate(ptr, (uint32) length, (uint32) alloc_length,
+ &my_charset_bin);
+ res= &str_value;
+ null_value= FALSE;
+ }
+
+ /* cleanup */
+ cleanup_arguments();
+
+ return res;
+}
+
+void Item_func_dyncol_create::print_arguments(String *str,
+ enum_query_type query_type)
+{
+ uint i;
+ uint column_count= (arg_count / 2);
+ for (i= 0; i < column_count; i++)
+ {
+ args[i*2]->print(str, query_type);
+ str->append(',');
+ args[i*2 + 1]->print(str, query_type);
+ switch (defs[i].type) {
+ case DYN_COL_NULL: // automatic type => write nothing
+ break;
+ case DYN_COL_INT:
+ str->append(STRING_WITH_LEN(" AS int"));
+ break;
+ case DYN_COL_UINT:
+ str->append(STRING_WITH_LEN(" AS unsigned int"));
+ break;
+ case DYN_COL_DOUBLE:
+ str->append(STRING_WITH_LEN(" AS double"));
+ break;
+ case DYN_COL_STRING:
+ str->append(STRING_WITH_LEN(" AS char"));
+ if (defs[i].cs)
+ {
+ str->append(STRING_WITH_LEN(" charset "));
+ str->append(defs[i].cs->csname);
+ str->append(' ');
+ }
+ break;
+ case DYN_COL_DECIMAL:
+ str->append(STRING_WITH_LEN(" AS decimal"));
+ break;
+ case DYN_COL_DATETIME:
+ str->append(STRING_WITH_LEN(" AS datetime"));
+ break;
+ case DYN_COL_DATE:
+ str->append(STRING_WITH_LEN(" AS date"));
+ break;
+ case DYN_COL_TIME:
+ str->append(STRING_WITH_LEN(" AS time"));
+ break;
+ }
+ if (i < column_count - 1)
+ str->append(',');
+ }
+}
+
+
+void Item_func_dyncol_create::print(String *str,
+ enum_query_type query_type)
+{
+ DBUG_ASSERT((arg_count & 0x1) == 0); // even number of arguments
+ str->append(STRING_WITH_LEN("column_create("));
+ print_arguments(str, query_type);
+ str->append(')');
+}
+
+
+String *Item_func_dyncol_add::val_str(String *str)
+{
+ DYNAMIC_COLUMN col;
+ String *res;
+ uint column_count= (arg_count / 2);
+ enum enum_dyncol_func_result rc;
+ DBUG_ASSERT((arg_count & 0x1) == 1); // odd number of arguments
+
+ /* We store the packed data last */
+ res= args[arg_count - 1]->val_str(str);
+ if (args[arg_count - 1]->null_value)
+ goto null;
+ init_dynamic_string(&col, NULL, res->length() + STRING_BUFFER_USUAL_SIZE,
+ STRING_BUFFER_USUAL_SIZE);
+
+ col.length= res->length();
+ memcpy(col.str, res->ptr(), col.length);
+
+ prepare_arguments();
+
+ if ((rc= dynamic_column_update_many(&col, column_count, nums, vals)))
+ {
+ dynamic_column_error_message(rc);
+ dynamic_column_column_free(&col);
+ cleanup_arguments();
+ goto null;
+ }
+
+ {
+ /* Move result from DYNAMIC_COLUMN to str */
+ char *ptr;
+ size_t length, alloc_length;
+ dynamic_column_reassociate(&col, &ptr, &length, &alloc_length);
+ str->reassociate(ptr, (uint32) length, (uint32) alloc_length,
+ &my_charset_bin);
+ null_value= FALSE;
+ }
+
+ /* cleanup */
+ dynamic_column_column_free(&col);
+ cleanup_arguments();
+
+ return str;
+
+null:
+ null_value= TRUE;
+ return NULL;
+}
+
+
+void Item_func_dyncol_add::print(String *str,
+ enum_query_type query_type)
+{
+ DBUG_ASSERT((arg_count & 0x1) == 1); // odd number of arguments
+ str->append(STRING_WITH_LEN("column_create("));
+ args[arg_count - 1]->print(str, query_type);
+ str->append(',');
+ print_arguments(str, query_type);
+ str->append(')');
+}
+
+
+/**
+ Get value for a column stored in a dynamic column
+
+ @notes
+ This function ensures that null_value is set correctly
+*/
+
+bool Item_dyncol_get::get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp)
+{
+ DYNAMIC_COLUMN dyn_str;
+ String *res;
+ longlong num;
+ enum enum_dyncol_func_result rc;
+
+ num= args[1]->val_int();
+ if (args[1]->null_value || num < 0 || num > INT_MAX)
+ {
+ null_value= 1;
+ return 1;
+ }
+
+ res= args[0]->val_str(tmp);
+ if (args[0]->null_value)
+ {
+ null_value= 1;
+ return 1;
+ }
+
+ dyn_str.str= (char*) res->ptr();
+ dyn_str.length= res->length();
+ if ((rc= dynamic_column_get(&dyn_str, (uint) num, val)))
+ {
+ dynamic_column_error_message(rc);
+ null_value= 1;
+ return 1;
+ }
+
+ null_value= 0;
+ return 0; // ok
+}
+
+
+String *Item_dyncol_get::val_str(String *str_result)
+{
+ DYNAMIC_COLUMN_VALUE val;
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String tmp(buff, sizeof(buff), &my_charset_bin);
+
+ if (get_dyn_value(&val, &tmp))
+ return NULL;
+
+ switch (val.type) {
+ case DYN_COL_NULL:
+ goto null;
+ case DYN_COL_INT:
+ case DYN_COL_UINT:
+ str_result->set_int(val.x.long_value, test(val.type == DYN_COL_UINT),
+ &my_charset_latin1);
+ break;
+ case DYN_COL_DOUBLE:
+ str_result->set_real(val.x.double_value, NOT_FIXED_DEC, &my_charset_latin1);
+ break;
+ case DYN_COL_STRING:
+ if ((char*) tmp.ptr() <= val.x.string.value.str &&
+ (char*) tmp.ptr() + tmp.length() >= val.x.string.value.str)
+ {
+ /* value is allocated in tmp buffer; We have to make a copy */
+ str_result->copy(val.x.string.value.str, val.x.string.value.length,
+ val.x.string.charset);
+ }
+ else
+ {
+ /*
+ It's safe to use the current value because it's either pointing
+ into a field or in a buffer for another item and this buffer
+ is not going to be deleted during expression evaluation
+ */
+ str_result->set(val.x.string.value.str, val.x.string.value.length,
+ val.x.string.charset);
+ }
+ break;
+ case DYN_COL_DECIMAL:
+ {
+ int res;
+ int length=
+ my_decimal_string_length((const my_decimal*)&val.x.decimal.value);
+ if (str_result->alloc(length))
+ goto null;
+ if ((res= decimal2string(&val.x.decimal.value, (char*) str_result->ptr(),
+ &length, 0, 0, ' ')) != E_DEC_OK)
+ {
+ char buff[40];
+ int len= sizeof(buff);
+ DBUG_ASSERT(length < (int)sizeof(buff));
+ decimal2string(&val.x.decimal.value, buff, &len, 0, 0, ' ');
+ decimal_operation_results(res, buff, "CHAR");
+ }
+ str_result->set_charset(&my_charset_latin1);
+ str_result->length(length);
+ break;
+ }
+ case DYN_COL_DATETIME:
+ case DYN_COL_DATE:
+ case DYN_COL_TIME:
+ {
+ int length;
+ /*
+ We use AUTO_SEC_PART_DIGITS here to ensure that we do not loose
+ any microseconds from the data. This is safe to do as we are
+ asked to return the time argument as a string.
+ */
+ if (str_result->alloc(MAX_DATE_STRING_REP_LENGTH) ||
+ !(length= my_TIME_to_str(&val.x.time_value, (char*) str_result->ptr(),
+ AUTO_SEC_PART_DIGITS)))
+ goto null;
+ str_result->set_charset(&my_charset_latin1);
+ str_result->length(length);
+ break;
+ }
+ }
+ return str_result;
+
+null:
+ null_value= TRUE;
+ return 0;
+}
+
+
+longlong Item_dyncol_get::val_int()
+{
+ DYNAMIC_COLUMN_VALUE val;
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String tmp(buff, sizeof(buff), &my_charset_bin);
+
+ if (get_dyn_value(&val, &tmp))
+ return 0;
+
+ switch (val.type) {
+ case DYN_COL_NULL:
+ goto null;
+ case DYN_COL_UINT:
+ unsigned_flag= 1; // Make it possible for caller to detect sign
+ return val.x.long_value;
+ case DYN_COL_INT:
+ unsigned_flag= 0; // Make it possible for caller to detect sign
+ return val.x.long_value;
+ case DYN_COL_DOUBLE:
+ {
+ bool error;
+ longlong num;
+
+ num= double_to_longlong(val.x.double_value, unsigned_flag, &error);
+ if (error)
+ {
+ char buff[30];
+ sprintf(buff, "%lg", val.x.double_value);
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_DATA_OVERFLOW,
+ ER(ER_DATA_OVERFLOW),
+ buff,
+ unsigned_flag ? "UNSIGNED INT" : "INT");
+ }
+ return num;
+ }
+ case DYN_COL_STRING:
+ {
+ int error;
+ longlong num;
+ char *end= val.x.string.value.str + val.x.string.value.length, *org_end= end;
+
+ num= my_strtoll10(val.x.string.value.str, &end, &error);
+ if (end != org_end || error > 0)
+ {
+ char buff[80];
+ strmake(buff, val.x.string.value.str, min(sizeof(buff)-1,
+ val.x.string.value.length));
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_BAD_DATA,
+ ER(ER_BAD_DATA),
+ buff,
+ unsigned_flag ? "UNSIGNED INT" : "INT");
+ }
+ unsigned_flag= error >= 0;
+ return num;
+ }
+ case DYN_COL_DECIMAL:
+ {
+ longlong num;
+ my_decimal2int(E_DEC_FATAL_ERROR, &val.x.decimal.value, unsigned_flag,
+ &num);
+ return num;
+ }
+ case DYN_COL_DATETIME:
+ case DYN_COL_DATE:
+ case DYN_COL_TIME:
+ unsigned_flag= !val.x.time_value.neg;
+ if (unsigned_flag)
+ return TIME_to_ulonglong(&val.x.time_value);
+ else
+ return -(longlong)TIME_to_ulonglong(&val.x.time_value);
+ }
+
+null:
+ null_value= TRUE;
+ return 0;
+}
+
+
+double Item_dyncol_get::val_real()
+{
+ DYNAMIC_COLUMN_VALUE val;
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String tmp(buff, sizeof(buff), &my_charset_bin);
+
+ if (get_dyn_value(&val, &tmp))
+ return 0.0;
+
+ switch (val.type) {
+ case DYN_COL_NULL:
+ goto null;
+ case DYN_COL_UINT:
+ return ulonglong2double(val.x.ulong_value);
+ case DYN_COL_INT:
+ return (double) val.x.long_value;
+ case DYN_COL_DOUBLE:
+ return (double) val.x.double_value;
+ case DYN_COL_STRING:
+ {
+ int error;
+ char *end;
+ double res= my_strntod(val.x.string.charset, (char*) val.x.string.value.str,
+ val.x.string.value.length, &end, &error);
+
+ if (end != (char*) val.x.string.value.str + val.x.string.value.length ||
+ error)
+ {
+ char buff[80];
+ strmake(buff, val.x.string.value.str, min(sizeof(buff)-1,
+ val.x.string.value.length));
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_BAD_DATA,
+ ER(ER_BAD_DATA),
+ buff, "DOUBLE");
+ }
+ return res;
+ }
+ case DYN_COL_DECIMAL:
+ {
+ double res;
+ /* This will always succeed */
+ decimal2double(&val.x.decimal.value, &res);
+ return res;
+ }
+ case DYN_COL_DATETIME:
+ case DYN_COL_DATE:
+ case DYN_COL_TIME:
+ return TIME_to_double(&val.x.time_value);
+ }
+
+null:
+ null_value= TRUE;
+ return 0.0;
+}
+
+
+my_decimal *Item_dyncol_get::val_decimal(my_decimal *decimal_value)
+{
+ DYNAMIC_COLUMN_VALUE val;
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String tmp(buff, sizeof(buff), &my_charset_bin);
+
+ if (get_dyn_value(&val, &tmp))
+ return NULL;
+
+ switch (val.type) {
+ case DYN_COL_NULL:
+ goto null;
+ case DYN_COL_UINT:
+ int2my_decimal(E_DEC_FATAL_ERROR, val.x.long_value, TRUE, decimal_value);
+ break;
+ case DYN_COL_INT:
+ int2my_decimal(E_DEC_FATAL_ERROR, val.x.long_value, FALSE, decimal_value);
+ break;
+ case DYN_COL_DOUBLE:
+ double2my_decimal(E_DEC_FATAL_ERROR, val.x.double_value, decimal_value);
+ break;
+ case DYN_COL_STRING:
+ {
+ int rc;
+ rc= str2my_decimal(0, val.x.string.value.str, val.x.string.value.length,
+ val.x.string.charset, decimal_value);
+ char buff[80];
+ strmake(buff, val.x.string.value.str, min(sizeof(buff)-1,
+ val.x.string.value.length));
+ if (rc != E_DEC_OK)
+ {
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_BAD_DATA,
+ ER(ER_BAD_DATA),
+ buff, "DECIMAL");
+ }
+ break;
+ }
+ case DYN_COL_DECIMAL:
+ decimal2my_decimal(&val.x.decimal.value, decimal_value);
+ break;
+ case DYN_COL_DATETIME:
+ case DYN_COL_DATE:
+ case DYN_COL_TIME:
+ decimal_value= seconds2my_decimal(val.x.time_value.neg,
+ TIME_to_ulonglong(&val.x.time_value),
+ val.x.time_value.second_part,
+ decimal_value);
+ break;
+ }
+ return decimal_value;
+
+null:
+ null_value= TRUE;
+ return 0;
+}
+
+
+bool Item_dyncol_get::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
+{
+ DYNAMIC_COLUMN_VALUE val;
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String tmp(buff, sizeof(buff), &my_charset_bin);
+ bool signed_value= 0;
+
+ if (get_dyn_value(&val, &tmp))
+ return 1; // Error
+
+ switch (val.type) {
+ case DYN_COL_NULL:
+ goto null;
+ case DYN_COL_INT:
+ signed_value= 1; // For error message
+ /* fall_trough */
+ case DYN_COL_UINT:
+ if (signed_value || val.x.ulong_value <= LONGLONG_MAX)
+ {
+ if (int_to_datetime_with_warn(val.x.ulong_value, ltime, fuzzy_date,
+ 0 /* TODO */))
+ goto null;
+ return 0;
+ }
+ /* let double_to_datetime_with_warn() issue the warning message */
+ val.x.double_value= static_cast<double>(ULONGLONG_MAX);
+ /* fall_trough */
+ case DYN_COL_DOUBLE:
+ if (double_to_datetime_with_warn(val.x.double_value, ltime, fuzzy_date,
+ 0 /* TODO */))
+ goto null;
+ return 0;
+ case DYN_COL_DECIMAL:
+ if (decimal_to_datetime_with_warn((my_decimal*)&val.x.decimal.value, ltime,
+ fuzzy_date, 0 /* TODO */))
+ goto null;
+ return 0;
+ case DYN_COL_STRING:
+ if (str_to_datetime_with_warn(val.x.string.value.str,
+ val.x.string.value.length,
+ ltime, fuzzy_date) <= MYSQL_TIMESTAMP_ERROR)
+ goto null;
+ return 0;
+ case DYN_COL_DATETIME:
+ case DYN_COL_DATE:
+ case DYN_COL_TIME:
+ *ltime= val.x.time_value;
+ return 0;
+ }
+
+null:
+ null_value= TRUE;
+ return 1;
+}
+
+
+void Item_dyncol_get::print(String *str, enum_query_type query_type)
+{
+ str->append(STRING_WITH_LEN("column_get("));
+ args[0]->print(str, query_type);
+ str->append(',');
+ args[1]->print(str, query_type);
+ str->append(')');
+}
+
+
+String *Item_func_dyncol_list::val_str(String *str)
+{
+ uint i;
+ enum enum_dyncol_func_result rc;
+ DYNAMIC_ARRAY arr;
+ DYNAMIC_COLUMN col;
+ String *res= args[0]->val_str(str);
+
+ if (args[0]->null_value)
+ goto null;
+ col.length= res->length();
+ /* We do not change the string, so could do this trick */
+ col.str= (char *)res->ptr();
+ if ((rc= dynamic_column_list(&col, &arr)))
+ {
+ dynamic_column_error_message(rc);
+ delete_dynamic(&arr);
+ goto null;
+ }
+
+ /*
+ We support elements from 0 - 65536, so max size for one element is
+ 6 (including ,).
+ */
+ if (str->alloc(arr.elements * 6))
+ goto null;
+
+ str->length(0);
+ for (i= 0; i < arr.elements; i++)
+ {
+ str->qs_append(*dynamic_element(&arr, i, uint*));
+ if (i < arr.elements - 1)
+ str->qs_append(',');
+ }
+
+ null_value= FALSE;
+ delete_dynamic(&arr);
+ return str;
+
+null:
+ null_value= TRUE;
+ return NULL;
+}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index b731c13a871..e3b040a2e55 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -319,7 +319,7 @@ public:
String *val_str(String *);
void fix_length_and_dec()
{
- maybe_null=1;
+ set_persist_maybe_null(1);
/* 9 = MAX ((8- (arg_len % 8)) + 1) */
max_length = args[0]->max_length + 9;
}
@@ -335,7 +335,7 @@ public:
String *val_str(String *);
void fix_length_and_dec()
{
- maybe_null=1;
+ set_persist_maybe_null(1);
/* 9 = MAX ((8- (arg_len % 8)) + 1) */
max_length = args[0]->max_length - 9;
}
@@ -361,7 +361,7 @@ public:
constructor_helper();
}
String *val_str(String *);
- void fix_length_and_dec() { maybe_null=1; max_length = 13; }
+ void fix_length_and_dec() { set_persist_maybe_null(1); max_length = 13; }
const char *func_name() const { return "encrypt"; }
bool check_vcol_func_processor(uchar *int_arg)
{
@@ -431,7 +431,7 @@ public:
void fix_length_and_dec()
{
max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
const char *func_name() const { return "database"; }
const char *fully_qualified_func_name() const { return "database()"; }
@@ -607,7 +607,7 @@ public:
{
collation.set(default_charset());
max_length=64;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
};
@@ -634,7 +634,7 @@ public:
Item_func_unhex(Item *a) :Item_str_func(a)
{
/* there can be bad hex strings */
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
const char *func_name() const { return "unhex"; }
String *val_str(String *);
@@ -680,7 +680,7 @@ public:
void fix_length_and_dec()
{
collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
- maybe_null=1;
+ set_persist_maybe_null(1);
max_length=MAX_BLOB_WIDTH;
}
bool check_vcol_func_processor(uchar *int_arg)
@@ -713,7 +713,7 @@ public:
{
decimals= 0;
max_length= 3 * 8 + 7;
- maybe_null= 1;
+ set_persist_maybe_null(1);
}
};
@@ -747,7 +747,7 @@ public:
{
DBUG_ASSERT(args[0]->fixed);
conv_charset= cs;
- if (cache_if_const && args[0]->const_item())
+ if (cache_if_const && args[0]->const_item() && !args[0]->with_subselect)
{
uint errors= 0;
String tmp, *str= args[0]->val_str(&tmp);
@@ -804,7 +804,7 @@ public:
{
collation.set(system_charset_info);
max_length= 64 * collation.collation->mbmaxlen; // should be enough
- maybe_null= 0;
+ set_persist_maybe_null(0);
};
table_map not_null_tables() const { return 0; }
};
@@ -819,7 +819,7 @@ public:
{
collation.set(system_charset_info);
max_length= 64 * collation.collation->mbmaxlen; // should be enough
- maybe_null= 0;
+ set_persist_maybe_null(0);
};
table_map not_null_tables() const { return 0; }
};
@@ -865,7 +865,8 @@ class Item_func_uncompress: public Item_str_func
String buffer;
public:
Item_func_uncompress(Item *a): Item_str_func(a){}
- void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; }
+ void fix_length_and_dec()
+ { set_persist_maybe_null(1); max_length= MAX_BLOB_WIDTH; }
const char *func_name() const{return "uncompress";}
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
};
@@ -892,3 +893,72 @@ public:
}
};
+
+class Item_func_dyncol_create: public Item_str_func
+{
+protected:
+ DYNCALL_CREATE_DEF *defs;
+ DYNAMIC_COLUMN_VALUE *vals;
+ uint *nums;
+ void prepare_arguments();
+ void cleanup_arguments();
+ void print_arguments(String *str, enum_query_type query_type);
+public:
+ Item_func_dyncol_create(List<Item> &args, DYNCALL_CREATE_DEF *dfs);
+ bool fix_fields(THD *thd, Item **ref);
+ void fix_length_and_dec();
+ const char *func_name() const{ return "column_create"; }
+ String *val_str(String *);
+ virtual void print(String *str, enum_query_type query_type);
+};
+
+
+class Item_func_dyncol_add: public Item_func_dyncol_create
+{
+public:
+ Item_func_dyncol_add(List<Item> &args, DYNCALL_CREATE_DEF *dfs)
+ :Item_func_dyncol_create(args, dfs)
+ {}
+ const char *func_name() const{ return "column_add"; }
+ String *val_str(String *);
+ virtual void print(String *str, enum_query_type query_type);
+};
+
+
+/*
+ The following functions is always called from an Item_cast function
+*/
+
+class Item_dyncol_get: public Item_str_func
+{
+public:
+ Item_dyncol_get(Item *str, Item *num)
+ :Item_str_func(str, num)
+ {
+ max_length= MAX_DYNAMIC_COLUMN_LENGTH;
+ }
+ void fix_length_and_dec()
+ { set_persist_maybe_null(1); }
+ /* Mark that collation can change between calls */
+ bool dynamic_result() { return 1; }
+
+ const char *func_name() const { return "column_get"; }
+ String *val_str(String *);
+ longlong val_int();
+ double val_real();
+ my_decimal *val_decimal(my_decimal *);
+ bool get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp);
+ bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
+ void print(String *str, enum_query_type query_type);
+};
+
+
+class Item_func_dyncol_list: public Item_str_func
+{
+public:
+ Item_func_dyncol_list(Item *str) :Item_str_func(str) {};
+ void fix_length_and_dec()
+ { set_persist_maybe_null(1); max_length= MAX_BLOB_WIDTH; };
+ const char *func_name() const{ return "column_list"; }
+ String *val_str(String *);
+};
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 55db3c6136f..a91efaec51f 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -31,29 +31,34 @@
#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);
-}
+double get_post_group_estimate(JOIN* join, double join_op_rows);
+
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),
+ Item_result_field(), value_assigned(0), own_engine(0), thd(0), old_engine(0),
+ used_tables_cache(0), have_to_be_excluded(0), const_item_cache(1),
+ inside_first_fix_fields(0), done_first_fix_fields(FALSE),
+ expr_cache(0), forced_const(FALSE), substitution(0), engine(0), eliminated(FALSE),
engine_changed(0), changed(0), is_correlated(FALSE)
{
+ DBUG_ENTER("Item_subselect::Item_subselect");
+ DBUG_PRINT("enter", ("this: 0x%lx", (ulong) this));
+#ifndef DBUG_OFF
+ exec_counter= 0;
+#endif
with_subselect= 1;
reset();
/*
- 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;
+ DBUG_VOID_RETURN;
}
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(),
@@ -61,8 +66,10 @@ void Item_subselect::init(st_select_lex *select_lex,
*/
DBUG_ENTER("Item_subselect::init");
- DBUG_PRINT("enter", ("select_lex: 0x%lx", (long) select_lex));
+ DBUG_PRINT("enter", ("select_lex: 0x%lx this: 0x%lx",
+ (ulong) select_lex, (ulong) this));
unit= select_lex->master_unit();
+ thd= unit->thd;
if (unit->item)
{
@@ -71,10 +78,10 @@ void Item_subselect::init(st_select_lex *select_lex,
=> we do not copy old_engine here
*/
engine= unit->item->engine;
+ own_engine= FALSE;
parsing_place= unit->item->parsing_place;
- unit->item->engine= 0;
- unit->item= this;
- engine->change_result(this, result);
+ thd->change_item_tree((Item**)&unit->item, this);
+ engine->change_result(this, result, TRUE);
}
else
{
@@ -87,15 +94,18 @@ 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_PRINT("info", ("engine: 0x%lx", (ulong)engine));
DBUG_VOID_RETURN;
}
@@ -120,6 +130,12 @@ void Item_subselect::cleanup()
engine->cleanup();
reset();
value_assigned= 0;
+ expr_cache= 0;
+ forced_const= FALSE;
+ DBUG_PRINT("info", ("exec_counter: %d", exec_counter));
+#ifndef DBUG_OFF
+ exec_counter= 0;
+#endif
DBUG_VOID_RETURN;
}
@@ -132,16 +148,59 @@ 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;
+ }
+ /*
+ TODO: This breaks the commented assert in add_strategy().
+ in_strategy&= ~SUBS_STRATEGY_CHOSEN;
+ */
+ first_execution= TRUE;
+ pushed_cond_guards= NULL;
+ Item_subselect::cleanup();
+ DBUG_VOID_RETURN;
+}
+
+
+void Item_allany_subselect::cleanup()
+{
+ /*
+ The MAX/MIN transformation through injection is reverted through the
+ change_item_tree() mechanism. Revert the select_lex object of the
+ query to its initial state.
+ */
+ for (SELECT_LEX *sl= unit->first_select();
+ sl; sl= sl->next_select())
+ if (test_set_strategy(SUBS_MAXMIN_INJECTED))
+ sl->with_sum_func= false;
+ Item_in_subselect::cleanup();
+}
+
+
Item_subselect::~Item_subselect()
{
- delete engine;
+ DBUG_ENTER("Item_subselect::~Item_subselect");
+ DBUG_PRINT("enter", ("this: 0x%lx", (ulong) this));
+ if (own_engine)
+ delete engine;
+ else
+ engine->cleanup();
+ engine= NULL;
+ DBUG_VOID_RETURN;
}
-Item_subselect::trans_res
+bool
Item_subselect::select_transformer(JOIN *join)
{
DBUG_ENTER("Item_subselect::select_transformer");
- DBUG_RETURN(RES_OK);
+ DBUG_RETURN(false);
}
@@ -153,27 +212,46 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
DBUG_ASSERT(fixed == 0);
engine->set_thd((thd= thd_param));
- if (!in_fix_fields)
- refers_to.empty();
+ 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;
+ /*
+ 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
+ /*
+ If the top item of the WHERE/HAVING condition changed,
+ set correct WHERE/HAVING for PS.
+ */
if (unit->outer_select()->where == (*ref))
- unit->outer_select()->where= substitution; // correct WHERE for PS
+ unit->outer_select()->where= substitution;
else if (unit->outer_select()->having == (*ref))
- unit->outer_select()->having= substitution; // correct HAVING for PS
+ unit->outer_select()->having= substitution;
(*ref)= substitution;
substitution->name= name;
@@ -185,12 +263,13 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
if (!(*ref)->fixed)
res= (*ref)->fix_fields(thd, ref);
goto end;
+
}
// Is it one field subselect?
if (engine->cols() > max_columns)
{
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
- res= 1;
+
goto end;
}
fix_length_and_dec();
@@ -207,7 +286,8 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
fixed= 1;
end:
- in_fix_fields--;
+ done_first_fix_fields= FALSE;
+ inside_first_fix_fields= FALSE;
thd->where= save_where;
return res;
}
@@ -215,11 +295,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;
@@ -231,9 +312,224 @@ bool Item_subselect::mark_as_eliminated_processor(uchar *arg)
return FALSE;
}
+
+/**
+ Remove a subselect item from its unit so that the unit no longer
+ represents a subquery.
+
+ @param arg unused parameter
+
+ @return
+ FALSE to force the evaluation of the processor for the subsequent items.
+*/
+
+bool Item_subselect::eliminate_subselect_processor(uchar *arg)
+{
+ unit->item= NULL;
+ unit->exclude_from_tree();
+ eliminated= TRUE;
+ return FALSE;
+}
+
+
+/**
+ Adjust the master select of the subquery to be the fake_select which
+ represents the whole UNION right above the subquery, instead of the
+ last query of the UNION.
+
+ @param arg pointer to the fake select
+
+ @return
+ FALSE to force the evaluation of the processor for the subsequent items.
+*/
+
+bool Item_subselect::set_fake_select_as_master_processor(uchar *arg)
+{
+ SELECT_LEX *fake_select= (SELECT_LEX*) arg;
+ /*
+ Move the st_select_lex_unit of a subquery from a global ORDER BY clause to
+ become a direct child of the fake_select of a UNION. In this way the
+ ORDER BY that is applied to the temporary table that contains the result of
+ the whole UNION, and all columns in the subquery are resolved against this
+ table. The transformation is applied only for immediate child subqueries of
+ a UNION query.
+ */
+ if (unit->outer_select()->master_unit()->fake_select_lex == fake_select)
+ {
+ /*
+ Set the master of the subquery to be the fake select (i.e. the whole
+ UNION), instead of the last query in the UNION.
+ */
+ fake_select->add_slave(unit);
+ DBUG_ASSERT(unit->outer_select() == fake_select);
+ /* Adjust the name resolution context hierarchy accordingly. */
+ for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
+ sl->context.outer_context= &(fake_select->context);
+ /*
+ Undo Item_subselect::eliminate_subselect_processor because at that phase
+ we don't know yet that the ORDER clause will be moved to the fake select.
+ */
+ unit->item= this;
+ eliminated= FALSE;
+ }
+ 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;
+ upper->item->walk(&Item::update_table_bitmaps_processor, FALSE, NULL);
+/*
+ if (after_pullout)
+ upper->item->fix_after_pullout(new_parent, &(upper->item));
+ upper->item->update_used_tables();
+*/
+ }
+ }
+ }
+ 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)
{
+ if (!(unit->uncacheable & ~UNCACHEABLE_DEPENDENT) && engine->is_executed() &&
+ !unit->describe)
+ {
+ /*
+ The subquery has already been executed (for real, it wasn't EXPLAIN's
+ fake execution) so it should not matter what it has inside.
+
+ The actual reason for not walking inside is that parts of the subquery
+ (e.g. JTBM join nests and their IN-equality conditions may have been
+ invalidated by irreversible cleanups (those happen after an uncorrelated
+ subquery has been executed).
+ */
+ return (this->*processor)(argument);
+ }
if (walk_subquery)
{
@@ -290,7 +586,9 @@ bool Item_subselect::exec()
DBUG_EXECUTE_IF("subselect_exec_fail", return 1;);
res= engine->exec();
-
+#ifndef DBUG_OFF
+ ++exec_counter;
+#endif
if (engine_changed)
{
engine_changed= 0;
@@ -299,6 +597,166 @@ bool Item_subselect::exec()
return (res);
}
+
+void Item_subselect::get_cache_parameters(List<Item> &parameters)
+{
+ Collect_deps_prm prm= {&parameters,
+ unit->first_select()->nest_level_base,
+ unit->first_select()->nest_level};
+ walk(&Item::collect_outer_ref_processor, TRUE, (uchar*)&prm);
+}
+
+int Item_in_subselect::optimize(double *out_rows, double *cost)
+{
+ int res;
+ DBUG_ENTER("Item_in_subselect::optimize");
+ SELECT_LEX *save_select= thd->lex->current_select;
+ JOIN *join= unit->first_select()->join;
+
+ thd->lex->current_select= join->select_lex;
+ if ((res= join->optimize()))
+ DBUG_RETURN(res);
+
+ /* Calculate #rows and cost of join execution */
+ join->get_partial_cost_and_fanout(join->table_count - join->const_tables,
+ table_map(-1),
+ cost, out_rows);
+
+ /*
+ Adjust join output cardinality. There can be these cases:
+ - Have no GROUP BY and no aggregate funcs: we won't get into this
+ function because such join will be processed as a merged semi-join
+ (TODO: does it really mean we don't need to handle such cases here at
+ all? put ASSERT)
+ - Have no GROUP BY but have aggregate funcs: output is 1 record.
+ - Have GROUP BY and have (or not) aggregate funcs: need to adjust output
+ cardinality.
+ */
+ thd->lex->current_select= save_select;
+ if (!join->group_list && !join->group_optimized_away &&
+ join->tmp_table_param.sum_func_count)
+ {
+ DBUG_PRINT("info",("Materialized join will have only 1 row (it has "
+ "aggregates but no GROUP BY"));
+ *out_rows= 1;
+ }
+
+ /* Now with grouping */
+ if (join->group_list)
+ {
+ DBUG_PRINT("info",("Materialized join has grouping, trying to estimate it"));
+ double output_rows= get_post_group_estimate(join, *out_rows);
+ DBUG_PRINT("info",("Got value of %g", output_rows));
+ *out_rows= output_rows;
+ }
+
+ DBUG_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 ((engine->uncacheable() & UNCACHEABLE_DEPENDENT) &&
+ engine->cols() == 1 &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_SUBQUERY_CACHE) &&
+ !(engine->uncacheable() & (UNCACHEABLE_RAND |
+ UNCACHEABLE_SIDEEFFECT)));
+}
+
+
+/**
+ Check if the left IN argument contains NULL values.
+
+ @retval TRUE there are NULLs
+ @retval FALSE otherwise
+*/
+
+inline bool Item_in_subselect::left_expr_has_null()
+{
+ return (*(optimizer->get_cache()))->null_value;
+}
+
+
+/**
+ 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 (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 && (test_strategy(SUBS_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;
@@ -313,13 +771,16 @@ void Item_subselect::fix_length_and_dec()
table_map Item_subselect::used_tables() const
{
- return (table_map) (engine->uncacheable() ? used_tables_cache : 0L);
+ return (table_map) ((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN)?
+ used_tables_cache : 0L);
}
bool Item_subselect::const_item() const
{
- return thd->lex->context_analysis_only ? FALSE : const_item_cache;
+ return (thd->lex->context_analysis_only ?
+ FALSE :
+ forced_const || const_item_cache);
}
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
@@ -331,11 +792,15 @@ Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
void Item_subselect::update_used_tables()
{
- if (!engine->uncacheable())
+ if (!forced_const)
{
- // did all used tables become static?
- if (!(used_tables_cache & ~engine->upper_select_const_tables()))
- const_item_cache= 1;
+ recalc_used_tables(parent_select, FALSE);
+ if (!engine->uncacheable())
+ {
+ // did all used tables become static?
+ if (!(used_tables_cache & ~engine->upper_select_const_tables()))
+ const_item_cache= 1;
+ }
}
}
@@ -404,7 +869,7 @@ Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
of Items belonged to subquery, which will be not repeated
*/
used_tables_cache= parent->get_used_tables_cache();
- const_item_cache= parent->get_const_item_cache();
+ const_item_cache= parent->const_item();
/*
this subquery always creates during preparation, so we can assign
@@ -440,12 +905,49 @@ void Item_maxmin_subselect::print(String *str, enum_query_type query_type)
}
+void Item_maxmin_subselect::no_rows_in_result()
+{
+ /*
+ Subquery predicates outside of the SELECT list must be evaluated in order
+ to possibly filter the special result row generated for implicit grouping
+ if the subquery is in the HAVING clause.
+ If the predicate is constant, we need its actual value in the only result
+ row for queries with implicit grouping.
+ */
+ if (parsing_place != SELECT_LIST || const_item())
+ return;
+ value= Item_cache::get_cache(new Item_null());
+ null_value= 0;
+ was_values= 0;
+ make_const();
+}
+
+
+void Item_singlerow_subselect::no_rows_in_result()
+{
+ /*
+ Subquery predicates outside of the SELECT list must be evaluated in order
+ to possibly filter the special result row generated for implicit grouping
+ if the subquery is in the HAVING clause.
+ If the predicate is constant, we need its actual value in the only result
+ row for queries with implicit grouping.
+ */
+ if (parsing_place != SELECT_LIST || const_item())
+ return;
+ value= Item_cache::get_cache(new Item_null());
+ reset();
+ make_const();
+}
+
+
void Item_singlerow_subselect::reset()
{
- eliminated= FALSE;
- null_value= TRUE;
+ Item_subselect::reset();
if (value)
- value->null_value= TRUE;
+ {
+ for(uint i= 0; i < engine->cols(); i++)
+ row[i]->set_null();
+ }
}
@@ -458,12 +960,17 @@ void Item_singlerow_subselect::reset()
- switch off this optimization for prepare statement,
because we do not rollback this changes.
Make rollback for it, or special name resolving mode in 5.0.
+
+ @param join Join object of the subquery (i.e. 'child' join).
+
+ @retval false The subquery was transformed
*/
-Item_subselect::trans_res
+bool
Item_singlerow_subselect::select_transformer(JOIN *join)
{
+ DBUG_ENTER("Item_singlerow_subselect::select_transformer");
if (changed)
- return RES_OK;
+ DBUG_RETURN(false);
SELECT_LEX *select_lex= join->select_lex;
Query_arena *arena= thd->stmt_arena;
@@ -490,7 +997,6 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
!arena->is_stmt_prepare_or_first_sp_execute()
)
{
-
have_to_be_excluded= 1;
if (thd->lex->describe)
{
@@ -501,14 +1007,11 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
}
substitution= select_lex->item_list.head();
/*
- as far as we moved content to upper level, field which depend of
- 'upper' select is not really dependent => we remove this dependence
+ as far as we moved content to upper level we have to fix dependences & Co
*/
- substitution->walk(&Item::remove_dependence_processor, 0,
- (uchar *) select_lex->outer_select());
- return RES_REDUCE;
+ substitution->fix_after_pullout(select_lex->outer_select(), &substitution);
}
- return RES_OK;
+ DBUG_RETURN(false);
}
@@ -553,8 +1056,47 @@ void Item_singlerow_subselect::fix_length_and_dec()
*/
if (engine->no_tables())
maybe_null= engine->may_be_null();
+ else
+ {
+ for (uint i= 0; i < max_columns; i++)
+ row[i]->maybe_null= TRUE;
+ }
+}
+
+
+/**
+ 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)))
+ DBUG_RETURN(expr_cache);
+ DBUG_RETURN(this);
}
+
uint Item_singlerow_subselect::cols()
{
return engine->cols();
@@ -591,6 +1133,8 @@ void Item_singlerow_subselect::bring_value()
double Item_singlerow_subselect::val_real()
{
DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value->val_real();
if (!exec() && !value->null_value)
{
null_value= FALSE;
@@ -606,6 +1150,8 @@ double Item_singlerow_subselect::val_real()
longlong Item_singlerow_subselect::val_int()
{
DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value->val_int();
if (!exec() && !value->null_value)
{
null_value= FALSE;
@@ -620,6 +1166,9 @@ longlong Item_singlerow_subselect::val_int()
String *Item_singlerow_subselect::val_str(String *str)
{
+ DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value->val_str(str);
if (!exec() && !value->null_value)
{
null_value= FALSE;
@@ -635,6 +1184,9 @@ String *Item_singlerow_subselect::val_str(String *str)
my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
{
+ DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value->val_decimal(decimal_value);
if (!exec() && !value->null_value)
{
null_value= FALSE;
@@ -650,6 +1202,9 @@ my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
bool Item_singlerow_subselect::val_bool()
{
+ DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value->val_bool();
if (!exec() && !value->null_value)
{
null_value= FALSE;
@@ -663,6 +1218,24 @@ bool Item_singlerow_subselect::val_bool()
}
+bool Item_singlerow_subselect::get_date(MYSQL_TIME *ltime,uint fuzzydate)
+{
+ DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value->get_date(ltime, fuzzydate);
+ if (!exec() && !value->null_value)
+ {
+ null_value= FALSE;
+ return value->get_date(ltime, fuzzydate);
+ }
+ else
+ {
+ reset();
+ return 1;
+ }
+}
+
+
Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
Item_subselect()
{
@@ -701,11 +1274,17 @@ 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), in_strategy(SUBS_NOT_TRANSFORMED),
+ optimizer(0), pushed_cond_guards(NULL), emb_on_expr_nest(NULL),
+ is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE),
+ is_flattenable_semijoin(FALSE),
+ is_registered_semijoin(FALSE),
+ upper_item(0)
{
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
left_expr= left_exp;
+ func= &eq_creator;
init(select_lex, new select_exists_subselect(this));
max_columns= UINT_MAX;
maybe_null= 1;
@@ -716,13 +1295,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));
@@ -735,19 +1319,99 @@ Item_allany_subselect::Item_allany_subselect(Item * left_exp,
}
+/**
+ Initialize length and decimals for EXISTS and inherited (IN/ALL/ANY)
+ subqueries
+*/
+
+void Item_exists_subselect::init_length_and_dec()
+{
+ decimals= 0;
+ max_length= 1;
+ max_columns= engine->cols();
+}
+
+
void Item_exists_subselect::fix_length_and_dec()
{
- decimals= 0;
- max_length= 1;
- max_columns= engine->cols();
- /* We need only 1 row to determine existence */
- unit->global_parameters->select_limit= new Item_int((int32) 1);
+ DBUG_ENTER("Item_exists_subselect::fix_length_and_dec");
+ init_length_and_dec();
+ /*
+ We need only 1 row to determine existence (i.e. any EXISTS that is not
+ an IN always requires LIMIT 1)
+ */
+ thd->change_item_tree(&unit->global_parameters->select_limit,
+ new Item_int((int32) 1));
+ DBUG_PRINT("info", ("Set limit to 1"));
+ DBUG_VOID_RETURN;
+}
+
+
+void Item_in_subselect::fix_length_and_dec()
+{
+ DBUG_ENTER("Item_in_subselect::fix_length_and_dec");
+ init_length_and_dec();
+ /*
+ Unlike Item_exists_subselect, LIMIT 1 is set later for
+ Item_in_subselect, depending on the chosen strategy.
+ */
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ 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)))
+ DBUG_RETURN(expr_cache);
+ DBUG_RETURN(this);
+}
+
+
+void Item_exists_subselect::no_rows_in_result()
+{
+ /*
+ Subquery predicates outside of the SELECT list must be evaluated in order
+ to possibly filter the special result row generated for implicit grouping
+ if the subquery is in the HAVING clause.
+ If the predicate is constant, we need its actual value in the only result
+ row for queries with implicit grouping.
+ */
+ if (parsing_place != SELECT_LIST || const_item())
+ return;
+ value= 0;
+ null_value= 0;
+ make_const();
}
double Item_exists_subselect::val_real()
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (!forced_const && exec())
{
reset();
return 0;
@@ -758,7 +1422,7 @@ double Item_exists_subselect::val_real()
longlong Item_exists_subselect::val_int()
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (!forced_const && exec())
{
reset();
return 0;
@@ -783,7 +1447,7 @@ longlong Item_exists_subselect::val_int()
String *Item_exists_subselect::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (!forced_const && exec())
reset();
str->set((ulonglong)value,&my_charset_bin);
return str;
@@ -806,7 +1470,7 @@ String *Item_exists_subselect::val_str(String *str)
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (!forced_const && exec())
reset();
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
return decimal_value;
@@ -816,7 +1480,7 @@ my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
bool Item_exists_subselect::val_bool()
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (!forced_const && exec())
{
reset();
return 0;
@@ -833,6 +1497,10 @@ double Item_in_subselect::val_real()
*/
DBUG_ASSERT(0);
DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value;
+ DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
+ ! engine->is_executed());
null_value= was_null= FALSE;
if (exec())
{
@@ -853,6 +1521,10 @@ longlong Item_in_subselect::val_int()
*/
DBUG_ASSERT(0);
DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value;
+ DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
+ ! engine->is_executed());
null_value= was_null= FALSE;
if (exec())
{
@@ -873,6 +1545,10 @@ String *Item_in_subselect::val_str(String *str)
*/
DBUG_ASSERT(0);
DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ goto value_is_ready;
+ DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
+ ! engine->is_executed());
null_value= was_null= FALSE;
if (exec())
{
@@ -884,6 +1560,7 @@ String *Item_in_subselect::val_str(String *str)
null_value= TRUE;
return 0;
}
+value_is_ready:
str->set((ulonglong)value, &my_charset_bin);
return str;
}
@@ -892,6 +1569,10 @@ String *Item_in_subselect::val_str(String *str)
bool Item_in_subselect::val_bool()
{
DBUG_ASSERT(fixed == 1);
+ if (forced_const)
+ return value;
+ DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
+ ! engine->is_executed());
null_value= was_null= FALSE;
if (exec())
{
@@ -910,6 +1591,10 @@ my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
method should not be used
*/
DBUG_ASSERT(0);
+ if (forced_const)
+ goto value_is_ready;
+ DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
+ ! engine->is_executed());
null_value= was_null= FALSE;
DBUG_ASSERT(fixed == 1);
if (exec())
@@ -919,64 +1604,33 @@ my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
}
if (was_null && !value)
null_value= TRUE;
+value_is_ready:
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
return decimal_value;
}
-/*
- Rewrite a single-column IN/ALL/ANY subselect
-
- SYNOPSIS
- Item_in_subselect::single_value_transformer()
- join Join object of the subquery (i.e. 'child' join).
- func Subquery comparison creator
-
- DESCRIPTION
- Rewrite a single-column subquery using rule-based approach. The subquery
-
- oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
-
- First, try to convert the subquery to scalar-result subquery in one of
- the forms:
-
- - oe $cmp$ (SELECT MAX(...) ) // handled by Item_singlerow_subselect
- - oe $cmp$ <max>(SELECT ...) // handled by Item_maxmin_subselect
-
- If that fails, the subquery will be handled with class Item_in_optimizer,
- Inject the predicates into subquery, i.e. convert it to:
-
- - If the subquery has aggregates, GROUP BY, or HAVING, convert to
+/**
+ Prepare a single-column IN/ALL/ANY subselect for rewriting.
- 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.
+ @param join Join object of the subquery (i.e. 'child' join).
- - Otherwise (no aggregates/GROUP BY/HAVING) convert it to one of the
- following:
+ @details
- = If we don't need to distinguish between NULL and FALSE subquery:
-
- SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
+ Prepare a single-column subquery to be rewritten. Given the subquery.
- = If we need to distinguish between those:
+ If the subquery has no tables it will be turned to an expression between
+ left part and SELECT list.
- SELECT 1 FROM ...
- WHERE subq_where AND trigcond((oe $cmp$ ie) OR (ie IS NULL))
- HAVING trigcond(<is_not_null_test>(ie))
+ In other cases the subquery will be wrapped with Item_in_optimizer which
+ allow later to turn it to EXISTS or MAX/MIN.
- 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
+ @retval false The subquery was transformed
+ @retval true Error
*/
-Item_subselect::trans_res
-Item_in_subselect::single_value_transformer(JOIN *join,
- Comp_creator *func)
+bool
+Item_in_subselect::single_value_transformer(JOIN *join)
{
SELECT_LEX *select_lex= join->select_lex;
DBUG_ENTER("Item_in_subselect::single_value_transformer");
@@ -985,119 +1639,46 @@ 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);
- DBUG_RETURN(RES_ERROR);
+ DBUG_RETURN(true);
}
- /*
- If this is an ALL/ANY single-value subselect, try to rewrite it with
- a MIN/MAX subselect. We can do that if a possible NULL result of the
- subselect can be ignored.
- E.g. SELECT * FROM t1 WHERE b > ANY (SELECT a FROM t2) can be rewritten
- with SELECT * FROM t1 WHERE b > (SELECT MAX(a) FROM t2).
- We can't check that this optimization is safe if it's not a top-level
- item of the WHERE clause (e.g. because the WHERE clause can contain IS
- NULL/IS NOT NULL functions). If so, we rewrite ALL/ANY with NOT EXISTS
- later in this method.
- */
- if ((abort_on_null || (upper_item && upper_item->top_level())) &&
- !select_lex->master_unit()->uncacheable && !func->eqne_op())
+ Item* join_having= join->having ? join->having : join->tmp_having;
+ if (!(join_having || select_lex->with_sum_func ||
+ select_lex->group_list.elements) &&
+ select_lex->table_list.elements == 0 &&
+ !select_lex->master_unit()->is_union())
{
- if (substitution)
- {
- // It is second (third, ...) SELECT of UNION => All is done
- DBUG_RETURN(RES_OK);
- }
-
- Item *subs;
+ Item *where_item= (Item*) select_lex->item_list.head();
/*
- Check if optimization with aggregate min/max possible
- 1 There is no aggregate in the subquery
- 2 It is not UNION
- 3 There is tables
- 4 It is not ALL subquery with possible NULLs in the SELECT list
+ it is single select without tables => possible optimization
+ remove the dependence mark since the item is moved to upper
+ select and is not outer anymore.
*/
- if (!select_lex->group_list.elements && /*1*/
- !select_lex->having && /*1*/
- !select_lex->with_sum_func && /*1*/
- !(select_lex->next_select()) && /*2*/
- select_lex->table_list.elements && /*3*/
- (!select_lex->ref_pointer_array[0]->maybe_null || /*4*/
- substype() != Item_subselect::ALL_SUBS)) /*4*/
- {
- Item_sum_hybrid *item;
- nesting_map save_allow_sum_func;
- if (func->l_op())
- {
- /*
- (ALL && (> || =>)) || (ANY && (< || =<))
- for ALL condition is inverted
- */
- item= new Item_sum_max(*select_lex->ref_pointer_array);
- }
- else
- {
- /*
- (ALL && (< || =<)) || (ANY && (> || =>))
- for ALL condition is inverted
- */
- item= new Item_sum_min(*select_lex->ref_pointer_array);
- }
- if (upper_item)
- upper_item->set_sum_test(item);
- *select_lex->ref_pointer_array= item;
- {
- List_iterator<Item> it(select_lex->item_list);
- it++;
- it.replace(item);
- }
-
- DBUG_EXECUTE("where",
- print_where(item, "rewrite with MIN/MAX", QT_ORDINARY););
- if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
- {
- DBUG_ASSERT(item->get_arg(0)->real_item()->type() != Item::FIELD_ITEM ||
- select_lex->non_agg_field_used());
- select_lex->set_non_agg_field_used(false);
- }
-
- save_allow_sum_func= thd->lex->allow_sum_func;
- thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
- /*
- Item_sum_(max|min) can't substitute other item => we can use 0 as
- reference, also Item_sum_(max|min) can't be fixed after creation, so
- we do not check item->fixed
- */
- if (item->fix_fields(thd, 0))
- DBUG_RETURN(RES_ERROR);
- thd->lex->allow_sum_func= save_allow_sum_func;
- /* we added aggregate function => we have to change statistic */
- count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
- 0);
-
- subs= new Item_singlerow_subselect(select_lex);
- }
- else
+ where_item->walk(&Item::remove_dependence_processor, 0,
+ (uchar *) select_lex->outer_select());
+ substitution= func->create(left_expr, where_item);
+ have_to_be_excluded= 1;
+ if (thd->lex->describe)
{
- Item_maxmin_subselect *item;
- subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
- if (upper_item)
- upper_item->set_sub_test(item);
+ char warn_buff[MYSQL_ERRMSG_SIZE];
+ sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ ER_SELECT_REDUCED, warn_buff);
}
- /*
- The swap is needed for expressions of type 'f1 < ALL ( SELECT ....)'
- where we want to evaluate the sub query even if f1 would be null.
- */
- substitution= func->create_swap(left_expr, subs);
- DBUG_RETURN(RES_OK);
+ DBUG_RETURN(false);
}
+ /*
+ 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)
{
/* We're invoked for the 1st (or the only) SELECT in the subquery UNION */
- SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
substitution= optimizer;
SELECT_LEX *current= thd->lex->current_select;
@@ -1107,10 +1688,13 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (!optimizer || optimizer->fix_left(thd, 0))
{
thd->lex->current_select= current;
- DBUG_RETURN(RES_ERROR);
+ DBUG_RETURN(true);
}
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.
@@ -1119,22 +1703,224 @@ Item_in_subselect::single_value_transformer(JOIN *join,
(Item**)optimizer->get_cache(),
(char *)"<no matter>",
(char *)in_left_expr_name);
- if (!left_expr->const_item())
- master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
}
- if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
+
+ DBUG_RETURN(false);
+}
+
+
+/**
+ Apply transformation max/min transwormation to ALL/ANY subquery if it is
+ possible.
+
+ @param join Join object of the subquery (i.e. 'child' join).
+
+ @details
+
+ If this is an ALL/ANY single-value subselect, try to rewrite it with
+ a MIN/MAX subselect. We can do that if a possible NULL result of the
+ subselect can be ignored.
+ E.g. SELECT * FROM t1 WHERE b > ANY (SELECT a FROM t2) can be rewritten
+ with SELECT * FROM t1 WHERE b > (SELECT MAX(a) FROM t2).
+ We can't check that this optimization is safe if it's not a top-level
+ item of the WHERE clause (e.g. because the WHERE clause can contain IS
+ NULL/IS NOT NULL functions). If so, we rewrite ALL/ANY with NOT EXISTS
+ later in this method.
+
+ @retval false The subquery was transformed
+ @retval true Error
+*/
+
+bool Item_allany_subselect::transform_into_max_min(JOIN *join)
+{
+ DBUG_ENTER("Item_allany_subselect::transform_into_max_min");
+ if (!test_strategy(SUBS_MAXMIN_INJECTED | SUBS_MAXMIN_ENGINE))
+ DBUG_RETURN(false);
+ Item **place= optimizer->arguments() + 1;
+ THD *thd= join->thd;
+ SELECT_LEX *select_lex= join->select_lex;
+ Item *subs;
+
+ /*
+ */
+ DBUG_ASSERT(!substitution);
+
+ /*
+ Check if optimization with aggregate min/max possible
+ 1 There is no aggregate in the subquery
+ 2 It is not UNION
+ 3 There is tables
+ 4 It is not ALL subquery with possible NULLs in the SELECT list
+ */
+ if (!select_lex->group_list.elements && /*1*/
+ !select_lex->having && /*1*/
+ !select_lex->with_sum_func && /*1*/
+ !(select_lex->next_select()) && /*2*/
+ select_lex->table_list.elements && /*3*/
+ (!select_lex->ref_pointer_array[0]->maybe_null || /*4*/
+ substype() != Item_subselect::ALL_SUBS)) /*4*/
+ {
+ Item_sum_hybrid *item;
+ nesting_map save_allow_sum_func;
+ if (func->l_op())
+ {
+ /*
+ (ALL && (> || =>)) || (ANY && (< || =<))
+ for ALL condition is inverted
+ */
+ item= new Item_sum_max(*select_lex->ref_pointer_array);
+ }
+ else
+ {
+ /*
+ (ALL && (< || =<)) || (ANY && (> || =>))
+ for ALL condition is inverted
+ */
+ item= new Item_sum_min(*select_lex->ref_pointer_array);
+ }
+ if (upper_item)
+ upper_item->set_sum_test(item);
+ thd->change_item_tree(select_lex->ref_pointer_array, item);
+ {
+ List_iterator<Item> it(select_lex->item_list);
+ it++;
+ thd->change_item_tree(it.ref(), item);
+ }
+
+ DBUG_EXECUTE("where",
+ print_where(item, "rewrite with MIN/MAX", QT_ORDINARY););
+
+ save_allow_sum_func= thd->lex->allow_sum_func;
+ thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
+ /*
+ Item_sum_(max|min) can't substitute other item => we can use 0 as
+ reference, also Item_sum_(max|min) can't be fixed after creation, so
+ we do not check item->fixed
+ */
+ if (item->fix_fields(thd, 0))
+ DBUG_RETURN(true);
+ thd->lex->allow_sum_func= save_allow_sum_func;
+ /* we added aggregate function => we have to change statistic */
+ count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
+ 0);
+ if (join->prepare_stage2())
+ DBUG_RETURN(true);
+ subs= new Item_singlerow_subselect(select_lex);
+
+ /*
+ Remove other strategies if any (we already changed the query and
+ can't apply other strategy).
+ */
+ set_strategy(SUBS_MAXMIN_INJECTED);
+ }
+ else
{
- if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool))))
- DBUG_RETURN(RES_ERROR);
- pushed_cond_guards[0]= TRUE;
+ Item_maxmin_subselect *item;
+ subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
+ if (upper_item)
+ upper_item->set_sub_test(item);
+ /*
+ Remove other strategies if any (we already changed the query and
+ can't apply other strategy).
+ */
+ set_strategy(SUBS_MAXMIN_ENGINE);
}
+ /*
+ The swap is needed for expressions of type 'f1 < ALL ( SELECT ....)'
+ where we want to evaluate the sub query even if f1 would be null.
+ */
+ subs= func->create_swap(*(optimizer->get_cache()), subs);
+ thd->change_item_tree(place, subs);
+ if (subs->fix_fields(thd, &subs))
+ DBUG_RETURN(true);
+ DBUG_ASSERT(subs == (*place)); // There was no substitutions
+
+ select_lex->master_unit()->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
+ select_lex->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
+
+ DBUG_RETURN(false);
+}
+
+
+bool Item_in_subselect::fix_having(Item *having, SELECT_LEX *select_lex)
+{
+ bool fix_res= 0;
+ if (!having->fixed)
+ {
+ select_lex->having_fix_field= 1;
+ fix_res= having->fix_fields(thd, 0);
+ select_lex->having_fix_field= 0;
+ }
+ return fix_res;
+}
+
+bool Item_allany_subselect::is_maxmin_applicable(JOIN *join)
+{
+ /*
+ Check if max/min optimization applicable: It is top item of
+ WHERE condition.
+ */
+ return (abort_on_null || (upper_item && upper_item->is_top_level_item())) &&
+ !join->select_lex->master_unit()->uncacheable && !func->eqne_op();
+}
+
+
+/**
+ Create the predicates needed to transform a single-column IN/ALL/ANY
+ subselect into a correlated EXISTS via predicate injection.
+
+ @param join[in] Join object of the subquery (i.e. 'child' join).
+ @param where_item[out] the in-to-exists addition to the where clause
+ @param having_item[out] the in-to-exists addition to the having clause
+
+ @details
+ The correlated predicates are created 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 ie FROM ... WHERE subq_where AND (oe $cmp$ ie)
+
+ = If we need to distinguish between those:
+
+ SELECT ie FROM ...
+ WHERE subq_where AND trigcond((oe $cmp$ ie) OR (ie IS NULL))
+ HAVING trigcond(<is_not_null_test>(ie))
+
+ @retval false If the new conditions were created successfully
+ @retval true Error
+*/
+
+bool
+Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
+ Item **where_item,
+ Item **having_item)
+{
+ SELECT_LEX *select_lex= join->select_lex;
+ /*
+ The non-transformed HAVING clause of 'join' may be stored in two ways
+ during JOIN::optimize: this->tmp_having= this->having; this->having= 0;
+ */
+ Item* join_having= join->having ? join->having : join->tmp_having;
- if (!left_expr->const_item())
- select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
- if (join->having || select_lex->with_sum_func ||
+ DBUG_ENTER("Item_in_subselect::create_single_in_to_exists_cond");
+
+ *where_item= NULL;
+ *having_item= NULL;
+
+ if (join_having || select_lex->with_sum_func ||
select_lex->group_list.elements)
{
- bool tmp;
Item *item= func->create(expr,
new Item_ref_null_helper(&select_lex->context,
this,
@@ -1150,24 +1936,12 @@ Item_in_subselect::single_value_transformer(JOIN *join,
*/
item= new Item_func_trig_cond(item, get_cond_guard(0));
}
-
- /*
- AND and comparison functions can't be changed during fix_fields()
- we can assign select_lex->having here, and pass 0 as last
- argument (reference) to fix_fields()
- */
- select_lex->having= join->having= and_items(join->having, item);
- if (join->having == item)
- item->name= (char*)in_having_cond;
- select_lex->having_fix_field= 1;
- /*
- we do not check join->having->fixed, because Item_and (from and_items)
- or comparison function (from func->create) can't be fixed after creation
- */
- tmp= join->having->fix_fields(thd, 0);
- select_lex->having_fix_field= 0;
- if (tmp)
- DBUG_RETURN(RES_ERROR);
+
+ if (!join_having)
+ item->name= (char*) in_having_cond;
+ if (fix_having(item, select_lex))
+ DBUG_RETURN(true);
+ *having_item= item;
}
else
{
@@ -1175,13 +1949,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (select_lex->table_list.elements)
{
- bool tmp;
- Item *having= item, *orig_item= item;
- select_lex->item_list.empty();
- select_lex->item_list.push_back(new Item_int("Not_used",
- (longlong) 1,
- MY_INT64_NUM_DECIMAL_DIGITS));
- select_lex->ref_pointer_array[0]= select_lex->item_list.head();
+ Item *having= item;
+ Item *orig_item= item;
item= func->create(expr, item);
if (!abort_on_null && orig_item->maybe_null)
@@ -1191,25 +1960,13 @@ Item_in_subselect::single_value_transformer(JOIN *join,
{
if (!(having= new Item_func_trig_cond(having,
get_cond_guard(0))))
- DBUG_RETURN(RES_ERROR);
+ DBUG_RETURN(true);
}
- /*
- Item_is_not_null_test can't be changed during fix_fields()
- we can assign select_lex->having here, and pass 0 as last
- argument (reference) to fix_fields()
- */
- having->name= (char*)in_having_cond;
- select_lex->having= join->having= having;
- select_lex->having_fix_field= 1;
- /*
- we do not check join->having->fixed, because Item_and (from
- and_items) or comparison function (from func->create) can't be
- fixed after creation
- */
- tmp= join->having->fix_fields(thd, 0);
- select_lex->having_fix_field= 0;
- if (tmp)
- DBUG_RETURN(RES_ERROR);
+ having->name= (char*) in_having_cond;
+ if (fix_having(having, select_lex))
+ DBUG_RETURN(true);
+ *having_item= having;
+
item= new Item_cond_or(item,
new Item_func_isnull(orig_item));
}
@@ -1220,39 +1977,23 @@ Item_in_subselect::single_value_transformer(JOIN *join,
if (!abort_on_null && left_expr->maybe_null)
{
if (!(item= new Item_func_trig_cond(item, get_cond_guard(0))))
- DBUG_RETURN(RES_ERROR);
+ DBUG_RETURN(true);
}
+
/*
TODO: figure out why the following is done here in
single_value_transformer but there is no corresponding action in
row_value_transformer?
*/
- item->name= (char *)in_additional_cond;
-
- /*
- AND can't be changed during fix_fields()
- we can assign select_lex->having here, and pass 0 as last
- argument (reference) to fix_fields()
- */
- select_lex->where= join->conds= and_items(join->conds, item);
- select_lex->where->top_level_item();
- /*
- we do not check join->conds->fixed, because Item_and can't be fixed
- after creation
- */
- if (join->conds->fix_fields(thd, 0))
- DBUG_RETURN(RES_ERROR);
+ item->name= (char *) in_additional_cond;
+ if (!item->fixed && item->fix_fields(thd, 0))
+ DBUG_RETURN(true);
+ *where_item= item;
}
else
{
- bool tmp;
if (select_lex->master_unit()->is_union())
{
- /*
- comparison functions can't be changed during fix_fields()
- we can assign select_lex->having here, and pass 0 as last
- argument (reference) to fix_fields()
- */
Item *new_having=
func->create(expr,
new Item_ref_null_helper(&select_lex->context, this,
@@ -1263,65 +2004,58 @@ Item_in_subselect::single_value_transformer(JOIN *join,
{
if (!(new_having= new Item_func_trig_cond(new_having,
get_cond_guard(0))))
- DBUG_RETURN(RES_ERROR);
+ DBUG_RETURN(true);
}
- new_having->name= (char*)in_having_cond;
- select_lex->having= join->having= new_having;
- select_lex->having_fix_field= 1;
-
- /*
- we do not check join->having->fixed, because comparison function
- (from func->create) can't be fixed after creation
- */
- tmp= join->having->fix_fields(thd, 0);
- select_lex->having_fix_field= 0;
- if (tmp)
- DBUG_RETURN(RES_ERROR);
+
+ new_having->name= (char*) in_having_cond;
+ if (fix_having(new_having, select_lex))
+ DBUG_RETURN(true);
+ *having_item= new_having;
}
else
- {
- // it is single select without tables => possible optimization
- // remove the dependence mark since the item is moved to upper
- // select and is not outer anymore.
- item->walk(&Item::remove_dependence_processor, 0,
- (uchar *) select_lex->outer_select());
- item= func->create(left_expr, item);
- // fix_field of item will be done in time of substituting
- substitution= item;
- have_to_be_excluded= 1;
- if (thd->lex->describe)
- {
- char warn_buff[MYSQL_ERRMSG_SIZE];
- sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_SELECT_REDUCED, warn_buff);
- }
- DBUG_RETURN(RES_REDUCE);
- }
+ DBUG_ASSERT(false);
}
}
- DBUG_RETURN(RES_OK);
+ DBUG_RETURN(false);
}
-Item_subselect::trans_res
+/**
+ Wrap a multi-column IN/ALL/ANY subselect into an Item_in_optimizer.
+
+ @param join Join object of the subquery (i.e. 'child' join).
+
+ @details
+ The subquery predicate is wrapped into an Item_in_optimizer. Later the query
+ optimization phase chooses whether the subquery under the Item_in_optimizer
+ will be further transformed into an equivalent correlated EXISTS by injecting
+ additional predicates, or will be executed via subquery materialization in its
+ unmodified form.
+
+ @retval false The subquery was transformed
+ @retval true Error
+*/
+
+bool
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());
- DBUG_RETURN(RES_ERROR);
+ my_error(ER_OPERAND_COLUMNS, MYF(0), cols_num);
+ DBUG_RETURN(true);
}
+ /*
+ 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
@@ -1334,54 +2068,113 @@ Item_in_subselect::row_value_transformer(JOIN *join)
if (!optimizer || optimizer->fix_left(thd, 0))
{
thd->lex->current_select= current;
- DBUG_RETURN(RES_ERROR);
+ DBUG_RETURN(true);
}
// we will refer to upper level cache array => we have to save it in PS
optimizer->keep_top_level_cache();
thd->lex->current_select= current;
- if (!left_expr->const_item())
- master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
-
- if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
- {
- if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool) *
- left_expr->cols())))
- DBUG_RETURN(RES_ERROR);
- for (uint i= 0; i < cols_num; i++)
- pushed_cond_guards[i]= TRUE;
- }
+ /*
+ The uncacheable property controls a number of actions, e.g. whether to
+ save/restore (via init_save_join_tab/restore_tmp) the original JOIN for
+ plans with a temp table where the original JOIN was overriden by
+ make_simple_join. The UNCACHEABLE_EXPLAIN is ignored by EXPLAIN, thus
+ non-correlated subqueries will not appear as such to EXPLAIN.
+ */
+ master_unit->uncacheable|= UNCACHEABLE_EXPLAIN;
+ select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
}
- if (!left_expr->const_item())
- select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
+ DBUG_RETURN(false);
+}
+
+
+/**
+ Create the predicates needed to transform a multi-column IN/ALL/ANY
+ subselect into a correlated EXISTS via predicate injection.
+
+ @details
+ The correlated predicates are created as follows:
+
+ - If the subquery has aggregates, GROUP BY, or HAVING, convert to
+
+ (l1, l2, l3) IN (SELECT v1, v2, v3 ... HAVING having)
+ =>
+ EXISTS (SELECT ... HAVING having and
+ (l1 = v1 or is null v1) and
+ (l2 = v2 or is null v2) and
+ (l3 = v3 or is null v3) and
+ is_not_null_test(v1) and
+ is_not_null_test(v2) and
+ is_not_null_test(v3))
+
+ where is_not_null_test used to register nulls in case if we have
+ not found matching to return correct NULL value.
+
+ - Otherwise (no aggregates/GROUP BY/HAVING) convert the subquery as follows:
+
+ (l1, l2, l3) IN (SELECT v1, v2, v3 ... WHERE where)
+ =>
+ EXISTS (SELECT ... WHERE where and
+ (l1 = v1 or is null v1) and
+ (l2 = v2 or is null v2) and
+ (l3 = v3 or is null v3)
+ HAVING is_not_null_test(v1) and
+ is_not_null_test(v2) and
+ is_not_null_test(v3))
+ where is_not_null_test registers NULLs values but reject rows.
+
+ in case when we do not need correct NULL, we have simplier construction:
+ EXISTS (SELECT ... WHERE where and
+ (l1 = v1) and
+ (l2 = v2) and
+ (l3 = v3)
+
+ @param join[in] Join object of the subquery (i.e. 'child' join).
+ @param where_item[out] the in-to-exists addition to the where clause
+ @param having_item[out] the in-to-exists addition to the having clause
+
+ @retval false If the new conditions were created successfully
+ @retval true Error
+*/
+
+bool
+Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
+ Item **where_item,
+ Item **having_item)
+{
+ SELECT_LEX *select_lex= join->select_lex;
+ uint cols_num= left_expr->cols();
+ /*
+ The non-transformed HAVING clause of 'join' may be stored in two ways
+ during JOIN::optimize: this->tmp_having= this->having; this->having= 0;
+ */
+ Item* join_having= join->having ? join->having : join->tmp_having;
+ 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::create_row_in_to_exists_cond");
+
+ *where_item= NULL;
+ *having_item= NULL;
+
if (is_having_used)
{
- /*
- (l1, l2, l3) IN (SELECT v1, v2, v3 ... HAVING having) =>
- EXISTS (SELECT ... HAVING having and
- (l1 = v1 or is null v1) and
- (l2 = v2 or is null v2) and
- (l3 = v3 or is null v3) and
- is_not_null_test(v1) and
- is_not_null_test(v2) and
- is_not_null_test(v3))
- where is_not_null_test used to register nulls in case if we have
- not found matching to return correct NULL value
- TODO: say here explicitly if the order of AND parts matters or not.
- */
+ /* TODO: say here explicitly if the order of AND parts matters or not. */
Item *item_having_part2= 0;
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));
if (select_lex->ref_pointer_array[i]->
check_cols(left_expr->element_index(i)->cols()))
- DBUG_RETURN(RES_ERROR);
+ DBUG_RETURN(true);
Item *item_eq=
new Item_func_eq(new
Item_ref(&select_lex->context,
@@ -1393,23 +2186,21 @@ Item_in_subselect::row_value_transformer(JOIN *join)
Item_ref(&select_lex->context,
select_lex->ref_pointer_array + i,
(char *)"<no matter>",
- (char *)"<list ref>")
- );
+ (char *)"<list ref>"));
Item *item_isnull=
new Item_func_isnull(new
Item_ref(&select_lex->context,
select_lex->ref_pointer_array+i,
(char *)"<no matter>",
- (char *)"<list ref>")
- );
+ (char *)"<list ref>"));
Item *col_item= new Item_cond_or(item_eq, item_isnull);
if (!abort_on_null && left_expr->element_index(i)->maybe_null)
{
if (!(col_item= new Item_func_trig_cond(col_item, get_cond_guard(i))))
- DBUG_RETURN(RES_ERROR);
+ DBUG_RETURN(true);
}
- having_item= and_items(having_item, col_item);
-
+ *having_item= and_items(*having_item, col_item);
+
Item *item_nnull_test=
new Item_is_not_null_test(this,
new Item_ref(&select_lex->context,
@@ -1421,45 +2212,26 @@ Item_in_subselect::row_value_transformer(JOIN *join)
{
if (!(item_nnull_test=
new Item_func_trig_cond(item_nnull_test, get_cond_guard(i))))
- DBUG_RETURN(RES_ERROR);
+ DBUG_RETURN(true);
}
item_having_part2= and_items(item_having_part2, item_nnull_test);
item_having_part2->top_level_item();
}
- having_item= and_items(having_item, item_having_part2);
- having_item->top_level_item();
+ *having_item= and_items(*having_item, item_having_part2);
}
else
{
- /*
- (l1, l2, l3) IN (SELECT v1, v2, v3 ... WHERE where) =>
- EXISTS (SELECT ... WHERE where and
- (l1 = v1 or is null v1) and
- (l2 = v2 or is null v2) and
- (l3 = v3 or is null v3)
- HAVING is_not_null_test(v1) and
- is_not_null_test(v2) and
- is_not_null_test(v3))
- where is_not_null_test register NULLs values but reject rows
-
- in case when we do not need correct NULL, we have simplier construction:
- EXISTS (SELECT ... WHERE where and
- (l1 = v1) and
- (l2 = v2) and
- (l3 = v3)
- */
- Item *where_item= 0;
for (uint i= 0; i < cols_num; i++)
{
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));
if (select_lex->ref_pointer_array[i]->
check_cols(left_expr->element_index(i)->cols()))
- DBUG_RETURN(RES_ERROR);
+ DBUG_RETURN(true);
item=
new Item_func_eq(new
Item_direct_ref(&select_lex->context,
@@ -1472,8 +2244,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
select_lex->
ref_pointer_array+i,
(char *)"<no matter>",
- (char *)"<list ref>")
- );
+ (char *)"<list ref>"));
if (!abort_on_null)
{
Item *having_col_item=
@@ -1491,8 +2262,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
select_lex->
ref_pointer_array+i,
(char *)"<no matter>",
- (char *)"<list ref>")
- );
+ (char *)"<list ref>"));
item= new Item_cond_or(item, item_isnull);
/*
TODO: why we create the above for cases where the right part
@@ -1501,106 +2271,221 @@ Item_in_subselect::row_value_transformer(JOIN *join)
if (left_expr->element_index(i)->maybe_null)
{
if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
- DBUG_RETURN(RES_ERROR);
+ DBUG_RETURN(true);
if (!(having_col_item=
new Item_func_trig_cond(having_col_item, get_cond_guard(i))))
- DBUG_RETURN(RES_ERROR);
+ DBUG_RETURN(true);
}
- having_item= and_items(having_item, having_col_item);
+ *having_item= and_items(*having_item, having_col_item);
}
- where_item= and_items(where_item, item);
+ *where_item= and_items(*where_item, item);
}
- /*
- AND can't be changed during fix_fields()
- we can assign select_lex->where here, and pass 0 as last
- argument (reference) to fix_fields()
- */
- select_lex->where= join->conds= and_items(join->conds, where_item);
- select_lex->where->top_level_item();
- if (join->conds->fix_fields(thd, 0))
- DBUG_RETURN(RES_ERROR);
}
- if (having_item)
+
+ if (*where_item)
{
- bool res;
- select_lex->having= join->having= and_items(join->having, having_item);
- if (having_item == select_lex->having)
- having_item->name= (char*)in_having_cond;
- select_lex->having->top_level_item();
- /*
- AND can't be changed during fix_fields()
- we can assign select_lex->having here, and pass 0 as last
- argument (reference) to fix_fields()
- */
- select_lex->having_fix_field= 1;
- res= join->having->fix_fields(thd, 0);
- select_lex->having_fix_field= 0;
- if (res)
- {
- DBUG_RETURN(RES_ERROR);
- }
+ if (!(*where_item)->fixed && (*where_item)->fix_fields(thd, 0))
+ DBUG_RETURN(true);
+ (*where_item)->top_level_item();
}
- DBUG_RETURN(RES_OK);
+ if (*having_item)
+ {
+ if (!join_having)
+ (*having_item)->name= (char*) in_having_cond;
+ if (fix_having(*having_item, select_lex))
+ DBUG_RETURN(true);
+ (*having_item)->top_level_item();
+ }
+
+ DBUG_RETURN(false);
}
-Item_subselect::trans_res
+bool
Item_in_subselect::select_transformer(JOIN *join)
{
- return select_in_like_transformer(join, &eq_creator);
+ return select_in_like_transformer(join);
}
/**
- Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate
- transformation function.
+ Create the predicates needed to transform an IN/ALL/ANY subselect into a
+ correlated EXISTS via predicate injection.
+
+ @param join_arg Join object of the subquery.
+
+ @retval FALSE ok
+ @retval TRUE error
+*/
+
+bool Item_in_subselect::create_in_to_exists_cond(JOIN *join_arg)
+{
+ bool res;
+
+ DBUG_ASSERT(engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE ||
+ engine->engine_type() == subselect_engine::UNION_ENGINE);
+ /*
+ TODO: the call to init_cond_guards allocates and initializes an
+ array of booleans that may not be used later because we may choose
+ materialization.
+ The two calls below to create_XYZ_cond depend on this boolean array.
+ If the dependency is removed, the call can be moved to a later phase.
+ */
+ init_cond_guards();
+ if (left_expr->cols() == 1)
+ res= create_single_in_to_exists_cond(join_arg,
+ &(join_arg->in_to_exists_where),
+ &(join_arg->in_to_exists_having));
+ else
+ res= create_row_in_to_exists_cond(join_arg,
+ &(join_arg->in_to_exists_where),
+ &(join_arg->in_to_exists_having));
+
+ /*
+ The IN=>EXISTS transformation makes non-correlated subqueries correlated.
+ */
+ if (!left_expr->const_item() || left_expr->is_expensive())
+ {
+ join_arg->select_lex->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
+ join_arg->select_lex->master_unit()->uncacheable|=
+ UNCACHEABLE_DEPENDENT_INJECTED;
+ }
+ /*
+ The uncacheable property controls a number of actions, e.g. whether to
+ save/restore (via init_save_join_tab/restore_tmp) the original JOIN for
+ plans with a temp table where the original JOIN was overriden by
+ make_simple_join. The UNCACHEABLE_EXPLAIN is ignored by EXPLAIN, thus
+ non-correlated subqueries will not appear as such to EXPLAIN.
+ */
+ join_arg->select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
+ join_arg->select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
+ return (res);
+}
+
+
+/**
+ Transform an IN/ALL/ANY subselect into a correlated EXISTS via injecting
+ correlated in-to-exists predicates.
+
+ @param join_arg Join object of the subquery.
+
+ @retval FALSE ok
+ @retval TRUE error
+*/
+
+bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
+{
+ SELECT_LEX *select_lex= join_arg->select_lex;
+ Item *where_item= join_arg->in_to_exists_where;
+ Item *having_item= join_arg->in_to_exists_having;
+
+ DBUG_ENTER("Item_in_subselect::inject_in_to_exists_cond");
+
+ if (where_item)
+ {
+ List<Item> *and_args= NULL;
+ /*
+ If the top-level Item of the WHERE clause is an AND, detach the multiple
+ equality list that was attached to the end of the AND argument list by
+ build_equal_items_for_cond(). The multiple equalities must be detached
+ because fix_fields merges lower level AND arguments into the upper AND.
+ As a result, the arguments from lower-level ANDs are concatenated after
+ the multiple equalities. When the multiple equality list is treated as
+ such, it turns out that it contains non-Item_equal object which is wrong.
+ */
+ if (join_arg->conds && join_arg->conds->type() == Item::COND_ITEM &&
+ ((Item_cond*) join_arg->conds)->functype() == Item_func::COND_AND_FUNC)
+ {
+ and_args= ((Item_cond*) join_arg->conds)->argument_list();
+ if (join_arg->cond_equal)
+ and_args->disjoin((List<Item> *) &join_arg->cond_equal->current_level);
+ }
+
+ where_item= and_items(join_arg->conds, where_item);
+ if (!where_item->fixed && where_item->fix_fields(thd, 0))
+ DBUG_RETURN(true);
+ // TIMOUR TODO: call optimize_cond() for the new where clause
+ thd->change_item_tree(&select_lex->where, where_item);
+ select_lex->where->top_level_item();
+ join_arg->conds= select_lex->where;
+
+ /* Attach back the list of multiple equalities to the new top-level AND. */
+ if (and_args && join_arg->cond_equal)
+ {
+ /* The argument list of the top-level AND may change after fix fields. */
+ and_args= ((Item_cond*) join_arg->conds)->argument_list();
+ List_iterator<Item_equal> li(join_arg->cond_equal->current_level);
+ Item_equal *elem;
+ while ((elem= li++))
+ {
+ and_args->push_back(elem);
+ }
+ }
+ }
+
+ if (having_item)
+ {
+ Item* join_having= join_arg->having ? join_arg->having:join_arg->tmp_having;
+ having_item= and_items(join_having, having_item);
+ if (fix_having(having_item, select_lex))
+ DBUG_RETURN(true);
+ // TIMOUR TODO: call optimize_cond() for the new having clause
+ thd->change_item_tree(&select_lex->having, having_item);
+ select_lex->having->top_level_item();
+ join_arg->having= select_lex->having;
+ }
+ join_arg->thd->change_item_tree(&unit->global_parameters->select_limit,
+ new Item_int((int32) 1));
+ unit->select_limit_cnt= 1;
- To decide which transformation procedure (scalar or row) applicable here
- we have to call fix_fields() for left expression to be able to call
- cols() method on it. Also this method make arena management for
- underlying transformation methods.
+ DBUG_RETURN(false);
+}
+
+
+/**
+ Prepare IN/ALL/ANY/SOME subquery transformation and call the appropriate
+ transformation function.
@param join JOIN object of transforming subquery
- @param func creator of condition function of subquery
- @retval
- RES_OK OK
- @retval
- RES_REDUCE OK, and current subquery was reduced during
- transformation
- @retval
- RES_ERROR Error
+ @notes
+ To decide which transformation procedure (scalar or row) applicable here
+ we have to call fix_fields() for the left expression to be able to call
+ cols() method on it. Also this method makes arena management for
+ underlying transformation methods.
+
+ @retval false OK
+ @retval true Error
*/
-Item_subselect::trans_res
-Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
+bool
+Item_in_subselect::select_in_like_transformer(JOIN *join)
{
Query_arena *arena, backup;
SELECT_LEX *current= thd->lex->current_select;
const char *save_where= thd->where;
- Item_subselect::trans_res res= RES_ERROR;
+ bool trans_res= true;
bool result;
DBUG_ENTER("Item_in_subselect::select_in_like_transformer");
+ /*
+ IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
+ ORDER BY clause becomes meaningless thus we drop it here.
+ */
+ for (SELECT_LEX *sl= current->master_unit()->first_select();
+ sl; sl= sl->next_select())
{
- /*
- IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
- ORDER BY clause becomes meaningless thus we drop it here.
- */
- SELECT_LEX *sl= current->master_unit()->first_select();
- for (; sl; sl= sl->next_select())
+ if (sl->join)
{
- if (sl->join)
- sl->join->order= 0;
+ sl->join->order= 0;
+ sl->join->skip_sort_order= 1;
}
}
if (changed)
- {
- DBUG_RETURN(RES_OK);
- }
+ DBUG_RETURN(false);
thd->where= "IN/ALL/ANY subquery";
@@ -1608,6 +2493,9 @@ 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.
+
+ note: we won't need Item_in_optimizer when handling degenerate cases
+ like "... IN (SELECT 1)"
*/
if (!optimizer)
{
@@ -1629,9 +2517,6 @@ Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
if (result)
goto err;
- transformed= 1;
- arena= thd->activate_stmt_arena_if_needed(&backup);
-
/*
Both transformers call fix_fields() only for Items created inside them,
and all that items do not make permanent changes in current item arena
@@ -1639,8 +2524,9 @@ Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
of Item, we have to call fix_fields() for it only with original arena to
avoid memory leack)
*/
+ arena= thd->activate_stmt_arena_if_needed(&backup);
if (left_expr->cols() == 1)
- res= single_value_transformer(join, func);
+ trans_res= single_value_transformer(join);
else
{
/* we do not support row operation for ALL/ANY/SOME */
@@ -1649,21 +2535,21 @@ Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
if (arena)
thd->restore_active_arena(arena, &backup);
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
- DBUG_RETURN(RES_ERROR);
+ DBUG_RETURN(true);
}
- res= row_value_transformer(join);
+ trans_res= row_value_transformer(join);
}
if (arena)
thd->restore_active_arena(arena, &backup);
err:
thd->where= save_where;
- DBUG_RETURN(res);
+ DBUG_RETURN(trans_res);
}
void Item_in_subselect::print(String *str, enum_query_type query_type)
{
- if (transformed)
+ if (test_strategy(SUBS_IN_TO_EXISTS))
str->append(STRING_WITH_LEN("<exists>"));
else
{
@@ -1676,35 +2562,197 @@ 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;
-
+ uint outer_cols_num;
+ List<Item> *inner_cols;
+
+ if (test_strategy(SUBS_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();
+
+ 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->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) &&
- left_expr && !left_expr->fixed)
- result = left_expr->fix_fields(thd_arg, &left_expr);
+ left_expr && !left_expr->fixed &&
+ left_expr->fix_fields(thd_arg, &left_expr))
+ return TRUE;
+ else
+ if (Item_subselect::fix_fields(thd_arg, ref))
+ return TRUE;
+ fixed= TRUE;
+ return FALSE;
+}
+
- return result || Item_subselect::fix_fields(thd_arg, ref);
+void Item_in_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ left_expr->fix_after_pullout(new_parent, &left_expr);
+ Item_subselect::fix_after_pullout(new_parent, ref);
+ used_tables_cache |= left_expr->used_tables();
}
+void Item_in_subselect::update_used_tables()
+{
+ Item_subselect::update_used_tables();
+ left_expr->update_used_tables();
+ //used_tables_cache |= left_expr->used_tables();
+ used_tables_cache= Item_subselect::used_tables() | left_expr->used_tables();
+}
-inline bool Item_in_subselect::left_expr_has_null()
+
+/**
+ Try to create and initialize an engine to compute a subselect via
+ materialization.
+
+ @details
+ The method creates a new engine for materialized execution, and initializes
+ the engine. The initialization may fail
+ - either because it wasn't possible to create the needed temporary table
+ and its index,
+ - or because of a memory allocation error,
+
+ @returns
+ @retval TRUE memory allocation error occurred
+ @retval FALSE an execution method was chosen successfully
+*/
+
+bool Item_in_subselect::setup_mat_engine()
{
- return (*(optimizer->get_cache()))->null_value;
+ subselect_hash_sj_engine *mat_engine= NULL;
+ subselect_single_select_engine *select_engine;
+
+ DBUG_ENTER("Item_in_subselect::setup_mat_engine");
+
+ /*
+ The select_engine (that executes transformed IN=>EXISTS subselects) is
+ pre-created at parse time, and is stored in statment memory (preserved
+ across PS executions).
+ */
+ DBUG_ASSERT(engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE);
+ select_engine= (subselect_single_select_engine*) engine;
+
+ /* Create/initialize execution objects. */
+ if (!(mat_engine= new subselect_hash_sj_engine(thd, this, select_engine)))
+ DBUG_RETURN(TRUE);
+
+ if (mat_engine->init(&select_engine->join->fields_list,
+ engine->get_identifier()))
+ DBUG_RETURN(TRUE);
+
+ engine= mat_engine;
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ 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->table_count || !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;
}
-Item_subselect::trans_res
+bool Item_in_subselect::init_cond_guards()
+{
+ uint cols_num= left_expr->cols();
+ if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
+ {
+ if (!(pushed_cond_guards= (bool*)thd->alloc(sizeof(bool) * cols_num)))
+ return TRUE;
+ for (uint i= 0; i < cols_num; i++)
+ pushed_cond_guards[i]= TRUE;
+ }
+ return FALSE;
+}
+
+
+bool
Item_allany_subselect::select_transformer(JOIN *join)
{
- transformed= 1;
+ DBUG_ENTER("Item_allany_subselect::select_transformer");
+ DBUG_ASSERT((in_strategy & ~(SUBS_MAXMIN_INJECTED | SUBS_MAXMIN_ENGINE |
+ SUBS_IN_TO_EXISTS | SUBS_STRATEGY_CHOSEN)) == 0);
if (upper_item)
upper_item->show= 1;
- return select_in_like_transformer(join, func);
+ DBUG_RETURN(select_in_like_transformer(join));
}
void Item_allany_subselect::print(String *str, enum_query_type query_type)
{
- if (transformed)
+ if (test_strategy(SUBS_IN_TO_EXISTS))
str->append(STRING_WITH_LEN("<exists>"));
else
{
@@ -1717,6 +2765,24 @@ void Item_allany_subselect::print(String *str, enum_query_type query_type)
}
+void Item_allany_subselect::no_rows_in_result()
+{
+ /*
+ Subquery predicates outside of the SELECT list must be evaluated in order
+ to possibly filter the special result row generated for implicit grouping
+ if the subquery is in the HAVING clause.
+ If the predicate is constant, we need its actual value in the only result
+ row for queries with implicit grouping.
+ */
+ if (parsing_place != SELECT_LIST || const_item())
+ return;
+ value= 0;
+ null_value= 0;
+ was_null= 0;
+ make_const();
+}
+
+
void subselect_engine::set_thd(THD *thd_arg)
{
thd= thd_arg;
@@ -1726,23 +2792,28 @@ 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), optimize_error(0),
+ :subselect_engine(thd_arg, item_arg, result_arg),
+ prepared(0), executed(0), optimize_error(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= optimize_error= 0;
+ prepared= executed= optimize_error= 0;
join= 0;
result->cleanup();
+ select_lex->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
DBUG_VOID_RETURN;
}
@@ -1752,6 +2823,9 @@ void subselect_union_engine::cleanup()
DBUG_ENTER("subselect_union_engine::cleanup");
unit->reinit_exec_mechanism();
result->cleanup();
+ unit->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
+ for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
+ sl->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
DBUG_VOID_RETURN;
}
@@ -1783,21 +2857,18 @@ 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
- */
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
@@ -1806,6 +2877,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)
@@ -1847,8 +2944,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;
}
@@ -1892,10 +2989,10 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
item->decimals= sel_item->decimals;
item->unsigned_flag= sel_item->unsigned_flag;
maybe_null= sel_item->maybe_null;
- if (!(row[i]= Item_cache::get_cache(sel_item)))
+ if (!(row[i]= Item_cache::get_cache(sel_item, sel_item->cmp_type())))
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;
@@ -1947,19 +3044,16 @@ 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();
- DBUG_EXECUTE_IF("bug11747970_simulate_error",
- DBUG_SET("+d,bug11747970_raise_error"););
-
- optimized= 1;
unit->set_limit(unit->global_parameters);
if (join->optimize())
{
thd->where= save_where;
- optimize_error= 1;
+ executed= optimize_error= 1;
thd->lex->current_select= save_select;
DBUG_RETURN(join->error ? join->error : 1);
}
@@ -2018,9 +3112,9 @@ int subselect_single_select_engine::exec()
pushed down into the subquery. Those optimizations are ref[_or_null]
acceses. Change them to be full table scans.
*/
- for (uint i=join->const_tables ; i < join->tables ; i++)
+ for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES); tab;
+ tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
- JOIN_TAB *tab=join->join_tab+i;
if (tab && tab->keyuse)
{
for (uint i= 0; i < tab->ref.key_parts; i++)
@@ -2056,9 +3150,11 @@ int subselect_single_select_engine::exec()
tab->read_record.read_record= tab->save_read_record;
}
executed= 1;
+ if (!(uncacheable() & ~UNCACHEABLE_EXPLAIN))
+ item->make_const();
thd->where= save_where;
thd->lex->current_select= save_select;
- DBUG_RETURN(join->error||thd->is_fatal_error);
+ DBUG_RETURN(join->error || thd->is_fatal_error || thd->is_error());
}
thd->where= save_where;
thd->lex->current_select= save_select;
@@ -2109,14 +3205,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())
{
@@ -2130,53 +3235,40 @@ int subselect_uniquesubquery_engine::scan_table()
}
-/*
- Copy ref key and check for null parts in it
-
- SYNOPSIS
- subselect_uniquesubquery_engine::copy_ref_key()
+/**
+ Copy ref key for index access into the only subquery table.
- DESCRIPTION
+ @details
Copy ref key and check for conversion problems.
-
If there is an error converting the left IN operand to the column type of
the right IN operand count it as no match. In this case IN has the value of
FALSE. We mark the subquery table cursor as having no more rows (to ensure
that the processing that follows will not find a match) and return FALSE,
so IN is not treated as returning NULL.
- RETURN
- FALSE - The value of the IN predicate is not known. Proceed to find the
- value of the IN predicate using the copied key.
- TRUE - IN predicate has a value of FALSE. Stop the processing right there
- and tell the outer predicate it is FALSE.
+ @returns
+ @retval FALSE The outer ref was copied into an index lookup key.
+ @retval TRUE The outer ref cannot possibly match any row, IN is FALSE.
*/
-bool subselect_uniquesubquery_engine::copy_ref_key()
+bool subselect_uniquesubquery_engine::copy_ref_key(bool skip_constants)
{
DBUG_ENTER("subselect_uniquesubquery_engine::copy_ref_key");
for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
{
- if ((*copy)->store_key_is_const())
+ enum store_key::store_key_result store_res;
+ if (skip_constants && (*copy)->store_key_is_const())
continue;
- tab->ref.key_err= (*copy)->copy();
+ store_res= (*copy)->copy();
+ tab->ref.key_err= store_res;
- /*
- 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 (tab->ref.key_err & 1)
+ if (store_res == store_key::STORE_KEY_FATAL)
{
/*
Error converting the left IN operand to the column type of the right
IN operand.
*/
- tab->table->status= STATUS_NOT_FOUND;
DBUG_RETURN(true);
}
}
@@ -2184,13 +3276,10 @@ bool subselect_uniquesubquery_engine::copy_ref_key()
}
-/*
- Execute subselect
-
- SYNOPSIS
- subselect_uniquesubquery_engine::exec()
+/**
+ Execute subselect via unique index lookup
- DESCRIPTION
+ @details
Find rows corresponding to the ref key using index access.
If some part of the lookup key is NULL, then we're evaluating
NULL IN (SELECT ... )
@@ -2207,12 +3296,11 @@ bool subselect_uniquesubquery_engine::copy_ref_key()
The result of this function (info about whether a row was found) is
stored in this->empty_result_set.
- NOTE
- RETURN
- 0 - ok
- 1 - notify caller to call Item_subselect::reset(),
- in most cases reset() sets the result to NULL
+ @returns
+ @retval 0 OK
+ @retval 1 notify caller to call Item_subselect::reset(),
+ in most cases reset() sets the result to NULL
*/
int subselect_uniquesubquery_engine::exec()
@@ -2223,6 +3311,9 @@ int subselect_uniquesubquery_engine::exec()
empty_result_set= TRUE;
table->status= 0;
Item_in_subselect *in_subs= (Item_in_subselect *) item;
+
+ if (!tab->preread_init_done && tab->preread_init())
+ DBUG_RETURN(1);
if (in_subs->left_expr_has_null())
{
@@ -2236,7 +3327,7 @@ int subselect_uniquesubquery_engine::exec()
DBUG_RETURN(scan_table());
}
- if (copy_ref_key())
+ if (copy_ref_key(true))
{
/* We know that there will be no rows even if we scan. */
in_subs->value= 0;
@@ -2270,21 +3361,58 @@ 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();
}
-/*
- Index-lookup subselect 'engine' - run the subquery
-
- SYNOPSIS
- subselect_uniquesubquery_engine:exec()
- full_scan
+/**
+ Execute subselect via unique index lookup
- DESCRIPTION
+ @details
The engine is used to resolve subqueries in form
oe IN (SELECT key FROM tbl WHERE subq_where)
@@ -2299,7 +3427,7 @@ subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine()
row that satisfies subq_where. If found, return NULL, otherwise
return FALSE.
- TODO
+ @todo
The step #1 can be optimized further when the index has several key
parts. Consider a subquery:
@@ -2324,20 +3452,21 @@ subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine()
cheaper. We can use index statistics to quickly check whether "ref" scan
will be cheaper than full table scan.
- 0 - ok
- 1 - notify caller to call Item_subselect::reset(),
- in most cases reset() sets the result to NULL
+ @returns
+ @retval 0 OK
+ @retval 1 notify caller to call Item_subselect::reset(),
+ in most cases reset() sets the result to NULL
*/
int subselect_indexsubquery_engine::exec()
{
- DBUG_ENTER("subselect_indexsubquery_engine::exec");
+ DBUG_ENTER("subselect_indexsubquery_engine");
int error;
bool null_finding= 0;
TABLE *table= tab->table;
Item_in_subselect *in_subs= (Item_in_subselect *) item;
- in_subs->value= 0;
+ ((Item_in_subselect *) item)->value= 0;
empty_result_set= TRUE;
table->status= 0;
@@ -2348,6 +3477,9 @@ int subselect_indexsubquery_engine::exec()
((Item_in_subselect *) item)->was_null= 0;
}
+ if (!tab->preread_init_done && tab->preread_init())
+ DBUG_RETURN(1);
+
if (in_subs->left_expr_has_null())
{
/*
@@ -2360,7 +3492,7 @@ int subselect_indexsubquery_engine::exec()
DBUG_RETURN(scan_table());
}
- if (copy_ref_key())
+ if (copy_ref_key(true))
{
/* We know that there will be no rows even if we scan. */
in_subs->value= 0;
@@ -2421,8 +3553,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;
}
@@ -2463,10 +3597,13 @@ void subselect_uniquesubquery_engine::exclude()
}
-table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
+table_map subselect_engine::calc_const_tables(List<TABLE_LIST> &list)
{
table_map map= 0;
- for (; table; table= table->next_leaf)
+ List_iterator<TABLE_LIST> ti(list);
+ TABLE_LIST *table;
+ //for (; table; table= table->next_leaf)
+ while ((table= ti++))
{
TABLE *tbl= table->table;
if (tbl && tbl->const_table)
@@ -2504,10 +3641,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);
@@ -2519,6 +3666,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)
@@ -2550,6 +3720,7 @@ void subselect_indexsubquery_engine::print(String *str,
@param si new subselect Item
@param res new select_result object
+ @param temp temporary assignment
@retval
FALSE OK
@@ -2557,12 +3728,32 @@ void subselect_indexsubquery_engine::print(String *str,
TRUE error
*/
-bool subselect_single_select_engine::change_result(Item_subselect *si,
- select_subselect *res)
+bool
+subselect_single_select_engine::change_result(Item_subselect *si,
+ select_result_interceptor *res,
+ bool temp)
{
item= si;
- result= res;
- return select_lex->join->change_result(result);
+ if (temp)
+ {
+ /*
+ Here we reuse change_item_tree to roll back assignment. It has
+ nothing special about Item* pointer so it is safe conversion. We do
+ not change the interface to be compatible with MySQL.
+ */
+ thd->change_item_tree((Item**) &result, (Item*)res);
+ }
+ else
+ result= res;
+
+ /*
+ We can't use 'result' below as gcc 4.2.4's alias optimization
+ assumes that result was not changed by thd->change_item_tree().
+ I tried to find a solution to make gcc happy, but could not find anything
+ that would not require a lot of extra code that would be harder to manage
+ than the current code.
+ */
+ return select_lex->join->change_result(res);
}
@@ -2579,11 +3770,15 @@ 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,
+ bool temp)
{
item= si;
int rc= unit->change_result(res, result);
- result= res;
+ if (temp)
+ thd->change_item_tree((Item**) &result, (Item*)res);
+ else
+ result= res;
return rc;
}
@@ -2600,8 +3795,11 @@ bool subselect_union_engine::change_result(Item_subselect *si,
TRUE error
*/
-bool subselect_uniquesubquery_engine::change_result(Item_subselect *si,
- select_subselect *res)
+bool
+subselect_uniquesubquery_engine::change_result(Item_subselect *si,
+ select_result_interceptor *res,
+ bool temp
+ __attribute__((unused)))
{
DBUG_ASSERT(0);
return TRUE;
@@ -2669,5 +3867,2085 @@ 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 (result_sink->get_null_count_of_col(i))
+ ++count_columns_with_nulls;
+ }
+
+ /* 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;
+ ha_rows max_null_row;
+
+ /* 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 */
+ max_null_row= result_sink->get_max_null_of_col(i);
+ if (max_null_row >= UINT_MAX)
+ {
+ /*
+ There can be at most UINT_MAX bits in a MY_BITMAP that is used to
+ store NULLs in an Ordered_key. Return a number of bytes bigger than
+ the maximum allowed memory buffer for partial matching to disable
+ the rowid merge strategy.
+ */
+ return ULONGLONG_MAX;
+ }
+ buff_size+= bitmap_buffer_size(max_null_row);
+ }
+ }
+
+ 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
+ @param subquery_id subquery's identifier (to make "<subquery%d>" name for
+ EXPLAIN)
+
+ @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(List<Item> *tmp_columns, uint subquery_id)
+{
+ select_union *result_sink;
+ /* 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");
+
+ 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_sink= new select_materialize_with_stats))
+ DBUG_RETURN(TRUE);
+
+ char buf[32];
+ uint len= my_snprintf(buf, sizeof(buf), "<subquery%d>", subquery_id);
+ char *name;
+ if (!(name= (char*)thd->alloc(len + 1)))
+ DBUG_RETURN(TRUE);
+ memcpy(name, buf, len+1);
+
+ result_sink->get_tmp_table_param()->materialized_subquery= true;
+ if (item->substype() == Item_subselect::IN_SUBS &&
+ ((Item_in_subselect*)item)->is_jtbm_merged)
+ {
+ result_sink->get_tmp_table_param()->force_not_null_cols= true;
+ }
+ if (result_sink->create_result_table(thd, tmp_columns, TRUE,
+ tmp_create_options,
+ name, TRUE, TRUE))
+ DBUG_RETURN(TRUE);
+
+ tmp_table= result_sink->table;
+ result= result_sink;
+
+ /*
+ 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)
+ {
+ //fprintf(stderr, "Q: %s\n", current_thd->query());
+ DBUG_ASSERT(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);
+
+ /*
+ 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))
+ DBUG_RETURN(TRUE);
+ /* Let our engine reuse this query plan for materialization. */
+ materialize_join= materialize_engine->join;
+ materialize_join->change_result(result);
+
+ 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("", tmp_table->alias.c_ptr(), 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;
+ semi_join_conds_context= context;
+
+ 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->preread_init_done= FALSE;
+ tab->ref.tmp_table_index_lookup_init(thd, tmp_key, it, FALSE);
+
+ DBUG_RETURN(new subselect_uniquesubquery_engine(thd, tab, item,
+ semi_join_conds));
+}
+
+
+subselect_hash_sj_engine::~subselect_hash_sj_engine()
+{
+ delete lookup_engine;
+ delete result;
+ if (tmp_table)
+ free_tmp_table(thd, tmp_table);
+}
+
+
+int subselect_hash_sj_engine::prepare()
+{
+ /*
+ Create and optimize the JOIN that will be used to materialize
+ the subquery if not yet created.
+ */
+ return materialize_engine->prepare();
+}
+
+
+/**
+ 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();
+ /*
+ Restore the original Item_in_subselect engine. This engine is created once
+ at parse time and stored across executions, while all other materialization
+ related engines are created and chosen for each execution.
+ */
+ ((Item_in_subselect *) item)->engine= materialize_engine;
+ 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. */
+ DBUG_ASSERT(tmp_table);
+ free_tmp_table(thd, tmp_table);
+ tmp_table= NULL;
+}
+
+
+/*
+ Get fanout produced by tables specified in the table_map
+*/
+
+double get_fanout_with_deps(JOIN *join, table_map tset)
+{
+ /* Handle the case of "Impossible WHERE" */
+ if (join->table_count == 0)
+ return 0.0;
+
+ /* First, recursively get all tables we depend on */
+ table_map deps_to_check= tset;
+ table_map checked_deps= 0;
+ table_map further_deps;
+ do
+ {
+ further_deps= 0;
+ Table_map_iterator tm_it(deps_to_check);
+ int tableno;
+ while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END)
+ {
+ /* get tableno's dependency tables that are not in needed_set */
+ further_deps |= join->map2table[tableno]->ref.depend_map & ~checked_deps;
+ }
+
+ checked_deps |= deps_to_check;
+ deps_to_check= further_deps;
+ } while (further_deps != 0);
+
+
+ /* Now, walk the join order and calculate the fanout */
+ double fanout= 1;
+ for (JOIN_TAB *tab= first_top_level_tab(join, WITHOUT_CONST_TABLES); tab;
+ tab= next_top_level_tab(join, tab))
+ {
+ /*
+ Ignore SJM nests. They have tab->table==NULL. There is no point to walk
+ inside them, because GROUP BY clause cannot refer to tables from within
+ subquery.
+ */
+ if (!tab->is_sjm_nest() && (tab->table->map & checked_deps) &&
+ !tab->emb_sj_nest &&
+ tab->records_read != 0)
+ {
+ fanout *= rows2double(tab->records_read);
+ }
+ }
+ return fanout;
+}
+
+
+#if 0
+void check_out_index_stats(JOIN *join)
+{
+ ORDER *order;
+ uint n_order_items;
+
+ /*
+ First, collect the keys that we can use in each table.
+ We can use a key if
+ - all tables refer to it.
+ */
+ key_map key_start_use[MAX_TABLES];
+ key_map key_infix_use[MAX_TABLES];
+ table_map key_used=0;
+ table_map non_key_used= 0;
+
+ bzero(&key_start_use, sizeof(key_start_use)); //psergey-todo: safe initialization!
+ bzero(&key_infix_use, sizeof(key_infix_use));
+
+ for (order= join->group_list; order; order= order->next)
+ {
+ Item *item= order->item[0];
+
+ if (item->real_type() == Item::FIELD_ITEM)
+ {
+ if (item->used_tables() & OUTER_REF_TABLE_BIT)
+ continue; /* outside references are like constants for us */
+
+ Field *field= ((Item_field*)item->real_item())->field;
+ uint table_no= field->table->tablenr;
+ if (!(non_key_used && table_map(1) << table_no) &&
+ !field->part_of_key.is_clear_all())
+ {
+ key_map infix_map= field->part_of_key;
+ infix_map.subtract(field->key_start);
+ key_start_use[table_no].merge(field->key_start);
+ key_infix_use[table_no].merge(infix_map);
+ key_used |= table_no;
+ }
+ continue;
+ }
+ /*
+ Note: the below will cause clauses like GROUP BY YEAR(date) not to be
+ handled.
+ */
+ non_key_used |= item->used_tables();
+ }
+
+ Table_map_iterator tm_it(key_used & ~non_key_used);
+ int tableno;
+ while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END)
+ {
+ key_map::iterator key_it(key_start_use);
+ int keyno;
+ while ((keyno = tm_it.next_bit()) != key_map::iterator::BITMAP_END)
+ {
+ for (order= join->group_list; order; order= order->next)
+ {
+ Item *item= order->item[0];
+ if (item->used_tables() & (table_map(1) << tableno))
+ {
+ DBUG_ASSERT(item->real_type() == Item::FIELD_ITEM);
+ }
+ }
+ /*
+ if (continuation)
+ {
+ walk through list and find which key parts are occupied;
+ // note that the above can't be made any faster.
+ }
+ else
+ use rec_per_key[0];
+
+ find out the cardinality.
+ check if cardinality decreases if we use it;
+ */
+ }
+ }
+}
+#endif
+
+
+/*
+ Get an estimate of how many records will be produced after the GROUP BY
+ operation.
+
+ @param join Join we're operating on
+ @param join_op_rows How many records will be produced by the join
+ operations (this is what join optimizer produces)
+
+ @seealso
+ See also optimize_semijoin_nests(), grep for "Adjust output cardinality
+ estimates". Very similar code there that is not joined with this one
+ because we operate on different data structs and too much effort is
+ needed to abstract them out.
+
+ @return
+ Number of records we expect to get after the GROUP BY operation
+*/
+
+double get_post_group_estimate(JOIN* join, double join_op_rows)
+{
+ table_map tables_in_group_list= table_map(0);
+
+ /* Find out which tables are used in GROUP BY list */
+ for (ORDER *order= join->group_list; order; order= order->next)
+ {
+ Item *item= order->item[0];
+ if (item->used_tables() & RAND_TABLE_BIT)
+ {
+ /* Each join output record will be in its own group */
+ return join_op_rows;
+ }
+ tables_in_group_list|= item->used_tables();
+ }
+ tables_in_group_list &= ~PSEUDO_TABLE_BITS;
+
+ /*
+ Use join fanouts to calculate the max. number of records in the group-list
+ */
+ double fanout_rows[MAX_KEY];
+ bzero(&fanout_rows, sizeof(fanout_rows));
+ double out_rows;
+
+ out_rows= get_fanout_with_deps(join, tables_in_group_list);
+
+#if 0
+ /* The following will be needed when making use of index stats: */
+ /*
+ Also generate max. number of records for each of the tables mentioned
+ in the group-list. We'll use that a baseline number that we'll try to
+ reduce by using
+ - #table-records
+ - index statistics.
+ */
+ Table_map_iterator tm_it(tables_in_group_list);
+ int tableno;
+ while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END)
+ {
+ fanout_rows[tableno]= get_fanout_with_deps(join, table_map(1) << tableno);
+ }
+
+ /*
+ Try to bring down estimates using index statistics.
+ */
+ //check_out_index_stats(join);
+#endif
+
+ return out_rows;
+}
+
+
+/**
+ 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;
+ /* The subquery should be optimized, and materialized only once. */
+ DBUG_ASSERT(materialize_join->optimized && !is_materialized);
+ materialize_join->exec();
+ if ((res= test(materialize_join->error || thd->is_fatal_error ||
+ thd->is_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)
+ {
+ /* The value of IN will not change during this execution. */
+ item_in->reset();
+ item_in->make_const();
+ item_in->set_first_execution();
+ 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= NULL; /* Key parts of the only non-NULL index. */
+ uint count_non_null_columns= 0; /* Number of columns in nn_key_parts. */
+ bool has_covering_null_row;
+ bool has_covering_null_columns;
+ select_materialize_with_stats *result_sink=
+ (select_materialize_with_stats *) result;
+ uint field_count= tmp_table->s->fields;
+
+ if (count_partial_match_columns < field_count)
+ {
+ nn_key_parts= &non_null_key_parts;
+ count_non_null_columns= bitmap_bits_set(nn_key_parts);
+ }
+ has_covering_null_row= (result_sink->get_max_nulls_in_row() == field_count);
+ has_covering_null_columns= (count_non_null_columns +
+ count_null_only_columns == field_count);
+
+ if (has_covering_null_row && has_covering_null_columns)
+ {
+ /*
+ The whole table consist of only NULL values. The result of IN is
+ a constant UNKNOWN.
+ */
+ DBUG_ASSERT(tmp_table->file->stats.records == 1);
+ item_in->value= 0;
+ item_in->null_value= 1;
+ item_in->make_const();
+ item_in->set_first_execution();
+ DBUG_RETURN(FALSE);
+ }
+
+ if (has_covering_null_row)
+ {
+ DBUG_ASSERT(count_partial_match_columns = field_count);
+ count_pm_keys= 0;
+ }
+ else if (has_covering_null_columns)
+ count_pm_keys= 1;
+ else
+ count_pm_keys= count_partial_match_columns - count_null_only_columns +
+ (nn_key_parts ? 1 : 0);
+
+ choose_partial_match_strategy(test(nn_key_parts),
+ has_covering_null_row,
+ &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,
+ has_covering_null_row,
+ has_covering_null_columns,
+ count_columns_with_nulls,
+ 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(),
+ has_covering_null_row,
+ has_covering_null_columns,
+ count_columns_with_nulls)))
+ {
+ /* 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,
+ bool temp __attribute__((unused)))
+{
+ 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);
+ key_columns= (Item_field**) thd->alloc(key_column_count *
+ sizeof(Item_field*));
+ compare_pred= (Item_func_lt**) thd->alloc(key_column_count *
+ sizeof(Item_func_lt*));
+
+ if (!key_columns || !compare_pred)
+ return TRUE; /* Revert to table scan partial match. */
+
+ for (uint i= 0; i < columns_to_index->n_bits; i++)
+ {
+ if (!bitmap_is_set(columns_to_index, i))
+ 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((size_t)(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, (uint)(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, (size_t) 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,
+ bool has_covering_null_row_arg,
+ bool has_covering_null_columns_arg,
+ uint count_columns_with_nulls_arg)
+ :subselect_engine(thd_arg, item_arg, result_arg),
+ tmp_table(tmp_table_arg), lookup_engine(engine_arg),
+ equi_join_conds(equi_join_conds_arg),
+ has_covering_null_row(has_covering_null_row_arg),
+ has_covering_null_columns(has_covering_null_columns_arg),
+ count_columns_with_nulls(count_columns_with_nulls_arg)
+{}
+
+
+int subselect_partial_match_engine::exec()
+{
+ Item_in_subselect *item_in= (Item_in_subselect *) item;
+ int lookup_res;
+
+ DBUG_ASSERT(!(item_in->left_expr_has_null() &&
+ item_in->is_top_level_item()));
+
+ if (!item_in->left_expr_has_null())
+ {
+ /* Try to find a matching row by index lookup. */
+ if (lookup_engine->copy_ref_key(false))
+ {
+ /* The result is FALSE based on the outer reference. */
+ item_in->value= 0;
+ item_in->null_value= 0;
+ return 0;
+ }
+ else
+ {
+ /* Search for a complete match. */
+ if ((lookup_res= lookup_engine->index_lookup()))
+ {
+ /* An error occured during lookup(). */
+ item_in->value= 0;
+ item_in->null_value= 0;
+ return lookup_res;
+ }
+ else if (item_in->value || !count_columns_with_nulls)
+ {
+ /*
+ A complete match was found, the result of IN is TRUE.
+ If no match was found, and there are no NULLs in the materialized
+ subquery, then the result is guaranteed to be false because this
+ branch is executed when the outer reference has no NULLs as well.
+ Notice: (this->item == lookup_engine->item)
+ */
+ return 0;
+ }
+ }
+ }
+
+ if (has_covering_null_row)
+ {
+ /*
+ 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.
+
+ @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 (merge_keys_count == 0)
+ {
+ DBUG_ASSERT(bitmap_bits_set(partial_match_key_parts) == 0 ||
+ has_covering_null_row);
+ /* There is nothing to initialize, we will only do regular lookups. */
+ return FALSE;
+ }
+
+ /*
+ If all nullable columns contain only NULLs, there must be one index
+ over all non-null columns.
+ */
+ DBUG_ASSERT(!has_covering_null_columns ||
+ (has_covering_null_columns &&
+ merge_keys_count == 1 && non_null_key_parts));
+ /*
+ Allocate buffers to hold the merged keys and the mapping between rowids and
+ row numbers. All small buffers are allocated in the runtime memroot. Big
+ buffers are allocated from the OS via malloc.
+ */
+ if (!(merge_keys= (Ordered_key**) thd->alloc(merge_keys_count *
+ sizeof(Ordered_key*))) ||
+ !(null_bitmaps= (MY_BITMAP**) thd->alloc(merge_keys_count *
+ sizeof(MY_BITMAP*))) ||
+ !(row_num_to_rowid= (uchar*) my_malloc((size_t)(row_count * rowid_length),
+ MYF(MY_WME))))
+ return TRUE;
+
+ /* 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 all nullable columns contain NULLs, the only key that is needed is the
+ only non-NULL key that is already created above.
+ */
+ if (!has_covering_null_columns)
+ {
+ if (bitmap_init_memroot(&matching_keys, merge_keys_count, thd->mem_root) ||
+ bitmap_init_memroot(&matching_outer_cols, merge_keys_count, thd->mem_root))
+ return TRUE;
+
+ /*
+ 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++)
+ {
+ /* Skip columns that have no NULLs, or contain only NULLs. */
+ if (!bitmap_is_set(partial_match_key_parts, i) ||
+ result_sink->get_null_count_of_col(i) == row_count)
+ continue;
+
+ 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 == merge_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 < merge_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, merge_keys_count, sizeof(Ordered_key*),
+ (qsort_cmp) cmp_keys_by_null_selectivity);
+
+ /* Sort the keys in each of the indexes. */
+ for (uint i= 0; i < merge_keys_count; i++)
+ merge_keys[i]->sort_keys();
+
+ if (init_queue(&pq, merge_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 (merge_keys_count)
+ {
+ my_free((char*) row_num_to_rowid, MYF(0));
+ for (uint i= 0; i < merge_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.
+
+ @note
+ There is no need to check the columns that contain only NULLs, because
+ those are guaranteed to match.
+
+ @retval TRUE if a NULL row exists
+ @retval FALSE otherwise
+*/
+
+bool subselect_rowid_merge_engine::test_null_row(rownum_t row_num)
+{
+ Ordered_key *cur_key;
+ for (uint i = 0; i < merge_keys_count; i++)
+ {
+ cur_key= merge_keys[i];
+ if (bitmap_is_set(&matching_keys, cur_key->get_keyid()))
+ {
+ /*
+ The key 'i' (with id 'cur_keyid') already matches a value in row
+ 'row_num', thus we skip it as it can't possibly match a NULL.
+ */
+ continue;
+ }
+ if (!cur_key->is_null(row_num))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/**
+ Test if a subset of NULL-able columns contains a row of NULLs.
+ @retval TRUE if such a row exists
+ @retval FALSE no complementing null row
+*/
+
+bool subselect_rowid_merge_engine::
+exists_complementing_null_row(MY_BITMAP *keys_to_complement)
+{
+ rownum_t highest_min_row= 0;
+ rownum_t lowest_max_row= UINT_MAX;
+ uint count_null_keys, i;
+ Ordered_key *cur_key;
+
+ if (!count_columns_with_nulls)
+ {
+ /*
+ If there are both NULLs and non-NUll values in the outer reference, and
+ the subquery contains no NULLs, a complementing NULL row cannot exist.
+ */
+ return FALSE;
+ }
+
+ for (i= (non_null_key ? 1 : 0), count_null_keys= 0; i < merge_keys_count; i++)
+ {
+ cur_key= merge_keys[i];
+ if (bitmap_is_set(keys_to_complement, cur_key->get_keyid()))
+ continue;
+ if (!cur_key->get_null_count())
+ {
+ /* If there is column without NULLs, there cannot be a partial match. */
+ return FALSE;
+ }
+ if (cur_key->get_min_null_row() > highest_min_row)
+ highest_min_row= cur_key->get_min_null_row();
+ if (cur_key->get_max_null_row() < lowest_max_row)
+ lowest_max_row= cur_key->get_max_null_row();
+ null_bitmaps[count_null_keys++]= cur_key->get_null_key();
+ }
+
+ if (lowest_max_row < highest_min_row)
+ {
+ /* The intersection of NULL rows is empty. */
+ return FALSE;
+ }
+
+ return bitmap_exists_intersection((const MY_BITMAP**) null_bitmaps,
+ count_null_keys,
+ (uint)highest_min_row, (uint)lowest_max_row);
+}
+
+
+/*
+ @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;
+ uint max_null_in_any_row=
+ ((select_materialize_with_stats *) result)->get_max_nulls_in_row();
+ bool res= FALSE;
+
+ /* If there is a non-NULL key, it must be the first key in the keys array. */
+ 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 all nullable columns contain only NULLs, then there is a guranteed
+ partial match, and we don't need to search for a matching row.
+ */
+ if (has_covering_null_columns)
+ {
+ res= TRUE;
+ goto end;
+ }
+
+ 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 < merge_keys_count; i++)
+ {
+ DBUG_ASSERT(merge_keys[i]->get_column_count() == 1);
+ if (merge_keys[i]->get_search_key(0)->null_value)
+ {
+ ++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 (above we guarantee there is a match for the non-null
+ coumns), the result is UNKNOWN.
+ */
+ if (count_nulls_in_search_key == merge_keys_count - test(non_null_key))
+ {
+ res= TRUE;
+ goto end;
+ }
+
+ /*
+ If the outer row has NULLs in some columns, and
+ there is no match for any of the remaining columns, and
+ there is a subquery row with NULLs in all unmatched columns,
+ then there is a partial match, otherwise the result is FALSE.
+ */
+ if (count_nulls_in_search_key && !pq.elements)
+ {
+ DBUG_ASSERT(!non_null_key);
+ /*
+ Check if the intersection of all NULL bitmaps of all keys that
+ are not in matching_outer_cols is non-empty.
+ */
+ res= exists_complementing_null_row(&matching_outer_cols);
+ goto end;
+ }
+
+ /*
+ If there is no NULL (sub)row that covers all NULL columns, and there is no
+ match for any of the NULL columns, the result is FALSE. Notice that if there
+ is a non-null key, and there is only one matching key, the non-null key is
+ the matching key. This is so, because this method returns FALSE if the
+ non-null key doesn't have a match.
+ */
+ if (!count_nulls_in_search_key &&
+ (!pq.elements ||
+ (pq.elements == 1 && non_null_key &&
+ max_null_in_any_row < merge_keys_count-1)))
+ {
+ if (!pq.elements)
+ {
+ DBUG_ASSERT(!non_null_key);
+ /*
+ The case of a covering null row is handled by
+ subselect_partial_match_engine::exec()
+ */
+ DBUG_ASSERT(max_null_in_any_row != tmp_table->s->fields);
+ }
+ res= FALSE;
+ goto end;
+ }
+
+ DBUG_ASSERT(pq.elements);
+
+ min_key= (Ordered_key*) queue_remove_top(&pq);
+ min_row_num= min_key->current();
+ 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_clear_all(&matching_keys);
+ 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:
+ if (!has_covering_null_columns)
+ bitmap_clear_all(&matching_keys);
+ 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,
+ bool has_covering_null_row_arg,
+ bool has_covering_null_columns_arg,
+ uint count_columns_with_nulls_arg)
+ :subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, item_arg,
+ result_arg, equi_join_conds_arg,
+ has_covering_null_row_arg,
+ has_covering_null_columns_arg,
+ count_columns_with_nulls_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);
+ 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 b6b9750b910..d75e415c347 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -24,24 +24,21 @@
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 */
class Item_subselect :public Item_result_field
{
- bool value_assigned; /* value already assigned to subselect */
+ bool value_assigned; /* value already assigned to subselect */
+ bool own_engine; /* the engine was not taken from other Item_subselect */
protected:
/* thread handler, will be assigned in fix_fields only */
THD *thd;
- /* substitution instead of subselect in case of optimization */
- Item *substitution;
- /* unit of subquery */
- st_select_lex_unit *unit;
- /* engine that perform execution of subselect (single select or union) */
- subselect_engine *engine;
/* old engine if engine was changed */
subselect_engine *old_engine;
/* cache of used external tables */
@@ -55,13 +52,62 @@ protected:
/* cache of constant state */
bool const_item_cache;
+ bool inside_first_fix_fields;
+ bool done_first_fix_fields;
+ Item *expr_cache;
+ /*
+ Set to TRUE if at optimization or execution time we determine that this
+ item's value is a constant. We need this member because it is not possible
+ to substitute 'this' with a constant item.
+ */
+ bool forced_const;
+#ifndef DBUG_OFF
+ /* Count the number of times this subquery predicate has been executed. */
+ uint exec_counter;
+#endif
public:
/*
- References from inside the subquery to the select that this predicate is
- in. References to parent selects not included.
+ 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;
+ substitution= NULL;
+ < Item_subselect::fix_fields
+ */
+ /* TODO make this protected member again. */
+ Item *substitution;
+ /* engine that perform execution of subselect (single select or union) */
+ /* TODO make this protected member again. */
+ subselect_engine *engine;
+ /* unit of subquery */
+ st_select_lex_unit *unit;
+ /* A reference from inside subquery predicate to somewhere outside of it */
+ class Ref_to_outside : public Sql_alloc
+ {
+ 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;
+
+ /*
+ 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 */
@@ -72,21 +118,26 @@ public:
/* TRUE <=> The underlying SELECT is correlated w.r.t some ancestor select */
bool is_correlated;
- enum trans_res {RES_OK, RES_REDUCE, RES_ERROR};
enum subs_type {UNKNOWN_SUBS, SINGLEROW_SUBS,
EXISTS_SUBS, IN_SUBS, ALL_SUBS, ANY_SUBS};
Item_subselect();
virtual subs_type substype() { return UNKNOWN_SUBS; }
+ bool is_in_predicate()
+ {
+ return (substype() == Item_subselect::IN_SUBS ||
+ substype() == Item_subselect::ALL_SUBS ||
+ substype() == Item_subselect::ANY_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();
@@ -95,7 +146,12 @@ public:
eliminated= FALSE;
null_value= 1;
}
- virtual trans_res select_transformer(JOIN *join);
+ /**
+ Set the subquery result to a default value consistent with the semantics of
+ the result row produced for queries with implicit grouping.
+ */
+ void no_rows_in_result()= 0;
+ virtual bool select_transformer(JOIN *join);
bool assigned() { return value_assigned; }
void assigned(bool a) { value_assigned= a; }
enum Type type() const;
@@ -105,13 +161,25 @@ 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();
+ /*
+ If subquery optimization or execution determines that the subquery has
+ an empty result, mark the subquery predicate as a constant value.
+ */
+ void make_const()
+ {
+ used_tables_cache= 0;
+ const_item_cache= 0;
+ forced_const= TRUE;
+ }
virtual void fix_length_and_dec();
table_map used_tables() const;
table_map not_null_tables() const { return 0; }
bool const_item() const;
inline table_map get_used_tables_cache() { return used_tables_cache; }
- inline bool get_const_item_cache() { return const_item_cache; }
Item *get_tmp_table_item(THD *thd);
void update_used_tables();
virtual void print(String *str, enum_query_type query_type);
@@ -129,6 +197,7 @@ public:
*/
bool is_evaluated() const;
bool is_uncacheable() const;
+ bool is_expensive() { return TRUE; }
/*
Used by max/min subquery to initialize value presence registration
@@ -138,11 +207,23 @@ public:
enum_parsing_place place() { return parsing_place; }
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
bool mark_as_eliminated_processor(uchar *arg);
+ bool eliminate_subselect_processor(uchar *arg);
+ bool set_fake_select_as_master_processor(uchar *arg);
bool enumerate_field_refs_processor(uchar *arg);
bool check_vcol_func_processor(uchar *int_arg)
{
return trace_unsupported_by_check_vcol_func_processor("subselect");
}
+ /**
+ Callback to test if an IN predicate is expensive.
+
+ @notes
+ The return value affects the behavior of make_cond_for_table().
+
+ @retval TRUE if the predicate is expensive
+ @retval FALSE otherwise
+ */
+ bool is_expensive_processor(uchar *arg) { return TRUE; }
/**
Get the SELECT_LEX structure associated with this Item.
@@ -150,8 +231,15 @@ public:
*/
st_select_lex* get_select_lex();
const char *func_name() const { DBUG_ASSERT(0); return "subselect"; }
+ virtual bool expr_cache_is_needed(THD *);
+ virtual void get_cache_parameters(List<Item> &parameters);
+ virtual bool is_subquery_processor (uchar *opt_arg) { return 1; }
+ bool limit_index_condition_pushdown_processor(uchar *opt_arg)
+ {
+ return TRUE;
+ }
- 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 **);
@@ -159,6 +247,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 */
@@ -170,19 +260,22 @@ 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; }
void reset();
- trans_res select_transformer(JOIN *join);
+ void no_rows_in_result();
+ bool select_transformer(JOIN *join);
void store(uint i, Item* item);
double val_real();
longlong val_int ();
String *val_str (String *);
my_decimal *val_decimal(my_decimal *);
bool val_bool();
+ bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
enum Item_result result_type() const;
enum_field_types field_type() const;
void fix_length_and_dec();
@@ -208,6 +301,8 @@ public:
*/
st_select_lex* invalidate_and_restore_select_lex();
+ Item* expr_cache_insert_transformer(uchar *thd_arg);
+
friend class select_singlerow_subselect;
};
@@ -226,6 +321,7 @@ public:
bool any_value() { return was_values; }
void register_value() { was_values= TRUE; }
void reset_value_registration() { was_values= FALSE; }
+ void no_rows_in_result();
};
/* exists subselect */
@@ -235,6 +331,8 @@ class Item_exists_subselect :public Item_subselect
protected:
bool value; /* value of this item (boolean: exists/not-exists) */
+ void init_length_and_dec();
+
public:
Item_exists_subselect(st_select_lex *select_lex);
Item_exists_subselect(): Item_subselect() {}
@@ -245,6 +343,7 @@ public:
eliminated= FALSE;
value= 0;
}
+ void no_rows_in_result();
enum Item_result result_type() const { return INT_RESULT;}
longlong val_int();
@@ -255,20 +354,45 @@ 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 ...)"
+TABLE_LIST * const NO_JOIN_NEST=(TABLE_LIST*)0x1;
+/*
+ Possible methods to execute an IN predicate. These are set by the optimizer
+ based on user-set optimizer switches, semantic analysis and cost comparison.
+*/
+#define SUBS_NOT_TRANSFORMED 0 /* No execution method was chosen for this IN. */
+/* The Final decision about the strategy is made. */
+#define SUBS_STRATEGY_CHOSEN 1
+#define SUBS_SEMI_JOIN 2 /* IN was converted to semi-join. */
+#define SUBS_IN_TO_EXISTS 4 /* IN was converted to correlated EXISTS. */
+#define SUBS_MATERIALIZATION 8 /* Execute IN via subquery materialization. */
+/* Partial matching substrategies of MATERIALIZATION. */
+#define SUBS_PARTIAL_MATCH_ROWID_MERGE 16
+#define SUBS_PARTIAL_MATCH_TABLE_SCAN 32
+/* ALL/ANY will be transformed with max/min optimization */
+/* The subquery has not aggregates, transform it into a MAX/MIN query. */
+#define SUBS_MAXMIN_INJECTED 64
+/* The subquery has aggregates, use a special max/min subselect engine. */
+#define SUBS_MAXMIN_ENGINE 128
+
+
+/**
+ 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
@@ -278,20 +402,125 @@ public:
class Item_in_subselect :public Item_exists_subselect
{
protected:
- Item *left_expr;
+ /*
+ 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;
+
/*
expr & optimizer used in subselect rewriting to store Item for
all JOIN in UNION
*/
Item *expr;
- Item_in_optimizer *optimizer;
bool was_null;
bool abort_on_null;
- bool transformed;
+ /* A bitmap of possible execution strategies for an IN predicate. */
+ uchar in_strategy;
public:
+ Item_in_optimizer *optimizer;
+protected:
/* Used to trigger on/off conditions that were pushed down to subselect */
bool *pushed_cond_guards;
+ Comp_creator *func;
+
+protected:
+ bool init_cond_guards();
+ bool select_in_like_transformer(JOIN *join);
+ bool single_value_transformer(JOIN *join);
+ bool row_value_transformer(JOIN * join);
+ bool fix_having(Item *having, st_select_lex *select_lex);
+ bool create_single_in_to_exists_cond(JOIN * join,
+ Item **where_item,
+ Item **having_item);
+ bool create_row_in_to_exists_cond(JOIN * join,
+ Item **where_item,
+ Item **having_item);
+public:
+ Item *left_expr;
+ /* 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:
+ NO_JOIN_NEST - 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
+ */
+ TABLE_LIST *emb_on_expr_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;
+
+ /*
+ JoinTaB Materialization (JTBM) members
+ */
+
+ /*
+ TRUE <=> This subselect has been converted into non-mergeable semi-join
+ table.
+ */
+ bool is_jtbm_merged;
+
+ /* (Applicable if is_jtbm_merged==TRUE) Time required to run the materialized join */
+ double jtbm_read_time;
+
+ /* (Applicable if is_jtbm_merged==TRUE) Number of output rows in materialized join */
+ double jtbm_record_count;
+
+ /*
+ (Applicable if is_jtbm_merged==TRUE) TRUE <=> The materialized subselect is
+ a degenerate subselect which produces 0 or 1 rows, which we know at
+ optimization phase.
+ Examples:
+ 1. subquery has "Impossible WHERE":
+ SELECT * FROM ot WHERE ot.column IN (SELECT it.col FROM it WHERE 2 > 3)
+
+ 2. Subquery produces one row which opt_sum.cc is able to get with one lookup:
+
+ SELECT * FROM ot WHERE ot.column IN (SELECT MAX(it.key_col) FROM it)
+ */
+ bool is_jtbm_const_tab;
+
+ /*
+ (Applicable if is_jtbm_const_tab==TRUE) Whether the subquery has produced
+ the row (or not)
+ */
+ bool jtbm_const_row_found;
+
+ /*
+ TRUE<=>this is a flattenable semi-join, false overwise.
+ */
+ bool is_flattenable_semijoin;
+
+ /*
+ TRUE<=>registered in the list of semijoins in outer select
+ */
+ bool is_registered_semijoin;
+
+ /*
+ Used to determine how this subselect item is represented in the item tree,
+ in case there is a need to locate it there and replace with something else.
+ Two options are possible:
+ 1. This item is there 'as-is'.
+ 1. This item is wrapped within Item_in_optimizer.
+ */
+ Item *original_item()
+ {
+ return is_flattenable_semijoin ? (Item*)this : (Item*)optimizer;
+ }
+
bool *get_cond_guard(int i)
{
return pushed_cond_guards ? pushed_cond_guards + i : NULL;
@@ -307,10 +536,13 @@ 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),
+ abort_on_null(0), in_strategy(SUBS_NOT_TRANSFORMED), optimizer(0),
+ pushed_cond_guards(NULL), func(NULL), emb_on_expr_nest(NULL),
+ is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE),
+ upper_item(0)
+ {}
+ void cleanup();
subs_type substype() { return IN_SUBS; }
void reset()
{
@@ -319,10 +551,11 @@ public:
null_value= 0;
was_null= 0;
}
- trans_res select_transformer(JOIN *join);
- 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);
+ bool select_transformer(JOIN *join);
+ bool create_in_to_exists_cond(JOIN *join_arg);
+ bool inject_in_to_exists_cond(JOIN *join_arg);
+
+ virtual bool exec();
longlong val_int();
double val_real();
String *val_str(String*);
@@ -334,11 +567,92 @@ 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_length_and_dec();
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void update_used_tables();
+ bool setup_mat_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 expr_cache_is_needed(THD *thd);
inline bool left_expr_has_null();
+
+ int optimize(double *out_rows, double *cost);
+ /*
+ Return the identifier that we could use to identify the subquery for the
+ user.
+ */
+ int get_identifier();
+
+ void mark_as_condition_AND_part(TABLE_LIST *embedding)
+ {
+ emb_on_expr_nest= embedding;
+ }
+
+ bool test_strategy(uchar strategy)
+ { return test(in_strategy & strategy); }
+
+ /**
+ Test that the IN strategy was chosen for execution. This is so
+ when the CHOSEN flag is ON, and there is no other strategy.
+ */
+ bool test_set_strategy(uchar strategy)
+ {
+ DBUG_ASSERT(strategy == SUBS_SEMI_JOIN ||
+ strategy == SUBS_IN_TO_EXISTS ||
+ strategy == SUBS_MATERIALIZATION ||
+ strategy == SUBS_PARTIAL_MATCH_ROWID_MERGE ||
+ strategy == SUBS_PARTIAL_MATCH_TABLE_SCAN ||
+ strategy == SUBS_MAXMIN_INJECTED ||
+ strategy == SUBS_MAXMIN_ENGINE);
+ return ((in_strategy & SUBS_STRATEGY_CHOSEN) &&
+ (in_strategy & ~SUBS_STRATEGY_CHOSEN) == strategy);
+ }
+
+ bool is_set_strategy()
+ { return test(in_strategy & SUBS_STRATEGY_CHOSEN); }
+
+ bool has_strategy()
+ { return in_strategy != SUBS_NOT_TRANSFORMED; }
+
+ void add_strategy (uchar strategy)
+ {
+ DBUG_ASSERT(strategy != SUBS_NOT_TRANSFORMED);
+ DBUG_ASSERT(!(strategy & SUBS_STRATEGY_CHOSEN));
+ /*
+ TODO: PS re-execution breaks this condition, because
+ check_and_do_in_subquery_rewrites() is called for each reexecution
+ and re-adds the same strategies.
+ DBUG_ASSERT(!(in_strategy & SUBS_STRATEGY_CHOSEN));
+ */
+ in_strategy|= strategy;
+ }
+
+ void reset_strategy(uchar strategy)
+ {
+ DBUG_ASSERT(strategy != SUBS_NOT_TRANSFORMED);
+ in_strategy= strategy;
+ }
+
+ void set_strategy(uchar strategy)
+ {
+ /* Check that only one strategy is set for execution. */
+ DBUG_ASSERT(strategy == SUBS_SEMI_JOIN ||
+ strategy == SUBS_IN_TO_EXISTS ||
+ strategy == SUBS_MATERIALIZATION ||
+ strategy == SUBS_PARTIAL_MATCH_ROWID_MERGE ||
+ strategy == SUBS_PARTIAL_MATCH_TABLE_SCAN ||
+ strategy == SUBS_MAXMIN_INJECTED ||
+ strategy == SUBS_MAXMIN_ENGINE);
+ in_strategy= (SUBS_STRATEGY_CHOSEN | strategy);
+ }
friend class Item_ref_null_helper;
friend class Item_is_not_null_test;
+ friend class Item_in_optimizer;
friend class subselect_indexsubquery_engine;
+ friend class subselect_hash_sj_engine;
+ friend class subselect_partial_match_engine;
};
@@ -347,23 +661,27 @@ class Item_allany_subselect :public Item_in_subselect
{
public:
chooser_compare_func_creator func_creator;
- Comp_creator *func;
bool all;
Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc,
st_select_lex *select_lex, bool all);
+ void cleanup();
// only ALL subquery has upper not
subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
- trans_res select_transformer(JOIN *join);
+ bool select_transformer(JOIN *join);
+ void create_comp_func(bool invert) { func= func_creator(invert); }
virtual void print(String *str, enum_query_type query_type);
+ bool is_maxmin_applicable(JOIN *join);
+ bool transform_into_max_min(JOIN *join);
+ void no_rows_in_result();
};
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 */
@@ -371,14 +689,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;
@@ -420,13 +744,17 @@ public:
virtual bool may_be_null() { return maybe_null; };
virtual table_map upper_select_const_tables()= 0;
static table_map calc_const_tables(TABLE_LIST *);
+ static table_map calc_const_tables(List<TABLE_LIST> &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,
+ bool temp= FALSE)= 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);
};
@@ -435,14 +763,13 @@ protected:
class subselect_single_select_engine: public subselect_engine
{
bool prepared; /* simple subselect is prepared */
- bool optimized; /* simple subselect is optimized */
bool executed; /* simple subselect is executed */
bool optimize_error; /* simple subselect optimization failed */
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();
@@ -453,11 +780,21 @@ 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 temp);
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;
+ friend bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
+ Item **join_where);
+
};
@@ -465,8 +802,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();
@@ -477,10 +814,13 @@ 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 temp= FALSE);
bool no_tables();
bool is_executed() const;
bool no_rows();
+ virtual enum_engine_type engine_type() { return UNION_ENGINE; }
};
@@ -519,25 +859,27 @@ 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();
void fix_length_and_dec(Item_cache** row);
int exec();
uint cols() { return 1; }
- uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; }
+ uint8 uncacheable() { return UNCACHEABLE_DEPENDENT_INJECTED; }
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 temp= FALSE);
bool no_tables();
+ int index_lookup(); /* TIMOUR: this method needs refactoring. */
int scan_table();
- bool copy_ref_key();
+ bool copy_ref_key(bool skip_constants);
bool no_rows() { return empty_result_set; }
+ virtual enum_engine_type engine_type() { return UNIQUESUBQUERY_ENGINE; }
};
@@ -587,6 +929,7 @@ public:
{}
int exec();
virtual void print (String *str, enum_query_type query_type);
+ virtual enum_engine_type engine_type() { return INDEXSUBQUERY_ENGINE; }
};
@@ -595,9 +938,471 @@ 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
+{
+public:
+ /* 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;
+ /*
+ QEP to execute the subquery and materialize its result into a
+ temporary table. Created during the first call to exec().
+ */
+ JOIN *materialize_join;
+ /*
+ 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;
+ Name_resolution_context *semi_join_conds_context;
+
+
+ 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),
+ materialize_join(NULL), semi_join_conds(NULL), lookup_engine(NULL),
+ count_partial_match_columns(0), count_null_only_columns(0),
+ count_columns_with_nulls(0), strategy(UNDEFINED)
+ {}
+ ~subselect_hash_sj_engine();
+
+ bool init(List<Item> *tmp_columns, uint subquery_id);
+ void cleanup();
+ int prepare();
+ 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 temp= FALSE);
+ bool no_tables();//=>base class
+
+protected:
+ /* The engine used to compute the IN predicate. */
+ subselect_engine *lookup_engine;
+ /* 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;
+ uint count_columns_with_nulls;
+ /* 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;
+ 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();
+
+};
+
+
+/*
+ Distinguish the type of (0-based) row numbers from the type of the index into
+ an array of row numbers.
+*/
+typedef ha_rows rownum_t;
+
+
+/*
+ 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. */
+ rownum_t min_null_row;
+ /* The row number that contains the last NULL in a column. */
+ rownum_t 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;
+ }
+ rownum_t get_min_null_row() { return min_null_row; }
+ rownum_t get_max_null_row() { return max_null_row; }
+ MY_BITMAP * get_null_key() { return &null_key; }
+ ha_rows get_null_count() { return null_count; }
+ /*
+ Get the search key element that corresponds to the i-th key part of this
+ index.
+ */
+ 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, (uint)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, (uint)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;
+ /*
+ True if there is an all NULL row in tmp_table. If so, then if there is
+ no complete match, there is a guaranteed partial match.
+ */
+ bool has_covering_null_row;
+
+ /*
+ True if all nullable columns of tmp_table consist of only NULL values.
+ If so, then if there is a match in the non-null columns, there is a
+ guaranteed partial match.
+ */
+ bool has_covering_null_columns;
+ uint count_columns_with_nulls;
+
+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,
+ bool has_covering_null_row_arg,
+ bool has_covering_null_columns_arg,
+ uint count_columns_with_nulls_arg);
+ int prepare() { return 0; }
+ int exec();
+ void fix_length_and_dec(Item_cache**) {}
+ 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*,
+ bool temp= FALSE)
+ { 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;
+ /*
+ 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 merge_keys. */
+ uint merge_keys_count;
+ /* The NULL bitmaps of merge keys.*/
+ MY_BITMAP **null_bitmaps;
+ /*
+ An index on all non-NULL columns of 'tmp_table'. The index has the
+ logical form: <[v_i1 | ... | v_ik], rownum>. It allows to find the row
+ 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 'merge_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 exists_complementing_null_row(MY_BITMAP *keys_to_complement);
+ bool partial_match();
+public:
+ subselect_rowid_merge_engine(THD *thd_arg,
+ subselect_uniquesubquery_engine *engine_arg,
+ TABLE *tmp_table_arg, uint merge_keys_count_arg,
+ bool has_covering_null_row_arg,
+ bool has_covering_null_columns_arg,
+ uint count_columns_with_nulls_arg,
+ Item_subselect *item_arg,
+ select_result_interceptor *result_arg,
+ List<Item> *equi_join_conds_arg)
+ :subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg,
+ item_arg, result_arg, equi_join_conds_arg,
+ has_covering_null_row_arg,
+ has_covering_null_columns_arg,
+ count_columns_with_nulls_arg),
+ merge_keys_count(merge_keys_count_arg), non_null_key(NULL)
+ {}
+ ~subselect_rowid_merge_engine();
+ bool init(MY_BITMAP *non_null_key_parts, MY_BITMAP *partial_match_key_parts);
+ 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,
+ bool has_covering_null_row_arg,
+ bool has_covering_null_columns_arg,
+ uint count_columns_with_nulls_arg);
+ void cleanup();
+ virtual enum_engine_type engine_type() { return TABLE_SCAN_ENGINE; }
+};
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 4e02b40ddba..b9c041c1a2e 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -351,7 +351,19 @@ 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;
+}
+
+
+bool Item_sum::collect_outer_ref_processor(uchar *param)
+{
+ Collect_deps_prm *prm= (Collect_deps_prm *)param;
+ SELECT_LEX *ds;
+ if ((ds= depended_from()) &&
+ ds->nest_level_base == prm->nest_level_base &&
+ ds->nest_level < prm->nest_level)
+ prm->parameters->add_unique(this, &cmp_items);
return FALSE;
}
@@ -415,6 +427,7 @@ void Item_sum::mark_as_sum_func()
cur_select->n_sum_items++;
cur_select->with_sum_func= 1;
with_sum_func= 1;
+ with_field= 0;
}
@@ -481,7 +494,7 @@ bool Item_sum::walk (Item_processor processor, bool walk_subquery,
Field *Item_sum::create_tmp_field(bool group, TABLE *table,
uint convert_blob_length)
{
- Field *field;
+ Field *UNINIT_VAR(field);
switch (result_type()) {
case REAL_RESULT:
field= new Field_double(max_length, maybe_null, name, decimals, TRUE);
@@ -501,7 +514,8 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table,
field= Field_new_decimal::create_from_item(this);
break;
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
return 0;
@@ -617,7 +631,8 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
max_length= float_length(decimals);
break;
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
};
setup_hybrid(args[0], NULL);
@@ -652,17 +667,31 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
Setup cache/comparator of MIN/MAX functions. When called by the
copy_or_same function value_arg parameter contains calculated value
of the original MIN/MAX object and it is saved in this object's cache.
+
+ We mark the value and arg_cache with 'RAND_TABLE_BIT' to ensure
+ that Arg_comparator::compare_datetime() doesn't allocate new
+ item inside of Arg_comparator. This would cause compare_datetime()
+ and Item_sum_min::add() to use different values!
*/
void Item_sum_hybrid::setup_hybrid(Item *item, Item *value_arg)
{
- value= Item_cache::get_cache(item);
+ if (!(value= Item_cache::get_cache(item)))
+ return;
value->setup(item);
value->store(value_arg);
- arg_cache= Item_cache::get_cache(item);
+ /* Don't cache value, as it will change */
+ if (!item->const_item())
+ value->set_used_tables(RAND_TABLE_BIT);
+ if (!(arg_cache= Item_cache::get_cache(item, item->cmp_type())))
+ return;
arg_cache->setup(item);
+ /* Don't cache value, as it will change */
+ if (!item->const_item())
+ arg_cache->set_used_tables(RAND_TABLE_BIT);
cmp= new Arg_comparator();
- cmp->set_cmp_func(this, (Item**)&arg_cache, (Item**)&value, FALSE);
+ if (cmp)
+ cmp->set_cmp_func(this, (Item**)&arg_cache, (Item**)&value, FALSE);
collation.set(item->collation);
}
@@ -687,14 +716,17 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
*/
switch (args[0]->field_type()) {
case MYSQL_TYPE_DATE:
- field= new Field_newdate(maybe_null, name, collation.collation);
+ field= new Field_newdate(0, maybe_null ? (uchar*)"" : 0, 0, Field::NONE,
+ name, collation.collation);
break;
case MYSQL_TYPE_TIME:
- field= new Field_time(maybe_null, name, collation.collation);
+ field= new_Field_time(0, maybe_null ? (uchar*)"" : 0, 0, Field::NONE,
+ name, decimals, collation.collation);
break;
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME:
- field= new Field_datetime(maybe_null, name, collation.collation);
+ field= new_Field_datetime(0, maybe_null ? (uchar*)"" : 0, 0, Field::NONE,
+ name, decimals, collation.collation);
break;
default:
return Item_sum::create_tmp_field(group, table, convert_blob_length);
@@ -753,13 +785,14 @@ void Item_sum_sum::fix_length_and_dec()
DBUG_ENTER("Item_sum_sum::fix_length_and_dec");
maybe_null=null_value=1;
decimals= args[0]->decimals;
- switch (args[0]->result_type()) {
+ switch (args[0]->cast_to_int_type()) {
case REAL_RESULT:
case STRING_RESULT:
hybrid_type= REAL_RESULT;
sum= 0.0;
break;
case INT_RESULT:
+ case TIME_RESULT:
case DECIMAL_RESULT:
{
/* SUM result can't be longer than length(arg) + length(MAX_ROWS) */
@@ -773,7 +806,7 @@ void Item_sum_sum::fix_length_and_dec()
break;
}
case ROW_RESULT:
- default:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
DBUG_PRINT("info", ("Type: %s (%d, %d)",
@@ -962,7 +995,8 @@ void Item_sum_distinct::fix_length_and_dec()
table_field_type= MYSQL_TYPE_NEWDECIMAL;
break;
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
val.traits->fix_length_and_dec(this, args[0]);
@@ -1049,9 +1083,10 @@ bool Item_sum_distinct::unique_walk_function(void *element)
void Item_sum_distinct::clear()
{
DBUG_ENTER("Item_sum_distinct::clear");
- DBUG_ASSERT(tree != 0); /* we always have a tree */
+ /* During EXPLAIN there is no tree because it is created during execution. */
+ if (tree != 0)
+ tree->reset();
null_value= 1;
- tree->reset();
is_evaluated= FALSE;
DBUG_VOID_RETURN;
}
@@ -1413,7 +1448,8 @@ void Item_sum_variance::fix_length_and_dec()
break;
}
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
DBUG_PRINT("info", ("Type: REAL_RESULT (%d, %d)", max_length, (int)decimals));
@@ -1838,7 +1874,8 @@ void Item_sum_hybrid::reset_field()
break;
}
case ROW_RESULT:
- default:
+ case TIME_RESULT:
+ case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
}
@@ -2112,9 +2149,8 @@ Item_sum_hybrid::min_max_update_int_field()
void
Item_sum_hybrid::min_max_update_decimal_field()
{
- /* TODO: optimize: do not get result_field in case of args[0] is NULL */
my_decimal old_val, nr_val;
- const my_decimal *old_nr= result_field->val_decimal(&old_val);
+ const my_decimal *old_nr;
const my_decimal *nr= args[0]->val_decimal(&nr_val);
if (!args[0]->null_value)
{
@@ -2122,16 +2158,17 @@ Item_sum_hybrid::min_max_update_decimal_field()
old_nr=nr;
else
{
+ old_nr= result_field->val_decimal(&old_val);
bool res= my_decimal_cmp(old_nr, nr) > 0;
/* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */
if ((cmp_sign > 0) ^ (!res))
old_nr=nr;
}
result_field->set_notnull();
+ result_field->store_decimal(old_nr);
}
else if (result_field->is_null(0))
result_field->set_null();
- result_field->store_decimal(old_nr);
}
@@ -2563,7 +2600,7 @@ bool Item_sum_count_distinct::add()
*/
return tree->unique_add(table->record[0] + table->s->null_bytes);
}
- if ((error= table->file->ha_write_row(table->record[0])) &&
+ if ((error= table->file->ha_write_tmp_row(table->record[0])) &&
table->file->is_fatal_error(error, HA_CHECK_DUP))
return TRUE;
return FALSE;
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 3d4b00e3b52..c970dec5082 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -376,6 +376,7 @@ public:
virtual Field *create_tmp_field(bool group, TABLE *table,
uint convert_blob_length);
bool walk(Item_processor processor, bool walk_subquery, uchar *argument);
+ virtual bool collect_outer_ref_processor(uchar *param);
bool init_sum_func_check(THD *thd);
bool check_sum_func(THD *thd, Item **ref);
bool register_sum_func(THD *thd, Item **ref);
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 0d87c729286..9f2f9b2950d 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1,5 +1,6 @@
/*
Copyright (c) 2000, 2012, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2013, Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -37,193 +38,6 @@
/** Day number for Dec 31st, 9999. */
#define MAX_DAY_NUMBER 3652424L
-/**
- @todo
- OPTIMIZATION
- - Replace the switch with a function that should be called for each
- date type.
- - Remove sprintf and opencode the conversion, like we do in
- Field_datetime.
-
- The reason for this functions existence is that as we don't have a
- way to know if a datetime/time value has microseconds in them
- we are now only adding microseconds to the output if the
- value has microseconds.
-
- We can't use a standard make_date_time() for this as we don't know
- if someone will use %f in the format specifier in which case we would get
- the microseconds twice.
-*/
-
-static bool make_datetime(date_time_format_types format, MYSQL_TIME *ltime,
- String *str)
-{
- char *buff;
- CHARSET_INFO *cs= &my_charset_bin;
- uint length= MAX_DATE_STRING_REP_LENGTH;
-
- if (str->alloc(length))
- return 1;
- buff= (char*) str->ptr();
-
- switch (format) {
- case TIME_ONLY:
- length= cs->cset->snprintf(cs, buff, length, "%s%02d:%02d:%02d",
- ltime->neg ? "-" : "",
- ltime->hour, ltime->minute, ltime->second);
- break;
- case TIME_MICROSECOND:
- length= cs->cset->snprintf(cs, buff, length, "%s%02d:%02d:%02d.%06ld",
- ltime->neg ? "-" : "",
- ltime->hour, ltime->minute, ltime->second,
- ltime->second_part);
- break;
- case DATE_ONLY:
- length= cs->cset->snprintf(cs, buff, length, "%04d-%02d-%02d",
- ltime->year, ltime->month, ltime->day);
- break;
- case DATE_TIME:
- length= cs->cset->snprintf(cs, buff, length,
- "%04d-%02d-%02d %02d:%02d:%02d",
- ltime->year, ltime->month, ltime->day,
- ltime->hour, ltime->minute, ltime->second);
- break;
- case DATE_TIME_MICROSECOND:
- length= cs->cset->snprintf(cs, buff, length,
- "%04d-%02d-%02d %02d:%02d:%02d.%06ld",
- ltime->year, ltime->month, ltime->day,
- ltime->hour, ltime->minute, ltime->second,
- ltime->second_part);
- break;
- }
-
- str->length(length);
- str->set_charset(cs);
- return 0;
-}
-
-
-/*
- Wrapper over make_datetime() with validation of the input MYSQL_TIME value
-
- NOTE
- see make_datetime() for more information
-
- RETURN
- 1 if there was an error during converion
- 0 otherwise
-*/
-
-static bool make_datetime_with_warn(date_time_format_types format, MYSQL_TIME *ltime,
- String *str)
-{
- int warning= 0;
-
- if (make_datetime(format, ltime, str))
- return 1;
- if (check_time_range(ltime, &warning))
- return 1;
- if (!warning)
- return 0;
-
- make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- str->ptr(), str->length(),
- MYSQL_TIMESTAMP_TIME, NullS);
- return make_datetime(format, ltime, str);
-}
-
-
-/*
- Wrapper over make_time() with validation of the input MYSQL_TIME value
-
- NOTE
- see make_time() for more info
-
- RETURN
- 1 if there was an error during conversion
- 0 otherwise
-*/
-
-static bool make_time_with_warn(const DATE_TIME_FORMAT *format,
- MYSQL_TIME *l_time, String *str)
-{
- int warning= 0;
- make_time(format, l_time, str);
- if (check_time_range(l_time, &warning))
- return 1;
- if (warning)
- {
- make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- str->ptr(), str->length(),
- MYSQL_TIMESTAMP_TIME, NullS);
- make_time(format, l_time, str);
- }
-
- return 0;
-}
-
-
-/*
- Convert seconds to MYSQL_TIME value with overflow checking
-
- SYNOPSIS:
- sec_to_time()
- seconds number of seconds
- unsigned_flag 1, if 'seconds' is unsigned, 0, otherwise
- ltime output MYSQL_TIME value
-
- DESCRIPTION
- If the 'seconds' argument is inside MYSQL_TIME data range, convert it to a
- corresponding value.
- Otherwise, truncate the resulting value to the nearest endpoint, and
- produce a warning message.
-
- RETURN
- 1 if the value was truncated during conversion
- 0 otherwise
-*/
-
-static bool sec_to_time(longlong seconds, bool unsigned_flag, MYSQL_TIME *ltime)
-{
- uint sec;
-
- bzero((char *)ltime, sizeof(*ltime));
-
- if (seconds < 0)
- {
- if (unsigned_flag)
- goto overflow;
- ltime->neg= 1;
- if (seconds < -3020399)
- goto overflow;
- seconds= -seconds;
- }
- else if (seconds > 3020399)
- goto overflow;
-
- sec= (uint) ((ulonglong) seconds % 3600);
- ltime->hour= (uint) (seconds/3600);
- ltime->minute= sec/60;
- ltime->second= sec % 60;
-
- return 0;
-
-overflow:
- ltime->hour= TIME_MAX_HOUR;
- ltime->minute= TIME_MAX_MINUTE;
- ltime->second= TIME_MAX_SECOND;
-
- char buf[22];
- int len= (int)(longlong10_to_str(seconds, buf, unsigned_flag ? 10 : -10)
- - buf);
- make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- buf, len, MYSQL_TIMESTAMP_TIME,
- NullS);
-
- return 1;
-}
-
-
/*
Date formats corresponding to compound %r and %T conversion specifiers
@@ -272,7 +86,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
const char *val, uint length, MYSQL_TIME *l_time,
timestamp_type cached_timestamp_type,
const char **sub_pattern_end,
- const char *date_time_type)
+ const char *date_time_type,
+ uint fuzzy_date)
{
int weekday= 0, yearday= 0, daypart= 0;
int week_number= -1;
@@ -293,6 +108,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
if (!sub_pattern_end)
bzero((char*) l_time, sizeof(*l_time));
+ l_time->time_type= cached_timestamp_type;
+
for (; ptr != end && val != val_end; ptr++)
{
/* Skip pre-space between each argument */
@@ -466,7 +283,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
*/
if (extract_date_time(&time_ampm_format, val,
(uint)(val_end - val), l_time,
- cached_timestamp_type, &val, "time"))
+ cached_timestamp_type, &val, "time", fuzzy_date))
DBUG_RETURN(1);
break;
@@ -474,7 +291,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
case 'T':
if (extract_date_time(&time_24hrs_format, val,
(uint)(val_end - val), l_time,
- cached_timestamp_type, &val, "time"))
+ cached_timestamp_type, &val, "time", fuzzy_date))
DBUG_RETURN(1);
break;
@@ -525,9 +342,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
{
uint days;
days= calc_daynr(l_time->year,1,1) + yearday - 1;
- if (days <= 0 || days > MAX_DAY_NUMBER)
+ if (get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day))
goto err;
- get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day);
}
if (week_number >= 0 && weekday)
@@ -572,15 +388,18 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
(weekday - 1);
}
- if (days <= 0 || days > MAX_DAY_NUMBER)
+ if (get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day))
goto err;
- get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day);
}
if (l_time->month > 12 || l_time->day > 31 || l_time->hour > 23 ||
l_time->minute > 59 || l_time->second > 59)
goto err;
+ if ((fuzzy_date & TIME_NO_ZERO_DATE) &&
+ (l_time->year == 0 || l_time->month == 0 || l_time->day == 0))
+ goto err;
+
if (val != val_end)
{
do
@@ -933,7 +752,7 @@ longlong Item_func_to_days::val_int()
{
DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime;
- if (get_arg0_date(&ltime, TIME_NO_ZERO_DATE))
+ if (get_arg0_date(&ltime, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE))
return 0;
return (longlong) calc_daynr(ltime.year,ltime.month,ltime.day);
}
@@ -1027,7 +846,7 @@ longlong Item_func_dayofyear::val_int()
{
DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime;
- if (get_arg0_date(&ltime,TIME_NO_ZERO_DATE))
+ if (get_arg0_date(&ltime, TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE))
return 0;
return (longlong) calc_daynr(ltime.year,ltime.month,ltime.day) -
calc_daynr(ltime.year,1,1) + 1;
@@ -1059,7 +878,7 @@ void Item_func_monthname::fix_length_and_dec()
collation.set(cs, DERIVATION_COERCIBLE, repertoire);
decimals=0;
max_length= locale->max_month_name_length * collation.collation->mbmaxlen;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
@@ -1212,7 +1031,7 @@ void Item_func_dayname::fix_length_and_dec()
collation.set(cs, DERIVATION_COERCIBLE, repertoire);
decimals=0;
max_length= locale->max_day_name_length * collation.collation->mbmaxlen;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
@@ -1296,47 +1115,83 @@ longlong Item_func_year::val_int_endpoint(bool left_endp, bool *incl_endp)
}
-longlong Item_func_unix_timestamp::val_int()
+bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds,
+ ulong *second_part)
{
- MYSQL_TIME ltime;
- my_bool not_used;
-
DBUG_ASSERT(fixed == 1);
- if (arg_count == 0)
- return (longlong) current_thd->query_start();
if (args[0]->type() == FIELD_ITEM)
{ // Optimize timestamp field
Field *field=((Item_field*) args[0])->field;
if (field->type() == MYSQL_TYPE_TIMESTAMP)
- return ((Field_timestamp*) field)->get_timestamp(&null_value);
+ {
+ if ((null_value= field->is_null()))
+ return 1;
+ *seconds= ((Field_timestamp*)field)->get_timestamp(second_part);
+ return 0;
+ }
}
-
+
+ MYSQL_TIME ltime;
if (get_arg0_date(&ltime, 0))
- {
- /*
- We have to set null_value again because get_arg0_date will also set it
- to true if we have wrong datetime parameter (and we should return 0 in
- this case).
- */
- null_value= args[0]->null_value;
- return 0;
- }
+ return 1;
+
+ uint error_code;
+ *seconds= TIME_to_timestamp(current_thd, &ltime, &error_code);
+ *second_part= ltime.second_part;
+ return (null_value= (error_code == ER_WARN_DATA_OUT_OF_RANGE));
+}
+
+
+longlong Item_func_unix_timestamp::int_op()
+{
+ if (arg_count == 0)
+ return (longlong) current_thd->query_start();
- return (longlong) TIME_to_timestamp(current_thd, &ltime, &not_used);
+ ulong second_part;
+ my_time_t seconds;
+ if (get_timestamp_value(&seconds, &second_part))
+ return 0;
+
+ return seconds;
}
-longlong Item_func_time_to_sec::val_int()
+my_decimal *Item_func_unix_timestamp::decimal_op(my_decimal* buf)
+{
+ ulong second_part;
+ my_time_t seconds;
+ if (get_timestamp_value(&seconds, &second_part))
+ return 0;
+
+ return seconds2my_decimal(seconds < 0, seconds < 0 ? -seconds : seconds,
+ second_part, buf);
+}
+
+
+longlong Item_func_time_to_sec::int_op()
{
DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime;
- longlong seconds;
- (void) get_arg0_time(&ltime);
- seconds=ltime.hour*3600L+ltime.minute*60+ltime.second;
+ if (get_arg0_time(&ltime))
+ return 0;
+
+ longlong seconds=ltime.hour*3600L+ltime.minute*60+ltime.second;
return ltime.neg ? -seconds : seconds;
}
+my_decimal *Item_func_time_to_sec::decimal_op(my_decimal* buf)
+{
+ DBUG_ASSERT(fixed == 1);
+ MYSQL_TIME ltime;
+ if (get_arg0_time(&ltime))
+ return 0;
+
+ longlong seconds= ltime.hour*3600L+ltime.minute*60+ltime.second;
+ return seconds2my_decimal(ltime.neg, seconds, ltime.second_part, buf);
+}
+
+
/**
Convert a string to a interval value.
@@ -1495,29 +1350,31 @@ bool get_interval_value(Item *args,interval_type int_type,
}
-String *Item_date::val_str(String *str)
+String *Item_temporal_func::val_str(String *str)
+{
+ DBUG_ASSERT(fixed == 1);
+ return val_string_from_date(str);
+}
+
+
+longlong Item_temporal_func::val_int()
{
DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE))
- return (String *) 0;
- if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
- {
- null_value= 1;
- return (String *) 0;
- }
- make_date((DATE_TIME_FORMAT *) 0, &ltime, str);
- return str;
+ return 0;
+ longlong v= TIME_to_ulonglong(&ltime);
+ return ltime.neg ? -v : v;
}
-longlong Item_date::val_int()
+double Item_temporal_func::val_real()
{
DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE))
return 0;
- return (longlong) (ltime.year*10000L+ltime.month*100+ltime.day);
+ return TIME_to_double(&ltime);
}
@@ -1527,11 +1384,10 @@ bool Item_func_from_days::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
if ((null_value=args[0]->null_value))
return 1;
bzero(ltime, sizeof(MYSQL_TIME));
- get_date_from_daynr((long) value, &ltime->year, &ltime->month, &ltime->day);
- if ((null_value= (fuzzy_date & TIME_NO_ZERO_DATE) &&
- (ltime->year == 0 || ltime->month == 0 || ltime->day == 0)))
- return TRUE;
+ if (get_date_from_daynr((long) value, &ltime->year, &ltime->month,
+ &ltime->day))
+ return 0;
ltime->time_type= MYSQL_TIMESTAMP_DATE;
return 0;
@@ -1540,28 +1396,13 @@ bool Item_func_from_days::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
void Item_func_curdate::fix_length_and_dec()
{
- collation.set(&my_charset_bin);
- decimals=0;
- max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
-
store_now_in_TIME(&ltime);
/* We don't need to set second_part and neg because they already 0 */
ltime.hour= ltime.minute= ltime.second= 0;
ltime.time_type= MYSQL_TIMESTAMP_DATE;
- value= (longlong) TIME_to_ulonglong_date(&ltime);
-}
-
-String *Item_func_curdate::val_str(String *str)
-{
- DBUG_ASSERT(fixed == 1);
- if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
- {
- null_value= 1;
- return (String *) 0;
- }
- make_date((DATE_TIME_FORMAT *) 0, &ltime, str);
- return str;
+ Item_datefunc::fix_length_and_dec();
+ set_persist_maybe_null(0);
}
/**
@@ -1571,8 +1412,7 @@ String *Item_func_curdate::val_str(String *str)
void Item_func_curdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
{
THD *thd= current_thd;
- thd->variables.time_zone->gmt_sec_to_TIME(now_time,
- (my_time_t)thd->query_start());
+ thd->variables.time_zone->gmt_sec_to_TIME(now_time, thd->query_start());
thd->time_zone_used= 1;
}
@@ -1583,8 +1423,8 @@ void Item_func_curdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
*/
void Item_func_curdate_utc::store_now_in_TIME(MYSQL_TIME *now_time)
{
- my_tz_UTC->gmt_sec_to_TIME(now_time,
- (my_time_t)(current_thd->query_start()));
+ THD *thd= current_thd;
+ my_tz_UTC->gmt_sec_to_TIME(now_time, thd->query_start());
/*
We are not flagging this query as using time zone, since it uses fixed
UTC-SYSTEM time-zone.
@@ -1600,26 +1440,35 @@ bool Item_func_curdate::get_date(MYSQL_TIME *res,
}
-String *Item_func_curtime::val_str(String *str)
+bool Item_func_curtime::fix_fields(THD *thd, Item **items)
{
- DBUG_ASSERT(fixed == 1);
- str_value.set(buff, buff_length, &my_charset_bin);
- return &str_value;
+ if (decimals > TIME_SECOND_PART_DIGITS)
+ {
+ my_error(ER_TOO_BIG_PRECISION, MYF(0), decimals, func_name(),
+ TIME_SECOND_PART_DIGITS);
+ return 1;
+ }
+ return Item_timefunc::fix_fields(thd, items);
}
-
-void Item_func_curtime::fix_length_and_dec()
+bool Item_func_curtime::get_date(MYSQL_TIME *res,
+ uint fuzzy_date __attribute__((unused)))
{
- MYSQL_TIME ltime;
-
- decimals= DATETIME_DEC;
- collation.set(&my_charset_bin);
- store_now_in_TIME(&ltime);
- value= TIME_to_ulonglong_time(&ltime);
- buff_length= (uint) my_time_to_str(&ltime, buff);
- max_length= buff_length;
+ *res= ltime;
+ return 0;
}
+static void set_sec_part(ulong sec_part, MYSQL_TIME *ltime, Item *item)
+{
+ DBUG_ASSERT(item->decimals == AUTO_SEC_PART_DIGITS ||
+ item->decimals <= TIME_SECOND_PART_DIGITS);
+ if (item->decimals)
+ {
+ ltime->second_part= sec_part;
+ if (item->decimals < TIME_SECOND_PART_DIGITS)
+ ltime->second_part= sec_part_truncate(ltime->second_part, item->decimals);
+ }
+}
/**
Converts current time in my_time_t to MYSQL_TIME represenatation for local
@@ -1628,8 +1477,10 @@ void Item_func_curtime::fix_length_and_dec()
void Item_func_curtime_local::store_now_in_TIME(MYSQL_TIME *now_time)
{
THD *thd= current_thd;
- thd->variables.time_zone->gmt_sec_to_TIME(now_time,
- (my_time_t)thd->query_start());
+ thd->variables.time_zone->gmt_sec_to_TIME(now_time, thd->query_start());
+ now_time->year= now_time->month= now_time->day= 0;
+ now_time->time_type= MYSQL_TIMESTAMP_TIME;
+ set_sec_part(thd->query_start_sec_part(), now_time, this);
thd->time_zone_used= 1;
}
@@ -1640,36 +1491,28 @@ void Item_func_curtime_local::store_now_in_TIME(MYSQL_TIME *now_time)
*/
void Item_func_curtime_utc::store_now_in_TIME(MYSQL_TIME *now_time)
{
- my_tz_UTC->gmt_sec_to_TIME(now_time,
- (my_time_t)(current_thd->query_start()));
+ THD *thd= current_thd;
+ my_tz_UTC->gmt_sec_to_TIME(now_time, thd->query_start());
+ now_time->year= now_time->month= now_time->day= 0;
+ now_time->time_type= MYSQL_TIMESTAMP_TIME;
+ set_sec_part(thd->query_start_sec_part(), now_time, this);
/*
We are not flagging this query as using time zone, since it uses fixed
UTC-SYSTEM time-zone.
*/
}
-
-String *Item_func_now::val_str(String *str)
+bool Item_func_now::fix_fields(THD *thd, Item **items)
{
- DBUG_ASSERT(fixed == 1);
- str_value.set(buff,buff_length, &my_charset_bin);
- return &str_value;
-}
-
-
-void Item_func_now::fix_length_and_dec()
-{
- decimals= DATETIME_DEC;
- collation.set(&my_charset_bin);
-
- store_now_in_TIME(&ltime);
- value= (longlong) TIME_to_ulonglong_datetime(&ltime);
-
- buff_length= (uint) my_datetime_to_str(&ltime, buff);
- max_length= buff_length;
+ if (decimals > TIME_SECOND_PART_DIGITS)
+ {
+ my_error(ER_TOO_BIG_PRECISION, MYF(0), decimals, func_name(),
+ TIME_SECOND_PART_DIGITS);
+ return 1;
+ }
+ return Item_temporal_func::fix_fields(thd, items);
}
-
/**
Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole NOW function.
@@ -1677,8 +1520,8 @@ void Item_func_now::fix_length_and_dec()
void Item_func_now_local::store_now_in_TIME(MYSQL_TIME *now_time)
{
THD *thd= current_thd;
- thd->variables.time_zone->gmt_sec_to_TIME(now_time,
- (my_time_t)thd->query_start());
+ thd->variables.time_zone->gmt_sec_to_TIME(now_time, thd->query_start());
+ set_sec_part(thd->query_start_sec_part(), now_time, this);
thd->time_zone_used= 1;
}
@@ -1689,8 +1532,9 @@ void Item_func_now_local::store_now_in_TIME(MYSQL_TIME *now_time)
*/
void Item_func_now_utc::store_now_in_TIME(MYSQL_TIME *now_time)
{
- my_tz_UTC->gmt_sec_to_TIME(now_time,
- (my_time_t)(current_thd->query_start()));
+ THD *thd= current_thd;
+ my_tz_UTC->gmt_sec_to_TIME(now_time, thd->query_start());
+ set_sec_part(thd->query_start_sec_part(), now_time, this);
/*
We are not flagging this query as using time zone, since it uses fixed
UTC-SYSTEM time-zone.
@@ -1706,13 +1550,6 @@ bool Item_func_now::get_date(MYSQL_TIME *res,
}
-int Item_func_now::save_in_field(Field *to, bool no_conversions)
-{
- to->set_notnull();
- return to->store_time(&ltime, MYSQL_TIMESTAMP_DATETIME);
-}
-
-
/**
Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole SYSDATE function.
@@ -1720,98 +1557,61 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions)
void Item_func_sysdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
{
THD *thd= current_thd;
- thd->variables.time_zone->gmt_sec_to_TIME(now_time, (my_time_t) my_time(0));
+ my_hrtime_t now= my_hrtime();
+ thd->variables.time_zone->gmt_sec_to_TIME(now_time, hrtime_to_my_time(now));
+ set_sec_part(hrtime_sec_part(now), now_time, this);
thd->time_zone_used= 1;
}
-String *Item_func_sysdate_local::val_str(String *str)
-{
- DBUG_ASSERT(fixed == 1);
- store_now_in_TIME(&ltime);
- buff_length= (uint) my_datetime_to_str(&ltime, buff);
- str_value.set(buff, buff_length, &my_charset_bin);
- return &str_value;
-}
-
-
-longlong Item_func_sysdate_local::val_int()
-{
- DBUG_ASSERT(fixed == 1);
- store_now_in_TIME(&ltime);
- return (longlong) TIME_to_ulonglong_datetime(&ltime);
-}
-
-
-double Item_func_sysdate_local::val_real()
-{
- DBUG_ASSERT(fixed == 1);
- store_now_in_TIME(&ltime);
- return ulonglong2double(TIME_to_ulonglong_datetime(&ltime));
-}
-
-
-void Item_func_sysdate_local::fix_length_and_dec()
-{
- decimals= 0;
- collation.set(&my_charset_bin);
- max_length= MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
-}
-
-
bool Item_func_sysdate_local::get_date(MYSQL_TIME *res,
uint fuzzy_date __attribute__((unused)))
{
- store_now_in_TIME(&ltime);
- *res= ltime;
+ store_now_in_TIME(res);
return 0;
}
-
-int Item_func_sysdate_local::save_in_field(Field *to, bool no_conversions)
-{
- store_now_in_TIME(&ltime);
- to->set_notnull();
- to->store_time(&ltime, MYSQL_TIMESTAMP_DATETIME);
- return 0;
-}
-
-
-String *Item_func_sec_to_time::val_str(String *str)
+bool Item_func_sec_to_time::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- longlong arg_val= args[0]->val_int();
+ bool sign;
+ ulonglong sec;
+ ulong sec_part;
- if ((null_value=args[0]->null_value) ||
- str->alloc(MAX_DATE_STRING_REP_LENGTH))
- {
- null_value= 1;
- return (String*) 0;
- }
+ bzero((char *)ltime, sizeof(*ltime));
+ ltime->time_type= MYSQL_TIMESTAMP_TIME;
- sec_to_time(arg_val, args[0]->unsigned_flag, &ltime);
-
- make_time((DATE_TIME_FORMAT *) 0, &ltime, str);
- return str;
-}
+ sign= args[0]->get_seconds(&sec, &sec_part);
+ if ((null_value= args[0]->null_value))
+ return 1;
-longlong Item_func_sec_to_time::val_int()
-{
- DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- longlong arg_val= args[0]->val_int();
+ ltime->neg= sign;
+ if (sec > TIME_MAX_VALUE_SECONDS)
+ goto overflow;
+
+ DBUG_ASSERT(sec_part <= TIME_MAX_SECOND_PART);
- if ((null_value=args[0]->null_value))
- return 0;
+ ltime->hour= (uint) (sec/3600);
+ ltime->minute= (uint) (sec % 3600) /60;
+ ltime->second= (uint) sec % 60;
+ ltime->second_part= sec_part;
- sec_to_time(arg_val, args[0]->unsigned_flag, &ltime);
+ return 0;
- return (ltime.neg ? -1 : 1) *
- ((ltime.hour)*10000 + ltime.minute*100 + ltime.second);
-}
+overflow:
+ /* use check_time_range() to set ltime to the max value depending on dec */
+ int unused;
+ char buf[100];
+ String tmp(buf, sizeof(buf), &my_charset_bin), *err= args[0]->val_str(&tmp);
+ ltime->hour= TIME_MAX_HOUR+1;
+ check_time_range(ltime, decimals, &unused);
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ err->ptr(), err->length(),
+ MYSQL_TIMESTAMP_TIME, NullS);
+ return 0;
+}
void Item_func_date_format::fix_length_and_dec()
{
@@ -1841,7 +1641,7 @@ void Item_func_date_format::fix_length_and_dec()
collation.collation->mbmaxlen;
set_if_smaller(max_length,MAX_BLOB_WIDTH);
}
- maybe_null=1; // If wrong date
+ set_persist_maybe_null(1); // If wrong date
}
@@ -1948,24 +1748,12 @@ String *Item_func_date_format::val_str(String *str)
String *format;
MYSQL_TIME l_time;
uint size;
+ int is_time_flag = is_time_format ? TIME_TIME_ONLY : 0;
DBUG_ASSERT(fixed == 1);
-
- if (!is_time_format)
- {
- if (get_arg0_date(&l_time, TIME_FUZZY_DATE))
- return 0;
- }
- else
- {
- String *res;
- if (!(res=args[0]->val_str(str)) ||
- (str_to_time_with_warn(res->ptr(), res->length(), &l_time)))
- goto null_date;
-
- l_time.year=l_time.month=l_time.day=0;
- null_value=0;
- }
-
+
+ if (get_arg0_date(&l_time, TIME_FUZZY_DATE | is_time_flag))
+ return 0;
+
if (!(format = args[1]->val_str(str)) || !format->length())
goto null_date;
@@ -2003,100 +1791,39 @@ null_date:
void Item_func_from_unixtime::fix_length_and_dec()
{
thd= current_thd;
- collation.set(&my_charset_bin);
- decimals= DATETIME_DEC;
- max_length=MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null= 1;
thd->time_zone_used= 1;
+ decimals= args[0]->decimals;
+ Item_temporal_func::fix_length_and_dec();
}
-String *Item_func_from_unixtime::val_str(String *str)
-{
- MYSQL_TIME time_tmp;
-
- DBUG_ASSERT(fixed == 1);
-
- if (get_date(&time_tmp, 0))
- return 0;
-
- if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
- {
- null_value= 1;
- return 0;
- }
-
- make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str);
-
- return str;
-}
-
-
-longlong Item_func_from_unixtime::val_int()
-{
- MYSQL_TIME time_tmp;
-
- DBUG_ASSERT(fixed == 1);
-
- if (get_date(&time_tmp, 0))
- return 0;
-
- return (longlong) TIME_to_ulonglong_datetime(&time_tmp);
-}
-
bool Item_func_from_unixtime::get_date(MYSQL_TIME *ltime,
uint fuzzy_date __attribute__((unused)))
{
- ulonglong tmp= (ulonglong)(args[0]->val_int());
- /*
- "tmp > TIMESTAMP_MAX_VALUE" check also covers case of negative
- from_unixtime() argument since tmp is unsigned.
- */
- if ((null_value= (args[0]->null_value || tmp > TIMESTAMP_MAX_VALUE)))
- return 1;
-
- thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)tmp);
-
- return 0;
-}
-
-
-void Item_func_convert_tz::fix_length_and_dec()
-{
- collation.set(&my_charset_bin);
- decimals= 0;
- max_length= MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null= 1;
-}
+ bool sign;
+ ulonglong sec;
+ ulong sec_part;
+ bzero((char *)ltime, sizeof(*ltime));
+ ltime->time_type= MYSQL_TIMESTAMP_TIME;
-String *Item_func_convert_tz::val_str(String *str)
-{
- MYSQL_TIME time_tmp;
+ sign= args[0]->get_seconds(&sec, &sec_part);
- if (get_date(&time_tmp, 0))
- return 0;
+ if (args[0]->null_value || sign || sec > TIMESTAMP_MAX_VALUE)
+ return (null_value= 1);
- if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
- {
- null_value= 1;
- return 0;
- }
+ thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)sec);
- make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str);
+ ltime->second_part= sec_part;
- return str;
+ return (null_value= 0);
}
-longlong Item_func_convert_tz::val_int()
+void Item_func_convert_tz::fix_length_and_dec()
{
- MYSQL_TIME time_tmp;
-
- if (get_date(&time_tmp, 0))
- return 0;
-
- return (longlong)TIME_to_ulonglong_datetime(&time_tmp);
+ decimals= args[0]->decimals;
+ Item_temporal_func::fix_length_and_dec();
}
@@ -2119,18 +1846,22 @@ bool Item_func_convert_tz::get_date(MYSQL_TIME *ltime,
to_tz_cached= args[2]->const_item();
}
- if (from_tz==0 || to_tz==0 || get_arg0_date(ltime, TIME_NO_ZERO_DATE))
+ if (from_tz==0 || to_tz==0 ||
+ get_arg0_date(ltime, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE))
{
null_value= 1;
return 1;
}
{
- my_bool not_used;
+ uint not_used;
my_time_tmp= from_tz->TIME_to_gmt_sec(ltime, &not_used);
+ ulong sec_part= ltime->second_part;
/* my_time_tmp is guranteed to be in the allowed range */
if (my_time_tmp)
to_tz->gmt_sec_to_TIME(ltime, my_time_tmp);
+ /* we rely on the fact that no timezone conversion can change sec_part */
+ ltime->second_part= sec_part;
}
null_value= 0;
@@ -2141,7 +1872,7 @@ bool Item_func_convert_tz::get_date(MYSQL_TIME *ltime,
void Item_func_convert_tz::cleanup()
{
from_tz_cached= to_tz_cached= 0;
- Item_date_func::cleanup();
+ Item_temporal_func::cleanup();
}
@@ -2149,21 +1880,20 @@ void Item_date_add_interval::fix_length_and_dec()
{
enum_field_types arg0_field_type;
- collation.set(&my_charset_bin);
- maybe_null=1;
- max_length=MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
- value.alloc(max_length);
-
/*
The field type for the result of an Item_date function is defined as
follows:
- If first arg is a MYSQL_TYPE_DATETIME result is MYSQL_TYPE_DATETIME
- If first arg is a MYSQL_TYPE_DATE and the interval type uses hours,
- minutes or seconds then type is MYSQL_TYPE_DATETIME.
+ minutes or seconds then type is MYSQL_TYPE_DATETIME
+ otherwise it's MYSQL_TYPE_DATE
+ - if first arg is a MYSQL_TYPE_TIME and the interval type isn't using
+ anything larger than days, then the result is MYSQL_TYPE_TIME,
+ otherwise - MYSQL_TYPE_DATETIME.
- Otherwise the result is MYSQL_TYPE_STRING
- (This is because you can't know if the string contains a DATE, MYSQL_TIME or
- DATETIME argument)
+ (This is because you can't know if the string contains a DATE,
+ MYSQL_TIME or DATETIME argument)
*/
cached_field_type= MYSQL_TYPE_STRING;
arg0_field_type= args[0]->field_type();
@@ -2177,6 +1907,20 @@ void Item_date_add_interval::fix_length_and_dec()
else
cached_field_type= MYSQL_TYPE_DATETIME;
}
+ else if (arg0_field_type == MYSQL_TYPE_TIME)
+ {
+ if (int_type >= INTERVAL_DAY && int_type != INTERVAL_YEAR_MONTH)
+ cached_field_type= arg0_field_type;
+ else
+ cached_field_type= MYSQL_TYPE_DATETIME;
+ }
+ if (int_type == INTERVAL_MICROSECOND || int_type >= INTERVAL_DAY_MICROSECOND)
+ decimals= 6;
+ else
+ decimals= args[0]->decimals;
+
+ Item_temporal_func::fix_length_and_dec();
+ value.alloc(max_length);
}
@@ -2186,7 +1930,7 @@ bool Item_date_add_interval::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
INTERVAL interval;
- if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE) ||
+ if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE | TIME_FUZZY_DATE | TIME_NO_ZERO_IN_DATE) ||
get_interval_value(args[1], int_type, &value, &interval))
return (null_value=1);
@@ -2199,44 +1943,6 @@ bool Item_date_add_interval::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
}
-String *Item_date_add_interval::val_str(String *str)
-{
- DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- enum date_time_format_types format;
-
- if (Item_date_add_interval::get_date(&ltime, TIME_NO_ZERO_DATE))
- return 0;
-
- if (ltime.time_type == MYSQL_TIMESTAMP_DATE)
- format= DATE_ONLY;
- else if (ltime.second_part)
- format= DATE_TIME_MICROSECOND;
- else
- format= DATE_TIME;
-
- if (!make_datetime(format, &ltime, str))
- return str;
-
- null_value=1;
- return 0;
-}
-
-
-longlong Item_date_add_interval::val_int()
-{
- DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- longlong date;
- if (Item_date_add_interval::get_date(&ltime, TIME_NO_ZERO_DATE))
- return (longlong) 0;
- date = (ltime.year*100L + ltime.month)*100L + ltime.day;
- return ltime.time_type == MYSQL_TIMESTAMP_DATE ? date :
- ((date*100L + ltime.hour)*100L+ ltime.minute)*100L + ltime.second;
-}
-
-
-
bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const
{
Item_date_add_interval *other= (Item_date_add_interval*) item;
@@ -2284,7 +1990,7 @@ void Item_extract::print(String *str, enum_query_type query_type)
void Item_extract::fix_length_and_dec()
{
- maybe_null=1; // If wrong date
+ set_persist_maybe_null(1); // If wrong date
switch (int_type) {
case INTERVAL_YEAR: max_length=4; date_value=1; break;
case INTERVAL_YEAR_MONTH: max_length=6; date_value=1; break;
@@ -2318,25 +2024,12 @@ longlong Item_extract::val_int()
uint year;
ulong week_format;
long neg;
- if (date_value)
- {
- if (get_arg0_date(&ltime, TIME_FUZZY_DATE))
- return 0;
- neg=1;
- }
- else
- {
- char buf[40];
- String value(buf, sizeof(buf), &my_charset_bin);;
- String *res= args[0]->val_str(&value);
- if (!res || str_to_time_with_warn(res->ptr(), res->length(), &ltime))
- {
- null_value=1;
- return 0;
- }
- neg= ltime.neg ? -1 : 1;
- null_value=0;
- }
+ int is_time_flag = date_value ? 0 : TIME_TIME_ONLY;
+
+ if (get_arg0_date(&ltime, TIME_FUZZY_DATE | is_time_flag))
+ return 0;
+ neg= ltime.neg ? -1 : 1;
+
switch (int_type) {
case INTERVAL_YEAR: return ltime.year;
case INTERVAL_YEAR_MONTH: return ltime.year*100L+ltime.month;
@@ -2419,12 +2112,19 @@ bool Item_char_typecast::eq(const Item *item, bool binary_cmp) const
return 1;
}
-void Item_typecast::print(String *str, enum_query_type query_type)
+void Item_temporal_typecast::print(String *str, enum_query_type query_type)
{
+ char buf[32];
str->append(STRING_WITH_LEN("cast("));
args[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" as "));
str->append(cast_type());
+ if (decimals)
+ {
+ str->append('(');
+ str->append(llstr(decimals, buf));
+ str->append(')');
+ }
str->append(')');
}
@@ -2434,13 +2134,13 @@ void Item_char_typecast::print(String *str, enum_query_type query_type)
str->append(STRING_WITH_LEN("cast("));
args[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" as char"));
- if (cast_length >= 0)
+ if (cast_length != ~0U)
{
str->append('(');
char buffer[20];
// my_charset_bin is good enough for numbers
String st(buffer, sizeof(buffer), &my_charset_bin);
- st.set((ulonglong)cast_length, &my_charset_bin);
+ st.set(static_cast<ulonglong>(cast_length), &my_charset_bin);
str->append(st);
str->append(')');
}
@@ -2458,19 +2158,6 @@ String *Item_char_typecast::val_str(String *str)
String *res;
uint32 length;
- if (cast_length >= 0 &&
- ((unsigned) cast_length) > current_thd->variables.max_allowed_packet)
- {
- push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_ALLOWED_PACKET_OVERFLOWED,
- ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
- cast_cs == &my_charset_bin ?
- "cast_as_binary" : func_name(),
- current_thd->variables.max_allowed_packet);
- null_value= 1;
- return 0;
- }
-
if (!charset_conversion)
{
if (!(res= args[0]->val_str(str)))
@@ -2481,10 +2168,15 @@ String *Item_char_typecast::val_str(String *str)
}
else
{
- // Convert character set if differ
+ /*
+ Convert character set if differ
+ from_cs is 0 in the case where the result set may vary between calls,
+ for example with dynamic columns.
+ */
uint dummy_errors;
if (!(res= args[0]->val_str(str)) ||
- tmp_value.copy(res->ptr(), res->length(), from_cs,
+ tmp_value.copy(res->ptr(), res->length(),
+ from_cs ? from_cs : res->charset(),
cast_cs, &dummy_errors))
{
null_value= 1;
@@ -2500,7 +2192,7 @@ String *Item_char_typecast::val_str(String *str)
and the result is longer than cast length, e.g.
CAST('string' AS CHAR(1))
*/
- if (cast_length >= 0)
+ if (cast_length != ~0U)
{
if (res->length() > (length= (uint32) res->charpos(cast_length)))
{ // Safe even if const arg
@@ -2520,20 +2212,31 @@ String *Item_char_typecast::val_str(String *str)
res->c_ptr_safe());
res->length((uint) length);
}
- else if (cast_cs == &my_charset_bin && res->length() < (uint) cast_length)
+ else if (cast_cs == &my_charset_bin && res->length() < cast_length)
{
- if (res->alloced_length() < (uint) cast_length)
+ if (res->alloced_length() < cast_length)
{
str_value.alloc(cast_length);
str_value.copy(*res);
res= &str_value;
}
- bzero((char*) res->ptr() + res->length(),
- (uint) cast_length - res->length());
+ bzero((char*) res->ptr() + res->length(), cast_length - res->length());
res->length(cast_length);
}
}
null_value= 0;
+
+ if (res->length() > current_thd->variables.max_allowed_packet)
+ {
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
+ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
+ cast_cs == &my_charset_bin ?
+ "cast_as_binary" : func_name(),
+ current_thd->variables.max_allowed_packet);
+ null_value= 1;
+ return 0;
+ }
return res;
}
@@ -2562,193 +2265,116 @@ void Item_char_typecast::fix_length_and_dec()
and thus avoid unnecessary character set conversion.
- If the argument is not a number, then from_cs is set to
the argument's charset.
+ - If argument has a dynamic collation (can change from call to call)
+ we set from_cs to 0 as a marker that we have to take the collation
+ from the result string.
Note (TODO): we could use repertoire technique here.
*/
- from_cs= (args[0]->result_type() == INT_RESULT ||
- args[0]->result_type() == DECIMAL_RESULT ||
- args[0]->result_type() == REAL_RESULT) ?
- (cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) :
- args[0]->collation.collation;
- charset_conversion= (cast_cs->mbmaxlen > 1) ||
+ from_cs= ((args[0]->result_type() == INT_RESULT ||
+ args[0]->result_type() == DECIMAL_RESULT ||
+ args[0]->result_type() == REAL_RESULT) ?
+ (cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) :
+ args[0]->dynamic_result() ? 0 :
+ args[0]->collation.collation);
+ charset_conversion= !from_cs || (cast_cs->mbmaxlen > 1) ||
(!my_charset_same(from_cs, cast_cs) &&
from_cs != &my_charset_bin &&
cast_cs != &my_charset_bin);
collation.set(cast_cs, DERIVATION_IMPLICIT);
- char_length= (cast_length >= 0) ? cast_length :
+ char_length= ((cast_length != ~0U) ? cast_length :
args[0]->max_length /
- (cast_cs == &my_charset_bin ? 1 : args[0]->collation.collation->mbmaxlen);
+ (cast_cs == &my_charset_bin ? 1 :
+ args[0]->collation.collation->mbmaxlen));
max_length= char_length * cast_cs->mbmaxlen;
}
-String *Item_datetime_typecast::val_str(String *str)
+bool Item_time_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
- DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
-
- if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) &&
- !make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME,
- &ltime, str))
- return str;
-
- null_value=1;
- return 0;
-}
-
-
-longlong Item_datetime_typecast::val_int()
-{
- DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- if (get_arg0_date(&ltime,1))
- {
- null_value= 1;
- return 0;
- }
-
- return TIME_to_ulonglong_datetime(&ltime);
-}
-
-
-bool Item_time_typecast::get_time(MYSQL_TIME *ltime)
-{
- bool res= get_arg0_time(ltime);
+ if (get_arg0_time(ltime))
+ return 1;
+ if (decimals < TIME_SECOND_PART_DIGITS)
+ ltime->second_part= sec_part_truncate(ltime->second_part, decimals);
/*
- For MYSQL_TIMESTAMP_TIME value we can have non-zero day part,
+ MYSQL_TIMESTAMP_TIME value can have non-zero day part,
which we should not lose.
*/
- if (ltime->time_type == MYSQL_TIMESTAMP_DATETIME)
+ if (ltime->time_type != MYSQL_TIMESTAMP_TIME)
ltime->year= ltime->month= ltime->day= 0;
ltime->time_type= MYSQL_TIMESTAMP_TIME;
- return res;
-}
-
-
-longlong Item_time_typecast::val_int()
-{
- MYSQL_TIME ltime;
- if (get_time(&ltime))
- {
- null_value= 1;
- return 0;
- }
- return ltime.hour * 10000L + ltime.minute * 100 + ltime.second;
-}
-
-String *Item_time_typecast::val_str(String *str)
-{
- DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
-
- if (!get_arg0_time(&ltime) &&
- !make_datetime(ltime.second_part ? TIME_MICROSECOND : TIME_ONLY,
- &ltime, str))
- return str;
-
- null_value=1;
return 0;
}
bool Item_date_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
- bool res= get_arg0_date(ltime, TIME_FUZZY_DATE);
+ if (get_arg0_date(ltime, fuzzy_date & ~TIME_TIME_ONLY))
+ return 1;
ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
ltime->time_type= MYSQL_TIMESTAMP_DATE;
- return res;
-}
-
-
-bool Item_date_typecast::get_time(MYSQL_TIME *ltime)
-{
- bzero((char *)ltime, sizeof(MYSQL_TIME));
- return args[0]->null_value;
-}
-
-
-String *Item_date_typecast::val_str(String *str)
-{
- DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) &&
- !str->alloc(MAX_DATE_STRING_REP_LENGTH))
+ int unused;
+ if (check_date(ltime, ltime->year || ltime->month || ltime->day,
+ fuzzy_date, &unused))
{
- make_date((DATE_TIME_FORMAT *) 0, &ltime, str);
- return str;
+ Lazy_string_time str(ltime);
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ &str, MYSQL_TIMESTAMP_DATE, 0);
+ return (null_value= 1);
}
-
- null_value=1;
- return 0;
+ return (null_value= 0);
}
-longlong Item_date_typecast::val_int()
-{
- DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- if ((null_value= args[0]->get_date(&ltime, TIME_FUZZY_DATE)))
- return 0;
- return (longlong) (ltime.year * 10000L + ltime.month * 100 + ltime.day);
-}
-
-/**
- MAKEDATE(a,b) is a date function that creates a date value
- from a year and day value.
- NOTES:
- As arguments are integers, we can't know if the year is a 2 digit or 4 digit year.
- In this case we treat all years < 100 as 2 digit years. Ie, this is not safe
- for dates between 0000-01-01 and 0099-12-31
-*/
-
-String *Item_func_makedate::val_str(String *str)
+bool Item_datetime_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
- DBUG_ASSERT(fixed == 1);
- MYSQL_TIME l_time;
- long daynr= (long) args[1]->val_int();
- long year= (long) args[0]->val_int();
- long days;
+ if (get_arg0_date(ltime, fuzzy_date & ~TIME_TIME_ONLY))
+ return 1;
- if (args[0]->null_value || args[1]->null_value ||
- year < 0 || year > 9999 || daynr <= 0)
- goto err;
+ if (decimals < TIME_SECOND_PART_DIGITS)
+ ltime->second_part= sec_part_truncate(ltime->second_part, decimals);
- if (year < 100)
- year= year_2000_handling(year);
- days= calc_daynr(year,1,1) + daynr - 1;
- /* Day number from year 0 to 9999-12-31 */
- if (days >= 0 && days <= MAX_DAY_NUMBER)
+ /*
+ ltime is valid MYSQL_TYPE_TIME (according to fuzzy_date).
+ But not every valid TIME value is a valid DATETIME value!
+ */
+ if (ltime->time_type == MYSQL_TIMESTAMP_TIME)
{
- null_value=0;
- get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day);
- if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
- goto err;
- make_date((DATE_TIME_FORMAT *) 0, &l_time, str);
- return str;
+ if (ltime->neg)
+ {
+ Lazy_string_time str(ltime);
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ &str, MYSQL_TIMESTAMP_DATETIME, 0);
+ return (null_value= 1);
+ }
+
+ uint day= ltime->hour/24;
+ ltime->hour %= 24;
+ ltime->month= day / 31;
+ ltime->day= day % 31;
}
-err:
- null_value=1;
+ ltime->time_type= MYSQL_TIMESTAMP_DATETIME;
return 0;
}
-/*
+/**
MAKEDATE(a,b) is a date function that creates a date value
from a year and day value.
NOTES:
- As arguments are integers, we can't know if the year is a 2 digit or 4 digit year.
- In this case we treat all years < 100 as 2 digit years. Ie, this is not safe
- for dates between 0000-01-01 and 0099-12-31
+ As arguments are integers, we can't know if the year is a 2 digit
+ or 4 digit year. In this case we treat all years < 100 as 2 digit
+ years. Ie, this is not safe for dates between 0000-01-01 and
+ 0099-12-31
*/
-longlong Item_func_makedate::val_int()
+bool Item_func_makedate::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME l_time;
long daynr= (long) args[1]->val_int();
long year= (long) args[0]->val_int();
long days;
@@ -2761,26 +2387,22 @@ longlong Item_func_makedate::val_int()
year= year_2000_handling(year);
days= calc_daynr(year,1,1) + daynr - 1;
- /* Day number from year 0 to 9999-12-31 */
- if (days >= 0 && days < MAX_DAY_NUMBER)
- {
- null_value=0;
- get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day);
- return (longlong) (l_time.year * 10000L + l_time.month * 100 + l_time.day);
- }
+ if (get_date_from_daynr(days, &ltime->year, &ltime->month, &ltime->day))
+ goto err;
+ ltime->time_type= MYSQL_TIMESTAMP_DATE;
+ ltime->neg= 0;
+ ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
+ return (null_value= 0);
err:
- null_value= 1;
- return 0;
+ return (null_value= 1);
}
void Item_func_add_time::fix_length_and_dec()
{
enum_field_types arg0_field_type;
- decimals=0;
- max_length=MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null= 1;
+ decimals= max(args[0]->decimals, args[1]->decimals);
/*
The field type for the result of an Item_func_add_time function is defined
@@ -2800,6 +2422,7 @@ void Item_func_add_time::fix_length_and_dec()
cached_field_type= MYSQL_TYPE_DATETIME;
else if (arg0_field_type == MYSQL_TYPE_TIME)
cached_field_type= MYSQL_TYPE_TIME;
+ Item_temporal_func::fix_length_and_dec();
}
/**
@@ -2812,38 +2435,37 @@ void Item_func_add_time::fix_length_and_dec()
Result: Time value or datetime value
*/
-String *Item_func_add_time::val_str(String *str)
+bool Item_func_add_time::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME l_time1, l_time2, l_time3;
+ MYSQL_TIME l_time1, l_time2;
bool is_time= 0;
long days, microseconds;
longlong seconds;
- int l_sign= sign;
+ int l_sign= sign, was_cut= 0;
- null_value=0;
if (is_date) // TIMESTAMP function
{
if (get_arg0_date(&l_time1, TIME_FUZZY_DATE) ||
args[1]->get_time(&l_time2) ||
l_time1.time_type == MYSQL_TIMESTAMP_TIME ||
l_time2.time_type != MYSQL_TIMESTAMP_TIME)
- goto null_date;
+ return (null_value= 1);
}
else // ADDTIME function
{
if (args[0]->get_time(&l_time1) ||
args[1]->get_time(&l_time2) ||
l_time2.time_type == MYSQL_TIMESTAMP_DATETIME)
- goto null_date;
+ return (null_value= 1);
is_time= (l_time1.time_type == MYSQL_TIMESTAMP_TIME);
}
if (l_time1.neg != l_time2.neg)
l_sign= -l_sign;
- bzero((char *)&l_time3, sizeof(l_time3));
+ bzero(ltime, sizeof(*ltime));
- l_time3.neg= calc_time_diff(&l_time1, &l_time2, -l_sign,
+ ltime->neg= calc_time_diff(&l_time1, &l_time2, -l_sign,
&seconds, &microseconds);
/*
@@ -2851,35 +2473,36 @@ String *Item_func_add_time::val_str(String *str)
is non-zero we need to swap sign to get proper result.
*/
if (l_time1.neg && (seconds || microseconds))
- l_time3.neg= 1-l_time3.neg; // Swap sign of result
+ ltime->neg= 1-ltime->neg; // Swap sign of result
- if (!is_time && l_time3.neg)
- goto null_date;
+ if (!is_time && ltime->neg)
+ return (null_value= 1);
days= (long)(seconds/86400L);
- calc_time_from_sec(&l_time3, (long)(seconds%86400L), microseconds);
+ calc_time_from_sec(ltime, (long)(seconds%86400L), microseconds);
+
+ ltime->time_type= is_time ? MYSQL_TIMESTAMP_TIME : MYSQL_TIMESTAMP_DATETIME;
if (!is_time)
{
- get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day);
- if (l_time3.day &&
- !make_datetime(l_time1.second_part || l_time2.second_part ?
- DATE_TIME_MICROSECOND : DATE_TIME,
- &l_time3, str))
- return str;
- goto null_date;
+ if (get_date_from_daynr(days,&ltime->year,&ltime->month,&ltime->day) ||
+ !ltime->day)
+ return (null_value= 1);
+ return (null_value= 0);
}
- l_time3.hour+= days*24;
- if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ?
- TIME_MICROSECOND : TIME_ONLY,
- &l_time3, str))
- return str;
+ ltime->hour+= days*24;
-null_date:
- null_value=1;
- return 0;
+ MYSQL_TIME copy= *ltime;
+ Lazy_string_time str(&copy);
+
+ check_time_range(ltime, decimals, &was_cut);
+ if (was_cut)
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ &str, MYSQL_TIMESTAMP_TIME, NullS);
+
+ return (null_value= 0);
}
@@ -2912,15 +2535,19 @@ void Item_func_add_time::print(String *str, enum_query_type query_type)
Result: Time value
*/
-String *Item_func_timediff::val_str(String *str)
+bool Item_func_timediff::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
DBUG_ASSERT(fixed == 1);
longlong seconds;
long microseconds;
- int l_sign= 1;
- MYSQL_TIME l_time1 ,l_time2, l_time3;
+ int l_sign= 1, was_cut= 0;
+ MYSQL_TIME l_time1,l_time2,l_time3;
+ Lazy_string_time str(&l_time3);
+
+ /* the following may be true in, for example, date_add(timediff(...), ... */
+ if (fuzzy_date & TIME_NO_ZERO_IN_DATE)
+ goto null_date;
- null_value= 0;
if (args[0]->get_time(&l_time1) ||
args[1]->get_time(&l_time2) ||
l_time1.time_type != l_time2.time_type)
@@ -2942,16 +2569,30 @@ String *Item_func_timediff::val_str(String *str)
if (l_time1.neg && (seconds || microseconds))
l_time3.neg= 1-l_time3.neg; // Swap sign of result
+ /*
+ seconds is longlong, when casted to long it may become a small number
+ even if the original seconds value was too large and invalid.
+ as a workaround we limit seconds by a large invalid long number
+ ("invalid" means > TIME_MAX_SECOND)
+ */
+ set_if_smaller(seconds, INT_MAX32);
+
calc_time_from_sec(&l_time3, (long) seconds, microseconds);
- if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ?
- TIME_MICROSECOND : TIME_ONLY,
- &l_time3, str))
- return str;
+ if ((fuzzy_date & TIME_NO_ZERO_DATE) && (seconds == 0) &&
+ (microseconds == 0))
+ goto null_date;
+
+ *ltime= l_time3;
+ check_time_range(ltime, decimals, &was_cut);
+
+ if (was_cut)
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ &str, MYSQL_TIMESTAMP_TIME, NullS);
+ return (null_value= 0);
null_date:
- null_value=1;
- return 0;
+ return (null_value= 1);
}
/**
@@ -2960,10 +2601,9 @@ null_date:
Result: Time value
*/
-String *Item_func_maketime::val_str(String *str)
+bool Item_func_maketime::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
bool overflow= 0;
longlong hour= args[0]->val_int();
@@ -2974,12 +2614,11 @@ String *Item_func_maketime::val_str(String *str)
args[1]->null_value ||
args[2]->null_value ||
minute < 0 || minute > 59 ||
- second < 0 || second > 59 ||
- str->alloc(MAX_DATE_STRING_REP_LENGTH))))
- return 0;
+ second < 0 || second > 59)))
+ return 1;
- bzero((char *)&ltime, sizeof(ltime));
- ltime.neg= 0;
+ bzero(ltime, sizeof(*ltime));
+ ltime->time_type= MYSQL_TIMESTAMP_TIME;
/* Check for integer overflows */
if (hour < 0)
@@ -2987,22 +2626,22 @@ String *Item_func_maketime::val_str(String *str)
if (args[0]->unsigned_flag)
overflow= 1;
else
- ltime.neg= 1;
+ ltime->neg= 1;
}
- if (-hour > UINT_MAX || hour > UINT_MAX)
+ if (-hour > TIME_MAX_HOUR || hour > TIME_MAX_HOUR)
overflow= 1;
if (!overflow)
{
- ltime.hour= (uint) ((hour < 0 ? -hour : hour));
- ltime.minute= (uint) minute;
- ltime.second= (uint) second;
+ ltime->hour= (uint) ((hour < 0 ? -hour : hour));
+ ltime->minute= (uint) minute;
+ ltime->second= (uint) second;
}
else
{
- ltime.hour= TIME_MAX_HOUR;
- ltime.minute= TIME_MAX_MINUTE;
- ltime.second= TIME_MAX_SECOND;
+ ltime->hour= TIME_MAX_HOUR;
+ ltime->minute= TIME_MAX_MINUTE;
+ ltime->second= TIME_MAX_SECOND;
char buf[28];
char *ptr= longlong10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10);
int len = (int)(ptr - buf) +
@@ -3012,12 +2651,7 @@ String *Item_func_maketime::val_str(String *str)
NullS);
}
- if (make_time_with_warn((DATE_TIME_FORMAT *) 0, &ltime, str))
- {
- null_value= 1;
- return 0;
- }
- return str;
+ return 0;
}
@@ -3033,7 +2667,7 @@ longlong Item_func_microsecond::val_int()
{
DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime;
- if (!get_arg0_time(&ltime))
+ if (!get_arg0_date(&ltime, TIME_TIME_ONLY))
return ltime.second_part;
return 0;
}
@@ -3048,8 +2682,8 @@ longlong Item_func_timestamp_diff::val_int()
int neg= 1;
null_value= 0;
- if (args[0]->get_date(&ltime1, TIME_NO_ZERO_DATE) ||
- args[1]->get_date(&ltime2, TIME_NO_ZERO_DATE))
+ if (args[0]->get_date(&ltime1, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE) ||
+ args[1]->get_date(&ltime2, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE))
goto null_date;
if (calc_time_diff(&ltime2,&ltime1, 1,
@@ -3299,9 +2933,9 @@ get_date_time_result_type(const char *format, uint length)
have all types of date-time components and can end our search.
*/
return DATE_TIME_MICROSECOND;
+ }
}
}
- }
/* We don't have all three types of date-time components */
if (frac_second_used)
@@ -3318,40 +2952,39 @@ get_date_time_result_type(const char *format, uint length)
void Item_func_str_to_date::fix_length_and_dec()
{
- maybe_null= 1;
- decimals=0;
- cached_format_type= DATE_TIME;
cached_field_type= MYSQL_TYPE_DATETIME;
- max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
- cached_timestamp_type= MYSQL_TIMESTAMP_NONE;
+ decimals= NOT_FIXED_DEC;
if ((const_item= args[1]->const_item()))
{
char format_buff[64];
String format_str(format_buff, sizeof(format_buff), &my_charset_bin);
String *format= args[1]->val_str(&format_str);
+ decimals= 0;
if (!args[1]->null_value)
{
- cached_format_type= get_date_time_result_type(format->ptr(),
- format->length());
+ date_time_format_types cached_format_type=
+ get_date_time_result_type(format->ptr(), format->length());
switch (cached_format_type) {
case DATE_ONLY:
- cached_timestamp_type= MYSQL_TIMESTAMP_DATE;
cached_field_type= MYSQL_TYPE_DATE;
- max_length= MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN;
break;
- case TIME_ONLY:
case TIME_MICROSECOND:
- cached_timestamp_type= MYSQL_TIMESTAMP_TIME;
+ decimals= 6;
+ /* fall through */
+ case TIME_ONLY:
cached_field_type= MYSQL_TYPE_TIME;
- max_length= MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN;
break;
- default:
- cached_timestamp_type= MYSQL_TIMESTAMP_DATETIME;
+ case DATE_TIME_MICROSECOND:
+ decimals= 6;
+ /* fall through */
+ case DATE_TIME:
cached_field_type= MYSQL_TYPE_DATETIME;
break;
}
}
}
+ cached_timestamp_type= mysql_type_to_time_type(cached_field_type);
+ Item_temporal_func::fix_length_and_dec();
}
@@ -3360,21 +2993,19 @@ bool Item_func_str_to_date::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
DATE_TIME_FORMAT date_time_format;
char val_buff[64], format_buff[64];
String val_string(val_buff, sizeof(val_buff), &my_charset_bin), *val;
- String format_str(format_buff, sizeof(format_buff), &my_charset_bin), *format;
+ String format_str(format_buff, sizeof(format_buff), &my_charset_bin),
+ *format;
val= args[0]->val_str(&val_string);
format= args[1]->val_str(&format_str);
if (args[0]->null_value || args[1]->null_value)
goto null_date;
- null_value= 0;
- bzero((char*) ltime, sizeof(*ltime));
date_time_format.format.str= (char*) format->ptr();
date_time_format.format.length= format->length();
if (extract_date_time(&date_time_format, val->ptr(), val->length(),
- ltime, cached_timestamp_type, 0, "datetime") ||
- ((fuzzy_date & TIME_NO_ZERO_DATE) &&
- (ltime->year == 0 || ltime->month == 0 || ltime->day == 0)))
+ ltime, cached_timestamp_type, 0, "datetime",
+ fuzzy_date))
goto null_date;
if (cached_timestamp_type == MYSQL_TIMESTAMP_TIME && ltime->day)
{
@@ -3386,6 +3017,7 @@ bool Item_func_str_to_date::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
ltime->hour+= ltime->day*24;
ltime->day= 0;
}
+ null_value= 0;
return 0;
null_date:
@@ -3393,25 +3025,9 @@ null_date:
}
-String *Item_func_str_to_date::val_str(String *str)
-{
- DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
-
- if (Item_func_str_to_date::get_date(&ltime, TIME_FUZZY_DATE))
- return 0;
-
- if (!make_datetime((const_item ? cached_format_type :
- (ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME)),
- &ltime, str))
- return str;
- return 0;
-}
-
-
bool Item_func_last_day::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
- if (get_arg0_date(ltime, fuzzy_date & ~TIME_FUZZY_DATE) ||
+ if (get_arg0_date(ltime, fuzzy_date) ||
(ltime->month == 0))
{
null_value= 1;
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 9eff2deba48..25a160d91f6 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -67,7 +67,7 @@ public:
{
decimals=0;
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
enum_monotonicity_info get_monotonicity_info() const;
longlong val_int_endpoint(bool left_endp, bool *incl_endp);
@@ -90,7 +90,7 @@ public:
{
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
@@ -123,7 +123,7 @@ public:
collation.set(&my_charset_bin);
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
@@ -158,7 +158,7 @@ public:
{
decimals=0;
max_length=3*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
@@ -179,7 +179,7 @@ public:
{
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
@@ -200,7 +200,7 @@ public:
{
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
@@ -221,7 +221,7 @@ public:
{
decimals=0;
max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
@@ -242,7 +242,7 @@ public:
{
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
@@ -263,7 +263,7 @@ public:
{
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
};
@@ -277,7 +277,7 @@ public:
{
decimals=0;
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
@@ -300,7 +300,7 @@ public:
{
decimals=0;
max_length=4*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
@@ -335,7 +335,7 @@ public:
collation.set(&my_charset_bin);
decimals=0;
max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
@@ -359,13 +359,30 @@ class Item_func_dayname :public Item_func_weekday
};
-class Item_func_unix_timestamp :public Item_int_func
+class Item_func_seconds_hybrid: public Item_func_numhybrid
{
- String value;
public:
- Item_func_unix_timestamp() :Item_int_func() {}
- Item_func_unix_timestamp(Item *a) :Item_int_func(a) {}
- longlong val_int();
+ Item_func_seconds_hybrid() :Item_func_numhybrid() {}
+ Item_func_seconds_hybrid(Item *a) :Item_func_numhybrid(a) {}
+ void fix_num_length_and_dec()
+ {
+ if (arg_count)
+ decimals= args[0]->decimals;
+ set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
+ max_length=17 + (decimals ? decimals + 1 : 0);
+ }
+ void find_num_type() { hybrid_type= decimals ? DECIMAL_RESULT : INT_RESULT; }
+ double real_op() { DBUG_ASSERT(0); return 0; }
+ String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
+};
+
+
+class Item_func_unix_timestamp :public Item_func_seconds_hybrid
+{
+ bool get_timestamp_value(my_time_t *seconds, ulong *second_part);
+public:
+ Item_func_unix_timestamp() :Item_func_seconds_hybrid() {}
+ Item_func_unix_timestamp(Item *a) :Item_func_seconds_hybrid(a) {}
const char *func_name() const { return "unix_timestamp"; }
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
/*
@@ -377,11 +394,6 @@ public:
{
return !has_timestamp_args();
}
- void fix_length_and_dec()
- {
- decimals=0;
- max_length=10*MY_CHARSET_BIN_MB_MAXLEN;
- }
bool check_vcol_func_processor(uchar *int_arg)
{
/*
@@ -390,20 +402,21 @@ public:
*/
return trace_unsupported_by_check_vcol_func_processor(func_name());
}
+ longlong int_op();
+ my_decimal *decimal_op(my_decimal* buf);
};
-class Item_func_time_to_sec :public Item_int_func
+
+class Item_func_time_to_sec :public Item_func_seconds_hybrid
{
public:
- Item_func_time_to_sec(Item *item) :Item_int_func(item) {}
- longlong val_int();
+ Item_func_time_to_sec(Item *item) :Item_func_seconds_hybrid(item) {}
const char *func_name() const { return "time_to_sec"; }
- void fix_length_and_dec()
+ void fix_num_length_and_dec()
{
- maybe_null= TRUE;
- decimals=0;
- max_length=10*MY_CHARSET_BIN_MB_MAXLEN;
+ set_persist_maybe_null(1);
+ Item_func_seconds_hybrid::fix_num_length_and_dec();
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
@@ -411,126 +424,98 @@ public:
{
return !has_time_args();
}
+ longlong int_op();
+ my_decimal *decimal_op(my_decimal* buf);
};
-/*
- This can't be a Item_str_func, because the val_real() functions are special
-*/
-
-class Item_date :public Item_func
+class Item_temporal_func: public Item_func
{
public:
- Item_date() :Item_func() {}
- Item_date(Item *a) :Item_func(a) {}
+ Item_temporal_func() :Item_func() {}
+ Item_temporal_func(Item *a) :Item_func(a) {}
+ Item_temporal_func(Item *a, Item *b) :Item_func(a,b) {}
+ Item_temporal_func(Item *a, Item *b, Item *c) :Item_func(a,b,c) {}
enum Item_result result_type () const { return STRING_RESULT; }
- enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
+ enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
String *val_str(String *str);
longlong val_int();
- double val_real() { return val_real_from_decimal(); }
- const char *func_name() const { return "date"; }
- void fix_length_and_dec()
- {
- collation.set(&my_charset_bin);
- decimals=0;
- max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
- }
- Field *tmp_table_field(TABLE *table)
- {
- return tmp_table_field_from_field_type(table, 0);
- }
- bool result_as_longlong() { return TRUE; }
+ double val_real();
+ bool get_date(MYSQL_TIME *res, uint fuzzy_date) { DBUG_ASSERT(0); return 1; }
my_decimal *val_decimal(my_decimal *decimal_value)
- {
- DBUG_ASSERT(fixed == 1);
- return val_decimal_from_date(decimal_value);
- }
+ { return val_decimal_from_date(decimal_value); }
+ Field *tmp_table_field(TABLE *table)
+ { return tmp_table_field_from_field_type(table, 0); }
int save_in_field(Field *field, bool no_conversions)
- {
- return save_date_in_field(field);
+ { return save_date_in_field(field); }
+ void fix_length_and_dec()
+ {
+ static const uint max_time_type_width[5]=
+ { MAX_DATETIME_WIDTH, MAX_DATETIME_WIDTH, MAX_DATE_WIDTH,
+ MAX_DATETIME_WIDTH, MIN_TIME_WIDTH };
+
+ set_persist_maybe_null(1);
+ max_length= max_time_type_width[mysql_type_to_time_type(field_type())+2];
+ if (decimals)
+ {
+ if (decimals == NOT_FIXED_DEC)
+ max_length+= TIME_SECOND_PART_DIGITS + 1;
+ else
+ {
+ set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
+ max_length+= decimals + 1;
+ }
+ }
+ /*
+ We set maybe_null to 1 as default as any bad argument with date or
+ time can get us to return NULL.
+ */
+ set_persist_maybe_null(1);
}
};
-class Item_date_func :public Item_str_func
+class Item_datefunc :public Item_temporal_func
{
public:
- Item_date_func() :Item_str_func() {}
- Item_date_func(Item *a) :Item_str_func(a) {}
- Item_date_func(Item *a,Item *b) :Item_str_func(a,b) {}
- Item_date_func(Item *a,Item *b, Item *c) :Item_str_func(a,b,c) {}
- enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
- Field *tmp_table_field(TABLE *table)
- {
- return tmp_table_field_from_field_type(table, 0);
- }
- bool result_as_longlong() { return TRUE; }
- double val_real() { return (double) val_int(); }
- my_decimal *val_decimal(my_decimal *decimal_value)
- {
- DBUG_ASSERT(fixed == 1);
- return val_decimal_from_date(decimal_value);
- }
- int save_in_field(Field *field, bool no_conversions)
- {
- return save_date_in_field(field);
- }
+ Item_datefunc() :Item_temporal_func() { }
+ Item_datefunc(Item *a) :Item_temporal_func(a) { }
+ enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
};
-class Item_str_timefunc :public Item_str_func
+class Item_timefunc :public Item_temporal_func
{
public:
- Item_str_timefunc() :Item_str_func() {}
- Item_str_timefunc(Item *a) :Item_str_func(a) {}
- Item_str_timefunc(Item *a,Item *b) :Item_str_func(a,b) {}
- Item_str_timefunc(Item *a, Item *b, Item *c) :Item_str_func(a, b ,c) {}
+ Item_timefunc() :Item_temporal_func() {}
+ Item_timefunc(Item *a) :Item_temporal_func(a) {}
+ Item_timefunc(Item *a,Item *b) :Item_temporal_func(a,b) {}
+ Item_timefunc(Item *a, Item *b, Item *c) :Item_temporal_func(a, b ,c) {}
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
- void fix_length_and_dec()
- {
- decimals= DATETIME_DEC;
- max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
- }
- Field *tmp_table_field(TABLE *table)
- {
- return tmp_table_field_from_field_type(table, 0);
- }
- double val_real() { return val_real_from_decimal(); }
- my_decimal *val_decimal(my_decimal *decimal_value)
- {
- DBUG_ASSERT(fixed == 1);
- return val_decimal_from_time(decimal_value);
- }
- int save_in_field(Field *field, bool no_conversions)
- {
- return save_time_in_field(field);
- }
- longlong val_int() { return val_int_from_decimal(); }
- bool result_as_longlong() { return TRUE; }
};
/* Abstract CURTIME function. Children should define what time zone is used */
-class Item_func_curtime :public Item_str_timefunc
+class Item_func_curtime :public Item_timefunc
{
- longlong value;
- char buff[9*2+32];
- uint buff_length;
+ MYSQL_TIME ltime;
public:
- Item_func_curtime() :Item_str_timefunc() {}
- Item_func_curtime(Item *a) :Item_str_timefunc(a) {}
- double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; }
- longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
- String *val_str(String *str);
- void fix_length_and_dec();
+ Item_func_curtime(uint dec) :Item_timefunc() { decimals= dec; }
+ bool fix_fields(THD *, Item **);
+ void fix_length_and_dec()
+ {
+ store_now_in_TIME(&ltime);
+ Item_timefunc::fix_length_and_dec();
+ set_persist_maybe_null(0);
+ }
+ bool get_date(MYSQL_TIME *res, uint fuzzy_date);
/*
Abstract method that defines which time zone is used for conversion.
Converts time current time in my_time_t representation to broken-down
MYSQL_TIME representation using UTC-SYSTEM or per-thread time zone.
*/
virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
- bool result_as_longlong() { return TRUE; }
bool check_vcol_func_processor(uchar *int_arg)
{
return trace_unsupported_by_check_vcol_func_processor(func_name());
@@ -541,8 +526,7 @@ public:
class Item_func_curtime_local :public Item_func_curtime
{
public:
- Item_func_curtime_local() :Item_func_curtime() {}
- Item_func_curtime_local(Item *a) :Item_func_curtime(a) {}
+ Item_func_curtime_local(uint dec) :Item_func_curtime(dec) {}
const char *func_name() const { return "curtime"; }
virtual void store_now_in_TIME(MYSQL_TIME *now_time);
};
@@ -551,8 +535,7 @@ public:
class Item_func_curtime_utc :public Item_func_curtime
{
public:
- Item_func_curtime_utc() :Item_func_curtime() {}
- Item_func_curtime_utc(Item *a) :Item_func_curtime(a) {}
+ Item_func_curtime_utc(uint dec) :Item_func_curtime(dec) {}
const char *func_name() const { return "utc_time"; }
virtual void store_now_in_TIME(MYSQL_TIME *now_time);
};
@@ -560,14 +543,11 @@ public:
/* Abstract CURDATE function. See also Item_func_curtime. */
-class Item_func_curdate :public Item_date
+class Item_func_curdate :public Item_datefunc
{
- longlong value;
MYSQL_TIME ltime;
public:
- Item_func_curdate() :Item_date() {}
- longlong val_int() { DBUG_ASSERT(fixed == 1); return (value) ; }
- String *val_str(String *str);
+ Item_func_curdate() :Item_datefunc() {}
void fix_length_and_dec();
bool get_date(MYSQL_TIME *res, uint fuzzy_date);
virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
@@ -598,21 +578,19 @@ public:
/* Abstract CURRENT_TIMESTAMP function. See also Item_func_curtime */
-class Item_func_now :public Item_date_func
+
+class Item_func_now :public Item_temporal_func
{
-protected:
- longlong value;
- char buff[20*2+32]; // +32 to make my_snprintf_{8bit|ucs2} happy
- uint buff_length;
MYSQL_TIME ltime;
public:
- Item_func_now() :Item_date_func() {}
- Item_func_now(Item *a) :Item_date_func(a) {}
- enum Item_result result_type () const { return STRING_RESULT; }
- longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
- int save_in_field(Field *to, bool no_conversions);
- String *val_str(String *str);
- void fix_length_and_dec();
+ Item_func_now(uint dec) :Item_temporal_func() { decimals= dec; }
+ bool fix_fields(THD *, Item **);
+ void fix_length_and_dec()
+ {
+ store_now_in_TIME(&ltime);
+ Item_temporal_func::fix_length_and_dec();
+ set_persist_maybe_null(0);
+ }
bool get_date(MYSQL_TIME *res, uint fuzzy_date);
virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
bool check_vcol_func_processor(uchar *int_arg)
@@ -625,8 +603,7 @@ public:
class Item_func_now_local :public Item_func_now
{
public:
- Item_func_now_local() :Item_func_now() {}
- Item_func_now_local(Item *a) :Item_func_now(a) {}
+ Item_func_now_local(uint dec) :Item_func_now(dec) {}
const char *func_name() const { return "now"; }
virtual void store_now_in_TIME(MYSQL_TIME *now_time);
virtual enum Functype functype() const { return NOW_FUNC; }
@@ -636,8 +613,7 @@ public:
class Item_func_now_utc :public Item_func_now
{
public:
- Item_func_now_utc() :Item_func_now() {}
- Item_func_now_utc(Item *a) :Item_func_now(a) {}
+ Item_func_now_utc(uint dec) :Item_func_now(dec) {}
const char *func_name() const { return "utc_timestamp"; }
virtual void store_now_in_TIME(MYSQL_TIME *now_time);
};
@@ -650,16 +626,10 @@ public:
class Item_func_sysdate_local :public Item_func_now
{
public:
- Item_func_sysdate_local() :Item_func_now() {}
- Item_func_sysdate_local(Item *a) :Item_func_now(a) {}
+ Item_func_sysdate_local(uint dec) :Item_func_now(dec) {}
bool const_item() const { return 0; }
const char *func_name() const { return "sysdate"; }
void store_now_in_TIME(MYSQL_TIME *now_time);
- double val_real();
- longlong val_int();
- int save_in_field(Field *to, bool no_conversions);
- String *val_str(String *str);
- void fix_length_and_dec();
bool get_date(MYSQL_TIME *res, uint fuzzy_date);
void update_used_tables()
{
@@ -669,10 +639,10 @@ public:
};
-class Item_func_from_days :public Item_date
+class Item_func_from_days :public Item_datefunc
{
public:
- Item_func_from_days(Item *a) :Item_date(a) {}
+ Item_func_from_days(Item *a) :Item_datefunc(a) {}
const char *func_name() const { return "from_days"; }
bool get_date(MYSQL_TIME *res, uint fuzzy_date);
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
@@ -701,13 +671,11 @@ public:
};
-class Item_func_from_unixtime :public Item_date_func
+class Item_func_from_unixtime :public Item_temporal_func
{
THD *thd;
public:
- Item_func_from_unixtime(Item *a) :Item_date_func(a) {}
- longlong val_int();
- String *val_str(String *str);
+ Item_func_from_unixtime(Item *a) :Item_temporal_func(a) {}
const char *func_name() const { return "from_unixtime"; }
void fix_length_and_dec();
bool get_date(MYSQL_TIME *res, uint fuzzy_date);
@@ -728,7 +696,7 @@ class Time_zone;
tables can be used during this function calculation for loading time zone
descriptions.
*/
-class Item_func_convert_tz :public Item_date_func
+class Item_func_convert_tz :public Item_temporal_func
{
/*
If time zone parameters are constants we are caching objects that
@@ -740,9 +708,7 @@ class Item_func_convert_tz :public Item_date_func
Time_zone *from_tz, *to_tz;
public:
Item_func_convert_tz(Item *a, Item *b, Item *c):
- Item_date_func(a, b, c), from_tz_cached(0), to_tz_cached(0) {}
- longlong val_int();
- String *val_str(String *str);
+ Item_temporal_func(a, b, c), from_tz_cached(0), to_tz_cached(0) {}
const char *func_name() const { return "convert_tz"; }
void fix_length_and_dec();
bool get_date(MYSQL_TIME *res, uint fuzzy_date);
@@ -750,29 +716,21 @@ class Item_func_convert_tz :public Item_date_func
};
-class Item_func_sec_to_time :public Item_str_timefunc
+class Item_func_sec_to_time :public Item_timefunc
{
public:
- Item_func_sec_to_time(Item *item) :Item_str_timefunc(item) {}
- double val_real()
- {
- DBUG_ASSERT(fixed == 1);
- return (double) Item_func_sec_to_time::val_int();
- }
- longlong val_int();
- String *val_str(String *);
+ Item_func_sec_to_time(Item *item) :Item_timefunc(item) {}
+ bool get_date(MYSQL_TIME *res, uint fuzzy_date);
void fix_length_and_dec()
- {
- Item_str_timefunc::fix_length_and_dec();
- collation.set(&my_charset_bin);
- maybe_null=1;
+ {
+ decimals= args[0]->decimals;
+ Item_timefunc::fix_length_and_dec();
}
const char *func_name() const { return "sec_to_time"; }
- bool result_as_longlong() { return TRUE; }
};
-class Item_date_add_interval :public Item_date_func
+class Item_date_add_interval :public Item_temporal_func
{
String value;
enum_field_types cached_field_type;
@@ -781,12 +739,10 @@ public:
const interval_type int_type; // keep it public
const bool date_sub_interval; // keep it public
Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg)
- :Item_date_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
- String *val_str(String *);
+ :Item_temporal_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
const char *func_name() const { return "date_add_interval"; }
void fix_length_and_dec();
enum_field_types field_type() const { return cached_field_type; }
- longlong val_int();
bool get_date(MYSQL_TIME *res, uint fuzzy_date);
bool eq(const Item *item, bool binary_cmp) const;
virtual void print(String *str, enum_query_type query_type);
@@ -847,177 +803,84 @@ class Item_extract :public Item_int_func
};
-class Item_typecast :public Item_str_func
-{
-public:
- Item_typecast(Item *a) :Item_str_func(a) {}
- String *val_str(String *a)
- {
- DBUG_ASSERT(fixed == 1);
- String *tmp=args[0]->val_str(a);
- null_value=args[0]->null_value;
- if (tmp)
- tmp->set_charset(collation.collation);
- return tmp;
- }
- void fix_length_and_dec()
- {
- collation.set(&my_charset_bin);
- max_length=args[0]->max_length;
- }
- virtual const char* cast_type() const= 0;
- virtual void print(String *str, enum_query_type query_type);
-};
-
-
-class Item_typecast_maybe_null :public Item_typecast
-{
-public:
- Item_typecast_maybe_null(Item *a) :Item_typecast(a) {}
- void fix_length_and_dec()
- {
- collation.set(&my_charset_bin);
- max_length=args[0]->max_length;
- maybe_null= 1;
- }
-};
-
-
-class Item_char_typecast :public Item_typecast
+class Item_char_typecast :public Item_str_func
{
- int cast_length;
+ uint cast_length;
CHARSET_INFO *cast_cs, *from_cs;
bool charset_conversion;
String tmp_value;
public:
- Item_char_typecast(Item *a, int length_arg, CHARSET_INFO *cs_arg)
- :Item_typecast(a), cast_length(length_arg), cast_cs(cs_arg) {}
+ Item_char_typecast(Item *a, uint length_arg, CHARSET_INFO *cs_arg)
+ :Item_str_func(a), cast_length(length_arg), cast_cs(cs_arg) {}
enum Functype functype() const { return CHAR_TYPECAST_FUNC; }
bool eq(const Item *item, bool binary_cmp) const;
const char *func_name() const { return "cast_as_char"; }
- const char* cast_type() const { return "char"; };
String *val_str(String *a);
void fix_length_and_dec();
- virtual void print(String *str, enum_query_type query_type);
+ void print(String *str, enum_query_type query_type);
};
-class Item_date_typecast :public Item_typecast_maybe_null
+class Item_temporal_typecast: public Item_temporal_func
{
public:
- Item_date_typecast(Item *a) :Item_typecast_maybe_null(a) {}
+ Item_temporal_typecast(Item *a) :Item_temporal_func(a) {}
+ virtual const char *cast_type() const = 0;
+ void print(String *str, enum_query_type query_type);
+ void fix_length_and_dec()
+ {
+ if (decimals == NOT_FIXED_DEC)
+ decimals= args[0]->decimals;
+ Item_temporal_func::fix_length_and_dec();
+ }
+};
+
+class Item_date_typecast :public Item_temporal_typecast
+{
+public:
+ Item_date_typecast(Item *a) :Item_temporal_typecast(a) {}
const char *func_name() const { return "cast_as_date"; }
- String *val_str(String *str);
bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
- bool get_time(MYSQL_TIME *ltime);
const char *cast_type() const { return "date"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
- Field *tmp_table_field(TABLE *table)
- {
- return tmp_table_field_from_field_type(table, 0);
- }
- void fix_length_and_dec()
- {
- collation.set(&my_charset_bin);
- max_length= 10;
- maybe_null= 1;
- }
- bool result_as_longlong() { return TRUE; }
- longlong val_int();
- double val_real() { return (double) val_int(); }
- my_decimal *val_decimal(my_decimal *decimal_value)
- {
- DBUG_ASSERT(fixed == 1);
- return val_decimal_from_date(decimal_value);
- }
- int save_in_field(Field *field, bool no_conversions)
- {
- return save_date_in_field(field);
- }
};
-class Item_time_typecast :public Item_typecast_maybe_null
+class Item_time_typecast :public Item_temporal_typecast
{
public:
- Item_time_typecast(Item *a) :Item_typecast_maybe_null(a) {}
+ Item_time_typecast(Item *a, uint dec_arg)
+ :Item_temporal_typecast(a) { decimals= dec_arg; }
const char *func_name() const { return "cast_as_time"; }
- String *val_str(String *str);
- bool get_time(MYSQL_TIME *ltime);
+ bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
const char *cast_type() const { return "time"; }
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
- Field *tmp_table_field(TABLE *table)
- {
- return tmp_table_field_from_field_type(table, 0);
- }
- bool result_as_longlong() { return TRUE; }
- longlong val_int();
- double val_real() { return val_real_from_decimal(); }
- my_decimal *val_decimal(my_decimal *decimal_value)
- {
- DBUG_ASSERT(fixed == 1);
- return val_decimal_from_time(decimal_value);
- }
- int save_in_field(Field *field, bool no_conversions)
- {
- return save_time_in_field(field);
- }
};
-class Item_datetime_typecast :public Item_typecast_maybe_null
+class Item_datetime_typecast :public Item_temporal_typecast
{
public:
- Item_datetime_typecast(Item *a) :Item_typecast_maybe_null(a) {}
+ Item_datetime_typecast(Item *a, uint dec_arg)
+ :Item_temporal_typecast(a) { decimals= dec_arg; }
const char *func_name() const { return "cast_as_datetime"; }
- String *val_str(String *str);
const char *cast_type() const { return "datetime"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
- Field *tmp_table_field(TABLE *table)
- {
- return tmp_table_field_from_field_type(table, 0);
- }
- void fix_length_and_dec()
- {
- collation.set(&my_charset_bin);
- maybe_null= 1;
- max_length= MAX_DATETIME_FULL_WIDTH * MY_CHARSET_BIN_MB_MAXLEN;
- decimals= DATETIME_DEC;
- }
- bool result_as_longlong() { return TRUE; }
- longlong val_int();
- double val_real() { return val_real_from_decimal(); }
- double val() { return (double) val_int(); }
- my_decimal *val_decimal(my_decimal *decimal_value)
- {
- DBUG_ASSERT(fixed == 1);
- return val_decimal_from_date(decimal_value);
- }
- int save_in_field(Field *field, bool no_conversions)
- {
- return save_date_in_field(field);
- }
+ bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
};
-class Item_func_makedate :public Item_date_func
+
+class Item_func_makedate :public Item_temporal_func
{
public:
- Item_func_makedate(Item *a,Item *b) :Item_date_func(a,b) {}
- String *val_str(String *str);
+ Item_func_makedate(Item *a,Item *b) :Item_temporal_func(a,b) {}
const char *func_name() const { return "makedate"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
- void fix_length_and_dec()
- {
- decimals=0;
- max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
- /* It returns NULL when the second argument is less or equal to 0 */
- maybe_null= 1;
- }
- longlong val_int();
+ bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
};
-class Item_func_add_time :public Item_str_func
+class Item_func_add_time :public Item_temporal_func
{
const bool is_date;
int sign;
@@ -1025,63 +888,39 @@ class Item_func_add_time :public Item_str_func
public:
Item_func_add_time(Item *a, Item *b, bool type_arg, bool neg_arg)
- :Item_str_func(a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; }
- String *val_str(String *str);
+ :Item_temporal_func(a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; }
enum_field_types field_type() const { return cached_field_type; }
void fix_length_and_dec();
-
- Field *tmp_table_field(TABLE *table)
- {
- return tmp_table_field_from_field_type(table, 0);
- }
+ bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
virtual void print(String *str, enum_query_type query_type);
const char *func_name() const { return "add_time"; }
- double val_real() { return val_real_from_decimal(); }
- my_decimal *val_decimal(my_decimal *decimal_value)
- {
- DBUG_ASSERT(fixed == 1);
- if (cached_field_type == MYSQL_TYPE_TIME)
- return val_decimal_from_time(decimal_value);
- if (cached_field_type == MYSQL_TYPE_DATETIME)
- return val_decimal_from_date(decimal_value);
- return Item_str_func::val_decimal(decimal_value);
- }
- int save_in_field(Field *field, bool no_conversions)
- {
- if (cached_field_type == MYSQL_TYPE_TIME)
- return save_time_in_field(field);
- if (cached_field_type == MYSQL_TYPE_DATETIME)
- return save_date_in_field(field);
- return Item_str_func::save_in_field(field, no_conversions);
- }
};
-class Item_func_timediff :public Item_str_timefunc
+class Item_func_timediff :public Item_timefunc
{
public:
Item_func_timediff(Item *a, Item *b)
- :Item_str_timefunc(a, b) {}
- String *val_str(String *str);
+ :Item_timefunc(a, b) {}
const char *func_name() const { return "timediff"; }
void fix_length_and_dec()
{
- Item_str_timefunc::fix_length_and_dec();
- maybe_null= 1;
+ decimals= max(args[0]->decimals, args[1]->decimals);
+ Item_timefunc::fix_length_and_dec();
}
+ bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
};
-class Item_func_maketime :public Item_str_timefunc
+class Item_func_maketime :public Item_timefunc
{
public:
Item_func_maketime(Item *a, Item *b, Item *c)
- :Item_str_timefunc(a, b, c)
- {
- maybe_null= TRUE;
- }
- String *val_str(String *str);
+ :Item_timefunc(a, b, c)
+ {}
const char *func_name() const { return "maketime"; }
+ bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
};
+
class Item_func_microsecond :public Item_int_func
{
public:
@@ -1091,7 +930,7 @@ public:
void fix_length_and_dec()
{
decimals=0;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
@@ -1113,7 +952,7 @@ public:
void fix_length_and_dec()
{
decimals=0;
- maybe_null=1;
+ set_persist_maybe_null(1);
}
virtual void print(String *str, enum_query_type query_type);
};
@@ -1135,7 +974,7 @@ public:
const char *func_name() const { return "get_format"; }
void fix_length_and_dec()
{
- maybe_null= 1;
+ set_persist_maybe_null(1);
decimals=0;
max_length=17*MY_CHARSET_BIN_MB_MAXLEN;
}
@@ -1143,37 +982,26 @@ public:
};
-class Item_func_str_to_date :public Item_str_func
+class Item_func_str_to_date :public Item_temporal_func
{
enum_field_types cached_field_type;
- date_time_format_types cached_format_type;
timestamp_type cached_timestamp_type;
bool const_item;
public:
Item_func_str_to_date(Item *a, Item *b)
- :Item_str_func(a, b), const_item(false)
+ :Item_temporal_func(a, b), const_item(false)
{}
- String *val_str(String *str);
bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
const char *func_name() const { return "str_to_date"; }
enum_field_types field_type() const { return cached_field_type; }
void fix_length_and_dec();
- Field *tmp_table_field(TABLE *table)
- {
- return tmp_table_field_from_field_type(table, 1);
- }
};
-class Item_func_last_day :public Item_date
+class Item_func_last_day :public Item_datefunc
{
public:
- Item_func_last_day(Item *a) :Item_date(a) {}
- void fix_length_and_dec()
- {
- Item_date::fix_length_and_dec();
- maybe_null= 1;
- }
+ Item_func_last_day(Item *a) :Item_datefunc(a) {}
const char *func_name() const { return "last_day"; }
bool get_date(MYSQL_TIME *res, uint fuzzy_date);
};
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index a873cc0b277..4c12e6528ac 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -2579,6 +2579,7 @@ void Item_xml_str_func::fix_length_and_dec()
int rc;
nodeset_func= 0;
+ set_persist_maybe_null(1);
if (agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1))
return;
diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h
index ce33d161c79..be56a83349f 100644
--- a/sql/item_xmlfunc.h
+++ b/sql/item_xmlfunc.h
@@ -30,14 +30,10 @@ protected:
public:
Item_xml_str_func(Item *a, Item *b):
Item_str_func(a,b)
- {
- maybe_null= TRUE;
- }
+ {}
Item_xml_str_func(Item *a, Item *b, Item *c):
Item_str_func(a,b,c)
- {
- maybe_null= TRUE;
- }
+ {}
void fix_length_and_dec();
String *parse_xml(String *raw_xml, String *parsed_xml_buf);
bool check_vcol_func_processor(uchar *int_arg)
diff --git a/sql/key.cc b/sql/key.cc
index fec67b35ebc..b8edb2b3119 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -106,30 +106,46 @@ int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field,
@param from_record full record to be copied from
@param key_info descriptor of the index
@param key_length specifies length of all keyparts that will be copied
+ @param with_zerofill skipped bytes in the key buffer to be filled with 0
*/
void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
- uint key_length)
+ uint key_length, bool with_zerofill)
{
uint length;
KEY_PART_INFO *key_part;
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);
+ if (with_zerofill)
+ bzero((char*) to_key, length);
+ continue;
+ }
}
if (key_part->key_part_flag & HA_BLOB_PART ||
key_part->key_part_flag & HA_VAR_LENGTH_PART)
{
key_length-= HA_KEY_BLOB_LENGTH;
length= min(key_length, key_part->length);
- key_part->field->get_key_image(to_key, length, Field::itRAW);
+ uint bytes= key_part->field->get_key_image(to_key, length, Field::itRAW);
+ if (with_zerofill && bytes < length)
+ bzero((char*) to_key + bytes, length - bytes);
to_key+= HA_KEY_BLOB_LENGTH;
}
else
@@ -141,8 +157,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;
}
}
@@ -169,16 +183,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)
{
@@ -232,8 +258,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;
}
}
@@ -551,3 +575,287 @@ 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);
+ LINT_INIT(length);
+ LINT_INIT(pack_length);
+
+ 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:
+ 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:
+ case HA_KEYTYPE_VARTEXT2:
+ cs= key_part->field->charset();
+ length= uint2korr(pos);
+ pack_length= 2;
+ break;
+ case HA_KEYTYPE_VARBINARY1:
+ 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);
+ LINT_INIT(length1);
+ LINT_INIT(length2);
+ LINT_INIT(pack_length);
+
+ 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:
+ case HA_KEYTYPE_VARTEXT2:
+ case HA_KEYTYPE_VARBINARY2:
+ key1+= 2; key2+= 2;
+ break;
+ default:
+ ;
+ }
+ continue;
+ }
+ if (*pos1 != *pos2)
+ return TRUE;
+ 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:
+ case HA_KEYTYPE_VARTEXT2:
+ cs= key_part->field->charset();
+ length1= uint2korr(pos1);
+ length2= uint2korr(pos2);
+ pack_length= 2;
+ break;
+ case HA_KEYTYPE_VARBINARY1:
+ 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/lex.h b/sql/lex.h
index f304e0412fa..5d7546dcdc9 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -107,6 +107,7 @@ static SYMBOL symbols[] = {
{ "CHARACTER", SYM(CHAR_SYM)},
{ "CHARSET", SYM(CHARSET)},
{ "CHECK", SYM(CHECK_SYM)},
+ { "CHECKPOINT", SYM(CHECKPOINT_SYM)},
{ "CHECKSUM", SYM(CHECKSUM_SYM)},
{ "CIPHER", SYM(CIPHER_SYM)},
{ "CLIENT", SYM(CLIENT_SYM)},
@@ -118,6 +119,12 @@ static SYMBOL symbols[] = {
{ "COLLATION", SYM(COLLATION_SYM)},
{ "COLUMN", SYM(COLUMN_SYM)},
{ "COLUMNS", SYM(COLUMNS)},
+ { "COLUMN_ADD", SYM(COLUMN_ADD_SYM)},
+ { "COLUMN_CREATE", SYM(COLUMN_CREATE_SYM)},
+ { "COLUMN_DELETE", SYM(COLUMN_DELETE_SYM)},
+ { "COLUMN_EXISTS", SYM(COLUMN_EXISTS_SYM)},
+ { "COLUMN_GET", SYM(COLUMN_GET_SYM)},
+ { "COLUMN_LIST", SYM(COLUMN_LIST_SYM)},
{ "COMMENT", SYM(COMMENT_SYM)},
{ "COMMIT", SYM(COMMIT_SYM)},
{ "COMMITTED", SYM(COMMITTED_SYM)},
@@ -234,6 +241,7 @@ static SYMBOL symbols[] = {
{ "GRANTS", SYM(GRANTS)},
{ "GROUP", SYM(GROUP_SYM)},
{ "HANDLER", SYM(HANDLER_SYM)},
+ { "HARD", SYM(HARD_SYM)},
{ "HASH", SYM(HASH_SYM)},
{ "HAVING", SYM(HAVING)},
{ "HELP", SYM(HELP_SYM)},
@@ -380,6 +388,7 @@ static SYMBOL symbols[] = {
{ "ON", SYM(ON)},
{ "ONE", SYM(ONE_SYM)},
{ "ONE_SHOT", SYM(ONE_SHOT_SYM)},
+ { "ONLINE", SYM(ONLINE_SYM)},
{ "OPEN", SYM(OPEN_SYM)},
{ "OPTIMIZE", SYM(OPTIMIZE)},
{ "OPTIONS", SYM(OPTIONS_SYM)},
@@ -491,6 +500,7 @@ static SYMBOL symbols[] = {
{ "SNAPSHOT", SYM(SNAPSHOT_SYM)},
{ "SMALLINT", SYM(SMALLINT)},
{ "SOCKET", SYM(SOCKET_SYM)},
+ { "SOFT", SYM(SOFT_SYM)},
{ "SOME", SYM(ANY_SYM)},
{ "SONAME", SYM(SONAME_SYM)},
{ "SOUNDS", SYM(SOUNDS_SYM)},
diff --git a/sql/lock.cc b/sql/lock.cc
index 1b66fd3d33f..ba6bac22945 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -86,41 +86,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[]=
@@ -134,6 +103,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;
@@ -196,14 +166,39 @@ 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");
+ DBUG_ENTER("mysql_lock_tables(tables)");
*need_reopen= FALSE;
@@ -212,137 +207,177 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
for (;;)
{
- if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS,
- &write_lock_used)) ||
- ! sql_lock->table_count)
+ if (!(sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS,
+ &write_lock_used)) ||
+ !sql_lock->table_count)
break;
+ rc= mysql_lock_tables(thd, sql_lock, write_lock_used != 0, flags,
+ need_reopen);
+ if (!rc)
+ break; // Got lock
+ my_free(sql_lock, MYF(0));
+ if (rc > 0)
+ DBUG_RETURN(0); // Failed
+ }
+ DBUG_RETURN(sql_lock);
+}
- if (global_read_lock && write_lock_used &&
- ! (flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK))
+/**
+ Lock a table based on a MYSQL_LOCK structure.
+
+ 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 fatal error
+ @return -1 retry
+*/
+
+int mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock,
+ bool write_lock_used,
+ uint flags, bool *need_reopen)
+{
+ int res= 0;
+ int rc;
+ DBUG_ENTER("mysql_lock_tables(sql_lock)");
+ *need_reopen= FALSE;
+
+ if (write_lock_used && !(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK))
+ {
+ if (global_read_lock)
{
/*
- Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
- Wait until the lock is gone
+ 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))
{
/* 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;
+ reset_lock_data(sql_lock, 1);
+ DBUG_RETURN(1); // Fatal error
}
if (thd->version != refresh_version)
{
/* 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;
+ reset_lock_data(sql_lock, 1);
+ goto retry;
}
}
- if (!(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) &&
- write_lock_used &&
- opt_readonly &&
+ if (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.
+ 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;
+ reset_lock_data(sql_lock, 1);
+ DBUG_RETURN(1); // Fatal error
}
+ }
- 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));
- /* Lock on the copied half of the lock data array. */
- rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks +
- sql_lock->lock_count,
- sql_lock->lock_count,
- thd->lock_id)];
- if (rc > 1) /* a timeout or a deadlock */
- {
+ thd_proc_info(thd, "System lock");
+ if (lock_external(thd, sql_lock->table, sql_lock->table_count))
+ {
+ /* Clear the lock type of all lock data to avoid reusage. */
+ res= 1; // Fatal error
+ goto end;
+ }
+ thd_proc_info(thd, "Table lock");
+ DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
+ /* 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));
+ /* Lock on the copied half of the lock data array. */
+ rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks +
+ sql_lock->lock_count,
+ sql_lock->lock_count,
+ thd->lock_id)];
+ if (rc) // Locking failed
+ {
+ if (sql_lock->table_count)
VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
+
+ /*
+ 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, 1);
+
+ if (rc > 1)
+ {
my_error(rc, MYF(0));
- my_free((uchar*) sql_lock,MYF(0));
- sql_lock= 0;
- break;
+ DBUG_RETURN(1);
}
- else if (rc == 1) /* aborted */
+ DBUG_ASSERT(rc == 1); // Timeout
+ thd->some_tables_deleted= 1; // Reopen tables
+ sql_lock->lock_count= 0; // Locks are already freed
+ /* Retry */
+ }
+ else
+ {
+ /*
+ Lock worked. Now check that nothing happend while we where waiting
+ to get the lock that would require us to free it.
+ */
+ if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH))
{
- /*
- 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
+ res= 0;
+ goto end; /* Lock was not aborted. Return to upper level */
}
- else if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH))
+ if (!thd->open_tables && !(flags & MYSQL_LOCK_NOT_TEMPORARY))
{
/*
- Thread was killed or lock aborted. Let upper level close all
- used tables and retry or give error.
+ 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->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;
+ goto end;
}
- thd_proc_info(thd, 0);
+ /* Free lock and retry */
+ }
+
+ /* some table was altered or deleted. reopen tables marked deleted */
+ mysql_unlock_tables(thd, sql_lock, 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
+ res= -1; // Retry
+ if (flags & MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN)
+ {
+ *need_reopen= TRUE; // Upper level will retry
+ DBUG_RETURN(1); // Fatal error
}
+ if (wait_for_tables(thd))
+ res= 1; // Couldn't open tables
+
+end:
thd_proc_info(thd, 0);
if (thd->killed)
{
thd->send_kill_message();
- if (sql_lock)
- {
- mysql_unlock_tables(thd,sql_lock);
- sql_lock=0;
- }
+ if (res == 0)
+ mysql_unlock_tables(thd,sql_lock,0);
+ else
+ reset_lock_data(sql_lock, 1);
+ res= 1; // Fatal
}
-
thd->set_time_after_lock();
- DBUG_RETURN (sql_lock);
+ DBUG_RETURN(res);
}
@@ -382,15 +417,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;
}
@@ -849,12 +884,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");
@@ -865,8 +900,10 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
for (i=tables=lock_count=0 ; i < count ; i++)
{
TABLE *t= table_ptr[i];
-
- if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE)
+
+
+ if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE &&
+ t->s->tmp_table != INTERNAL_TMP_TABLE)
{
tables+= t->file->lock_count();
lock_count++;
@@ -893,8 +930,10 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
{
TABLE *table;
enum thr_lock_type lock_type;
-
- if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
+ THR_LOCK_DATA **locks_start;
+ table= table_ptr[i];
+ if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE ||
+ table->s->tmp_table == INTERNAL_TMP_TABLE)
continue;
lock_type= table->reginfo.lock_type;
DBUG_ASSERT(lock_type != TL_WRITE_DEFAULT && lock_type != TL_READ_DEFAULT);
@@ -906,12 +945,11 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
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 :
@@ -924,11 +962,14 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
}
*to++= table;
if (locks)
- for ( ; org_locks != locks ; org_locks++)
+ {
+ for ( ; locks_start != locks ; locks_start++)
{
- (*org_locks)->debug_print_param= (void *) table;
- (*org_locks)->lock->name= table->alias.c_ptr();
+ (*locks_start)->debug_print_param= (void *) table;
+ (*locks_start)->lock->name= table->alias.c_ptr();
+ (*locks_start)->org_type= (*locks_start)->type;
}
+ }
}
/*
We do not use 'tables', because there are cases where store_lock()
@@ -969,10 +1010,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;
@@ -980,10 +1024,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;
}
@@ -1446,7 +1487,7 @@ static void print_lock_error(int error, const char *table)
****************************************************************************/
-volatile uint global_read_lock=0;
+volatile uint global_read_lock=0, global_disable_checkpoint= 0;
volatile uint global_read_lock_blocks_commit=0;
static volatile uint protect_against_global_read_lock=0;
static volatile uint waiting_for_read_lock=0;
@@ -1505,6 +1546,14 @@ void unlock_global_read_lock(THD *thd)
tmp= --global_read_lock;
if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT)
--global_read_lock_blocks_commit;
+ if (thd->global_disable_checkpoint)
+ {
+ thd->global_disable_checkpoint= 0;
+ if (!--global_disable_checkpoint)
+ {
+ ha_checkpoint_state(0); // Enable checkpoints
+ }
+ }
pthread_mutex_unlock(&LOCK_global_read_lock);
/* Send the signal outside the mutex to avoid a context switch */
if (!tmp)
@@ -1627,6 +1676,24 @@ bool make_global_read_lock_block_commit(THD *thd)
/**
+ Disable checkpoints for all handlers
+ This is released in unlock_global_read_lock()
+*/
+
+void disable_checkpoints(THD *thd)
+{
+ pthread_mutex_lock(&LOCK_global_read_lock);
+ if (!thd->global_disable_checkpoint)
+ {
+ thd->global_disable_checkpoint= 1;
+ if (!global_disable_checkpoint++)
+ ha_checkpoint_state(1); // Disable checkpoints
+ }
+ pthread_mutex_unlock(&LOCK_global_read_lock);
+}
+
+
+/**
Broadcast COND_refresh and COND_global_read_lock.
Due to a bug in a threading library it could happen that a signal
diff --git a/sql/log.cc b/sql/log.cc
index e44f0ab0171..c1e0370613f 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -39,6 +39,7 @@
#endif
#include <mysql/plugin.h>
+#include "debug_sync.h"
#include "sql_show.h"
/* max size of the log message */
@@ -63,6 +64,39 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv);
static int binlog_commit(handlerton *hton, THD *thd, bool all);
static int binlog_rollback(handlerton *hton, THD *thd, bool all);
static int binlog_prepare(handlerton *hton, THD *thd, bool all);
+static int binlog_start_consistent_snapshot(handlerton *hton, THD *thd);
+
+static LEX_STRING const write_error_msg=
+ { C_STRING_WITH_LEN("error writing to the binary log") };
+
+static my_bool opt_optimize_thread_scheduling= TRUE;
+ulong binlog_checksum_options;
+#ifndef DBUG_OFF
+ulong opt_binlog_dbug_fsync_sleep= 0;
+#endif
+
+static my_bool mutexes_inited;
+pthread_mutex_t LOCK_prepare_ordered;
+pthread_mutex_t LOCK_commit_ordered;
+
+static ulonglong binlog_status_var_num_commits;
+static ulonglong binlog_status_var_num_group_commits;
+static char binlog_snapshot_file[FN_REFLEN];
+static ulonglong binlog_snapshot_position;
+
+static SHOW_VAR binlog_status_vars_detail[]=
+{
+ {"commits",
+ (char *)&binlog_status_var_num_commits, SHOW_LONGLONG},
+ {"group_commits",
+ (char *)&binlog_status_var_num_group_commits, SHOW_LONGLONG},
+ {"snapshot_file",
+ (char *)&binlog_snapshot_file, SHOW_CHAR},
+ {"snapshot_position",
+ (char *)&binlog_snapshot_position, SHOW_LONGLONG},
+ {NullS, NullS, SHOW_LONG}
+};
+
/**
Silence all errors and warnings reported when performing a write
@@ -136,50 +170,17 @@ char *make_once_alloced_filename(const char *basename, const char *ext)
/*
- Helper class to hold a mutex for the duration of the
- block.
-
- Eliminates the need for explicit unlocking of mutexes on, e.g.,
- error returns. On passing a null pointer, the sentry will not do
- anything.
- */
-class Mutex_sentry
-{
-public:
- Mutex_sentry(pthread_mutex_t *mutex)
- : m_mutex(mutex)
- {
- if (m_mutex)
- pthread_mutex_lock(mutex);
- }
-
- ~Mutex_sentry()
- {
- if (m_mutex)
- pthread_mutex_unlock(m_mutex);
-#ifndef DBUG_OFF
- m_mutex= 0;
-#endif
- }
-
-private:
- pthread_mutex_t *m_mutex;
-
- // It's not allowed to copy this object in any way
- Mutex_sentry(Mutex_sentry const&);
- void operator=(Mutex_sentry const&);
-};
-
-/*
Helper class to store binary log transaction data.
*/
class binlog_trx_data {
public:
binlog_trx_data()
: at_least_one_stmt_committed(0), incident(FALSE), m_pending(0),
- before_stmt_pos(MY_OFF_T_UNDEF)
+ before_stmt_pos(MY_OFF_T_UNDEF), last_commit_pos_offset(0),
+ using_xa(FALSE), xa_xid(0)
{
trans_log.end_of_file= max_binlog_cache_size;
+ last_commit_pos_file[0]= 0;
}
~binlog_trx_data()
@@ -231,11 +232,14 @@ public:
completely.
*/
void reset() {
- if (!empty())
+ if (trans_log.type != WRITE_CACHE || !empty())
truncate(0);
before_stmt_pos= MY_OFF_T_UNDEF;
incident= FALSE;
trans_log.end_of_file= max_binlog_cache_size;
+ using_xa= FALSE;
+ last_commit_pos_file[0]= 0;
+ last_commit_pos_offset= 0;
DBUG_ASSERT(empty());
}
@@ -280,6 +284,22 @@ public:
Binlog position before the start of the current statement.
*/
my_off_t before_stmt_pos;
+ /*
+ Binlog position for current transaction.
+ For START TRANSACTION WITH CONSISTENT SNAPSHOT, this is the binlog
+ position corresponding to the snapshot taken. During (and after) commit,
+ this is set to the binlog position corresponding to just after the
+ commit (so storage engines can store it in their transaction log).
+ */
+ char last_commit_pos_file[FN_REFLEN];
+ my_off_t last_commit_pos_offset;
+
+ /*
+ Flag set true if this transaction is committed with log_xid() as part of
+ XA, false if not.
+ */
+ bool using_xa;
+ my_xid xa_xid;
};
handlerton *binlog_hton;
@@ -378,7 +398,7 @@ void Log_to_csv_event_handler::cleanup()
*/
bool Log_to_csv_event_handler::
- log_general(THD *thd, time_t event_time, const char *user_host,
+ log_general(THD *thd, my_hrtime_t event_time, const char *user_host,
uint user_host_len, int thread_id,
const char *command_type, uint command_type_len,
const char *sql_text, uint sql_text_len,
@@ -460,8 +480,8 @@ bool Log_to_csv_event_handler::
DBUG_ASSERT(table->field[0]->type() == MYSQL_TYPE_TIMESTAMP);
- ((Field_timestamp*) table->field[0])->store_timestamp((my_time_t)
- event_time);
+ ((Field_timestamp*) table->field[0])->store_TIME(
+ hrtime_to_my_time(event_time), hrtime_sec_part(event_time));
/* do a write */
if (table->field[1]->store(user_host, user_host_len, client_cs) ||
@@ -525,7 +545,6 @@ err:
log_slow()
thd THD of the query
current_time current timestamp
- query_start_arg command start timestamp
user_host the pointer to the string with user@host info
user_host_len length of the user_host string. this is computed once
and passed to all general log event handlers
@@ -548,7 +567,7 @@ err:
*/
bool Log_to_csv_event_handler::
- log_slow(THD *thd, time_t current_time, time_t query_start_arg,
+ log_slow(THD *thd, my_hrtime_t current_time,
const char *user_host, uint user_host_len,
ulonglong query_utime, ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len)
@@ -562,6 +581,11 @@ bool Log_to_csv_event_handler::
Open_tables_state open_tables_backup;
CHARSET_INFO *client_cs= thd->variables.character_set_client;
bool save_time_zone_used;
+ long query_time= (long) min(query_utime/1000000, TIME_MAX_VALUE_SECONDS);
+ long lock_time= (long) min(lock_utime/1000000, TIME_MAX_VALUE_SECONDS);
+ long query_time_micro= (long) (query_utime % 1000000);
+ long lock_time_micro= (long) (lock_utime % 1000000);
+
DBUG_ENTER("Log_to_csv_event_handler::log_slow");
thd->push_internal_handler(& error_handler);
@@ -603,45 +627,34 @@ bool Log_to_csv_event_handler::
/* store the time and user values */
DBUG_ASSERT(table->field[0]->type() == MYSQL_TYPE_TIMESTAMP);
- ((Field_timestamp*) table->field[0])->store_timestamp((my_time_t)
- current_time);
+ ((Field_timestamp*) table->field[0])->store_TIME(
+ hrtime_to_my_time(current_time), hrtime_sec_part(current_time));
if (table->field[1]->store(user_host, user_host_len, client_cs))
goto err;
- if (query_start_arg)
- {
- longlong query_time= (longlong) (query_utime/1000000);
- longlong lock_time= (longlong) (lock_utime/1000000);
- /*
- A TIME field can not hold the full longlong range; query_time or
- lock_time may be truncated without warning here, if greater than
- 839 hours (~35 days)
- */
- MYSQL_TIME t;
- t.neg= 0;
+ /*
+ A TIME field can not hold the full longlong range; query_time or
+ lock_time may be truncated without warning here, if greater than
+ 839 hours (~35 days)
+ */
+ MYSQL_TIME t;
+ t.neg= 0;
+
+ /* fill in query_time field */
+ calc_time_from_sec(&t, query_time, query_time_micro);
+ if (table->field[2]->store_time(&t))
+ goto err;
+ /* lock_time */
+ calc_time_from_sec(&t, lock_time, lock_time_micro);
+ if (table->field[3]->store_time(&t))
+ goto err;
+ /* rows_sent */
+ if (table->field[4]->store((longlong) thd->sent_row_count, TRUE))
+ goto err;
+ /* rows_examined */
+ if (table->field[5]->store((longlong) thd->examined_row_count, TRUE))
+ goto err;
- /* fill in query_time field */
- calc_time_from_sec(&t, (long) min(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
- if (table->field[2]->store_time(&t, MYSQL_TIMESTAMP_TIME))
- goto err;
- /* lock_time */
- calc_time_from_sec(&t, (long) min(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
- if (table->field[3]->store_time(&t, MYSQL_TIMESTAMP_TIME))
- goto err;
- /* rows_sent */
- if (table->field[4]->store((longlong) thd->sent_row_count, TRUE))
- goto err;
- /* rows_examined */
- if (table->field[5]->store((longlong) thd->examined_row_count, TRUE))
- goto err;
- }
- else
- {
- table->field[2]->set_null();
- table->field[3]->set_null();
- table->field[4]->set_null();
- table->field[5]->set_null();
- }
/* fill database field */
if (thd->db)
{
@@ -778,14 +791,14 @@ void Log_to_file_event_handler::init_pthread_objects()
/** Wrapper around MYSQL_LOG::write() for slow log. */
bool Log_to_file_event_handler::
- log_slow(THD *thd, time_t current_time, time_t query_start_arg,
+ log_slow(THD *thd, my_hrtime_t current_time,
const char *user_host, uint user_host_len,
ulonglong query_utime, ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len)
{
Silence_log_table_errors error_handler;
thd->push_internal_handler(&error_handler);
- bool retval= mysql_slow_log.write(thd, current_time, query_start_arg,
+ bool retval= mysql_slow_log.write(thd, hrtime_to_my_time(current_time),
user_host, user_host_len,
query_utime, lock_utime, is_command,
sql_text, sql_text_len);
@@ -800,7 +813,7 @@ bool Log_to_file_event_handler::
*/
bool Log_to_file_event_handler::
- log_general(THD *thd, time_t event_time, const char *user_host,
+ log_general(THD *thd, my_hrtime_t event_time, const char *user_host,
uint user_host_len, int thread_id,
const char *command_type, uint command_type_len,
const char *sql_text, uint sql_text_len,
@@ -808,7 +821,8 @@ bool Log_to_file_event_handler::
{
Silence_log_table_errors error_handler;
thd->push_internal_handler(&error_handler);
- bool retval= mysql_log.write(event_time, user_host, user_host_len,
+ bool retval= mysql_log.write(hrtime_to_time(event_time), user_host,
+ user_host_len,
thread_id, command_type, command_type_len,
sql_text, sql_text_len);
thd->pop_internal_handler();
@@ -1017,8 +1031,6 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
if (*slow_log_handler_list)
{
- time_t current_time;
-
/* do not log slow queries from replication threads */
if (thd->slave_thread && !opt_log_slow_slave_statements)
return 0;
@@ -1038,16 +1050,12 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
sctx->ip ? sctx->ip : "", "]", NullS) -
user_host_buff);
- current_time= my_time_possible_from_micro(current_utime);
- if (thd->start_utime)
- {
- query_utime= (current_utime - thd->start_utime);
- lock_utime= (thd->utime_after_lock - thd->start_utime);
- }
- else
- {
- query_utime= lock_utime= 0;
- }
+ DBUG_ASSERT(thd->start_utime);
+ DBUG_ASSERT(thd->start_time);
+ query_utime= (current_utime - thd->start_utime);
+ lock_utime= (thd->utime_after_lock - thd->start_utime);
+ my_hrtime_t current_time= { hrtime_from_time(thd->start_time) +
+ thd->start_time_sec_part + query_utime };
if (!query)
{
@@ -1056,19 +1064,8 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
query_length= command_name[thd->command].length;
}
- if (!query_length)
- {
- /*
- Not a real query; Reset counts for slow query logging
- (QQ: Wonder if this is really needed)
- */
- thd->sent_row_count= thd->examined_row_count= 0;
- thd->query_plan_flags= QPLAN_INIT;
- thd->query_plan_fsort_passes= 0;
- }
-
for (current_handler= slow_log_handler_list; *current_handler ;)
- error= (*current_handler++)->log_slow(thd, current_time, thd->start_time,
+ error= (*current_handler++)->log_slow(thd, current_time,
user_host_buff, user_host_len,
query_utime, lock_utime, is_command,
query, query_length) || error;
@@ -1086,7 +1083,7 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
char user_host_buff[MAX_USER_HOST_SIZE + 1];
Security_context *sctx= thd->security_ctx;
uint user_host_len= 0;
- time_t current_time;
+ my_hrtime_t current_time;
DBUG_ASSERT(thd);
@@ -1103,7 +1100,7 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
sctx->ip ? sctx->ip : "", "]", NullS) -
user_host_buff;
- current_time= my_time(0);
+ current_time= my_hrtime();
while (*current_handler)
error|= (*current_handler++)->
log_general(thd, current_time, user_host_buff,
@@ -1423,6 +1420,7 @@ int binlog_init(void *p)
binlog_hton->commit= binlog_commit;
binlog_hton->rollback= binlog_rollback;
binlog_hton->prepare= binlog_prepare;
+ binlog_hton->start_consistent_snapshot= binlog_start_consistent_snapshot;
binlog_hton->flags= HTON_NOT_USER_SELECTABLE | HTON_HIDDEN;
return 0;
}
@@ -1439,91 +1437,118 @@ static int binlog_close_connection(handlerton *hton, THD *thd)
}
/*
- End a transaction.
+ End a transaction, writing events to the binary log.
SYNOPSIS
- binlog_end_trans()
+ binlog_flush_trx_cache()
thd The thread whose transaction should be ended
trx_data Pointer to the transaction data to use
- end_ev The end event to use, or NULL
all True if the entire transaction should be ended, false if
only the statement transaction should be ended.
+ end_ev The end event to use (COMMIT, ROLLBACK, or commit XID)
DESCRIPTION
End the currently open transaction. The transaction can be either
- a real transaction (if 'all' is true) or a statement transaction
- (if 'all' is false).
+ a real transaction or a statement transaction.
- If 'end_ev' is NULL, the transaction is a rollback of only
- transactional tables, so the transaction cache will be truncated
- to either just before the last opened statement transaction (if
- 'all' is false), or reset completely (if 'all' is true).
+ This can be to commit a transaction, with a COMMIT query event or an XA
+ commit XID event. But it can also be to rollback a transaction with a
+ ROLLBACK query event, used for rolling back transactions which also
+ contain updates to non-transactional tables.
*/
static int
-binlog_end_trans(THD *thd, binlog_trx_data *trx_data,
- Log_event *end_ev, bool all)
+binlog_flush_trx_cache(THD *thd, binlog_trx_data *trx_data,
+ Log_event *end_ev, bool all)
{
- DBUG_ENTER("binlog_end_trans");
- int error=0;
+ DBUG_ENTER("binlog_flush_trx_cache");
IO_CACHE *trans_log= &trx_data->trans_log;
- DBUG_PRINT("enter", ("transaction: %s end_ev: 0x%lx",
- all ? "all" : "stmt", (long) end_ev));
DBUG_PRINT("info", ("thd->options={ %s%s}",
FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
FLAGSTR(thd->options, OPTION_BEGIN)));
+ if (thd->binlog_flush_pending_rows_event(TRUE))
+ DBUG_RETURN(1);
+
/*
- NULL denotes ROLLBACK with nothing to replicate: i.e., rollback of
- only transactional tables. If the transaction contain changes to
- any non-transactiona tables, we need write the transaction and log
- a ROLLBACK last.
- */
- if (end_ev != NULL)
- {
- if (thd->binlog_flush_pending_rows_event(TRUE))
- DBUG_RETURN(1);
- /*
- Doing a commit or a rollback including non-transactional tables,
- i.e., ending a transaction where we might write the transaction
- cache to the binary log.
-
- We can always end the statement when ending a transaction since
- transactions are not allowed inside stored functions. If they
- were, we would have to ensure that we're not ending a statement
- inside a stored function.
- */
- error= mysql_bin_log.write(thd, &trx_data->trans_log, end_ev,
- trx_data->has_incident());
- trx_data->reset();
+ Doing a commit or a rollback including non-transactional tables,
+ i.e., ending a transaction where we might write the transaction
+ cache to the binary log.
+
+ We can always end the statement when ending a transaction since
+ transactions are not allowed inside stored functions. If they
+ were, we would have to ensure that we're not ending a statement
+ inside a stored function.
+ */
+ int error= mysql_bin_log.write_transaction_to_binlog(thd, trx_data,
+ end_ev, all);
- statistic_increment(binlog_cache_use, &LOCK_status);
- if (trans_log->disk_writes != 0)
- {
- statistic_increment(binlog_cache_disk_use, &LOCK_status);
- trans_log->disk_writes= 0;
- }
- }
- else
+ trx_data->reset();
+
+ statistic_increment(binlog_cache_use, &LOCK_status);
+ if (trans_log->disk_writes != 0)
{
- /*
- If rolling back an entire transaction or a single statement not
- inside a transaction, we reset the transaction cache.
+ statistic_increment(binlog_cache_disk_use, &LOCK_status);
+ trans_log->disk_writes= 0;
+ }
- If rolling back a statement in a transaction, we truncate the
- transaction cache to remove the statement.
- */
- thd->binlog_remove_pending_rows_event(TRUE);
- if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
- {
- if (trx_data->has_incident())
- error= mysql_bin_log.write_incident(thd, TRUE);
- trx_data->reset();
- }
- else // ...statement
- trx_data->truncate(trx_data->before_stmt_pos);
+ DBUG_ASSERT(thd->binlog_get_pending_rows_event() == NULL);
+ DBUG_RETURN(error);
+}
+
+/*
+ Discard a transaction, ie. ROLLBACK with only transactional table updates.
+
+ SYNOPSIS
+ binlog_truncate_trx_cache()
+
+ thd The thread whose transaction should be ended
+ trx_data Pointer to the transaction data to use
+ all True if the entire transaction should be ended, false if
+ only the statement transaction should be ended.
+
+ DESCRIPTION
+
+ Rollback (and end) a transaction that only modifies transactional
+ tables. The transaction can be either a real transaction (if 'all' is
+ true) or a statement transaction (if 'all' is false).
+
+ The transaction cache will be truncated to either just before the last
+ opened statement transaction (if 'all' is false), or reset completely (if
+ 'all' is true).
+ */
+static int
+binlog_truncate_trx_cache(THD *thd, binlog_trx_data *trx_data, bool all)
+{
+ DBUG_ENTER("binlog_truncate_trx_cache");
+ int error= 0;
+ DBUG_PRINT("enter", ("transaction: %s", all ? "all" : "stmt"));
+ DBUG_PRINT("info", ("thd->options={ %s%s}",
+ FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
+ FLAGSTR(thd->options, OPTION_BEGIN)));
+
+ /*
+ ROLLBACK with nothing to replicate: i.e., rollback of only transactional
+ tables.
+ */
+
+ /*
+ If rolling back an entire transaction or a single statement not
+ inside a transaction, we reset the transaction cache.
+
+ If rolling back a statement in a transaction, we truncate the
+ transaction cache to remove the statement.
+ */
+ thd->binlog_remove_pending_rows_event(TRUE);
+ if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
+ {
+ if (trx_data->has_incident())
+ error= mysql_bin_log.write_incident(thd);
+ trx_data->reset();
}
+ else // ...statement
+ trx_data->truncate(trx_data->before_stmt_pos);
DBUG_ASSERT(thd->binlog_get_pending_rows_event() == NULL);
DBUG_RETURN(error);
@@ -1535,7 +1560,7 @@ static int binlog_prepare(handlerton *hton, THD *thd, bool all)
do nothing.
just pretend we can do 2pc, so that MySQL won't
switch to 1pc.
- real work will be done in MYSQL_BIN_LOG::log_xid()
+ real work will be done in MYSQL_BIN_LOG::log_and_order()
*/
return 0;
}
@@ -1586,8 +1611,8 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
(trans_has_no_stmt_committed(thd, all) &&
!stmt_has_updated_trans_table(thd) && stmt_has_updated_non_trans_table(thd)))
{
- Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0);
- error= binlog_end_trans(thd, trx_data, &qev, all);
+ Query_log_event end_ev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0);
+ error= binlog_flush_trx_cache(thd, trx_data, &end_ev, all);
}
trx_data->at_least_one_stmt_committed = my_b_tell(&trx_data->trans_log) > 0;
@@ -1651,7 +1676,7 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
(thd->options & OPTION_KEEP_LOG)) &&
mysql_bin_log.check_write_error(thd))
trx_data->set_incident();
- error= binlog_end_trans(thd, trx_data, 0, all);
+ error= binlog_truncate_trx_cache(thd, trx_data, all);
}
else
{
@@ -1670,8 +1695,8 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
stmt_has_updated_non_trans_table(thd) &&
thd->current_stmt_binlog_row_based))
{
- Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0);
- error= binlog_end_trans(thd, trx_data, &qev, all);
+ Query_log_event end_ev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0);
+ error= binlog_flush_trx_cache(thd, trx_data, &end_ev, all);
}
/*
Otherwise, we simply truncate the cache as there is no change on
@@ -1679,7 +1704,7 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
*/
else if (ending_trans(thd, all) ||
(!(thd->options & OPTION_KEEP_LOG) && !stmt_has_updated_non_trans_table(thd)))
- error= binlog_end_trans(thd, trx_data, 0, all);
+ error= binlog_truncate_trx_cache(thd, trx_data, all);
}
if (!all)
trx_data->before_stmt_pos = MY_OFF_T_UNDEF; // part of the stmt rollback
@@ -1774,7 +1799,7 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
append_identifier(thd, &log_query,
thd->lex->ident.str, thd->lex->ident.length))
DBUG_RETURN(1);
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
TRUE, TRUE, errcode);
DBUG_RETURN(mysql_bin_log.write(&qinfo));
@@ -1797,7 +1822,7 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
append_identifier(thd, &log_query,
thd->lex->ident.str, thd->lex->ident.length))
DBUG_RETURN(1);
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
TRUE, TRUE, errcode);
DBUG_RETURN(mysql_bin_log.write(&qinfo));
@@ -2319,7 +2344,6 @@ err:
thd THD of the query
current_time current timestamp
- query_start_arg command start timestamp
user_host the pointer to the string with user@host info
user_host_len length of the user_host string. this is computed once
and passed to all general log event handlers
@@ -2341,7 +2365,7 @@ err:
*/
bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
- time_t query_start_arg, const char *user_host,
+ const char *user_host,
uint user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len)
@@ -2521,7 +2545,11 @@ const char *MYSQL_LOG::generate_name(const char *log_name,
MYSQL_BIN_LOG::MYSQL_BIN_LOG()
:bytes_written(0), prepared_xids(0), file_id(1), open_count(1),
need_start_event(TRUE),
+ group_commit_queue(0), group_commit_queue_busy(FALSE),
+ num_commits(0), num_group_commits(0),
is_relay_log(0),
+ checksum_alg_reset(BINLOG_CHECKSUM_ALG_UNDEF),
+ relay_log_checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF),
description_event_for_exec(0), description_event_for_queue(0)
{
/*
@@ -2577,6 +2605,7 @@ void MYSQL_BIN_LOG::init_pthread_objects()
(void) my_pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW, "LOCK_index",
MYF_NO_DEADLOCK_DETECTION);
(void) pthread_cond_init(&update_cond, 0);
+ (void) pthread_cond_init(&COND_queue_busy, 0);
}
@@ -2756,10 +2785,23 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
as we won't be able to reset it later
*/
if (io_cache_type == WRITE_CACHE)
- s.flags|= LOG_EVENT_BINLOG_IN_USE_F;
+ s.flags |= LOG_EVENT_BINLOG_IN_USE_F;
+ s.checksum_alg= is_relay_log ?
+ /* relay-log */
+ /* inherit master's A descriptor if one has been received */
+ (relay_log_checksum_alg=
+ (relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF) ?
+ relay_log_checksum_alg :
+ /* otherwise use slave's local preference of RL events verification */
+ (opt_slave_sql_verify_checksum == 0) ?
+ (uint8) BINLOG_CHECKSUM_ALG_OFF : (uint8) binlog_checksum_options):
+ /* binlog */
+ (uint8) binlog_checksum_options;
+ DBUG_ASSERT(s.checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
if (!s.is_valid())
goto err;
s.dont_set_created= null_created_arg;
+ s.pre_55_writing_direct();
if (s.write(&log_file))
goto err;
bytes_written+= s.data_written;
@@ -2791,13 +2833,19 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
/* Don't set log_pos in event header */
description_event_for_queue->set_artificial_event();
+ description_event_for_queue->pre_55_writing_direct();
if (description_event_for_queue->write(&log_file))
goto err;
bytes_written+= description_event_for_queue->data_written;
}
if (flush_io_cache(&log_file) ||
- my_sync(log_file.file, MYF(MY_WME)))
+ my_sync(log_file.file, MYF(MY_WME|MY_SYNC_FILESIZE)))
goto err;
+ pthread_mutex_lock(&LOCK_commit_ordered);
+ strmake(last_commit_pos_file, log_file_name,
+ sizeof(last_commit_pos_file)-1);
+ last_commit_pos_offset= my_b_tell(&log_file);
+ pthread_mutex_unlock(&LOCK_commit_ordered);
if (write_file_name_to_index_file)
{
@@ -2817,7 +2865,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
strlen(log_file_name)) ||
my_b_write(&index_file, (uchar*) "\n", 1) ||
flush_io_cache(&index_file) ||
- my_sync(index_file.file, MYF(MY_WME)))
+ my_sync(index_file.file, MYF(MY_WME|MY_SYNC_FILESIZE)))
goto err;
#ifdef HAVE_REPLICATION
@@ -2909,7 +2957,7 @@ static bool copy_up_file_and_fill(IO_CACHE *index_file, my_off_t offset)
}
/* The following will either truncate the file or fill the end with \n' */
if (my_chsize(file, offset - init_offset, '\n', MYF(MY_WME)) ||
- my_sync(file, MYF(MY_WME)))
+ my_sync(file, MYF(MY_WME|MY_SYNC_FILESIZE)))
goto err;
/* Reset data in old index cache */
@@ -3502,7 +3550,7 @@ int MYSQL_BIN_LOG::sync_purge_index_file()
DBUG_ENTER("MYSQL_BIN_LOG::sync_purge_index_file");
if ((error= flush_io_cache(&purge_index_file)) ||
- (error= my_sync(purge_index_file.file, MYF(MY_WME))))
+ (error= my_sync(purge_index_file.file, MYF(MY_WME|MY_SYNC_FILESIZE))))
DBUG_RETURN(error);
DBUG_RETURN(error);
@@ -3923,8 +3971,16 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
We log the whole file name for log file as the user may decide
to change base names at some point.
*/
- Rotate_log_event r(new_name+dirname_length(new_name),
- 0, LOG_EVENT_OFFSET, is_relay_log ? Rotate_log_event::RELAY_LOG : 0);
+ Rotate_log_event r(new_name+dirname_length(new_name), 0, LOG_EVENT_OFFSET,
+ is_relay_log ? Rotate_log_event::RELAY_LOG : 0);
+ /*
+ The current relay-log's closing Rotate event must have checksum
+ value computed with an algorithm of the last relay-logged FD event.
+ */
+ if (is_relay_log)
+ r.checksum_alg= relay_log_checksum_alg;
+ r.pre_55_writing_direct();
+ DBUG_ASSERT(!is_relay_log || relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
if(DBUG_EVALUATE_IF("fault_injection_new_file_rotate_event", (error=close_on_error=TRUE), FALSE) ||
(error= r.write(&log_file)))
{
@@ -3945,7 +4001,12 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
old_name=name;
name=0; // Don't free name
close(LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX);
-
+ if (log_type == LOG_BIN && checksum_alg_reset != BINLOG_CHECKSUM_ALG_UNDEF)
+ {
+ DBUG_ASSERT(!is_relay_log);
+ DBUG_ASSERT(binlog_checksum_options != checksum_alg_reset);
+ binlog_checksum_options= checksum_alg_reset;
+ }
/*
Note that at this point, log_state != LOG_CLOSED (important for is_open()).
*/
@@ -4024,6 +4085,7 @@ bool MYSQL_BIN_LOG::append(Log_event* ev)
Log_event::write() is smart enough to use my_b_write() or
my_b_append() depending on the kind of cache we have.
*/
+ ev->pre_55_writing_direct();
if (ev->write(&log_file))
{
error=1;
@@ -4078,7 +4140,11 @@ bool MYSQL_BIN_LOG::flush_and_sync()
if (++sync_binlog_counter >= sync_binlog_period && sync_binlog_period)
{
sync_binlog_counter= 0;
- err=my_sync(fd, MYF(MY_WME));
+ err=my_sync(fd, MYF(MY_WME|MY_SYNC_FILESIZE));
+#ifndef DBUG_OFF
+ if (opt_binlog_dbug_fsync_sleep > 0)
+ my_sleep(opt_binlog_dbug_fsync_sleep);
+#endif
}
return err;
}
@@ -4270,12 +4336,33 @@ void THD::binlog_set_stmt_begin() {
trx_data->before_stmt_pos= pos;
}
+static int
+binlog_start_consistent_snapshot(handlerton *hton, THD *thd)
+{
+ int err= 0;
+ binlog_trx_data *trx_data;
+ DBUG_ENTER("binlog_start_consistent_snapshot");
+
+ thd->binlog_setup_trx_data();
+ trx_data= (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
+
+ /* Server layer calls us with LOCK_commit_ordered locked, so this is safe. */
+ strmake(trx_data->last_commit_pos_file, mysql_bin_log.last_commit_pos_file,
+ sizeof(trx_data->last_commit_pos_file)-1);
+ trx_data->last_commit_pos_offset= mysql_bin_log.last_commit_pos_offset;
+
+ trans_register_ha(thd, TRUE, hton);
+
+ DBUG_RETURN(err);
+}
/*
- Write a table map to the binary log.
+ Write a table map to the binary log. If with_annotate != NULL and
+ *with_annotate = TRUE write also Annotate_rows before the table map.
*/
-int THD::binlog_write_table_map(TABLE *table, bool is_trans)
+int THD::binlog_write_table_map(TABLE *table, bool is_trans,
+ my_bool *with_annotate)
{
int error;
DBUG_ENTER("THD::binlog_write_table_map");
@@ -4293,7 +4380,7 @@ int THD::binlog_write_table_map(TABLE *table, bool is_trans)
if (is_trans && binlog_table_maps == 0)
binlog_start_trans_and_stmt();
- if ((error= mysql_bin_log.write(&the_event)))
+ if ((error= mysql_bin_log.write(&the_event, with_annotate)))
DBUG_RETURN(error);
binlog_table_maps++;
@@ -4377,50 +4464,53 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
if (Rows_log_event* pending= trx_data->pending())
{
- IO_CACHE *file= &log_file;
-
/*
Decide if we should write to the log file directly or to the
transaction log.
*/
if (pending->get_cache_stmt() || my_b_tell(&trx_data->trans_log))
- file= &trx_data->trans_log;
-
- /*
- If we are not writing to the log file directly, we could avoid
- locking the log.
- */
- pthread_mutex_lock(&LOCK_log);
-
- /*
- Write pending event to log file or transaction cache
- */
- DBUG_EXECUTE_IF("simulate_disk_full_at_flush_pending",
- {DBUG_SET("+d,simulate_file_write_error");});
- if (pending->write(file))
{
- pthread_mutex_unlock(&LOCK_log);
- set_write_error(thd);
- delete pending;
- trx_data->set_pending(NULL);
- DBUG_EXECUTE_IF("simulate_disk_full_at_flush_pending",
- {DBUG_SET("-d,simulate_file_write_error");});
- DBUG_RETURN(1);
+ /* Write to transaction log/cache. */
+ if (pending->write(&trx_data->trans_log))
+ {
+ set_write_error(thd);
+ delete pending;
+ trx_data->set_pending(NULL);
+ DBUG_RETURN(1);
+ }
}
-
- delete pending;
-
- if (file == &log_file)
+ else
{
+ /* Write directly to log file. */
+ pthread_mutex_lock(&LOCK_log);
+ pending->pre_55_writing_direct();
+ if (pending->write(&log_file))
+ {
+ pthread_mutex_unlock(&LOCK_log);
+ set_write_error(thd);
+ delete pending;
+ trx_data->set_pending(NULL);
+ DBUG_RETURN(1);
+ }
+
error= flush_and_sync();
if (!error)
{
signal_update();
error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
}
+
+ /*
+ Take mutex to protect against a reader seeing partial writes of 64-bit
+ offset on 32-bit CPUs.
+ */
+ pthread_mutex_lock(&LOCK_commit_ordered);
+ last_commit_pos_offset= my_b_tell(&log_file);
+ pthread_mutex_unlock(&LOCK_commit_ordered);
+ pthread_mutex_unlock(&LOCK_log);
}
- pthread_mutex_unlock(&LOCK_log);
+ delete pending;
}
thd->binlog_set_pending_rows_event(event);
@@ -4429,13 +4519,16 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
}
/**
- Write an event to the binary log.
+ Write an event to the binary log. If with_annotate != NULL and
+ *with_annotate = TRUE write also Annotate_rows before the event
+ (this should happen only if the event is a Table_map).
*/
-bool MYSQL_BIN_LOG::write(Log_event *event_info)
+bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
{
THD *thd= event_info->thd;
bool error= 1;
+ uint16 cache_type;
DBUG_ENTER("MYSQL_BIN_LOG::write(Log_event *)");
if (thd->binlog_evt_union.do_union)
@@ -4450,11 +4543,6 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
}
/*
- Flush the pending rows event to the transaction cache or to the
- log file. Since this function potentially aquire the LOCK_log
- mutex, we do this before aquiring the LOCK_log mutex in this
- function.
-
We only end the statement if we are in a top-level statement. If
we are inside a stored function, we do not end the statement since
this will close all tables on the slave.
@@ -4464,8 +4552,6 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
if (thd->binlog_flush_pending_rows_event(end_stmt))
DBUG_RETURN(error);
- pthread_mutex_lock(&LOCK_log);
-
/*
In most cases this is only called if 'is_open()' is true; in fact this is
mostly called if is_open() *was* true a few instructions before, but it
@@ -4487,7 +4573,6 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
thd->lex->sql_command != SQLCOM_SAVEPOINT &&
!binlog_filter->db_ok(local_db)))
{
- VOID(pthread_mutex_unlock(&LOCK_log));
DBUG_RETURN(0);
}
#endif /* HAVE_REPLICATION */
@@ -4531,15 +4616,26 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
thd->binlog_start_trans_and_stmt();
file= trans_log;
}
- /*
- TODO as Mats suggested, for all the cases above where we write to
- trans_log, it sounds unnecessary to lock LOCK_log. We should rather
- test first if we want to write to trans_log, and if not, lock
- LOCK_log.
- */
}
#endif /* USING_TRANSACTIONS */
DBUG_PRINT("info",("event type: %d",event_info->get_type_code()));
+ if (file == &log_file)
+ {
+ pthread_mutex_lock(&LOCK_log);
+ /*
+ We did not want to take LOCK_log unless really necessary.
+ However, now that we hold LOCK_log, we must check is_open() again, lest
+ the log was closed just before.
+ */
+ if (unlikely(!is_open()))
+ {
+ pthread_mutex_unlock(&LOCK_log);
+ DBUG_RETURN(error);
+ }
+ event_info->pre_55_writing_direct();
+ }
+
+ cache_type= event_info->cache_type;
/*
No check for auto events flag here - this write method should
@@ -4551,6 +4647,16 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
of the SQL command
*/
+ if (with_annotate && *with_annotate)
+ {
+ DBUG_ASSERT(event_info->get_type_code() == TABLE_MAP_EVENT);
+ Annotate_rows_log_event anno(thd, cache_type);
+ /* Annotate event should be written not more than once */
+ *with_annotate= 0;
+ if (anno.write(file))
+ goto err;
+ }
+
/*
If row-based binlogging, Insert_id, Rand and other kind of "setting
context" events are not needed.
@@ -4558,12 +4664,14 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
{
if (!thd->current_stmt_binlog_row_based)
{
+
if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
{
Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
- thd->first_successful_insert_id_in_prev_stmt_for_binlog);
+ thd->first_successful_insert_id_in_prev_stmt_for_binlog,
+ cache_type);
if (e.write(file))
- goto err;
+ goto err_unlock;
}
if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
{
@@ -4572,15 +4680,16 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
nb_elements()));
Intvar_log_event e(thd, (uchar) INSERT_ID_EVENT,
thd->auto_inc_intervals_in_cur_stmt_for_binlog.
- minimum());
+ minimum(), cache_type);
if (e.write(file))
- goto err;
+ goto err_unlock;
}
if (thd->rand_used)
{
- Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
+ Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2,
+ cache_type);
if (e.write(file))
- goto err;
+ goto err_unlock;
}
if (thd->user_var_events.elements)
{
@@ -4593,9 +4702,10 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
user_var_event->value,
user_var_event->length,
user_var_event->type,
- user_var_event->charset_number);
+ user_var_event->charset_number,
+ cache_type);
if (e.write(file))
- goto err;
+ goto err_unlock;
}
}
}
@@ -4604,7 +4714,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
/* Write the SQL command */
if (event_info->write(file) ||
DBUG_EVALUATE_IF("injecting_fault_writing", 1, 0))
- goto err;
+ goto err_unlock;
if (file == &log_file) // we are writing to the real log (disk)
{
@@ -4612,20 +4722,33 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
status_var_add(thd->status_var.binlog_bytes_written, data_written);
if (flush_and_sync())
- goto err;
+ goto err_unlock;
signal_update();
if ((error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED)))
- goto err;
+ goto err_unlock;
}
error=0;
+err_unlock:
+ if (file == &log_file)
+ {
+ my_off_t offset= my_b_tell(&log_file);
+ /*
+ Take mutex to protect against a reader seeing partial writes of 64-bit
+ offset on 32-bit CPUs.
+ */
+ pthread_mutex_lock(&LOCK_commit_ordered);
+ last_commit_pos_offset= offset;
+ pthread_mutex_unlock(&LOCK_commit_ordered);
+ pthread_mutex_unlock(&LOCK_log);
+ }
+
err:
if (error)
set_write_error(thd);
}
- pthread_mutex_unlock(&LOCK_log);
DBUG_RETURN(error);
}
@@ -4730,12 +4853,14 @@ int MYSQL_BIN_LOG::rotate_and_purge(uint flags)
We give it a shot and try to write an incident event anyway
to the current log.
*/
- if (!write_incident(current_thd, FALSE))
+ if (!write_incident_already_locked(current_thd))
flush_and_sync();
#ifdef HAVE_REPLICATION
check_purge= true;
#endif
+ if (flags & RP_BINLOG_CHECKSUM_ALG_CHANGE)
+ checksum_alg_reset= BINLOG_CHECKSUM_ALG_UNDEF; // done
}
if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
pthread_mutex_unlock(&LOCK_log);
@@ -4764,6 +4889,33 @@ uint MYSQL_BIN_LOG::next_file_id()
}
+/**
+ Calculate checksum of possibly a part of an event containing at least
+ the whole common header.
+
+ @param buf the pointer to trans cache's buffer
+ @param off the offset of the beginning of the event in the buffer
+ @param event_len no-checksum length of the event
+ @param length the current size of the buffer
+
+ @param crc [in-out] the checksum
+
+ Event size in incremented by @c BINLOG_CHECKSUM_LEN.
+
+ @return 0 or number of unprocessed yet bytes of the event excluding
+ the checksum part.
+*/
+ static ulong fix_log_event_crc(uchar *buf, uint off, uint event_len,
+ uint length, ha_checksum *crc)
+{
+ ulong ret;
+ uchar *event_begin= buf + off;
+
+ ret= length >= off + event_len ? 0 : off + event_len - length;
+ *crc= my_checksum(*crc, event_begin, event_len - ret);
+ return ret;
+}
+
/*
Write the contents of a cache to the binary log.
@@ -4771,24 +4923,33 @@ uint MYSQL_BIN_LOG::next_file_id()
write_cache()
thd Current_thread
cache Cache to write to the binary log
- lock_log True if the LOCK_log mutex should be aquired, false otherwise
- sync_log True if the log should be flushed and sync:ed
DESCRIPTION
Write the contents of the cache to the binary log. The cache will
be reset as a READ_CACHE to be able to read the contents from it.
- */
-int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache, bool lock_log,
- bool sync_log)
-{
- Mutex_sentry sentry(lock_log ? &LOCK_log : NULL);
+ Reading from the trans cache with possible (per @c binlog_checksum_options)
+ adding checksum value and then fixing the length and the end_log_pos of
+ events prior to fill in the binlog cache.
+*/
+int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
+{
+ safe_mutex_assert_owner(&LOCK_log);
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
return ER_ERROR_ON_WRITE;
uint length= my_b_bytes_in_cache(cache), group, carry, hdr_offs;
+ ulong remains= 0; // part of unprocessed yet netto length of the event
long val;
+ ulong end_log_pos_inc= 0; // each event processed adds BINLOG_CHECKSUM_LEN 2 t
uchar header[LOG_EVENT_HEADER_LEN];
+ ha_checksum crc= 0, crc_0= 0; // assignments to keep compiler happy
+ my_bool do_checksum= (binlog_checksum_options != BINLOG_CHECKSUM_ALG_OFF);
+ uchar buf[BINLOG_CHECKSUM_LEN];
+
+ // while there is just one alg the following must hold:
+ DBUG_ASSERT(!do_checksum ||
+ binlog_checksum_options == BINLOG_CHECKSUM_ALG_CRC32);
/*
The events in the buffer have incorrect end_log_pos data
@@ -4806,6 +4967,8 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache, bool lock_log,
group= (uint)my_b_tell(&log_file);
hdr_offs= carry= 0;
+ if (do_checksum)
+ crc= crc_0= my_checksum(0L, NULL, 0);
do
{
@@ -4819,12 +4982,21 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache, bool lock_log,
DBUG_ASSERT(carry < LOG_EVENT_HEADER_LEN);
/* assemble both halves */
- memcpy(&header[carry], (char *)cache->read_pos, LOG_EVENT_HEADER_LEN - carry);
+ memcpy(&header[carry], (char *)cache->read_pos,
+ LOG_EVENT_HEADER_LEN - carry);
/* fix end_log_pos */
- val= uint4korr(&header[LOG_POS_OFFSET]) + group;
+ val= uint4korr(&header[LOG_POS_OFFSET]) + group +
+ (end_log_pos_inc+= (do_checksum ? BINLOG_CHECKSUM_LEN : 0));
int4store(&header[LOG_POS_OFFSET], val);
+ if (do_checksum)
+ {
+ ulong len= uint4korr(&header[EVENT_LEN_OFFSET]);
+ /* fix len */
+ int4store(&header[EVENT_LEN_OFFSET], len + BINLOG_CHECKSUM_LEN);
+ }
+
/* write the first half of the split header */
if (my_b_write(&log_file, header, carry))
return ER_ERROR_ON_WRITE;
@@ -4834,11 +5006,20 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache, bool lock_log,
copy fixed second half of header to cache so the correct
version will be written later.
*/
- memcpy((char *)cache->read_pos, &header[carry], LOG_EVENT_HEADER_LEN - carry);
+ memcpy((char *)cache->read_pos, &header[carry],
+ LOG_EVENT_HEADER_LEN - carry);
/* next event header at ... */
- hdr_offs = uint4korr(&header[EVENT_LEN_OFFSET]) - carry;
+ hdr_offs= uint4korr(&header[EVENT_LEN_OFFSET]) - carry -
+ (do_checksum ? BINLOG_CHECKSUM_LEN : 0);
+ if (do_checksum)
+ {
+ DBUG_ASSERT(crc == crc_0 && remains == 0);
+ crc= my_checksum(crc, header, carry);
+ remains= uint4korr(header + EVENT_LEN_OFFSET) - carry -
+ BINLOG_CHECKSUM_LEN;
+ }
carry= 0;
}
@@ -4853,6 +5034,25 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache, bool lock_log,
very next iteration, just "eventually").
*/
+ /* crc-calc the whole buffer */
+ if (do_checksum && hdr_offs >= length)
+ {
+
+ DBUG_ASSERT(remains != 0 && crc != crc_0);
+
+ crc= my_checksum(crc, cache->read_pos, length);
+ remains -= length;
+ if (my_b_write(&log_file, cache->read_pos, length))
+ return ER_ERROR_ON_WRITE;
+ if (remains == 0)
+ {
+ int4store(buf, crc);
+ if (my_b_write(&log_file, buf, BINLOG_CHECKSUM_LEN))
+ return ER_ERROR_ON_WRITE;
+ crc= crc_0;
+ }
+ }
+
while (hdr_offs < length)
{
/*
@@ -4860,6 +5060,26 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache, bool lock_log,
we get the rest.
*/
+ if (do_checksum)
+ {
+ if (remains != 0)
+ {
+ /*
+ finish off with remains of the last event that crawls
+ from previous into the current buffer
+ */
+ DBUG_ASSERT(crc != crc_0);
+ crc= my_checksum(crc, cache->read_pos, hdr_offs);
+ int4store(buf, crc);
+ remains -= hdr_offs;
+ DBUG_ASSERT(remains == 0);
+ if (my_b_write(&log_file, cache->read_pos, hdr_offs) ||
+ my_b_write(&log_file, buf, BINLOG_CHECKSUM_LEN))
+ return ER_ERROR_ON_WRITE;
+ crc= crc_0;
+ }
+ }
+
if (hdr_offs + LOG_EVENT_HEADER_LEN > length)
{
carry= length - hdr_offs;
@@ -4869,17 +5089,38 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache, bool lock_log,
else
{
/* we've got a full event-header, and it came in one piece */
-
- uchar *log_pos= (uchar *)cache->read_pos + hdr_offs + LOG_POS_OFFSET;
+ uchar *ev= (uchar *)cache->read_pos + hdr_offs;
+ uint event_len= uint4korr(ev + EVENT_LEN_OFFSET); // netto len
+ uchar *log_pos= ev + LOG_POS_OFFSET;
/* fix end_log_pos */
- val= uint4korr(log_pos) + group;
+ val= uint4korr(log_pos) + group +
+ (end_log_pos_inc += (do_checksum ? BINLOG_CHECKSUM_LEN : 0));
int4store(log_pos, val);
+ /* fix CRC */
+ if (do_checksum)
+ {
+ /* fix length */
+ int4store(ev + EVENT_LEN_OFFSET, event_len + BINLOG_CHECKSUM_LEN);
+ remains= fix_log_event_crc(cache->read_pos, hdr_offs, event_len,
+ length, &crc);
+ if (my_b_write(&log_file, ev,
+ remains == 0 ? event_len : length - hdr_offs))
+ return ER_ERROR_ON_WRITE;
+ if (remains == 0)
+ {
+ int4store(buf, crc);
+ if (my_b_write(&log_file, buf, BINLOG_CHECKSUM_LEN))
+ return ER_ERROR_ON_WRITE;
+ crc= crc_0; // crc is complete
+ }
+ }
+
/* next event header at ... */
- log_pos= (uchar *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET;
- hdr_offs += uint4korr(log_pos);
+ hdr_offs += event_len; // incr by the netto len
+ DBUG_ASSERT(!do_checksum || remains == 0 || hdr_offs >= length);
}
}
@@ -4895,17 +5136,19 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache, bool lock_log,
}
/* Write data to the binary log file */
- if (my_b_write(&log_file, cache->read_pos, length))
- return ER_ERROR_ON_WRITE;
+ DBUG_EXECUTE_IF("fail_binlog_write_1",
+ errno= 28; return ER_ERROR_ON_WRITE;);
+ if (!do_checksum)
+ if (my_b_write(&log_file, cache->read_pos, length))
+ return ER_ERROR_ON_WRITE;
status_var_add(thd->status_var.binlog_bytes_written, length);
cache->read_pos=cache->read_end; // Mark buffer used up
} while ((length= my_b_fill(cache)));
DBUG_ASSERT(carry == 0);
-
- if (sync_log)
- flush_and_sync();
+ DBUG_ASSERT(!do_checksum || remains == 0);
+ DBUG_ASSERT(!do_checksum || crc == crc_0);
return 0; // All OK
}
@@ -4917,7 +5160,7 @@ int query_error_code(THD *thd, bool not_killed)
{
int error;
- if (not_killed || (thd->killed == THD::KILL_BAD_DATA))
+ if (not_killed || (killed_mask_hard(thd->killed) == KILL_BAD_DATA))
{
error= thd->is_error() ? thd->main_da.sql_errno() : 0;
@@ -4927,7 +5170,7 @@ int query_error_code(THD *thd, bool not_killed)
caller.
*/
if (error == ER_SERVER_SHUTDOWN || error == ER_QUERY_INTERRUPTED ||
- error == ER_NEW_ABORTING_CONNECTION)
+ error == ER_NEW_ABORTING_CONNECTION || error == ER_CONNECTION_KILLED)
error= 0;
}
else
@@ -4940,31 +5183,51 @@ int query_error_code(THD *thd, bool not_killed)
return error;
}
-bool MYSQL_BIN_LOG::write_incident(THD *thd, bool lock)
+
+bool MYSQL_BIN_LOG::write_incident_already_locked(THD *thd)
{
uint error= 0;
- DBUG_ENTER("MYSQL_BIN_LOG::write_incident");
-
- if (!is_open())
- DBUG_RETURN(error);
-
- LEX_STRING const write_error_msg=
- { C_STRING_WITH_LEN("error writing to the binary log") };
+ DBUG_ENTER("MYSQL_BIN_LOG::write_incident_already_locked");
Incident incident= INCIDENT_LOST_EVENTS;
Incident_log_event ev(thd, incident, write_error_msg);
- if (lock)
- pthread_mutex_lock(&LOCK_log);
- error= ev.write(&log_file);
- status_var_add(thd->status_var.binlog_bytes_written, ev.data_written);
- if (lock)
+
+ if (likely(is_open()))
{
- if (!error && !(error= flush_and_sync()))
+ ev.pre_55_writing_direct();
+ error= ev.write(&log_file);
+ status_var_add(thd->status_var.binlog_bytes_written, ev.data_written);
+ }
+
+ DBUG_RETURN(error);
+}
+
+
+bool MYSQL_BIN_LOG::write_incident(THD *thd)
+{
+ uint error= 0;
+ my_off_t offset;
+ DBUG_ENTER("MYSQL_BIN_LOG::write_incident");
+
+ pthread_mutex_lock(&LOCK_log);
+ if (likely(is_open()))
+ {
+ if (!(error= write_incident_already_locked(thd)) &&
+ !(error= flush_and_sync()))
{
signal_update();
error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
}
- pthread_mutex_unlock(&LOCK_log);
+ offset= my_b_tell(&log_file);
+ /*
+ Take mutex to protect against a reader seeing partial writes of 64-bit
+ offset on 32-bit CPUs.
+ */
+ pthread_mutex_lock(&LOCK_commit_ordered);
+ last_commit_pos_offset= offset;
+ pthread_mutex_unlock(&LOCK_commit_ordered);
}
+ pthread_mutex_unlock(&LOCK_log);
+
DBUG_RETURN(error);
}
@@ -4992,111 +5255,373 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd, bool lock)
'cache' needs to be reinitialized after this functions returns.
*/
-bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event,
- bool incident)
+bool
+MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd, binlog_trx_data *trx_data,
+ Log_event *end_ev, bool all)
{
- DBUG_ENTER("MYSQL_BIN_LOG::write(THD *, IO_CACHE *, Log_event *)");
+ group_commit_entry entry;
+ DBUG_ENTER("MYSQL_BIN_LOG::write_transaction_to_binlog");
+
+ entry.thd= thd;
+ entry.trx_data= trx_data;
+ entry.error= 0;
+ entry.all= all;
+
+ /*
+ Log "BEGIN" at the beginning of every transaction. Here, a transaction is
+ either a BEGIN..COMMIT block or a single statement in autocommit mode.
+
+ Create the necessary events here, where we have the correct THD (and
+ thread context).
+
+ Due to group commit the actual writing to binlog may happen in a different
+ thread.
+ */
+ Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, TRUE, 0);
+ entry.begin_event= &qinfo;
+ entry.end_event= end_ev;
+ if (trx_data->has_incident())
+ {
+ Incident_log_event inc_ev(thd, INCIDENT_LOST_EVENTS, write_error_msg);
+ entry.incident_event= &inc_ev;
+ DBUG_RETURN(write_transaction_to_binlog_events(&entry));
+ }
+ else
+ {
+ entry.incident_event= NULL;
+ DBUG_RETURN(write_transaction_to_binlog_events(&entry));
+ }
+}
+
+bool
+MYSQL_BIN_LOG::write_transaction_to_binlog_events(group_commit_entry *entry)
+{
+ /*
+ To facilitate group commit for the binlog, we first queue up ourselves in
+ the group commit queue. Then the first thread to enter the queue waits for
+ the LOCK_log mutex, and commits for everyone in the queue once it gets the
+ lock. Any other threads in the queue just wait for the first one to finish
+ the commit and wake them up.
+ */
+
+ entry->thd->clear_wakeup_ready();
+ pthread_mutex_lock(&LOCK_prepare_ordered);
+ group_commit_entry *orig_queue= group_commit_queue;
+ entry->next= orig_queue;
+ group_commit_queue= entry;
+
+ if (entry->trx_data->using_xa)
+ {
+ DEBUG_SYNC(entry->thd, "commit_before_prepare_ordered");
+ run_prepare_ordered(entry->thd, entry->all);
+ DEBUG_SYNC(entry->thd, "commit_after_prepare_ordered");
+ }
+ pthread_mutex_unlock(&LOCK_prepare_ordered);
+ DEBUG_SYNC(entry->thd, "commit_after_release_LOCK_prepare_ordered");
+
+ /*
+ The first in the queue handle group commit for all; the others just wait
+ to be signalled when group commit is done.
+ */
+ if (orig_queue != NULL)
+ entry->thd->wait_for_wakeup_ready();
+ else
+ trx_group_commit_leader(entry);
+
+ if (!opt_optimize_thread_scheduling)
+ {
+ /* For the leader, trx_group_commit_leader() already took the lock. */
+ if (orig_queue != NULL)
+ pthread_mutex_lock(&LOCK_commit_ordered);
+
+ DEBUG_SYNC(entry->thd, "commit_loop_entry_commit_ordered");
+ ++num_commits;
+ if (entry->trx_data->using_xa && !entry->error)
+ run_commit_ordered(entry->thd, entry->all);
+
+ group_commit_entry *next= entry->next;
+ if (!next)
+ {
+ group_commit_queue_busy= FALSE;
+ pthread_cond_signal(&COND_queue_busy);
+ DEBUG_SYNC(entry->thd, "commit_after_group_run_commit_ordered");
+ }
+ pthread_mutex_unlock(&LOCK_commit_ordered);
+
+ if (next)
+ {
+ next->thd->signal_wakeup_ready();
+ }
+ }
+
+ if (likely(!entry->error))
+ return 0;
+
+ switch (entry->error)
+ {
+ case ER_ERROR_ON_WRITE:
+ my_error(ER_ERROR_ON_WRITE, MYF(ME_NOREFRESH), name, entry->commit_errno);
+ break;
+ case ER_ERROR_ON_READ:
+ my_error(ER_ERROR_ON_READ, MYF(ME_NOREFRESH),
+ entry->trx_data->trans_log.file_name, entry->commit_errno);
+ break;
+ default:
+ /*
+ There are not (and should not be) any errors thrown not covered above.
+ But just in case one is added later without updating the above switch
+ statement, include a catch-all.
+ */
+ my_printf_error(entry->error,
+ "Error writing transaction to binary log: %d",
+ MYF(ME_NOREFRESH), entry->error);
+ }
+
+ /*
+ Since we return error, this transaction XID will not be committed, so
+ we need to mark it as not needed for recovery (unlog() is not called
+ for a transaction if log_xid() fails).
+ */
+ if (entry->trx_data->using_xa && entry->trx_data->xa_xid)
+ mark_xid_done();
+
+ return 1;
+}
+
+/*
+ Do binlog group commit as the lead thread.
+
+ This must be called when this thread/transaction is queued at the start of
+ the group_commit_queue. It will wait to obtain the LOCK_log mutex, then group
+ commit all the transactions in the queue (more may have entered while waiting
+ for LOCK_log). After commit is done, all other threads in the queue will be
+ signalled.
+
+ */
+void
+MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
+{
+ uint xid_count= 0;
+ uint write_count= 0;
+ my_off_t commit_offset;
+ group_commit_entry *current;
+ group_commit_entry *last_in_queue;
+ DBUG_ENTER("MYSQL_BIN_LOG::trx_group_commit_leader");
+ LINT_INIT(commit_offset);
+
+ /*
+ Lock the LOCK_log(), and once we get it, collect any additional writes
+ that queued up while we were waiting.
+ */
VOID(pthread_mutex_lock(&LOCK_log));
+ DEBUG_SYNC(leader->thd, "commit_after_get_LOCK_log");
- /* NULL would represent nothing to replicate after ROLLBACK */
- DBUG_ASSERT(commit_event != NULL);
+ pthread_mutex_lock(&LOCK_prepare_ordered);
+ current= group_commit_queue;
+ group_commit_queue= NULL;
+ pthread_mutex_unlock(&LOCK_prepare_ordered);
+ /* As the queue is in reverse order of entering, reverse it. */
+ group_commit_entry *queue= NULL;
+ last_in_queue= current;
+ while (current)
+ {
+ group_commit_entry *next= current->next;
+ current->next= queue;
+ queue= current;
+ current= next;
+ }
+ DBUG_ASSERT(leader == queue /* the leader should be first in queue */);
+
+ /* Now we have in queue the list of transactions to be committed in order. */
DBUG_ASSERT(is_open());
if (likely(is_open())) // Should always be true
{
/*
- We only bother to write to the binary log if there is anything
- to write.
- */
- if (my_b_tell(cache) > 0)
+ Commit every transaction in the queue.
+
+ Note that we are doing this in a different thread than the one running
+ the transaction! So we are limited in the operations we can do. In
+ particular, we cannot call my_error() on behalf of a transaction, as
+ that obtains the THD from thread local storage. Instead, we must set
+ current->error and let the thread do the error reporting itself once
+ we wake it up.
+ */
+ for (current= queue; current != NULL; current= current->next)
{
- /*
- Log "BEGIN" at the beginning of every transaction. Here, a
- transaction is either a BEGIN..COMMIT block or a single
- statement in autocommit mode.
- */
- Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, TRUE, 0);
+ binlog_trx_data *trx_data= current->trx_data;
+ IO_CACHE *cache= &trx_data->trans_log;
/*
- Now this Query_log_event has artificial log_pos 0. It must be
- adjusted to reflect the real position in the log. Not doing it
- would confuse the slave: it would prevent this one from
- knowing where he is in the master's binlog, which would result
- in wrong positions being shown to the user, MASTER_POS_WAIT
- undue waiting etc.
+ We only bother to write to the binary log if there is anything
+ to write.
*/
- if (qinfo.write(&log_file))
- goto err;
- status_var_add(thd->status_var.binlog_bytes_written, qinfo.data_written);
-
- DBUG_EXECUTE_IF("crash_before_writing_xid",
- {
- if ((write_error= write_cache(thd, cache, FALSE,
- TRUE)))
- DBUG_PRINT("info", ("error writing binlog cache: %d",
- write_error));
- DBUG_PRINT("info", ("crashing before writing xid"));
- DBUG_SUICIDE();
- });
-
- if ((write_error= write_cache(thd, cache, FALSE, FALSE)))
- goto err;
-
- if (commit_event)
+ if (my_b_tell(cache) > 0)
{
- if (commit_event->write(&log_file))
- goto err;
- status_var_add(thd->status_var.binlog_bytes_written,
- commit_event->data_written);
+ if ((current->error= write_transaction(current)))
+ current->commit_errno= errno;
+
+ write_count++;
}
- if (incident && write_incident(thd, FALSE))
- goto err;
+ strmake(trx_data->last_commit_pos_file, log_file_name,
+ sizeof(trx_data->last_commit_pos_file)-1);
+ commit_offset= my_b_write_tell(&log_file);
+ trx_data->last_commit_pos_offset= commit_offset;
+ if (trx_data->using_xa && trx_data->xa_xid)
+ xid_count++;
+ }
+ if (write_count > 0)
+ {
if (flush_and_sync())
- goto err;
- DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_SUICIDE(););
- if (cache->error) // Error on read
{
- sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno);
- write_error=1; // Don't give more errors
- goto err;
+ for (current= queue; current != NULL; current= current->next)
+ {
+ if (!current->error)
+ {
+ current->error= ER_ERROR_ON_WRITE;
+ current->commit_errno= errno;
+ }
+ }
+ }
+ else
+ {
+ signal_update();
}
- signal_update();
}
/*
- if commit_event is Xid_log_event, increase the number of
- prepared_xids (it's decreasd in ::unlog()). Binlog cannot be rotated
+ if any commit_events are Xid_log_event, increase the number of
+ prepared_xids (it's decreased in ::unlog()). Binlog cannot be rotated
if there're prepared xids in it - see the comment in new_file() for
an explanation.
- If the commit_event is not Xid_log_event (then it's a Query_log_event)
- rotate binlog, if necessary.
+ If no Xid_log_events (then it's all Query_log_event) rotate binlog,
+ if necessary.
*/
- if (commit_event && commit_event->get_type_code() == XID_EVENT)
+ if (xid_count > 0)
{
- pthread_mutex_lock(&LOCK_prep_xids);
- prepared_xids++;
- pthread_mutex_unlock(&LOCK_prep_xids);
+ mark_xids_active(xid_count);
}
else
+ {
if (rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED))
- goto err;
+ {
+ /*
+ If we fail to rotate, which thread should get the error?
+ We give the error to the *last* transaction thread; that seems to
+ make the most sense, as it was the last to write to the log.
+ */
+ last_in_queue->error= ER_ERROR_ON_WRITE;
+ last_in_queue->commit_errno= errno;
+ }
+ }
}
- VOID(pthread_mutex_unlock(&LOCK_log));
- DBUG_RETURN(0);
+ DEBUG_SYNC(leader->thd, "commit_before_get_LOCK_commit_ordered");
+ pthread_mutex_lock(&LOCK_commit_ordered);
+ last_commit_pos_offset= commit_offset;
+ /*
+ We cannot unlock LOCK_log until we have locked LOCK_commit_ordered;
+ otherwise scheduling could allow the next group commit to run ahead of us,
+ messing up the order of commit_ordered() calls. But as soon as
+ LOCK_commit_ordered is obtained, we can let the next group commit start.
+ */
+ pthread_mutex_unlock(&LOCK_log);
+ DEBUG_SYNC(leader->thd, "commit_after_release_LOCK_log");
+ ++num_group_commits;
-err:
- if (!write_error)
+ if (!opt_optimize_thread_scheduling)
{
- write_error= 1;
- sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
+ /*
+ If we want to run commit_ordered() each in the transaction's own thread
+ context, then we need to mark the queue reserved; we need to finish all
+ threads in one group commit before the next group commit can be allowed
+ to proceed, and we cannot unlock a simple pthreads mutex in a different
+ thread from the one that locked it.
+ */
+
+ while (group_commit_queue_busy)
+ pthread_cond_wait(&COND_queue_busy, &LOCK_commit_ordered);
+ group_commit_queue_busy= TRUE;
+
+ /* Note that we return with LOCK_commit_ordered locked! */
+ DBUG_VOID_RETURN;
}
- VOID(pthread_mutex_unlock(&LOCK_log));
- DBUG_RETURN(1);
+
+ /*
+ Wakeup each participant waiting for our group commit, first calling the
+ commit_ordered() methods for any transactions doing 2-phase commit.
+ */
+ current= queue;
+ while (current != NULL)
+ {
+ group_commit_entry *next;
+
+ DEBUG_SYNC(leader->thd, "commit_loop_entry_commit_ordered");
+ ++num_commits;
+ if (current->trx_data->using_xa && !current->error)
+ run_commit_ordered(current->thd, current->all);
+
+ /*
+ Careful not to access current->next after waking up the other thread! As
+ it may change immediately after wakeup.
+ */
+ next= current->next;
+ if (current != leader) // Don't wake up ourself
+ current->thd->signal_wakeup_ready();
+ current= next;
+ }
+ DEBUG_SYNC(leader->thd, "commit_after_group_run_commit_ordered");
+ pthread_mutex_unlock(&LOCK_commit_ordered);
+
+ DBUG_VOID_RETURN;
}
+int
+MYSQL_BIN_LOG::write_transaction(group_commit_entry *entry)
+{
+ binlog_trx_data *trx_data= entry->trx_data;
+ IO_CACHE *cache= &trx_data->trans_log;
+
+ entry->begin_event->pre_55_writing_direct();
+ if (entry->begin_event->write(&log_file))
+ return ER_ERROR_ON_WRITE;
+ status_var_add(entry->thd->status_var.binlog_bytes_written,
+ entry->begin_event->data_written);
+
+ DBUG_EXECUTE_IF("crash_before_writing_xid",
+ {
+ if ((write_cache(entry->thd, cache)))
+ DBUG_PRINT("info", ("error writing binlog cache"));
+ else
+ flush_and_sync();
+
+ DBUG_PRINT("info", ("crashing before writing xid"));
+ DBUG_SUICIDE();
+ });
+
+ if (write_cache(entry->thd, cache))
+ return ER_ERROR_ON_WRITE;
+
+ entry->end_event->pre_55_writing_direct();
+ if (entry->end_event->write(&log_file))
+ return ER_ERROR_ON_WRITE;
+ status_var_add(entry->thd->status_var.binlog_bytes_written,
+ entry->end_event->data_written);
+
+ if (entry->incident_event)
+ {
+ entry->incident_event->pre_55_writing_direct();
+ if (entry->incident_event->write(&log_file))
+ return ER_ERROR_ON_WRITE;
+ }
+
+ if (cache->error) // Error on read
+ return ER_ERROR_ON_READ;
+
+ return 0;
+}
/**
Wait until we get a signal that the binary log has been updated.
@@ -5154,6 +5679,12 @@ void MYSQL_BIN_LOG::close(uint exiting)
(exiting & LOG_CLOSE_STOP_EVENT))
{
Stop_log_event s;
+ // the checksumming rule for relay-log case is similar to Rotate
+ s.checksum_alg= is_relay_log ?
+ (uint8) relay_log_checksum_alg : (uint8) binlog_checksum_options;
+ DBUG_ASSERT(!is_relay_log ||
+ relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
+ s.pre_55_writing_direct();
s.write(&log_file);
bytes_written+= s.data_written;
signal_update();
@@ -5489,6 +6020,171 @@ void sql_print_information(const char *format, ...)
}
+void
+TC_init()
+{
+ my_pthread_mutex_init(&LOCK_prepare_ordered, MY_MUTEX_INIT_SLOW,
+ "LOCK_prepare_ordered", MYF(0));
+ my_pthread_mutex_init(&LOCK_commit_ordered, MY_MUTEX_INIT_SLOW,
+ "LOCK_commit_ordered", MYF(0));
+ mutexes_inited= TRUE;
+}
+
+
+void
+TC_destroy()
+{
+ if (mutexes_inited)
+ {
+ pthread_mutex_destroy(&LOCK_prepare_ordered);
+ pthread_mutex_destroy(&LOCK_commit_ordered);
+ mutexes_inited= FALSE;
+ }
+}
+
+
+void
+TC_LOG::run_prepare_ordered(THD *thd, bool all)
+{
+ Ha_trx_info *ha_info=
+ all ? thd->transaction.all.ha_list : thd->transaction.stmt.ha_list;
+
+ safe_mutex_assert_owner(&LOCK_prepare_ordered);
+ for (; ha_info; ha_info= ha_info->next())
+ {
+ handlerton *ht= ha_info->ht();
+ if (!ht->prepare_ordered)
+ continue;
+ ht->prepare_ordered(ht, thd, all);
+ }
+}
+
+
+void
+TC_LOG::run_commit_ordered(THD *thd, bool all)
+{
+ Ha_trx_info *ha_info=
+ all ? thd->transaction.all.ha_list : thd->transaction.stmt.ha_list;
+
+ safe_mutex_assert_owner(&LOCK_commit_ordered);
+ for (; ha_info; ha_info= ha_info->next())
+ {
+ handlerton *ht= ha_info->ht();
+ if (!ht->commit_ordered)
+ continue;
+ ht->commit_ordered(ht, thd, all);
+ DEBUG_SYNC(thd, "commit_after_run_commit_ordered");
+ }
+}
+
+
+int TC_LOG_MMAP::log_and_order(THD *thd, my_xid xid, bool all,
+ bool need_prepare_ordered,
+ bool need_commit_ordered)
+{
+ int cookie;
+ struct commit_entry entry;
+ bool is_group_commit_leader;
+ LINT_INIT(is_group_commit_leader);
+
+ if (need_prepare_ordered)
+ {
+ pthread_mutex_lock(&LOCK_prepare_ordered);
+ run_prepare_ordered(thd, all);
+ if (need_commit_ordered)
+ {
+ /*
+ Must put us in queue so we can run_commit_ordered() in same sequence
+ as we did run_prepare_ordered().
+ */
+ thd->clear_wakeup_ready();
+ entry.thd= thd;
+ commit_entry *previous_queue= commit_ordered_queue;
+ entry.next= previous_queue;
+ commit_ordered_queue= &entry;
+ is_group_commit_leader= (previous_queue == NULL);
+ }
+ pthread_mutex_unlock(&LOCK_prepare_ordered);
+ }
+
+ cookie= 0;
+ if (xid)
+ cookie= log_one_transaction(xid);
+
+ if (need_commit_ordered)
+ {
+ if (need_prepare_ordered)
+ {
+ /*
+ We did the run_prepare_ordered() serialised, then ran the log_xid() in
+ parallel. Now we have to do run_commit_ordered() serialised in the
+ same sequence as run_prepare_ordered().
+
+ We do this starting from the head of the queue, each thread doing
+ run_commit_ordered() and signalling the next in queue.
+ */
+ if (is_group_commit_leader)
+ {
+ /* The first in queue starts the ball rolling. */
+ pthread_mutex_lock(&LOCK_prepare_ordered);
+ while (commit_ordered_queue_busy)
+ pthread_cond_wait(&COND_queue_busy, &LOCK_prepare_ordered);
+ commit_entry *queue= commit_ordered_queue;
+ commit_ordered_queue= NULL;
+ /*
+ Mark the queue busy while we bounce it from one thread to the
+ next.
+ */
+ commit_ordered_queue_busy= true;
+ pthread_mutex_unlock(&LOCK_prepare_ordered);
+
+ /* Reverse the queue list so we get correct order. */
+ commit_entry *prev= NULL;
+ while (queue)
+ {
+ commit_entry *next= queue->next;
+ queue->next= prev;
+ prev= queue;
+ queue= next;
+ }
+ DBUG_ASSERT(prev == &entry && prev->thd == thd);
+ }
+ else
+ {
+ /* Not first in queue; just wait until previous thread wakes us up. */
+ thd->wait_for_wakeup_ready();
+ }
+ }
+
+ /* Only run commit_ordered() if log_xid was successful. */
+ if (cookie)
+ {
+ pthread_mutex_lock(&LOCK_commit_ordered);
+ run_commit_ordered(thd, all);
+ pthread_mutex_unlock(&LOCK_commit_ordered);
+ }
+
+ if (need_prepare_ordered)
+ {
+ commit_entry *next= entry.next;
+ if (next)
+ {
+ next->thd->signal_wakeup_ready();
+ }
+ else
+ {
+ pthread_mutex_lock(&LOCK_prepare_ordered);
+ commit_ordered_queue_busy= false;
+ pthread_cond_signal(&COND_queue_busy);
+ pthread_mutex_unlock(&LOCK_prepare_ordered);
+ }
+ }
+ }
+
+ return cookie;
+}
+
+
/********* transaction coordinator log for 2pc - mmap() based solution *******/
/*
@@ -5625,6 +6321,7 @@ int TC_LOG_MMAP::open(const char *opt_name)
pthread_mutex_init(&LOCK_pool, MY_MUTEX_INIT_FAST);
pthread_cond_init(&COND_active, 0);
pthread_cond_init(&COND_pool, 0);
+ pthread_cond_init(&COND_queue_busy, 0);
inited=6;
@@ -5633,6 +6330,8 @@ int TC_LOG_MMAP::open(const char *opt_name)
DBUG_ASSERT(npages >= 2);
pool=pages+1;
pool_last_ptr= &((pages+npages-1)->next);
+ commit_ordered_queue= NULL;
+ commit_ordered_queue_busy= false;
return 0;
@@ -5738,7 +6437,7 @@ int TC_LOG_MMAP::overflow()
to the position in memory where xid was logged to.
*/
-int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid)
+int TC_LOG_MMAP::log_one_transaction(my_xid xid)
{
int err;
PAGE *p;
@@ -5905,6 +6604,8 @@ void TC_LOG_MMAP::close()
pthread_mutex_destroy(&LOCK_active);
pthread_mutex_destroy(&LOCK_pool);
pthread_cond_destroy(&COND_pool);
+ pthread_cond_destroy(&COND_active);
+ pthread_cond_destroy(&COND_queue_busy);
case 5:
data[0]='A'; // garble the first (signature) byte, in case my_delete fails
case 4:
@@ -6083,7 +6784,8 @@ int TC_LOG_BINLOG::open(const char *opt_name)
goto err;
}
- if ((ev= Log_event::read_log_event(&log, 0, &fdle)) &&
+ if ((ev= Log_event::read_log_event(&log, 0, &fdle,
+ opt_master_verify_checksum)) &&
ev->get_type_code() == FORMAT_DESCRIPTION_EVENT &&
ev->flags & LOG_EVENT_BINLOG_IN_USE_F)
{
@@ -6113,39 +6815,98 @@ void TC_LOG_BINLOG::close()
pthread_cond_destroy (&COND_prep_xids);
}
-/**
- @todo
- group commit
-
- @retval
- 0 error
- @retval
- 1 success
+/*
+ Do a binlog log_xid() for a group of transactions, linked through
+ thd->next_commit_ordered.
*/
-int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
+int
+TC_LOG_BINLOG::log_and_order(THD *thd, my_xid xid, bool all,
+ bool need_prepare_ordered __attribute__((unused)),
+ bool need_commit_ordered __attribute__((unused)))
{
- DBUG_ENTER("TC_LOG_BINLOG::log");
- Xid_log_event xle(thd, xid);
- binlog_trx_data *trx_data=
+ int err;
+ DBUG_ENTER("TC_LOG_BINLOG::log_and_order");
+
+ binlog_trx_data *const trx_data=
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
- /*
- We always commit the entire transaction when writing an XID. Also
- note that the return value is inverted.
- */
- DBUG_RETURN(!binlog_end_trans(thd, trx_data, &xle, TRUE));
+
+ trx_data->using_xa= TRUE;
+ trx_data->xa_xid= xid;
+ if (xid)
+ {
+ Xid_log_event xid_event(thd, xid);
+ err= binlog_flush_trx_cache(thd, trx_data, &xid_event, all);
+ }
+ else
+ {
+ /*
+ Empty xid occurs in XA COMMIT ... ONE PHASE.
+ In this case, we do not have a MySQL xid for the transaction, and the
+ external XA transaction coordinator will have to handle recovery if
+ needed. So we end the transaction with a plain COMMIT query event.
+ */
+ Query_log_event end_event(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0);
+ err= binlog_flush_trx_cache(thd, trx_data, &end_event, all);
+ }
+
+ DEBUG_SYNC(thd, "binlog_after_log_and_order");
+
+ DBUG_RETURN(!err);
}
-int TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
+/*
+ After an XID is logged, we need to hold on to the current binlog file until
+ it is fully committed in the storage engine. The reason is that crash
+ recovery only looks at the latest binlog, so we must make sure there are no
+ outstanding prepared (but not committed) transactions before rotating the
+ binlog.
+
+ To handle this, we keep a count of outstanding XIDs. This function is used
+ to increase this count when committing one or more transactions to the
+ binary log.
+*/
+void
+TC_LOG_BINLOG::mark_xids_active(uint xid_count)
{
- DBUG_ENTER("TC_LOG_BINLOG::unlog");
+ DBUG_ENTER("TC_LOG_BINLOG::mark_xids_active");
+ DBUG_PRINT("info", ("xid_count=%u", xid_count));
+ pthread_mutex_lock(&LOCK_prep_xids);
+ prepared_xids+= xid_count;
+ pthread_mutex_unlock(&LOCK_prep_xids);
+ DBUG_VOID_RETURN;
+}
+
+/*
+ Once an XID is committed, it is safe to rotate the binary log, as it can no
+ longer be needed during crash recovery.
+
+ This function is called to mark an XID this way. It needs to decrease the
+ count of pending XIDs, and signal the log rotator thread when it reaches zero.
+*/
+void
+TC_LOG_BINLOG::mark_xid_done()
+{
+ my_bool send_signal;
+
+ DBUG_ENTER("TC_LOG_BINLOG::mark_xid_done");
pthread_mutex_lock(&LOCK_prep_xids);
DBUG_ASSERT(prepared_xids > 0);
- if (--prepared_xids == 0) {
+ send_signal= !--prepared_xids;
+ pthread_mutex_unlock(&LOCK_prep_xids);
+ if (send_signal) {
DBUG_PRINT("info", ("prepared_xids=%lu", prepared_xids));
pthread_cond_signal(&COND_prep_xids);
}
- pthread_mutex_unlock(&LOCK_prep_xids);
- DBUG_RETURN(rotate_and_purge(0)); // as ::write() did not rotate
+ DBUG_VOID_RETURN;
+}
+
+int TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
+{
+ DBUG_ENTER("TC_LOG_BINLOG::unlog");
+ if (xid)
+ mark_xid_done();
+ /* As ::write_transaction_to_binlog() did not rotate, do it here. */
+ DBUG_RETURN(rotate_and_purge(0));
}
int TC_LOG_BINLOG::recover(IO_CACHE *log, Format_description_log_event *fdle)
@@ -6163,7 +6924,9 @@ int TC_LOG_BINLOG::recover(IO_CACHE *log, Format_description_log_event *fdle)
fdle->flags&= ~LOG_EVENT_BINLOG_IN_USE_F; // abort on the first error
- while ((ev= Log_event::read_log_event(log,0,fdle)) && ev->is_valid())
+ while ((ev= Log_event::read_log_event(log, 0, fdle,
+ opt_master_verify_checksum))
+ && ev->is_valid())
{
if (ev->get_type_code() == XID_EVENT)
{
@@ -6214,9 +6977,153 @@ ulonglong mysql_bin_log_file_pos(void)
{
return (ulonglong) mysql_bin_log.get_log_file()->pos_in_file;
}
+/*
+ Get the current position of the MySQL binlog for transaction currently being
+ committed.
+
+ This is valid to call from within storage engine commit_ordered() and
+ commit() methods only.
+
+ Since it stores the position inside THD, it is safe to call without any
+ locking.
+*/
+void
+mysql_bin_log_commit_pos(THD *thd, ulonglong *out_pos, const char **out_file)
+{
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
+ if (trx_data)
+ {
+ *out_file= trx_data->last_commit_pos_file;
+ *out_pos= (ulonglong)(trx_data->last_commit_pos_offset);
+ }
+ else
+ {
+ *out_file= NULL;
+ *out_pos= 0;
+ }
+}
#endif /* INNODB_COMPATIBILITY_HOOKS */
+static void
+binlog_checksum_update(MYSQL_THD thd, struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save)
+{
+ ulong value= *((ulong *)save);
+
+ pthread_mutex_lock(mysql_bin_log.get_log_lock());
+ if(mysql_bin_log.is_open())
+ {
+ uint flags= RP_FORCE_ROTATE | RP_LOCK_LOG_IS_ALREADY_LOCKED |
+ (binlog_checksum_options != (uint) value?
+ RP_BINLOG_CHECKSUM_ALG_CHANGE : 0);
+ if (flags & RP_BINLOG_CHECKSUM_ALG_CHANGE)
+ mysql_bin_log.checksum_alg_reset= (uint8) value;
+ mysql_bin_log.rotate_and_purge(flags);
+ }
+ else
+ {
+ binlog_checksum_options= value;
+ }
+ DBUG_ASSERT((ulong) binlog_checksum_options == value);
+ DBUG_ASSERT(mysql_bin_log.checksum_alg_reset == BINLOG_CHECKSUM_ALG_UNDEF);
+ pthread_mutex_unlock(mysql_bin_log.get_log_lock());
+}
+
+
+static int show_binlog_vars(THD *thd, SHOW_VAR *var, char *buff)
+{
+ mysql_bin_log.set_status_variables(thd);
+ var->type= SHOW_ARRAY;
+ var->value= (char *)&binlog_status_vars_detail;
+ return 0;
+}
+
+static SHOW_VAR binlog_status_vars_top[]= {
+ {"binlog", (char *) &show_binlog_vars, SHOW_FUNC},
+ {NullS, NullS, SHOW_LONG}
+};
+
+static MYSQL_SYSVAR_BOOL(
+ optimize_thread_scheduling,
+ opt_optimize_thread_scheduling,
+ PLUGIN_VAR_READONLY,
+ "Run fast part of group commit in a single thread, to optimize kernel "
+ "thread scheduling. On by default. Disable to run each transaction in group "
+ "commit in its own thread, which can be slower at very high concurrency. "
+ "This option is mostly for testing one algorithm versus the other, and it "
+ "should not normally be necessary to change it.",
+ NULL,
+ NULL,
+ 1);
+
+static MYSQL_SYSVAR_ENUM(
+ checksum,
+ binlog_checksum_options,
+ PLUGIN_VAR_RQCMDARG,
+ "Type of BINLOG_CHECKSUM_ALG. Include checksum for "
+ "log events in the binary log. Possible values are NONE and CRC32; "
+ "default is NONE.",
+ NULL,
+ binlog_checksum_update,
+ BINLOG_CHECKSUM_ALG_OFF,
+ &binlog_checksum_typelib);
+
+static struct st_mysql_sys_var *binlog_sys_vars[]=
+{
+ MYSQL_SYSVAR(optimize_thread_scheduling),
+ MYSQL_SYSVAR(checksum),
+ NULL
+};
+
+
+/*
+ Copy out the non-directory part of binlog position filename for the
+ `binlog_snapshot_file' status variable, same way as it is done for
+ SHOW MASTER STATUS.
+*/
+static void
+set_binlog_snapshot_file(const char *src)
+{
+ int dir_len = dirname_length(src);
+ strmake(binlog_snapshot_file, src + dir_len, sizeof(binlog_snapshot_file)-1);
+}
+
+/*
+ Copy out current values of status variables, for SHOW STATUS or
+ information_schema.global_status.
+
+ This is called only under LOCK_status, so we can fill in a static array.
+*/
+void
+TC_LOG_BINLOG::set_status_variables(THD *thd)
+{
+ binlog_trx_data *trx_data;
+
+ if (thd)
+ trx_data= (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
+ else
+ trx_data= NULL;
+
+ bool have_snapshot= (trx_data && trx_data->last_commit_pos_file[0] != 0);
+ pthread_mutex_lock(&LOCK_commit_ordered);
+ binlog_status_var_num_commits= this->num_commits;
+ binlog_status_var_num_group_commits= this->num_group_commits;
+ if (!have_snapshot)
+ {
+ set_binlog_snapshot_file(last_commit_pos_file);
+ binlog_snapshot_position= last_commit_pos_offset;
+ }
+ pthread_mutex_unlock(&LOCK_commit_ordered);
+
+ if (have_snapshot)
+ {
+ set_binlog_snapshot_file(trx_data->last_commit_pos_file);
+ binlog_snapshot_position= trx_data->last_commit_pos_offset;
+ }
+}
+
struct st_mysql_storage_engine binlog_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
@@ -6231,8 +7138,8 @@ mysql_declare_plugin(binlog)
binlog_init, /* Plugin Init */
NULL, /* Plugin Deinit */
0x0100 /* 1.0 */,
- NULL, /* status variables */
- NULL, /* system variables */
+ binlog_status_vars_top, /* status variables */
+ binlog_sys_vars, /* system variables */
NULL /* config options */
}
mysql_declare_plugin_end;
@@ -6247,8 +7154,8 @@ maria_declare_plugin(binlog)
binlog_init, /* Plugin Init */
NULL, /* Plugin Deinit */
0x0100 /* 1.0 */,
- NULL, /* status variables */
- NULL, /* system variables */
+ binlog_status_vars_top, /* status variables */
+ binlog_sys_vars, /* system variables */
"1.0", /* string version */
MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
}
diff --git a/sql/log.h b/sql/log.h
index 79c2592e7d4..156a8e6f1b6 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -40,17 +40,58 @@ class TC_LOG
virtual int open(const char *opt_name)=0;
virtual void close()=0;
- virtual int log_xid(THD *thd, my_xid xid)=0;
+ virtual int log_and_order(THD *thd, my_xid xid, bool all,
+ bool need_prepare_ordered,
+ bool need_commit_ordered) = 0;
virtual int unlog(ulong cookie, my_xid xid)=0;
+
+protected:
+ /*
+ These methods are meant to be invoked from log_and_order() implementations
+ to run any prepare_ordered() respectively commit_ordered() methods in
+ participating handlers.
+
+ They must be called using suitable thread syncronisation to ensure that
+ they are each called in the correct commit order among all
+ transactions. However, it is only necessary to call them if the
+ corresponding flag passed to log_and_order is set (it is safe, but not
+ required, to call them when the flag is false).
+
+ The caller must be holding LOCK_prepare_ordered respectively
+ LOCK_commit_ordered when calling these methods.
+ */
+ void run_prepare_ordered(THD *thd, bool all);
+ void run_commit_ordered(THD *thd, bool all);
};
+/*
+ Locks used to ensure serialised execution of TC_LOG::run_prepare_ordered()
+ and TC_LOG::run_commit_ordered(), or any other code that calls handler
+ prepare_ordered() or commit_ordered() methods.
+*/
+extern pthread_mutex_t LOCK_prepare_ordered;
+extern pthread_mutex_t LOCK_commit_ordered;
+
+extern void TC_init();
+extern void TC_destroy();
+
class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
{
public:
TC_LOG_DUMMY() {}
int open(const char *opt_name) { return 0; }
void close() { }
- int log_xid(THD *thd, my_xid xid) { return 1; }
+ /*
+ TC_LOG_DUMMY is only used when there are <= 1 XA-capable engines, and we
+ only use internal XA during commit when >= 2 XA-capable engines
+ participate.
+ */
+ int log_and_order(THD *thd, my_xid xid, bool all,
+ bool need_prepare_ordered, bool need_commit_ordered)
+ {
+ DBUG_ASSERT(0 /* Internal error - TC_LOG_DUMMY::log_and_order() called */);
+ return 1;
+ }
int unlog(ulong cookie, my_xid xid) { return 0; }
};
@@ -76,6 +117,13 @@ class TC_LOG_MMAP: public TC_LOG
pthread_cond_t cond; // to wait for a sync
} PAGE;
+ /* List of THDs for which to invoke commit_ordered(), in order. */
+ struct commit_entry
+ {
+ struct commit_entry *next;
+ THD *thd;
+ };
+
char logname[FN_REFLEN];
File fd;
my_off_t file_length;
@@ -90,16 +138,38 @@ class TC_LOG_MMAP: public TC_LOG
*/
pthread_mutex_t LOCK_active, LOCK_pool, LOCK_sync;
pthread_cond_t COND_pool, COND_active;
+ /*
+ Queue of threads that need to call commit_ordered().
+ Access to this queue must be protected by LOCK_prepare_ordered.
+ */
+ commit_entry *commit_ordered_queue;
+ /*
+ This flag and condition is used to reserve the queue while threads in it
+ each run the commit_ordered() methods one after the other. Only once the
+ last commit_ordered() in the queue is done can we start on a new queue
+ run.
+
+ Since we start this process in the first thread in the queue and finish in
+ the last (and possibly different) thread, we need a condition variable for
+ this (we cannot unlock a mutex in a different thread than the one who
+ locked it).
+
+ The condition is used together with the LOCK_prepare_ordered mutex.
+ */
+ my_bool commit_ordered_queue_busy;
+ pthread_cond_t COND_queue_busy;
public:
TC_LOG_MMAP(): inited(0) {}
int open(const char *opt_name);
void close();
- int log_xid(THD *thd, my_xid xid);
+ int log_and_order(THD *thd, my_xid xid, bool all,
+ bool need_prepare_ordered, bool need_commit_ordered);
int unlog(ulong cookie, my_xid xid);
int recover();
private:
+ int log_one_transaction(my_xid xid);
void get_active_from_pool();
int sync();
int overflow();
@@ -218,7 +288,7 @@ public:
uint user_host_len, int thread_id,
const char *command_type, uint command_type_len,
const char *sql_text, uint sql_text_len);
- bool write(THD *thd, time_t current_time, time_t query_start_arg,
+ bool write(THD *thd, time_t current_time,
const char *user_host, uint user_host_len,
ulonglong query_utime, ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len);
@@ -239,9 +309,31 @@ private:
time_t last_time;
};
+class binlog_trx_data;
class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
{
private:
+ struct group_commit_entry
+ {
+ struct group_commit_entry *next;
+ THD *thd;
+ binlog_trx_data *trx_data;
+ /*
+ Extra events (BEGIN, COMMIT/ROLLBACK/XID, and possibly INCIDENT) to be
+ written during group commit. The incident_event is only valid if
+ trx_data->has_incident() is true.
+ */
+ Log_event *begin_event;
+ Log_event *end_event;
+ Log_event *incident_event;
+ /* Set during group commit to record any per-thread error. */
+ int error;
+ int commit_errno;
+ /* This is the `all' parameter for ha_commit_ordered(). */
+ bool all;
+ /* True if we come in through XA log_and_order(), false otherwise. */
+ };
+
/* LOCK_log and LOCK_index are inited by init_pthread_objects() */
pthread_mutex_t LOCK_index;
pthread_mutex_t LOCK_prep_xids;
@@ -283,6 +375,20 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
In 5.0 it's 0 for relay logs too!
*/
bool no_auto_events;
+ /* Queue of transactions queued up to participate in group commit. */
+ group_commit_entry *group_commit_queue;
+ /*
+ Condition variable to mark that the group commit queue is busy.
+ Used when each thread does it's own commit_ordered() (when
+ binlog_optimize_thread_scheduling=1).
+ Used with the LOCK_commit_ordered mutex.
+ */
+ my_bool group_commit_queue_busy;
+ pthread_cond_t COND_queue_busy;
+ /* Total number of committed transactions. */
+ ulonglong num_commits;
+ /* Number of group commits done. */
+ ulonglong num_group_commits;
int write_to_file(IO_CACHE *cache);
/*
@@ -292,6 +398,11 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
*/
int new_file_without_locking();
int new_file_impl(bool need_lock);
+ int write_transaction(group_commit_entry *entry);
+ bool write_transaction_to_binlog_events(group_commit_entry *entry);
+ void trx_group_commit_leader(group_commit_entry *leader);
+ void mark_xid_done();
+ void mark_xids_active(uint xid_count);
public:
using MYSQL_LOG::generate_name;
@@ -299,7 +410,41 @@ public:
/* This is relay log */
bool is_relay_log;
-
+ uint8 checksum_alg_reset; // to contain a new value when binlog is rotated
+ /*
+ Holds the last seen in Relay-Log FD's checksum alg value.
+ The initial value comes from the slave's local FD that heads
+ the very first Relay-Log file. In the following the value may change
+ with each received master's FD_m.
+ Besides to be used in verification events that IO thread receives
+ (except the 1st fake Rotate, see @c Master_info:: checksum_alg_before_fd),
+ the value specifies if/how to compute checksum for slave's local events
+ and the first fake Rotate (R_f^1) coming from the master.
+ R_f^1 needs logging checksum-compatibly with the RL's heading FD_s.
+
+ Legends for the checksum related comments:
+
+ FD - Format-Description event,
+ R - Rotate event
+ R_f - the fake Rotate event
+ E - an arbirary event
+
+ The underscore indexes for any event
+ `_s' indicates the event is generated by Slave
+ `_m' - by Master
+
+ Two special underscore indexes of FD:
+ FD_q - Format Description event for queuing (relay-logging)
+ FD_e - Format Description event for executing (relay-logging)
+
+ Upper indexes:
+ E^n - n:th event is a sequence
+
+ RL - Relay Log
+ (A) - checksum algorithm descriptor value
+ FD.(A) - the value of (A) in FD
+ */
+ uint8 relay_log_checksum_alg;
/*
These describe the log's format. This is used only for relay logs.
_for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
@@ -310,6 +455,12 @@ public:
*/
Format_description_log_event *description_event_for_exec,
*description_event_for_queue;
+ /*
+ Binlog position of last commit (or non-transactional write) to the binlog.
+ Access to this is protected by LOCK_commit_ordered.
+ */
+ char last_commit_pos_file[FN_REFLEN];
+ my_off_t last_commit_pos_offset;
MYSQL_BIN_LOG();
/*
@@ -320,7 +471,8 @@ public:
int open(const char *opt_name);
void close();
- int log_xid(THD *thd, my_xid xid);
+ int log_and_order(THD *thd, my_xid xid, bool all,
+ bool need_prepare_ordered, bool need_commit_ordered);
int unlog(ulong cookie, my_xid xid);
int recover(IO_CACHE *log, Format_description_log_event *fdle);
#if !defined(MYSQL_CLIENT)
@@ -364,11 +516,14 @@ public:
int new_file();
void reset_gathered_updates(THD *thd);
- bool write(Log_event* event_info); // binary log write
- bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident);
- bool write_incident(THD *thd, bool lock);
- int write_cache(THD *thd, IO_CACHE *cache, bool lock_log,
- bool flush_and_sync);
+ bool write(Log_event* event_info,
+ my_bool *with_annotate= 0); // binary log write
+ bool write_transaction_to_binlog(THD *thd, binlog_trx_data *trx_data,
+ Log_event *end_ev, bool all);
+
+ bool write_incident_already_locked(THD *thd);
+ bool write_incident(THD *thd);
+ int write_cache(THD *thd, IO_CACHE *cache);
void set_write_error(THD *thd);
bool check_write_error(THD *thd);
@@ -423,6 +578,7 @@ public:
inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
inline IO_CACHE *get_index_file() { return &index_file;}
inline uint32 get_open_count() { return open_count; }
+ void set_status_variables(THD *thd);
};
class Log_event_handler
@@ -432,14 +588,14 @@ public:
virtual bool init()= 0;
virtual void cleanup()= 0;
- virtual bool log_slow(THD *thd, time_t current_time,
- time_t query_start_arg, const char *user_host,
+ virtual bool log_slow(THD *thd, my_hrtime_t current_time,
+ const char *user_host,
uint user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len)= 0;
virtual bool log_error(enum loglevel level, const char *format,
va_list args)= 0;
- virtual bool log_general(THD *thd, time_t event_time, const char *user_host,
+ virtual bool log_general(THD *thd, my_hrtime_t event_time, const char *user_host,
uint user_host_len, int thread_id,
const char *command_type, uint command_type_len,
const char *sql_text, uint sql_text_len,
@@ -461,14 +617,14 @@ public:
virtual bool init();
virtual void cleanup();
- virtual bool log_slow(THD *thd, time_t current_time,
- time_t query_start_arg, const char *user_host,
+ virtual bool log_slow(THD *thd, my_hrtime_t current_time,
+ const char *user_host,
uint user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len);
virtual bool log_error(enum loglevel level, const char *format,
va_list args);
- virtual bool log_general(THD *thd, time_t event_time, const char *user_host,
+ virtual bool log_general(THD *thd, my_hrtime_t event_time, const char *user_host,
uint user_host_len, int thread_id,
const char *command_type, uint command_type_len,
const char *sql_text, uint sql_text_len,
@@ -493,14 +649,14 @@ public:
virtual bool init();
virtual void cleanup();
- virtual bool log_slow(THD *thd, time_t current_time,
- time_t query_start_arg, const char *user_host,
+ virtual bool log_slow(THD *thd, my_hrtime_t current_time,
+ const char *user_host,
uint user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len);
virtual bool log_error(enum loglevel level, const char *format,
va_list args);
- virtual bool log_general(THD *thd, time_t event_time, const char *user_host,
+ virtual bool log_general(THD *thd, my_hrtime_t event_time, const char *user_host,
uint user_host_len, int thread_id,
const char *command_type, uint command_type_len,
const char *sql_text, uint sql_text_len,
diff --git a/sql/log_event.cc b/sql/log_event.cc
index fb69dbb5d09..10b14c29e02 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -42,6 +42,31 @@
#include <base64.h>
#include <my_bitmap.h>
+
+/**
+ BINLOG_CHECKSUM variable.
+*/
+const char *binlog_checksum_type_names[]= {
+ "NONE",
+ "CRC32",
+ NullS
+};
+
+unsigned int binlog_checksum_type_length[]= {
+ sizeof("NONE") - 1,
+ sizeof("CRC32") - 1,
+ 0
+};
+
+TYPELIB binlog_checksum_typelib=
+{
+ array_elements(binlog_checksum_type_names) - 1, "",
+ binlog_checksum_type_names,
+ binlog_checksum_type_length
+};
+
+
+
#define log_cs &my_charset_latin1
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
@@ -72,6 +97,25 @@ template bool valid_buffer_range<unsigned int>(unsigned int,
const char*,
unsigned int);
+/*
+ replication event checksum is introduced in the following "checksum-home" version.
+ The checksum-aware servers extract FD's version to decide whether the FD event
+ carries checksum info.
+
+ TODO: correct the constant when it has been determined
+ (which main tree to push and when)
+*/
+const uchar checksum_version_split_mysql[3]= {5, 6, 1};
+const ulong checksum_version_product_mysql=
+ (checksum_version_split_mysql[0] * 256 +
+ checksum_version_split_mysql[1]) * 256 +
+ checksum_version_split_mysql[2];
+const uchar checksum_version_split_mariadb[3]= {5, 3, 0};
+const ulong checksum_version_product_mariadb=
+ (checksum_version_split_mariadb[0] * 256 +
+ checksum_version_split_mariadb[1]) * 256 +
+ checksum_version_split_mariadb[2];
+
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd);
@@ -419,6 +463,7 @@ inline bool unexpected_error_code(int unexpected_error)
case ER_NET_READ_ERROR:
case ER_NET_ERROR_ON_WRITE:
case ER_QUERY_INTERRUPTED:
+ case ER_CONNECTION_KILLED:
case ER_SERVER_SHUTDOWN:
case ER_NEW_ABORTING_CONNECTION:
return(TRUE);
@@ -651,7 +696,6 @@ static void print_set_option(IO_CACHE* file, uint32 bits_changed,
}
}
#endif
-
/**************************************************************************
Log_event methods (= the parent class of all events)
**************************************************************************/
@@ -690,6 +734,7 @@ const char* Log_event::get_type_str(Log_event_type type)
case BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
case EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
case INCIDENT_EVENT: return "Incident";
+ case ANNOTATE_ROWS_EVENT: return "Annotate_rows";
default: return "Unknown"; /* impossible */
}
}
@@ -706,10 +751,13 @@ const char* Log_event::get_type_str()
#ifndef MYSQL_CLIENT
Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
- :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), thd(thd_arg)
+ :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg),
+ cache_type(EVENT_INVALID_CACHE), crc(0), thd(thd_arg),
+ checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
{
server_id= thd->server_id;
- when= thd->start_time;
+ when= thd->start_time;
+ when_sec_part=thd->start_time_sec_part;
cache_stmt= using_trans;
}
@@ -723,14 +771,16 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
Log_event::Log_event()
:temp_buf(0), exec_time(0), flags(0), cache_stmt(0),
- thd(0)
+ cache_type(EVENT_INVALID_CACHE), crc(0),
+ thd(0), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
{
server_id= ::server_id;
/*
We can't call my_time() here as this would cause a call before
my_init() is called
*/
- when= 0;
+ when= 0;
+ when_sec_part=0;
log_pos= 0;
}
#endif /* !MYSQL_CLIENT */
@@ -742,12 +792,14 @@ Log_event::Log_event()
Log_event::Log_event(const char* buf,
const Format_description_log_event* description_event)
- :temp_buf(0), cache_stmt(0)
+ :temp_buf(0), cache_stmt(0), cache_type(EVENT_INVALID_CACHE),
+ crc(0), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
{
#ifndef MYSQL_CLIENT
thd = 0;
#endif
when = uint4korr(buf);
+ when_sec_part= 0;
server_id = uint4korr(buf + SERVER_ID_OFFSET);
data_written= uint4korr(buf + EVENT_LEN_OFFSET);
if (description_event->binlog_version==1)
@@ -769,7 +821,7 @@ Log_event::Log_event(const char* buf,
logs are in 4.0 format, until it finds a Format_desc).
*/
if (description_event->binlog_version==3 &&
- buf[EVENT_TYPE_OFFSET]<FORMAT_DESCRIPTION_EVENT && log_pos)
+ (uchar)buf[EVENT_TYPE_OFFSET]<FORMAT_DESCRIPTION_EVENT && log_pos)
{
/*
If log_pos=0, don't change it. log_pos==0 is a marker to mean
@@ -787,8 +839,8 @@ Log_event::Log_event(const char* buf,
DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
flags= uint2korr(buf + FLAGS_OFFSET);
- if ((buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) ||
- (buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT))
+ if (((uchar)buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) ||
+ ((uchar)buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT))
{
/*
These events always have a header which stops here (i.e. their
@@ -836,21 +888,13 @@ int Log_event::do_update_pos(Relay_log_info *rli)
DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
if (debug_not_change_ts_if_art_event == 1
&& is_artificial_event())
- {
- debug_not_change_ts_if_art_event= 0;
- });
-#ifndef DBUG_OFF
- rli->stmt_done(log_pos,
- is_artificial_event() &&
- debug_not_change_ts_if_art_event > 0 ? 0 : when);
-#else
- rli->stmt_done(log_pos, is_artificial_event()? 0 : when);
-#endif
+ debug_not_change_ts_if_art_event= 0; );
+ rli->stmt_done(log_pos, is_artificial_event()
+ IF_DBUG(&& debug_not_change_ts_if_art_event > 0) ?
+ 0 : when);
DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
if (debug_not_change_ts_if_art_event == 0)
- {
- debug_not_change_ts_if_art_event= 2;
- });
+ debug_not_change_ts_if_art_event= 2; );
}
return 0; // Cannot fail currently
}
@@ -928,6 +972,105 @@ void Log_event::init_show_field_list(List<Item>* field_list)
field_list->push_back(new Item_empty_string("Info", 20));
}
+/**
+ A decider of whether to trigger checksum computation or not.
+ To be invoked in Log_event::write() stack.
+ The decision is positive
+
+ S,M) if it's been marked for checksumming with @c checksum_alg
+
+ M) otherwise, if @@global.binlog_checksum is not NONE and the event is
+ directly written to the binlog file.
+ The to-be-cached event decides at @c write_cache() time.
+
+ Otherwise the decision is negative.
+
+ @note A side effect of the method is altering Log_event::checksum_alg
+ it the latter was undefined at calling.
+
+ @return true (positive) or false (negative)
+*/
+my_bool Log_event::need_checksum()
+{
+ DBUG_ENTER("Log_event::need_checksum");
+ my_bool ret;
+ /*
+ few callers of Log_event::write
+ (incl FD::write, FD constructing code on the slave side, Rotate relay log
+ and Stop event)
+ provides their checksum alg preference through Log_event::checksum_alg.
+ */
+ ret= ((checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF) ?
+ (checksum_alg != BINLOG_CHECKSUM_ALG_OFF) :
+ ((binlog_checksum_options != BINLOG_CHECKSUM_ALG_OFF) &&
+ (cache_type == Log_event::EVENT_NO_CACHE)) ?
+ test(binlog_checksum_options) : FALSE);
+
+ /*
+ FD calls the methods before data_written has been calculated.
+ The following invariant claims if the current is not the first
+ call (and therefore data_written is not zero) then `ret' must be
+ TRUE. It may not be null because FD is always checksummed.
+ */
+
+ DBUG_ASSERT(get_type_code() != FORMAT_DESCRIPTION_EVENT || ret ||
+ data_written == 0);
+
+ if (checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF)
+ checksum_alg= ret ? // calculated value stored
+ (uint8) binlog_checksum_options : (uint8) BINLOG_CHECKSUM_ALG_OFF;
+
+ DBUG_ASSERT(!ret ||
+ ((checksum_alg == binlog_checksum_options ||
+ /*
+ Stop event closes the relay-log and its checksum alg
+ preference is set by the caller can be different
+ from the server's binlog_checksum_options.
+ */
+ get_type_code() == STOP_EVENT ||
+ /*
+ Rotate:s can be checksummed regardless of the server's
+ binlog_checksum_options. That applies to both
+ the local RL's Rotate and the master's Rotate
+ which IO thread instantiates via queue_binlog_ver_3_event.
+ */
+ get_type_code() == ROTATE_EVENT
+ || /* FD is always checksummed */
+ get_type_code() == FORMAT_DESCRIPTION_EVENT) &&
+ checksum_alg != BINLOG_CHECKSUM_ALG_OFF));
+
+ DBUG_ASSERT(checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
+
+ DBUG_ASSERT(((get_type_code() != ROTATE_EVENT &&
+ get_type_code() != STOP_EVENT) ||
+ get_type_code() != FORMAT_DESCRIPTION_EVENT) ||
+ cache_type == Log_event::EVENT_NO_CACHE);
+
+ DBUG_RETURN(ret);
+}
+
+bool Log_event::wrapper_my_b_safe_write(IO_CACHE* file, const uchar* buf, ulong size)
+{
+ if (need_checksum() && size != 0)
+ crc= my_checksum(crc, buf, size);
+
+ return my_b_safe_write(file, buf, size);
+}
+
+bool Log_event::write_footer(IO_CACHE* file)
+{
+ /*
+ footer contains the checksum-algorithm descriptor
+ followed by the checksum value
+ */
+ if (need_checksum())
+ {
+ uchar buf[BINLOG_CHECKSUM_LEN];
+ int4store(buf, crc);
+ return (my_b_safe_write(file, (uchar*) buf, sizeof(buf)));
+ }
+ return 0;
+}
/*
Log_event::write()
@@ -937,11 +1080,18 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
{
uchar header[LOG_EVENT_HEADER_LEN];
ulong now;
+ bool ret;
DBUG_ENTER("Log_event::write_header");
/* Store number of bytes that will be written by this event */
data_written= event_data_length + sizeof(header);
+ if (need_checksum())
+ {
+ crc= my_checksum(0L, NULL, 0);
+ data_written += BINLOG_CHECKSUM_LEN;
+ }
+
/*
log_pos != 0 if this is relay-log event. In this case we should not
change the position
@@ -986,7 +1136,7 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
log_pos= my_b_safe_tell(file)+data_written;
}
- now= (ulong) get_time(); // Query start time
+ now= get_time(); // Query start time
/*
Header will be of size LOG_EVENT_HEADER_LEN for all events, except for
@@ -1000,9 +1150,36 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
int4store(header+ SERVER_ID_OFFSET, server_id);
int4store(header+ EVENT_LEN_OFFSET, data_written);
int4store(header+ LOG_POS_OFFSET, log_pos);
- int2store(header+ FLAGS_OFFSET, flags);
-
- DBUG_RETURN(my_b_safe_write(file, header, sizeof(header)) != 0);
+ /*
+ recording checksum of FD event computed with dropped
+ possibly active LOG_EVENT_BINLOG_IN_USE_F flag.
+ Similar step at verication: the active flag is dropped before
+ checksum computing.
+ */
+ if (header[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT ||
+ !need_checksum() || !(flags & LOG_EVENT_BINLOG_IN_USE_F))
+ {
+ int2store(header+ FLAGS_OFFSET, flags);
+ ret= wrapper_my_b_safe_write(file, header, sizeof(header)) != 0;
+ }
+ else
+ {
+ ret= (wrapper_my_b_safe_write(file, header, FLAGS_OFFSET) != 0);
+ if (!ret)
+ {
+ flags &= ~LOG_EVENT_BINLOG_IN_USE_F;
+ int2store(header + FLAGS_OFFSET, flags);
+ crc= my_checksum(crc, header + FLAGS_OFFSET, sizeof(flags));
+ flags |= LOG_EVENT_BINLOG_IN_USE_F;
+ int2store(header + FLAGS_OFFSET, flags);
+ ret= (my_b_safe_write(file, header + FLAGS_OFFSET, sizeof(flags)) != 0);
+ }
+ if (!ret)
+ ret= (wrapper_my_b_safe_write(file, header + FLAGS_OFFSET + sizeof(flags),
+ sizeof(header)
+ - (FLAGS_OFFSET + sizeof(flags))) != 0);
+ }
+ DBUG_RETURN( ret);
}
@@ -1012,11 +1189,13 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
*/
int Log_event::read_log_event(IO_CACHE* file, String* packet,
- pthread_mutex_t* log_lock)
+ pthread_mutex_t* log_lock,
+ uint8 checksum_alg_arg)
{
ulong data_len;
int result=0;
char buf[LOG_EVENT_MINIMAL_HEADER_LEN];
+ uchar ev_offset= packet->length();
DBUG_ENTER("Log_event::read_log_event");
if (log_lock)
@@ -1074,6 +1253,31 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
(file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO));
/* Implicit goto end; */
}
+ else
+ {
+ /* Corrupt the event for Dump thread*/
+ DBUG_EXECUTE_IF("corrupt_read_log_event2",
+ uchar *debug_event_buf_c = (uchar*) packet->ptr() + ev_offset;
+ if (debug_event_buf_c[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT)
+ {
+ int debug_cor_pos = rand() % (data_len + sizeof(buf) - BINLOG_CHECKSUM_LEN);
+ debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
+ DBUG_PRINT("info", ("Corrupt the event at Log_event::read_log_event: byte on position %d", debug_cor_pos));
+ DBUG_SET("-d,corrupt_read_log_event2");
+ }
+ );
+ /*
+ CRC verification of the Dump thread
+ */
+ if (opt_master_verify_checksum &&
+ event_checksum_test((uchar*) packet->ptr() + ev_offset,
+ data_len + sizeof(buf),
+ checksum_alg_arg))
+ {
+ result= LOG_READ_CHECKSUM_FAILURE;
+ goto end;
+ }
+ }
}
end:
@@ -1099,11 +1303,13 @@ end:
Log_event* Log_event::read_log_event(IO_CACHE* file,
pthread_mutex_t* log_lock,
const Format_description_log_event
- *description_event)
+ *description_event,
+ my_bool crc_check)
#else
Log_event* Log_event::read_log_event(IO_CACHE* file,
const Format_description_log_event
- *description_event)
+ *description_event,
+ my_bool crc_check)
#endif
{
DBUG_ENTER("Log_event::read_log_event");
@@ -1167,7 +1373,7 @@ failed my_b_read"));
error = "read error";
goto err;
}
- if ((res= read_log_event(buf, data_len, &error, description_event)))
+ if ((res= read_log_event(buf, data_len, &error, description_event, crc_check)))
res->register_temp_buf(buf, TRUE);
err:
@@ -1200,9 +1406,11 @@ err:
Log_event* Log_event::read_log_event(const char* buf, uint event_len,
const char **error,
- const Format_description_log_event *description_event)
+ const Format_description_log_event *description_event,
+ my_bool crc_check)
{
Log_event* ev;
+ uint8 alg;
DBUG_ENTER("Log_event::read_log_event(char*,...)");
DBUG_ASSERT(description_event != 0);
DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version));
@@ -1210,14 +1418,68 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
/* Check the integrity */
if (event_len < EVENT_LEN_OFFSET ||
- buf[EVENT_TYPE_OFFSET] >= ENUM_END_EVENT ||
+ (uchar)buf[EVENT_TYPE_OFFSET] >= ENUM_END_EVENT ||
(uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
{
*error="Sanity check failed"; // Needed to free buffer
DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
}
- uint event_type= buf[EVENT_TYPE_OFFSET];
+ uint event_type= (uchar)buf[EVENT_TYPE_OFFSET];
+ // all following START events in the current file are without checksum
+ if (event_type == START_EVENT_V3)
+ (const_cast< Format_description_log_event *>(description_event))->checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
+ /*
+ CRC verification by SQL and Show-Binlog-Events master side.
+ The caller has to provide @description_event->checksum_alg to
+ be the last seen FD's (A) descriptor.
+ If event is FD the descriptor is in it.
+ Notice, FD of the binlog can be only in one instance and therefore
+ Show-Binlog-Events executing master side thread needs just to know
+ the only FD's (A) value - whereas RL can contain more.
+ In the RL case, the alg is kept in FD_e (@description_event) which is reset
+ to the newer read-out event after its execution with possibly new alg descriptor.
+ Therefore in a typical sequence of RL:
+ {FD_s^0, FD_m, E_m^1} E_m^1
+ will be verified with (A) of FD_m.
+
+ See legends definition on MYSQL_BIN_LOG::relay_log_checksum_alg docs
+ lines (log.h).
+
+ Notice, a pre-checksum FD version forces alg := BINLOG_CHECKSUM_ALG_UNDEF.
+ */
+ alg= (event_type != FORMAT_DESCRIPTION_EVENT) ?
+ description_event->checksum_alg : get_checksum_alg(buf, event_len);
+ // Emulate the corruption during reading an event
+ DBUG_EXECUTE_IF("corrupt_read_log_event_char",
+ if (event_type != FORMAT_DESCRIPTION_EVENT)
+ {
+ char *debug_event_buf_c = (char *)buf;
+ int debug_cor_pos = rand() % (event_len - BINLOG_CHECKSUM_LEN);
+ debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
+ DBUG_PRINT("info", ("Corrupt the event at Log_event::read_log_event(char*,...): byte on position %d", debug_cor_pos));
+ DBUG_SET("-d,corrupt_read_log_event_char");
+ }
+ );
+ if (crc_check &&
+ event_checksum_test((uchar *) buf, event_len, alg))
+ {
+#ifdef MYSQL_CLIENT
+ *error= "Event crc check failed! Most likely there is event corruption.";
+ if (force_opt)
+ {
+ ev= new Unknown_log_event(buf, description_event);
+ DBUG_RETURN(ev);
+ }
+ else
+ DBUG_RETURN(NULL);
+#else
+ *error= ER(ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE);
+ sql_print_error("%s", ER(ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE));
+ DBUG_RETURN(NULL);
+#endif
+ }
+
if (event_type > description_event->number_of_event_types &&
event_type != FORMAT_DESCRIPTION_EVENT)
{
@@ -1256,6 +1518,11 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
event_type= description_event->event_type_permutation[event_type];
}
+ if (alg != BINLOG_CHECKSUM_ALG_UNDEF &&
+ (event_type == FORMAT_DESCRIPTION_EVENT ||
+ alg != BINLOG_CHECKSUM_ALG_OFF))
+ event_len= event_len - BINLOG_CHECKSUM_LEN;
+
switch(event_type) {
case QUERY_EVENT:
ev = new Query_log_event(buf, event_len, description_event, QUERY_EVENT);
@@ -1339,6 +1606,9 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
case INCIDENT_EVENT:
ev = new Incident_log_event(buf, event_len, description_event);
break;
+ case ANNOTATE_ROWS_EVENT:
+ ev = new Annotate_rows_log_event(buf, event_len, description_event);
+ break;
default:
DBUG_PRINT("error",("Unknown event code: %d",
(int) buf[EVENT_TYPE_OFFSET]));
@@ -1347,6 +1617,14 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
}
}
+ if (ev)
+ {
+ ev->checksum_alg= alg;
+ if (ev->checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
+ ev->checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
+ ev->crc= uint4korr(buf + (event_len));
+ }
+
DBUG_PRINT("read_event", ("%s(type_code: %d; event_len: %d)",
ev ? ev->get_type_str() : "<unknown>",
buf[EVENT_TYPE_OFFSET],
@@ -1401,6 +1679,18 @@ void Log_event::print_header(IO_CACHE* file,
my_b_printf(file, " server id %lu end_log_pos %s ", (ulong) server_id,
llstr(log_pos,llbuff));
+ /* print the checksum */
+
+ if (checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
+ checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
+ {
+ char checksum_buf[BINLOG_CHECKSUM_LEN * 2 + 4]; // to fit to "0x%lx "
+ size_t const bytes_written=
+ my_snprintf(checksum_buf, sizeof(checksum_buf), "0x%08lx ", (ulong) crc);
+ my_b_printf(file, "%s ", get_type(&binlog_checksum_typelib, checksum_alg));
+ my_b_printf(file, checksum_buf, bytes_written);
+ }
+
/* mysqlbinlog --hexdump */
if (print_event_info->hexdump_from)
{
@@ -1769,6 +2059,7 @@ beg:
uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
d= (ulong) (i64 / 1000000);
t= (ulong) (i64 % 1000000);
+
my_b_printf(file, "%04d-%02d-%02d %02d:%02d:%02d",
(int) (d / 10000), (int) (d % 10000) / 100, (int) (d % 100),
(int) (t / 10000), (int) (t % 10000) / 100, (int) t % 100);
@@ -2024,12 +2315,10 @@ end:
delete td;
}
-#ifdef MYSQL_CLIENT
void free_table_map_log_event(Table_map_log_event *event)
{
delete event;
}
-#endif
void Log_event::print_base64(IO_CACHE* file,
PRINT_EVENT_INFO* print_event_info,
@@ -2066,6 +2355,9 @@ void Log_event::print_base64(IO_CACHE* file,
if (print_event_info->verbose)
{
Rows_log_event *ev= NULL;
+ if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF &&
+ checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
+ size-= BINLOG_CHECKSUM_LEN; // checksum is displayed through the header
if (ptr[4] == TABLE_MAP_EVENT)
{
@@ -2109,15 +2401,13 @@ void Log_event::print_base64(IO_CACHE* file,
void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
{
struct tm *res;
+ time_t my_when= when;
DBUG_ENTER("Log_event::print_timestamp");
if (!ts)
- ts = &when;
-#ifdef MYSQL_SERVER // This is always false
- struct tm tm_tmp;
- localtime_r(ts,(res= &tm_tmp));
-#else
+ {
+ ts = &my_when;
+ }
res=localtime(ts);
-#endif
my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
res->tm_year % 100,
@@ -2396,6 +2686,15 @@ bool Query_log_event::write(IO_CACHE* file)
memcpy(start, host.str, host.length);
start+= host.length;
}
+
+ }
+
+ if (thd && thd->query_start_sec_part_used)
+ {
+ *start++= Q_HRNOW;
+ get_time();
+ int3store(start, when_sec_part);
+ start+= 3;
}
/*
NOTE: When adding new status vars, please don't forget to update
@@ -2423,12 +2722,13 @@ bool Query_log_event::write(IO_CACHE* file)
event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
return (write_header(file, event_length) ||
- my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
+ wrapper_my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
write_post_header_for_derived(file) ||
- my_b_safe_write(file, (uchar*) start_of_status,
+ wrapper_my_b_safe_write(file, (uchar*) start_of_status,
(uint) (start-start_of_status)) ||
- my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
- my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
+ wrapper_my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
+ wrapper_my_b_safe_write(file, (uchar*) query, q_len) ||
+ write_footer(file)) ? 1 : 0;
}
/**
@@ -2488,7 +2788,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
error_code= errcode;
- time(&end_time);
+ end_time= my_time(0);
exec_time = (ulong) (end_time - thd_arg->start_time);
/**
@todo this means that if we have no catalog, then it is replicated
@@ -2623,6 +2923,7 @@ code_name(int code)
case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
case Q_TABLE_MAP_FOR_UPDATE_CODE: return "Q_TABLE_MAP_FOR_UPDATE_CODE";
case Q_MASTER_DATA_WRITTEN_CODE: return "Q_MASTER_DATA_WRITTEN_CODE";
+ case Q_HRNOW: return "Q_HRNOW";
}
sprintf(buf, "CODE#%d", code);
return buf;
@@ -2839,6 +3140,14 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
CHECK_SPACE(pos, end, host.length);
host.str= (char *)pos;
pos+= host.length;
+ break;
+ }
+ case Q_HRNOW:
+ {
+ CHECK_SPACE(pos, end, 3);
+ when_sec_part= uint3korr(pos);
+ pos+= 3;
+ break;
}
default:
/* That's why you must write status vars in growing order of code */
@@ -2872,6 +3181,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
+ data_len + 1
+ sizeof(size_t)//for db_len
+ db_len + 1
+ + QUERY_CACHE_DB_LENGTH_SIZE
+ QUERY_CACHE_FLAGS_SIZE,
MYF(MY_WME))))
#else
@@ -2943,7 +3253,7 @@ void Query_log_event::print_query_header(IO_CACHE* file,
PRINT_EVENT_INFO* print_event_info)
{
// TODO: print the catalog ??
- char buff[40],*end; // Enough for SET TIMESTAMP
+ char buff[64], *end; // Enough for SET TIMESTAMP
bool different_db= 1;
uint32 tmp;
@@ -2970,6 +3280,11 @@ void Query_log_event::print_query_header(IO_CACHE* file,
}
end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
+ if (when_sec_part)
+ {
+ *end++= '.';
+ end=int10_to_str(when_sec_part, end, 10);
+ }
end= strmov(end, print_event_info->delimiter);
*end++='\n';
my_b_write(file, (uchar*) buff, (uint) (end-buff));
@@ -3237,7 +3552,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
*/
if (is_trans_keyword() || rpl_filter->db_ok(thd->db))
{
- thd->set_time((time_t)when);
+ thd->set_time(when, when_sec_part);
thd->set_query((char*)query_arg, q_len_arg);
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id = next_query_id();
@@ -3442,7 +3757,7 @@ Default database: '%s'. Query: '%s'",
{
DBUG_PRINT("info",("error ignored"));
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
- thd->killed= THD::NOT_KILLED;
+ thd->killed= NOT_KILLED;
/*
When an error is expected and matches the actual error the
slave does not report any error and by consequence changes
@@ -3684,10 +3999,11 @@ bool Start_log_event_v3::write(IO_CACHE* file)
int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
if (!dont_set_created)
- created= when= get_time();
+ created= get_time(); // this sets when and when_sec_part as a side effect
int4store(buff + ST_CREATED_OFFSET,created);
return (write_header(file, sizeof(buff)) ||
- my_b_safe_write(file, (uchar*) buff, sizeof(buff)));
+ wrapper_my_b_safe_write(file, (uchar*) buff, sizeof(buff)) ||
+ write_footer(file));
}
#endif
@@ -3789,6 +4105,7 @@ int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
old 4.0 (binlog version 2) is not supported;
it should not be used for replication with
5.0.
+ @param server_ver a string containing the server version.
*/
Format_description_log_event::
@@ -3804,9 +4121,9 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
common_header_len= LOG_EVENT_HEADER_LEN;
number_of_event_types= LOG_EVENT_TYPES;
/* we'll catch my_malloc() error in is_valid() */
- post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
+ post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8)
+ + BINLOG_CHECKSUM_ALG_DESC_LEN,
MYF(0));
-
/*
This long list of assignments is not beautiful, but I see no way to
make it nicer, as the right members are #defines, not array members, so
@@ -3869,6 +4186,13 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
post_header_len[DELETE_ROWS_EVENT-1]= 6;);
post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
+ // Set header length of the reserved events to 0
+ memset(post_header_len + MYSQL_EVENTS_END - 1, 0,
+ (MARIA_EVENTS_BEGIN - MYSQL_EVENTS_END)*sizeof(uint8));
+
+ // Set header lengths of Maria events
+ post_header_len[ANNOTATE_ROWS_EVENT-1]= ANNOTATE_ROWS_HEADER_LEN;
+
// Sanity-check that all post header lengths are initialized.
IF_DBUG({
int i;
@@ -3923,6 +4247,7 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
break;
}
calc_server_version_split();
+ checksum_alg= (uint8) BINLOG_CHECKSUM_ALG_UNDEF;
}
@@ -3957,14 +4282,26 @@ Format_description_log_event(const char* buf,
if ((common_header_len=buf[ST_COMMON_HEADER_LEN_OFFSET]) < OLD_HEADER_LEN)
DBUG_VOID_RETURN; /* sanity check */
number_of_event_types=
- event_len-(LOG_EVENT_MINIMAL_HEADER_LEN+ST_COMMON_HEADER_LEN_OFFSET+1);
+ event_len - (LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET + 1);
DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d",
common_header_len, number_of_event_types));
/* If alloc fails, we'll detect it in is_valid() */
+
post_header_len= (uint8*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
number_of_event_types*
- sizeof(*post_header_len), MYF(0));
+ sizeof(*post_header_len),
+ MYF(0));
calc_server_version_split();
+ if (!is_version_before_checksum(&server_version_split))
+ {
+ /* the last bytes are the checksum alg desc and value (or value's room) */
+ number_of_event_types -= BINLOG_CHECKSUM_ALG_DESC_LEN;
+ checksum_alg= post_header_len[number_of_event_types];
+ }
+ else
+ {
+ checksum_alg= (uint8) BINLOG_CHECKSUM_ALG_UNDEF;
+ }
/*
In some previous versions, the events were given other event type
@@ -4075,21 +4412,59 @@ Format_description_log_event(const char* buf,
#ifndef MYSQL_CLIENT
bool Format_description_log_event::write(IO_CACHE* file)
{
+ bool ret;
+ bool no_checksum;
/*
We don't call Start_log_event_v3::write() because this would make 2
my_b_safe_write().
*/
- uchar buff[FORMAT_DESCRIPTION_HEADER_LEN];
+ uchar buff[FORMAT_DESCRIPTION_HEADER_LEN + BINLOG_CHECKSUM_ALG_DESC_LEN];
+ size_t rec_size= sizeof(buff);
int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
if (!dont_set_created)
- created= when= get_time();
+ created= get_time();
int4store(buff + ST_CREATED_OFFSET,created);
buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
- memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET+1, (uchar*) post_header_len,
+ memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET + 1, (uchar*) post_header_len,
LOG_EVENT_TYPES);
- return (write_header(file, sizeof(buff)) ||
- my_b_safe_write(file, buff, sizeof(buff)));
+ /*
+ if checksum is requested
+ record the checksum-algorithm descriptor next to
+ post_header_len vector which will be followed by the checksum value.
+ Master is supposed to trigger checksum computing by binlog_checksum_options,
+ slave does it via marking the event according to
+ FD_queue checksum_alg value.
+ */
+ compile_time_assert(sizeof(BINLOG_CHECKSUM_ALG_DESC_LEN == 1));
+#ifndef DBUG_OFF
+ data_written= 0; // to prepare for need_checksum assert
+#endif
+ buff[FORMAT_DESCRIPTION_HEADER_LEN]= need_checksum() ?
+ checksum_alg : (uint8) BINLOG_CHECKSUM_ALG_OFF;
+ /*
+ FD of checksum-aware server is always checksum-equipped, (V) is in,
+ regardless of @@global.binlog_checksum policy.
+ Thereby a combination of (A) == 0, (V) != 0 means
+ it's the checksum-aware server's FD event that heads checksum-free binlog
+ file.
+ Here 0 stands for checksumming OFF to evaluate (V) as 0 is that case.
+ A combination of (A) != 0, (V) != 0 denotes FD of the checksum-aware server
+ heading the checksummed binlog.
+ (A), (V) presence in FD of the checksum-aware server makes the event
+ 1 + 4 bytes bigger comparing to the former FD.
+ */
+
+ if ((no_checksum= (checksum_alg == BINLOG_CHECKSUM_ALG_OFF)))
+ {
+ checksum_alg= BINLOG_CHECKSUM_ALG_CRC32; // Forcing (V) room to fill anyway
+ }
+ ret= (write_header(file, rec_size) ||
+ wrapper_my_b_safe_write(file, buff, rec_size) ||
+ write_footer(file));
+ if (no_checksum)
+ checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
+ return ret;
}
#endif
@@ -4185,18 +4560,11 @@ Format_description_log_event::do_shall_skip(Relay_log_info *rli)
#endif
-
-/**
- Splits the event's 'server_version' string into three numeric pieces stored
- into 'server_version_split':
- X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
- X.Yabc -> {X,Y,0}
- 'server_version_split' is then used for lookups to find if the server which
- created this event has some known bug.
-*/
-void Format_description_log_event::calc_server_version_split()
+static inline void
+do_server_version_split(char* version,
+ Format_description_log_event::master_version_split *split_versions)
{
- char *p= server_version, *r;
+ char *p= version, *r;
ulong number;
for (uint i= 0; i<=2; i++)
{
@@ -4206,12 +4574,12 @@ void Format_description_log_event::calc_server_version_split()
first number is not followed by '.'.
*/
if (number < 256 && (*r == '.' || i != 0))
- server_version_split[i]= (uchar)number;
+ split_versions->ver[i]= (uchar) number;
else
{
- server_version_split[0]= 0;
- server_version_split[1]= 0;
- server_version_split[2]= 0;
+ split_versions->ver[0]= 0;
+ split_versions->ver[1]= 0;
+ split_versions->ver[2]= 0;
break;
}
@@ -4219,12 +4587,86 @@ void Format_description_log_event::calc_server_version_split()
if (*r == '.')
p++; // skip the dot
}
+ if (strinstr(p, "MariaDB") != 0 || strinstr(p, "-maria-") != 0)
+ split_versions->kind=
+ Format_description_log_event::master_version_split::KIND_MARIADB;
+ else
+ split_versions->kind=
+ Format_description_log_event::master_version_split::KIND_MYSQL;
+}
+
+
+/**
+ Splits the event's 'server_version' string into three numeric pieces stored
+ into 'server_version_split':
+ X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
+ X.Yabc -> {X,Y,0}
+ 'server_version_split' is then used for lookups to find if the server which
+ created this event has some known bug.
+*/
+void Format_description_log_event::calc_server_version_split()
+{
+ do_server_version_split(server_version, &server_version_split);
+
DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
" '%s' %d %d %d", server_version,
- server_version_split[0],
- server_version_split[1], server_version_split[2]));
+ server_version_split.ver[0],
+ server_version_split.ver[1], server_version_split.ver[2]));
+}
+
+static inline ulong
+version_product(const Format_description_log_event::master_version_split* version_split)
+{
+ return ((version_split->ver[0] * 256 + version_split->ver[1]) * 256
+ + version_split->ver[2]);
}
+/**
+ @return TRUE is the event's version is earlier than one that introduced
+ the replication event checksum. FALSE otherwise.
+*/
+bool
+Format_description_log_event::is_version_before_checksum(master_version_split
+ *version_split)
+{
+ return version_product(version_split) <
+ (version_split->kind == master_version_split::KIND_MARIADB ?
+ checksum_version_product_mariadb : checksum_version_product_mysql);
+}
+
+/**
+ @param buf buffer holding serialized FD event
+ @param len netto (possible checksum is stripped off) length of the event buf
+
+ @return the version-safe checksum alg descriptor where zero
+ designates no checksum, 255 - the orginator is
+ checksum-unaware (effectively no checksum) and the actuall
+ [1-254] range alg descriptor.
+*/
+uint8 get_checksum_alg(const char* buf, ulong len)
+{
+ uint8 ret;
+ char version[ST_SERVER_VER_LEN];
+ Format_description_log_event::master_version_split version_split;
+
+ DBUG_ENTER("get_checksum_alg");
+ DBUG_ASSERT(buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT);
+
+ memcpy(version, buf +
+ buf[LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET]
+ + ST_SERVER_VER_OFFSET, ST_SERVER_VER_LEN);
+ version[ST_SERVER_VER_LEN - 1]= 0;
+
+ do_server_version_split(version, &version_split);
+ ret= Format_description_log_event::is_version_before_checksum(&version_split) ?
+ (uint8) BINLOG_CHECKSUM_ALG_UNDEF :
+ * (uint8*) (buf + len - BINLOG_CHECKSUM_LEN - BINLOG_CHECKSUM_ALG_DESC_LEN);
+ DBUG_ASSERT(ret == BINLOG_CHECKSUM_ALG_OFF ||
+ ret == BINLOG_CHECKSUM_ALG_UNDEF ||
+ ret == BINLOG_CHECKSUM_ALG_CRC32);
+ DBUG_RETURN(ret);
+}
+
/**************************************************************************
Load_log_event methods
@@ -4507,8 +4949,8 @@ Load_log_event::Load_log_event(const char *buf, uint event_len,
*/
if (event_len)
copy_log_event(buf, event_len,
- ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
- LOAD_HEADER_LEN +
+ (((uchar)buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
+ LOAD_HEADER_LEN +
description_event->common_header_len :
LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN),
description_event);
@@ -4545,7 +4987,7 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
*/
if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
buf_end,
- buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
+ (uchar)buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
DBUG_RETURN(1);
data_len = event_len - body_offset;
@@ -4783,7 +5225,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
*/
if (rpl_filter->db_ok(thd->db))
{
- thd->set_time((time_t)when);
+ thd->set_time(when, when_sec_part);
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id = next_query_id();
VOID(pthread_mutex_unlock(&LOCK_thread_count));
@@ -5054,6 +5496,7 @@ Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
DBUG_PRINT("enter",("new_log_ident: %s pos: %s flags: %lu", new_log_ident_arg,
llstr(pos_arg, buff), (ulong) flags));
#endif
+ cache_type= EVENT_NO_CACHE;
if (flags & DUP_NAME)
new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
if (flags & RELAY_LOG)
@@ -5095,9 +5538,11 @@ bool Rotate_log_event::write(IO_CACHE* file)
{
char buf[ROTATE_HEADER_LEN];
int8store(buf + R_POS_OFFSET, pos);
- return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
- my_b_safe_write(file, (uchar*)buf, ROTATE_HEADER_LEN) ||
- my_b_safe_write(file, (uchar*)new_log_ident, (uint) ident_len));
+ return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
+ wrapper_my_b_safe_write(file, (uchar*) buf, ROTATE_HEADER_LEN) ||
+ wrapper_my_b_safe_write(file, (uchar*) new_log_ident,
+ (uint) ident_len) ||
+ write_footer(file));
}
#endif
@@ -5266,7 +5711,8 @@ bool Intvar_log_event::write(IO_CACHE* file)
buf[I_TYPE_OFFSET]= (uchar) type;
int8store(buf + I_VAL_OFFSET, val);
return (write_header(file, sizeof(buf)) ||
- my_b_safe_write(file, buf, sizeof(buf)));
+ wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
+ write_footer(file));
}
#endif
@@ -5398,7 +5844,8 @@ bool Rand_log_event::write(IO_CACHE* file)
int8store(buf + RAND_SEED1_OFFSET, seed1);
int8store(buf + RAND_SEED2_OFFSET, seed2);
return (write_header(file, sizeof(buf)) ||
- my_b_safe_write(file, buf, sizeof(buf)));
+ wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
+ write_footer(file));
}
#endif
@@ -5526,8 +5973,9 @@ Xid_log_event(const char* buf,
bool Xid_log_event::write(IO_CACHE* file)
{
DBUG_EXECUTE_IF("do_not_write_xid", return 0;);
- return write_header(file, sizeof(xid)) ||
- my_b_safe_write(file, (uchar*) &xid, sizeof(xid));
+ return (write_header(file, sizeof(xid)) ||
+ wrapper_my_b_safe_write(file, (uchar*) &xid, sizeof(xid)) ||
+ write_footer(file));
}
#endif
@@ -5816,10 +6264,11 @@ bool User_var_log_event::write(IO_CACHE* file)
event_length= sizeof(buf)+ name_len + buf1_length + val_len;
return (write_header(file, event_length) ||
- my_b_safe_write(file, (uchar*) buf, sizeof(buf)) ||
- my_b_safe_write(file, (uchar*) name, name_len) ||
- my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
- my_b_safe_write(file, pos, val_len));
+ wrapper_my_b_safe_write(file, (uchar*) buf, sizeof(buf)) ||
+ wrapper_my_b_safe_write(file, (uchar*) name, name_len) ||
+ wrapper_my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
+ wrapper_my_b_safe_write(file, pos, val_len) ||
+ write_footer(file));
}
#endif
@@ -6351,7 +6800,7 @@ Create_file_log_event::Create_file_log_event(const char* buf, uint len,
uint8 create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
copy_log_event(event_buf,len,
- ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
+ (((uchar)buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
load_header_len + header_len :
(fake_base ? (header_len+load_header_len) :
(header_len+load_header_len) +
@@ -6593,8 +7042,9 @@ bool Append_block_log_event::write(IO_CACHE* file)
uchar buf[APPEND_BLOCK_HEADER_LEN];
int4store(buf + AB_FILE_ID_OFFSET, file_id);
return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
- my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
- my_b_safe_write(file, (uchar*) block, block_len));
+ wrapper_my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
+ wrapper_my_b_safe_write(file, (uchar*) block, block_len) ||
+ write_footer(file));
}
#endif
@@ -6748,7 +7198,8 @@ bool Delete_file_log_event::write(IO_CACHE* file)
uchar buf[DELETE_FILE_HEADER_LEN];
int4store(buf + DF_FILE_ID_OFFSET, file_id);
return (write_header(file, sizeof(buf)) ||
- my_b_safe_write(file, buf, sizeof(buf)));
+ wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
+ write_footer(file));
}
#endif
@@ -6845,7 +7296,8 @@ bool Execute_load_log_event::write(IO_CACHE* file)
uchar buf[EXEC_LOAD_HEADER_LEN];
int4store(buf + EL_FILE_ID_OFFSET, file_id);
return (write_header(file, sizeof(buf)) ||
- my_b_safe_write(file, buf, sizeof(buf)));
+ wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
+ write_footer(file));
}
#endif
@@ -6906,16 +7358,17 @@ int Execute_load_log_event::do_apply_event(Relay_log_info const *rli)
fname);
goto err;
}
- if (!(lev = (Load_log_event*)Log_event::read_log_event(&file,
- (pthread_mutex_t*)0,
- rli->relay_log.description_event_for_exec)) ||
+ if (!(lev= (Load_log_event*)
+ Log_event::read_log_event(&file,
+ (pthread_mutex_t*)0,
+ rli->relay_log.description_event_for_exec,
+ opt_slave_sql_verify_checksum)) ||
lev->get_type_code() != NEW_LOAD_EVENT)
{
rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
"file '%s' appears corrupted", fname);
goto err;
}
-
lev->thd = thd;
/*
lev->do_apply_event should use rli only for errors i.e. should
@@ -7078,7 +7531,7 @@ Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
int4store(buf + 4, fn_pos_start);
int4store(buf + 4 + 4, fn_pos_end);
*(buf + 4 + 4 + 4)= (uchar) dup_handling;
- return my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
+ return wrapper_my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
}
#endif
@@ -7320,7 +7773,8 @@ Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
m_width(tbl_arg ? tbl_arg->s->fields : 1),
m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0)
#ifdef HAVE_REPLICATION
- , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
+ , m_curr_row(NULL), m_curr_row_end(NULL),
+ m_key(NULL), m_key_info(NULL), m_key_nr(0)
#endif
{
/*
@@ -7368,7 +7822,8 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
#endif
m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
- , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
+ , m_curr_row(NULL), m_curr_row_end(NULL),
+ m_key(NULL), m_key_info(NULL), m_key_nr(0)
#endif
{
DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
@@ -7713,7 +8168,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
}
#ifdef HAVE_QUERY_CACHE
- query_cache.invalidate_locked_for_write(rli->tables_to_lock);
+ query_cache.invalidate_locked_for_write(thd, rli->tables_to_lock);
#endif
}
@@ -7740,7 +8195,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
TIMESTAMP column to a table with one.
So we call set_time(), like in SBR. Presently it changes nothing.
*/
- thd->set_time((time_t)when);
+ thd->set_time(when, when_sec_part);
/*
Now we are in a statement and will stay in a statement until we
@@ -8050,11 +8505,11 @@ bool Rows_log_event::write_data_header(IO_CACHE *file)
{
int4store(buf + 0, m_table_id);
int2store(buf + 4, m_flags);
- return (my_b_safe_write(file, buf, 6));
+ return (wrapper_my_b_safe_write(file, buf, 6));
});
int6store(buf + RW_MAPID_OFFSET, (ulonglong)m_table_id);
int2store(buf + RW_FLAGS_OFFSET, m_flags);
- return (my_b_safe_write(file, buf, ROWS_HEADER_LEN));
+ return (wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN));
}
bool Rows_log_event::write_data_body(IO_CACHE*file)
@@ -8070,10 +8525,10 @@ bool Rows_log_event::write_data_body(IO_CACHE*file)
DBUG_ASSERT(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf));
- res= res || my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
+ res= res || wrapper_my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
- res= res || my_b_safe_write(file, (uchar*) m_cols.bitmap,
+ res= res || wrapper_my_b_safe_write(file, (uchar*) m_cols.bitmap,
no_bytes_in_map(&m_cols));
/*
TODO[refactor write]: Remove the "down cast" here (and elsewhere).
@@ -8082,11 +8537,11 @@ bool Rows_log_event::write_data_body(IO_CACHE*file)
{
DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
no_bytes_in_map(&m_cols_ai));
- res= res || my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
+ res= res || wrapper_my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
no_bytes_in_map(&m_cols_ai));
}
DBUG_DUMP("rows", m_rows_buf, data_size);
- res= res || my_b_safe_write(file, m_rows_buf, (size_t) data_size);
+ res= res || wrapper_my_b_safe_write(file, m_rows_buf, (size_t) data_size);
return res;
@@ -8131,6 +8586,144 @@ void Rows_log_event::print_helper(FILE *file,
#endif
/**************************************************************************
+ Annotate_rows_log_event member functions
+**************************************************************************/
+
+#ifndef MYSQL_CLIENT
+Annotate_rows_log_event::Annotate_rows_log_event(THD *thd,
+ uint16 cache_type_arg)
+ : Log_event(thd, 0, true),
+ m_save_thd_query_txt(0),
+ m_save_thd_query_len(0)
+{
+ m_query_txt= thd->query();
+ m_query_len= thd->query_length();
+ cache_type= cache_type_arg;
+}
+#endif
+
+Annotate_rows_log_event::Annotate_rows_log_event(const char *buf,
+ uint event_len,
+ const Format_description_log_event *desc)
+ : Log_event(buf, desc),
+ m_save_thd_query_txt(0),
+ m_save_thd_query_len(0)
+{
+ m_query_len= event_len - desc->common_header_len;
+ m_query_txt= (char*) buf + desc->common_header_len;
+}
+
+Annotate_rows_log_event::~Annotate_rows_log_event()
+{
+#ifndef MYSQL_CLIENT
+ if (m_save_thd_query_txt)
+ thd->set_query(m_save_thd_query_txt, m_save_thd_query_len);
+#endif
+}
+
+int Annotate_rows_log_event::get_data_size()
+{
+ return m_query_len;
+}
+
+Log_event_type Annotate_rows_log_event::get_type_code()
+{
+ return ANNOTATE_ROWS_EVENT;
+}
+
+bool Annotate_rows_log_event::is_valid() const
+{
+ return (m_query_txt != NULL && m_query_len != 0);
+}
+
+#ifndef MYSQL_CLIENT
+bool Annotate_rows_log_event::write_data_header(IO_CACHE *file)
+{
+ return 0;
+}
+#endif
+
+#ifndef MYSQL_CLIENT
+bool Annotate_rows_log_event::write_data_body(IO_CACHE *file)
+{
+ return wrapper_my_b_safe_write(file, (uchar*) m_query_txt, m_query_len);
+}
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+void Annotate_rows_log_event::pack_info(THD *thd, Protocol* protocol)
+{
+ if (m_query_txt && m_query_len)
+ protocol->store(m_query_txt, m_query_len, &my_charset_bin);
+}
+#endif
+
+#ifdef MYSQL_CLIENT
+void Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
+{
+ if (pinfo->short_form)
+ return;
+
+ print_header(&pinfo->head_cache, pinfo, TRUE);
+ my_b_printf(&pinfo->head_cache, "\tAnnotate_rows:\n");
+
+ char *pbeg; // beginning of the next line
+ char *pend; // end of the next line
+ uint cnt= 0; // characters counter
+
+ for (pbeg= m_query_txt; ; pbeg= pend)
+ {
+ // skip all \r's and \n's at the beginning of the next line
+ for (;; pbeg++)
+ {
+ if (++cnt > m_query_len)
+ return;
+
+ if (*pbeg != '\r' && *pbeg != '\n')
+ break;
+ }
+
+ // find end of the next line
+ for (pend= pbeg + 1;
+ ++cnt <= m_query_len && *pend != '\r' && *pend != '\n';
+ pend++)
+ ;
+
+ // print next line
+ my_b_write(&pinfo->head_cache, (const uchar*) "#Q> ", 4);
+ my_b_write(&pinfo->head_cache, (const uchar*) pbeg, pend - pbeg);
+ my_b_write(&pinfo->head_cache, (const uchar*) "\n", 1);
+ }
+}
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+int Annotate_rows_log_event::do_apply_event(Relay_log_info const *rli)
+{
+ m_save_thd_query_txt= thd->query();
+ m_save_thd_query_len= thd->query_length();
+ thd->set_query(m_query_txt, m_query_len);
+ return 0;
+}
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+int Annotate_rows_log_event::do_update_pos(Relay_log_info *rli)
+{
+ rli->inc_event_relay_log_pos();
+ return 0;
+}
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+Log_event::enum_skip_reason
+Annotate_rows_log_event::do_shall_skip(Relay_log_info *rli)
+{
+ return continue_group(rli);
+}
+#endif
+
+/**************************************************************************
Table_map_log_event member functions and support functions
**************************************************************************/
@@ -8752,11 +9345,11 @@ bool Table_map_log_event::write_data_header(IO_CACHE *file)
{
int4store(buf + 0, m_table_id);
int2store(buf + 4, m_flags);
- return (my_b_safe_write(file, buf, 6));
+ return (wrapper_my_b_safe_write(file, buf, 6));
});
int6store(buf + TM_MAPID_OFFSET, (ulonglong)m_table_id);
int2store(buf + TM_FLAGS_OFFSET, m_flags);
- return (my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
+ return (wrapper_my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
}
bool Table_map_log_event::write_data_body(IO_CACHE *file)
@@ -8780,15 +9373,15 @@ bool Table_map_log_event::write_data_body(IO_CACHE *file)
uchar mbuf[sizeof(m_field_metadata_size)];
uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
- return (my_b_safe_write(file, dbuf, sizeof(dbuf)) ||
- my_b_safe_write(file, (const uchar*)m_dbnam, m_dblen+1) ||
- my_b_safe_write(file, tbuf, sizeof(tbuf)) ||
- my_b_safe_write(file, (const uchar*)m_tblnam, m_tbllen+1) ||
- my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
- my_b_safe_write(file, m_coltype, m_colcnt) ||
- my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
- my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
- my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
+ return (wrapper_my_b_safe_write(file, dbuf, sizeof(dbuf)) ||
+ wrapper_my_b_safe_write(file, (const uchar*)m_dbnam, m_dblen+1) ||
+ wrapper_my_b_safe_write(file, tbuf, sizeof(tbuf)) ||
+ wrapper_my_b_safe_write(file, (const uchar*)m_tblnam, m_tbllen+1) ||
+ wrapper_my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
+ wrapper_my_b_safe_write(file, m_coltype, m_colcnt) ||
+ wrapper_my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
+ wrapper_my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
+ wrapper_my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
}
#endif
@@ -9389,6 +9982,86 @@ record_compare_exit:
return result;
}
+
+/**
+ Find the best key to use when locating the row in @c find_row().
+
+ A primary key is preferred if it exists; otherwise a unique index is
+ preferred. Else we pick the index with the smalles rec_per_key value.
+
+ If a suitable key is found, set @c m_key, @c m_key_nr and @c m_key_info
+ member fields appropriately.
+
+ @returns Error code on failure, 0 on success.
+*/
+int Rows_log_event::find_key()
+{
+ uint i, best_key_nr, last_part;
+ KEY *key, *best_key;
+ ulong best_rec_per_key, tmp;
+ DBUG_ENTER("Rows_log_event::find_key");
+ DBUG_ASSERT(m_table);
+
+ best_key_nr= MAX_KEY;
+ LINT_INIT(best_key);
+ LINT_INIT(best_rec_per_key);
+
+ /*
+ Keys are sorted so that any primary key is first, followed by unique keys,
+ followed by any other. So we will automatically pick the primary key if
+ it exists.
+ */
+ for (i= 0, key= m_table->key_info; i < m_table->s->keys; i++, key++)
+ {
+ if (!m_table->s->keys_in_use.is_set(i))
+ continue;
+ /*
+ We cannot use a unique key with NULL-able columns to uniquely identify
+ a row (but we can still select it for range scan below if nothing better
+ is available).
+ */
+ if ((key->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
+ {
+ best_key_nr= i;
+ best_key= key;
+ break;
+ }
+ /*
+ We can only use a non-unique key if it allows range scans (ie. skip
+ FULLTEXT indexes and such).
+ */
+ last_part= key->key_parts - 1;
+ DBUG_PRINT("info", ("Index %s rec_per_key[%u]= %lu",
+ key->name, last_part, key->rec_per_key[last_part]));
+ if (!(m_table->file->index_flags(i, last_part, 1) & HA_READ_NEXT))
+ continue;
+
+ tmp= key->rec_per_key[last_part];
+ if (best_key_nr == MAX_KEY || (tmp > 0 && tmp < best_rec_per_key))
+ {
+ best_key_nr= i;
+ best_key= key;
+ best_rec_per_key= tmp;
+ }
+ }
+
+ if (best_key_nr == MAX_KEY)
+ {
+ m_key_info= NULL;
+ DBUG_RETURN(0);
+ }
+
+ // Allocate buffer for key searches
+ m_key= (uchar *) my_malloc(best_key->key_length, MYF(MY_WME));
+ if (m_key == NULL)
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ m_key_info= best_key;
+ m_key_nr= best_key_nr;
+
+ DBUG_RETURN(0);;
+}
+
+
/**
Locate the current row in event's table.
@@ -9488,12 +10161,17 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
*/
store_record(table,record[1]);
- if (table->s->keys > 0 && table->s->keys_in_use.is_set(0))
+ if (m_key_info)
{
- DBUG_PRINT("info",("locating record using primary key (index_read)"));
+ DBUG_PRINT("info",("locating record using key #%u [%s] (index_read)",
+ m_key_nr, m_key_info->name));
+ /* We use this to test that the correct key is used in test cases. */
+ DBUG_EXECUTE_IF("slave_crash_if_wrong_index",
+ if(0 != strcmp(m_key_info->name,"expected_key")) abort(););
- /* The 0th key is active: search the table using the index */
- if (!table->file->inited && (error= table->file->ha_index_init(0, FALSE)))
+ /* The key is active: search the table using the index */
+ if (!table->file->inited &&
+ (error= table->file->ha_index_init(m_key_nr, FALSE)))
{
DBUG_PRINT("info",("ha_index_init returns error %d",error));
table->file->print_error(error, MYF(0));
@@ -9503,14 +10181,14 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
/* Fill key data for the row */
DBUG_ASSERT(m_key);
- key_copy(m_key, table->record[0], table->key_info, 0);
+ key_copy(m_key, table->record[0], m_key_info, 0);
/*
Don't print debug messages when running valgrind since they can
trigger false warnings.
*/
#ifndef HAVE_valgrind
- DBUG_DUMP("key data", m_key, table->key_info->key_length);
+ DBUG_DUMP("key data", m_key, m_key_info->key_length);
#endif
/*
@@ -9596,6 +10274,8 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
record we are looking for is stored in record[1].
*/
DBUG_PRINT("info",("non-unique index, scanning it to find matching record"));
+ /* We use this to test that the correct key is used in test cases. */
+ DBUG_EXECUTE_IF("slave_crash_if_index_scan", abort(););
while (record_compare(table))
{
@@ -9634,6 +10314,8 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
else
{
DBUG_PRINT("info",("locating record using table scan (rnd_next)"));
+ /* We use this to test that the correct key is used in test cases. */
+ DBUG_EXECUTE_IF("slave_crash_if_table_scan", abort(););
int restart_count= 0; // Number of times scanning has restarted from top
@@ -9754,14 +10436,7 @@ Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability
return 0;
}
- if (m_table->s->keys > 0)
- {
- // Allocate buffer for key searches
- m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
- if (!m_key)
- return HA_ERR_OUT_OF_MEM;
- }
- return 0;
+ return find_key();
}
int
@@ -9772,6 +10447,7 @@ Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability
m_table->file->ha_index_or_rnd_end();
my_free(m_key, MYF(MY_ALLOW_ZERO_PTR));
m_key= NULL;
+ m_key_info= NULL;
return error;
}
@@ -9874,13 +10550,9 @@ Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
int
Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
{
- if (m_table->s->keys > 0)
- {
- // Allocate buffer for key searches
- m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
- if (!m_key)
- return HA_ERR_OUT_OF_MEM;
- }
+ int err;
+ if ((err= find_key()))
+ return err;
m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
@@ -9895,6 +10567,7 @@ Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability
m_table->file->ha_index_or_rnd_end();
my_free(m_key, MYF(MY_ALLOW_ZERO_PTR)); // Free for multi_malloc
m_key= NULL;
+ m_key_info= NULL;
return error;
}
@@ -10070,13 +10743,25 @@ Incident_log_event::write_data_header(IO_CACHE *file)
DBUG_PRINT("enter", ("m_incident: %d", m_incident));
uchar buf[sizeof(int16)];
int2store(buf, (int16) m_incident);
- DBUG_RETURN(my_b_safe_write(file, buf, sizeof(buf)));
+#ifndef MYSQL_CLIENT
+ DBUG_RETURN(wrapper_my_b_safe_write(file, buf, sizeof(buf)));
+#else
+ DBUG_RETURN(my_b_safe_write(file, buf, sizeof(buf)));
+#endif
}
bool
Incident_log_event::write_data_body(IO_CACHE *file)
{
+ uchar tmp[1];
DBUG_ENTER("Incident_log_event::write_data_body");
+ tmp[0]= (uchar) m_message.length;
+ crc= my_checksum(crc, (uchar*) tmp, 1);
+ if (m_message.length > 0)
+ {
+ crc= my_checksum(crc, (uchar*) m_message.str, m_message.length);
+ // todo: report a bug on write_str accepts uint but treats it as uchar
+ }
DBUG_RETURN(write_str(file, m_message.str, (uint) m_message.length));
}
diff --git a/sql/log_event.h b/sql/log_event.h
index 43bc6ed4437..5a761a67dcc 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -74,6 +74,7 @@
#define LOG_READ_MEM -5
#define LOG_READ_TRUNC -6
#define LOG_READ_TOO_LARGE -7
+#define LOG_READ_CHECKSUM_FAILURE -8
#define LOG_EVENT_OFFSET 4
@@ -252,6 +253,7 @@ struct sql_ex_info
#define EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN (4 + 4 + 4 + 1)
#define EXECUTE_LOAD_QUERY_HEADER_LEN (QUERY_HEADER_LEN + EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN)
#define INCIDENT_HEADER_LEN 2
+#define ANNOTATE_ROWS_HEADER_LEN 0
/*
Max number of possible extra bytes in a replication event compared to a
packet (i.e. a query) sent from client to master;
@@ -267,6 +269,7 @@ struct sql_ex_info
1 + 2 /* type, charset_database_number */ + \
1 + 8 /* type, table_map_for_update */ + \
1 + 4 /* type, master_data_written */ + \
+ 1 + 3 /* type, sec_part of NOW() */ + \
1 + 16 + 1 + 60/* type, user_len, user, host_len, host */)
#define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \
LOG_EVENT_HEADER_LEN + /* write_header */ \
@@ -345,6 +348,8 @@ struct sql_ex_info
#define Q_INVOKER 11
+#define Q_HRNOW 128
+
/* Intvar event post-header */
/* Intvar event data */
@@ -533,6 +538,22 @@ struct sql_ex_info
#endif
#undef EXPECTED_OPTIONS /* You shouldn't use this one */
+enum enum_binlog_checksum_alg {
+ BINLOG_CHECKSUM_ALG_OFF= 0, // Events are without checksum though its generator
+ // is checksum-capable New Master (NM).
+ BINLOG_CHECKSUM_ALG_CRC32= 1, // CRC32 of zlib algorithm.
+ BINLOG_CHECKSUM_ALG_ENUM_END, // the cut line: valid alg range is [1, 0x7f].
+ BINLOG_CHECKSUM_ALG_UNDEF= 255 // special value to tag undetermined yet checksum
+ // or events from checksum-unaware servers
+};
+
+#define CHECKSUM_CRC32_SIGNATURE_LEN 4
+/**
+ defined statically while there is just one alg implemented
+*/
+#define BINLOG_CHECKSUM_LEN CHECKSUM_CRC32_SIGNATURE_LEN
+#define BINLOG_CHECKSUM_ALG_DESC_LEN 1 /* 1 byte checksum alg descriptor */
+
/**
@enum Log_event_type
@@ -591,8 +612,14 @@ enum Log_event_type
*/
INCIDENT_EVENT= 26,
+ /* New MySQL/Sun events are to be added right above this comment */
+ MYSQL_EVENTS_END,
+
+ MARIA_EVENTS_BEGIN= 160,
+ /* New Maria event numbers start from here */
+ ANNOTATE_ROWS_EVENT= 160,
+
/*
- Add new events here - right above this comment!
Existing events (except ENUM_END_EVENT) should never change their numbers
*/
@@ -905,7 +932,8 @@ public:
execution time, which guarantees good replication (otherwise, we
could have a query and its event with different timestamps).
*/
- time_t when;
+ my_time_t when;
+ ulong when_sec_part;
/* The number of seconds the query took to run on the master. */
ulong exec_time;
/* Number of bytes written by write() function */
@@ -925,6 +953,27 @@ public:
uint16 flags;
bool cache_stmt;
+ /*
+ The revid:alfranio.correia@sun.com-20091103190256-637o8qxlveikrt3i commit
+ ("WL#2687 WL#5072 BUG#40278 BUG#47175") in MySQL 5.5 changes the bool
+ cache_stmt into an enum cache_type. For the backport of WL#2540 binlog
+ event checksum, we need this event_type member to know if we are writing
+ directly to the log, or into a transaction cache.
+
+ Until the cache_type stuff is merged, we temporarily partially backport
+ the cache_type member, only enough to be able to check if we are writing
+ directly to log or not. Once MySQL 5.5 is merged, this can be removed, and
+ replaced with the MySQL 5.5 code.
+
+ Similarly, in MySQL 5.5 the decision on whether to write directly to log
+ or indirectly through cache is decided differently, and the
+ pre_55_writing_direct() (and all calls to it) are not needed and can be
+ removed once 5.5 is merged.
+ */
+ enum enum_event_cache_type { EVENT_INVALID_CACHE, EVENT_STMT_CACHE,
+ EVENT_TRANSACTIONAL_CACHE, EVENT_NO_CACHE };
+ uint16 cache_type;
+ void pre_55_writing_direct() { cache_type= EVENT_NO_CACHE; }
/**
A storage to cache the global system variable's value.
@@ -932,6 +981,10 @@ public:
*/
ulong slave_exec_mode;
+ /**
+ Placeholder for event checksum while writing to binlog.
+ */
+ ha_checksum crc;
#ifndef MYSQL_CLIENT
THD* thd;
@@ -951,9 +1004,10 @@ public:
static Log_event* read_log_event(IO_CACHE* file,
pthread_mutex_t* log_lock,
const Format_description_log_event
- *description_event);
+ *description_event,
+ my_bool crc_check);
static int read_log_event(IO_CACHE* file, String* packet,
- pthread_mutex_t* log_lock);
+ pthread_mutex_t* log_lock, uint8 checksum_alg_arg);
/*
init_show_field_list() prepares the column names and types for the
output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
@@ -981,7 +1035,7 @@ public:
/* avoid having to link mysqlbinlog against libpthread */
static Log_event* read_log_event(IO_CACHE* file,
const Format_description_log_event
- *description_event);
+ *description_event, my_bool crc_check);
/* print*() functions are used by mysqlbinlog */
virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0;
void print_timestamp(IO_CACHE* file, time_t *ts = 0);
@@ -990,6 +1044,15 @@ public:
void print_base64(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info,
bool is_more);
#endif
+ /*
+ The value is set by caller of FD constructor and
+ Log_event::write_header() for the rest.
+ In the FD case it's propagated into the last byte
+ of post_header_len[] at FD::write().
+ On the slave side the value is assigned from post_header_len[last]
+ of the last seen FD event.
+ */
+ uint8 checksum_alg;
static void *operator new(size_t size)
{
@@ -1004,29 +1067,46 @@ public:
/* Placement version of the above operators */
static void *operator new(size_t, void* ptr) { return ptr; }
static void operator delete(void*, void*) { }
+ bool wrapper_my_b_safe_write(IO_CACHE* file, const uchar* buf, ulong data_length);
#ifndef MYSQL_CLIENT
bool write_header(IO_CACHE* file, ulong data_length);
+ bool write_footer(IO_CACHE* file);
+ my_bool need_checksum();
+
virtual bool write(IO_CACHE* file)
{
- return (write_header(file, get_data_size()) ||
- write_data_header(file) ||
- write_data_body(file));
+ return(write_header(file, get_data_size()) ||
+ write_data_header(file) ||
+ write_data_body(file) ||
+ write_footer(file));
}
virtual bool write_data_header(IO_CACHE* file)
{ return 0; }
virtual bool write_data_body(IO_CACHE* file __attribute__((unused)))
{ return 0; }
- inline time_t get_time()
+ inline my_time_t get_time()
{
THD *tmp_thd;
if (when)
return when;
if (thd)
- return thd->start_time;
+ {
+ when= thd->start_time;
+ when_sec_part= thd->start_time_sec_part;
+ return when;
+ }
+ /* thd will only be 0 here at time of log creation */
if ((tmp_thd= current_thd))
- return tmp_thd->start_time;
- return my_time(0);
+ {
+ when= tmp_thd->start_time;
+ when_sec_part= tmp_thd->start_time_sec_part;
+ return when;
+ }
+ my_hrtime_t hrtime= my_hrtime();
+ when= hrtime_to_my_time(hrtime);
+ when_sec_part= hrtime_sec_part(hrtime);
+ return when;
}
#endif
virtual Log_event_type get_type_code() = 0;
@@ -1061,7 +1141,7 @@ public:
static Log_event* read_log_event(const char* buf, uint event_len,
const char **error,
const Format_description_log_event
- *description_event);
+ *description_event, my_bool crc_check);
/**
Returns the human readable name of the given event type.
*/
@@ -2242,9 +2322,17 @@ public:
*/
uint8 common_header_len;
uint8 number_of_event_types;
- /* The list of post-headers' lengthes */
+ /*
+ The list of post-headers' lengths followed
+ by the checksum alg decription byte
+ */
uint8 *post_header_len;
- uchar server_version_split[3];
+ struct master_version_split {
+ enum {KIND_MYSQL, KIND_MARIADB};
+ int kind;
+ uchar ver[3];
+ };
+ master_version_split server_version_split;
const uint8 *event_type_permutation;
Format_description_log_event(uint8 binlog_ver, const char* server_ver=0);
@@ -2269,9 +2357,9 @@ public:
bool version_is_valid() const
{
/* It is invalid only when all version numbers are 0 */
- return !(server_version_split[0] == 0 &&
- server_version_split[1] == 0 &&
- server_version_split[2] == 0);
+ return !(server_version_split.ver[0] == 0 &&
+ server_version_split.ver[1] == 0 &&
+ server_version_split.ver[2] == 0);
}
bool is_valid() const
@@ -2290,7 +2378,7 @@ public:
}
void calc_server_version_split();
-
+ static bool is_version_before_checksum(master_version_split *version_split);
protected:
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
virtual int do_apply_event(Relay_log_info const *rli);
@@ -2345,9 +2433,10 @@ public:
uchar type;
#ifndef MYSQL_CLIENT
- Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg)
- :Log_event(thd_arg,0,0),val(val_arg),type(type_arg)
- {}
+ Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg,
+ uint16 cache_type_arg)
+ :Log_event(thd_arg,0,0), val(val_arg), type(type_arg)
+ { cache_type= cache_type_arg; }
#ifdef HAVE_REPLICATION
void pack_info(THD *thd, Protocol* protocol);
#endif /* HAVE_REPLICATION */
@@ -2421,9 +2510,10 @@ class Rand_log_event: public Log_event
ulonglong seed2;
#ifndef MYSQL_CLIENT
- Rand_log_event(THD* thd_arg, ulonglong seed1_arg, ulonglong seed2_arg)
- :Log_event(thd_arg,0,0),seed1(seed1_arg),seed2(seed2_arg)
- {}
+ Rand_log_event(THD* thd_arg, ulonglong seed1_arg, ulonglong seed2_arg,
+ uint16 cache_type_arg)
+ :Log_event(thd_arg, 0, 0), seed1(seed1_arg), seed2(seed2_arg)
+ { cache_type= cache_type_arg; }
#ifdef HAVE_REPLICATION
void pack_info(THD *thd, Protocol* protocol);
#endif /* HAVE_REPLICATION */
@@ -2467,7 +2557,8 @@ class Xid_log_event: public Log_event
my_xid xid;
#ifndef MYSQL_CLIENT
- Xid_log_event(THD* thd_arg, my_xid x): Log_event(thd_arg,0,0), xid(x) {}
+ Xid_log_event(THD* thd_arg, my_xid x): Log_event(thd_arg, 0, 0), xid(x)
+ { cache_type= EVENT_NO_CACHE; }
#ifdef HAVE_REPLICATION
void pack_info(THD *thd, Protocol* protocol);
#endif /* HAVE_REPLICATION */
@@ -2515,11 +2606,12 @@ public:
bool deferred;
User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg,
char *val_arg, ulong val_len_arg, Item_result type_arg,
- uint charset_number_arg)
- :Log_event(thd_arg,0,0), name(name_arg), name_len(name_len_arg), val(val_arg),
- val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg),
+ uint charset_number_arg,
+ uint16 cache_type_arg)
+ :Log_event(thd_arg, 0, 0), name(name_arg), name_len(name_len_arg), val(val_arg),
+ val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg),
deferred(false)
- { is_null= !val; }
+ { is_null= !val; cache_type= cache_type_arg; }
void pack_info(THD *thd, Protocol* protocol);
#else
void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
@@ -3023,6 +3115,59 @@ public:
char *str_to_hex(char *to, const char *from, uint len);
/**
+ @class Annotate_rows_log_event
+
+ In row-based mode, if binlog_annotate_row_events = ON, each group of
+ Table_map_log_events is preceded by an Annotate_rows_log_event which
+ contains the query which caused the subsequent rows operations.
+
+ The Annotate_rows_log_event has no post-header and its body contains
+ the corresponding query (without trailing zero). Note. The query length
+ is to be calculated as a difference between the whole event length and
+ the common header length.
+*/
+class Annotate_rows_log_event: public Log_event
+{
+public:
+#ifndef MYSQL_CLIENT
+ Annotate_rows_log_event(THD*, uint16 cache_type_arg);
+#endif
+ Annotate_rows_log_event(const char *buf, uint event_len,
+ const Format_description_log_event*);
+ ~Annotate_rows_log_event();
+
+ virtual int get_data_size();
+ virtual Log_event_type get_type_code();
+ virtual bool is_valid() const;
+
+#ifndef MYSQL_CLIENT
+ virtual bool write_data_header(IO_CACHE*);
+ virtual bool write_data_body(IO_CACHE*);
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual void pack_info(THD *thd, Protocol*);
+#endif
+
+#ifdef MYSQL_CLIENT
+ virtual void print(FILE*, PRINT_EVENT_INFO*);
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+private:
+ virtual int do_apply_event(Relay_log_info const*);
+ virtual int do_update_pos(Relay_log_info*);
+ virtual enum_skip_reason do_shall_skip(Relay_log_info*);
+#endif
+
+private:
+ char *m_query_txt;
+ uint m_query_len;
+ char *m_save_thd_query_txt;
+ uint m_save_thd_query_len;
+};
+
+/**
@class Table_map_log_event
In row-based mode, every row operation event is preceded by a
@@ -3627,7 +3772,10 @@ protected:
const uchar *m_curr_row; /* Start of the row being processed */
const uchar *m_curr_row_end; /* One-after the end of the current row */
uchar *m_key; /* Buffer to keep key value during searches */
+ KEY *m_key_info; /* Pointer to KEY info for m_key_nr */
+ uint m_key_nr; /* Key number */
+ int find_key(); // Find a best key to use in find_row()
int find_row(const Relay_log_info *const);
int write_row(const Relay_log_info *const, const bool);
@@ -3637,7 +3785,8 @@ protected:
DBUG_ASSERT(m_table);
ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
- int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
+ int const result= ::unpack_row(rli, m_table, m_width, m_curr_row,
+ m_rows_end, &m_cols,
&m_curr_row_end, &m_master_reclength);
if (m_curr_row_end > m_rows_end)
my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0));
@@ -4012,6 +4161,10 @@ bool rpl_get_position_info(const char **log_file_name, ulonglong *log_pos,
const char **group_relay_log_name,
ulonglong *relay_log_pos);
+bool event_checksum_test(uchar *buf, ulong event_len, uint8 alg);
+uint8 get_checksum_alg(const char* buf, ulong len);
+extern TYPELIB binlog_checksum_typelib;
+
#ifndef MYSQL_CLIENT
/**
The function is called by slave applier in case there are
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index 6f0fd316394..f29a2ed9ad6 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -151,7 +151,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
}
#ifdef HAVE_QUERY_CACHE
- query_cache.invalidate_locked_for_write(rli->tables_to_lock);
+ query_cache.invalidate_locked_for_write(thd, rli->tables_to_lock);
#endif
}
@@ -173,7 +173,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
TIMESTAMP column to a table with one.
So we call set_time(), like in SBR. Presently it changes nothing.
*/
- ev_thd->set_time((time_t)ev->when);
+ ev_thd->set_time(ev->when, ev->when_sec_part);
/*
There are a few flags that are replicated with each row event.
Make sure to set/clear them before executing the main body of
@@ -998,7 +998,8 @@ Write_rows_log_event_old::do_prepare_row(THD *thd_arg,
int error;
error= unpack_row_old(const_cast<Relay_log_info*>(rli),
table, m_width, table->record[0],
- row_start, &m_cols, row_end, &m_master_reclength,
+ row_start, m_rows_end,
+ &m_cols, row_end, &m_master_reclength,
table->write_set, PRE_GA_WRITE_ROWS_EVENT);
bitmap_copy(table->read_set, table->write_set);
return error;
@@ -1085,7 +1086,8 @@ Delete_rows_log_event_old::do_prepare_row(THD *thd_arg,
error= unpack_row_old(const_cast<Relay_log_info*>(rli),
table, m_width, table->record[0],
- row_start, &m_cols, row_end, &m_master_reclength,
+ row_start, m_rows_end,
+ &m_cols, row_end, &m_master_reclength,
table->read_set, PRE_GA_DELETE_ROWS_EVENT);
/*
If we will access rows using the random access method, m_key will
@@ -1184,13 +1186,15 @@ int Update_rows_log_event_old::do_prepare_row(THD *thd_arg,
/* record[0] is the before image for the update */
error= unpack_row_old(const_cast<Relay_log_info*>(rli),
table, m_width, table->record[0],
- row_start, &m_cols, row_end, &m_master_reclength,
+ row_start, m_rows_end,
+ &m_cols, row_end, &m_master_reclength,
table->read_set, PRE_GA_UPDATE_ROWS_EVENT);
row_start = *row_end;
/* m_after_image is the after image for the update */
error= unpack_row_old(const_cast<Relay_log_info*>(rli),
table, m_width, m_after_image,
- row_start, &m_cols, row_end, &m_master_reclength,
+ row_start, m_rows_end,
+ &m_cols, row_end, &m_master_reclength,
table->write_set, PRE_GA_UPDATE_ROWS_EVENT);
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
@@ -1650,7 +1654,7 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
}
#ifdef HAVE_QUERY_CACHE
- query_cache.invalidate_locked_for_write(rli->tables_to_lock);
+ query_cache.invalidate_locked_for_write(thd, rli->tables_to_lock);
#endif
}
@@ -1674,7 +1678,7 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
TIMESTAMP column to a table with one.
So we call set_time(), like in SBR. Presently it changes nothing.
*/
- thd->set_time((time_t)when);
+ thd->set_time(when, when_sec_part);
/*
There are a few flags that are replicated with each row event.
Make sure to set/clear them before executing the main body of
diff --git a/sql/log_event_old.h b/sql/log_event_old.h
index 2e551aa0cc0..3e1efd8e2c0 100644
--- a/sql/log_event_old.h
+++ b/sql/log_event_old.h
@@ -203,7 +203,8 @@ protected:
{
DBUG_ASSERT(m_table);
ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
- int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
+ int const result= ::unpack_row(rli, m_table, m_width, m_curr_row,
+ m_rows_end, &m_cols,
&m_curr_row_end, &m_master_reclength);
ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT);
return result;
diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc
new file mode 100644
index 00000000000..e86c9ca251c
--- /dev/null
+++ b/sql/multi_range_read.cc
@@ -0,0 +1,1828 @@
+#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(range_id_t *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(range_id_t *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;
+ }
+ if (res && res != HA_ERR_END_OF_FILE && res != HA_ERR_KEY_NOT_FOUND)
+ file->print_error(res, MYF(0)); // Fatal error
+ 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; Error is printed
+*/
+
+int Mrr_ordered_index_reader::get_next(range_id_t *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,
+ uint saved_pk_len,
+ uchar **space_start,
+ uchar *space_end)
+{
+ if (space_end - *space_start <= (ptrdiff_t)(rowid_length + key_len + saved_pk_len))
+ return TRUE;
+ support_scan_interruptions= TRUE;
+
+ saved_rowid= *space_start;
+ *space_start += rowid_length;
+
+ if (saved_pk_len)
+ {
+ saved_primary_key= *space_start;
+ *space_start += saved_pk_len;
+ }
+ else
+ saved_primary_key= NULL;
+
+ 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= saved_primary_key= NULL; /* safety */
+ have_saved_rowid= FALSE;
+}
+
+void Mrr_ordered_index_reader::interrupt_read()
+{
+ DBUG_ASSERT(support_scan_interruptions);
+ TABLE *table= file->get_table();
+ KEY *used_index= &table->key_info[file->active_index];
+ /* Save the current key value */
+ key_copy(saved_key_tuple, table->record[0],
+ used_index, used_index->key_length);
+
+ if (saved_primary_key)
+ {
+ key_copy(saved_primary_key, table->record[0],
+ &table->key_info[table->s->primary_key],
+ table->key_info[table->s->primary_key].key_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()
+{
+ TABLE *table= file->get_table();
+ KEY *used_index= &table->key_info[file->active_index];
+ key_restore(table->record[0], saved_key_tuple,
+ used_index, used_index->key_length);
+ if (saved_primary_key)
+ {
+ key_restore(table->record[0], saved_primary_key,
+ &table->key_info[table->s->primary_key],
+ table->key_info[table->s->primary_key].key_length);
+ }
+}
+
+
+/**
+ Fill the buffer with (lookup_tuple, range_id) pairs and sort
+
+ @return
+ 0 OK, the buffer is non-empty and sorted
+ HA_ERR_END_OF_FILE Source exhausted, the buffer is empty.
+*/
+
+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(range_id_t) : 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);
+
+ if (!initial)
+ {
+ /* This is a non-initial buffer fill and we've got a non-empty buffer */
+ THD *thd= current_thd;
+ status_var_increment(thd->status_var.ha_mrr_key_refills_count);
+ }
+
+ 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, key_info->key_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;
+ bool first_call= initial;
+ 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;
+ }
+
+ if (!first_call && !index_reader_exhausted)
+ {
+ /* Ok, this was a successful buffer refill operation */
+ THD *thd= current_thd;
+ status_var_increment(thd->status_var.ha_mrr_rowid_refills_count);
+ }
+
+ 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()
+{
+ range_id_t 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(range_id_t) : 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(range_id_t) : 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(range_id_t *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(range_id_t));
+ if (!index_reader->skip_record(*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(range_id_t));
+ 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;
+ }
+
+ 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)
+ {
+ uint saved_pk_length=0;
+ if (h_idx->primary_key_is_clustered())
+ {
+ uint pk= h_idx->get_table()->s->primary_key;
+ if (pk != MAX_KEY)
+ saved_pk_length= h_idx->get_table()->key_info[pk].key_length;
+ }
+
+ KEY *used_index= &h_idx->get_table()->key_info[h_idx->active_index];
+ if (reader_factory.ordered_index_reader.
+ set_interruption_temp_buffer(primary_file->ref_length,
+ used_index->key_length,
+ saved_pk_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(range_id_t)))
+ 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;
+ }
+ }
+
+ /*
+ At this point, we're sure that we're running a native MRR scan (i.e. we
+ didnt fall back to default implementation for some reason).
+ */
+ status_var_increment(thd->status_var.ha_mrr_init_count);
+
+ 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(res);
+
+use_default_impl:
+ if (primary_file->inited != handler::INDEX)
+ {
+ /* We can get here when
+ - we've previously successfully done a DS-MRR scan (and so have
+ secondary_file!= NULL, secondary_file->inited= INDEX,
+ primary_file->inited=RND)
+ - for this invocation, we haven't got enough buffer space, and so we
+ have to use the default MRR implementation.
+
+ note: primary_file->ha_index_end() will call dsmrr_close() which will
+ close/destroy the secondary_file, this is intentional.
+ (Yes this is slow, but one can't expect performance with join buffer
+ so small that it can accomodate one rowid and one index tuple)
+ */
+ if ((res= primary_file->ha_rnd_end()) ||
+ (res= primary_file->ha_index_init(keyno, test(mode & HA_MRR_SORTED))))
+ {
+ DBUG_RETURN(res);
+ }
+ }
+ /* 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(primary_file->get_table()->s->
+ normalized_path.str,
+ 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->ha_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(range_id_t);
+
+ 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(range_id_t);
+
+ /*
+ 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= (ptrdiff_t)(rowid_buf_elem_size + 1 - bytes_for_rowids);
+ bytes_for_rowids= (ptrdiff_t)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((size_t)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(range_id_t *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(range_id_t));
+
+ 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(range_id_t *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, flags, 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_switch settings
+ */
+ 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());
+ *flags &= ~HA_MRR_IMPLEMENTATION_FLAGS;
+ if (!optimizer_flag(thd, OPTIMIZER_SWITCH_MRR) ||
+ *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;
+ *flags &= ~HA_MRR_IMPLEMENTATION_FLAGS;
+ 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 mrr_cost_based flag is not set, 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= !optimizer_flag(thd, OPTIMIZER_SWITCH_MRR_COST_BASED)) &&
+ 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 ((using_cpk && doing_cpk_scan) ||
+ (optimizer_flag(thd, OPTIMIZER_SWITCH_MRR_SORT_KEYS) &&
+ *flags & HA_MRR_SINGLE_POINT))
+ {
+ *flags |= DSMRR_IMPL_SORT_KEYS;
+ }
+
+ if (!(using_cpk && doing_cpk_scan) &&
+ !(*flags & HA_MRR_INDEX_ONLY))
+ {
+ *flags |= DSMRR_IMPL_SORT_ROWIDS;
+ }
+ /*
+ 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;
+}
+
+/*
+ Take the flags we've returned previously and print one of
+ - Key-ordered scan
+ - Rowid-ordered scan
+ - Key-ordered Rowid-ordered scan
+*/
+
+int DsMrr_impl::dsmrr_explain_info(uint mrr_mode, char *str, size_t size)
+{
+ const char *key_ordered= "Key-ordered scan";
+ const char *rowid_ordered= "Rowid-ordered scan";
+ const char *both_ordered= "Key-ordered Rowid-ordered scan";
+ const char *used_str="";
+ const uint BOTH_FLAGS= (DSMRR_IMPL_SORT_KEYS | DSMRR_IMPL_SORT_ROWIDS);
+
+ if (!(mrr_mode & HA_MRR_USE_DEFAULT_IMPL))
+ {
+ if ((mrr_mode & BOTH_FLAGS) == BOTH_FLAGS)
+ used_str= both_ordered;
+ else if (mrr_mode & DSMRR_IMPL_SORT_KEYS)
+ used_str= key_ordered;
+ else if (mrr_mode & DSMRR_IMPL_SORT_ROWIDS)
+ used_str= rowid_ordered;
+
+ uint used_str_len= strlen(used_str);
+ uint copy_len= min(used_str_len, size);
+ memcpy(str, used_str, size);
+ return copy_len;
+ }
+ return 0;
+}
+
+
+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;
+ ha_rows 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_in_full_step, 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..1b72e71944d
--- /dev/null
+++ b/sql/multi_range_read.h
@@ -0,0 +1,637 @@
+/**
+ @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(range_id_t *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(range_id_t *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(range_id_t 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(range_id_t *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(range_id_t 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(range_id_t *range_info);
+ int refill_buffer(bool initial);
+ uchar *get_rowid_ptr() { return file->ref; }
+
+ bool skip_record(range_id_t range_info, uchar *rowid)
+ {
+ return (mrr_funcs.skip_record &&
+ mrr_funcs.skip_record(mrr_iter, range_info, rowid));
+ }
+
+ bool skip_index_tuple(range_id_t 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,
+ uint saved_pk_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;
+
+ /*
+ Following members are for interrupt_read()/resume_read(). The idea is that
+ in some cases index scan that is done by this object is interrupted by
+ rnd_pos() calls made by Mrr_ordered_rndpos_reader. The problem is that
+ we're sharing handler->record[0] with that object, and it destroys its
+ contents.
+ We need to save/restore our current
+ - index tuple (for pushed index condition checks)
+ - clustered primary key values (again, for pushed index condition checks)
+ - rowid of the last record we've retrieved (in case this rowid matches
+ multiple ranges and we'll need to return it again)
+ */
+ bool support_scan_interruptions;
+ /* Space where we save the rowid of the last record we've returned */
+ uchar *saved_rowid;
+
+ /* TRUE <=> saved_rowid has the last saved rowid */
+ bool have_saved_rowid;
+
+ uchar *saved_key_tuple; /* Saved current key tuple */
+ uchar *saved_primary_key; /* Saved current primary 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(range_id_t *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;
+};
+
+
+#define DSMRR_IMPL_SORT_KEYS HA_MRR_IMPLEMENTATION_FLAG1
+#define DSMRR_IMPL_SORT_ROWIDS HA_MRR_IMPLEMENTATION_FLAG2
+
+/*
+ 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(range_id_t *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);
+
+ int dsmrr_explain_info(uint mrr_mode, char *str, size_t size);
+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/my_decimal.cc b/sql/my_decimal.cc
index 960ccbf3439..44207b9319b 100644
--- a/sql/my_decimal.cc
+++ b/sql/my_decimal.cc
@@ -18,6 +18,10 @@
#include "mysql_priv.h"
#include <time.h>
+#define DIG_BASE 1000000000
+#define DIG_PER_DEC1 9
+#define ROUND_UP(X) (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
+
#ifndef MYSQL_CLIENT
/**
@@ -32,21 +36,20 @@
result
*/
-int decimal_operation_results(int result)
+int decimal_operation_results(int result, const char *value, const char *type)
{
switch (result) {
case E_DEC_OK:
break;
case E_DEC_TRUNCATED:
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- WARN_DATA_TRUNCATED, ER(WARN_DATA_TRUNCATED),
- "", (ulong) 0);
+ ER_DATA_TRUNCATED, ER(ER_DATA_TRUNCATED),
+ value, type);
break;
case E_DEC_OVERFLOW:
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- ER_TRUNCATED_WRONG_VALUE,
- ER(ER_TRUNCATED_WRONG_VALUE),
- "DECIMAL", "");
+ ER_DATA_OVERFLOW, ER(ER_DATA_OVERFLOW),
+ value, type);
break;
case E_DEC_DIV_ZERO:
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
@@ -54,9 +57,8 @@ int decimal_operation_results(int result)
break;
case E_DEC_BAD_NUM:
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
- ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
- "decimal", "", "", (ulong) 0);
+ ER_BAD_DATA, ER(ER_BAD_DATA),
+ value, type);
break;
case E_DEC_OOM:
my_error(ER_OUT_OF_RESOURCES, MYF(0));
@@ -212,20 +214,69 @@ int str2my_decimal(uint mask, const char *from, uint length,
}
+/**
+ converts a decimal into a pair of integers - for integer and fractional parts
+
+ special version, for decimals representing number of seconds.
+ integer part cannot be larger that 1e18 (otherwise it's an overflow).
+ fractional part is microseconds.
+*/
+bool my_decimal2seconds(const my_decimal *d, ulonglong *sec, ulong *microsec)
+{
+ int pos;
+
+ if (d->intg)
+ {
+ pos= (d->intg-1)/DIG_PER_DEC1;
+ *sec= d->buf[pos];
+ if (pos > 0)
+ *sec+= static_cast<longlong>(d->buf[pos-1]) * DIG_BASE;
+ }
+ else
+ {
+ *sec=0;
+ pos= -1;
+ }
+
+ *microsec= d->frac ? static_cast<longlong>(d->buf[pos+1]) / (DIG_BASE/1000000) : 0;
+
+ if (pos > 1)
+ {
+ for (int i=0; i < pos-1; i++)
+ if (d->buf[i])
+ {
+ *sec= LONGLONG_MAX;
+ break;
+ }
+ }
+ return d->sign();
+}
+
+
+/**
+ converts a pair of integers (seconds, microseconds) into a decimal
+*/
+my_decimal *seconds2my_decimal(bool sign,
+ ulonglong sec, ulong microsec, my_decimal *d)
+{
+ d->init();
+ longlong2decimal(sec, d); // cannot fail
+ if (microsec)
+ {
+ d->buf[(d->intg-1) / DIG_PER_DEC1 + 1]= microsec * (DIG_BASE/1000000);
+ d->frac= 6;
+ }
+ ((decimal_t *)d)->sign= sign;
+ return d;
+}
+
+
my_decimal *date2my_decimal(MYSQL_TIME *ltime, my_decimal *dec)
{
- longlong date;
- date = (ltime->year*100L + ltime->month)*100L + ltime->day;
+ longlong date= (ltime->year*100L + ltime->month)*100L + ltime->day;
if (ltime->time_type > MYSQL_TIMESTAMP_DATE)
date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
- if (int2my_decimal(E_DEC_FATAL_ERROR, ltime->neg ? -date : date, FALSE, dec))
- return dec;
- if (ltime->second_part)
- {
- dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
- dec->frac= 6;
- }
- return dec;
+ return seconds2my_decimal(ltime->neg, date, ltime->second_part, dec);
}
@@ -240,12 +291,37 @@ void my_decimal_trim(ulong *precision, uint *scale)
}
+/*
+ Convert a decimal to an ulong with a descriptive error message
+*/
+
+int my_decimal2int(uint mask, const decimal_t *d, bool unsigned_flag,
+ longlong *l)
+{
+ int res;
+ my_decimal rounded;
+ /* decimal_round can return only E_DEC_TRUNCATED */
+ decimal_round(d, &rounded, 0, HALF_UP);
+ res= (unsigned_flag ?
+ decimal2ulonglong(&rounded, (ulonglong *) l) :
+ decimal2longlong(&rounded, l));
+ if (res & mask)
+ {
+ char buff[DECIMAL_MAX_STR_LENGTH];
+ int length= sizeof(buff);
+ decimal2string(d, buff, &length, 0, 0, 0);
+
+ decimal_operation_results(res, buff,
+ unsigned_flag ? "UNSIGNED INT" :
+ "INT");
+ }
+ return res;
+}
+
+
#ifndef DBUG_OFF
/* routines for debugging print */
-#define DIG_PER_DEC1 9
-#define ROUND_UP(X) (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
-
/* print decimal */
void
print_decimal(const my_decimal *dec)
@@ -286,7 +362,6 @@ const char *dbug_decimal_as_string(char *buff, const my_decimal *val)
return buff;
}
-#endif /*DBUG_OFF*/
-
+#endif /*DBUG_OFF*/
#endif /*MYSQL_CLIENT*/
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index 0f5a31e999c..5eae7a2f386 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -34,32 +34,7 @@ C_MODE_START
#include <decimal.h>
C_MODE_END
-#define DECIMAL_LONGLONG_DIGITS 22
-#define DECIMAL_LONG_DIGITS 10
-#define DECIMAL_LONG3_DIGITS 8
-
-/** maximum length of buffer in our big digits (uint32). */
-#define DECIMAL_BUFF_LENGTH 9
-
-/* the number of digits that my_decimal can possibly contain */
-#define DECIMAL_MAX_POSSIBLE_PRECISION (DECIMAL_BUFF_LENGTH * 9)
-
-
-/**
- maximum guaranteed precision of number in decimal digits (number of our
- digits * number of decimal digits in one our big digit - number of decimal
- digits in one our big digit decreased by 1 (because we always put decimal
- point on the border of our big digits))
-*/
-#define DECIMAL_MAX_PRECISION (DECIMAL_MAX_POSSIBLE_PRECISION - 8*2)
-#define DECIMAL_MAX_SCALE 30
-#define DECIMAL_NOT_SPECIFIED 31
-
-/**
- maximum length of string representation (number of maximum decimal
- digits + 1 position for sign + 1 position for decimal point, no terminator)
-*/
-#define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2)
+#include <my_decimal_limits.h>
/**
maximum size of packet length.
@@ -163,9 +138,10 @@ const char *dbug_decimal_as_string(char *buff, const my_decimal *val);
#endif
#ifndef MYSQL_CLIENT
-int decimal_operation_results(int result);
+int decimal_operation_results(int result, const char *value, const char *type);
#else
-inline int decimal_operation_results(int result)
+inline int decimal_operation_results(int result, const char *value,
+ const char *type)
{
return result;
}
@@ -187,7 +163,7 @@ inline void max_internal_decimal(my_decimal *to)
inline int check_result(uint mask, int result)
{
if (result & mask)
- decimal_operation_results(result);
+ decimal_operation_results(result, "", "DECIMAL");
return result;
}
@@ -324,24 +300,19 @@ int my_decimal2string(uint mask, const my_decimal *d, uint fixed_prec,
uint fixed_dec, char filler, String *str);
#endif
-inline
-int my_decimal2int(uint mask, const my_decimal *d, my_bool unsigned_flag,
- longlong *l)
-{
- my_decimal rounded;
- /* decimal_round can return only E_DEC_TRUNCATED */
- decimal_round((decimal_t*)d, &rounded, 0, HALF_UP);
- return check_result(mask, (unsigned_flag ?
- decimal2ulonglong(&rounded, (ulonglong *)l) :
- decimal2longlong(&rounded, l)));
-}
+bool my_decimal2seconds(const my_decimal *d, ulonglong *sec, ulong *microsec);
+my_decimal *seconds2my_decimal(bool sign, ulonglong sec, ulong microsec,
+ my_decimal *d);
+
+int my_decimal2int(uint mask, const decimal_t *d, bool unsigned_flag,
+ longlong *l);
inline
-int my_decimal2double(uint, const my_decimal *d, double *result)
+int my_decimal2double(uint, const decimal_t *d, double *result)
{
/* No need to call check_result as this will always succeed */
- return decimal2double((decimal_t*) d, result);
+ return decimal2double(d, result);
}
@@ -384,6 +355,16 @@ int int2my_decimal(uint mask, longlong i, my_bool unsigned_flag, my_decimal *d)
longlong2decimal(i, d)));
}
+inline
+void decimal2my_decimal(decimal_t *from, my_decimal *to)
+{
+ DBUG_ASSERT(to->len >= from->len);
+ to->intg= from->intg;
+ to->frac= from->frac;
+ to->sign(from->sign);
+ memcpy(to->buf, from->buf, to->len*sizeof(decimal_digit_t));
+}
+
inline
void my_decimal_neg(decimal_t *arg)
@@ -447,7 +428,6 @@ int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a,
res);
}
-
/**
@return
-1 if a<b, 1 if a>b and 0 if a==b
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 6af37cb3e2c..128c0bda9dd 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -63,12 +63,15 @@ class Parser_state;
QT_ORDINARY -- ordinary SQL query.
QT_IS -- SQL query to be shown in INFORMATION_SCHEMA (in utf8 and without
- character set introducers).
+ character set introducers).
+ QT_VIEW_INTERNAL -- view internal representation (like QT_ORDINARY except
+ ORDER BY clause)
*/
enum enum_query_type
{
QT_ORDINARY,
- QT_IS
+ QT_IS,
+ QT_VIEW_INTERNAL
};
/* TODO convert all these three maps to Bitmap classes */
@@ -117,8 +120,6 @@ char *sql_strmake_with_convert(const char *str, size_t arg_length,
CHARSET_INFO *from_cs,
size_t max_res_length,
CHARSET_INFO *to_cs, size_t *result_length);
-uint kill_one_thread(THD *thd, ulong id, bool only_kill_query);
-void sql_kill(THD *thd, ulong id, bool only_kill_query);
bool net_request_file(NET* net, const char* fname);
char* query_table_status(THD *thd,const char *db,const char *table_name);
@@ -353,7 +354,10 @@ protected:
Number of comparisons of table rowids equivalent to reading one row from a
table.
*/
-#define TIME_FOR_COMPARE_ROWID (TIME_FOR_COMPARE*2)
+#define TIME_FOR_COMPARE_ROWID (TIME_FOR_COMPARE*100)
+
+/* cost1 is better that cost2 only if cost1 + COST_EPS < cost2 */
+#define COST_EPS 0.001
/*
For sequential disk seeks the cost formula is:
@@ -362,11 +366,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)
/**
@@ -376,6 +380,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
@@ -403,7 +413,6 @@ protected:
#define DELAYED_LIMIT 100 /**< pause after xxx inserts */
#define DELAYED_QUEUE_SIZE 1000
#define DELAYED_WAIT_TIMEOUT 5*60 /**< Wait for delayed insert */
-#define FLUSH_TIME 0 /**< Don't flush tables */
#define MAX_CONNECT_ERRORS 10 ///< errors before disabling host
#ifdef __NETWARE__
@@ -413,8 +422,6 @@ protected:
#endif
#if defined(__WIN__)
-#undef FLUSH_TIME
-#define FLUSH_TIME 1800 /**< Flush every half hour */
#define INTERRUPT_PRIOR -2
#define CONNECT_PRIOR -1
@@ -508,7 +515,6 @@ protected:
#define OPTION_PROFILING (ULL(1) << 33)
-
/**
Maximum length of time zone name that we support
(Time zone name is char(64) in db). mysqlbinlog needs it.
@@ -592,27 +598,59 @@ template <class T> bool valid_buffer_range(T jump,
#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_MERGE_SORT_INTERSECT 16
+#define OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN 32
+#define OPTIMIZER_SWITCH_DERIVED_MERGE 64
+#define OPTIMIZER_SWITCH_DERIVED_WITH_KEYS 128
+#define OPTIMIZER_SWITCH_FIRSTMATCH 256
+#define OPTIMIZER_SWITCH_LOOSE_SCAN 512
+#define OPTIMIZER_SWITCH_MATERIALIZATION 1024
+#define OPTIMIZER_SWITCH_IN_TO_EXISTS (1<<11)
+#define OPTIMIZER_SWITCH_SEMIJOIN (1<<12)
+#define OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE (1<<13)
+#define OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN (1<<14)
+#define OPTIMIZER_SWITCH_SUBQUERY_CACHE (1<<15)
+/** If this is off, MRR is never used. */
+#define OPTIMIZER_SWITCH_MRR (1ULL << 16)
+/**
+ If OPTIMIZER_SWITCH_MRR is on and this is on, MRR is used depending on a
+ cost-based choice ("automatic"). If OPTIMIZER_SWITCH_MRR is on and this is
+ off, MRR is "forced" (i.e. used as long as the storage engine is capable of
+ doing it).
+*/
+#define OPTIMIZER_SWITCH_MRR_COST_BASED (1ULL << 17)
+#define OPTIMIZER_SWITCH_MRR_SORT_KEYS (1ULL << 18)
+#define OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE (1ULL << 19)
+#define OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE (1ULL << 20)
+#define OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL (1ULL << 21)
+#define OPTIMIZER_SWITCH_JOIN_CACHE_HASHED (1ULL << 22)
+#define OPTIMIZER_SWITCH_JOIN_CACHE_BKA (1ULL << 23)
+#define OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE (1ULL << 24)
+#define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1ULL << 25)
+#define OPTIMIZER_SWITCH_LAST (1ULL << 26)
-#ifdef DBUG_OFF
-# define OPTIMIZER_SWITCH_LAST 16
-#else
-# define OPTIMIZER_SWITCH_TABLE_ELIMINATION 16
-# define OPTIMIZER_SWITCH_LAST 32
-#endif
-
-#ifdef DBUG_OFF
/* The following must be kept in sync with optimizer_switch_str in mysqld.cc */
-# 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
-# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
+#define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
- OPTIMIZER_SWITCH_TABLE_ELIMINATION)
-#endif
+ OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN | \
+ OPTIMIZER_SWITCH_DERIVED_MERGE | \
+ OPTIMIZER_SWITCH_DERIVED_WITH_KEYS | \
+ OPTIMIZER_SWITCH_TABLE_ELIMINATION | \
+ OPTIMIZER_SWITCH_IN_TO_EXISTS | \
+ OPTIMIZER_SWITCH_MATERIALIZATION | \
+ OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE|\
+ OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN|\
+ OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE | \
+ OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE | \
+ OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL | \
+ OPTIMIZER_SWITCH_JOIN_CACHE_HASHED | \
+ OPTIMIZER_SWITCH_JOIN_CACHE_BKA | \
+ OPTIMIZER_SWITCH_SUBQUERY_CACHE | \
+ OPTIMIZER_SWITCH_SEMIJOIN | \
+ OPTIMIZER_SWITCH_FIRSTMATCH | \
+ OPTIMIZER_SWITCH_LOOSE_SCAN )
/*
Replication uses 8 bytes to store SQL_MODE in the binary log. The day you
@@ -657,15 +695,36 @@ template <class T> bool valid_buffer_range(T jump,
*/
#define CONTEXT_ANALYSIS_ONLY_DERIVED 4
-// uncachable cause
-#define UNCACHEABLE_DEPENDENT 1
-#define UNCACHEABLE_RAND 2
-#define UNCACHEABLE_SIDEEFFECT 4
-/// forcing to save JOIN for explain
-#define UNCACHEABLE_EXPLAIN 8
+/*
+ Don't evaluate constant sub-expressions of virtual column
+ expressions when opening tables
+*/
+#define CONTEXT_ANALYSIS_ONLY_VCOL_EXPR 8
+
+/*
+ Uncachable causes:
+
+This subquery has fields from outer query (put by user)
+*/
+#define UNCACHEABLE_DEPENDENT_GENERATED 1
+/* This subquery contains functions with random result */
+#define UNCACHEABLE_RAND 2
+/* This subquery contains functions with side effect */
+#define UNCACHEABLE_SIDEEFFECT 4
+/* Forcing to save JOIN tables for explain */
+#define UNCACHEABLE_EXPLAIN 8
/* For uncorrelated SELECT in an UNION with some correlated SELECTs */
-#define UNCACHEABLE_UNITED 16
-#define UNCACHEABLE_CHECKOPTION 32
+#define UNCACHEABLE_UNITED 16
+#define UNCACHEABLE_CHECKOPTION 32
+/*
+ This subquery has fields from outer query injected during
+ transformation process
+*/
+#define UNCACHEABLE_DEPENDENT_INJECTED 64
+
+/* This subquery has fields from outer query (any nature) */
+#define UNCACHEABLE_DEPENDENT (UNCACHEABLE_DEPENDENT_GENERATED | \
+ UNCACHEABLE_DEPENDENT_INJECTED)
/* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */
#define UNDEF_POS (-1)
@@ -673,7 +732,11 @@ template <class T> bool valid_buffer_range(T jump,
/* BINLOG_DUMP options */
#define BINLOG_DUMP_NON_BLOCK 1
+#endif /* !MYSQL_CLIENT */
+
+#define BINLOG_SEND_ANNOTATE_ROWS_EVENT 2
+#ifndef MYSQL_CLIENT
/* sql_show.cc:show_log_files() */
#define SHOW_LOG_STATUS_FREE "FREE"
#define SHOW_LOG_STATUS_INUSE "IN USE"
@@ -716,7 +779,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;
@@ -747,17 +811,6 @@ inline THD *_current_thd(void)
#endif
#define current_thd _current_thd()
-
-/**
- The meat of thd_proc_info(THD*, char*), a macro that packs the last
- three calling-info parameters.
-*/
-extern "C"
-const char *set_thd_proc_info(THD *thd, const char *info,
- const char *calling_func,
- const char *calling_file,
- const unsigned int calling_line);
-
/**
Enumerate possible types of a table from re-execution
standpoint.
@@ -793,9 +846,92 @@ typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
uint key_length,
ulonglong *engine_data);
#include "sql_string.h"
+#include "my_decimal.h"
+
+/*
+ to unify the code that differs only in the argument passed to the
+ error message (string vs. number)
+
+ We pass this container around, and only convert the number
+ to a string when necessary.
+*/
+class Lazy_string
+{
+public:
+ Lazy_string() {}
+ virtual ~Lazy_string() {}
+ virtual void copy_to(String *str) const = 0;
+};
+
+class Lazy_string_str : public Lazy_string
+{
+ const char *str;
+ size_t len;
+public:
+ Lazy_string_str(const char *str_arg, size_t len_arg)
+ : Lazy_string(), str(str_arg), len(len_arg) {}
+ void copy_to(String *dst) const
+ { dst->copy(str, (uint32)len, system_charset_info); }
+};
+
+class Lazy_string_num : public Lazy_string
+{
+ longlong num;
+public:
+ Lazy_string_num(longlong num_arg) : Lazy_string(), num(num_arg) {}
+ void copy_to(String *dst) const { dst->set(num, &my_charset_bin); }
+};
+
+class Lazy_string_decimal: public Lazy_string
+{
+ const my_decimal *d;
+public:
+ Lazy_string_decimal(const my_decimal *d_arg)
+ : Lazy_string(), d(d_arg) {}
+ void copy_to(String *dst) const {
+ my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, ' ', dst);
+ }
+};
+
+class Lazy_string_double: public Lazy_string
+{
+ double num;
+public:
+ Lazy_string_double(double num_arg) : Lazy_string(), num(num_arg) {}
+ void copy_to(String *dst) const
+ { dst->set_real(num, NOT_FIXED_DEC, &my_charset_bin); }
+};
+
+class Lazy_string_time : public Lazy_string
+{
+ const MYSQL_TIME *ltime;
+public:
+ Lazy_string_time(const MYSQL_TIME *ltime_arg)
+ : Lazy_string(), ltime(ltime_arg) {}
+ void copy_to(String *dst) const
+ {
+ dst->alloc(MAX_DATETIME_FULL_WIDTH);
+ dst->length((uint) my_TIME_to_str(ltime, (char*) dst->ptr(),
+ AUTO_SEC_PART_DIGITS));
+ dst->set_charset(&my_charset_bin);
+ }
+};
+
+static inline enum enum_mysql_timestamp_type
+mysql_type_to_time_type(enum enum_field_types mysql_type)
+{
+ switch (mysql_type) {
+ case MYSQL_TYPE_TIME: return MYSQL_TIMESTAMP_TIME;
+ case MYSQL_TYPE_TIMESTAMP:
+ case MYSQL_TYPE_DATETIME: return MYSQL_TIMESTAMP_DATETIME;
+ case MYSQL_TYPE_NEWDATE:
+ case MYSQL_TYPE_DATE: return MYSQL_TIMESTAMP_DATE;
+ default: return MYSQL_TIMESTAMP_ERROR;
+ }
+}
+
#include "sql_list.h"
#include "sql_map.h"
-#include "my_decimal.h"
#include "handler.h"
#include "parse_file.h"
#include "table.h"
@@ -819,6 +955,7 @@ typedef Comp_creator* (*chooser_compare_func_creator)(bool invert);
#endif
#include "item.h"
extern my_decimal decimal_zero;
+extern my_decimal max_seconds_for_time_type, time_second_part_factor;
/* sql_parse.cc */
void free_items(Item *item);
@@ -920,6 +1057,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
@@ -944,6 +1082,7 @@ struct Query_cache_query_flags
MY_LOCALE *lc_time_names;
};
#define QUERY_CACHE_FLAGS_SIZE sizeof(Query_cache_query_flags)
+#define QUERY_CACHE_DB_LENGTH_SIZE 2
#include "sql_cache.h"
#define query_cache_store_query(A, B) query_cache.store_query(A, B)
#define query_cache_destroy() query_cache.destroy()
@@ -952,7 +1091,7 @@ struct Query_cache_query_flags
#define query_cache_resize(A) query_cache.resize(A)
#define query_cache_set_min_res_unit(A) query_cache.set_min_res_unit(A)
#define query_cache_invalidate3(A, B, C) query_cache.invalidate(A, B, C)
-#define query_cache_invalidate1(A) query_cache.invalidate(A)
+#define query_cache_invalidate1(A,B) query_cache.invalidate(A,B)
#define query_cache_send_result_to_client(A, B, C) \
query_cache.send_result_to_client(A, B, C)
#define query_cache_invalidate_by_MyISAM_filename_ref \
@@ -964,6 +1103,7 @@ struct Query_cache_query_flags
(((L)->sql_command == SQLCOM_SELECT) && (L)->safe_to_cache_query)
#else
#define QUERY_CACHE_FLAGS_SIZE 0
+#define QUERY_CACHE_DB_LENGTH_SIZE 0
#define query_cache_store_query(A, B) do { } while(0)
#define query_cache_destroy() do { } while(0)
#define query_cache_result_size_limit(A) do { } while(0)
@@ -971,16 +1111,19 @@ struct Query_cache_query_flags
#define query_cache_resize(A) do { } while(0)
#define query_cache_set_min_res_unit(A) do { } while(0)
#define query_cache_invalidate3(A, B, C) do { } while(0)
-#define query_cache_invalidate1(A) do { } while(0)
+#define query_cache_invalidate1(A,B) do { } while(0)
#define query_cache_send_result_to_client(A, B, C) 0
#define query_cache_invalidate_by_MyISAM_filename_ref NULL
-
-#define query_cache_abort(A)
-#define query_cache_end_of_result(A)
+#define query_cache_abort(A) do { } while(0)
+#define query_cache_end_of_result(A) do { } while(0)
#define query_cache_maybe_disabled(T) 1
#define query_cache_is_cacheable_query(L) 0
#endif /*HAVE_QUERY_CACHE*/
+uint kill_one_thread(THD *thd, ulong id, killed_state kill_signal);
+void sql_kill(THD *thd, ulong id, killed_state kill_signal);
+void sql_kill_user(THD *thd, LEX_USER *str, killed_state kill_signal);
+
/*
Error injector Macros to enable easy testing of recovery after failures
in various error cases.
@@ -1260,6 +1403,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);
@@ -1267,11 +1413,9 @@ int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type,
select_result *result);
bool mysql_union(THD *thd, LEX *lex, select_result *result,
SELECT_LEX_UNIT *unit, ulong setup_tables_done_option);
-bool mysql_handle_derived(LEX *lex, bool (*processor)(THD *thd,
- LEX *lex,
- TABLE_LIST *table));
-bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *t);
-bool mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t);
+bool mysql_handle_derived(LEX *lex, uint phases);
+bool mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases);
+bool mysql_handle_list_of_derived(LEX *lex, TABLE_LIST *dt_list, uint phases);
bool check_table_file_presence(char *old_path, char *path,
const char *db,
const char *table_name,
@@ -1284,6 +1428,12 @@ 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);
+bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
+ ENGINE_COLUMNDEF *start_recinfo,
+ ENGINE_COLUMNDEF **recinfo,
+ ulonglong options);
+
void sp_prepare_create_field(THD *thd, Create_field *sql_field);
int prepare_create_field(Create_field *sql_field,
uint *blob_columns,
@@ -1303,7 +1453,8 @@ bool mysql_alter_table(THD *thd, char *new_db, char *new_name,
HA_CREATE_INFO *create_info,
TABLE_LIST *table_list,
Alter_info *alter_info,
- uint order_num, ORDER *order, bool ignore);
+ uint order_num, ORDER *order, bool ignore,
+ bool require_online);
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list);
bool mysql_create_like_table(THD *thd, TABLE_LIST *table,
TABLE_LIST *src_table,
@@ -1428,6 +1579,7 @@ Field *
find_field_in_table_sef(TABLE *table, const char *name);
int update_virtual_fields(THD *thd, TABLE *table,
enum enum_vcol_update_mode vcol_update_mode= VCOL_UPDATE_FOR_READ);
+int dynamic_column_error_message(enum_dyncol_func_result rc);
#endif /* MYSQL_SERVER */
@@ -1539,15 +1691,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);
@@ -1618,17 +1761,21 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
bool insert_fields(THD *thd, Name_resolution_context *context,
const char *db_name, const char *table_name,
List_iterator<Item> *it, bool any_privileges);
+void make_leaves_list(List<TABLE_LIST> &list, TABLE_LIST *tables,
+ bool full_table_list, TABLE_LIST *boundary);
bool setup_tables(THD *thd, Name_resolution_context *context,
List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
- TABLE_LIST **leaves, bool select_insert);
+ List<TABLE_LIST> &leaves, bool select_insert,
+ bool full_table_list);
bool setup_tables_and_check_access(THD *thd,
Name_resolution_context *context,
List<TABLE_LIST> *from_clause,
TABLE_LIST *tables,
- TABLE_LIST **leaves,
+ List<TABLE_LIST> &leaves,
bool select_insert,
ulong want_access_first,
- ulong want_access);
+ ulong want_access,
+ bool full_table_list);
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
List<Item> *sum_func_list, uint wild_num);
bool setup_fields(THD *thd, Item** ref_pointer_array,
@@ -1647,8 +1794,9 @@ inline bool setup_fields_with_no_wrap(THD *thd, Item **ref_pointer_array,
thd->lex->select_lex.no_wrap_view_item= FALSE;
return res;
}
-int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
+int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
COND **conds);
+void wrap_ident(THD *thd, Item **conds);
int setup_ftfuncs(SELECT_LEX* select);
int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order);
void wait_for_condition(THD *thd, pthread_mutex_t *mutex,
@@ -1669,7 +1817,8 @@ inline int open_and_lock_tables(THD *thd, TABLE_LIST *tables)
/* simple open_and_lock_tables without derived handling for single table */
TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
thr_lock_type lock_type);
-bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags);
+bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags,
+ uint dt_phases);
int lock_tables(THD *thd, TABLE_LIST *tables, uint counter, bool *need_reopen);
int decide_logging_format(THD *thd, TABLE_LIST *tables);
TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
@@ -1699,6 +1848,7 @@ void flush_tables();
bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
char *make_default_log_name(char *buff,const char* log_ext);
char *make_once_alloced_filename(const char *basename, const char *ext);
+void unfix_fields(List<Item> &items);
#ifdef WITH_PARTITION_STORAGE_ENGINE
uint fast_alter_partition_table(THD *thd, TABLE *table,
@@ -1856,12 +2006,13 @@ void close_performance_schema_table(THD *thd, Open_tables_state *backup);
bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
bool wait_for_refresh, bool wait_for_placeholders);
+bool close_cached_tables_set_readonly(THD *thd);
bool close_cached_connection_tables(THD *thd, bool wait_for_refresh,
LEX_STRING *connect_string,
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,
@@ -1916,19 +2067,26 @@ 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 */
int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field,
uint *key_length, uint *keypart);
-void key_copy(uchar *to_key, uchar *from_record, KEY *key_info, uint key_length);
+void key_copy(uchar *to_key, uchar *from_record, KEY *key_info, uint key_length,
+ bool with_zerofill= FALSE);
void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
uint key_length);
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 */
@@ -1936,6 +2094,7 @@ void sql_perror(const char *message);
bool fn_format_relative_to_data_home(char * to, const char *name,
const char *dir, const char *extension);
+void set_server_version(void);
/**
Test a file path to determine if the path is compatible with the secure file
path restriction.
@@ -1959,6 +2118,7 @@ void flush_thread_cache();
/* item_func.cc */
extern bool check_reserved_words(LEX_STRING *name);
extern enum_field_types agg_field_type(Item **items, uint nitems);
+Item *find_date_time_item(Item **args, uint nargs, uint col);
/* strfunc.cc */
ulonglong find_set(TYPELIB *lib, const char *x, uint length, CHARSET_INFO *cs,
@@ -2047,6 +2207,7 @@ extern ulonglong thd_startup_options;
extern ulong thread_id;
extern ulong binlog_cache_use, binlog_cache_disk_use;
extern ulong aborted_threads,aborted_connects;
+extern ulong opt_progress_report_time;
extern ulong delayed_insert_timeout;
extern ulong delayed_insert_limit, delayed_queue_size;
extern ulong delayed_insert_threads, delayed_insert_writes;
@@ -2059,7 +2220,8 @@ extern MYSQL_PLUGIN_IMPORT ulong max_connections;
extern ulong max_connect_errors, connect_timeout;
extern ulong extra_max_connections;
extern ulong slave_net_timeout, slave_trans_retries;
-extern uint max_user_connections;
+extern int max_user_connections;
+extern bool max_user_connections_checking;
extern ulonglong denied_connections;
extern ulong what_to_log,flush_time;
extern ulong query_buff_size;
@@ -2067,8 +2229,10 @@ extern ulong slave_max_allowed_packet;
extern ulong max_prepared_stmt_count, prepared_stmt_count;
extern ulong binlog_cache_size, open_files_limit;
extern ulonglong max_binlog_cache_size;
-extern ulong max_binlog_size, max_relay_log_size;
+extern ulong max_binlog_size, max_relay_log_size, opt_binlog_dbug_fsync_sleep;
extern ulong opt_binlog_rows_event_max_size;
+extern my_bool opt_master_verify_checksum;
+extern my_bool opt_slave_sql_verify_checksum;
extern ulong rpl_recovery_rank, thread_cache_size, thread_pool_size;
extern ulong back_log;
#endif /* MYSQL_SERVER */
@@ -2078,6 +2242,7 @@ extern ulong MYSQL_PLUGIN_IMPORT specialflag;
#ifdef MYSQL_SERVER
extern ulong current_pid;
extern ulong expire_logs_days, sync_binlog_period, sync_binlog_counter;
+extern ulong binlog_checksum_options;
extern ulong opt_tc_log_size, tc_log_max_pages_used, tc_log_page_size;
extern ulong tc_log_page_waits;
extern my_bool relay_log_purge, opt_innodb_safe_binlog, opt_innodb;
@@ -2086,6 +2251,8 @@ extern uint test_flags,select_errors,ha_open_options;
extern uint protocol_version, mysqld_port, mysqld_extra_port, dropping_tables;
extern uint delay_key_write_options;
extern ulong max_long_data_size, max_used_connections;
+extern uint internal_tmp_table_max_key_length;
+extern uint internal_tmp_table_max_key_segments;
#endif /* MYSQL_SERVER */
#if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS
extern MYSQL_PLUGIN_IMPORT uint lower_case_table_names;
@@ -2110,13 +2277,13 @@ extern bool opt_ignore_builtin_innodb;
extern my_bool opt_character_set_client_handshake;
extern bool volatile abort_loop, shutdown_in_progress;
extern bool in_bootstrap;
-extern uint volatile thread_count, thread_running, global_read_lock;
+extern uint volatile thread_count, thread_running, global_read_lock, global_disable_checkpoint;
extern ulong thread_created;
extern uint thread_handling;
extern uint connection_count, extra_connection_count;
extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types;
extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap;
-extern my_bool opt_slave_compressed_protocol, use_temp_pool;
+extern my_bool opt_slave_compressed_protocol, use_temp_pool, opt_help;
extern ulong slave_exec_mode_options;
extern my_bool opt_readonly, lower_case_file_system;
extern my_bool opt_userstat_running;
@@ -2124,6 +2291,7 @@ extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
extern my_bool opt_secure_auth, debug_assert_if_crashed_table;
extern char* opt_secure_file_priv;
extern my_bool opt_log_slow_admin_statements, opt_log_slow_slave_statements;
+extern my_bool opt_query_cache_strip_comments;
extern my_bool sp_automatic_privileges, opt_noacl;
extern my_bool opt_old_style_user_limits, trust_function_creators;
extern uint opt_crash_binlog_innodb;
@@ -2242,6 +2410,10 @@ extern struct st_VioSSLFd * ssl_acceptor_fd;
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
uint flags, bool *need_reopen);
+int 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
@@ -2249,8 +2421,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,
@@ -2262,15 +2438,19 @@ 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,
bool is_not_commit);
void start_waiting_global_read_lock(THD *thd);
bool make_global_read_lock_block_commit(THD *thd);
+void disable_checkpoints(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);
@@ -2329,19 +2509,36 @@ void free_field_buffers_larger_than(TABLE *table, uint32 size);
int set_zone(int nr,int min_zone,int max_zone);
ulong convert_period_to_month(ulong period);
ulong convert_month_to_period(ulong month);
-void get_date_from_daynr(long daynr,uint *year, uint *month,
+bool get_date_from_daynr(long daynr,uint *year, uint *month,
uint *day);
-my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *not_exist);
-bool str_to_time_with_warn(const char *str,uint length,MYSQL_TIME *l_time);
+my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, uint *error);
+bool str_to_time_with_warn(const char *str,uint length,MYSQL_TIME *l_time,
+ ulong fuzzydate);
timestamp_type str_to_datetime_with_warn(const char *str, uint length,
- MYSQL_TIME *l_time, uint flags);
+ MYSQL_TIME *l_time, ulong flags);
void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
void calc_time_from_sec(MYSQL_TIME *to, long seconds, long microseconds);
-void make_truncated_value_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
- const char *str_val,
- uint str_length, timestamp_type time_type,
+void make_truncated_value_warning(THD *thd,
+ MYSQL_ERROR::enum_warning_level level,
+ const Lazy_string *str_val,
+ timestamp_type time_type,
const char *field_name);
+bool double_to_datetime_with_warn(double value, MYSQL_TIME *ltime,
+ ulong fuzzydate, const char *field_name);
+bool decimal_to_datetime_with_warn(const my_decimal *value, MYSQL_TIME *ltime,
+ ulong fuzzydate, const char *field_name);
+bool int_to_datetime_with_warn(longlong value, MYSQL_TIME *ltime,
+ ulong fuzzydate, const char *field_name);
+
+static inline void make_truncated_value_warning(THD *thd,
+ MYSQL_ERROR::enum_warning_level level, const char *str_val,
+ uint str_length, timestamp_type time_type,
+ const char *field_name)
+{
+ const Lazy_string_str str(str_val, str_length);
+ make_truncated_value_warning(thd, level, &str, time_type, field_name);
+}
bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type, INTERVAL interval);
bool calc_time_diff(MYSQL_TIME *l_time1, MYSQL_TIME *l_time2, int l_sign,
@@ -2358,12 +2555,6 @@ const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
timestamp_type type);
extern bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
timestamp_type type, String *str);
-void make_datetime(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time,
- String *str);
-void make_date(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time,
- String *str);
-void make_time(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time,
- String *str);
int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b);
longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
Item *warn_item, bool *is_null);
@@ -2381,6 +2572,8 @@ ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder,
ha_rows max_rows, bool sort_positions,
ha_rows *examined_rows);
void filesort_free_buffers(TABLE *table, bool full);
+double get_merge_many_buffs_cost(uint *buffer, uint last_n_elems,
+ int elem_size);
void change_double_for_sort(double nr,uchar *to);
double my_double_round(double value, longlong dec, bool dec_unsigned,
bool truncate);
@@ -2562,7 +2755,7 @@ Item * all_any_subquery_creator(Item *left_expr,
inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
{
table->used_fields= 0;
- table->const_table= 0;
+ table_list->reset_const_table();
table->null_row= 0;
table->status= STATUS_NO_RECORD;
table->maybe_null= table_list->outer_join;
@@ -2578,6 +2771,14 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
table->force_index_order= table->force_index_group= 0;
table->covering_keys= table->s->keys_for_keyread;
table->merge_keys.clear_all();
+ TABLE_LIST *orig= table_list->select_lex ?
+ table_list->select_lex->master_unit()->derived : 0;
+ if (!orig || !orig->is_merged_derived())
+ {
+ /* Tables merged from derived were set up already.*/
+ table->covering_keys= table->s->keys_for_keyread;
+ table->merge_keys.clear_all();
+ }
}
@@ -2604,6 +2805,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
@@ -2684,6 +2898,8 @@ bool load_collation(MEM_ROOT *mem_root,
CHARSET_INFO *dflt_cl,
CHARSET_INFO **cl);
+bool db_name_is_in_ignore_db_dirs_list(const char *dbase);
+
#endif /* MYSQL_SERVER */
extern "C" int test_if_data_home_dir(const char *dir);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 885f2e72190..393296bd471 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -33,6 +33,7 @@
#include <waiting_threads.h>
#include "debug_sync.h"
#include "log_event.h"
+#include "sql_show.h"
#include "../storage/myisam/ha_myisam.h"
@@ -149,6 +150,7 @@ static event_handle_t eh;
static Report_t ref;
static void *refneb= NULL;
my_bool event_flag= FALSE;
+
static int volumeid= -1;
/* NEB event callback */
@@ -338,10 +340,23 @@ TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
static const char *optimizer_switch_names[]=
{
"index_merge","index_merge_union","index_merge_sort_union",
- "index_merge_intersection",
-#ifndef DBUG_OFF
+ "index_merge_intersection","index_merge_sort_intersection",
+ "index_condition_pushdown",
+ "derived_merge", "derived_with_keys",
+ "firstmatch","loosescan","materialization","in_to_exists","semijoin",
+ "partial_match_rowid_merge",
+ "partial_match_table_scan",
+ "subquery_cache",
+ "mrr",
+ "mrr_cost_based",
+ "mrr_sort_keys",
+ "outer_join_with_cache",
+ "semijoin_with_cache",
+ "join_cache_incremental",
+ "join_cache_hashed",
+ "join_cache_bka",
+ "optimize_join_buffer_size",
"table_elimination",
-#endif
"default", NullS
};
@@ -352,9 +367,28 @@ static const unsigned int optimizer_switch_names_len[]=
sizeof("index_merge_union") - 1,
sizeof("index_merge_sort_union") - 1,
sizeof("index_merge_intersection") - 1,
-#ifndef DBUG_OFF
+ sizeof("index_merge_sort_intersection") - 1,
+ sizeof("index_condition_pushdown") - 1,
+ sizeof("derived_merge") - 1,
+ sizeof("derived_with_keys") - 1,
+ sizeof("firstmatch") - 1,
+ sizeof("loosescan") - 1,
+ sizeof("materialization") - 1,
+ sizeof("in_to_exists") - 1,
+ sizeof("semijoin") - 1,
+ sizeof("partial_match_rowid_merge") - 1,
+ sizeof("partial_match_table_scan") - 1,
+ sizeof("subquery_cache") - 1,
+ sizeof("mrr") - 1,
+ sizeof("mrr_cost_based") - 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,
+ sizeof("optimize_join_buffer_size") - 1,
sizeof("table_elimination") - 1,
-#endif
sizeof("default") - 1
};
TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
@@ -407,14 +441,15 @@ bool opt_large_files= sizeof(my_off_t) > 4;
/*
Used with --help for detailed option
*/
-static my_bool opt_help= 0, opt_verbose= 0;
+static my_bool opt_verbose= 0;
-arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
+arg_cmp_func Arg_comparator::comparator_matrix[6][2] =
{{&Arg_comparator::compare_string, &Arg_comparator::compare_e_string},
{&Arg_comparator::compare_real, &Arg_comparator::compare_e_real},
{&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int},
{&Arg_comparator::compare_row, &Arg_comparator::compare_e_row},
- {&Arg_comparator::compare_decimal, &Arg_comparator::compare_e_decimal}};
+ {&Arg_comparator::compare_decimal, &Arg_comparator::compare_e_decimal},
+ {&Arg_comparator::compare_datetime, &Arg_comparator::compare_e_datetime}};
const char *log_output_names[] = { "NONE", "FILE", "TABLE", NullS};
static const unsigned int log_output_names_len[]= { 4, 4, 5, 0 };
@@ -436,7 +471,13 @@ 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;
-static my_bool opt_sync= 0;
+static my_bool opt_sync= 0, opt_thread_alarm;
+/*
+ Set this to 1 if you want to that 'strict mode' should affect all date
+ operations. If this is 0, then date checking is only done when storing
+ dates into a table.
+*/
+my_bool strict_date_checking= 0;
static uint kill_cached_threads, wake_thread;
ulong thread_created;
uint thread_handling;
@@ -447,12 +488,30 @@ 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
- ",table_elimination=on";
-#else
+ "index_merge_intersection=on,"
+ "index_merge_sort_intersection=off,"
+ "index_condition_pushdown=on,"
+ "derived_merge=on,"
+ "derived_with_keys=on,"
+ "firstmatch=on,"
+ "loosescan=on,"
+ "materialization=on,"
+ "in_to_exists=on,"
+ "semijoin=on,"
+ "partial_match_rowid_merge=on,"
+ "partial_match_table_scan=on,"
+ "subquery_cache=on,"
+ "mrr=off,"
+ "mrr_cost_based=off,"
+ "mrr_sort_keys=off,"
+ "outer_join_with_cache=on,"
+ "semijoin_with_cache=on,"
+ "join_cache_incremental=on,"
+ "join_cache_hashed=on,"
+ "join_cache_bka=on,"
+ "optimize_join_buffer_size=off,"
+ "table_elimination=on";
;
-#endif
#ifdef SAFEMALLOC
my_bool sf_malloc_trough_check= 0;
#endif
@@ -474,7 +533,7 @@ static pthread_cond_t COND_thread_cache, COND_flush_thread_cache;
/* Global variables */
bool opt_update_log, opt_bin_log, opt_ignore_builtin_innodb= 0;
-my_bool opt_log, opt_slow_log, debug_assert_if_crashed_table;
+my_bool opt_log, opt_slow_log, debug_assert_if_crashed_table, opt_help= 0;
my_bool opt_userstat_running;
ulong log_output_options;
my_bool opt_log_queries_not_using_indexes= 0;
@@ -519,6 +578,7 @@ my_bool opt_local_infile, opt_slave_compressed_protocol;
my_bool opt_safe_user_create = 0, opt_no_mix_types = 0;
my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
my_bool opt_log_slave_updates= 0;
+my_bool opt_replicate_annotate_row_events= 0;
bool slave_warning_issued = false;
/*
@@ -554,6 +614,7 @@ my_bool opt_secure_auth= 0;
char* opt_secure_file_priv= 0;
my_bool opt_log_slow_admin_statements= 0;
my_bool opt_log_slow_slave_statements= 0;
+my_bool opt_query_cache_strip_comments = 0;
my_bool lower_case_file_system= 0;
my_bool opt_large_pages= 0;
my_bool opt_myisam_use_mmap= 0;
@@ -572,6 +633,8 @@ my_bool opt_noacl;
my_bool sp_automatic_privileges= 1;
ulong opt_binlog_rows_event_max_size;
+my_bool opt_master_verify_checksum= 0;
+my_bool opt_slave_sql_verify_checksum= 1;
const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
TYPELIB binlog_format_typelib=
{ array_elements(binlog_format_names) - 1, "",
@@ -618,7 +681,12 @@ ulong extra_max_connections;
*/
ulong max_long_data_size;
-uint max_user_connections= 0;
+/* Limits for internal temporary tables (MyISAM or Aria) */
+uint internal_tmp_table_max_key_length;
+uint internal_tmp_table_max_key_segments;
+
+int max_user_connections= 0;
+bool max_user_connections_checking=0;
ulonglong denied_connections;
/**
Limit of the total number of prepared statements in the server.
@@ -651,6 +719,7 @@ char mysql_real_data_home[FN_REFLEN],
language[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
*opt_init_file, *opt_tc_log_file,
def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
+const char *opt_basename;
char mysql_unpacked_real_data_home[FN_REFLEN];
int mysql_unpacked_real_data_home_len;
uint reg_ext_length;
@@ -675,6 +744,8 @@ const char *in_additional_cond= "<IN COND>";
const char *in_having_cond= "<IN HAVING>";
my_decimal decimal_zero;
+my_decimal max_seconds_for_time_type, time_second_part_factor;
+
/* classes for comparation parsing/processing */
Eq_creator eq_creator;
Ne_creator ne_creator;
@@ -764,9 +835,7 @@ char *opt_logname, *opt_slow_logname;
/* Static variables */
static volatile sig_atomic_t kill_in_progress;
-#ifdef HAVE_STACKTRACE
my_bool opt_stack_trace;
-#endif /* HAVE_STACKTRACE */
my_bool opt_expect_abort= 0;
static my_bool opt_bootstrap, opt_myisam_log;
static int cleanup_done;
@@ -878,7 +947,6 @@ pthread_handler_t signal_hand(void *arg);
static int mysql_init_variables(void);
static int get_options(int *argc,char **argv);
extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *);
-static void set_server_version(void);
static int init_thread_environment();
static char *get_relative_path(const char *path);
static int fix_paths(void);
@@ -1034,7 +1102,7 @@ static void close_connections(void)
if (tmp->slave_thread)
continue;
- tmp->killed= THD::KILL_CONNECTION;
+ tmp->killed= KILL_SERVER_HARD;
thread_scheduler.post_kill_notification(tmp);
pthread_mutex_lock(&tmp->LOCK_thd_data);
if (tmp->mysys_var)
@@ -1384,6 +1452,7 @@ void clean_up(bool print_message)
#endif
my_tz_free();
my_database_names_free();
+ ignore_db_dirs_free();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
servers_free(1);
acl_free(1);
@@ -1407,6 +1476,7 @@ void clean_up(bool print_message)
ha_end();
if (tc_log)
tc_log->close();
+ TC_destroy();
xid_cache_free();
wt_end();
delete_elements(&key_caches, (void (*)(const char*, uchar*)) free_key_cache);
@@ -1821,8 +1891,10 @@ static my_socket activate_tcp_port(uint port)
}
if (ret < 0)
{
- DBUG_PRINT("error",("Got error: %d from bind",socket_errno));
- sql_perror("Can't start server: Bind on TCP/IP port");
+ char buff[100];
+ sprintf(buff, "Can't start server: Bind on TCP/IP port. Got error: %d",
+ (int) socket_errno);
+ sql_perror(buff);
sql_print_error("Do you already have another mysqld server running on "
"port: %u ?", port);
unireg_abort(1);
@@ -1977,7 +2049,7 @@ void close_connection(THD *thd, uint errcode, bool lock)
errcode ? ER(errcode) : ""));
if (lock)
(void) pthread_mutex_lock(&LOCK_thread_count);
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_CONNECTION;
if (global_system_variables.log_warnings > 3)
{
@@ -2091,7 +2163,8 @@ static bool cache_thread()
this thread for handling of new THD object/connection.
*/
thd->mysys_var->abort= 0;
- thd->thr_create_utime= thd->start_utime= my_micro_time();
+ thd->thr_create_utime= microsecond_interval_timer();
+ thd->start_utime= thd->thr_create_utime;
threads.append(thd);
return(1);
}
@@ -2924,41 +2997,25 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
thd->is_slave_error= 1; // needed to catch query errors during replication
- /*
- thd->lex->current_select == 0 if lex structure is not inited
- (not query command (COM_QUERY))
- */
- if (thd->lex->current_select &&
- thd->lex->current_select->no_error && !thd->is_fatal_error)
+ if (thd->main_da.is_ok() && !thd->main_da.can_overwrite_status)
{
- DBUG_PRINT("error",
- ("Error converted to warning: current_select: no_error %d "
- "fatal_error: %d",
- (thd->lex->current_select ?
- thd->lex->current_select->no_error : 0),
- (int) thd->is_fatal_error));
+ /*
+ Client has already got ok packet and we are not in net_flush(), so
+ we write a message to error log.
+ This could happen if we get an error in implicit commit.
+ This should never happen in normal operation, so lets
+ assert here in debug builds.
+ */
+ DBUG_ASSERT(0);
+ func= sql_print_error;
+ MyFlags|= ME_NOREFRESH;
}
- else
+ else if (! thd->main_da.is_error()) // Return only first message
{
- if (thd->main_da.is_ok() && !thd->main_da.can_overwrite_status)
- {
- /*
- Client has already got ok packet and we are not in net_flush(), so
- we write a message to error log.
- This could happen if we get an error in implicit commit.
- This should never happen in normal operation, so lets
- assert here in debug builds.
- */
- DBUG_ASSERT(0);
- func= sql_print_error;
- MyFlags|= ME_NOREFRESH;
- }
- else if (! thd->main_da.is_error()) // Return only first message
- {
- thd->main_da.set_error_status(thd, error, str);
- }
- query_cache_abort(&thd->net);
+ thd->main_da.set_error_status(thd, error, str);
}
+ query_cache_abort(&thd->net);
+
/*
If a continue handler is found, the error message will be cleared
by the stored procedures code.
@@ -3040,6 +3097,7 @@ const char *load_default_groups[]= {
#endif
"mysqld", "server", MYSQL_BASE_VERSION,
"mariadb", MARIADB_BASE_VERSION,
+"client-server",
0, 0};
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
@@ -3259,9 +3317,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
char **argv, const char **groups)
{
char buff[FN_REFLEN], *s;
- const char *basename;
umask(((~my_umask) & 0666));
- my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
tzset(); // Set tzname
max_system_variables.pseudo_thread_id= (ulong)~0;
@@ -3279,6 +3335,9 @@ static int init_common_variables(const char *conf_file_name, int argc,
mysql_init_variables())
return 1;
+ if (ignore_db_dirs_init())
+ return 1;
+
#ifdef HAVE_TZNAME
{
struct tm tm_tmp;
@@ -3320,13 +3379,13 @@ static int init_common_variables(const char *conf_file_name, int argc,
strmake(glob_hostname, STRING_WITH_LEN("localhost"));
sql_print_warning("gethostname failed, using '%s' as hostname",
glob_hostname);
- basename= "mysql";
+ opt_basename= "mysql";
}
else
{
- basename= glob_hostname;
+ opt_basename= glob_hostname;
}
- strmake(pidfile_name, basename, sizeof(pidfile_name)-5);
+ strmake(pidfile_name, opt_basename, sizeof(pidfile_name)-5);
strmov(fn_ext(pidfile_name),".pid"); // Add proper extension
/*
@@ -3605,8 +3664,7 @@ You should consider changing lower_case_table_names to 1 or 2",
}
}
else if (lower_case_table_names == 2 &&
- !(lower_case_file_system=
- (test_if_case_insensitive(mysql_real_data_home) == 1)))
+ !(lower_case_file_system= (lower_case_file_system == 1)))
{
if (global_system_variables.log_warnings)
sql_print_warning("lower_case_table_names was set to 2, even though your "
@@ -3617,8 +3675,7 @@ You should consider changing lower_case_table_names to 1 or 2",
}
else
{
- lower_case_file_system=
- (test_if_case_insensitive(mysql_real_data_home) == 1);
+ lower_case_file_system= (lower_case_file_system == 1);
}
/* Reset table_alias_charset, now that lower_case_table_names is set. */
@@ -3626,6 +3683,12 @@ You should consider changing lower_case_table_names to 1 or 2",
files_charset_info :
&my_charset_bin);
+ if (ignore_db_dirs_process_additions())
+ {
+ sql_print_error("An error occurred while storing ignore_db_dirs to a hash.");
+ return 1;
+ }
+
return 0;
}
@@ -4056,11 +4119,13 @@ a file name for --log-bin-index option", opt_binlog_index_name);
require a name. But as we don't want to break many existing setups, we
only give warning, not error.
*/
- sql_print_warning("No argument was provided to --log-bin, and "
- "--log-bin-index was not used; so replication "
- "may break when this MySQL server acts as a "
- "master and has his hostname changed!! Please "
- "use '--log-bin=%s' to avoid this problem.", ln);
+ sql_print_warning("No argument was provided to --log-bin and "
+ "neither --log-basename or --log-bin-index where "
+ "used; This may cause repliction to break when this "
+ "server acts as a master and has its hostname "
+ "changed!! Please use '--log-basename=%s' or "
+ "'--log-bin=%s' to avoid this problem.",
+ opt_basename, ln);
}
if (ln == buf)
{
@@ -4130,6 +4195,8 @@ a file name for --log-bin-index option", opt_binlog_index_name);
if (!errmesg[0][0])
unireg_abort(1);
+ TC_init();
+
/* We have to initialize the storage engines before CSV logging */
if (ha_init())
{
@@ -4217,6 +4284,11 @@ a file name for --log-bin-index option", opt_binlog_index_name);
sql_print_error("Aria engine is not enabled or did not start. The Aria engine must be enabled to continue as mysqld was configured with --with-aria-tmp-tables");
unireg_abort(1);
}
+ internal_tmp_table_max_key_length= maria_max_key_length();
+ internal_tmp_table_max_key_segments= maria_max_key_segments();
+#else
+ internal_tmp_table_max_key_length= myisam_max_key_length();
+ internal_tmp_table_max_key_segments= myisam_max_key_segments();
#endif
tc_log= (total_ha_2pc > 1 ? (opt_bin_log ?
@@ -4513,13 +4585,14 @@ int main(int argc, char **argv)
#ifndef DBUG_OFF
test_lc_time_sz();
+ srand((uint) time(NULL));
#endif
/*
We have enough space for fiddling with the argv, continue
*/
check_data_home(mysql_real_data_home);
- if (my_setwd(mysql_real_data_home,MYF(MY_WME)) && !opt_help)
+ if (my_setwd(mysql_real_data_home, opt_help ? 0 : MYF(MY_WME)) && !opt_help)
unireg_abort(1); /* purecov: inspected */
mysql_data_home= mysql_data_home_buff;
mysql_data_home[0]=FN_CURLIB; // all paths are relative from here
@@ -5001,9 +5074,9 @@ void handle_connection_in_main_thread(THD *thd)
safe_mutex_assert_owner(&LOCK_thread_count);
thread_cache_size=0; // Safety
threads.append(thd);
- thd->start_utime= my_micro_time();
+ thd->set_time(my_hrtime());
pthread_mutex_unlock(&LOCK_thread_count);
- thd->start_utime= my_micro_time();
+ thd->start_utime= microsecond_interval_timer();
handle_one_connection(thd);
}
@@ -5029,7 +5102,7 @@ void create_thread_to_handle_connection(THD *thd)
thread_created++;
threads.append(thd);
DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
- thd->prior_thr_create_utime= thd->start_utime= my_micro_time();
+ thd->prior_thr_create_utime= microsecond_interval_timer();
if ((error=pthread_create(&thd->real_id,&connection_attrib,
handle_one_connection,
(void*) thd)))
@@ -5039,7 +5112,7 @@ void create_thread_to_handle_connection(THD *thd)
("Can't create thread to handle request (error %d)",
error));
thread_count--;
- thd->killed= THD::KILL_CONNECTION; // Safety
+ thd->killed= KILL_CONNECTION; // Safety
(void) pthread_mutex_unlock(&LOCK_thread_count);
pthread_mutex_lock(&LOCK_connection_count);
@@ -5760,7 +5833,9 @@ enum options_mysqld
OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB,
OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES,
OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB,
- OPT_BINLOG_FORMAT,
+ OPT_BINLOG_FORMAT, OPT_DEBUG_BINLOG_FSYNC_SLEEP,
+ OPT_BINLOG_ANNOTATE_ROWS_EVENTS,
+ OPT_REPLICATE_ANNOTATE_ROWS_EVENTS,
#ifndef DBUG_OFF
OPT_BINLOG_SHOW_XID,
#endif
@@ -5808,6 +5883,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,
@@ -5822,7 +5898,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,
@@ -5842,17 +5918,20 @@ 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,
- OPT_WAIT_TIMEOUT,
+ OPT_WAIT_TIMEOUT, OPT_PROGRESS_REPORT_TIME,
OPT_ERROR_LOG_FILE,
OPT_DEFAULT_WEEK_FORMAT,
OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS,
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,
@@ -5927,7 +6006,11 @@ enum options_mysqld
OPT_IGNORE_BUILTIN_INNODB,
OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
OPT_DEFAULT_CHARACTER_SET_OLD,
- OPT_MAX_LONG_DATA_SIZE
+ OPT_MAX_LONG_DATA_SIZE,
+ OPT_MASTER_VERIFY_CHECKSUM,
+ OPT_SLAVE_SQL_VERIFY_CHECKSUM,
+ OPT_QUERY_CACHE_STRIP_COMMENTS,
+ OPT_IGNORE_DB_DIRECTORY
};
@@ -5978,6 +6061,12 @@ struct my_option my_long_options[] =
{"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
&my_bind_addr_str, &my_bind_addr_str, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifndef DBUG_OFF
+ {"debug-binlog-fsync-sleep", OPT_DEBUG_BINLOG_FSYNC_SLEEP,
+ "Extra sleep (in microseconds) to add to binlog fsync(), for debugging",
+ &opt_binlog_dbug_fsync_sleep, &opt_binlog_dbug_fsync_sleep,
+ 0, GET_ULONG, REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1, 0},
+#endif
{"binlog_format", OPT_BINLOG_FORMAT,
"Does not have any effect without '--log-bin'. "
"Tell the master the form of binary logging to use: either 'row' for "
@@ -5991,6 +6080,18 @@ struct my_option my_long_options[] =
#endif
, &opt_binlog_format, &opt_binlog_format,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"binlog-annotate-row-events", OPT_BINLOG_ANNOTATE_ROWS_EVENTS,
+ "Tells the master to annotate RBR events with the statement that "
+ "caused these events.",
+ (uchar**) &global_system_variables.binlog_annotate_row_events,
+ (uchar**) &max_system_variables.binlog_annotate_row_events,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-annotate-row-events", OPT_REPLICATE_ANNOTATE_ROWS_EVENTS,
+ "Tells the slave to write annotate rows events recieved from the master "
+ "to its own binary log. Sensible only in pair with log-slave-updates option.",
+ (uchar**) &opt_replicate_annotate_row_events,
+ (uchar**) &opt_replicate_annotate_row_events,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"binlog-do-db", OPT_BINLOG_DO_DB,
"Tells the master it should log updates for the specified database, "
"and exclude all others not explicitly mentioned.",
@@ -6184,7 +6285,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
@@ -6198,6 +6299,11 @@ struct my_option my_long_options[] =
each time the SQL thread starts.",
&opt_init_slave, &opt_init_slave, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"ignore-db-dir", OPT_IGNORE_DB_DIRECTORY,
+ "Specifies a directory to add to the ignore list when collecting "
+ "database names from the datadir. Put a blank argument to reset "
+ "the list accumulated so far.", 0, 0, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
{"language", 'L',
"Client error messages in given language. May be given as a full path.",
&language_ptr, &language_ptr, 0, GET_STR, REQUIRED_ARG,
@@ -6780,6 +6886,19 @@ each time the SQL thread starts.",
"not stop for operations that are idempotent. In STRICT mode, replication "
"will stop on any unexpected difference between the master and the slave.",
&slave_exec_mode_str, &slave_exec_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"master-verify-checksum", OPT_MASTER_VERIFY_CHECKSUM,
+ "Force checksum verification of logged events in binary log before "
+ "sending them to slaves or printing them in output of SHOW BINLOG EVENTS. "
+ "Disabled by default.",
+ &opt_master_verify_checksum, &opt_master_verify_checksum,
+ 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"slave-sql-verify-checksum", OPT_SLAVE_SQL_VERIFY_CHECKSUM,
+ "Force checksum verification of replication events after reading them "
+ "from relay log. Note: Events are always checksum-verified by slave on "
+ "receiving them from the network before writing them to the relay "
+ "log. Enabled by default.",
+ &opt_slave_sql_verify_checksum, &opt_slave_sql_verify_checksum,
+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
#endif
{"slow-query-log", OPT_SLOW_LOG,
"Enable/disable slow query log. See also '--log-slow-queries'",
@@ -6952,7 +7071,7 @@ each time the SQL thread starts.",
{ "flush_time", OPT_FLUSH_TIME,
"A dedicated thread is created to flush all tables at the given interval.",
&flush_time, &flush_time, 0, GET_ULONG, REQUIRED_ARG,
- FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1, 0},
+ 0 , 0, LONG_TIMEOUT, 0, 1, 0},
{ "ft_boolean_syntax", OPT_FT_BOOLEAN_SYNTAX,
"List of operators for MATCH ... AGAINST ( ... IN BOOLEAN MODE).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -6986,11 +7105,22 @@ each time the SQL thread starts.",
&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, (ulonglong) 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, (ulonglong) 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, 16*128*1024L, 2048+MALLOC_OVERHEAD, (ulonglong) 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, 2, 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,
@@ -7158,9 +7288,9 @@ each time the SQL thread starts.",
&max_system_variables.max_tmp_tables, 0, GET_ULONG,
REQUIRED_ARG, 32, 1, (ulonglong) ULONG_MAX, 0, 1, 0},
{"max_user_connections", OPT_MAX_USER_CONNECTIONS,
- "The maximum number of active connections for a single user (0 = no limit).",
- &max_user_connections, &max_user_connections, 0, GET_UINT,
- REQUIRED_ARG, 0, 0, UINT_MAX, 0, 1, 0},
+ "The maximum number of active connections for a single user (0 = no limit. In addition global max_user_connections counting and checking is permanently disabled).",
+ &max_user_connections, &max_user_connections, 0, GET_INT,
+ REQUIRED_ARG, 0, 0, INT_MAX, 0, 1, 0},
{"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
"After this many write locks, allow some read locks to run in between.",
&max_write_lock_count, &max_write_lock_count, 0, GET_ULONG,
@@ -7170,11 +7300,12 @@ each time the SQL thread starts.",
&global_system_variables.min_examined_row_limit,
&max_system_variables.min_examined_row_limit, 0, GET_ULONG,
REQUIRED_ARG, 0, 0, (ulonglong) 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, (ulonglong) 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,
@@ -7281,10 +7412,16 @@ each time the SQL thread starts.",
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"
-#ifndef DBUG_OFF
+ "index_merge_union, index_merge_sort_union, index_merge_intersection, "
+ "index_merge_sort_intersection, index_condition_pushdown, "
+ "derived_merge, derived_with_keys, "
+ "firstmatch, loosescan, materialization, in_to_exists, "
+ "semijoin, partial_match_rowid_merge, partial_match_table_scan, "
+ "subquery_cache, mrr, mrr_cost_based, mrr_sort_keys, "
+ "outer_join_with_cache, semijoin_with_cache, "
+ "join_cache_incremental, join_cache_hashed, join_cache_bka, "
+ "optimize_join_buffer_size"
", table_elimination"
-#endif
"} and val={on, off, default}.",
&optimizer_switch_str, &optimizer_switch_str, 0, GET_STR, REQUIRED_ARG,
/*OPTIMIZER_SWITCH_DEFAULT*/0, 0, 0, 0, 0, 0},
@@ -7307,6 +7444,11 @@ each time the SQL thread starts.",
&global_system_variables.preload_buff_size,
&max_system_variables.preload_buff_size, 0, GET_ULONG,
REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
+ {"progress_report_time", OPT_PROGRESS_REPORT_TIME,
+ "Seconds between sending progress reports to the client for slow commands. Set to 0 to disable progress reporting.",
+ &global_system_variables.progress_report_time,
+ &max_system_variables.progress_report_time,
+ 0, GET_ULONG, REQUIRED_ARG, 5, 0, ULONG_MAX, 0, 1, 0},
{"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
"Allocation block size for query parsing and execution.",
&global_system_variables.query_alloc_block_size,
@@ -7330,6 +7472,13 @@ each time the SQL thread starts.",
&query_cache_size, &query_cache_size, 0, GET_ULONG,
REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1024, 0},
#ifdef HAVE_QUERY_CACHE
+ {"query_cache_strip_comments", OPT_QUERY_CACHE_STRIP_COMMENTS,
+ "Enable and disable optimisation \"strip comment for query cache\" - "
+ "optimisation strip all comments from query while search query result "
+ "in query cache",
+ (uchar**) &opt_query_cache_strip_comments,
+ (uchar**) &opt_query_cache_strip_comments,
+ 0, GET_BOOL, REQUIRED_ARG, 0, 0, 1, 0, 1, 0},
{"query_cache_type", OPT_QUERY_CACHE_TYPE,
"0 = OFF = Don't cache or retrieve results. 1 = ON = Cache all results "
"except SELECT SQL_NO_CACHE ... queries. 2 = DEMAND = Cache only SELECT "
@@ -7354,6 +7503,11 @@ each time the SQL thread starts.",
&max_system_variables.range_alloc_block_size, 0, GET_ULONG,
REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE,
(ulonglong) 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 "
@@ -7448,6 +7602,10 @@ each time the SQL thread starts.",
"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,
@@ -7961,16 +8119,27 @@ SHOW_VAR status_vars[]= {
{"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
{"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
{"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS},
+
+ {"Handler_icp_attempts ", (char*) offsetof(STATUS_VAR, ha_icp_attempts), SHOW_LONG_STATUS},
+ {"Handler_icp_match", (char*) offsetof(STATUS_VAR, ha_icp_match), SHOW_LONG_STATUS},
+
+ {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_mrr_init_count), SHOW_LONG_STATUS},
+ {"Handler_mrr_key_refills", (char*) offsetof(STATUS_VAR, ha_mrr_key_refills_count), SHOW_LONG_STATUS},
+ {"Handler_mrr_rowid_refills", (char*) offsetof(STATUS_VAR, ha_mrr_rowid_refills_count), SHOW_LONG_STATUS},
+
{"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS},
{"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
{"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
{"Handler_read_next", (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
{"Handler_read_prev", (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
{"Handler_read_rnd", (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
+ {"Handler_read_rnd_deleted", (char*) offsetof(STATUS_VAR, ha_read_rnd_deleted_count), SHOW_LONG_STATUS},
{"Handler_read_rnd_next", (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
{"Handler_rollback", (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
{"Handler_savepoint", (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
{"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
+ {"Handler_tmp_update", (char*) offsetof(STATUS_VAR, ha_tmp_update_count), SHOW_LONG_STATUS},
+ {"Handler_tmp_write", (char*) offsetof(STATUS_VAR, ha_tmp_write_count), SHOW_LONG_STATUS},
{"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
{"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
{"Key", (char*) &show_default_keycache, SHOW_FUNC},
@@ -7987,6 +8156,7 @@ SHOW_VAR status_vars[]= {
{"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_FUNC},
{"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS},
{"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS},
+ {"Rows_tmp_read", (char*) offsetof(STATUS_VAR, rows_tmp_read), SHOW_LONGLONG_STATUS},
#ifdef HAVE_QUERY_CACHE
{"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH},
{"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH},
@@ -8044,6 +8214,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
@@ -8179,6 +8355,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;
@@ -8250,6 +8427,13 @@ static int mysql_init_variables(void)
/* set key_cache_hash.default_value = dflt_key_cache */
multi_keycache_init();
+ /* Useful MariaDB variables */
+ double2decimal((double) TIME_MAX_VALUE_SECONDS +
+ TIME_MAX_SECOND_PART/(double)TIME_SECOND_PART_FACTOR,
+ &max_seconds_for_time_type);
+ longlong2decimal(TIME_SECOND_PART_FACTOR, &time_second_part_factor);
+ my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
+
/* Set directory paths */
strmake(language, LANGUAGE, sizeof(language)-1);
strmake(mysql_real_data_home, get_relative_path(MYSQL_DATADIR),
@@ -9112,6 +9296,22 @@ mysqld_get_one_option(int optid,
case OPT_MAX_LONG_DATA_SIZE:
max_long_data_size_used= true;
break;
+
+
+ case OPT_IGNORE_DB_DIRECTORY:
+ if (*argument == 0)
+ ignore_db_dirs_reset();
+ else
+ {
+ if (push_ignored_db_dir(argument))
+ {
+ sql_print_error("Can't start server: "
+ "cannot process --ignore-db-dir=%.*s",
+ FN_REFLEN, argument);
+ return 1;
+ }
+ }
+ break;
}
return 0;
}
@@ -9255,6 +9455,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;
@@ -9317,6 +9518,8 @@ static int get_options(int *argc,char **argv)
if (!max_long_data_size_used)
max_long_data_size= global_system_variables.max_allowed_packet;
+ /* Rember if max_user_connections was 0 at startup */
+ max_user_connections_checking= max_user_connections != 0;
return 0;
}
@@ -9328,7 +9531,7 @@ static int get_options(int *argc,char **argv)
(MYSQL_SERVER_SUFFIX is set by the compilation environment)
*/
-static void set_server_version(void)
+void set_server_version(void)
{
char *end= strxmov(server_version, MYSQL_SERVER_VERSION,
MYSQL_SERVER_SUFFIX_STR, NullS);
@@ -9641,7 +9844,8 @@ static int test_if_case_insensitive(const char *dir_name)
(void) my_delete(buff2, MYF(0));
if ((file= my_create(buff, 0666, O_RDWR, MYF(0))) < 0)
{
- sql_print_warning("Can't create test file %s", buff);
+ if (!opt_help)
+ sql_print_warning("Can't create test file %s", buff);
DBUG_RETURN(-1);
}
my_close(file, MYF(0));
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 272b1759151..df392616676 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -258,18 +258,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
@@ -277,20 +279,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 */
@@ -687,7 +687,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)));
@@ -978,7 +979,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..c2b49d863a1
--- /dev/null
+++ b/sql/opt_index_cond_pushdown.cc
@@ -0,0 +1,430 @@
+#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->walk(&Item::limit_index_condition_pushdown_processor, FALSE, NULL))
+ {
+ return FALSE;
+ }
+
+ 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;
+ Field *field= item_field->field;
+ if (field->table != tbl)
+ return TRUE;
+ /*
+ The below is probably a repetition - the first part checks the
+ other two, but let's play it safe:
+ */
+ if(!field->part_of_key.is_set(keyno) ||
+ field->type() == MYSQL_TYPE_GEOMETRY ||
+ field->type() == MYSQL_TYPE_BLOB)
+ return FALSE;
+ KEY *key_info= tbl->key_info + keyno;
+ KEY_PART_INFO *key_part= key_info->key_part;
+ KEY_PART_INFO *key_part_end= key_part + key_info->key_parts;
+ for ( ; key_part < key_part_end; key_part++)
+ {
+ if (field->eq(key_part->field))
+ return !(key_part->key_part_flag & HA_PART_KEY_SEG);
+ }
+ if ((tbl->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
+ tbl->s->primary_key != MAX_KEY &&
+ tbl->s->primary_key != keyno)
+ {
+ key_info= tbl->key_info + tbl->s->primary_key;
+ key_part= key_info->key_part;
+ key_part_end= key_part + key_info->key_parts;
+ for ( ; key_part < key_part_end; key_part++)
+ {
+ /*
+ It does not make sense to use the fact that the engine can read in
+ a full field if the key if the index is built only over a part
+ of this field.
+ */
+ if (field->eq(key_part->field))
+ return !(key_part->key_part_flag & HA_PART_KEY_SEG);
+ }
+ }
+ return FALSE;
+ }
+ case Item::REF_ITEM:
+ return uses_index_fields_only(item->real_item(), tbl, keyno,
+ 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, TABLE *table, uint keyno,
+ bool other_tbls_ok, bool exclude_index)
+{
+ 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, table, keyno,
+ other_tbls_ok, 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, table, keyno,
+ other_tbls_ok, 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;
+ }
+ }
+ else
+ {
+ if (exclude_index &&
+ uses_index_fields_only(cond, table, keyno, other_tbls_ok))
+ return 0;
+ else
+ 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
+
+ DESCRIPTION
+ Try to extract and push the index condition down to table handler
+*/
+
+void push_index_cond(JOIN_TAB *tab, uint keyno)
+{
+ DBUG_ENTER("push_index_cond");
+ Item *idx_cond;
+
+ /*
+ Backported the following from MySQL 5.6:
+ 6. The index is not a clustered index. The performance improvement
+ of pushing an index condition on a clustered key is much lower
+ than on a non-clustered key. This restriction should be
+ re-evaluated when WL#6061 is implemented.
+ */
+ if ((tab->table->file->index_flags(keyno, 0, 1) &
+ HA_DO_INDEX_COND_PUSHDOWN) &&
+ optimizer_flag(tab->join->thd, OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN) &&
+ tab->join->thd->lex->sql_command != SQLCOM_UPDATE_MULTI &&
+ tab->join->thd->lex->sql_command != SQLCOM_DELETE_MULTI &&
+ tab->type != JT_CONST && tab->type != JT_SYSTEM &&
+ !(keyno == tab->table->s->primary_key && // (6)
+ tab->table->file->primary_key_is_clustered())) // (6)
+
+ {
+ DBUG_EXECUTE("where",
+ print_where(tab->select_cond, "full cond", QT_ORDINARY););
+
+ idx_cond= make_cond_for_index(tab->select_cond, tab->table, keyno,
+ tab->icp_other_tables_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).
+ */
+ tab->icp_other_tables_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= tab->idx_cond_fact_out ?
+ make_cond_remainder(tab->select_cond, tab->table, keyno,
+ tab->icp_other_tables_ok, 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 100b900e50d..df1d691ca58 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -35,7 +35,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.
@@ -60,6 +60,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
@@ -263,6 +305,11 @@ public:
uint8 part; // Which key part
uint8 maybe_null;
/*
+ The ordinal number the least significant component encountered in
+ the ranges of the SEL_ARG tree (the first component has number 1)
+ */
+ uint16 max_part_no;
+ /*
Number of children of this element in the RB-tree, plus 1 for this
element itself.
*/
@@ -295,8 +342,9 @@ public:
SEL_ARG(Field *field, uint8 part, uchar *min_value, uchar *max_value,
uint8 min_flag, uint8 max_flag, uint8 maybe_flag);
SEL_ARG(enum Type type_arg)
- :min_flag(0),elements(1),use_count(1),left(0),right(0),next_key_part(0),
- color(BLACK), type(type_arg)
+ :min_flag(0), max_part_no(0) /* first key part means 1. 0 mean 'no parts'*/,
+ elements(1),use_count(1),left(0),right(0),
+ next_key_part(0), color(BLACK), type(type_arg)
{}
inline bool is_same(SEL_ARG *arg)
{
@@ -404,6 +452,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))))
@@ -503,6 +552,14 @@ public:
increment_use_count(1);
use_count++;
}
+ void incr_refs_all()
+ {
+ for (SEL_ARG *pos=first(); pos ; pos=pos->next)
+ {
+ pos->increment_use_count(1);
+ }
+ use_count++;
+ }
void free_tree()
{
for (SEL_ARG *pos=first(); pos ; pos=pos->next)
@@ -564,7 +621,100 @@ public:
class SEL_IMERGE;
+#define CLONE_KEY1_MAYBE 1
+#define CLONE_KEY2_MAYBE 2
+#define swap_clone_flag(A) ((A & 1) << 1) | ((A & 2) >> 1)
+
+/*
+ While objects of the class SEL_ARG represent ranges for indexes or
+ index infixes (including ranges for index prefixes and index suffixes),
+ objects of the class SEL_TREE represent AND/OR formulas of such ranges.
+ Currently an AND/OR formula represented by a SEL_TREE object can have
+ at most three levels:
+
+ <SEL_TREE formula> ::=
+ [ <SEL_RANGE_TREE formula> AND ]
+ [ <SEL_IMERGE formula> [ AND <SEL_IMERGE formula> ...] ]
+
+ <SEL_RANGE_TREE formula> ::=
+ <SEL_ARG formula> [ AND <SEL_ARG_formula> ... ]
+
+ <SEL_IMERGE formula> ::=
+ <SEL_RANGE_TREE formula> [ OR <SEL_RANGE_TREE formula> ]
+
+ As we can see from the above definitions:
+ - SEL_RANGE_TREE formula is a conjunction of SEL_ARG formulas
+ - SEL_IMERGE formula is a disjunction of SEL_RANGE_TREE formulas
+ - SEL_TREE formula is a conjunction of a SEL_RANGE_TREE formula
+ and SEL_IMERGE formulas.
+ It's required above that a SEL_TREE formula has at least one conjunct.
+
+ Usually we will consider normalized SEL_RANGE_TREE formulas where we use
+ TRUE as conjunct members for those indexes whose SEL_ARG trees are empty.
+
+ We will call an SEL_TREE object simply 'tree'.
+ The part of a tree that represents SEL_RANGE_TREE formula is called
+ 'range part' of the tree while the remaining part is called 'imerge part'.
+ If a tree contains only a range part then we call such a tree 'range tree'.
+ Components of a range tree that represent SEL_ARG formulas are called ranges.
+ If a tree does not contain any range part we call such a tree 'imerge tree'.
+ Components of the imerge part of a tree that represent SEL_IMERGE formula
+ are called imerges.
+
+ Usually we'll designate:
+ SEL_TREE formulas by T_1,...,T_k
+ SEL_ARG formulas by R_1,...,R_k
+ SEL_RANGE_TREE formulas by RT_1,...,RT_k
+ SEL_IMERGE formulas by M_1,...,M_k
+ Accordingly we'll use:
+ t_1,...,t_k - to designate trees representing T_1,...,T_k
+ r_1,...,r_k - to designate ranges representing R_1,...,R_k
+ rt_1,...,r_tk - to designate range trees representing RT_1,...,RT_k
+ m_1,...,m_k - to designate imerges representing M_1,...,M_k
+
+ SEL_TREE objects are usually built from WHERE conditions or
+ ON expressions.
+ A SEL_TREE object always represents an inference of the condition it is
+ built from. Therefore, if a row satisfies a SEL_TREE formula it also
+ satisfies the condition it is built from.
+
+ The following transformations of tree t representing SEL_TREE formula T
+ yield a new tree t1 thar represents an inference of T: T=>T1.
+ (1) remove any of SEL_ARG tree from the range part of t
+ (2) remove any imerge from the tree t
+ (3) remove any of SEL_ARG tree from any range tree contained
+ in any imerge of tree
+
+ Since the basic blocks of any SEL_TREE objects are ranges, SEL_TREE
+ objects in many cases can be effectively used to filter out a big part
+ of table rows that do not satisfy WHERE/IN conditions utilizing
+ only single or multiple range index scans.
+
+ A single range index scan is constructed for a range tree that contains
+ only one SEL_ARG object for an index or an index prefix.
+ An index intersection scan can be constructed for a range tree
+ that contains several SEL_ARG objects. Currently index intersection
+ scans are constructed only for single-point ranges.
+ An index merge scan is constructed for a imerge tree that contains only
+ one imerge. If range trees of this imerge contain only single-point merges
+ than a union of index intersections can be built.
+
+ Usually the tree built by the range optimizer for a query table contains
+ more than one range in the range part, and additionally may contain some
+ imerges in the imerge part. The range optimizer evaluates all of them one
+ by one and chooses the range or the imerge that provides the cheapest
+ single or multiple range index scan of the table. According to rules
+ (1)-(3) this scan always filter out only those rows that do not satisfy
+ the query conditions.
+
+ For any condition the SEL_TREE object for it is built in a bottom up
+ manner starting from the range trees for the predicates. The tree_and
+ function builds a tree for any conjunction of formulas from the trees
+ for its conjuncts. The tree_or function builds a tree for any disjunction
+ of formulas from the trees for its disjuncts.
+*/
+
class SEL_TREE :public Sql_alloc
{
public:
@@ -580,7 +730,7 @@ public:
keys_map.clear_all();
bzero((char*) keys,sizeof(keys));
}
- SEL_TREE(SEL_TREE *arg, RANGE_OPT_PARAM *param);
+ SEL_TREE(SEL_TREE *arg, bool without_merges, RANGE_OPT_PARAM *param);
/*
Note: there may exist SEL_TREE objects with sel_tree->type=KEY and
keys[i]=0 for all i. (SergeyP: it is not clear whether there is any
@@ -600,9 +750,15 @@ public:
key_map ror_scans_map; /* bitmask of ROR scan-able elements in keys */
uint n_ror_scans; /* number of set bits in ror_scans_map */
+ struct st_index_scan_info **index_scans; /* list of index scans */
+ struct st_index_scan_info **index_scans_end; /* last index scan */
+
struct st_ror_scan_info **ror_scans; /* list of ROR key scans */
struct st_ror_scan_info **ror_scans_end; /* last ROR scan */
/* Note that #records for each key scan is stored in table->quick_rows */
+
+ bool without_ranges() { return keys_map.is_clear_all(); }
+ bool without_imerges() { return merges.is_empty(); }
};
class RANGE_OPT_PARAM
@@ -633,6 +789,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;
/*
@@ -640,19 +801,27 @@ 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;
+ KEY_PART *key[MAX_KEY]; /* First key parts of keys used in the query */
};
class PARAM : public RANGE_OPT_PARAM
{
public:
- KEY_PART *key[MAX_KEY]; /* First key parts of keys used in the query */
+ ha_rows quick_rows[MAX_KEY];
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;
@@ -671,13 +840,16 @@ public:
uint8 first_null_comp; /* first null component if any, 0 - otherwise */
};
+
class TABLE_READ_PLAN;
class TRP_RANGE;
class TRP_ROR_INTERSECT;
class TRP_ROR_UNION;
- class TRP_ROR_INDEX_MERGE;
+ class TRP_INDEX_INTERSECT;
+ class TRP_INDEX_MERGE;
class TRP_GROUP_MIN_MAX;
+struct st_index_scan_info;
struct st_ror_scan_info;
static SEL_TREE * get_mm_parts(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
@@ -689,20 +861,22 @@ 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,
double read_time);
static
+TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree,
+ double read_time);
+static
TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
double read_time,
bool *are_all_covering);
@@ -713,7 +887,12 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
static
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
double read_time);
-static TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
+static
+TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge,
+ TRP_INDEX_MERGE *imerge_trp,
+ double read_time);
+static
+TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
#ifndef DBUG_OFF
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
@@ -724,11 +903,15 @@ static void print_ror_scans_arr(TABLE *table, const char *msg,
static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg);
#endif
-static SEL_TREE *tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
-static SEL_TREE *tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
+static SEL_TREE *tree_and(RANGE_OPT_PARAM *param,
+ SEL_TREE *tree1, SEL_TREE *tree2);
+static SEL_TREE *tree_or(RANGE_OPT_PARAM *param,
+ SEL_TREE *tree1,SEL_TREE *tree2);
static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2);
-static SEL_ARG *key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2);
-static SEL_ARG *key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
+static SEL_ARG *key_or(RANGE_OPT_PARAM *param,
+ SEL_ARG *key1, SEL_ARG *key2);
+static SEL_ARG *key_and(RANGE_OPT_PARAM *param,
+ SEL_ARG *key1, SEL_ARG *key2,
uint clone_flag);
static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1);
bool get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
@@ -739,7 +922,25 @@ static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
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"
+
+static bool sel_trees_have_common_keys(SEL_TREE *tree1, SEL_TREE *tree2,
+ key_map *common_keys);
+static void eliminate_single_tree_imerges(RANGE_OPT_PARAM *param,
+ SEL_TREE *tree);
+
+static bool sel_trees_can_be_ored(RANGE_OPT_PARAM* param,
+ SEL_TREE *tree1, SEL_TREE *tree2,
+ key_map *common_keys);
+static bool sel_trees_must_be_ored(RANGE_OPT_PARAM* param,
+ SEL_TREE *tree1, SEL_TREE *tree2,
+ key_map common_keys);
+static int and_range_trees(RANGE_OPT_PARAM *param,
+ SEL_TREE *tree1, SEL_TREE *tree2,
+ SEL_TREE *result);
+static bool remove_nonrange_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree);
/*
@@ -771,23 +972,39 @@ public:
trees_next(trees),
trees_end(trees + PREALLOCED_TREES)
{}
- SEL_IMERGE (SEL_IMERGE *arg, RANGE_OPT_PARAM *param);
+ SEL_IMERGE (SEL_IMERGE *arg, uint cnt, RANGE_OPT_PARAM *param);
int or_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree);
- int or_sel_tree_with_checks(RANGE_OPT_PARAM *param, SEL_TREE *new_tree);
- int or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, SEL_IMERGE* imerge);
+ bool have_common_keys(RANGE_OPT_PARAM *param, SEL_TREE *tree);
+ int and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree,
+ SEL_IMERGE *new_imerge);
+ int or_sel_tree_with_checks(RANGE_OPT_PARAM *param,
+ uint n_init_trees,
+ SEL_TREE *new_tree,
+ bool is_first_check_pass,
+ bool *is_last_check_pass);
+ int or_sel_imerge_with_checks(RANGE_OPT_PARAM *param,
+ uint n_init_trees,
+ SEL_IMERGE* imerge,
+ bool is_first_check_pass,
+ bool *is_last_check_pass);
};
/*
- Add SEL_TREE to this index_merge without any checks,
+ Add a range tree to the range trees of this imerge
- NOTES
- This function implements the following:
- (x_1||...||x_N) || t = (x_1||...||x_N||t), where x_i, t are SEL_TREEs
+ SYNOPSIS
+ or_sel_tree()
+ param Context info for the operation
+ tree SEL_TREE to add to this imerge
+
+ DESCRIPTION
+ The function just adds the range tree 'tree' to the range trees
+ of this imerge.
RETURN
- 0 - OK
- -1 - Out of memory.
+ 0 if the operation is success
+ -1 if the function runs out memory
*/
int SEL_IMERGE::or_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree)
@@ -812,96 +1029,302 @@ int SEL_IMERGE::or_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree)
/*
- Perform OR operation on this SEL_IMERGE and supplied SEL_TREE new_tree,
- combining new_tree with one of the trees in this SEL_IMERGE if they both
- have SEL_ARGs for the same key.
+ Check if any of the range trees of this imerge intersects with a given tree
SYNOPSIS
- or_sel_tree_with_checks()
- param PARAM from SQL_SELECT::test_quick_select
- new_tree SEL_TREE with type KEY or KEY_SMALLER.
+ have_common_keys()
+ param Context info for the function
+ tree SEL_TREE intersection with the imerge range trees is checked for
- NOTES
- This does the following:
- (t_1||...||t_k)||new_tree =
- either
- = (t_1||...||t_k||new_tree)
- or
- = (t_1||....||(t_j|| new_tree)||...||t_k),
-
- where t_i, y are SEL_TREEs.
- new_tree is combined with the first t_j it has a SEL_ARG on common
- key with. As a consequence of this, choice of keys to do index_merge
- read may depend on the order of conditions in WHERE part of the query.
+ DESCRIPTION
+ The function checks whether there is any range tree rt_i in this imerge
+ such that there are some indexes for which ranges are defined in both
+ rt_i and the range part of the SEL_TREE tree.
+ To check this the function calls the function sel_trees_have_common_keys.
+
+ RETURN
+ TRUE if there are such range trees in this imerge
+ FALSE otherwise
+*/
+
+bool SEL_IMERGE::have_common_keys(RANGE_OPT_PARAM *param, SEL_TREE *tree)
+{
+ for (SEL_TREE** or_tree= trees, **bound= trees_next;
+ or_tree != bound; or_tree++)
+ {
+ key_map common_keys;
+ if (sel_trees_have_common_keys(*or_tree, tree, &common_keys))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ Perform AND operation for this imerge and the range part of a tree
+
+ SYNOPSIS
+ and_sel_tree()
+ param Context info for the operation
+ tree SEL_TREE for the second operand of the operation
+ new_imerge OUT imerge for the result of the operation
+
+ DESCRIPTION
+ This function performs AND operation for this imerge m and the
+ range part of the SEL_TREE tree rt. In other words the function
+ pushes rt into this imerge. The resulting imerge is returned in
+ the parameter new_imerge.
+ If this imerge m represent the formula
+ RT_1 OR ... OR RT_k
+ then the resulting imerge of the function represents the formula
+ (RT_1 AND RT) OR ... OR (RT_k AND RT)
+ The function calls the function and_range_trees to construct the
+ range tree representing (RT_i AND RT).
+
+ NOTE
+ The function may return an empty imerge without any range trees.
+ This happens when each call of and_range_trees returns an
+ impossible range tree (SEL_TREE::IMPOSSIBLE).
+ Example: (key1 < 2 AND key2 > 10) AND (key1 > 4 OR key2 < 6).
+
RETURN
- 0 OK
- 1 One of the trees was combined with new_tree to SEL_TREE::ALWAYS,
- and (*this) should be discarded.
- -1 An error occurred.
+ 0 if the operation is a success
+ -1 otherwise: there is not enough memory to perform the operation
*/
-int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, SEL_TREE *new_tree)
+int SEL_IMERGE::and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree,
+ SEL_IMERGE *new_imerge)
{
- for (SEL_TREE** tree = trees;
- tree != trees_next;
- tree++)
+ for (SEL_TREE** or_tree= trees; or_tree != trees_next; or_tree++)
{
- if (sel_trees_can_be_ored(*tree, new_tree, param))
+ SEL_TREE *res_or_tree= 0;
+ SEL_TREE *and_tree= 0;
+ if (!(res_or_tree= new SEL_TREE()) ||
+ !(and_tree= new SEL_TREE(tree, TRUE, param)))
+ return (-1);
+ if (!and_range_trees(param, *or_tree, and_tree, res_or_tree))
{
- *tree = tree_or(param, *tree, new_tree);
- if (!*tree)
- return 1;
- if (((*tree)->type == SEL_TREE::MAYBE) ||
- ((*tree)->type == SEL_TREE::ALWAYS))
+ if (new_imerge->or_sel_tree(param, res_or_tree))
+ return (-1);
+ }
+ }
+ return 0;
+}
+
+
+/*
+ Perform OR operation on this imerge and the range part of a tree
+
+ SYNOPSIS
+ or_sel_tree_with_checks()
+ param Context info for the operation
+ n_trees Number of trees in this imerge to check for oring
+ tree SEL_TREE whose range part is to be ored
+ is_first_check_pass <=> the first call of the function for this imerge
+ is_last_check_pass OUT <=> no more calls of the function for this imerge
+
+ DESCRIPTION
+ The function performs OR operation on this imerge m and the range part
+ of the SEL_TREE tree rt. It always replaces this imerge with the result
+ of the operation.
+
+ The operation can be performed in two different modes: with
+ is_first_check_pass==TRUE and is_first_check_pass==FALSE, transforming
+ this imerge differently.
+
+ Given this imerge represents the formula
+ RT_1 OR ... OR RT_k:
+
+ 1. In the first mode, when is_first_check_pass==TRUE :
+ 1.1. If rt must be ored(see the function sel_trees_must_be_ored) with
+ some rt_j (there may be only one such range tree in the imerge)
+ then the function produces an imerge representing the formula
+ RT_1 OR ... OR (RT_j OR RT) OR ... OR RT_k,
+ where the tree for (RT_j OR RT) is built by oring the pairs
+ of SEL_ARG trees for the corresponding indexes
+ 1.2. Otherwise the function produces the imerge representing the formula:
+ RT_1 OR ... OR RT_k OR RT.
+
+ 2. In the second mode, when is_first_check_pass==FALSE :
+ 2.1. For each rt_j in the imerge that can be ored (see the function
+ sel_trees_can_be_ored) with rt the function replaces rt_j for a
+ range tree such that for each index for which ranges are defined
+ in both in rt_j and rt the tree contains the result of oring of
+ these ranges.
+ 2.2. In other cases the function does not produce any imerge.
+
+ When is_first_check==TRUE the function returns FALSE in the parameter
+ is_last_check_pass if there is no rt_j such that rt_j can be ored with rt,
+ but, at the same time, it's not true that rt_j must be ored with rt.
+ When is_first_check==FALSE the function always returns FALSE in the
+ parameter is_last_check_pass.
+
+ RETURN
+ 1 The result of oring of rt_j and rt that must be ored returns the
+ the range tree with type==SEL_TREE::ALWAYS
+ (in this case the imerge m should be discarded)
+ -1 The function runs out of memory
+ 0 in all other cases
+*/
+
+int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param,
+ uint n_trees,
+ SEL_TREE *tree,
+ bool is_first_check_pass,
+ bool *is_last_check_pass)
+{
+ bool was_ored= FALSE;
+ *is_last_check_pass= is_first_check_pass;
+ SEL_TREE** or_tree = trees;
+ for (uint i= 0; i < n_trees; i++, or_tree++)
+ {
+ SEL_TREE *result= 0;
+ key_map result_keys;
+ key_map ored_keys;
+ if (sel_trees_can_be_ored(param, *or_tree, tree, &ored_keys))
+ {
+ bool must_be_ored= sel_trees_must_be_ored(param, *or_tree, tree,
+ ored_keys);
+ if (must_be_ored || !is_first_check_pass)
+ {
+ result_keys.clear_all();
+ result= *or_tree;
+ for (uint key_no= 0; key_no < param->keys; key_no++)
+ {
+ if (!ored_keys.is_set(key_no))
+ {
+ result->keys[key_no]= 0;
+ continue;
+ }
+ SEL_ARG *key1= (*or_tree)->keys[key_no];
+ SEL_ARG *key2= tree->keys[key_no];
+ key2->incr_refs();
+ if ((result->keys[key_no]= key_or(param, key1, key2)))
+ {
+
+ result_keys.set_bit(key_no);
+#ifdef EXTRA_DEBUG
+ if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
+ {
+ key1= result->keys[key_no];
+ (key1)->test_use_count(key1);
+ }
+#endif
+ }
+ }
+ }
+ else if(is_first_check_pass)
+ *is_last_check_pass= FALSE;
+ }
+
+ if (result)
+ {
+ result->keys_map= result_keys;
+ if (result_keys.is_clear_all())
+ result->type= SEL_TREE::ALWAYS;
+ if ((result->type == SEL_TREE::MAYBE) ||
+ (result->type == SEL_TREE::ALWAYS))
return 1;
/* SEL_TREE::IMPOSSIBLE is impossible here */
- return 0;
+ *or_tree= result;
+ was_ored= TRUE;
}
}
+ if (was_ored)
+ return 0;
- /* New tree cannot be combined with any of existing trees. */
- return or_sel_tree(param, new_tree);
+ if (is_first_check_pass && !*is_last_check_pass &&
+ !(tree= new SEL_TREE(tree, FALSE, param)))
+ return (-1);
+ return or_sel_tree(param, tree);
}
/*
- Perform OR operation on this index_merge and supplied index_merge list.
+ Perform OR operation on this imerge and and another imerge
+ SYNOPSIS
+ or_sel_imerge_with_checks()
+ param Context info for the operation
+ n_trees Number of trees in this imerge to check for oring
+ imerge The second operand of the operation
+ is_first_check_pass <=> the first call of the function for this imerge
+ is_last_check_pass OUT <=> no more calls of the function for this imerge
+
+ DESCRIPTION
+ For each range tree rt from 'imerge' the function calls the method
+ SEL_IMERGE::or_sel_tree_with_checks that performs OR operation on this
+ SEL_IMERGE object m and the tree rt. The mode of the operation is
+ specified by the parameter is_first_check_pass. Each call of
+ SEL_IMERGE::or_sel_tree_with_checks transforms this SEL_IMERGE object m.
+ The function returns FALSE in the prameter is_last_check_pass if
+ at least one of the calls of SEL_IMERGE::or_sel_tree_with_checks
+ returns FALSE as the value of its last parameter.
+
RETURN
- 0 - OK
- 1 - One of conditions in result is always TRUE and this SEL_IMERGE
- should be discarded.
- -1 - An error occurred
+ 1 One of the calls of SEL_IMERGE::or_sel_tree_with_checks returns 1.
+ (in this case the imerge m should be discarded)
+ -1 The function runs out of memory
+ 0 in all other cases
*/
-int SEL_IMERGE::or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, SEL_IMERGE* imerge)
-{
- for (SEL_TREE** tree= imerge->trees;
- tree != imerge->trees_next;
- tree++)
- {
- if (or_sel_tree_with_checks(param, *tree))
- return 1;
+int SEL_IMERGE::or_sel_imerge_with_checks(RANGE_OPT_PARAM *param,
+ uint n_trees,
+ SEL_IMERGE* imerge,
+ bool is_first_check_pass,
+ bool *is_last_check_pass)
+{
+ *is_last_check_pass= TRUE;
+ SEL_TREE** tree= imerge->trees;
+ SEL_TREE** tree_end= imerge->trees_next;
+ for ( ; tree < tree_end; tree++)
+ {
+ uint rc;
+ bool is_last= TRUE;
+ rc= or_sel_tree_with_checks(param, n_trees, *tree,
+ is_first_check_pass, &is_last);
+ if (!is_last)
+ *is_last_check_pass= FALSE;
+ if (rc)
+ return rc;
}
return 0;
}
-SEL_TREE::SEL_TREE(SEL_TREE *arg, RANGE_OPT_PARAM *param): Sql_alloc()
+/*
+ Copy constructor for SEL_TREE objects
+
+ SYNOPSIS
+ SEL_TREE
+ arg The source tree for the constructor
+ without_merges <=> only the range part of the tree arg is copied
+ param Context info for the operation
+
+ DESCRIPTION
+ The constructor creates a full copy of the SEL_TREE arg if
+ the prameter without_merges==FALSE. Otherwise a tree is created
+ that contains the copy only of the range part of the tree arg.
+*/
+
+SEL_TREE::SEL_TREE(SEL_TREE *arg, bool without_merges,
+ RANGE_OPT_PARAM *param): Sql_alloc()
{
keys_map= arg->keys_map;
type= arg->type;
- for (int idx= 0; idx < MAX_KEY; idx++)
+ for (uint idx= 0; idx < param->keys; idx++)
{
if ((keys[idx]= arg->keys[idx]))
- keys[idx]->increment_use_count(1);
+ keys[idx]->incr_refs_all();
}
+ if (without_merges)
+ return;
+
List_iterator<SEL_IMERGE> it(arg->merges);
for (SEL_IMERGE *el= it++; el; el= it++)
{
- SEL_IMERGE *merge= new SEL_IMERGE(el, param);
+ SEL_IMERGE *merge= new SEL_IMERGE(el, 0, param);
if (!merge || merge->trees == merge->trees_next)
{
merges.empty();
@@ -912,7 +1335,23 @@ SEL_TREE::SEL_TREE(SEL_TREE *arg, RANGE_OPT_PARAM *param): Sql_alloc()
}
-SEL_IMERGE::SEL_IMERGE (SEL_IMERGE *arg, RANGE_OPT_PARAM *param) : Sql_alloc()
+/*
+ Copy constructor for SEL_IMERGE objects
+
+ SYNOPSIS
+ SEL_IMERGE
+ arg The source imerge for the constructor
+ cnt How many trees from arg are to be copied
+ param Context info for the operation
+
+ DESCRIPTION
+ The cnt==0 then the constructor creates a full copy of the
+ imerge arg. Otherwise only the first cnt trees of the imerge
+ are copied.
+*/
+
+SEL_IMERGE::SEL_IMERGE(SEL_IMERGE *arg, uint cnt,
+ RANGE_OPT_PARAM *param) : Sql_alloc()
{
uint elements= (arg->trees_end - arg->trees);
if (elements > PREALLOCED_TREES)
@@ -924,13 +1363,13 @@ SEL_IMERGE::SEL_IMERGE (SEL_IMERGE *arg, RANGE_OPT_PARAM *param) : Sql_alloc()
else
trees= &trees_prealloced[0];
- trees_next= trees;
+ trees_next= trees + (cnt ? cnt : arg->trees_next-arg->trees);
trees_end= trees + elements;
- for (SEL_TREE **tree = trees, **arg_tree= arg->trees; tree < trees_end;
+ for (SEL_TREE **tree = trees, **arg_tree= arg->trees; tree < trees_next;
tree++, arg_tree++)
{
- if (!(*tree= new SEL_TREE(*arg_tree, param)))
+ if (!(*tree= new SEL_TREE(*arg_tree, TRUE, param)))
goto mem_err;
}
@@ -944,7 +1383,19 @@ mem_err:
/*
- Perform AND operation on two index_merge lists and store result in *im1.
+ Perform AND operation on two imerge lists
+
+ SYNOPSIS
+ imerge_list_and_list()
+ param Context info for the operation
+ im1 The first imerge list for the operation
+ im2 The second imerge list for the operation
+
+ DESCRIPTION
+ The function just appends the imerge list im2 to the imerge list im1
+
+ RETURN VALUE
+ none
*/
inline void imerge_list_and_list(List<SEL_IMERGE> *im1, List<SEL_IMERGE> *im2)
@@ -954,73 +1405,254 @@ inline void imerge_list_and_list(List<SEL_IMERGE> *im1, List<SEL_IMERGE> *im2)
/*
- Perform OR operation on 2 index_merge lists, storing result in first list.
-
- NOTES
- The following conversion is implemented:
- (a_1 &&...&& a_N)||(b_1 &&...&& b_K) = AND_i,j(a_i || b_j) =>
- => (a_1||b_1).
-
- i.e. all conjuncts except the first one are currently dropped.
- This is done to avoid producing N*K ways to do index_merge.
-
- If (a_1||b_1) produce a condition that is always TRUE, NULL is returned
- and index_merge is discarded (while it is actually possible to try
- harder).
-
- As a consequence of this, choice of keys to do index_merge read may depend
- on the order of conditions in WHERE part of the query.
+ Perform OR operation on two imerge lists
+ SYNOPSIS
+ imerge_list_or_list()
+ param Context info for the operation
+ im1 The first imerge list for the operation
+ im2 The second imerge list for the operation
+
+ DESCRIPTION
+ Assuming that the first imerge list represents the formula
+ F1= M1_1 AND ... AND M1_k1
+ while the second imerge list represents the formula
+ F2= M2_1 AND ... AND M2_k2,
+ where M1_i= RT1_i_1 OR ... OR RT1_i_l1i (i in [1..k1])
+ and M2_i = RT2_i_1 OR ... OR RT2_i_l2i (i in [1..k2]),
+ the function builds a list of imerges for some formula that can be
+ inferred from the formula (F1 OR F2).
+
+ More exactly the function builds imerges for the formula (M1_1 OR M2_1).
+ Note that
+ (F1 OR F2) = (M1_1 AND ... AND M1_k1) OR (M2_1 AND ... AND M2_k2) =
+ AND (M1_i OR M2_j) (i in [1..k1], j in [1..k2]) =>
+ M1_1 OR M2_1.
+ So (M1_1 OR M2_1) is indeed an inference formula for (F1 OR F2).
+
+ To build imerges for the formula (M1_1 OR M2_1) the function invokes,
+ possibly twice, the method SEL_IMERGE::or_sel_imerge_with_checks
+ for the imerge m1_1.
+ At its first invocation the method SEL_IMERGE::or_sel_imerge_with_checks
+ performs OR operation on the imerge m1_1 and the range tree rt2_1_1 by
+ calling SEL_IMERGE::or_sel_tree_with_checks with is_first_pass_check==TRUE.
+ The resulting imerge of the operation is ored with the next range tree of
+ the imerge m2_1. This oring continues until the last range tree from
+ m2_1 has been ored.
+ At its second invocation the method SEL_IMERGE::or_sel_imerge_with_checks
+ performs the same sequence of OR operations, but now calling
+ SEL_IMERGE::or_sel_tree_with_checks with is_first_pass_check==FALSE.
+
+ The imerges that the operation produces replace those in the list im1
+
RETURN
- 0 OK, result is stored in *im1
- other Error, both passed lists are unusable
+ 0 if the operation is a success
+ -1 if the function has run out of memory
*/
int imerge_list_or_list(RANGE_OPT_PARAM *param,
List<SEL_IMERGE> *im1,
List<SEL_IMERGE> *im2)
{
+
+ uint rc;
+ bool is_last_check_pass= FALSE;
+
SEL_IMERGE *imerge= im1->head();
+ uint elems= imerge->trees_next-imerge->trees;
im1->empty();
im1->push_back(imerge);
- return imerge->or_sel_imerge_with_checks(param, im2->head());
+ rc= imerge->or_sel_imerge_with_checks(param, elems, im2->head(),
+ TRUE, &is_last_check_pass);
+ if (rc)
+ {
+ if (rc == 1)
+ {
+ im1->empty();
+ rc= 0;
+ }
+ return rc;
+ }
+
+ if (!is_last_check_pass)
+ {
+ SEL_IMERGE* new_imerge= new SEL_IMERGE(imerge, elems, param);
+ if (new_imerge)
+ {
+ is_last_check_pass= TRUE;
+ rc= new_imerge->or_sel_imerge_with_checks(param, elems, im2->head(),
+ FALSE, &is_last_check_pass);
+ if (!rc)
+ im1->push_back(new_imerge);
+ }
+ }
+ return rc;
}
/*
- Perform OR operation on index_merge list and key tree.
+ Perform OR operation for each imerge from a list and the range part of a tree
+ SYNOPSIS
+ imerge_list_or_tree()
+ param Context info for the operation
+ merges The list of imerges to be ored with the range part of tree
+ tree SEL_TREE whose range part is to be ored with the imerges
+
+ DESCRIPTION
+ For each imerge mi from the list 'merges' the function performes OR
+ operation with mi and the range part of 'tree' rt, producing one or
+ two imerges.
+
+ Given the merge mi represent the formula RTi_1 OR ... OR RTi_k,
+ the function forms the merges by the following rules:
+
+ 1. If rt cannot be ored with any of the trees rti the function just
+ produces an imerge that represents the formula
+ RTi_1 OR ... RTi_k OR RT.
+ 2. If there exist a tree rtj that must be ored with rt the function
+ produces an imerge the represents the formula
+ RTi_1 OR ... OR (RTi_j OR RT) OR ... OR RTi_k,
+ where the range tree for (RTi_j OR RT) is constructed by oring the
+ SEL_ARG trees that must be ored.
+ 3. For each rti_j that can be ored with rt the function produces
+ the new tree rti_j' and substitutes rti_j for this new range tree.
+
+ In any case the function removes mi from the list and then adds all
+ produced imerges.
+
+ To build imerges by rules 1-3 the function calls the method
+ SEL_IMERGE::or_sel_tree_with_checks, possibly twice. With the first
+ call it passes TRUE for the third parameter of the function.
+ At this first call imerges by rules 1-2 are built. If the call
+ returns FALSE as the return value of its fourth parameter then the
+ function are called for the second time. At this call the imerge
+ of rule 3 is produced.
+
+ If a call of SEL_IMERGE::or_sel_tree_with_checks returns 1 then
+ then it means that the produced tree contains an always true
+ range tree and the whole imerge can be discarded.
+
RETURN
- 0 OK, result is stored in *im1.
- other Error
+ 1 if no imerges are produced
+ 0 otherwise
*/
+static
int imerge_list_or_tree(RANGE_OPT_PARAM *param,
- List<SEL_IMERGE> *im1,
+ List<SEL_IMERGE> *merges,
SEL_TREE *tree)
{
+
SEL_IMERGE *imerge;
- List_iterator<SEL_IMERGE> it(*im1);
- bool tree_used= FALSE;
+ List<SEL_IMERGE> additional_merges;
+ List_iterator<SEL_IMERGE> it(*merges);
+
while ((imerge= it++))
{
- SEL_TREE *or_tree;
- if (tree_used)
+ bool is_last_check_pass;
+ int rc= 0;
+ int rc1= 0;
+ SEL_TREE *or_tree= new SEL_TREE (tree, FALSE, param);
+ if (or_tree)
{
- or_tree= new SEL_TREE (tree, param);
- if (!or_tree ||
- (or_tree->keys_map.is_clear_all() && or_tree->merges.is_empty()))
- return FALSE;
+ uint elems= imerge->trees_next-imerge->trees;
+ rc= imerge->or_sel_tree_with_checks(param, elems, or_tree,
+ TRUE, &is_last_check_pass);
+ if (!is_last_check_pass)
+ {
+ SEL_IMERGE *new_imerge= new SEL_IMERGE(imerge, elems, param);
+ if (new_imerge)
+ {
+ rc1= new_imerge->or_sel_tree_with_checks(param, elems, or_tree,
+ FALSE, &is_last_check_pass);
+ if (!rc1)
+ additional_merges.push_back(new_imerge);
+ }
+ }
}
- else
- or_tree= tree;
-
- if (imerge->or_sel_tree_with_checks(param, or_tree))
+ if (rc || rc1 || !or_tree)
it.remove();
- tree_used= TRUE;
}
- return im1->is_empty();
+
+ merges->concat(&additional_merges);
+ return merges->is_empty();
+}
+
+
+/*
+ Perform pushdown operation of the range part of a tree into given imerges
+
+ SYNOPSIS
+ imerge_list_and_tree()
+ param Context info for the operation
+ merges IN/OUT List of imerges to push the range part of 'tree' into
+ tree SEL_TREE whose range part is to be pushed into imerges
+ replace if the pushdow operation for a imerge is a success
+ then the original imerge is replaced for the result
+ of the pushdown
+
+ DESCRIPTION
+ For each imerge from the list merges the function pushes the range part
+ rt of 'tree' into the imerge.
+ More exactly if the imerge mi from the list represents the formula
+ RTi_1 OR ... OR RTi_k
+ the function bulds a new imerge that represents the formula
+ (RTi_1 AND RT) OR ... OR (RTi_k AND RT)
+ and adds this imerge to the list merges.
+ To perform this pushdown operation the function calls the method
+ SEL_IMERGE::and_sel_tree.
+ For any imerge mi the new imerge is not created if for each pair of
+ trees rti_j and rt the intersection of the indexes with defined ranges
+ is empty.
+ If the result of the pushdown operation for the imerge mi returns an
+ imerge with no trees then then not only nothing is added to the list
+ merges but mi itself is removed from the list.
+
+ TODO
+ Optimize the code in order to not create new SEL_IMERGE and new SER_TREE
+ objects when 'replace' is TRUE. (Currently this function is called always
+ with this parameter equal to TRUE.)
+
+ RETURN
+ 1 if no imerges are left in the list merges
+ 0 otherwise
+*/
+
+static
+int imerge_list_and_tree(RANGE_OPT_PARAM *param,
+ List<SEL_IMERGE> *merges,
+ SEL_TREE *tree,
+ bool replace)
+{
+ SEL_IMERGE *imerge;
+ SEL_IMERGE *new_imerge= NULL;
+ List<SEL_IMERGE> new_merges;
+ List_iterator<SEL_IMERGE> it(*merges);
+
+ while ((imerge= it++))
+ {
+ if (!new_imerge)
+ new_imerge= new SEL_IMERGE();
+ if (imerge->have_common_keys(param, tree) &&
+ new_imerge && !imerge->and_sel_tree(param, tree, new_imerge))
+ {
+ if (new_imerge->trees == new_imerge->trees_next)
+ it.remove();
+ else
+ {
+ if (replace)
+ it.replace(new_imerge);
+ else
+ new_merges.push_back(new_imerge);
+ new_imerge= NULL;
+ }
+ }
+ }
+ imerge_list_and_list(&new_merges, merges);
+ *merges= new_merges;
+ return merges->is_empty();
}
@@ -1054,7 +1686,7 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
select->read_tables=read_tables;
select->const_tables=const_tables;
select->head=head;
- select->cond=conds;
+ select->cond= conds;
if (head->sort.io_cache)
{
@@ -1068,7 +1700,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);
@@ -1102,25 +1734,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)
{
@@ -1135,12 +1764,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);
@@ -1148,6 +1777,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");
@@ -1181,7 +1824,7 @@ QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
DBUG_PRINT("info", ("Freeing separate handler 0x%lx (free: %d)", (long) file,
free_file));
file->ha_external_lock(current_thd, F_UNLCK);
- file->close();
+ file->ha_close();
delete file;
}
}
@@ -1190,17 +1833,22 @@ 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;
}
+/*
+ QUICK_INDEX_SORT_SELECT works as follows:
+ - Do index scans, accumulate rowids in the Unique object
+ (Unique will also sort and de-duplicate rowids)
+ - Use rowids from unique to run a disk-ordered sweep
+*/
-QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(THD *thd_param,
- TABLE *table)
+QUICK_INDEX_SORT_SELECT::QUICK_INDEX_SORT_SELECT(THD *thd_param,
+ TABLE *table)
:unique(NULL), pk_quick_select(NULL), thd(thd_param)
{
- DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT");
+ DBUG_ENTER("QUICK_INDEX_SORT_SELECT::QUICK_INDEX_SORT_SELECT");
index= MAX_KEY;
head= table;
bzero(&read_record, sizeof(read_record));
@@ -1208,38 +1856,48 @@ QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(THD *thd_param,
DBUG_VOID_RETURN;
}
-int QUICK_INDEX_MERGE_SELECT::init()
+int QUICK_INDEX_SORT_SELECT::init()
{
- DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::init");
+ DBUG_ENTER("QUICK_INDEX_SORT_SELECT::init");
DBUG_RETURN(0);
}
-int QUICK_INDEX_MERGE_SELECT::reset()
+int QUICK_INDEX_SORT_SELECT::reset()
{
- DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::reset");
+ DBUG_ENTER("QUICK_INDEX_SORT_SELECT::reset");
DBUG_RETURN(read_keys_and_merge());
}
bool
-QUICK_INDEX_MERGE_SELECT::push_quick_back(QUICK_RANGE_SELECT *quick_sel_range)
+QUICK_INDEX_SORT_SELECT::push_quick_back(QUICK_RANGE_SELECT *quick_sel_range)
{
- /*
- Save quick_select that does scan on clustered primary key as it will be
- processed separately.
- */
+ DBUG_ENTER("QUICK_INDEX_SORT_SELECT::push_quick_back");
if (head->file->primary_key_is_clustered() &&
quick_sel_range->index == head->s->primary_key)
+ {
+ /*
+ A quick_select over a clustered primary key is handled specifically
+ Here we assume:
+ - PK columns are included in any other merged index
+ - Scan on the PK is disk-ordered.
+ (not meeting #2 will only cause performance degradation)
+
+ We could treat clustered PK as any other index, but that would
+ be inefficient. There is no point in doing scan on
+ CPK, remembering the rowid, then making rnd_pos() call with
+ that rowid.
+ */
pk_quick_select= quick_sel_range;
- else
- return quick_selects.push_back(quick_sel_range);
- return 0;
+ DBUG_RETURN(0);
+ }
+ DBUG_RETURN(quick_selects.push_back(quick_sel_range));
}
-QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT()
+QUICK_INDEX_SORT_SELECT::~QUICK_INDEX_SORT_SELECT()
{
List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
QUICK_RANGE_SELECT* quick;
- DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT");
+ DBUG_ENTER("QUICK_INDEX_SORT_SELECT::~QUICK_INDEX_SORT_SELECT");
delete unique;
quick_it.rewind();
while ((quick= quick_it++))
@@ -1253,7 +1911,6 @@ QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT()
DBUG_VOID_RETURN;
}
-
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param,
TABLE *table,
bool retrieve_full_rows,
@@ -1362,7 +2019,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
if (init() || reset())
{
file->ha_external_lock(thd, F_UNLCK);
- file->close();
+ file->ha_close();
goto failure;
}
free_file= TRUE;
@@ -1384,7 +2041,24 @@ end:
doing_key_read= 1;
head->mark_columns_used_by_index(index);
}
+
head->prepare_for_position();
+
+ if (head->no_keyread)
+ {
+ /*
+ We can get here when doing multi-table delete and having index_merge
+ condition on a table that we're deleting from. It probably doesn't make
+ sense to use index_merge, but de-facto it is used.
+
+ When it is used, we need to index columns to be read (before maria-5.3,
+ read_multi_range_first() would set it).
+ We shouldn't call mark_columns_used_by_index(), because it calls
+ enable_keyread(), which is not allowed.
+ */
+ head->mark_columns_used_by_index_no_reset(index, head->read_set);
+ }
+
head->file= org_file;
head->key_read= org_key_read;
bitmap_copy(&column_bitmap, head->read_set);
@@ -1541,7 +2215,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);
@@ -1665,6 +2339,7 @@ SEL_ARG::SEL_ARG(SEL_ARG &arg) :Sql_alloc()
min_value=arg.min_value;
max_value=arg.max_value;
next_key_part=arg.next_key_part;
+ max_part_no= arg.max_part_no;
use_count=1; elements=1;
}
@@ -1682,9 +2357,10 @@ SEL_ARG::SEL_ARG(Field *f,const uchar *min_value_arg,
:min_flag(0), max_flag(0), maybe_flag(0), maybe_null(f->real_maybe_null()),
elements(1), use_count(1), field(f), min_value((uchar*) min_value_arg),
max_value((uchar*) max_value_arg), next(0),prev(0),
- next_key_part(0),color(BLACK),type(KEY_RANGE)
+ next_key_part(0), color(BLACK), type(KEY_RANGE)
{
left=right= &null_element;
+ max_part_no= 1;
}
SEL_ARG::SEL_ARG(Field *field_,uint8 part_,
@@ -1695,6 +2371,7 @@ SEL_ARG::SEL_ARG(Field *field_,uint8 part_,
field(field_), min_value(min_value_), max_value(max_value_),
next(0),prev(0),next_key_part(0),color(BLACK),type(KEY_RANGE)
{
+ max_part_no= part+1;
left=right= &null_element;
}
@@ -1738,6 +2415,7 @@ SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent,
increment_use_count(1);
tmp->color= color;
tmp->elements= this->elements;
+ tmp->max_part_no= max_part_no;
return tmp;
}
@@ -1981,9 +2659,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 */
@@ -1992,7 +2672,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;
@@ -2040,6 +2721,26 @@ public:
/*
+ Plan for QUICK_INDEX_INTERSECT_SELECT scan.
+ QUICK_INDEX_INTERSECT_SELECT always retrieves full rows, so retrieve_full_rows
+ is ignored by make_quick.
+*/
+
+class TRP_INDEX_INTERSECT : public TABLE_READ_PLAN
+{
+public:
+ TRP_INDEX_INTERSECT() {} /* Remove gcc warning */
+ virtual ~TRP_INDEX_INTERSECT() {} /* Remove gcc warning */
+ QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
+ MEM_ROOT *parent_alloc);
+ TRP_RANGE **range_scans; /* array of ptrs to plans of intersected scans */
+ TRP_RANGE **range_scans_end; /* end of the array */
+ /* keys whose scans are to be filtered by cpk conditions */
+ key_map filtered_scans;
+};
+
+
+/*
Plan for QUICK_INDEX_MERGE_SELECT scan.
QUICK_ROR_INTERSECT_SELECT always retrieves full rows, so retrieve_full_rows
is ignored by make_quick.
@@ -2106,6 +2807,38 @@ public:
};
+typedef struct st_index_scan_info
+{
+ uint idx; /* # of used key in param->keys */
+ uint keynr; /* # of used key in table */
+ uint range_count;
+ ha_rows records; /* estimate of # records this scan will return */
+
+ /* Set of intervals over key fields that will be used for row retrieval. */
+ SEL_ARG *sel_arg;
+
+ KEY *key_info;
+ uint used_key_parts;
+
+ /* Estimate of # records filtered out by intersection with cpk */
+ ha_rows filtered_out;
+ /* Bitmap of fields used in index intersection */
+ MY_BITMAP used_fields;
+
+ /* Fields used in the query and covered by ROR scan. */
+ MY_BITMAP covered_fields;
+ uint used_fields_covered; /* # of set bits in covered_fields */
+ int key_rec_length; /* length of key record (including rowid) */
+
+ /*
+ Cost of reading all index records with values in sel_arg intervals set
+ (assuming there is no need to access full table records)
+ */
+ double index_read_cost;
+ uint first_uncovered_field; /* first unused bit in covered_fields */
+ uint key_components; /* # of parts in the key */
+} INDEX_SCAN_INFO;
+
/*
Fill param->needed_fields with bitmap of fields used in the query.
SYNOPSIS
@@ -2217,7 +2950,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;
@@ -2230,7 +2964,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
quick=0;
needed_reg.clear_all();
quick_keys.clear_all();
- if (keys_to_use.is_clear_all())
+ DBUG_ASSERT(!head->is_filled_at_execution());
+ if (keys_to_use.is_clear_all() || head->is_filled_at_execution())
DBUG_RETURN(0);
records= head->file->stats.records;
if (!records)
@@ -2275,6 +3010,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);
@@ -2381,72 +3117,92 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
It is possible to use a range-based quick select (but it might be
slower than 'all' table scan).
*/
- if (tree->merges.is_empty())
- {
- TRP_RANGE *range_trp;
- TRP_ROR_INTERSECT *rori_trp;
- bool can_build_covering= FALSE;
+ TRP_RANGE *range_trp;
+ TRP_ROR_INTERSECT *rori_trp;
+ TRP_INDEX_INTERSECT *intersect_trp;
+ bool can_build_covering= FALSE;
+
+ remove_nonrange_trees(&param, tree);
- /* Get best 'range' plan and prepare data for making other plans */
- if ((range_trp= get_key_scans_params(&param, tree, FALSE, TRUE,
- best_read_time)))
- {
- best_trp= range_trp;
- best_read_time= best_trp->read_cost;
- }
+ /* Get best 'range' plan and prepare data for making other plans */
+ if ((range_trp= get_key_scans_params(&param, tree, FALSE, TRUE,
+ best_read_time)))
+ {
+ best_trp= range_trp;
+ best_read_time= best_trp->read_cost;
+ }
+ /*
+ Simultaneous key scans and row deletes on several handler
+ objects are not allowed so don't use ROR-intersection for
+ table deletes.
+ */
+ if ((thd->lex->sql_command != SQLCOM_DELETE) &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE))
+ {
/*
- Simultaneous key scans and row deletes on several handler
- objects are not allowed so don't use ROR-intersection for
- table deletes.
+ Get best non-covering ROR-intersection plan and prepare data for
+ building covering ROR-intersection.
*/
- if ((thd->lex->sql_command != SQLCOM_DELETE) &&
- optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE))
+ if ((rori_trp= get_best_ror_intersect(&param, tree, best_read_time,
+ &can_build_covering)))
{
+ best_trp= rori_trp;
+ best_read_time= best_trp->read_cost;
/*
- Get best non-covering ROR-intersection plan and prepare data for
- building covering ROR-intersection.
+ Try constructing covering ROR-intersect only if it looks possible
+ and worth doing.
*/
- if ((rori_trp= get_best_ror_intersect(&param, tree, best_read_time,
- &can_build_covering)))
- {
+ if (!rori_trp->is_covering && can_build_covering &&
+ (rori_trp= get_best_covering_ror_intersect(&param, tree,
+ best_read_time)))
best_trp= rori_trp;
- best_read_time= best_trp->read_cost;
- /*
- Try constructing covering ROR-intersect only if it looks possible
- and worth doing.
- */
- if (!rori_trp->is_covering && can_build_covering &&
- (rori_trp= get_best_covering_ror_intersect(&param, tree,
- best_read_time)))
- best_trp= rori_trp;
- }
}
}
- else
+ /*
+ Do not look for an index intersection plan if there is a covering
+ index. The scan by this covering index will be always cheaper than
+ any index intersection.
+ */
+ if (param.table->covering_keys.is_clear_all() &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE) &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT))
+ {
+ if ((intersect_trp= get_best_index_intersect(&param, tree,
+ best_read_time)))
+ {
+ best_trp= intersect_trp;
+ best_read_time= best_trp->read_cost;
+ set_if_smaller(param.table->quick_condition_rows,
+ intersect_trp->records);
+ }
+ }
+
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE))
{
- if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE))
+ /* Try creating index_merge/ROR-union scan. */
+ SEL_IMERGE *imerge;
+ TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp;
+ LINT_INIT(new_conj_trp); /* no empty index_merge lists possible */
+ DBUG_PRINT("info",("No range reads possible,"
+ " trying to construct index_merge"));
+ List_iterator_fast<SEL_IMERGE> it(tree->merges);
+ while ((imerge= it++))
{
- /* Try creating index_merge/ROR-union scan. */
- SEL_IMERGE *imerge;
- TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp;
- LINT_INIT(new_conj_trp); /* no empty index_merge lists possible */
- DBUG_PRINT("info",("No range reads possible,"
- " trying to construct index_merge"));
- List_iterator_fast<SEL_IMERGE> it(tree->merges);
- while ((imerge= it++))
+ new_conj_trp= get_best_disjunct_quick(&param, imerge, best_read_time);
+ if (new_conj_trp)
+ set_if_smaller(param.table->quick_condition_rows,
+ new_conj_trp->records);
+ if (new_conj_trp &&
+ (!best_conj_trp ||
+ new_conj_trp->read_cost < best_conj_trp->read_cost))
{
- new_conj_trp= get_best_disjunct_quick(&param, imerge, best_read_time);
- if (new_conj_trp)
- set_if_smaller(param.table->quick_condition_rows,
- new_conj_trp->records);
- if (!best_conj_trp || (new_conj_trp && new_conj_trp->read_cost <
- best_conj_trp->read_cost))
- best_conj_trp= new_conj_trp;
+ best_conj_trp= new_conj_trp;
+ best_read_time= best_conj_trp->read_cost;
}
- if (best_conj_trp)
- best_trp= best_conj_trp;
}
+ if (best_conj_trp)
+ best_trp= best_conj_trp;
}
}
@@ -3598,11 +4354,19 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records)
DBUG_ENTER("get_sweep_read_cost");
if (param->table->file->primary_key_is_clustered())
{
+ /*
+ We are using the primary key to find the rows.
+ Calculate the cost for this.
+ */
result= param->table->file->read_time(param->table->s->primary_key,
(uint)records, records);
}
else
{
+ /*
+ Rows will be retreived with rnd_pos(). Caluclate the expected
+ cost for this.
+ */
double n_blocks=
ceil(ulonglong2double(param->table->file->stats.data_file_length) /
IO_SIZE);
@@ -3619,7 +4383,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records)
return 1;
*/
JOIN *join= param->thd->lex->select_lex.join;
- if (!join || join->tables == 1)
+ if (!join || join->table_count == 1)
{
/* No join, assume reading is done in one 'sweep' */
result= busy_blocks*(DISK_SEEK_BASE_COST +
@@ -3710,7 +4474,6 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
{
SEL_TREE **ptree;
TRP_INDEX_MERGE *imerge_trp= NULL;
- uint n_child_scans= imerge->trees_next - imerge->trees;
TRP_RANGE **range_scans;
TRP_RANGE **cur_child;
TRP_RANGE **cpk_scan= NULL;
@@ -3730,6 +4493,24 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
DBUG_ENTER("get_best_disjunct_quick");
DBUG_PRINT("info", ("Full table scan cost: %g", read_time));
+ /*
+ In every tree of imerge remove SEL_ARG trees that do not make ranges.
+ If after this removal some SEL_ARG tree becomes empty discard imerge.
+ */
+ for (ptree= imerge->trees; ptree != imerge->trees_next; ptree++)
+ {
+ if (remove_nonrange_trees(param, *ptree))
+ {
+ imerge->trees_next= imerge->trees;
+ break;
+ }
+ }
+
+ uint n_child_scans= imerge->trees_next - imerge->trees;
+
+ if (!n_child_scans)
+ DBUG_RETURN(NULL);
+
if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root,
sizeof(TRP_RANGE*)*
n_child_scans)))
@@ -3834,7 +4615,9 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
imerge_cost +=
Unique::get_use_cost(param->imerge_cost_buff, (uint)non_cpk_scan_records,
param->table->file->ref_length,
- param->thd->variables.sortbuff_size);
+ param->thd->variables.sortbuff_size,
+ TIME_FOR_COMPARE_ROWID,
+ FALSE, NULL);
DBUG_PRINT("info",("index_merge total cost: %g (wanted: less then %g)",
imerge_cost, read_time));
if (imerge_cost < read_time)
@@ -3849,6 +4632,13 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
imerge_trp->range_scans_end= range_scans + n_child_scans;
read_time= imerge_cost;
}
+ if (imerge_trp)
+ {
+ TABLE_READ_PLAN *trp= merge_same_index_scans(param, imerge, imerge_trp,
+ read_time);
+ if (trp != imerge_trp)
+ DBUG_RETURN(trp);
+ }
}
build_ror_index_merge:
@@ -3864,6 +4654,7 @@ build_ror_index_merge:
sizeof(TABLE_READ_PLAN*)*
n_child_scans)))
DBUG_RETURN(imerge_trp);
+
skip_to_ror_scan:
roru_index_costs= 0.0;
roru_total_records= 0;
@@ -3947,30 +4738,990 @@ skip_to_ror_scan:
DBUG_RETURN(roru);
}
}
- DBUG_RETURN(imerge_trp);
+ DBUG_RETURN(imerge_trp);
}
-typedef struct st_ror_scan_info
+
+/*
+ Merge index scans for the same indexes in an index merge plan
+
+ SYNOPSIS
+ merge_same_index_scans()
+ param Context info for the operation
+ imerge IN/OUT SEL_IMERGE from which imerge_trp has been extracted
+ imerge_trp The index merge plan where index scans for the same
+ indexes are to be merges
+ read_time The upper bound for the cost of the plan to be evaluated
+
+ DESRIPTION
+ For the given index merge plan imerge_trp extracted from the SEL_MERGE
+ imerge the function looks for range scans with the same indexes and merges
+ them into SEL_ARG trees. Then for each such SEL_ARG tree r_i the function
+ creates a range tree rt_i that contains only r_i. All rt_i are joined
+ into one index merge that replaces the original index merge imerge.
+ The function calls get_best_disjunct_quick for the new index merge to
+ get a new index merge plan that contains index scans only for different
+ indexes.
+ If there are no index scans for the same index in the original index
+ merge plan the function does not change the original imerge and returns
+ imerge_trp as its result.
+
+ RETURN
+ The original or or improved index merge plan
+*/
+
+static
+TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge,
+ TRP_INDEX_MERGE *imerge_trp,
+ double read_time)
{
- uint idx; /* # of used key in param->keys */
- uint keynr; /* # of used key in table */
- ha_rows records; /* estimate of # records this scan will return */
+ uint16 first_scan_tree_idx[MAX_KEY];
+ SEL_TREE **tree;
+ TRP_RANGE **cur_child;
+ uint removed_cnt= 0;
- /* Set of intervals over key fields that will be used for row retrieval. */
- SEL_ARG *sel_arg;
+ DBUG_ENTER("merge_same_index_scans");
- /* Fields used in the query and covered by this ROR scan. */
- MY_BITMAP covered_fields;
- uint used_fields_covered; /* # of set bits in covered_fields */
- int key_rec_length; /* length of key record (including rowid) */
+ bzero(first_scan_tree_idx, sizeof(first_scan_tree_idx[0])*param->keys);
- /*
- Cost of reading all index records with values in sel_arg intervals set
- (assuming there is no need to access full table records)
- */
- double index_read_cost;
- uint first_uncovered_field; /* first unused bit in covered_fields */
- uint key_components; /* # of parts in the key */
+ for (tree= imerge->trees, cur_child= imerge_trp->range_scans;
+ tree != imerge->trees_next;
+ tree++, cur_child++)
+ {
+ DBUG_ASSERT(tree);
+ uint key_idx= (*cur_child)->key_idx;
+ uint16 *tree_idx_ptr= &first_scan_tree_idx[key_idx];
+ if (!*tree_idx_ptr)
+ *tree_idx_ptr= (uint16) (tree-imerge->trees+1);
+ else
+ {
+ SEL_TREE **changed_tree= imerge->trees+(*tree_idx_ptr-1);
+ SEL_ARG *key= (*changed_tree)->keys[key_idx];
+ bzero((*changed_tree)->keys,
+ sizeof((*changed_tree)->keys[0])*param->keys);
+ (*changed_tree)->keys_map.clear_all();
+ if (((*changed_tree)->keys[key_idx]=
+ key_or(param, key, (*tree)->keys[key_idx])))
+ (*changed_tree)->keys_map.set_bit(key_idx);
+ *tree= NULL;
+ removed_cnt++;
+ }
+ }
+ if (!removed_cnt)
+ DBUG_RETURN(imerge_trp);
+
+ TABLE_READ_PLAN *trp= NULL;
+ SEL_TREE **new_trees_next= imerge->trees;
+ for (tree= new_trees_next; tree != imerge->trees_next; tree++)
+ {
+ if (!*tree)
+ continue;
+ if (tree > new_trees_next)
+ *new_trees_next= *tree;
+ new_trees_next++;
+ }
+ imerge->trees_next= new_trees_next;
+
+ DBUG_ASSERT(imerge->trees_next>imerge->trees);
+
+ if (imerge->trees_next-imerge->trees > 1)
+ trp= get_best_disjunct_quick(param, imerge, read_time);
+ else
+ {
+ /*
+ This alternative theoretically can be reached when the cost
+ of the index merge for such a formula as
+ (key1 BETWEEN c1_1 AND c1_2) AND key2 > c2 OR
+ (key1 BETWEEN c1_3 AND c1_4) AND key3 > c3
+ is estimated as being cheaper than the cost of index scan for
+ the formula
+ (key1 BETWEEN c1_1 AND c1_2) OR (key1 BETWEEN c1_3 AND c1_4)
+
+ In the current code this may happen for two reasons:
+ 1. for a single index range scan data records are accessed in
+ a random order
+ 2. the functions that estimate the cost of a range scan and an
+ index merge retrievals are not well calibrated
+ */
+ trp= get_key_scans_params(param, *imerge->trees, FALSE, TRUE,
+ read_time);
+ }
+
+ DBUG_RETURN(trp);
+}
+
+
+/*
+ This structure contains the info common for all steps of a partial
+ index intersection plan. Morever it contains also the info common
+ for index intersect plans. This info is filled in by the function
+ prepare_search_best just before searching for the best index
+ intersection plan.
+*/
+
+typedef struct st_common_index_intersect_info
+{
+ PARAM *param; /* context info for range optimizations */
+ uint key_size; /* size of a ROWID element stored in Unique object */
+ uint compare_factor; /* 1/compare - cost to compare two ROWIDs */
+ ulonglong max_memory_size; /* maximum space allowed for Unique objects */
+ ha_rows table_cardinality; /* estimate of the number of records in table */
+ double cutoff_cost; /* discard index intersects with greater costs */
+ INDEX_SCAN_INFO *cpk_scan; /* clustered primary key used in intersection */
+
+ bool in_memory; /* unique object for intersection is completely in memory */
+
+ INDEX_SCAN_INFO **search_scans; /* scans possibly included in intersect */
+ uint n_search_scans; /* number of elements in search_scans */
+
+ bool best_uses_cpk; /* current best intersect uses clustered primary key */
+ double best_cost; /* cost of the current best index intersection */
+ /* estimate of the number of records in the current best intersection */
+ ha_rows best_records;
+ uint best_length; /* number of indexes in the current best intersection */
+ INDEX_SCAN_INFO **best_intersect; /* the current best index intersection */
+ /* scans from the best intersect to be filtrered by cpk conditions */
+ key_map filtered_scans;
+
+ uint *buff_elems; /* buffer to calculate cost of index intersection */
+
+} COMMON_INDEX_INTERSECT_INFO;
+
+
+/*
+ This structure contains the info specific for one step of an index
+ intersection plan. The structure is filled in by the function
+ check_index_intersect_extension.
+*/
+
+typedef struct st_partial_index_intersect_info
+{
+ COMMON_INDEX_INTERSECT_INFO *common_info; /* shared by index intersects */
+ uint length; /* number of index scans in the partial intersection */
+ ha_rows records; /* estimate of the number of records in intersection */
+ double cost; /* cost of the partial index intersection */
+
+ /* estimate of total number of records of all scans of the partial index
+ intersect sent to the Unique object used for the intersection */
+ ha_rows records_sent_to_unique;
+
+ /* total cost of the scans of indexes from the partial index intersection */
+ double index_read_cost;
+
+ bool use_cpk_filter; /* cpk filter is to be used for this scan */
+ bool in_memory; /* uses unique object in memory */
+ double in_memory_cost; /* cost of using unique object in memory */
+
+ key_map filtered_scans; /* scans to be filtered by cpk conditions */
+
+ MY_BITMAP *intersect_fields; /* bitmap of fields used in intersection */
+} PARTIAL_INDEX_INTERSECT_INFO;
+
+
+/* Check whether two indexes have the same first n components */
+
+static
+bool same_index_prefix(KEY *key1, KEY *key2, uint used_parts)
+{
+ KEY_PART_INFO *part1= key1->key_part;
+ KEY_PART_INFO *part2= key2->key_part;
+ for(uint i= 0; i < used_parts; i++, part1++, part2++)
+ {
+ if (part1->fieldnr != part2->fieldnr)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/* Create a bitmap for all fields of a table */
+
+static
+bool create_fields_bitmap(PARAM *param, MY_BITMAP *fields_bitmap)
+{
+ my_bitmap_map *bitmap_buf;
+
+ if (!(bitmap_buf= (my_bitmap_map *) alloc_root(param->mem_root,
+ param->fields_bitmap_size)))
+ return TRUE;
+ if (bitmap_init(fields_bitmap, bitmap_buf, param->table->s->fields, FALSE))
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Compare two indexes scans for sort before search for the best intersection */
+
+static
+int cmp_intersect_index_scan(INDEX_SCAN_INFO **a, INDEX_SCAN_INFO **b)
+{
+ return (*a)->records < (*b)->records ?
+ -1 : (*a)->records == (*b)->records ? 0 : 1;
+}
+
+
+static inline
+void set_field_bitmap_for_index_prefix(MY_BITMAP *field_bitmap,
+ KEY_PART_INFO *key_part,
+ uint used_key_parts)
+{
+ bitmap_clear_all(field_bitmap);
+ for (KEY_PART_INFO *key_part_end= key_part+used_key_parts;
+ key_part < key_part_end; key_part++)
+ {
+ bitmap_set_bit(field_bitmap, key_part->fieldnr-1);
+ }
+}
+
+
+/*
+ Round up table cardinality read from statistics provided by engine.
+ This function should go away when mysql test will allow to handle
+ more or less easily in the test suites deviations of InnoDB
+ statistical data.
+*/
+
+static inline
+ha_rows get_table_cardinality_for_index_intersect(TABLE *table)
+{
+ if (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT)
+ return table->file->stats.records;
+ else
+ {
+ ha_rows d;
+ double q;
+ for (q= (double)table->file->stats.records, d= 1 ; q >= 10; q/= 10, d*= 10 ) ;
+ return (ha_rows) (floor(q+0.5) * d);
+ }
+}
+
+
+static
+ha_rows records_in_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr,
+ INDEX_SCAN_INFO *ext_index_scan);
+
+/*
+ Prepare to search for the best index intersection
+
+ SYNOPSIS
+ prepare_search_best_index_intersect()
+ param common info about index ranges
+ tree tree of ranges for indexes than can be intersected
+ common OUT info needed for search to be filled by the function
+ init OUT info for an initial pseudo step of the intersection plans
+ cutoff_cost cut off cost of the interesting index intersection
+
+ DESCRIPTION
+ The function initializes all fields of the structure 'common' to be used
+ when searching for the best intersection plan. It also allocates
+ memory to store the most cheap index intersection.
+
+ NOTES
+ When selecting candidates for index intersection we always take only
+ one representative out of any set of indexes that share the same range
+ conditions. These indexes always have the same prefixes and the
+ components of this prefixes are exactly those used in these range
+ conditions.
+ Range conditions over clustered primary key (cpk) is always used only
+ as the condition that filters out some rowids retrieved by the scans
+ for secondary indexes. The cpk index will be handled in special way by
+ the function that search for the best index intersection.
+
+ RETURN
+ FALSE in the case of success
+ TRUE otherwise
+*/
+
+static
+bool prepare_search_best_index_intersect(PARAM *param,
+ SEL_TREE *tree,
+ COMMON_INDEX_INTERSECT_INFO *common,
+ PARTIAL_INDEX_INTERSECT_INFO *init,
+ double cutoff_cost)
+{
+ uint i;
+ uint n_search_scans;
+ double cost;
+ INDEX_SCAN_INFO **index_scan;
+ INDEX_SCAN_INFO **scan_ptr;
+ INDEX_SCAN_INFO *cpk_scan= NULL;
+ TABLE *table= param->table;
+ uint n_index_scans= tree->index_scans_end - tree->index_scans;
+
+ if (!n_index_scans)
+ return 1;
+
+ bzero(init, sizeof(*init));
+ init->common_info= common;
+ init->cost= cutoff_cost;
+
+ common->param= param;
+ common->key_size= table->file->ref_length;
+ common->compare_factor= TIME_FOR_COMPARE_ROWID;
+ common->max_memory_size= param->thd->variables.sortbuff_size;
+ common->cutoff_cost= cutoff_cost;
+ common->cpk_scan= NULL;
+ common->table_cardinality=
+ get_table_cardinality_for_index_intersect(table);
+
+ if (n_index_scans <= 1)
+ return TRUE;
+
+ if (table->file->primary_key_is_clustered())
+ {
+ INDEX_SCAN_INFO **index_scan_end;
+ index_scan= tree->index_scans;
+ index_scan_end= index_scan+n_index_scans;
+ for ( ; index_scan < index_scan_end; index_scan++)
+ {
+ if ((*index_scan)->keynr == table->s->primary_key)
+ {
+ common->cpk_scan= cpk_scan= *index_scan;
+ break;
+ }
+ }
+ }
+
+ i= n_index_scans - test(cpk_scan != NULL) + 1;
+
+ if (!(common->search_scans =
+ (INDEX_SCAN_INFO **) alloc_root (param->mem_root,
+ sizeof(INDEX_SCAN_INFO *) * i)))
+ return TRUE;
+ bzero(common->search_scans, sizeof(INDEX_SCAN_INFO *) * i);
+
+ INDEX_SCAN_INFO **selected_index_scans= common->search_scans;
+
+ for (i=0, index_scan= tree->index_scans; i < n_index_scans; i++, index_scan++)
+ {
+ uint used_key_parts= (*index_scan)->used_key_parts;
+ KEY *key_info= (*index_scan)->key_info;
+
+ if (*index_scan == cpk_scan)
+ continue;
+ if (cpk_scan && cpk_scan->used_key_parts >= used_key_parts &&
+ same_index_prefix(cpk_scan->key_info, key_info, used_key_parts))
+ continue;
+
+ cost= table->file->keyread_time((*index_scan)->keynr,
+ (*index_scan)->range_count,
+ (*index_scan)->records);
+ if (cost >= cutoff_cost)
+ continue;
+
+ for (scan_ptr= selected_index_scans; *scan_ptr ; scan_ptr++)
+ {
+ /*
+ When we have range conditions for two different indexes with the same
+ beginning it does not make sense to consider both of them for index
+ intersection if the range conditions are covered by common initial
+ components of the indexes. Actually in this case the indexes are
+ guaranteed to have the same range conditions.
+ */
+ if ((*scan_ptr)->used_key_parts == used_key_parts &&
+ same_index_prefix((*scan_ptr)->key_info, key_info, used_key_parts))
+ break;
+ }
+ if (!*scan_ptr || cost < (*scan_ptr)->index_read_cost)
+ {
+ *scan_ptr= *index_scan;
+ (*scan_ptr)->index_read_cost= cost;
+ }
+ }
+
+ ha_rows records_in_scans= 0;
+
+ for (scan_ptr=selected_index_scans, i= 0; *scan_ptr; scan_ptr++, i++)
+ {
+ if (create_fields_bitmap(param, &(*scan_ptr)->used_fields))
+ return TRUE;
+ records_in_scans+= (*scan_ptr)->records;
+ }
+ n_search_scans= i;
+
+ if (cpk_scan && create_fields_bitmap(param, &cpk_scan->used_fields))
+ return TRUE;
+
+ if (!(common->n_search_scans= n_search_scans))
+ return TRUE;
+
+ common->best_uses_cpk= FALSE;
+ common->best_cost= cutoff_cost + COST_EPS;
+ common->best_length= 0;
+
+ if (!(common->best_intersect=
+ (INDEX_SCAN_INFO **) alloc_root (param->mem_root,
+ sizeof(INDEX_SCAN_INFO *) *
+ (i + test(cpk_scan != NULL)))))
+ return TRUE;
+
+ size_t calc_cost_buff_size=
+ Unique::get_cost_calc_buff_size((size_t)records_in_scans,
+ common->key_size,
+ common->max_memory_size);
+ if (!(common->buff_elems= (uint *) alloc_root(param->mem_root,
+ calc_cost_buff_size)))
+ return TRUE;
+
+ my_qsort(selected_index_scans, n_search_scans, sizeof(INDEX_SCAN_INFO *),
+ (qsort_cmp) cmp_intersect_index_scan);
+
+ if (cpk_scan)
+ {
+ PARTIAL_INDEX_INTERSECT_INFO curr;
+ set_field_bitmap_for_index_prefix(&cpk_scan->used_fields,
+ cpk_scan->key_info->key_part,
+ cpk_scan->used_key_parts);
+ curr.common_info= common;
+ curr.intersect_fields= &cpk_scan->used_fields;
+ curr.records= cpk_scan->records;
+ curr.length= 1;
+ for (scan_ptr=selected_index_scans; *scan_ptr; scan_ptr++)
+ {
+ ha_rows scan_records= (*scan_ptr)->records;
+ ha_rows records= records_in_index_intersect_extension(&curr, *scan_ptr);
+ (*scan_ptr)->filtered_out= records >= scan_records ?
+ 0 : scan_records-records;
+ }
+ }
+ else
+ {
+ for (scan_ptr=selected_index_scans; *scan_ptr; scan_ptr++)
+ (*scan_ptr)->filtered_out= 0;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ On Estimation of the Number of Records in an Index Intersection
+ ===============================================================
+
+ Consider query Q over table t. Let C be the WHERE condition of this query,
+ and, idx1(a1_1,...,a1_k1) and idx2(a2_1,...,a2_k2) be some indexes defined
+ on table t.
+ Let rt1 and rt2 be the range trees extracted by the range optimizer from C
+ for idx1 and idx2 respectively.
+ Let #t be the estimate of the number of records in table t provided for the
+ optimizer.
+ Let #r1 and #r2 be the estimates of the number of records in the range trees
+ rt1 and rt2, respectively, obtained by the range optimizer.
+
+ We need to get an estimate for the number of records in the index
+ intersection of rt1 and rt2. In other words, we need to estimate the
+ cardinality of the set of records that are in both trees. Let's designate
+ this number by #r.
+
+ If we do not make any assumptions then we can only state that
+ #r<=min(#r1,#r2).
+ With this estimate we can't say that the index intersection scan will be
+ cheaper than the cheapest index scan.
+
+ Let Rt1 and Rt2 be AND/OR conditions representing rt and rt2 respectively.
+ The probability that a record belongs to rt1 is sel(Rt1)=#r1/#t.
+ The probability that a record belongs to rt2 is sel(Rt2)=#r2/#t.
+
+ If we assume that the values in columns of idx1 and idx2 are independent
+ then #r/#t=sel(Rt1&Rt2)=sel(Rt1)*sel(Rt2)=(#r1/#t)*(#r2/#t).
+ So in this case we have: #r=#r1*#r2/#t.
+
+ The above assumption of independence of the columns in idx1 and idx2 means
+ that:
+ - all columns are different
+ - values from one column do not correlate with values from any other column.
+
+ We can't help with the case when column correlate with each other.
+ Yet, if they are assumed to be uncorrelated the value of #r theoretically can
+ be evaluated . Unfortunately this evaluation, in general, is rather complex.
+
+ Let's consider two indexes idx1:(dept, manager), idx2:(dept, building)
+ over table 'employee' and two range conditions over these indexes:
+ Rt1: dept=10 AND manager LIKE 'S%'
+ Rt2: dept=10 AND building LIKE 'L%'.
+ We can state that:
+ sel(Rt1&Rt2)=sel(dept=10)*sel(manager LIKE 'S%')*sel(building LIKE 'L%')
+ =sel(Rt1)*sel(Rt2)/sel(dept=10).
+ sel(Rt1/2_0:dept=10) can be estimated if we know the cardinality #r1_0 of
+ the range for sub-index idx1_0 (dept) of the index idx1 or the cardinality
+ #rt2_0 of the same range for sub-index idx2_0(dept) of the index idx2.
+ The current code does not make an estimate either for #rt1_0, or for #rt2_0,
+ but it can be adjusted to provide those numbers.
+ Alternatively, min(rec_per_key) for (dept) could be used to get an upper
+ bound for the value of sel(Rt1&Rt2). Yet this statistics is not provided
+ now.
+
+ Let's consider two other indexes idx1:(dept, last_name),
+ idx2:(first_name, last_name) and two range conditions over these indexes:
+ Rt1: dept=5 AND last_name='Sm%'
+ Rt2: first_name='Robert' AND last_name='Sm%'.
+
+ sel(Rt1&Rt2)=sel(dept=5)*sel(last_name='Sm5')*sel(first_name='Robert')
+ =sel(Rt2)*sel(dept=5)
+ Here max(rec_per_key) for (dept) could be used to get an upper bound for
+ the value of sel(Rt1&Rt2).
+
+ When the intersected indexes have different major columns, but some
+ minor column are common the picture may be more complicated.
+
+ Let's consider the following range conditions for the same indexes as in
+ the previous example:
+ Rt1: (Rt11: dept=5 AND last_name='So%')
+ OR
+ (Rt12: dept=7 AND last_name='Saw%')
+ Rt2: (Rt21: first_name='Robert' AND last_name='Saw%')
+ OR
+ (Rt22: first_name='Bob' AND last_name='So%')
+ Here we have:
+ sel(Rt1&Rt2)= sel(Rt11)*sel(Rt21)+sel(Rt22)*sel(dept=5) +
+ sel(Rt21)*sel(dept=7)+sel(Rt12)*sel(Rt22)
+ Now consider the range condition:
+ Rt1_0: (dept=5 OR dept=7)
+ For this condition we can state that:
+ sel(Rt1_0&Rt2)=(sel(dept=5)+sel(dept=7))*(sel(Rt21)+sel(Rt22))=
+ sel(dept=5)*sel(Rt21)+sel(dept=7)*sel(Rt21)+
+ sel(dept=5)*sel(Rt22)+sel(dept=7)*sel(Rt22)=
+ sel(dept=5)*sel(Rt21)+sel(Rt21)*sel(dept=7)+
+ sel(Rt22)*sel(dept=5)+sel(dept=7)*sel(Rt22) >
+ sel(Rt11)*sel(Rt21)+sel(Rt22)*sel(dept=5)+
+ sel(Rt21)*sel(dept=7)+sel(Rt12)*sel(Rt22) >
+ sel(Rt1 & Rt2)
+
+ We've just demonstrated for an example what is intuitively almost obvious
+ in general. We can remove the ending parts fromrange trees getting less
+ selective range conditions for sub-indexes.
+ So if not a most major component with the number k of an index idx is
+ encountered in the index with which we intersect we can use the sub-index
+ idx_k-1 that includes the components of idx up to the i-th component and
+ the range tree for idx_k-1 to make an upper bound estimate for the number
+ of records in the index intersection.
+ The range tree for idx_k-1 we use here is the subtree of the original range
+ tree for idx that contains only parts from the first k-1 components.
+
+ As it was mentioned above the range optimizer currently does not provide
+ an estimate for the number of records in the ranges for sub-indexes.
+ However, some reasonable upper bound estimate can be obtained.
+
+ Let's consider the following range tree:
+ Rt: (first_name='Robert' AND last_name='Saw%')
+ OR
+ (first_name='Bob' AND last_name='So%')
+ Let #r be the number of records in Rt. Let f_1 be the fan-out of column
+ last_name:
+ f_1 = rec_per_key[first_name]/rec_per_key[last_name].
+ The the number of records in the range tree:
+ Rt_0: (first_name='Robert' OR first_name='Bob')
+ for the sub-index (first_name) is not greater than max(#r*f_1, #t).
+ Strictly speaking, we can state only that it's not greater than
+ max(#r*max_f_1, #t), where
+ max_f_1= max_rec_per_key[first_name]/min_rec_per_key[last_name].
+ Yet, if #r/#t is big enough (and this is the case of an index intersection,
+ because using this index range with a single index scan is cheaper than
+ the cost of the intersection when #r/#t is small) then almost safely we
+ can use here f_1 instead of max_f_1.
+
+ The above considerations can be used in future development. Now, they are
+ used partly in the function that provides a rough upper bound estimate for
+ the number of records in an index intersection that follow below.
+*/
+
+/*
+ Estimate the number of records selected by an extension a partial intersection
+
+ SYNOPSIS
+ records_in_index_intersect_extension()
+ curr partial intersection plan to be extended
+ ext_index_scan the evaluated extension of this partial plan
+
+ DESCRIPTION
+ The function provides an estimate for the number of records in the
+ intersection of the partial index intersection curr with the index
+ ext_index_scan. If all intersected indexes does not have common columns
+ then the function returns an exact estimate (assuming there are no
+ correlations between values in the columns). If the intersected indexes
+ have common columns the function returns an upper bound for the number
+ of records in the intersection provided that the intersection of curr
+ with ext_index_scan can is expected to have less records than the expected
+ number of records in the partial intersection curr. In this case the
+ function also assigns the bitmap of the columns in the extended
+ intersection to ext_index_scan->used_fields.
+ If the function cannot expect that the number of records in the extended
+ intersection is less that the expected number of records #r in curr then
+ the function returns a number bigger than #r.
+
+ NOTES
+ See the comment before the desription of the function that explains the
+ reasoning used by this function.
+
+ RETURN
+ The expected number of rows in the extended index intersection
+*/
+
+static
+ha_rows records_in_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr,
+ INDEX_SCAN_INFO *ext_index_scan)
+{
+ KEY *key_info= ext_index_scan->key_info;
+ KEY_PART_INFO* key_part= key_info->key_part;
+ uint used_key_parts= ext_index_scan->used_key_parts;
+ MY_BITMAP *used_fields= &ext_index_scan->used_fields;
+
+ if (!curr->length)
+ {
+ /*
+ If this the first index in the intersection just mark the
+ fields in the used_fields bitmap and return the expected
+ number of records in the range scan for the index provided
+ by the range optimizer.
+ */
+ set_field_bitmap_for_index_prefix(used_fields, key_part, used_key_parts);
+ return ext_index_scan->records;
+ }
+
+ uint i;
+ bool better_selectivity= FALSE;
+ ha_rows records= curr->records;
+ MY_BITMAP *curr_intersect_fields= curr->intersect_fields;
+ for (i= 0; i < used_key_parts; i++, key_part++)
+ {
+ if (bitmap_is_set(curr_intersect_fields, key_part->fieldnr-1))
+ break;
+ }
+ if (i)
+ {
+ ha_rows table_cardinality= curr->common_info->table_cardinality;
+ ha_rows ext_records= ext_index_scan->records;
+ if (i < used_key_parts)
+ {
+ ulong *rec_per_key= key_info->rec_per_key+i-1;
+ ulong f1= rec_per_key[0] ? rec_per_key[0] : 1;
+ ulong f2= rec_per_key[1] ? rec_per_key[1] : 1;
+ ext_records= (ha_rows) ((double) ext_records / f2 * f1);
+ }
+ if (ext_records < table_cardinality)
+ {
+ better_selectivity= TRUE;
+ records= (ha_rows) ((double) records / table_cardinality *
+ ext_records);
+ bitmap_copy(used_fields, curr_intersect_fields);
+ key_part= key_info->key_part;
+ for (uint j= 0; j < used_key_parts; j++, key_part++)
+ bitmap_set_bit(used_fields, key_part->fieldnr-1);
+ }
+ }
+ return !better_selectivity ? records+1 :
+ !records ? 1 : records;
+}
+
+
+/*
+ Estimate the cost a binary search within disjoint cpk range intervals
+
+ Number of comparisons to check whether a cpk value satisfies
+ the cpk range condition = log2(cpk_scan->range_count).
+*/
+
+static inline
+double get_cpk_filter_cost(ha_rows filtered_records,
+ INDEX_SCAN_INFO *cpk_scan,
+ double compare_factor)
+{
+ return log((double) (cpk_scan->range_count+1)) / (compare_factor * M_LN2) *
+ filtered_records;
+}
+
+
+/*
+ Check whether a patial index intersection plan can be extended
+
+ SYNOPSIS
+ check_index_intersect_extension()
+ curr partial intersection plan to be extended
+ ext_index_scan a possible extension of this plan to be checked
+ next OUT the structure to be filled for the extended plan
+
+ DESCRIPTION
+ The function checks whether it makes sense to extend the index
+ intersection plan adding the index ext_index_scan, and, if this
+ the case, the function fills in the structure for the extended plan.
+
+ RETURN
+ TRUE if it makes sense to extend the given plan
+ FALSE otherwise
+*/
+
+static
+bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr,
+ INDEX_SCAN_INFO *ext_index_scan,
+ PARTIAL_INDEX_INTERSECT_INFO *next)
+{
+ ha_rows records;
+ ha_rows records_sent_to_unique;
+ double cost;
+ ha_rows ext_index_scan_records= ext_index_scan->records;
+ ha_rows records_filtered_out_by_cpk= ext_index_scan->filtered_out;
+ COMMON_INDEX_INTERSECT_INFO *common_info= curr->common_info;
+ double cutoff_cost= common_info->cutoff_cost;
+ uint idx= curr->length;
+ next->index_read_cost= curr->index_read_cost+ext_index_scan->index_read_cost;
+ if (next->index_read_cost > cutoff_cost)
+ return FALSE;
+
+ if ((next->in_memory= curr->in_memory))
+ next->in_memory_cost= curr->in_memory_cost;
+
+ next->intersect_fields= &ext_index_scan->used_fields;
+ next->filtered_scans= curr->filtered_scans;
+
+ records_sent_to_unique= curr->records_sent_to_unique;
+
+ next->use_cpk_filter= FALSE;
+
+ /* Calculate the cost of using a Unique object for index intersection */
+ if (idx && next->in_memory)
+ {
+ /*
+ All rowids received from the first scan are expected in one unique tree
+ */
+ ha_rows elems_in_tree= common_info->search_scans[0]->records-
+ common_info->search_scans[0]->filtered_out ;
+ next->in_memory_cost+= Unique::get_search_cost(elems_in_tree,
+ common_info->compare_factor)*
+ ext_index_scan_records;
+ cost= next->in_memory_cost;
+ }
+ else
+ {
+ uint *buff_elems= common_info->buff_elems;
+ uint key_size= common_info->key_size;
+ uint compare_factor= common_info->compare_factor;
+ ulonglong max_memory_size= common_info->max_memory_size;
+
+ records_sent_to_unique+= ext_index_scan_records;
+ cost= Unique::get_use_cost(buff_elems, (size_t) records_sent_to_unique, key_size,
+ max_memory_size, compare_factor, TRUE,
+ &next->in_memory);
+ if (records_filtered_out_by_cpk)
+ {
+ /* Check whether using cpk filter for this scan is beneficial */
+
+ double cost2;
+ bool in_memory2;
+ ha_rows records2= records_sent_to_unique-records_filtered_out_by_cpk;
+ cost2= Unique::get_use_cost(buff_elems, (size_t) records2, key_size,
+ max_memory_size, compare_factor, TRUE,
+ &in_memory2);
+ cost2+= get_cpk_filter_cost(ext_index_scan_records, common_info->cpk_scan,
+ compare_factor);
+ if (cost > cost2 + COST_EPS)
+ {
+ cost= cost2;
+ next->in_memory= in_memory2;
+ next->use_cpk_filter= TRUE;
+ records_sent_to_unique= records2;
+ }
+
+ }
+ if (next->in_memory)
+ next->in_memory_cost= cost;
+ }
+
+ if (next->use_cpk_filter)
+ {
+ next->filtered_scans.set_bit(ext_index_scan->keynr);
+ bitmap_union(&ext_index_scan->used_fields,
+ &common_info->cpk_scan->used_fields);
+ }
+ next->records_sent_to_unique= records_sent_to_unique;
+
+ records= records_in_index_intersect_extension(curr, ext_index_scan);
+ if (idx && records > curr->records)
+ return FALSE;
+ if (next->use_cpk_filter && curr->filtered_scans.is_clear_all())
+ records-= records_filtered_out_by_cpk;
+ next->records= records;
+
+ cost+= next->index_read_cost;
+ if (cost >= cutoff_cost)
+ return FALSE;
+
+ cost+= get_sweep_read_cost(common_info->param, records);
+
+ next->cost= cost;
+ next->length= curr->length+1;
+
+ return TRUE;
+}
+
+
+/*
+ Search for the cheapest extensions of range scans used to access a table
+
+ SYNOPSIS
+ find_index_intersect_best_extension()
+ curr partial intersection to evaluate all possible extension for
+
+ DESCRIPTION
+ The function tries to extend the partial plan curr in all possible ways
+ to look for a cheapest index intersection whose cost less than the
+ cut off value set in curr->common_info.cutoff_cost.
+*/
+
+static
+void find_index_intersect_best_extension(PARTIAL_INDEX_INTERSECT_INFO *curr)
+{
+ PARTIAL_INDEX_INTERSECT_INFO next;
+ COMMON_INDEX_INTERSECT_INFO *common_info= curr->common_info;
+ INDEX_SCAN_INFO **index_scans= common_info->search_scans;
+ uint idx= curr->length;
+ INDEX_SCAN_INFO **rem_first_index_scan_ptr= &index_scans[idx];
+ double cost= curr->cost;
+
+ if (cost + COST_EPS < common_info->best_cost)
+ {
+ common_info->best_cost= cost;
+ common_info->best_length= curr->length;
+ common_info->best_records= curr->records;
+ common_info->filtered_scans= curr->filtered_scans;
+ /* common_info->best_uses_cpk <=> at least one scan uses a cpk filter */
+ common_info->best_uses_cpk= !curr->filtered_scans.is_clear_all();
+ uint sz= sizeof(INDEX_SCAN_INFO *) * curr->length;
+ memcpy(common_info->best_intersect, common_info->search_scans, sz);
+ common_info->cutoff_cost= cost;
+ }
+
+ if (!(*rem_first_index_scan_ptr))
+ return;
+
+ next.common_info= common_info;
+
+ INDEX_SCAN_INFO *rem_first_index_scan= *rem_first_index_scan_ptr;
+ for (INDEX_SCAN_INFO **index_scan_ptr= rem_first_index_scan_ptr;
+ *index_scan_ptr; index_scan_ptr++)
+ {
+ *rem_first_index_scan_ptr= *index_scan_ptr;
+ *index_scan_ptr= rem_first_index_scan;
+ if (check_index_intersect_extension(curr, *rem_first_index_scan_ptr, &next))
+ find_index_intersect_best_extension(&next);
+ *index_scan_ptr= *rem_first_index_scan_ptr;
+ *rem_first_index_scan_ptr= rem_first_index_scan;
+ }
+}
+
+
+/*
+ Get the plan of the best intersection of range scans used to access a table
+
+ SYNOPSIS
+ get_best_index_intersect()
+ param common info about index ranges
+ tree tree of ranges for indexes than can be intersected
+ read_time cut off value for the evaluated plans
+
+ DESCRIPTION
+ The function looks for the cheapest index intersection of the range
+ scans to access a table. The info about the ranges for all indexes
+ is provided by the range optimizer and is passed through the
+ parameters param and tree. Any plan whose cost is greater than read_time
+ is rejected.
+ After the best index intersection is found the function constructs
+ the structure that manages the execution by the chosen plan.
+
+ RETURN
+ Pointer to the generated execution structure if a success,
+ 0 - otherwise.
+*/
+
+static
+TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree,
+ double read_time)
+{
+ uint i;
+ uint count;
+ TRP_RANGE **cur_range;
+ TRP_RANGE **range_scans;
+ INDEX_SCAN_INFO *index_scan;
+ COMMON_INDEX_INTERSECT_INFO common;
+ PARTIAL_INDEX_INTERSECT_INFO init;
+ TRP_INDEX_INTERSECT *intersect_trp= NULL;
+ TABLE *table= param->table;
+
+
+ DBUG_ENTER("get_best_index_intersect");
+
+ if (prepare_search_best_index_intersect(param, tree, &common, &init,
+ read_time))
+ DBUG_RETURN(NULL);
+
+ find_index_intersect_best_extension(&init);
+
+ if (common.best_length <= 1 && !common.best_uses_cpk)
+ DBUG_RETURN(NULL);
+
+ if (common.best_uses_cpk)
+ {
+ memmove((char *) (common.best_intersect+1), (char *) common.best_intersect,
+ sizeof(INDEX_SCAN_INFO *) * common.best_length);
+ common.best_intersect[0]= common.cpk_scan;
+ common.best_length++;
+ }
+
+ count= common.best_length;
+
+ if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root,
+ sizeof(TRP_RANGE *)*
+ count)))
+ DBUG_RETURN(NULL);
+
+ for (i= 0, cur_range= range_scans; i < count; i++)
+ {
+ index_scan= common.best_intersect[i];
+ if ((*cur_range= new (param->mem_root) TRP_RANGE(index_scan->sel_arg,
+ index_scan->idx, 0)))
+ {
+ TRP_RANGE *trp= *cur_range;
+ trp->read_cost= index_scan->index_read_cost;
+ trp->records= index_scan->records;
+ trp->is_ror= FALSE;
+ trp->mrr_buf_size= 0;
+ table->intersect_keys.set_bit(index_scan->keynr);
+ cur_range++;
+ }
+ }
+
+ count= tree->index_scans_end - tree->index_scans;
+ for (i= 0; i < count; i++)
+ {
+ index_scan= tree->index_scans[i];
+ if (!table->intersect_keys.is_set(index_scan->keynr))
+ {
+ for (uint j= 0; j < common.best_length; j++)
+ {
+ INDEX_SCAN_INFO *scan= common.best_intersect[j];
+ if (same_index_prefix(index_scan->key_info, scan->key_info,
+ scan->used_key_parts))
+ {
+ table->intersect_keys.set_bit(index_scan->keynr);
+ break;
+ }
+ }
+ }
+ }
+
+ if ((intersect_trp= new (param->mem_root)TRP_INDEX_INTERSECT))
+ {
+ intersect_trp->read_cost= common.best_cost;
+ intersect_trp->records= common.best_records;
+ intersect_trp->range_scans= range_scans;
+ intersect_trp->range_scans_end= cur_range;
+ intersect_trp->filtered_scans= common.filtered_scans;
+ }
+ DBUG_RETURN(intersect_trp);
+}
+
+
+typedef struct st_ror_scan_info : INDEX_SCAN_INFO
+{
} ROR_SCAN_INFO;
@@ -4006,7 +5757,7 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg)
ror_scan->key_rec_length= (param->table->key_info[keynr].key_length +
param->table->file->ref_length);
ror_scan->sel_arg= sel_arg;
- ror_scan->records= param->table->quick_rows[keynr];
+ ror_scan->records= param->quick_rows[keynr];
if (!(bitmap_buf= (my_bitmap_map*) alloc_root(param->mem_root,
param->fields_bitmap_size)))
@@ -4026,8 +5777,7 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg)
bitmap_set_bit(&ror_scan->covered_fields, key_part->fieldnr-1);
}
ror_scan->index_read_cost=
- param->table->file->keyread_time(ror_scan->keynr, 1,
- param->table->quick_rows[ror_scan->keynr]);
+ param->table->file->keyread_time(ror_scan->keynr, 1, ror_scan->records);
DBUG_RETURN(ror_scan);
}
@@ -4312,7 +6062,7 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
}
if (!prev_covered)
{
- double tmp= rows2double(info->param->table->quick_rows[scan->keynr]) /
+ double tmp= rows2double(info->param->quick_rows[scan->keynr]) /
rows2double(prev_records);
DBUG_PRINT("info", ("Selectivity multiplier: %g", tmp));
selectivity_mult *= tmp;
@@ -4391,7 +6141,7 @@ static bool ror_intersect_add(ROR_INTERSECT_INFO *info,
}
else
{
- info->index_records += info->param->table->quick_rows[ror_scan->keynr];
+ info->index_records += info->param->quick_rows[ror_scan->keynr];
info->index_scan_costs += ror_scan->index_read_cost;
bitmap_union(&info->covered_fields, &ror_scan->covered_fields);
if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields,
@@ -4501,7 +6251,6 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
ROR_SCAN_INFO **cur_ror_scan;
ROR_SCAN_INFO *cpk_scan= NULL;
uint cpk_no;
- bool cpk_scan_used= FALSE;
if (!(tree->ror_scans= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
sizeof(ROR_SCAN_INFO*)*
@@ -4513,11 +6262,20 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
for (idx= 0, cur_ror_scan= tree->ror_scans; idx < param->keys; idx++)
{
ROR_SCAN_INFO *scan;
+ uint key_no;
if (!tree->ror_scans_map.is_set(idx))
continue;
+ key_no= param->real_keynr[idx];
+ if (key_no != cpk_no &&
+ param->table->file->index_flags(key_no,0,0) & HA_CLUSTERED_INDEX)
+ {
+ /* Ignore clustering keys */
+ tree->n_ror_scans--;
+ continue;
+ }
if (!(scan= make_ror_scan(param, idx, tree->keys[idx])))
return NULL;
- if (param->real_keynr[idx] == cpk_no)
+ if (key_no == cpk_no)
{
cpk_scan= scan;
tree->n_ror_scans--;
@@ -4603,15 +6361,14 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
{
if (ror_intersect_add(intersect, cpk_scan, TRUE) &&
(intersect->total_cost < min_cost))
- {
- cpk_scan_used= TRUE;
intersect_best= intersect; //just set pointer here
- }
}
+ else
+ cpk_scan= 0; // Don't use cpk_scan
/* Ok, return ROR-intersect plan if we have found one */
TRP_ROR_INTERSECT *trp= NULL;
- if (min_cost < read_time && (cpk_scan_used || best_num > 1))
+ if (min_cost < read_time && (cpk_scan || best_num > 1))
{
if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
DBUG_RETURN(trp);
@@ -4630,7 +6387,7 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
set_if_smaller(param->table->quick_condition_rows, best_rows);
trp->records= best_rows;
trp->index_scan_costs= intersect_best->index_scan_costs;
- trp->cpk_scan= cpk_scan_used? cpk_scan: NULL;
+ trp->cpk_scan= cpk_scan;
DBUG_PRINT("info", ("Returning non-covering ROR-intersect plan:"
"cost %g, records %lu",
trp->read_cost, (ulong) trp->records));
@@ -4642,7 +6399,7 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
/*
Get best covering ROR-intersection.
SYNOPSIS
- get_best_covering_ror_intersect()
+ get_best_ntersectcovering_ror_intersect()
param Parameter from test_quick_select function.
tree SEL_TREE with sets of intervals for different keys.
read_time Don't return table read plans with cost > read_time.
@@ -4814,11 +6571,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
@@ -4829,14 +6587,23 @@ 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++)
+ tree->index_scans= 0;
+ if (!tree->keys_map.is_clear_all())
+ {
+ tree->index_scans=
+ (INDEX_SCAN_INFO **) alloc_root(param->mem_root,
+ sizeof(INDEX_SCAN_INFO *) * param->keys);
+ }
+ tree->index_scans_end= tree->index_scans;
+ 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;
+ INDEX_SCAN_INFO *index_scan;
uint keynr= param->real_keynr[idx];
if ((*key)->type == SEL_ARG::MAYBE_KEY ||
(*key)->maybe_flag)
@@ -4845,48 +6612,37 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
bool read_index_only= index_read_must_be_used ? TRUE :
(bool) param->table->covering_keys.is_set(keynr);
- found_records= check_quick_select(param, idx, *key, update_tbl_stats);
- if (param->is_ror_scan)
+ found_records= check_quick_select(param, idx, read_index_only, *key,
+ update_tbl_stats, &mrr_flags,
+ &buf_size, &cost);
+
+ if (found_records != HA_POS_ERROR && tree->index_scans &&
+ (index_scan= (INDEX_SCAN_INFO *)alloc_root(param->mem_root,
+ sizeof(INDEX_SCAN_INFO))))
+ {
+ index_scan->idx= idx;
+ index_scan->keynr= keynr;
+ index_scan->key_info= &param->table->key_info[keynr];
+ index_scan->used_key_parts= param->max_key_part+1;
+ index_scan->range_count= param->range_count;
+ index_scan->records= found_records;
+ index_scan->sel_arg= *key;
+ *tree->index_scans_end++= index_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;
}
-
}
}
@@ -4895,11 +6651,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,
@@ -4940,6 +6698,36 @@ QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param,
return quick_imerge;
}
+
+QUICK_SELECT_I *TRP_INDEX_INTERSECT::make_quick(PARAM *param,
+ bool retrieve_full_rows,
+ MEM_ROOT *parent_alloc)
+{
+ QUICK_INDEX_INTERSECT_SELECT *quick_intersect;
+ QUICK_RANGE_SELECT *quick;
+ /* index_merge always retrieves full rows, ignore retrieve_full_rows */
+ if (!(quick_intersect= new QUICK_INDEX_INTERSECT_SELECT(param->thd, param->table)))
+ return NULL;
+
+ quick_intersect->records= records;
+ quick_intersect->read_time= read_cost;
+ quick_intersect->filtered_scans= filtered_scans;
+ for (TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end;
+ range_scan++)
+ {
+ if (!(quick= (QUICK_RANGE_SELECT*)
+ ((*range_scan)->make_quick(param, FALSE, &quick_intersect->alloc)))||
+ quick_intersect->push_quick_back(quick))
+ {
+ delete quick;
+ delete quick_intersect;
+ return NULL;
+ }
+ }
+ return quick_intersect;
+}
+
+
QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param,
bool retrieve_full_rows,
MEM_ROOT *parent_alloc)
@@ -4962,7 +6750,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;
@@ -4972,7 +6762,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);
@@ -5385,11 +7177,10 @@ static SEL_TREE *get_full_func_mm_tree(RANGE_OPT_PARAM *param,
Item_equal *item_equal= field_item->item_equal;
if (item_equal)
{
- Item_equal_iterator it(*item_equal);
- Item_field *item;
- while ((item= it++))
+ Item_equal_fields_iterator it(*item_equal);
+ while (it++)
{
- Field *f= item->field;
+ Field *f= it.get_curr_field();
if (field->eq(f))
continue;
if (!((ref_tables | f->table->map) & param_comp))
@@ -5452,7 +7243,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
@@ -5538,13 +7329,13 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond)
case Item_func::MULT_EQUAL_FUNC:
{
Item_equal *item_equal= (Item_equal *) cond;
- if (!(value= item_equal->get_const()))
+ if (!(value= item_equal->get_const()) || value->is_expensive())
DBUG_RETURN(0);
- Item_equal_iterator it(*item_equal);
+ Item_equal_fields_iterator it(*item_equal);
ref_tables= value->used_tables();
- while ((field_item= it++))
+ while (it++)
{
- Field *field= field_item->field;
+ Field *field= it.get_curr_field();
Item_result cmp_type= field->cmp_type();
if (!((ref_tables | field->table->map) & param_comp))
{
@@ -5571,6 +7362,9 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond)
}
else
DBUG_RETURN(0);
+ if (value && value->is_expensive())
+ DBUG_RETURN(0);
+
ftree= get_full_func_mm_tree(param, cond_func, field_item, value, inv);
}
@@ -5619,6 +7413,7 @@ get_mm_parts(RANGE_OPT_PARAM *param, COND *cond_func, Field *field,
DBUG_RETURN(0); // OOM
}
sel_arg->part=(uchar) key_part->part;
+ sel_arg->max_part_no= sel_arg->part+1;
tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
tree->keys_map.set_bit(key_part->key);
}
@@ -5639,7 +7434,6 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
SEL_ARG *tree= 0;
MEM_ROOT *alloc= param->mem_root;
uchar *str;
- ulong orig_sql_mode;
int err;
DBUG_ENTER("get_mm_leaf");
@@ -5807,16 +7601,8 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
We can't always use indexes when comparing a string index to a number
cmp_type() is checked to allow compare of dates to numbers
*/
- if (field->result_type() == STRING_RESULT &&
- value->result_type() != STRING_RESULT &&
- field->cmp_type() != value->result_type())
+ if (field->cmp_type() == STRING_RESULT && value->cmp_type() != STRING_RESULT)
goto end;
- /* For comparison purposes allow invalid dates like 2000-01-32 */
- orig_sql_mode= field->table->in_use->variables.sql_mode;
- if (value->real_item()->type() == Item::STRING_ITEM &&
- (field->type() == MYSQL_TYPE_DATE ||
- field->type() == MYSQL_TYPE_DATETIME))
- field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
err= value->save_in_field_no_warnings(field, 1);
if (err > 0)
{
@@ -5828,7 +7614,6 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
{
tree= new (alloc) SEL_ARG(field, 0, 0);
tree->type= SEL_ARG::IMPOSSIBLE;
- field->table->in_use->variables.sql_mode= orig_sql_mode;
goto end;
}
else
@@ -5862,10 +7647,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
*/
}
else
- {
- field->table->in_use->variables.sql_mode= orig_sql_mode;
goto end;
- }
}
}
@@ -5888,12 +7670,10 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
}
else if (err < 0)
{
- field->table->in_use->variables.sql_mode= orig_sql_mode;
/* This happens when we try to insert a NULL field in a not null column */
tree= &null_element; // cmp with NULL is never TRUE
goto end;
}
- field->table->in_use->variables.sql_mode= orig_sql_mode;
/*
Any sargable predicate except "<=>" involving NULL as a constant is always
@@ -6068,13 +7848,149 @@ sel_add(SEL_ARG *key1,SEL_ARG *key2)
return root;
}
-#define CLONE_KEY1_MAYBE 1
-#define CLONE_KEY2_MAYBE 2
-#define swap_clone_flag(A) ((A & 1) << 1) | ((A & 2) >> 1)
+/*
+ Build a range tree for the conjunction of the range parts of two trees
-static SEL_TREE *
-tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
+ SYNOPSIS
+ and_range_trees()
+ param Context info for the operation
+ tree1 SEL_TREE for the first conjunct
+ tree2 SEL_TREE for the second conjunct
+ result SEL_TREE for the result
+
+ DESCRIPTION
+ This function takes range parts of two trees tree1 and tree2 and builds
+ a range tree for the conjunction of the formulas that these two range parts
+ represent.
+ More exactly:
+ if the range part of tree1 represents the normalized formula
+ R1_1 AND ... AND R1_k,
+ and the range part of tree2 represents the normalized formula
+ R2_1 AND ... AND R2_k,
+ then the range part of the result represents the formula:
+ RT = R_1 AND ... AND R_k, where R_i=(R1_i AND R2_i) for each i from [1..k]
+
+ The function assumes that tree1 is never equal to tree2. At the same
+ time the tree result can be the same as tree1 (but never as tree2).
+ If result==tree1 then rt replaces the range part of tree1 leaving
+ imerges as they are.
+ if result!=tree1 than it is assumed that the SEL_ARG trees in tree1 and
+ tree2 should be preserved. Otherwise they can be destroyed.
+
+ RETURN
+ 1 if the type the result tree is SEL_TREE::IMPOSSIBLE
+ 0 otherwise
+*/
+
+static
+int and_range_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree1, SEL_TREE *tree2,
+ SEL_TREE *result)
+{
+ DBUG_ENTER("and_ranges");
+ key_map result_keys;
+ result_keys.clear_all();
+ key_map anded_keys= tree1->keys_map;
+ anded_keys.merge(tree2->keys_map);
+ int key_no;
+ key_map::Iterator it(anded_keys);
+ while ((key_no= it++) != key_map::Iterator::BITMAP_END)
+ {
+ uint flag=0;
+ SEL_ARG *key1= tree1->keys[key_no];
+ SEL_ARG *key2= tree2->keys[key_no];
+ if (key1 && !key1->simple_key())
+ flag|= CLONE_KEY1_MAYBE;
+ if (key2 && !key2->simple_key())
+ flag|=CLONE_KEY2_MAYBE;
+ if (result != tree1)
+ {
+ if (key1)
+ key1->incr_refs();
+ if (key2)
+ key2->incr_refs();
+ }
+ SEL_ARG *key;
+ if ((result->keys[key_no]= key =key_and(param, key1, key2, flag)))
+ {
+ if (key && key->type == SEL_ARG::IMPOSSIBLE)
+ {
+ result->type= SEL_TREE::IMPOSSIBLE;
+ DBUG_RETURN(1);
+ }
+ result_keys.set_bit(key_no);
+#ifdef EXTRA_DEBUG
+ if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
+ key->test_use_count(key);
+#endif
+ }
+ }
+ result->keys_map= result_keys;
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Build a SEL_TREE for a conjunction out of such trees for the conjuncts
+
+ SYNOPSIS
+ tree_and()
+ param Context info for the operation
+ tree1 SEL_TREE for the first conjunct
+ tree2 SEL_TREE for the second conjunct
+
+ DESCRIPTION
+ This function builds a tree for the formula (A AND B) out of the trees
+ tree1 and tree2 that has been built for the formulas A and B respectively.
+
+ In a general case
+ tree1 represents the formula RT1 AND MT1,
+ where RT1 = R1_1 AND ... AND R1_k1, MT1=M1_1 AND ... AND M1_l1;
+ tree2 represents the formula RT2 AND MT2
+ where RT2 = R2_1 AND ... AND R2_k2, MT2=M2_1 AND ... AND M2_l2.
+
+ The result tree will represent the formula of the the following structure:
+ RT AND RT1MT2 AND RT2MT1, such that
+ rt is a tree obtained by range intersection of trees tree1 and tree2,
+ RT1MT2 = RT1M2_1 AND ... AND RT1M2_l2,
+ RT2MT1 = RT2M1_1 AND ... AND RT2M1_l1,
+ where rt1m2_i (i=1,...,l2) is the result of the pushdown operation
+ of range tree rt1 into imerge m2_i, while rt2m1_j (j=1,...,l1) is the
+ result of the pushdown operation of range tree rt2 into imerge m1_j.
+
+ RT1MT2/RT2MT is empty if MT2/MT1 is empty.
+
+ The range intersection of two range trees is produced by the function
+ and_range_trees. The pushdown of a range tree to a imerge is performed
+ by the function imerge_list_and_tree. This function may produce imerges
+ containing only one range tree. Such trees are intersected with rt and
+ the result of intersection is returned as the range part of the result
+ tree, while the corresponding imerges are removed altogether from its
+ imerge part.
+
+ NOTE
+ The pushdown operation of range trees into imerges is needed to be able
+ to construct valid imerges for the condition like this:
+ key1_p1=c1 AND (key1_p2 BETWEEN c21 AND c22 OR key2 < c2)
+
+ NOTE
+ Currently we do not support intersection between indexes and index merges.
+ When this will be supported the list of imerges for the result tree
+ should include also imerges from M1 and M2. That's why an extra parameter
+ is added to the function imerge_list_and_tree. If we call the function
+ with the last parameter equal to FALSE then MT1 and MT2 will be preserved
+ in the imerge list of the result tree. This can lead to the exponential
+ growth of the imerge list though.
+ Currently the last parameter of imerge_list_and_tree calls is always
+ TRUE.
+
+ RETURN
+ The result tree, if a success
+ 0 - otherwise.
+*/
+
+static
+SEL_TREE *tree_and(RANGE_OPT_PARAM *param, SEL_TREE *tree1, SEL_TREE *tree2)
{
DBUG_ENTER("tree_and");
if (!tree1)
@@ -6096,87 +8012,216 @@ tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
tree1->type=SEL_TREE::KEY_SMALLER;
DBUG_RETURN(tree1);
}
- key_map result_keys;
- result_keys.clear_all();
-
- /* Join the trees key per key */
- SEL_ARG **key1,**key2,**end;
- for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ;
- key1 != end ; key1++,key2++)
+
+ if (!tree1->merges.is_empty())
+ imerge_list_and_tree(param, &tree1->merges, tree2, TRUE);
+ if (!tree2->merges.is_empty())
+ imerge_list_and_tree(param, &tree2->merges, tree1, TRUE);
+ if (and_range_trees(param, tree1, tree2, tree1))
+ DBUG_RETURN(tree1);
+ imerge_list_and_list(&tree1->merges, &tree2->merges);
+ eliminate_single_tree_imerges(param, tree1);
+ DBUG_RETURN(tree1);
+}
+
+
+/*
+ Eliminate single tree imerges in a SEL_TREE objects
+
+ SYNOPSIS
+ eliminate_single_tree_imerges()
+ param Context info for the function
+ tree SEL_TREE where single tree imerges are to be eliminated
+
+ DESCRIPTION
+ For each imerge in 'tree' that contains only one disjunct tree, i.e.
+ for any imerge of the form m=rt, the function performs and operation
+ the range part of tree, replaces rt the with the result of anding and
+ removes imerge m from the the merge part of 'tree'.
+
+ RETURN VALUE
+ none
+*/
+
+static
+void eliminate_single_tree_imerges(RANGE_OPT_PARAM *param, SEL_TREE *tree)
+{
+ SEL_IMERGE *imerge;
+ List<SEL_IMERGE> merges= tree->merges;
+ List_iterator<SEL_IMERGE> it(merges);
+ tree->merges.empty();
+ while ((imerge= it++))
{
- uint flag=0;
- if (*key1 || *key2)
- {
- if (*key1 && !(*key1)->simple_key())
- flag|=CLONE_KEY1_MAYBE;
- if (*key2 && !(*key2)->simple_key())
- flag|=CLONE_KEY2_MAYBE;
- *key1=key_and(param, *key1, *key2, flag);
- if (*key1 && (*key1)->type == SEL_ARG::IMPOSSIBLE)
- {
- tree1->type= SEL_TREE::IMPOSSIBLE;
- DBUG_RETURN(tree1);
- }
- result_keys.set_bit(key1 - tree1->keys);
-#ifdef EXTRA_DEBUG
- if (*key1 && param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
- (*key1)->test_use_count(*key1);
-#endif
+ if (imerge->trees+1 == imerge->trees_next)
+ {
+ tree= tree_and(param, tree, *imerge->trees);
+ it.remove();
}
}
- tree1->keys_map= result_keys;
- /* dispose index_merge if there is a "range" option */
- if (!result_keys.is_clear_all())
- {
- tree1->merges.empty();
- DBUG_RETURN(tree1);
- }
+ tree->merges= merges;
+}
- /* ok, both trees are index_merge trees */
- imerge_list_and_list(&tree1->merges, &tree2->merges);
- DBUG_RETURN(tree1);
+
+/*
+ For two trees check that there are indexes with ranges in both of them
+
+ SYNOPSIS
+ sel_trees_have_common_keys()
+ tree1 SEL_TREE for the first tree
+ tree2 SEL_TREE for the second tree
+ common_keys OUT bitmap of all indexes with ranges in both trees
+
+ DESCRIPTION
+ For two trees tree1 and tree1 the function checks if there are indexes
+ in their range parts such that SEL_ARG trees are defined for them in the
+ range parts of both trees. The function returns the bitmap of such
+ indexes in the parameter common_keys.
+
+ RETURN
+ TRUE if there are such indexes (common_keys is nor empty)
+ FALSE otherwise
+*/
+
+static
+bool sel_trees_have_common_keys(SEL_TREE *tree1, SEL_TREE *tree2,
+ key_map *common_keys)
+{
+ *common_keys= tree1->keys_map;
+ common_keys->intersect(tree2->keys_map);
+ return !common_keys->is_clear_all();
}
/*
- Check if two SEL_TREES can be combined into one (i.e. a single key range
- read can be constructed for "cond_of_tree1 OR cond_of_tree2" ) without
- using index_merge.
+ Check whether range parts of two trees can be ored for some indexes
+
+ SYNOPSIS
+ sel_trees_can_be_ored()
+ param Context info for the function
+ tree1 SEL_TREE for the first tree
+ tree2 SEL_TREE for the second tree
+ common_keys IN/OUT IN: bitmap of all indexes with SEL_ARG in both trees
+ OUT: bitmap of all indexes that can be ored
+
+ DESCRIPTION
+ For two trees tree1 and tree2 and the bitmap common_keys containing
+ bits for indexes that have SEL_ARG trees in range parts of both trees
+ the function checks if there are indexes for which SEL_ARG trees can
+ be ored. Two SEL_ARG trees for the same index can be ored if the most
+ major components of the index used in these trees coincide. If the
+ SEL_ARG trees for an index cannot be ored the function clears the bit
+ for this index in the bitmap common_keys.
+
+ The function does not verify that indexes marked in common_keys really
+ have SEL_ARG trees in both tree1 and tree2. It assumes that this is true.
+
+ NOTE
+ The function sel_trees_can_be_ored is usually used in pair with the
+ function sel_trees_have_common_keys.
+
+ RETURN
+ TRUE if there are indexes for which SEL_ARG trees can be ored
+ FALSE otherwise
*/
-bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2,
- RANGE_OPT_PARAM* param)
+static
+bool sel_trees_can_be_ored(RANGE_OPT_PARAM* param,
+ SEL_TREE *tree1, SEL_TREE *tree2,
+ key_map *common_keys)
{
- key_map common_keys= tree1->keys_map;
DBUG_ENTER("sel_trees_can_be_ored");
- common_keys.intersect(tree2->keys_map);
+ if (!sel_trees_have_common_keys(tree1, tree2, common_keys))
+ DBUG_RETURN(FALSE);
+ int key_no;
+ key_map::Iterator it(*common_keys);
+ while ((key_no= it++) != key_map::Iterator::BITMAP_END)
+ {
+ DBUG_ASSERT(tree1->keys[key_no] && tree2->keys[key_no]);
+ /* Trees have a common key, check if they refer to the same key part */
+ if (tree1->keys[key_no]->part != tree2->keys[key_no]->part)
+ common_keys->clear_bit(key_no);
+ }
+ DBUG_RETURN(!common_keys->is_clear_all());
+}
+
+/*
+ Check whether range parts of two trees must be ored for some indexes
+
+ SYNOPSIS
+ sel_trees_must_be_ored()
+ param Context info for the function
+ tree1 SEL_TREE for the first tree
+ tree2 SEL_TREE for the second tree
+ ordable_keys bitmap of SEL_ARG trees that can be ored
+
+ DESCRIPTION
+ For two trees tree1 and tree2 the function checks whether they must be
+ ored. The function assumes that the bitmap ordable_keys contains bits for
+ those corresponding pairs of SEL_ARG trees from tree1 and tree2 that can
+ be ored.
+ We believe that tree1 and tree2 must be ored if any pair of SEL_ARG trees
+ r1 and r2, such that r1 is from tree1 and r2 is from tree2 and both
+ of them are marked in ordable_keys, can be merged.
+
+ NOTE
+ The function sel_trees_must_be_ored as a rule is used in pair with the
+ function sel_trees_can_be_ored.
+
+ RETURN
+ TRUE if there are indexes for which SEL_ARG trees must be ored
+ FALSE otherwise
+*/
+
+static
+bool sel_trees_must_be_ored(RANGE_OPT_PARAM* param,
+ SEL_TREE *tree1, SEL_TREE *tree2,
+ key_map oredable_keys)
+{
+ key_map tmp;
+ DBUG_ENTER("sel_trees_must_be_ored");
- if (common_keys.is_clear_all())
+ tmp= tree1->keys_map;
+ tmp.merge(tree2->keys_map);
+ tmp.subtract(oredable_keys);
+ if (!tmp.is_clear_all())
DBUG_RETURN(FALSE);
- /* trees have a common key, check if they refer to same key part */
- SEL_ARG **key1,**key2;
- for (uint key_no=0; key_no < param->keys; key_no++)
+ int idx1, idx2;
+ key_map::Iterator it1(oredable_keys);
+ while ((idx1= it1++) != key_map::Iterator::BITMAP_END)
{
- if (common_keys.is_set(key_no))
+ KEY_PART *key1_init= param->key[idx1]+tree1->keys[idx1]->part;
+ KEY_PART *key1_end= param->key[idx1]+tree1->keys[idx1]->max_part_no;
+ key_map::Iterator it2(oredable_keys);
+ while ((idx2= it2++) != key_map::Iterator::BITMAP_END)
{
- key1= tree1->keys + key_no;
- key2= tree2->keys + key_no;
- if ((*key1)->part == (*key2)->part)
- {
- DBUG_RETURN(TRUE);
+ if (idx2 <= idx1)
+ continue;
+
+ KEY_PART *key2_init= param->key[idx2]+tree2->keys[idx2]->part;
+ KEY_PART *key2_end= param->key[idx2]+tree2->keys[idx2]->max_part_no;
+ KEY_PART *part1, *part2;
+ for (part1= key1_init, part2= key2_init;
+ part1 < key1_end && part2 < key2_end;
+ part1++, part2++)
+ {
+ if (!part1->field->eq(part2->field))
+ DBUG_RETURN(FALSE);
}
}
}
- DBUG_RETURN(FALSE);
-}
+
+ DBUG_RETURN(TRUE);
+}
/*
- Remove the trees that are not suitable for record retrieval.
+ Remove the trees that are not suitable for record retrieval
+
SYNOPSIS
- param Range analysis parameter
- tree Tree to be processed, tree->type is KEY or KEY_SMALLER
+ remove_nonrange_trees()
+ param Context info for the function
+ tree Tree to be processed, tree->type is KEY or KEY_SMALLER
DESCRIPTION
This function walks through tree->keys[] and removes the SEL_ARG* trees
@@ -6187,41 +8232,36 @@ bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2,
A SEL_ARG* tree cannot be used to construct quick select if it has
tree->part != 0. (e.g. it could represent "keypart2 < const").
-
- WHY THIS FUNCTION IS NEEDED
Normally we allow construction of SEL_TREE objects that have SEL_ARG
- trees that do not allow quick range select construction. For example for
- " keypart1=1 AND keypart2=2 " the execution will proceed as follows:
+ trees that do not allow quick range select construction.
+ For example:
+ for " keypart1=1 AND keypart2=2 " the execution will proceed as follows:
tree1= SEL_TREE { SEL_ARG{keypart1=1} }
tree2= SEL_TREE { SEL_ARG{keypart2=2} } -- can't make quick range select
from this
call tree_and(tree1, tree2) -- this joins SEL_ARGs into a usable SEL_ARG
tree.
-
- There is an exception though: when we construct index_merge SEL_TREE,
- any SEL_ARG* tree that cannot be used to construct quick range select can
- be removed, because current range analysis code doesn't provide any way
- that tree could be later combined with another tree.
- Consider an example: we should not construct
- st1 = SEL_TREE {
- merges = SEL_IMERGE {
- SEL_TREE(t.key1part1 = 1),
- SEL_TREE(t.key2part2 = 2) -- (*)
- }
- };
- because
- - (*) cannot be used to construct quick range select,
- - There is no execution path that would cause (*) to be converted to
- a tree that could be used.
-
- The latter is easy to verify: first, notice that the only way to convert
- (*) into a usable tree is to call tree_and(something, (*)).
-
- Second look at what tree_and/tree_or function would do when passed a
- SEL_TREE that has the structure like st1 tree has, and conlcude that
- tree_and(something, (*)) will not be called.
+ Another example:
+ tree3= SEL_TREE { SEL_ARG{key1part1 = 1} }
+ tree4= SEL_TREE { SEL_ARG{key2part2 = 2} } -- can't make quick range select
+ from this
+ call tree_or(tree3, tree4) -- creates a SEL_MERGE ot of which no index
+ merge can be constructed, but it is potentially useful, as anding it with
+ tree5= SEL_TREE { SEL_ARG{key2part1 = 3} } creates an index merge that
+ represents the formula
+ key1part1=1 AND key2part1=3 OR key2part1=3 AND key2part2=2
+ for which an index merge can be built.
+
+ Any final SEL_TREE may contain SEL_ARG trees for which no quick select
+ can be built. Such SEL_ARG trees should be removed from the range part
+ before different range scans are evaluated. Such SEL_ARG trees also should
+ be removed from all range trees of each index merge before different
+ possible index merge plans are evaluated. If after this removal one
+ of the range trees in the index merge becomes empty the whole index merge
+ must be discarded.
+
RETURN
0 Ok, some suitable trees left
1 No tree->keys[] left.
@@ -6247,6 +8287,74 @@ static bool remove_nonrange_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree)
}
+/*
+ Build a SEL_TREE for a disjunction out of such trees for the disjuncts
+
+ SYNOPSIS
+ tree_or()
+ param Context info for the operation
+ tree1 SEL_TREE for the first disjunct
+ tree2 SEL_TREE for the second disjunct
+
+ DESCRIPTION
+ This function builds a tree for the formula (A OR B) out of the trees
+ tree1 and tree2 that has been built for the formulas A and B respectively.
+
+ In a general case
+ tree1 represents the formula RT1 AND MT1,
+ where RT1=R1_1 AND ... AND R1_k1, MT1=M1_1 AND ... AND M1_l1;
+ tree2 represents the formula RT2 AND MT2
+ where RT2=R2_1 AND ... AND R2_k2, MT2=M2_1 and ... and M2_l2.
+
+ The function constructs the result tree according the formula
+ (RT1 OR RT2) AND (MT1 OR RT1) AND (MT2 OR RT2) AND (MT1 OR MT2)
+ that is equivalent to the formula (RT1 AND MT1) OR (RT2 AND MT2).
+
+ To limit the number of produced imerges the function considers
+ a weaker formula than the original one:
+ (RT1 AND M1_1) OR (RT2 AND M2_1)
+ that is equivalent to:
+ (RT1 OR RT2) (1)
+ AND
+ (M1_1 OR M2_1) (2)
+ AND
+ (M1_1 OR RT2) (3)
+ AND
+ (M2_1 OR RT1) (4)
+
+ For the first conjunct (1) the function builds a tree with a range part
+ and, possibly, one imerge. For the other conjuncts (2-4)the function
+ produces sets of imerges. All constructed imerges are included into the
+ result tree.
+
+ For the formula (1) the function produces the tree representing a formula
+ of the structure RT [AND M], such that:
+ - the range tree rt contains the result of oring SEL_ARG trees from rt1
+ and rt2
+ - the imerge m consists of two range trees rt1 and rt2.
+ The imerge m is added if it's not true that rt1 and rt2 must be ored
+ If rt1 and rt2 can't be ored rt is empty and only m is produced for (1).
+
+ To produce imerges for the formula (2) the function calls the function
+ imerge_list_or_list passing it the merge parts of tree1 and tree2 as
+ parameters.
+
+ To produce imerges for the formula (3) the function calls the function
+ imerge_list_or_tree passing it the imerge m1_1 and the range tree rt2 as
+ parameters. Similarly, to produce imerges for the formula (4) the function
+ calls the function imerge_list_or_tree passing it the imerge m2_1 and the
+ range tree rt1.
+
+ If rt1 is empty then the trees for (1) and (4) are empty.
+ If rt2 is empty then the trees for (1) and (3) are empty.
+ If mt1 is empty then the trees for (2) and (3) are empty.
+ If mt2 is empty then the trees for (2) and (4) are empty.
+
+ RETURN
+ The result tree for the operation if a success
+ 0 - otherwise
+*/
+
static SEL_TREE *
tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
{
@@ -6262,74 +8370,100 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
if (tree2->type == SEL_TREE::MAYBE)
DBUG_RETURN(tree2);
- SEL_TREE *result= 0;
- key_map result_keys;
- result_keys.clear_all();
- if (sel_trees_can_be_ored(tree1, tree2, param))
+ SEL_TREE *result= NULL;
+ key_map result_keys;
+ key_map ored_keys;
+ SEL_TREE *rtree[2]= {NULL,NULL};
+ SEL_IMERGE *imerge[2]= {NULL, NULL};
+ bool no_ranges1= tree1->without_ranges();
+ bool no_ranges2= tree2->without_ranges();
+ bool no_merges1= tree1->without_imerges();
+ bool no_merges2= tree2->without_imerges();
+ if (!no_ranges1 && !no_merges2)
{
- /* Join the trees key per key */
- SEL_ARG **key1,**key2,**end;
- for (key1= tree1->keys,key2= tree2->keys,end= key1+param->keys ;
- key1 != end ; key1++,key2++)
- {
- *key1=key_or(param, *key1, *key2);
- if (*key1)
- {
- result=tree1; // Added to tree1
- result_keys.set_bit(key1 - tree1->keys);
-#ifdef EXTRA_DEBUG
- if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
- (*key1)->test_use_count(*key1);
-#endif
- }
- }
- if (result)
- result->keys_map= result_keys;
+ rtree[0]= new SEL_TREE(tree1, TRUE, param);
+ imerge[1]= new SEL_IMERGE(tree2->merges.head(), 0, param);
}
- else
+ if (!no_ranges2 && !no_merges1)
+ {
+ rtree[1]= new SEL_TREE(tree2, TRUE, param);
+ imerge[0]= new SEL_IMERGE(tree1->merges.head(), 0, param);
+ }
+ bool no_imerge_from_ranges= FALSE;
+ if (!(result= new SEL_TREE()))
+ DBUG_RETURN(result);
+
+ /* Build the range part of the tree for the formula (1) */
+ if (sel_trees_can_be_ored(param, tree1, tree2, &ored_keys))
{
- /* ok, two trees have KEY type but cannot be used without index merge */
- if (tree1->merges.is_empty() && tree2->merges.is_empty())
+ bool must_be_ored= sel_trees_must_be_ored(param, tree1, tree2, ored_keys);
+ no_imerge_from_ranges= must_be_ored;
+ key_map::Iterator it(ored_keys);
+ int key_no;
+ while ((key_no= it++) != key_map::Iterator::BITMAP_END)
{
- if (param->remove_jump_scans)
+ SEL_ARG *key1= tree1->keys[key_no];
+ SEL_ARG *key2= tree2->keys[key_no];
+ if (!must_be_ored)
{
- bool no_trees= remove_nonrange_trees(param, tree1);
- no_trees= no_trees || remove_nonrange_trees(param, tree2);
- if (no_trees)
- DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS));
+ key1->incr_refs();
+ key2->incr_refs();
}
- SEL_IMERGE *merge;
- /* both trees are "range" trees, produce new index merge structure */
- if (!(result= new SEL_TREE()) || !(merge= new SEL_IMERGE()) ||
- (result->merges.push_back(merge)) ||
- (merge->or_sel_tree(param, tree1)) ||
- (merge->or_sel_tree(param, tree2)))
- result= NULL;
- else
- result->type= tree1->type;
- }
- else if (!tree1->merges.is_empty() && !tree2->merges.is_empty())
- {
- if (imerge_list_or_list(param, &tree1->merges, &tree2->merges))
- result= new SEL_TREE(SEL_TREE::ALWAYS);
- else
- result= tree1;
+ if ((result->keys[key_no]= key_or(param, key1, key2)))
+ result->keys_map.set_bit(key_no);
}
- else
- {
- /* one tree is index merge tree and another is range tree */
- if (tree1->merges.is_empty())
- swap_variables(SEL_TREE*, tree1, tree2);
+ result->type= tree1->type;
+ }
- if (param->remove_jump_scans && remove_nonrange_trees(param, tree2))
- DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS));
- /* add tree2 to tree1->merges, checking if it collapses to ALWAYS */
- if (imerge_list_or_tree(param, &tree1->merges, tree2))
- result= new SEL_TREE(SEL_TREE::ALWAYS);
- else
- result= tree1;
- }
+ if (no_imerge_from_ranges && no_merges1 && no_merges2)
+ {
+ if (result->keys_map.is_clear_all())
+ result->type= SEL_TREE::ALWAYS;
+ DBUG_RETURN(result);
}
+
+ SEL_IMERGE *imerge_from_ranges;
+ if (!(imerge_from_ranges= new SEL_IMERGE()))
+ result= NULL;
+ else if (!no_ranges1 && !no_ranges2 && !no_imerge_from_ranges)
+ {
+ /* Build the imerge part of the tree for the formula (1) */
+ SEL_TREE *rt1= tree1;
+ SEL_TREE *rt2= tree2;
+ if (no_merges1)
+ rt1= new SEL_TREE(tree1, TRUE, param);
+ if (no_merges2)
+ rt2= new SEL_TREE(tree2, TRUE, param);
+ if (!rt1 || !rt2 ||
+ result->merges.push_back(imerge_from_ranges) ||
+ imerge_from_ranges->or_sel_tree(param, rt1) ||
+ imerge_from_ranges->or_sel_tree(param, rt2))
+ result= NULL;
+ }
+ if (!result)
+ DBUG_RETURN(result);
+
+ result->type= tree1->type;
+
+ if (!no_merges1 && !no_merges2 &&
+ !imerge_list_or_list(param, &tree1->merges, &tree2->merges))
+ {
+ /* Build the imerges for the formula (2) */
+ imerge_list_and_list(&result->merges, &tree1->merges);
+ }
+
+ /* Build the imerges for the formulas (3) and (4) */
+ for (uint i=0; i < 2; i++)
+ {
+ List<SEL_IMERGE> merges;
+ SEL_TREE *rt= rtree[i];
+ SEL_IMERGE *im= imerge[1-i];
+
+ if (rt && im && !merges.push_back(im) &&
+ !imerge_list_or_tree(param, &merges, rt))
+ imerge_list_and_list(&result->merges, &merges);
+ }
+
DBUG_RETURN(result);
}
@@ -6375,6 +8509,7 @@ and_all_keys(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
if (!key1)
return &null_element; // Impossible ranges
key1->use_count++;
+ key1->max_part_no= max(key2->max_part_no, key2->part+1);
return key1;
}
@@ -6467,6 +8602,7 @@ key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
key1->use_count--;
key2->use_count--;
SEL_ARG *e1=key1->first(), *e2=key2->first(), *new_tree=0;
+ uint max_part_no= max(key1->max_part_no, key2->max_part_no);
while (e1 && e2)
{
@@ -6504,6 +8640,7 @@ key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
key2->free_tree();
if (!new_tree)
return &null_element; // Impossible range
+ new_tree->max_part_no= max_part_no;
return new_tree;
}
@@ -6609,7 +8746,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
{
key1->free_tree();
key2->free_tree();
- return 0; // Can't optimize this
+ return 0; // Can't optimize this
}
// If one of the key is MAYBE_KEY then the found region may be bigger
@@ -6632,247 +8769,555 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
{
swap_variables(SEL_ARG *,key1,key2);
}
- if (key1->use_count > 0 || !(key1=key1->clone_tree(param)))
- return 0; // OOM
+ if (key1->use_count > 0 && !(key1=key1->clone_tree(param)))
+ return 0; // OOM
}
// Add tree at key2 to tree at key1
bool key2_shared=key2->use_count != 0;
key1->maybe_flag|=key2->maybe_flag;
+ /*
+ Notation for illustrations used in the rest of this function:
+
+ Range: [--------]
+ ^ ^
+ start stop
+
+ Two overlapping ranges:
+ [-----] [----] [--]
+ [---] or [---] or [-------]
+
+ Ambiguity: ***
+ The range starts or stops somewhere in the "***" range.
+ Example: a starts before b and may end before/the same plase/after b
+ a: [----***]
+ b: [---]
+
+ Adjacent ranges:
+ Ranges that meet but do not overlap. Example: a = "x < 3", b = "x >= 3"
+ a: ----]
+ b: [----
+ */
+
+ uint max_part_no= max(key1->max_part_no, key2->max_part_no);
+
for (key2=key2->first(); key2; )
{
- SEL_ARG *tmp=key1->find_range(key2); // Find key1.min <= key2.min
- int cmp;
+ /*
+ key1 consists of one or more ranges. tmp is the range currently
+ being handled.
+
+ initialize tmp to the latest range in key1 that starts the same
+ place or before the range in key2 starts
+
+ key2: [------]
+ key1: [---] [-----] [----]
+ ^
+ tmp
+ */
+ SEL_ARG *tmp=key1->find_range(key2);
+
+ /*
+ Used to describe how two key values are positioned compared to
+ each other. Consider key_value_a.<cmp_func>(key_value_b):
+
+ -2: key_value_a is smaller than key_value_b, and they are adjacent
+ -1: key_value_a is smaller than key_value_b (not adjacent)
+ 0: the key values are equal
+ 1: key_value_a is bigger than key_value_b (not adjacent)
+ -2: key_value_a is bigger than key_value_b, and they are adjacent
+
+ Example: "cmp= tmp->cmp_max_to_min(key2)"
+
+ key2: [-------- (10 <= x ...)
+ tmp: -----] (... x < 10) => cmp==-2
+ tmp: ----] (... x <= 9) => cmp==-1
+ tmp: ------] (... x = 10) => cmp== 0
+ tmp: --------] (... x <= 12) => cmp== 1
+ (cmp == 2 does not make sense for cmp_max_to_min())
+ */
+ int cmp= 0;
if (!tmp)
{
- tmp=key1->first(); // tmp.min > key2.min
+ /*
+ The range in key2 starts before the first range in key1. Use
+ the first range in key1 as tmp.
+
+ key2: [--------]
+ key1: [****--] [----] [-------]
+ ^
+ tmp
+ */
+ tmp=key1->first();
cmp= -1;
}
- else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
- { // Found tmp.max < key2.min
+ else if ((cmp= tmp->cmp_max_to_min(key2)) < 0)
+ {
+ /*
+ This is the case:
+ key2: [-------]
+ tmp: [----**]
+ */
SEL_ARG *next=tmp->next;
- /* key1 on the left of key2 non-overlapping */
if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
{
- // Join near ranges like tmp.max < 0 and key2.min >= 0
- SEL_ARG *key2_next=key2->next;
- if (key2_shared)
- {
- if (!(key2=new SEL_ARG(*key2)))
- return 0; // out of memory
- key2->increment_use_count(key1->use_count+1);
- key2->next=key2_next; // New copy of key2
- }
- key2->copy_min(tmp);
- if (!(key1=key1->tree_delete(tmp)))
- { // Only one key in tree
- key1=key2;
- key1->make_root();
- key2=key2_next;
- break;
- }
+ /*
+ Adjacent (cmp==-2) and equal next_key_parts => ranges can be merged
+
+ This is the case:
+ key2: [-------]
+ tmp: [----]
+
+ Result:
+ key2: [-------------] => inserted into key1 below
+ tmp: => deleted
+ */
+ SEL_ARG *key2_next=key2->next;
+ if (key2_shared)
+ {
+ if (!(key2=new SEL_ARG(*key2)))
+ return 0; // out of memory
+ key2->increment_use_count(key1->use_count+1);
+ key2->next=key2_next; // New copy of key2
+ }
+
+ key2->copy_min(tmp);
+ if (!(key1=key1->tree_delete(tmp)))
+ { // Only one key in tree
+ key1=key2;
+ key1->make_root();
+ key2=key2_next;
+ break;
+ }
}
- if (!(tmp=next)) // tmp.min > key2.min
- break; // Copy rest of key2
+ if (!(tmp=next)) // Move to next range in key1. Now tmp.min > key2.min
+ break; // No more ranges in key1. Copy rest of key2
}
+
if (cmp < 0)
- { // tmp.min > key2.min
+ {
+ /*
+ This is the case:
+ key2: [--***]
+ tmp: [----]
+ */
int tmp_cmp;
- if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
+ if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0)
{
- /* tmp is on the right of key2 non-overlapping */
- if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
- { // ranges are connected
- tmp->copy_min_to_min(key2);
- key1->merge_flags(key2);
- if (tmp->min_flag & NO_MIN_RANGE &&
- tmp->max_flag & NO_MAX_RANGE)
- {
- if (key1->maybe_flag)
- return new SEL_ARG(SEL_ARG::MAYBE_KEY);
- return 0;
- }
- key2->increment_use_count(-1); // Free not used tree
- key2=key2->next;
- continue;
- }
- else
- {
- SEL_ARG *next=key2->next; // Keys are not overlapping
- if (key2_shared)
- {
- SEL_ARG *cpy= new SEL_ARG(*key2); // Must make copy
- if (!cpy)
- return 0; // OOM
- key1=key1->insert(cpy);
- key2->increment_use_count(key1->use_count+1);
- }
- else
- key1=key1->insert(key2); // Will destroy key2_root
- key2=next;
- continue;
- }
+ /*
+ This is the case:
+ key2: [------**]
+ tmp: [----]
+ */
+ if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
+ {
+ /*
+ Adjacent ranges with equal next_key_part. Merge like this:
+
+ This is the case:
+ key2: [------]
+ tmp: [-----]
+
+ Result:
+ key2: [------]
+ tmp: [-------------]
+
+ Then move on to next key2 range.
+ */
+ tmp->copy_min_to_min(key2);
+ key1->merge_flags(key2);
+ if (tmp->min_flag & NO_MIN_RANGE &&
+ tmp->max_flag & NO_MAX_RANGE)
+ {
+ if (key1->maybe_flag)
+ return new SEL_ARG(SEL_ARG::MAYBE_KEY);
+ return 0;
+ }
+ key2->increment_use_count(-1); // Free not used tree
+ key2=key2->next;
+ continue;
+ }
+ else
+ {
+ /*
+ key2 not adjacent to tmp or has different next_key_part.
+ Insert into key1 and move to next range in key2
+
+ This is the case:
+ key2: [------**]
+ tmp: [----]
+
+ Result:
+ key1_ [------**][----]
+ ^ ^
+ insert tmp
+ */
+ SEL_ARG *next=key2->next;
+ if (key2_shared)
+ {
+ SEL_ARG *cpy= new SEL_ARG(*key2); // Must make copy
+ if (!cpy)
+ return 0; // OOM
+ key1=key1->insert(cpy);
+ key2->increment_use_count(key1->use_count+1);
+ }
+ else
+ key1=key1->insert(key2); // Will destroy key2_root
+ key2=next;
+ continue;
+ }
}
}
- /*
- tmp.min >= key2.min && tmp.min <= key.max (overlapping ranges)
- key2.min <= tmp.min <= key2.max
- */
+ /*
+ The ranges in tmp and key2 are overlapping:
+
+ key2: [----------]
+ tmp: [*****-----*****]
+
+ Corollary: tmp.min <= key2.max
+ */
if (eq_tree(tmp->next_key_part,key2->next_key_part))
{
+ // Merge overlapping ranges with equal next_key_part
if (tmp->is_same(key2))
{
- /*
- Found exact match of key2 inside key1.
+ /*
+ Found exact match of key2 inside key1.
Use the relevant range in key1.
*/
- tmp->merge_flags(key2); // Copy maybe flags
- key2->increment_use_count(-1); // Free not used tree
+ tmp->merge_flags(key2); // Copy maybe flags
+ key2->increment_use_count(-1); // Free not used tree
}
else
{
- SEL_ARG *last=tmp;
- SEL_ARG *first=tmp;
- /*
- Find the last range in tmp that overlaps key2 and has the same
- condition on the rest of the keyparts.
+ SEL_ARG *last= tmp;
+ SEL_ARG *first= tmp;
+
+ /*
+ Find the last range in key1 that overlaps key2 and
+ where all ranges first...last have the same next_key_part as
+ key2.
+
+ key2: [****----------------------*******]
+ key1: [--] [----] [---] [-----] [xxxx]
+ ^ ^ ^
+ first last different next_key_part
+
+ Since key2 covers them, the ranges between first and last
+ are merged into one range by deleting first...last-1 from
+ the key1 tree. In the figure, this applies to first and the
+ two consecutive ranges. The range of last is then extended:
+ * last.min: Set to min(key2.min, first.min)
+ * last.max: If there is a last->next that overlaps key2 (i.e.,
+ last->next has a different next_key_part):
+ Set adjacent to last->next.min
+ Otherwise: Set to max(key2.max, last.max)
+
+ Result:
+ key2: [****----------------------*******]
+ [--] [----] [---] => deleted from key1
+ key1: [**------------------------***][xxxx]
+ ^ ^
+ tmp=last different next_key_part
*/
- while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
- eq_tree(last->next->next_key_part,key2->next_key_part))
- {
+ while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
+ eq_tree(last->next->next_key_part,key2->next_key_part))
+ {
/*
- We've found the last overlapping key1 range in last.
- This means that the ranges between (and including) the
- first overlapping range (tmp) and the last overlapping range
- (last) are fully nested into the current range of key2
- and can safely be discarded. We just need the minimum endpoint
- of the first overlapping range (tmp) so we can compare it with
- the minimum endpoint of the enclosing key2 range.
+ last->next is covered by key2 and has same next_key_part.
+ last can be deleted
*/
- SEL_ARG *save=last;
- last=last->next;
- key1=key1->tree_delete(save);
- }
+ SEL_ARG *save=last;
+ last=last->next;
+ key1=key1->tree_delete(save);
+ }
+ // Redirect tmp to last which will cover the entire range
+ tmp= last;
+
/*
- The tmp range (the first overlapping range) could have been discarded
- by the previous loop. We should re-direct tmp to the new united range
- that's taking its place.
+ We need the minimum endpoint of first so we can compare it
+ with the minimum endpoint of the enclosing key2 range.
*/
- tmp= last;
last->copy_min(first);
bool full_range= last->copy_min(key2);
if (!full_range)
{
if (last->next && key2->cmp_max_to_min(last->next) >= 0)
{
- last->max_value= last->next->min_value;
- if (last->next->min_flag & NEAR_MIN)
- last->max_flag&= ~NEAR_MAX;
- else
- last->max_flag|= NEAR_MAX;
+ /*
+ This is the case:
+ key2: [-------------]
+ key1: [***------] [xxxx]
+ ^ ^
+ last different next_key_part
+
+ Extend range of last up to last->next:
+ key2: [-------------]
+ key1: [***--------][xxxx]
+ */
+ last->copy_min_to_max(last->next);
}
else
+ /*
+ This is the case:
+ key2: [--------*****]
+ key1: [***---------] [xxxx]
+ ^ ^
+ last different next_key_part
+
+ Extend range of last up to max(last.max, key2.max):
+ key2: [--------*****]
+ key1: [***----------**] [xxxx]
+ */
full_range= last->copy_max(key2);
}
- if (full_range)
- { // Full range
- key1->free_tree();
- for (; key2 ; key2=key2->next)
- key2->increment_use_count(-1); // Free not used tree
- if (key1->maybe_flag)
- return new SEL_ARG(SEL_ARG::MAYBE_KEY);
- return 0;
- }
+ if (full_range)
+ { // Full range
+ key1->free_tree();
+ for (; key2 ; key2=key2->next)
+ key2->increment_use_count(-1); // Free not used tree
+ if (key1->maybe_flag)
+ return new SEL_ARG(SEL_ARG::MAYBE_KEY);
+ return 0;
+ }
}
}
if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
- { // tmp.min <= x < key2.min
+ {
+ /*
+ This is the case ("cmp>=0" means that tmp.max >= key2.min):
+ key2: [----]
+ tmp: [------------*****]
+ */
+
+ if (!tmp->next_key_part)
+ {
+ /*
+ tmp->next_key_part is empty: cut the range that is covered
+ by tmp from key2.
+ Reason: (key2->next_key_part OR tmp->next_key_part) will be
+ empty and therefore equal to tmp->next_key_part. Thus, this
+ part of the key2 range is completely covered by tmp.
+ */
+ if (tmp->cmp_max_to_max(key2) >= 0)
+ {
+ /*
+ tmp covers the entire range in key2.
+ key2: [----]
+ tmp: [-----------------]
+
+ Move on to next range in key2
+ */
+ key2->increment_use_count(-1); // Free not used tree
+ key2=key2->next;
+ continue;
+ }
+ else
+ {
+ /*
+ This is the case:
+ key2: [-------]
+ tmp: [---------]
+
+ Result:
+ key2: [---]
+ tmp: [---------]
+ */
+ if (key2->use_count)
+ {
+ SEL_ARG *key2_cpy= new SEL_ARG(*key2);
+ if (key2_cpy)
+ return 0;
+ key2= key2_cpy;
+ }
+ key2->copy_max_to_min(tmp);
+ continue;
+ }
+ }
+
+ /*
+ The ranges are overlapping but have not been merged because
+ next_key_part of tmp and key2 differ.
+ key2: [----]
+ tmp: [------------*****]
+
+ Split tmp in two where key2 starts:
+ key2: [----]
+ key1: [--------][--*****]
+ ^ ^
+ insert tmp
+ */
SEL_ARG *new_arg=tmp->clone_first(key2);
if (!new_arg)
- return 0; // OOM
- if ((new_arg->next_key_part= key1->next_key_part))
- new_arg->increment_use_count(key1->use_count+1);
+ return 0; // OOM
+ if ((new_arg->next_key_part= tmp->next_key_part))
+ new_arg->increment_use_count(key1->use_count+1);
tmp->copy_min_to_min(key2);
key1=key1->insert(new_arg);
- }
+ } // tmp.min >= key2.min due to this if()
- // tmp.min >= key2.min && tmp.min <= key2.max
- SEL_ARG key(*key2); // Get copy we can modify
+ /*
+ Now key2.min <= tmp.min <= key2.max:
+ key2: [---------]
+ tmp: [****---*****]
+ */
+ SEL_ARG key2_cpy(*key2); // Get copy we can modify
for (;;)
{
- if (tmp->cmp_min_to_min(&key) > 0)
- { // key.min <= x < tmp.min
- SEL_ARG *new_arg=key.clone_first(tmp);
- if (!new_arg)
- return 0; // OOM
- if ((new_arg->next_key_part=key.next_key_part))
- new_arg->increment_use_count(key1->use_count+1);
- key1=key1->insert(new_arg);
- }
- if ((cmp=tmp->cmp_max_to_max(&key)) <= 0)
- { // tmp.min. <= x <= tmp.max
- tmp->maybe_flag|= key.maybe_flag;
- key.increment_use_count(key1->use_count+1);
- tmp->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
- if (!cmp) // Key2 is ready
- break;
- key.copy_max_to_min(tmp);
- if (!(tmp=tmp->next))
- {
- SEL_ARG *tmp2= new SEL_ARG(key);
- if (!tmp2)
- return 0; // OOM
- key1=key1->insert(tmp2);
- key2=key2->next;
- goto end;
- }
- if (tmp->cmp_min_to_max(&key) > 0)
- {
- SEL_ARG *tmp2= new SEL_ARG(key);
- if (!tmp2)
- return 0; // OOM
- key1=key1->insert(tmp2);
- break;
- }
+ if (tmp->cmp_min_to_min(&key2_cpy) > 0)
+ {
+ /*
+ This is the case:
+ key2_cpy: [------------]
+ key1: [-*****]
+ ^
+ tmp
+
+ Result:
+ key2_cpy: [---]
+ key1: [-------][-*****]
+ ^ ^
+ insert tmp
+ */
+ SEL_ARG *new_arg=key2_cpy.clone_first(tmp);
+ if (!new_arg)
+ return 0; // OOM
+ if ((new_arg->next_key_part=key2_cpy.next_key_part))
+ new_arg->increment_use_count(key1->use_count+1);
+ key1=key1->insert(new_arg);
+ key2_cpy.copy_min_to_min(tmp);
+ }
+ // Now key2_cpy.min == tmp.min
+
+ if ((cmp= tmp->cmp_max_to_max(&key2_cpy)) <= 0)
+ {
+ /*
+ tmp.max <= key2_cpy.max:
+ key2_cpy: a) [-------] or b) [----]
+ tmp: [----] [----]
+
+ Steps:
+ 1) Update next_key_part of tmp: OR it with key2_cpy->next_key_part.
+ 2) If case a: Insert range [tmp.max, key2_cpy.max] into key1 using
+ next_key_part of key2_cpy
+
+ Result:
+ key1: a) [----][-] or b) [----]
+ */
+ tmp->maybe_flag|= key2_cpy.maybe_flag;
+ key2_cpy.increment_use_count(key1->use_count+1);
+ tmp->next_key_part= key_or(param, tmp->next_key_part,
+ key2_cpy.next_key_part);
+
+ if (!cmp)
+ break; // case b: done with this key2 range
+
+ // Make key2_cpy the range [tmp.max, key2_cpy.max]
+ key2_cpy.copy_max_to_min(tmp);
+ if (!(tmp=tmp->next))
+ {
+ /*
+ No more ranges in key1. Insert key2_cpy and go to "end"
+ label to insert remaining ranges in key2 if any.
+ */
+ SEL_ARG *tmp2= new SEL_ARG(key2_cpy);
+ if (!tmp2)
+ return 0; // OOM
+ key1=key1->insert(tmp2);
+ key2=key2->next;
+ goto end;
+ }
+ if (tmp->cmp_min_to_max(&key2_cpy) > 0)
+ {
+ /*
+ The next range in key1 does not overlap with key2_cpy.
+ Insert this range into key1 and move on to the next range
+ in key2.
+ */
+ SEL_ARG *tmp2= new SEL_ARG(key2_cpy);
+ if (!tmp2)
+ return 0; // OOM
+ key1=key1->insert(tmp2);
+ break;
+ }
+ /*
+ key2_cpy overlaps with the next range in key1 and the case
+ is now "key2.min <= tmp.min <= key2.max". Go back to for(;;)
+ to handle this situation.
+ */
+ continue;
}
else
{
- SEL_ARG *new_arg=tmp->clone_last(&key); // tmp.min <= x <= key.max
- if (!new_arg)
- return 0; // OOM
- tmp->copy_max_to_min(&key);
- tmp->increment_use_count(key1->use_count+1);
- /* Increment key count as it may be used for next loop */
- key.increment_use_count(1);
- new_arg->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
- key1=key1->insert(new_arg);
- break;
+ /*
+ This is the case:
+ key2_cpy: [-------]
+ tmp: [------------]
+
+ Result:
+ key1: [-------][---]
+ ^ ^
+ new_arg tmp
+ Steps:
+ 0) If tmp->next_key_part is empty: do nothing. Reason:
+ (key2_cpy->next_key_part OR tmp->next_key_part) will be
+ empty and therefore equal to tmp->next_key_part. Thus,
+ the range in key2_cpy is completely covered by tmp
+ 1) Make new_arg with range [tmp.min, key2_cpy.max].
+ new_arg->next_key_part is OR between next_key_part
+ of tmp and key2_cpy
+ 2) Make tmp the range [key2.max, tmp.max]
+ 3) Insert new_arg into key1
+ */
+ if (!tmp->next_key_part) // Step 0
+ {
+ key2_cpy.increment_use_count(-1); // Free not used tree
+ break;
+ }
+ SEL_ARG *new_arg=tmp->clone_last(&key2_cpy);
+ if (!new_arg)
+ return 0; // OOM
+ tmp->copy_max_to_min(&key2_cpy);
+ tmp->increment_use_count(key1->use_count+1);
+ /* Increment key count as it may be used for next loop */
+ key2_cpy.increment_use_count(1);
+ new_arg->next_key_part= key_or(param, tmp->next_key_part,
+ key2_cpy.next_key_part);
+ key1=key1->insert(new_arg);
+ break;
}
}
- key2=key2->next;
+ // Move on to next range in key2
+ key2=key2->next;
}
end:
+ /*
+ Add key2 ranges that are non-overlapping with and higher than the
+ highest range in key1.
+ */
while (key2)
{
SEL_ARG *next=key2->next;
if (key2_shared)
{
- SEL_ARG *tmp=new SEL_ARG(*key2); // Must make copy
+ SEL_ARG *tmp=new SEL_ARG(*key2); // Must make copy
if (!tmp)
- return 0;
+ return 0;
key2->increment_use_count(key1->use_count+1);
key1=key1->insert(tmp);
}
else
- key1=key1->insert(key2); // Will destroy key2_root
+ key1=key1->insert(key2); // Will destroy key2_root
key2=next;
}
key1->use_count++;
+
+ key1->max_part_no= max_part_no;
return key1;
}
@@ -7348,11 +9793,7 @@ static ulong count_key_part_usage(SEL_ARG *root, SEL_ARG *key)
void SEL_ARG::test_use_count(SEL_ARG *root)
{
uint e_count=0;
- if (this == root && use_count != 1)
- {
- sql_print_information("Use_count: Wrong count %lu for root",use_count);
- return;
- }
+
if (this->type != SEL_ARG::KEY_RANGE)
return;
for (SEL_ARG *pos=first(); pos ; pos=pos->next)
@@ -7377,324 +9818,130 @@ 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= HA_POS_ERROR;
+ 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) &&
+ !(file->index_flags(keynr, param->max_key_part, 1) & HA_CLUSTERED_INDEX))
+ *mrr_flags |= HA_MRR_INDEX_ONLY;
+
+ if (param->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;
+ /*
+ Skip materialized derived table/view result table from MRR check as
+ they aren't contain any data yet.
+ */
+ if (param->table->pos_in_table_list->is_non_derived())
+ rows= file->multi_range_read_info_const(keynr, &seq_if, (void*)&seq, 0,
+ bufsize, mrr_flags, cost);
+ if (rows != HA_POS_ERROR)
{
+ param->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);
+ param->table->quick_rows[keynr]= 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)
- {
- /*
- 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;
- }
-
- 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->table->s->primary_key == keynr && pk_is_clustered)
{
- tmp_min_flag= min_key_flag | key_tree->min_flag;
- tmp_max_flag= max_key_flag | key_tree->max_flag;
+ /* Clustered PK scan is always a ROR scan (TODO: same as above) */
+ param->is_ror_scan= TRUE;
}
-
- 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)
+ else if (param->range_count > 1)
{
- 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.
}
@@ -7722,13 +9969,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
@@ -7741,9 +9989,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;
@@ -7768,12 +10026,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.
@@ -7784,25 +10044,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))
{
@@ -7811,6 +10072,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],
@@ -7959,7 +10222,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)
{
@@ -7979,7 +10255,7 @@ bool QUICK_SELECT_I::is_keys_used(const MY_BITMAP *fields)
return is_key_used(head, index, fields);
}
-bool QUICK_INDEX_MERGE_SELECT::is_keys_used(const MY_BITMAP *fields)
+bool QUICK_INDEX_SORT_SELECT::is_keys_used(const MY_BITMAP *fields)
{
QUICK_RANGE_SELECT *quick;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
@@ -8016,6 +10292,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.
@@ -8044,10 +10333,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;
/*
@@ -8056,7 +10347,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;
@@ -8110,8 +10401,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;
@@ -8135,13 +10443,23 @@ err:
other error
*/
-int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
+int read_keys_and_merge_scans(THD *thd,
+ TABLE *head,
+ List<QUICK_RANGE_SELECT> quick_selects,
+ QUICK_RANGE_SELECT *pk_quick_select,
+ READ_RECORD *read_record,
+ bool intersection,
+ key_map *filtered_scans,
+ Unique **unique_ptr)
{
List_iterator_fast<QUICK_RANGE_SELECT> cur_quick_it(quick_selects);
QUICK_RANGE_SELECT* cur_quick;
int result;
+ Unique *unique= *unique_ptr;
handler *file= head->file;
- DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge");
+ bool with_cpk_filter= pk_quick_select != NULL;
+
+ DBUG_ENTER("read_keys_and_merge");
/* We're going to just read rowids. */
if (!head->key_read)
@@ -8152,6 +10470,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
cur_quick_it.rewind();
cur_quick= cur_quick_it++;
+ bool first_quick= TRUE;
DBUG_ASSERT(cur_quick != 0);
/*
@@ -8169,9 +10488,11 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
unique= new Unique(refpos_order_cmp, (void *)file,
file->ref_length,
- thd->variables.sortbuff_size);
+ thd->variables.sortbuff_size,
+ intersection ? quick_selects.elements : 0);
if (!unique)
goto err;
+ *unique_ptr= unique;
}
else
unique->reset();
@@ -8183,6 +10504,14 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
{
while ((result= cur_quick->get_next()) == HA_ERR_END_OF_FILE)
{
+ if (intersection)
+ with_cpk_filter= filtered_scans->is_set(cur_quick->index);
+ if (first_quick)
+ {
+ first_quick= FALSE;
+ if (intersection && unique->is_in_memory())
+ unique->close_for_expansion();
+ }
cur_quick->range_end();
cur_quick= cur_quick_it++;
if (!cur_quick)
@@ -8207,8 +10536,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
if (thd->killed)
goto err;
- /* skip row if it will be retrieved by clustered PK scan */
- if (pk_quick_select && pk_quick_select->row_in_ranges())
+ if (with_cpk_filter &&
+ pk_quick_select->row_in_ranges() != intersection )
continue;
cur_quick->file->position(cur_quick->record);
@@ -8222,14 +10551,13 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
sequence.
*/
result= unique->get(head);
- doing_pk_scan= FALSE;
/*
- index_merge currently doesn't support "using index" at all
+ index merge currently doesn't support "using index" at all
*/
head->disable_keyread();
- if (init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE))
+ if (init_read_record(read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE))
result= 1;
- DBUG_RETURN(result);
+ DBUG_RETURN(result);
err:
head->disable_keyread();
@@ -8237,6 +10565,17 @@ err:
}
+int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
+
+{
+ int result;
+ DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge");
+ result= read_keys_and_merge_scans(thd, head, quick_selects, pk_quick_select,
+ &read_record, FALSE, NULL, &unique);
+ doing_pk_scan= FALSE;
+ DBUG_RETURN(result);
+}
+
/*
Get next row for index_merge.
NOTES
@@ -8273,6 +10612,32 @@ int QUICK_INDEX_MERGE_SELECT::get_next()
DBUG_RETURN(result);
}
+int QUICK_INDEX_INTERSECT_SELECT::read_keys_and_merge()
+
+{
+ int result;
+ DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::read_keys_and_merge");
+ result= read_keys_and_merge_scans(thd, head, quick_selects, pk_quick_select,
+ &read_record, TRUE, &filtered_scans,
+ &unique);
+ DBUG_RETURN(result);
+}
+
+int QUICK_INDEX_INTERSECT_SELECT::get_next()
+{
+ int result;
+ DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::get_next");
+
+ if ((result= read_record.read_record(&read_record)) == -1)
+ {
+ result= HA_ERR_END_OF_FILE;
+ end_read_record(&read_record);
+ free_io_cache(head);
+ }
+
+ DBUG_RETURN(result);
+}
+
/*
Retrieve next record.
@@ -8433,12 +10798,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)
@@ -8463,12 +10828,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)
@@ -8479,69 +10844,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);
}
@@ -8562,13 +10901,8 @@ int QUICK_RANGE_SELECT::reset()
int QUICK_RANGE_SELECT::get_next()
{
- int result;
- KEY_MULTI_RANGE *mrange;
+ range_id_t 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)
{
/*
@@ -8578,46 +10912,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 */
@@ -8626,6 +10922,7 @@ end:
DBUG_RETURN(result);
}
+
/*
Get the next record with a different prefix.
@@ -8664,9 +10961,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);
@@ -8795,7 +11090,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)
{
@@ -8804,9 +11100,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;
@@ -8915,6 +11211,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)
@@ -8984,30 +11281,53 @@ bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range_arg)
}
-void QUICK_RANGE_SELECT::add_info_string(String *str)
+void QUICK_SELECT_I::add_key_name(String *str, bool *first)
{
KEY *key_info= head->key_info + index;
+
+ if (*first)
+ *first= FALSE;
+ else
+ str->append(',');
str->append(key_info->name);
}
+
+
+void QUICK_RANGE_SELECT::add_info_string(String *str)
+{
+ bool first= TRUE;
+
+ add_key_name(str, &first);
+}
void QUICK_INDEX_MERGE_SELECT::add_info_string(String *str)
{
QUICK_RANGE_SELECT *quick;
bool first= TRUE;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
+
str->append(STRING_WITH_LEN("sort_union("));
while ((quick= it++))
{
- if (!first)
- str->append(',');
- else
- first= FALSE;
- quick->add_info_string(str);
+ quick->add_key_name(str, &first);
}
if (pk_quick_select)
+ pk_quick_select->add_key_name(str, &first);
+ str->append(')');
+}
+
+void QUICK_INDEX_INTERSECT_SELECT::add_info_string(String *str)
+{
+ QUICK_RANGE_SELECT *quick;
+ bool first= TRUE;
+ List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
+
+ str->append(STRING_WITH_LEN("sort_intersect("));
+ if (pk_quick_select)
+ pk_quick_select->add_key_name(str, &first);
+ while ((quick= it++))
{
- str->append(',');
- pk_quick_select->add_info_string(str);
+ quick->add_key_name(str, &first);
}
str->append(')');
}
@@ -9017,130 +11337,125 @@ void QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str)
bool first= TRUE;
QUICK_SELECT_WITH_RECORD *qr;
List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects);
+
str->append(STRING_WITH_LEN("intersect("));
while ((qr= it++))
{
- KEY *key_info= head->key_info + qr->quick->index;
- if (!first)
- str->append(',');
- else
- first= FALSE;
- str->append(key_info->name);
+ qr->quick->add_key_name(str, &first);
}
if (cpk_quick)
- {
- KEY *key_info= head->key_info + cpk_quick->index;
- str->append(',');
- str->append(key_info->name);
- }
+ cpk_quick->add_key_name(str, &first);
str->append(')');
}
+
void QUICK_ROR_UNION_SELECT::add_info_string(String *str)
{
- bool first= TRUE;
QUICK_SELECT_I *quick;
+ bool first= TRUE;
List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
+
str->append(STRING_WITH_LEN("union("));
while ((quick= it++))
{
- if (!first)
- str->append(',');
- else
+ if (first)
first= FALSE;
+ else
+ str->append(',');
quick->add_info_string(str);
}
str->append(')');
}
-void QUICK_RANGE_SELECT::add_keys_and_lengths(String *key_names,
- String *used_lengths)
+void QUICK_SELECT_I::add_key_and_length(String *key_names,
+ String *used_lengths,
+ bool *first)
{
char buf[64];
uint length;
KEY *key_info= head->key_info + index;
+
+ if (*first)
+ *first= FALSE;
+ else
+ {
+ key_names->append(',');
+ used_lengths->append(',');
+ }
key_names->append(key_info->name);
length= longlong10_to_str(max_used_key_length, buf, 10) - buf;
used_lengths->append(buf, length);
}
+
+void QUICK_RANGE_SELECT::add_keys_and_lengths(String *key_names,
+ String *used_lengths)
+{
+ bool first= TRUE;
+
+ add_key_and_length(key_names, used_lengths, &first);
+}
+
void QUICK_INDEX_MERGE_SELECT::add_keys_and_lengths(String *key_names,
String *used_lengths)
{
- char buf[64];
- uint length;
- bool first= TRUE;
QUICK_RANGE_SELECT *quick;
+ bool first= TRUE;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
+
while ((quick= it++))
{
- if (first)
- first= FALSE;
- else
- {
- key_names->append(',');
- used_lengths->append(',');
- }
-
- KEY *key_info= head->key_info + quick->index;
- key_names->append(key_info->name);
- length= longlong10_to_str(quick->max_used_key_length, buf, 10) - buf;
- used_lengths->append(buf, length);
+ quick->add_key_and_length(key_names, used_lengths, &first);
}
+
+ if (pk_quick_select)
+ pk_quick_select->add_key_and_length(key_names, used_lengths, &first);
+}
+
+
+void QUICK_INDEX_INTERSECT_SELECT::add_keys_and_lengths(String *key_names,
+ String *used_lengths)
+{
+ QUICK_RANGE_SELECT *quick;
+ bool first= TRUE;
+
+ List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
+
if (pk_quick_select)
+ pk_quick_select->add_key_and_length(key_names, used_lengths, &first);
+
+ while ((quick= it++))
{
- KEY *key_info= head->key_info + pk_quick_select->index;
- key_names->append(',');
- key_names->append(key_info->name);
- length= (longlong10_to_str(pk_quick_select->max_used_key_length, buf, 10)
- - buf);
- used_lengths->append(',');
- used_lengths->append(buf, length);
+ quick->add_key_and_length(key_names, used_lengths, &first);
}
}
void QUICK_ROR_INTERSECT_SELECT::add_keys_and_lengths(String *key_names,
String *used_lengths)
{
- char buf[64];
- uint length;
- bool first= TRUE;
QUICK_SELECT_WITH_RECORD *qr;
+ bool first= TRUE;
+
List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects);
+
while ((qr= it++))
{
- KEY *key_info= head->key_info + qr->quick->index;
- if (first)
- first= FALSE;
- else
- {
- key_names->append(',');
- used_lengths->append(',');
- }
- key_names->append(key_info->name);
- length= longlong10_to_str(qr->quick->max_used_key_length, buf, 10) - buf;
- used_lengths->append(buf, length);
+ qr->quick->add_key_and_length(key_names, used_lengths, &first);
}
-
if (cpk_quick)
- {
- KEY *key_info= head->key_info + cpk_quick->index;
- key_names->append(',');
- key_names->append(key_info->name);
- length= longlong10_to_str(cpk_quick->max_used_key_length, buf, 10) - buf;
- used_lengths->append(',');
- used_lengths->append(buf, length);
- }
+ cpk_quick->add_key_and_length(key_names, used_lengths, &first);
}
void QUICK_ROR_UNION_SELECT::add_keys_and_lengths(String *key_names,
String *used_lengths)
{
- bool first= TRUE;
QUICK_SELECT_I *quick;
+ bool first= TRUE;
+
List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
+
while ((quick= it++))
{
if (first)
@@ -9169,8 +11484,9 @@ static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
uchar *key_infix, uint *key_infix_len,
KEY_PART_INFO **first_non_infix_part);
static bool
-check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
- Field::imagetype image_type);
+check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
+ Field::imagetype image_type,
+ bool *has_min_max_fld, bool *has_other_fld);
static void
cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
@@ -9335,7 +11651,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
/* Perform few 'cheap' tests whether this access method is applicable. */
if (!join)
DBUG_RETURN(NULL); /* This is not a select statement. */
- if ((join->tables != 1) || /* The query must reference one table. */
+ if ((join->table_count != 1) || /* The query must reference one table. */
((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
(!join->select_distinct)) ||
(join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
@@ -9656,8 +11972,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,
@@ -9691,10 +12013,12 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
DBUG_RETURN(NULL);
/* Check (SA3) for the where clause. */
+ bool has_min_max_fld= false, has_other_fld= false;
if (join->conds && min_max_arg_item &&
!check_group_min_max_predicates(join->conds, min_max_arg_item,
(index_info->flags & HA_SPATIAL) ?
- Field::itMBR : Field::itRAW))
+ Field::itMBR : Field::itRAW,
+ &has_min_max_fld, &has_other_fld))
DBUG_RETURN(NULL);
/* The query passes all tests, so construct a new TRP object. */
@@ -9729,16 +12053,24 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
SYNOPSIS
check_group_min_max_predicates()
- cond tree (or subtree) describing all or part of the WHERE
- clause being analyzed
- min_max_arg_item the field referenced by the MIN/MAX function(s)
- min_max_arg_part the keypart of the MIN/MAX argument if any
+ cond [in] the expression tree being analyzed
+ min_max_arg [in] the field referenced by the MIN/MAX function(s)
+ image_type [in]
+ has_min_max_arg [out] true if the subtree being analyzed references min_max_arg
+ has_other_arg [out] true if the subtree being analyzed references a column
+ other min_max_arg
DESCRIPTION
The function walks recursively over the cond tree representing a WHERE
clause, and checks condition (SA3) - if a field is referenced by a MIN/MAX
aggregate function, it is referenced only by one of the following
- predicates: {=, !=, <, <=, >, >=, between, is null, is not null}.
+ predicates $FUNC$:
+ {=, !=, <, <=, >, >=, between, is [not] null, multiple equal}.
+ In addition the function checks that the WHERE condition is equivalent to
+ "cond1 AND cond2" where :
+ cond1 - does not use min_max_column at all.
+ cond2 - is an AND/OR tree with leaves in form
+ "$FUNC$(min_max_column[, const])".
RETURN
TRUE if cond passes the test
@@ -9746,39 +12078,63 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
*/
static bool
-check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
- Field::imagetype image_type)
+check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
+ Field::imagetype image_type,
+ bool *has_min_max_arg, bool *has_other_arg)
{
DBUG_ENTER("check_group_min_max_predicates");
DBUG_ASSERT(cond && min_max_arg_item);
cond= cond->real_item();
- Item::Type cond_type= cond->type();
+ Item::Type cond_type= cond->real_type();
if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
{
DBUG_PRINT("info", ("Analyzing: %s", ((Item_func*) cond)->func_name()));
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
Item *and_or_arg;
+ Item_func::Functype func_type= ((Item_cond*) cond)->functype();
+ bool has_min_max= false, has_other= false;
while ((and_or_arg= li++))
{
- if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item,
- image_type))
+ /*
+ The WHERE clause doesn't pass the condition if:
+ (1) any subtree doesn't pass the condition or
+ (2) the subtree passes the test, but it is an OR and it references both
+ the min/max argument and other columns.
+ */
+ if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item, //1
+ image_type,
+ &has_min_max, &has_other) ||
+ (func_type == Item_func::COND_OR_FUNC && has_min_max && has_other))//2
DBUG_RETURN(FALSE);
}
+ *has_min_max_arg= has_min_max || *has_min_max_arg;
+ *has_other_arg= has_other || *has_other_arg;
DBUG_RETURN(TRUE);
}
/*
- TODO:
- This is a very crude fix to handle sub-selects in the WHERE clause
- (Item_subselect objects). With the test below we rule out from the
- optimization all queries with subselects in the WHERE clause. What has to
- be done, is that here we should analyze whether the subselect references
- the MIN/MAX argument field, and disallow the optimization only if this is
- so.
+ Disallow loose index scan if the MIN/MAX argument field is referenced by
+ a subquery in the WHERE clause.
*/
+
if (cond_type == Item::SUBSELECT_ITEM)
- DBUG_RETURN(FALSE);
+ {
+ Item_subselect *subs_cond= (Item_subselect*) cond;
+ if (subs_cond->is_correlated)
+ {
+ DBUG_ASSERT(subs_cond->upper_refs.elements > 0);
+ List_iterator_fast<Item_subselect::Ref_to_outside>
+ li(subs_cond->upper_refs);
+ Item_subselect::Ref_to_outside *dep;
+ while ((dep= li++))
+ {
+ if (dep->item->eq(min_max_arg_item, FALSE))
+ DBUG_RETURN(FALSE);
+ }
+ }
+ DBUG_RETURN(TRUE);
+ }
/*
Condition of the form 'field' is equivalent to 'field <> 0' and thus
@@ -9787,6 +12143,10 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
if (cond_type == Item::FIELD_ITEM)
{
DBUG_PRINT("info", ("Analyzing: %s", cond->full_name()));
+ if (min_max_arg_item->eq((Item_field*)cond, 1))
+ *has_min_max_arg= true;
+ else
+ *has_other_arg= true;
DBUG_RETURN(TRUE);
}
@@ -9795,9 +12155,33 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
/* Test if cond references only group-by or non-group fields. */
Item_func *pred= (Item_func*) cond;
+ Item_func::Functype pred_type= pred->functype();
+ DBUG_PRINT("info", ("Analyzing: %s", pred->func_name()));
+ if (pred_type == Item_func::MULT_EQUAL_FUNC)
+ {
+ /*
+ Check that each field in a multiple equality is either a constant or
+ it is a reference to the min/max argument, or it doesn't contain the
+ min/max argument at all.
+ */
+ Item_equal_fields_iterator eq_it(*((Item_equal*)pred));
+ Item *eq_item;
+ bool has_min_max= false, has_other= false;
+ while ((eq_item= eq_it++))
+ {
+ if (min_max_arg_item->eq(eq_item->real_item(), 1))
+ has_min_max= true;
+ else
+ has_other= true;
+ }
+ *has_min_max_arg= has_min_max || *has_min_max_arg;
+ *has_other_arg= has_other || *has_other_arg;
+ DBUG_RETURN(!(has_min_max && has_other));
+ }
+
Item **arguments= pred->arguments();
Item *cur_arg;
- DBUG_PRINT("info", ("Analyzing: %s", pred->func_name()));
+ bool has_min_max= false, has_other= false;
for (uint arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
{
cur_arg= arguments[arg_idx]->real_item();
@@ -9806,11 +12190,11 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
{
if (min_max_arg_item->eq(cur_arg, 1))
{
- /*
- If pred references the MIN/MAX argument, check whether pred is a range
- condition that compares the MIN/MAX argument with a constant.
- */
- Item_func::Functype pred_type= pred->functype();
+ has_min_max= true;
+ /*
+ If pred references the MIN/MAX argument, check whether pred is a range
+ condition that compares the MIN/MAX argument with a constant.
+ */
if (pred_type != Item_func::EQUAL_FUNC &&
pred_type != Item_func::LT_FUNC &&
pred_type != Item_func::LE_FUNC &&
@@ -9850,14 +12234,16 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
min_max_arg_item->field->cmp_type() != args[1]->result_type())))
DBUG_RETURN(FALSE);
}
+ else
+ has_other= true;
}
else if (cur_arg->type() == Item::FUNC_ITEM)
{
- if (!check_group_min_max_predicates(cur_arg, min_max_arg_item,
- image_type))
+ if (!check_group_min_max_predicates(cur_arg, min_max_arg_item, image_type,
+ &has_min_max, &has_other))
DBUG_RETURN(FALSE);
}
- else if (cur_arg->const_item())
+ else if (cur_arg->const_item() && !cur_arg->is_expensive())
{
/*
For predicates of the form "const OP expr" we also have to check 'expr'
@@ -9867,7 +12253,11 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
}
else
DBUG_RETURN(FALSE);
+ if(has_min_max && has_other)
+ DBUG_RETURN(FALSE);
}
+ *has_min_max_arg= has_min_max || *has_min_max_arg;
+ *has_other_arg= has_other || *has_other_arg;
DBUG_RETURN(TRUE);
}
@@ -9925,13 +12315,14 @@ get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
Find the range tree for the current keypart. We assume that
index_range_tree points to the leftmost keypart in the index.
*/
- for (cur_range= index_range_tree; cur_range;
+ for (cur_range= index_range_tree;
+ cur_range && cur_range->type == SEL_ARG::KEY_RANGE;
cur_range= cur_range->next_key_part)
{
if (cur_range->field->eq(cur_part->field))
break;
}
- if (!cur_range)
+ if (!cur_range || cur_range->type != SEL_ARG::KEY_RANGE)
{
if (min_max_arg_part)
return FALSE; /* The current keypart has no range predicates at all. */
@@ -10245,6 +12636,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);
/*
@@ -11303,11 +13695,9 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_max_result()
void QUICK_GROUP_MIN_MAX_SELECT::add_keys_and_lengths(String *key_names,
String *used_lengths)
{
- char buf[64];
- uint length;
- key_names->append(index_info->name);
- length= longlong10_to_str(max_used_key_length, buf, 10) - buf;
- used_lengths->append(buf, length);
+ bool first= TRUE;
+
+ add_key_and_length(key_names, used_lengths, &first);
}
@@ -11339,7 +13729,7 @@ static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
tmp.append(STRING_WITH_LEN("(empty)"));
DBUG_PRINT("info", ("SEL_TREE: 0x%lx (%s) scans: %s", (long) tree, msg,
- tmp.c_ptr()));
+ tmp.c_ptr_safe()));
DBUG_VOID_RETURN;
}
@@ -11366,6 +13756,7 @@ static void print_ror_scans_arr(TABLE *table, const char *msg,
DBUG_VOID_RETURN;
}
+
/*****************************************************************************
** Print a quick range for debugging
** TODO:
@@ -11378,7 +13769,6 @@ print_key(KEY_PART *key_part, const uchar *key, uint used_length)
{
char buff[1024];
const uchar *key_end= key+used_length;
- String tmp(buff,sizeof(buff),&my_charset_bin);
uint store_length;
TABLE *table= key_part->field->table;
my_bitmap_map *old_sets[2];
@@ -11387,6 +13777,7 @@ print_key(KEY_PART *key_part, const uchar *key, uint used_length)
for (; key < key_end; key+=store_length, key_part++)
{
+ String tmp(buff,sizeof(buff),&my_charset_bin);
Field *field= key_part->field;
store_length= key_part->store_length;
@@ -11474,7 +13865,7 @@ void QUICK_RANGE_SELECT::dbug_dump(int indent, bool verbose)
/* purecov: end */
}
-void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose)
+void QUICK_INDEX_SORT_SELECT::dbug_dump(int indent, bool verbose)
{
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
QUICK_RANGE_SELECT *quick;
diff --git a/sql/opt_range.h b/sql/opt_range.h
index eaaf4a2a2a8..d4b92015042 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -195,13 +195,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;
@@ -274,14 +277,21 @@ 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,
- QS_TYPE_RANGE_DESC = 2,
- QS_TYPE_FULLTEXT = 3,
- QS_TYPE_ROR_INTERSECT = 4,
- QS_TYPE_ROR_UNION = 5,
- QS_TYPE_GROUP_MIN_MAX = 6
+ QS_TYPE_INDEX_INTERSECT = 1,
+ QS_TYPE_INDEX_MERGE = 2,
+ QS_TYPE_RANGE_DESC = 3,
+ QS_TYPE_FULLTEXT = 4,
+ QS_TYPE_ROR_INTERSECT = 5,
+ QS_TYPE_ROR_UNION = 6,
+ QS_TYPE_GROUP_MIN_MAX = 7
};
/* Get type of this quick select - one of the QS_TYPE_* values */
@@ -307,6 +317,10 @@ public:
Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
*/
virtual void save_last_pos(){};
+
+ void add_key_and_length(String *key_names,
+ String *used_lengths,
+ bool *first);
/*
Append comma-separated list of keys this quick select uses to key_names;
@@ -316,13 +330,16 @@ public:
virtual void add_keys_and_lengths(String *key_names,
String *used_lengths)=0;
+ void add_key_name(String *str, bool *first);
+
/*
Append text representation of quick select structure (what and how is
merged) to str. The result is added to "Extra" field in EXPLAIN output.
This function is implemented only by quick selects that merge other quick
selects output and/or can produce output suitable for merging.
*/
- virtual void add_info_string(String *str) {};
+ virtual void add_info_string(String *str) {}
+
/*
Return 1 if any index used by this quick select
uses field which is marked in passed bitmap.
@@ -339,6 +356,12 @@ public:
Table record buffer used by this quick select.
*/
uchar *record;
+
+ virtual void replace_handler(handler *new_file)
+ {
+ DBUG_ASSERT(0); /* Only supported in QUICK_RANGE_SELECT */
+ }
+
#ifndef DBUG_OFF
/*
Print quick select information to DBUG_FILE. Caller is responsible
@@ -353,6 +376,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.
@@ -360,62 +399,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,8 +457,41 @@ public:
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif
+ virtual void replace_handler(handler *new_file) { file= new_file; }
private:
/* Default copy ctor used by QUICK_SELECT_DESC */
+ friend class TRP_ROR_INTERSECT;
+ 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_SORT_SELECT;
+ friend class QUICK_INDEX_MERGE_SELECT;
+ friend class QUICK_ROR_INTERSECT_SELECT;
+ friend class QUICK_INDEX_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);
+ friend
+ int read_keys_and_merge_scans(THD *thd, TABLE *head,
+ List<QUICK_RANGE_SELECT> quick_selects,
+ QUICK_RANGE_SELECT *pk_quick_select,
+ READ_RECORD *read_record,
+ bool intersection,
+ key_map *filtered_scans,
+ Unique **unique_ptr);
+
};
@@ -442,48 +499,53 @@ 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();
};
/*
- QUICK_INDEX_MERGE_SELECT - index_merge access method quick select.
+ QUICK_INDEX_SORT_SELECT is the base class for the common functionality of:
+ - QUICK_INDEX_MERGE_SELECT, access based on multi-index merge/union
+ - QUICK_INDEX_INTERSECT_SELECT, access based on multi-index intersection
+
- QUICK_INDEX_MERGE_SELECT uses
+ QUICK_INDEX_SORT_SELECT uses
* QUICK_RANGE_SELECTs to get rows
- * Unique class to remove duplicate rows
+ * Unique class
+ - to remove duplicate rows for QUICK_INDEX_MERGE_SELECT
+ - to intersect rows for QUICK_INDEX_INTERSECT_SELECT
INDEX MERGE OPTIMIZER
- Current implementation doesn't detect all cases where index_merge could
+ Current implementation doesn't detect all cases where index merge could
be used, in particular:
- * index_merge will never be used if range scan is possible (even if
- range scan is more expensive)
- * index_merge+'using index' is not supported (this the consequence of
- the above restriction)
+ * index_merge+'using index' is not supported
* If WHERE part contains complex nested AND and OR conditions, some ways
- to retrieve rows using index_merge will not be considered. The choice
+ to retrieve rows using index merge will not be considered. The choice
of read plan may depend on the order of conjuncts/disjuncts in WHERE
part of the query, see comments near imerge_list_or_list and
SEL_IMERGE::or_sel_tree_with_checks functions for details.
- * There is no "index_merge_ref" method (but index_merge on non-first
+ * There is no "index_merge_ref" method (but index merge on non-first
table in join is possible with 'range checked for each record').
- See comments around SEL_IMERGE class and test_quick_select for more
- details.
ROW RETRIEVAL ALGORITHM
- index_merge uses Unique class for duplicates removal. index_merge takes
- advantage of Clustered Primary Key (CPK) if the table has one.
- The index_merge algorithm consists of two phases:
+ index merge/intersection uses Unique class for duplicates removal.
+ index merge/intersection takes advantage of Clustered Primary Key (CPK)
+ if the table has one.
+ The index merge/intersection algorithm consists of two phases:
+
+ Phase 1
+ (implemented by a QUICK_INDEX_MERGE_SELECT::read_keys_and_merge call):
- Phase 1 (implemented in QUICK_INDEX_MERGE_SELECT::prepare_unique):
prepare()
{
activate 'index only';
@@ -497,32 +559,32 @@ public:
deactivate 'index only';
}
- Phase 2 (implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next
- calls):
+ Phase 2
+ (implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next calls):
fetch()
{
- retrieve all rows from row pointers stored in Unique;
+ retrieve all rows from row pointers stored in Unique
+ (merging/intersecting them);
free Unique;
- retrieve all rows for CPK scan;
+ if (! intersection)
+ retrieve all rows for CPK scan;
}
*/
-class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I
+class QUICK_INDEX_SORT_SELECT : public QUICK_SELECT_I
{
+protected:
Unique *unique;
public:
- QUICK_INDEX_MERGE_SELECT(THD *thd, TABLE *table);
- ~QUICK_INDEX_MERGE_SELECT();
+ QUICK_INDEX_SORT_SELECT(THD *thd, TABLE *table);
+ ~QUICK_INDEX_SORT_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; }
bool unique_key_range() { return false; }
- int get_type() { return QS_TYPE_INDEX_MERGE; }
- void add_keys_and_lengths(String *key_names, String *used_lengths);
- void add_info_string(String *str);
bool is_keys_used(const MY_BITMAP *fields);
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
@@ -530,21 +592,53 @@ public:
bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
- /* range quick selects this index_merge read consists of */
+ /* range quick selects this index merge/intersect consists of */
List<QUICK_RANGE_SELECT> quick_selects;
/* quick select that uses clustered primary key (NULL if none) */
QUICK_RANGE_SELECT* pk_quick_select;
+ MEM_ROOT alloc;
+ THD *thd;
+ virtual int read_keys_and_merge()= 0;
+ /* used to get rows collected in Unique */
+ READ_RECORD read_record;
+};
+
+
+
+class QUICK_INDEX_MERGE_SELECT : public QUICK_INDEX_SORT_SELECT
+{
+private:
/* true if this select is currently doing a clustered PK scan */
bool doing_pk_scan;
+protected:
+ int read_keys_and_merge();
- MEM_ROOT alloc;
- THD *thd;
+public:
+ QUICK_INDEX_MERGE_SELECT(THD *thd, TABLE *table)
+ :QUICK_INDEX_SORT_SELECT(thd, table) {}
+
+ int get_next();
+ int get_type() { return QS_TYPE_INDEX_MERGE; }
+ void add_keys_and_lengths(String *key_names, String *used_lengths);
+ void add_info_string(String *str);
+};
+
+class QUICK_INDEX_INTERSECT_SELECT : public QUICK_INDEX_SORT_SELECT
+{
+protected:
int read_keys_and_merge();
- /* used to get rows collected in Unique */
- READ_RECORD read_record;
+public:
+ QUICK_INDEX_INTERSECT_SELECT(THD *thd, TABLE *table)
+ :QUICK_INDEX_SORT_SELECT(thd, table) {}
+
+ key_map filtered_scans;
+ int get_next();
+ int get_type() { return QS_TYPE_INDEX_INTERSECT; }
+ void add_keys_and_lengths(String *key_names, String *used_lengths);
+ void add_info_string(String *str);
};
@@ -575,6 +669,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; }
@@ -637,6 +732,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; }
@@ -758,6 +854,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; }
@@ -773,7 +870,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; }
@@ -790,6 +888,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
@@ -797,7 +902,7 @@ class SQL_SELECT :public Sql_alloc {
key_map quick_keys; // Possible quick keys
key_map needed_reg; // Possible quick keys after prev tables.
table_map const_tables,read_tables;
- bool free_cond;
+ bool free_cond; /* Currently not used and always FALSE */
SQL_SELECT();
~SQL_SELECT();
@@ -806,7 +911,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
@@ -822,21 +927,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..da6086d6cdc
--- /dev/null
+++ b/sql/opt_range_mrr.cc
@@ -0,0 +1,346 @@
+
+/****************************************************************************
+ 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
+*/
+
+#if (_MSC_FULL_VER == 160030319)
+/*
+ Workaround Visual Studio 2010 RTM compiler backend bug, the function enters
+ infinite loop.
+ */
+#pragma optimize("g", off)
+#endif
+
+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*)(intptr)(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;
+}
+
+#if (_MSC_FULL_VER == 160030319)
+/* VS2010 compiler bug workaround */
+#pragma optimize("g", on)
+#endif
+
+
+/****************************************************************************
+ 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..568297ba277
--- /dev/null
+++ b/sql/opt_subselect.cc
@@ -0,0 +1,5538 @@
+/**
+ @file
+
+ @brief
+ Semi-join subquery optimizations code
+
+*/
+
+#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>
+
+/*
+ This file contains optimizations for semi-join subqueries.
+
+ Contents
+ --------
+ 1. What is a semi-join subquery
+ 2. General idea about semi-join execution
+ 2.1 Correlated vs uncorrelated semi-joins
+ 2.2 Mergeable vs non-mergeable semi-joins
+ 3. Code-level view of semi-join processing
+ 3.1 Conversion
+ 3.1.1 Merged semi-join TABLE_LIST object
+ 3.1.2 Non-merged semi-join data structure
+ 3.2 Semi-joins and query optimization
+ 3.2.1 Non-merged semi-joins and join optimization
+ 3.2.2 Merged semi-joins and join optimization
+ 3.3 Semi-joins and query execution
+
+ 1. What is a semi-join subquery
+ -------------------------------
+ We use this definition of semi-join:
+
+ outer_tbl SEMI JOIN inner_tbl ON cond = {set of outer_tbl.row such that
+ exist inner_tbl.row, for which
+ cond(outer_tbl.row,inner_tbl.row)
+ is satisfied}
+
+ That is, semi-join operation is similar to inner join operation, with
+ exception that we don't care how many matches a row from outer_tbl has in
+ inner_tbl.
+
+ In SQL terms: a semi-join subquery is an IN subquery that is an AND-part of
+ the WHERE/ON clause.
+
+ 2. General idea about semi-join execution
+ -----------------------------------------
+ We can execute semi-join in a way similar to inner join, with exception that
+ we need to somehow ensure that we do not generate record combinations that
+ differ only in rows of inner tables.
+ There is a number of different ways to achieve this property, implemented by
+ a number of semi-join execution strategies.
+ Some strategies can handle any semi-joins, other can be applied only to
+ semi-joins that have certain properties that are described below:
+
+ 2.1 Correlated vs uncorrelated semi-joins
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ Uncorrelated semi-joins are special in the respect that they allow to
+ - execute the subquery (possible as it's uncorrelated)
+ - somehow make sure that generated set does not have duplicates
+ - perform an inner join with outer tables.
+
+ or, rephrasing in SQL form:
+
+ SELECT ... FROM ot WHERE ot.col IN (SELECT it.col FROM it WHERE uncorr_cond)
+ ->
+ SELECT ... FROM ot JOIN (SELECT DISTINCT it.col FROM it WHERE uncorr_cond)
+
+ 2.2 Mergeable vs non-mergeable semi-joins
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ Semi-join operation has some degree of commutability with inner join
+ operation: we can join subquery's tables with ouside table(s) and eliminate
+ duplicate record combination after that:
+
+ ot1 JOIN ot2 SEMI_JOIN{it1,it2} (it1 JOIN it2) ON sjcond(ot2,it*) ->
+ |
+ +-------------------------------+
+ v
+ ot1 SEMI_JOIN{it1,it2} (it1 JOIN it2 JOIN ot2) ON sjcond(ot2,it*)
+
+ In order for this to work, subquery's top-level operation must be join, and
+ grouping or ordering with limit (grouping or ordering with limit are not
+ commutative with duplicate removal). In other words, the conversion is
+ possible when the subquery doesn't have GROUP BY clause, any aggregate
+ functions*, or ORDER BY ... LIMIT clause.
+
+ Definitions:
+ - Subquery whose top-level operation is a join is called *mergeable semi-join*
+ - All other kinds of semi-join subqueries are considered non-mergeable.
+
+ *- this requirement is actually too strong, but its exceptions are too
+ complicated to be considered here.
+
+ 3. Code-level view of semi-join processing
+ ------------------------------------------
+
+ 3.1 Conversion and pre-optimization data structures
+ ---------------------------------------------------
+ * When doing JOIN::prepare for the subquery, we detect that it can be
+ converted into a semi-join and register it in parent_join->sj_subselects
+
+ * At the start of parent_join->optimize(), the predicate is converted into
+ a semi-join node. A semi-join node is a TABLE_LIST object that is linked
+ somewhere in parent_join->join_list (either it is just present there, or
+ it is a descendant of some of its members).
+
+ There are two kinds of semi-joins:
+ - Merged semi-joins
+ - Non-merged semi-joins
+
+ 3.1.1 Merged semi-join TABLE_LIST object
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ Merged semi-join object is a TABLE_LIST that contains a sub-join of
+ subquery tables and the semi-join ON expression (in this respect it is
+ very similar to nested outer join representation)
+ Merged semi-join represents this SQL:
+
+ ... SEMI JOIN (inner_tbl1 JOIN ... JOIN inner_tbl_n) ON sj_on_expr
+
+ Semi-join objects of this kind have TABLE_LIST::sj_subq_pred set.
+
+ 3.1.2 Non-merged semi-join data structure
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ Non-merged semi-join object is a leaf TABLE_LIST object that has a subquery
+ that produces rows. It is similar to a base table and represents this SQL:
+
+ ... SEMI_JOIN (SELECT non_mergeable_select) ON sj_on_expr
+
+ Subquery items that were converted into semi-joins are removed from the WHERE
+ clause. (They do remain in PS-saved WHERE clause, and they replace themselves
+ with Item_int(1) on subsequent re-executions).
+
+ 3.2 Semi-joins and join optimization
+ ------------------------------------
+
+ 3.2.1 Non-merged semi-joins and join optimization
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ For join optimization purposes, non-merged semi-join nests are similar to
+ base tables. Each such nest is represented by one one JOIN_TAB, which has
+ two possible access strategies:
+ - full table scan (representing SJ-Materialization-Scan strategy)
+ - eq_ref-like table lookup (representing SJ-Materialization-Lookup)
+
+ Unlike regular base tables, non-merged semi-joins have:
+ - non-zero JOIN_TAB::startup_cost, and
+ - join_tab->table->is_filled_at_execution()==TRUE, which means one
+ cannot do const table detection, range analysis or other dataset-dependent
+ optimizations.
+ Instead, get_delayed_table_estimates() will run optimization for the
+ subquery and produce an E(materialized table size).
+
+ 3.2.2 Merged semi-joins and join optimization
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ - optimize_semijoin_nests() does pre-optimization
+ - during join optimization, the join has one JOIN_TAB (or is it POSITION?)
+ array, and suffix-based detection is used, see advance_sj_state()
+ - after join optimization is done, get_best_combination() switches
+ the data-structure to prefix-based, multiple JOIN_TAB ranges format.
+
+ 3.3 Semi-joins and query execution
+ ----------------------------------
+ * Join executor has hooks for all semi-join strategies.
+ TODO elaborate.
+
+*/
+
+/*
+EqualityPropagationAndSjmNests
+******************************
+
+Equalities are used for:
+P1. Equality propagation
+P2. Equality substitution [for a certain join order]
+
+The equality propagation is not affected by SJM nests. In fact, it is done
+before we determine the execution plan, i.e. before we even know we will use
+SJM-nests for execution.
+
+The equality substitution is affected.
+
+Substitution without SJMs
+=========================
+When one doesn't have SJM nests, tables have a strict join order:
+
+ --------------------------------->
+ t1 -- t2 -- t3 -- t4 --- t5
+
+
+ ? ^
+ \
+ --(part-of-WHERE)
+
+
+parts WHERE/ON and ref. expressions are attached at some point along the axis.
+Expression is allowed to refer to a table column if the table is to the left of
+the attachment point. For any given expression, we have a goal:
+
+ "Move leftmost allowed attachment point as much as possible to the left"
+
+Substitution with SJMs - task setting
+=====================================
+
+When SJM nests are present, there is no global strict table ordering anymore:
+
+
+ --------------------------------->
+
+ ot1 -- ot2 --- sjm -- ot4 --- ot5
+ |
+ | Main execution
+ - - - - - - - - - - - - - - - - - - - - - - - -
+ | Materialization
+ it1 -- it2 --/
+
+
+Besides that, we must take into account that
+ - values for outer table columns, otN.col, are inaccessible at
+ materialization step (SJM-RULE)
+ - values for inner table columns, itN.col, are inaccessible at Main execution
+ step, except for SJ-Materialization-Scan and columns that are in the
+ subquery's select list. (SJM-RULE)
+
+Substitution with SJMs - solution
+=================================
+
+First, we introduce global strict table ordering like this:
+
+ ot1 - ot2 --\ /--- ot3 -- ot5
+ \--- it1 --- it2 --/
+
+Now, let's see how to meet (SJM-RULE).
+
+SJ-Materialization is only applicable for uncorrelated subqueries. From this, it
+follows that any multiple equality will either
+1. include only columns of outer tables, or
+2. include only columns of inner tables, or
+3. include columns of inner and outer tables, joined together through one
+ of IN-equalities.
+
+Cases #1 and #2 can be handled in the same way as with regular inner joins.
+
+Case #3 requires special handling, so that we don't construct violations of
+(SJM-RULE). Let's consider possible ways to build violations.
+
+Equality propagation starts with the clause in this form
+
+ top_query_where AND subquery_where AND in_equalities
+
+First, it builds multi-equalities. It can also build a mixed multi-equality
+
+ multiple-equal(ot1.col, ot2.col, ... it1.col, itN.col)
+
+Multi-equalities are pushed down the OR-clauses in top_query_where and in
+subquery_where, so it's possible that clauses like this one are built:
+
+ subquery_cond OR (multiple-equal(it1.col, ot1.col,...) AND ...)
+ ^^^^^^^^^^^^^ \
+ | this must be evaluated
+ \- can only be evaluated at the main phase.
+ at the materialization phase
+
+Finally, equality substitution is started. It does two operations:
+
+
+1. Field reference substitution
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(In the code, this is Item_field::replace_equal_field)
+
+This is a process of replacing each reference to "tblX.col"
+with the first element of the multi-equality. (REF-SUBST-ORIG)
+
+This behaviour can cause problems with Semi-join nests. Suppose, we have a
+condition:
+
+ func(it1.col, it2.col)
+
+and a multi-equality(ot1.col, it1.col). Then, reference to "it1.col" will be
+replaced with "ot1.col", constructing a condition
+
+ func(ot1.col, it2.col)
+
+which will be a violation of (SJM-RULE).
+
+In order to avoid this, (REF-SUBST-ORIG) is amended as follows:
+
+- references to tables "itX.col" that are inner wrt some SJM nest, are
+ replaced with references to the first inner table from the same SJM nest.
+
+- references to top-level tables "otX.col" are replaced with references to
+ the first element of the multi-equality, no matter if that first element is
+ a column of a top-level table or of table from some SJM nest.
+ (REF-SUBST-SJM)
+
+ The case where the first element is a table from an SJM nest $SJM is ok,
+ because it can be proven that $SJM uses SJ-Materialization-Scan, and
+ "unpacks" correct column values to the first element during the main
+ execution phase.
+
+2. Item_equal elimination
+~~~~~~~~~~~~~~~~~~~~~~~~~
+(In the code: eliminate_item_equal) This is a process of taking
+
+ multiple-equal(a,b,c,d,e)
+
+and replacing it with an equivalent expression which is an AND of pair-wise
+equalities:
+
+ a=b AND a=c AND ...
+
+The equalities are picked such that for any given join prefix (t1,t2...) the
+subset of equalities that can be evaluated gives the most restrictive
+filtering.
+
+Without SJM nests, it is sufficient to compare every multi-equality member
+with the first one:
+
+ elem1=elem2 AND elem1=elem3 AND elem1=elem4 ...
+
+When SJM nests are present, we should take care not to construct equalities
+that violate the (SJM-RULE). This is achieved by generating separate sets of
+equalites for top-level tables and for inner tables. That is, for the join
+order
+
+ ot1 - ot2 --\ /--- ot3 -- ot5
+ \--- it1 --- it2 --/
+
+we will generate
+ ot1.col=ot2.col
+ ot1.col=ot3.col
+ ot1.col=ot5.col
+ it2.col=it1.col
+
+
+2.1 The problem with Item_equals and ORs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+As has been mentioned above, multiple equalities are pushed down into OR
+clauses, possibly building clauses like this:
+
+ func(it.col2) OR multiple-equal(it1.col1, it1.col2, ot1.col) (1)
+
+where the first part of the clause has references to inner tables, while the
+second has references to the top-level tables, which is a violation of
+(SJM-RULE).
+
+AND-clauses of this kind do not create problems, because make_cond_for_table()
+will take them apart. OR-clauses will not be split. It is possible to
+split-out the part that's dependent on the inner table:
+
+ func(it.col2) OR it1.col1=it1.col2
+
+but this is a less-restrictive condition than condition (1). Current execution
+scheme will still try to generate the "remainder" condition:
+
+ func(it.col2) OR it1.col1=ot1.col
+
+which is a violation of (SJM-RULE).
+
+QQ: "ot1.col=it1.col" is checked at the upper level. Why was it not removed
+here?
+AA: because has a proper subset of conditions that are found on this level.
+ consider a join order of ot, sjm(it)
+ and a condition
+ ot.col=it.col AND ( ot.col=it.col='foo' OR it.col2='bar')
+
+ we will produce:
+ table ot: nothing
+ table it: ot.col=it.col AND (ot.col='foo' OR it.col2='bar')
+ ^^^^ ^^^^^^^^^^^^^^^^
+ | \ the problem is that
+ | this part condition didnt
+ | receive a substitution
+ |
+ +--- it was correct to subst, 'ot' is
+ the left-most.
+
+
+Does it make sense to push "inner=outer" down into ORs?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Yes. Consider the query:
+
+ select * from ot
+ where ot.col in (select it.col from it where (it.col='foo' OR it.col='bar'))
+
+here, it may be useful to infer that
+
+ (ot.col='foo' OR ot.col='bar') (CASE-FOR-SUBST)
+
+and attach that condition to the table 'ot'.
+
+Possible solutions for Item_equals and ORs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Solution #1
+~~~~~~~~~~~
+Let make_cond_for_table() chop analyze the OR clauses it has produced and
+discard them if they violate (SJM-RULE). This solution would allow to handle
+cases like (CASE-FOR-SUBST) at the expense of making semantics of
+make_cond_for_table() complicated.
+
+Solution #2
+~~~~~~~~~~~
+Before the equality propagation phase, none of the OR clauses violate the
+(SJM-RULE). This way, if we remember which tables the original equality
+referred to, we can only generate equalities that refer to the outer (or inner)
+tables. Note that this will disallow handling of cases like (CASE-FOR-SUBST).
+
+Currently, solution #2 is implemented.
+
+*/
+
+
+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* el1, Item_in_subselect* el2,
+ void *arg);
+static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred);
+static bool convert_subq_to_jtbm(JOIN *parent_join,
+ Item_in_subselect *subq_pred, bool *remove);
+static TABLE_LIST *alloc_join_nest(THD *thd);
+static uint get_tmp_table_rec_length(Item **p_list, uint elements);
+static double get_tmp_table_lookup_cost(THD *thd, double row_count,
+ uint row_size);
+static double get_tmp_table_write_cost(THD *thd, double row_count,
+ uint row_size);
+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);
+
+enum_nested_loop_state
+end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
+
+
+/*
+ Check if Materialization strategy is allowed for given subquery predicate.
+
+ @param thd Thread handle
+ @param in_subs The subquery predicate
+ @param child_select The select inside predicate (the function will
+ check it is the only one)
+
+ @return TRUE - Materialization is applicable
+ FALSE - Otherwise
+*/
+
+bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs,
+ st_select_lex *child_select)
+{
+ st_select_lex_unit* parent_unit= child_select->master_unit();
+ /*
+ Check if the subquery predicate can be executed via materialization.
+ The required conditions are:
+ 0. The materialization optimizer switch was set.
+ 1. Subquery is a single SELECT (not a UNION).
+ TODO: this is a limitation that can be fixed
+ 2. Subquery is not a table-less query. In this case there is no
+ point in materializing.
+ 2A The upper query is not a table-less SELECT ... FROM DUAL. We
+ can't do materialization for SELECT .. FROM DUAL because it
+ does not call setup_subquery_materialization(). We could make
+ SELECT ... FROM DUAL call that function but that doesn't seem
+ to be the case that is worth handling.
+ 3. Either the subquery predicate is a top-level predicate, or at
+ least one partial match strategy is enabled. If no partial match
+ strategy is enabled, then materialization cannot be used for
+ non-top-level queries because it cannot handle NULLs correctly.
+ 4. Subquery is non-correlated
+ TODO:
+ This condition is too restrictive (limitation). It can be extended to:
+ (Subquery is non-correlated ||
+ Subquery is correlated to any query outer to IN predicate ||
+ (Subquery is correlated to the immediate outer query &&
+ Subquery !contains {GROUP BY, ORDER BY [LIMIT],
+ aggregate functions}) && subquery predicate is not under "NOT IN"))
+
+ (*) The subquery must be part of a SELECT or CREATE TABLE ... SELECT statement.
+ The current condition also excludes multi-table update statements.
+ A note about prepared statements: we want the if-branch to be taken on
+ PREPARE and each EXECUTE. The rewrites are only done once, but we need
+ select_lex->sj_subselects list to be populated for every EXECUTE.
+
+ */
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION) && // 0
+ !child_select->is_part_of_union() && // 1
+ parent_unit->first_select()->leaf_tables.elements && // 2
+ (thd->lex->sql_command == SQLCOM_SELECT || // *
+ thd->lex->sql_command == SQLCOM_CREATE_TABLE) && // *
+ child_select->outer_select()->leaf_tables.elements && // 2A
+ subquery_types_allow_materialization(in_subs) &&
+ (in_subs->is_top_level_item() || //3
+ optimizer_flag(thd,
+ OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) || //3
+ optimizer_flag(thd,
+ OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN)) && //3
+ !in_subs->is_correlated) //4
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ Check if we need JOIN::prepare()-phase subquery rewrites and if yes, do them
+
+ SYNOPSIS
+ check_and_do_in_subquery_rewrites()
+ join Subquery's join
+
+ DESCRIPTION
+ Check if we need to do
+ - subquery -> mergeable semi-join rewrite
+ - if the subquery can be handled with materialization
+ - 'substitution' rewrite for table-less subqueries like "(select 1)"
+ - IN->EXISTS rewrite
+ and, depending on the rewrite, either do it, or record it to be done at a
+ later phase.
+
+ RETURN
+ 0 - OK
+ Other - 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;
+ st_select_lex_unit* parent_unit= select_lex->master_unit();
+ DBUG_ENTER("check_and_do_in_subquery_rewrites");
+
+ /*
+ IN/ALL/ANY rewrites are not applicable for so called fake select
+ (this select exists only to filter results of union if it is needed).
+ */
+ if (select_lex == select_lex->master_unit()->fake_select_lex)
+ DBUG_RETURN(0);
+
+ /*
+ 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->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) && // (1)
+ (subselect= parent_unit->item)) // (2)
+ {
+ Item_in_subselect *in_subs= NULL;
+ Item_allany_subselect *allany_subs= NULL;
+ switch (subselect->substype()) {
+ case Item_subselect::IN_SUBS:
+ in_subs= (Item_in_subselect *)subselect;
+ break;
+ case Item_subselect::ALL_SUBS:
+ case Item_subselect::ANY_SUBS:
+ allany_subs= (Item_allany_subselect *)subselect;
+ break;
+ default:
+ break;
+ }
+
+
+ /* 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
+ in_subs->emb_on_expr_nest && // 5
+ select_lex->outer_select()->join && // 6
+ parent_unit->first_select()->leaf_tables.elements && // 7
+ !in_subs->has_strategy() && // 8
+ select_lex->outer_select()->leaf_tables.elements && // 9
+ !((join->select_options | // 10
+ select_lex->outer_select()->join->select_options) // 10
+ & SELECT_STRAIGHT_JOIN)) // 10
+ {
+ DBUG_PRINT("info", ("Subquery is semi-join conversion candidate"));
+
+ (void)subquery_types_allow_materialization(in_subs);
+
+ in_subs->is_flattenable_semijoin= TRUE;
+
+ /* Register the subquery for further processing in flatten_subqueries() */
+ if (!in_subs->is_registered_semijoin)
+ {
+ Query_arena *arena, backup;
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+ select_lex->outer_select()->sj_subselects.push_back(in_subs);
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ in_subs->is_registered_semijoin= TRUE;
+ }
+ }
+ else
+ {
+ DBUG_PRINT("info", ("Subquery can't be converted to merged semi-join"));
+ /* Test if the user has set a legal combination of optimizer switches. */
+ if (!optimizer_flag(thd, OPTIMIZER_SWITCH_IN_TO_EXISTS) &&
+ !optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION))
+ my_error(ER_ILLEGAL_SUBQUERY_OPTIMIZER_SWITCHES, MYF(0));
+
+ /*
+ If the subquery predicate is IN/=ANY, analyse and set all possible
+ subquery execution strategies based on optimizer switches and syntactic
+ properties.
+ */
+ if (in_subs && !in_subs->has_strategy())
+ {
+ if (is_materialization_applicable(thd, in_subs, select_lex))
+ {
+ in_subs->add_strategy(SUBS_MATERIALIZATION);
+
+ /*
+ If the subquery is an AND-part of WHERE register for being processed
+ with jtbm strategy
+ */
+ if (in_subs->emb_on_expr_nest == NO_JOIN_NEST &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_SEMIJOIN))
+ {
+ in_subs->is_flattenable_semijoin= FALSE;
+ if (!in_subs->is_registered_semijoin)
+ {
+ Query_arena *arena, backup;
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+ select_lex->outer_select()->sj_subselects.push_back(in_subs);
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ in_subs->is_registered_semijoin= TRUE;
+ }
+ }
+ }
+
+ /*
+ IN-TO-EXISTS is the only universal strategy. Choose it if the user
+ allowed it via an optimizer switch, or if materialization is not
+ possible.
+ */
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_IN_TO_EXISTS) ||
+ !in_subs->has_strategy())
+ in_subs->add_strategy(SUBS_IN_TO_EXISTS);
+ }
+
+ /* Check if max/min optimization applicable */
+ if (allany_subs && !allany_subs->is_set_strategy())
+ {
+ uchar strategy= (allany_subs->is_maxmin_applicable(join) ?
+ (SUBS_MAXMIN_INJECTED | SUBS_MAXMIN_ENGINE) :
+ SUBS_IN_TO_EXISTS);
+ allany_subs->add_strategy(strategy);
+ }
+
+ /*
+ Transform each subquery predicate according to its overloaded
+ transformer.
+ */
+ if (subselect->select_transformer(join))
+ DBUG_RETURN(-1);
+ }
+ }
+ 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->cmp_type() != inner->cmp_type())
+ DBUG_RETURN(FALSE);
+ switch (outer->cmp_type()) {
+ case STRING_RESULT:
+ if (!(outer->collation.collation == inner->collation.collation))
+ DBUG_RETURN(FALSE);
+ // Materialization does not work with BLOB columns
+ if (inner->field_type() == MYSQL_TYPE_BLOB ||
+ inner->field_type() == MYSQL_TYPE_GEOMETRY)
+ DBUG_RETURN(FALSE);
+ /*
+ Materialization also is unable to work when create_tmp_table() will
+ create a blob column because item->max_length is too big.
+ The following check is copied from Item::make_string_field():
+ */
+ if (inner->max_length / inner->collation.collation->mbmaxlen >
+ CONVERT_IF_BIGGER_TO_BLOB)
+ {
+ DBUG_RETURN(FALSE);
+ }
+ break;
+ case TIME_RESULT:
+ if (mysql_type_to_time_type(outer->field_type()) !=
+ mysql_type_to_time_type(inner->field_type()))
+ DBUG_RETURN(FALSE);
+ default:
+ /* suitable for materialization */
+ break;
+ }
+ }
+
+ 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);
+}
+
+
+/**
+ Apply max min optimization of all/any subselect
+*/
+
+bool JOIN::transform_max_min_subquery()
+{
+ DBUG_ENTER("JOIN::transform_max_min_subquery");
+ Item_subselect *subselect= unit->item;
+ if (!subselect || (subselect->substype() != Item_subselect::ALL_SUBS &&
+ subselect->substype() != Item_subselect::ANY_SUBS))
+ DBUG_RETURN(0);
+ DBUG_RETURN(((Item_allany_subselect *) subselect)->
+ transform_into_max_min(this));
+}
+
+
+/*
+ Finalize IN->EXISTS conversion in case we couldn't use materialization.
+
+ DESCRIPTION Invoke the IN->EXISTS converter
+ Replace the Item_in_subselect with its wrapper Item_in_optimizer in WHERE.
+
+ RETURN
+ FALSE - Ok
+ TRUE - Fatal error
+*/
+
+bool make_in_exists_conversion(THD *thd, JOIN *join, Item_in_subselect *item)
+{
+ DBUG_ENTER("make_in_exists_conversion");
+ JOIN *child_join= item->unit->first_select()->join;
+ bool res;
+
+ /*
+ We're going to finalize IN->EXISTS conversion.
+ Normally, IN->EXISTS conversion takes place inside the
+ Item_subselect::fix_fields() call, where item_subselect->fixed==FALSE (as
+ fix_fields() haven't finished yet) and item_subselect->changed==FALSE (as
+ the conversion haven't been finalized)
+
+ At the end of Item_subselect::fix_fields() we had to set fixed=TRUE,
+ changed=TRUE (the only other option would have been to return error).
+
+ So, now we have to set these back for the duration of select_transformer()
+ call.
+ */
+ item->changed= 0;
+ item->fixed= 0;
+
+ SELECT_LEX *save_select_lex= thd->lex->current_select;
+ thd->lex->current_select= item->unit->first_select();
+
+ res= item->select_transformer(child_join);
+
+ thd->lex->current_select= save_select_lex;
+
+ if (res)
+ DBUG_RETURN(TRUE);
+
+ item->changed= 1;
+ item->fixed= 1;
+
+ Item *substitute= item->substitution;
+ bool do_fix_fields= !item->substitution->fixed;
+ /*
+ The Item_subselect has already been wrapped with Item_in_optimizer, so we
+ should search for item->optimizer, not 'item'.
+ */
+ Item *replace_me= item->optimizer;
+ DBUG_ASSERT(replace_me==substitute);
+
+ Item **tree= (item->emb_on_expr_nest == NO_JOIN_NEST)?
+ &join->conds : &(item->emb_on_expr_nest->on_expr);
+ if (replace_where_subcondition(join, tree, replace_me, substitute,
+ do_fix_fields))
+ DBUG_RETURN(TRUE);
+ item->substitution= NULL;
+
+ /*
+ If this is a prepared statement, repeat the above operation for
+ prep_where (or prep_on_expr).
+ */
+ if (!thd->stmt_arena->is_conventional())
+ {
+ tree= (item->emb_on_expr_nest == (TABLE_LIST*)NO_JOIN_NEST)?
+ &join->select_lex->prep_where :
+ &(item->emb_on_expr_nest->prep_on_expr);
+
+ if (replace_where_subcondition(join, tree, replace_me, substitute,
+ FALSE))
+ DBUG_RETURN(TRUE);
+ }
+ DBUG_RETURN(FALSE);
+}
+
+
+bool check_for_outer_joins(List<TABLE_LIST> *join_list)
+{
+ TABLE_LIST *table;
+ NESTED_JOIN *nested_join;
+ List_iterator<TABLE_LIST> li(*join_list);
+ while ((table= li++))
+ {
+ if ((nested_join= table->nested_join))
+ {
+ if (check_for_outer_joins(&nested_join->join_list))
+ return TRUE;
+ }
+
+ if (table->outer_join)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ 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;
+ THD *thd= join->thd;
+ List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables);
+ DBUG_ENTER("convert_join_subqueries_to_semijoins");
+
+ if (join->select_lex->sj_subselects.is_empty())
+ DBUG_RETURN(FALSE);
+
+ List_iterator_fast<Item_in_subselect> li(join->select_lex->sj_subselects);
+
+ while ((in_subq= li++))
+ {
+ SELECT_LEX *subq_sel= in_subq->get_select_lex();
+ if (subq_sel->handle_derived(thd->lex, DT_OPTIMIZE))
+ DBUG_RETURN(1);
+ if (subq_sel->handle_derived(thd->lex, DT_MERGE))
+ DBUG_RETURN(TRUE);
+ subq_sel->update_used_tables();
+ }
+
+ li.rewind();
+ /* First, convert child join's subqueries. We proceed bottom-up here */
+ while ((in_subq= li++))
+ {
+ st_select_lex *child_select= in_subq->get_select_lex();
+ JOIN *child_join= child_select->join;
+ child_join->outer_tables = child_join->table_count;
+
+ /*
+ 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=
+ test(in_subq->emb_on_expr_nest != NO_JOIN_NEST) * MAX_TABLES * 2 +
+ in_subq->is_correlated * MAX_TABLES + child_join->outer_tables;
+ }
+
+ // Temporary measure: disable semi-joins when they are together with outer
+ // joins.
+#if 0
+ if (check_for_outer_joins(join->join_list))
+ {
+ in_subq= join->select_lex->sj_subselects.head();
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+ goto skip_conversion;
+ }
+#endif
+ //dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables);
+ /*
+ 2. Pick which subqueries to convert:
+ sort the subquery array
+ - prefer correlated subqueries over uncorrelated;
+ - prefer subqueries that have greater number of outer tables;
+ */
+ bubble_sort<Item_in_subselect>(&join->select_lex->sj_subselects,
+ subq_sj_candidate_cmp, NULL);
+ // #tables-in-parent-query + #tables-in-subquery < MAX_TABLES
+ /* Replace all subqueries to be flattened with Item_int(1) */
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+
+ li.rewind();
+ while ((in_subq= li++))
+ {
+ bool remove_item= TRUE;
+
+ /* Stop processing if we've reached a subquery that's attached to the ON clause */
+ if (in_subq->emb_on_expr_nest != NO_JOIN_NEST)
+ break;
+
+ if (in_subq->is_flattenable_semijoin)
+ {
+ if (join->table_count +
+ in_subq->unit->first_select()->join->table_count >= MAX_TABLES)
+ break;
+ if (convert_subq_to_sj(join, in_subq))
+ goto restore_arena_and_fail;
+ }
+ else
+ {
+ if (join->table_count + 1 >= MAX_TABLES)
+ break;
+ if (convert_subq_to_jtbm(join, in_subq, &remove_item))
+ goto restore_arena_and_fail;
+ }
+ if (remove_item)
+ {
+ Item **tree= (in_subq->emb_on_expr_nest == NO_JOIN_NEST)?
+ &join->conds : &(in_subq->emb_on_expr_nest->on_expr);
+ Item *replace_me= in_subq->original_item();
+ if (replace_where_subcondition(join, tree, replace_me, new Item_int(1),
+ FALSE))
+ goto restore_arena_and_fail;
+ }
+ }
+//skip_conversion:
+ /*
+ 3. Finalize (perform IN->EXISTS rewrite) the subqueries that we didn't
+ convert:
+ */
+ while (in_subq)
+ {
+ JOIN *child_join= in_subq->unit->first_select()->join;
+ in_subq->changed= 0;
+ in_subq->fixed= 0;
+
+ SELECT_LEX *save_select_lex= thd->lex->current_select;
+ thd->lex->current_select= in_subq->unit->first_select();
+
+ bool res= in_subq->select_transformer(child_join);
+
+ thd->lex->current_select= save_select_lex;
+
+ if (res)
+ DBUG_RETURN(TRUE);
+
+ in_subq->changed= 1;
+ in_subq->fixed= 1;
+
+ Item *substitute= in_subq->substitution;
+ bool do_fix_fields= !in_subq->substitution->fixed;
+ Item **tree= (in_subq->emb_on_expr_nest == NO_JOIN_NEST)?
+ &join->conds : &(in_subq->emb_on_expr_nest->on_expr);
+ Item *replace_me= in_subq->original_item();
+ if (replace_where_subcondition(join, tree, replace_me, substitute,
+ do_fix_fields))
+ DBUG_RETURN(TRUE);
+ in_subq->substitution= NULL;
+ /*
+ If this is a prepared statement, repeat the above operation for
+ prep_where (or prep_on_expr). Subquery-to-semijoin conversion is
+ done once for prepared statement.
+ */
+ if (!thd->stmt_arena->is_conventional())
+ {
+ tree= (in_subq->emb_on_expr_nest == NO_JOIN_NEST)?
+ &join->select_lex->prep_where :
+ &(in_subq->emb_on_expr_nest->prep_on_expr);
+ /*
+ prep_on_expr/ prep_where may be NULL in some cases.
+ If that is the case, do nothing - simplify_joins() will copy
+ ON/WHERE expression into prep_on_expr/prep_where.
+ */
+ if (*tree && replace_where_subcondition(join, tree, replace_me, substitute,
+ FALSE))
+ DBUG_RETURN(TRUE);
+ }
+ /*
+ Revert to the IN->EXISTS strategy in the rare case when the subquery could
+ not be flattened.
+ */
+ in_subq->reset_strategy(SUBS_IN_TO_EXISTS);
+ if (is_materialization_applicable(thd, in_subq,
+ in_subq->unit->first_select()))
+ {
+ in_subq->add_strategy(SUBS_MATERIALIZATION);
+ }
+
+ in_subq= li++;
+ }
+
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ join->select_lex->sj_subselects.empty();
+ DBUG_RETURN(FALSE);
+
+restore_arena_and_fail:
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ DBUG_RETURN(TRUE);
+}
+
+
+/*
+ Get #output_rows and scan_time estimates for a "delayed" table.
+
+ SYNOPSIS
+ get_delayed_table_estimates()
+ table IN Table to get estimates for
+ out_rows OUT E(#rows in the table)
+ scan_time OUT E(scan_time).
+ startup_cost OUT cost to populate the table.
+
+ DESCRIPTION
+ Get #output_rows and scan_time estimates for a "delayed" table. By
+ "delayed" here we mean that the table is filled at the start of query
+ execution. This means that the optimizer can't use table statistics to
+ get #rows estimate for it, it has to call this function instead.
+
+ This function is expected to make different actions depending on the nature
+ of the table. At the moment there is only one kind of delayed tables,
+ non-flattenable semi-joins.
+*/
+
+void get_delayed_table_estimates(TABLE *table,
+ ha_rows *out_rows,
+ double *scan_time,
+ double *startup_cost)
+{
+ Item_in_subselect *item= table->pos_in_table_list->jtbm_subselect;
+
+ DBUG_ASSERT(item->engine->engine_type() ==
+ subselect_engine::HASH_SJ_ENGINE);
+
+ subselect_hash_sj_engine *hash_sj_engine=
+ ((subselect_hash_sj_engine*)item->engine);
+
+ *out_rows= (ha_rows)item->jtbm_record_count;
+ *startup_cost= item->jtbm_read_time;
+
+ /* Calculate cost of scanning the temptable */
+ double data_size= item->jtbm_record_count *
+ hash_sj_engine->tmp_table->s->reclength;
+ /* Do like in handler::read_time */
+ *scan_time= data_size/IO_SIZE + 2;
+}
+
+
+/**
+ @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)
+{
+ 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;
+ }
+ }
+ }
+ /*
+ We can come to here when
+ - we're doing replace operations on both on_expr and prep_on_expr
+ - on_expr is the same as prep_on_expr, or they share a sub-tree
+ (so, when we do replace in on_expr, we replace in prep_on_expr, too,
+ and when we try doing a replace in prep_on_expr, the item we wanted
+ to replace there has already been replaced)
+ */
+ return FALSE;
+}
+
+static int subq_sj_candidate_cmp(Item_in_subselect* el1, Item_in_subselect* el2,
+ void *arg)
+{
+ 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->emb_on_expr_nest != (void*)NO_JOIN_NEST)
+ {
+ if (subq_pred->emb_on_expr_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->emb_on_expr_nest;
+ emb_join_list= &emb_tbl_nest->nested_join->join_list;
+ }
+ else if (!subq_pred->emb_on_expr_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->emb_on_expr_nest->embedding;
+ if (emb_tbl_nest)
+ emb_join_list= &emb_tbl_nest->nested_join->join_list;
+ }
+ else if (!subq_pred->emb_on_expr_nest->nested_join)
+ {
+ TABLE_LIST *outer_tbl= subq_pred->emb_on_expr_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;
+ sj_nest->original_subq_pred_used_tables= subq_pred->used_tables() |
+ subq_pred->left_expr->used_tables();
+ /* 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;
+ 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.
+ */
+ parent_lex->leaf_tables.concat(&subq_lex->leaf_tables);
+
+ /*
+ 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= (TABLE_LIST*)(parent_lex->table_list.first); tl->next_local; tl= tl->next_local)
+ {}
+
+ tl->next_local= subq_lex->leaf_tables.head();
+
+ /* 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->reset_strategy(SUBS_SEMI_JOIN); // for subsequent executions
+ /*TODO: also reset the 'with_subselect' there. */
+
+ /* n. Adjust the parent_join->table_count counter */
+ uint table_no= parent_join->table_count;
+ /* n. Walk through child's tables and adjust table->map */
+ List_iterator_fast<TABLE_LIST> si(subq_lex->leaf_tables);
+ while ((tl= si++))
+ {
+ tl->set_tablenr(table_no);
+ if (tl->is_jtbm())
+ tl->jtbm_table_no= 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;
+ table_no++;
+ }
+ parent_join->table_count += subq_lex->join->table_count;
+ //parent_join->table_count += subq_lex->leaf_tables.elements;
+
+ /*
+ Put the subquery's WHERE into semi-join's sj_on_expr
+ 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 */
+ if (!sj_nest->sj_on_expr->fixed)
+ 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->top_level_item();
+ if (!emb_tbl_nest->on_expr->fixed)
+ emb_tbl_nest->on_expr->fix_fields(parent_join->thd,
+ &emb_tbl_nest->on_expr);
+ }
+ else
+ {
+ /* Inject into the WHERE */
+ parent_join->conds= and_items(parent_join->conds, sj_nest->sj_on_expr);
+ parent_join->conds->top_level_item();
+ /*
+ fix_fields must update the properties (e.g. st_select_lex::cond_count of
+ the correct select_lex.
+ */
+ save_lex= thd->lex->current_select;
+ thd->lex->current_select=parent_join->select_lex;
+ if (!parent_join->conds->fixed)
+ parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
+ thd->lex->current_select=save_lex;
+ 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);
+}
+
+
+const int SUBQERY_TEMPTABLE_NAME_MAX_LEN= 20;
+
+static void create_subquery_temptable_name(char *to, uint number)
+{
+ DBUG_ASSERT(number < 10000);
+ to= strmov(to, "<subquery");
+ to= int10_to_str((int) number, to, 10);
+ to[0]= '>';
+ to[1]= 0;
+}
+
+
+/*
+ Convert subquery predicate into non-mergeable semi-join nest.
+
+ TODO:
+ why does this do IN-EXISTS conversion? Can't we unify it with mergeable
+ semi-joins? currently, convert_subq_to_sj() cannot fail to convert (unless
+ fatal errors)
+
+
+ RETURN
+ FALSE - Ok
+ TRUE - Fatal error
+*/
+
+static bool convert_subq_to_jtbm(JOIN *parent_join,
+ Item_in_subselect *subq_pred,
+ bool *remove_item)
+{
+ SELECT_LEX *parent_lex= parent_join->select_lex;
+ List<TABLE_LIST> *emb_join_list= &parent_lex->top_join_list;
+ TABLE_LIST *emb_tbl_nest= NULL; // will change when we learn to handle outer joins
+ TABLE_LIST *tl;
+ DBUG_ENTER("convert_subq_to_jtbm");
+ bool optimization_delayed= TRUE;
+ subq_pred->set_strategy(SUBS_MATERIALIZATION);
+
+ subq_pred->is_jtbm_merged= TRUE;
+
+ *remove_item= TRUE;
+
+ TABLE_LIST *jtbm;
+ char *tbl_alias;
+ if (!(tbl_alias= (char*)parent_join->thd->calloc(SUBQERY_TEMPTABLE_NAME_MAX_LEN)) ||
+ !(jtbm= alloc_join_nest(parent_join->thd))) //todo: this is not a join nest!
+ {
+ DBUG_RETURN(TRUE);
+ }
+
+ jtbm->join_list= emb_join_list;
+ jtbm->embedding= emb_tbl_nest;
+ jtbm->jtbm_subselect= subq_pred;
+ jtbm->nested_join= NULL;
+
+ /* Nests do not participate in those 'chains', so: */
+ /* jtbm->next_leaf= jtbm->next_local= jtbm->next_global == NULL*/
+ emb_join_list->push_back(jtbm);
+
+ /*
+ Inject the jtbm table into TABLE_LIST::next_leaf list, so that
+ make_join_statistics() and co. can find it.
+ */
+ parent_lex->leaf_tables.push_back(jtbm);
+
+ /*
+ Same as above for TABLE_LIST::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= (TABLE_LIST*)(parent_lex->table_list.first); tl->next_local; tl= tl->next_local)
+ {}
+ tl->next_local= jtbm;
+
+ /* A theory: no need to re-connect the next_global chain */
+ if (optimization_delayed)
+ {
+ DBUG_ASSERT(parent_join->table_count < MAX_TABLES);
+
+ jtbm->jtbm_table_no= parent_join->table_count;
+
+ create_subquery_temptable_name(tbl_alias,
+ subq_pred->unit->first_select()->select_number);
+ jtbm->alias= tbl_alias;
+ parent_join->table_count++;
+ DBUG_RETURN(FALSE);
+ }
+ subselect_hash_sj_engine *hash_sj_engine=
+ ((subselect_hash_sj_engine*)subq_pred->engine);
+ jtbm->table= hash_sj_engine->tmp_table;
+
+ jtbm->table->tablenr= parent_join->table_count;
+ jtbm->table->map= table_map(1) << (parent_join->table_count);
+ jtbm->jtbm_table_no= jtbm->table->tablenr;
+
+ parent_join->table_count++;
+ DBUG_ASSERT(parent_join->table_count < MAX_TABLES);
+
+ Item *conds= hash_sj_engine->semi_join_conds;
+ conds->fix_after_pullout(parent_lex, &conds);
+
+ DBUG_EXECUTE("where", print_where(conds,"SJ-EXPR", QT_ORDINARY););
+
+ create_subquery_temptable_name(tbl_alias, hash_sj_engine->materialize_join->
+ select_lex->select_number);
+ jtbm->alias= tbl_alias;
+#if 0
+ /* Inject sj_on_expr into the parent's WHERE or ON */
+ if (emb_tbl_nest)
+ {
+ DBUG_ASSERT(0);
+ /*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, conds);
+ parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
+ parent_join->select_lex->where= parent_join->conds;
+ }
+#endif
+ /* Don't unlink the child subselect, as the subquery will be used. */
+
+ 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;
+}
+
+
+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);
+ }
+}
+
+
+static void set_emb_join_nest(List<TABLE_LIST> *tables, TABLE_LIST *emb_sj_nest)
+{
+ List_iterator<TABLE_LIST> it(*tables);
+ TABLE_LIST *tbl;
+ while ((tbl= it++))
+ {
+ /*
+ Note: check for nested_join first.
+ derived-merged tables have tbl->table!=NULL &&
+ tbl->table->reginfo==NULL.
+ */
+ if (tbl->nested_join)
+ set_emb_join_nest(&tbl->nested_join->join_list, emb_sj_nest);
+ else if (tbl->table)
+ tbl->table->reginfo.join_tab->emb_sj_nest= emb_sj_nest;
+
+ }
+}
+
+/*
+ Pull tables out of semi-join nests, if possible
+
+ 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++))
+ {
+ List_iterator<TABLE_LIST> child_li(sj_nest->nested_join->join_list);
+ TABLE_LIST *tbl;
+
+ /*
+ Don't do table pull-out for nested joins (if we get nested joins here, it
+ means these are outer joins. It is theoretically possible to do pull-out
+ for some of the outer tables but we dont support this currently.
+ */
+ bool have_join_nest_children= FALSE;
+
+ set_emb_join_nest(&sj_nest->nested_join->join_list, sj_nest);
+
+ while ((tbl= child_li++))
+ {
+ if (tbl->nested_join)
+ {
+ have_join_nest_children= TRUE;
+ break;
+ }
+ }
+
+
+ table_map pulled_tables= 0;
+ if (have_join_nest_children)
+ goto skip;
+
+ /* Action #1: Mark the constant tables to be pulled out */
+ child_li.rewind();
+ while ((tbl= child_li++))
+ {
+ if (tbl->table)
+ {
+ 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();
+ skip:
+ /*
+ 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.
+
+ NOTES
+ Because of Join::reoptimize(), this function may be called multiple times.
+
+ 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 &~join->const_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;
+
+ /*
+ join->get_partial_cost_and_fanout(n_tables + join->const_tables,
+ table_map(-1),
+ &subjoin_read_time,
+ &subjoin_out_rows);
+ */
+ join->get_prefix_cost_and_fanout(n_tables,
+ &subjoin_read_time,
+ &subjoin_out_rows);
+
+ sjm->materialization_cost.convert_from_cost(subjoin_read_time);
+ sjm->rows= subjoin_out_rows;
+
+ // Don't use the following list because it has "stale" items. use
+ // ref_pointer_array instead:
+ //
+ //List<Item> &right_expr_list=
+ // sj_nest->sj_subq_pred->unit->first_select()->item_list;
+ /*
+ Adjust output cardinality estimates. If the subquery has form
+
+ ... 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?)
+
+ See also get_post_group_estimate().
+ */
+ SELECT_LEX *subq_select= sj_nest->sj_subq_pred->unit->first_select();
+ {
+ for (uint i=0 ; i < join->const_tables + sjm->tables ; i++)
+ {
+ JOIN_TAB *tab= join->best_positions[i].table;
+ join->map2table[tab->table->tablenr]= tab;
+ }
+ //List_iterator<Item> it(right_expr_list);
+ Item **ref_array= subq_select->ref_pointer_array;
+ Item **ref_array_end= ref_array + subq_select->item_list.elements;
+ table_map map= 0;
+ //while ((item= it++))
+ for (;ref_array < ref_array_end; ref_array++)
+ map |= (*ref_array)->used_tables();
+ map= map & ~PSEUDO_TABLE_BITS;
+ Table_map_iterator tm_it(map);
+ int tableno;
+ 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(subq_select->ref_pointer_array,
+ subq_select->item_list.elements);
+ double lookup_cost= get_tmp_table_lookup_cost(join->thd,
+ subjoin_out_rows, rowlen);
+ double write_cost= get_tmp_table_write_cost(join->thd,
+ subjoin_out_rows, rowlen);
+
+ /*
+ Let materialization cost include the cost to write the data into the
+ temporary table:
+ */
+ sjm->materialization_cost.add_io(subjoin_out_rows, write_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(Item **p_items, uint elements)
+{
+ uint len= 0;
+ Item *item;
+ //List_iterator<Item> it(items);
+ Item **p_item;
+ for (p_item= p_items; p_item < p_items + elements ; p_item++)
+ {
+ item = *p_item;
+ switch (item->result_type()) {
+ case REAL_RESULT:
+ len += sizeof(double);
+ 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;
+}
+
+
+/**
+ The cost of a lookup into a unique hash/btree index on a temporary table
+ with 'row_count' rows each of size 'row_size'.
+
+ @param thd current query context
+ @param row_count number of rows in the temp table
+ @param row_size average size in bytes of the rows
+
+ @return the cost of one lookup
+*/
+
+static double
+get_tmp_table_lookup_cost(THD *thd, double row_count, uint row_size)
+{
+ if (row_count * row_size > thd->variables.max_heap_table_size)
+ return (double) DISK_TEMPTABLE_LOOKUP_COST;
+ else
+ return (double) HEAP_TEMPTABLE_LOOKUP_COST;
+}
+
+/**
+ The cost of writing a row into a temporary table with 'row_count' unique
+ rows each of size 'row_size'.
+
+ @param thd current query context
+ @param row_count number of rows in the temp table
+ @param row_size average size in bytes of the rows
+
+ @return the cost of writing one row
+*/
+
+static double
+get_tmp_table_write_cost(THD *thd, double row_count, uint row_size)
+{
+ double lookup_cost= get_tmp_table_lookup_cost(thd, row_count, row_size);
+ /*
+ TODO:
+ This is an optimistic estimate. Add additional costs resulting from
+ actually writing the row to memory/disk and possible index reorganization.
+ */
+ return lookup_cost;
+}
+
+
+/*
+ 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
+
+ Also check if it's feasible to factor common parts with table elimination
+
+ 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;
+
+ if (keyuse)
+ {
+ do
+ {
+ uint key= keyuse->key;
+ KEY *keyinfo;
+ key_part_map bound_parts= 0;
+ bool is_excluded_key= keyuse->is_for_hash_join();
+ if (!is_excluded_key)
+ {
+ keyinfo= table->key_info + key;
+ is_excluded_key= !test(keyinfo->flags & HA_NOSAME);
+ }
+ if (!is_excluded_key)
+ {
+ 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;
+ }
+ else
+ {
+ do
+ {
+ keyuse++;
+ } while (keyuse->key == key && keyuse->table == table);
+ }
+ } while (keyuse->table == table);
+ }
+ 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.
+*/
+
+bool is_multiple_semi_joins(JOIN *join, POSITION *prefix, uint idx, table_map inner_tables)
+{
+ for (int i= (int)idx; i >= 0; i--)
+ {
+ TABLE_LIST *emb_sj_nest;
+ if ((emb_sj_nest= prefix[i].table->emb_sj_nest))
+ {
+ if (inner_tables & emb_sj_nest->sj_inner_tables)
+ return !test(inner_tables == (emb_sj_nest->sj_inner_tables &
+ ~join->const_table_map));
+ }
+ }
+ return FALSE;
+}
+
+
+void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
+ double *current_record_count, double *current_read_time,
+ POSITION *loose_scan_pos)
+{
+ POSITION *pos= join->positions + idx;
+ const JOIN_TAB *new_join_tab= pos->table;
+ Semi_join_strategy_picker *pickers[]=
+ {
+ &pos->firstmatch_picker,
+ &pos->loosescan_picker,
+ &pos->sjmat_picker,
+ &pos->dups_weedout_picker,
+ NULL,
+ };
+
+ if (join->emb_sjm_nest)
+ {
+ /*
+ We're performing optimization inside SJ-Materialization nest:
+ - there are no other semi-joins inside semi-join nests
+ - attempts to build semi-join strategies here will confuse
+ the optimizer, so bail out.
+ */
+ pos->sj_strategy= SJ_OPT_NONE;
+ return;
+ }
+
+ /*
+ Update join->cur_sj_inner_tables (Used by FirstMatch in this function and
+ LooseScan detector in best_access_path)
+ */
+ remaining_tables &= ~new_join_tab->table->map;
+ pos->prefix_dups_producing_tables= join->cur_dups_producing_tables;
+ TABLE_LIST *emb_sj_nest;
+ if ((emb_sj_nest= new_join_tab->emb_sj_nest))
+ join->cur_dups_producing_tables |= emb_sj_nest->sj_inner_tables;
+
+ Semi_join_strategy_picker **strategy;
+ if (idx == join->const_tables)
+ {
+ /* First table, initialize pickers */
+ for (strategy= pickers; *strategy != NULL; strategy++)
+ (*strategy)->set_empty();
+ pos->inner_tables_handled_with_other_sjs= 0;
+ }
+ else
+ {
+ for (strategy= pickers; *strategy != NULL; strategy++)
+ {
+ (*strategy)->set_from_prev(pos - 1);
+ }
+ pos->inner_tables_handled_with_other_sjs=
+ pos[-1].inner_tables_handled_with_other_sjs;
+ }
+
+ pos->prefix_cost.convert_from_cost(*current_read_time);
+ pos->prefix_record_count= *current_record_count;
+
+ {
+ pos->sj_strategy= SJ_OPT_NONE;
+
+ for (strategy= pickers; *strategy != NULL; strategy++)
+ {
+ table_map handled_fanout;
+ sj_strategy_enum sj_strategy;
+ double rec_count= *current_record_count;
+ double read_time= *current_read_time;
+ if ((*strategy)->check_qep(join, idx, remaining_tables,
+ new_join_tab,
+ &rec_count,
+ &read_time,
+ &handled_fanout,
+ &sj_strategy,
+ loose_scan_pos))
+ {
+ /*
+ It's possible to use the strategy. Use it, if
+ - it removes semi-join fanout that was not removed before
+ - using it is cheaper than using something else,
+ and {if some other strategy has removed fanout
+ that this strategy is trying to remove, then it
+ did remove the fanout only for one semi-join}
+ This is to avoid a situation when
+ 1. strategy X removes fanout for semijoin X,Y
+ 2. using strategy Z is cheaper, but it only removes
+ fanout from semijoin X.
+ 3. We have no clue what to do about fanount of semi-join Y.
+ */
+ if ((join->cur_dups_producing_tables & handled_fanout) ||
+ (read_time < *current_read_time &&
+ !(handled_fanout & pos->inner_tables_handled_with_other_sjs)))
+ {
+ /* Mark strategy as used */
+ (*strategy)->mark_used();
+ pos->sj_strategy= sj_strategy;
+ if (sj_strategy == SJ_OPT_MATERIALIZE)
+ join->sjm_lookup_tables |= handled_fanout;
+ else
+ join->sjm_lookup_tables &= ~handled_fanout;
+ *current_read_time= read_time;
+ *current_record_count= rec_count;
+ join->cur_dups_producing_tables &= ~handled_fanout;
+ //TODO: update bitmap of semi-joins that were handled together with
+ // others.
+ if (is_multiple_semi_joins(join, join->positions, idx, handled_fanout))
+ pos->inner_tables_handled_with_other_sjs |= handled_fanout;
+ }
+ else
+ {
+ /* We decided not to apply the strategy. */
+ (*strategy)->set_empty();
+ }
+ }
+ }
+ }
+
+ if ((emb_sj_nest= new_join_tab->emb_sj_nest))
+ {
+ join->cur_sj_inner_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;
+ }
+
+ pos->prefix_cost.convert_from_cost(*current_read_time);
+ pos->prefix_record_count= *current_record_count;
+}
+
+
+void Sj_materialization_picker::set_from_prev(struct st_position *prev)
+{
+ if (prev->sjmat_picker.is_used)
+ set_empty();
+ else
+ {
+ sjm_scan_need_tables= prev->sjmat_picker.sjm_scan_need_tables;
+ sjm_scan_last_inner= prev->sjmat_picker.sjm_scan_last_inner;
+ }
+ is_used= FALSE;
+}
+
+
+bool Sj_materialization_picker::check_qep(JOIN *join,
+ uint idx,
+ table_map remaining_tables,
+ const JOIN_TAB *new_join_tab,
+ double *record_count,
+ double *read_time,
+ table_map *handled_fanout,
+ sj_strategy_enum *strategy,
+ POSITION *loose_scan_pos)
+{
+ 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.
+ */
+ 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;
+ 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();
+
+ /*
+ 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.
+ */
+ *read_time= mat_read_time;
+ *record_count= prefix_rec_count;
+ *handled_fanout= new_join_tab->emb_sj_nest->sj_inner_tables;
+ *strategy= SJ_OPT_MATERIALIZE;
+ return TRUE;
+ }
+ }
+
+ /* 4.A SJM-Scan second phase check */
+ if (sjm_scan_need_tables && /* Have SJM-Scan prefix */
+ !(sjm_scan_need_tables & remaining_tables))
+ {
+ TABLE_LIST *mat_nest=
+ join->positions[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= 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 */
+ bool disable_jbuf= (join->thd->variables.join_cache_level == 0);
+ for (i= first_tab + mat_info->tables; i <= idx; i++)
+ {
+ best_access_path(join, join->positions[i].table, rem_tables, i,
+ disable_jbuf, prefix_rec_count, &curpos, &dummy);
+ prefix_rec_count *= curpos.records_read;
+ prefix_cost += curpos.read_time;
+ }
+
+ *strategy= SJ_OPT_MATERIALIZE_SCAN;
+ *read_time= prefix_cost;
+ *record_count= prefix_rec_count;
+ *handled_fanout= mat_nest->sj_inner_tables;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+void LooseScan_picker::set_from_prev(struct st_position *prev)
+{
+ if (prev->loosescan_picker.is_used)
+ set_empty();
+ else
+ {
+ first_loosescan_table= prev->loosescan_picker.first_loosescan_table;
+ loosescan_need_tables= prev->loosescan_picker.loosescan_need_tables;
+ }
+ is_used= FALSE;
+}
+
+
+bool LooseScan_picker::check_qep(JOIN *join,
+ uint idx,
+ table_map remaining_tables,
+ const JOIN_TAB *new_join_tab,
+ double *record_count,
+ double *read_time,
+ table_map *handled_fanout,
+ sj_strategy_enum *strategy,
+ struct st_position *loose_scan_pos)
+{
+ POSITION *first= join->positions + 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 ((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)
+ {
+ 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 && !join->outer_join)
+ {
+ first_loosescan_table= idx;
+ 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 ((first_loosescan_table != MAX_TABLES) &&
+ !(remaining_tables & loosescan_need_tables) &&
+ (new_join_tab->table->map & 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 + 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.
+ */
+ bool disable_jbuf= (join->thd->variables.join_cache_level == 0);
+ optimize_wo_join_buffering(join, first_loosescan_table, idx,
+ remaining_tables,
+ TRUE, //first_alt
+ disable_jbuf ? join->table_count :
+ first_loosescan_table + n_tables,
+ record_count,
+ 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.
+ */
+ *strategy= SJ_OPT_LOOSE_SCAN;
+ *handled_fanout= first->table->emb_sj_nest->sj_inner_tables;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void Firstmatch_picker::set_from_prev(struct st_position *prev)
+{
+ if (prev->firstmatch_picker.is_used)
+ invalidate_firstmatch_prefix();
+ else
+ {
+ first_firstmatch_table= prev->firstmatch_picker.first_firstmatch_table;
+ first_firstmatch_rtbl= prev->firstmatch_picker.first_firstmatch_rtbl;
+ firstmatch_need_tables= prev->firstmatch_picker.firstmatch_need_tables;
+ }
+ is_used= FALSE;
+}
+
+bool Firstmatch_picker::check_qep(JOIN *join,
+ uint idx,
+ table_map remaining_tables,
+ const JOIN_TAB *new_join_tab,
+ double *record_count,
+ double *read_time,
+ table_map *handled_fanout,
+ sj_strategy_enum *strategy,
+ POSITION *loose_scan_pos)
+{
+ if (new_join_tab->emb_sj_nest &&
+ optimizer_flag(join->thd, OPTIMIZER_SWITCH_FIRSTMATCH) &&
+ !join->outer_join)
+ {
+ const table_map outer_corr_tables=
+ new_join_tab->emb_sj_nest->nested_join->sj_corr_tables |
+ 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 */
+ first_firstmatch_table= idx;
+ firstmatch_need_tables= sj_inner_tables;
+ first_firstmatch_rtbl= remaining_tables;
+ }
+
+ if (in_firstmatch_prefix())
+ {
+ if (outer_corr_tables & 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.
+ */
+ invalidate_firstmatch_prefix();
+ }
+ else
+ {
+ /* Record that we need all of this semi-join's inner tables, too */
+ firstmatch_need_tables|= sj_inner_tables;
+ }
+
+ if (in_firstmatch_prefix() &&
+ !(firstmatch_need_tables & remaining_tables))
+ {
+ /*
+ Got a complete FirstMatch range. Calculate correct costs and fanout
+ */
+
+ if (idx == first_firstmatch_table &&
+ optimizer_flag(join->thd, OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE))
+ {
+ /*
+ An important special case: only one inner table, and @@optimizer_switch
+ allows join buffering.
+ - read_time is the same (i.e. FirstMatch doesn't add any cost
+ - remove fanout added by the last table
+ */
+ if (*record_count)
+ *record_count /= join->positions[idx].records_read;
+ }
+ else
+ {
+ optimize_wo_join_buffering(join, first_firstmatch_table, idx,
+ remaining_tables, FALSE, idx,
+ record_count,
+ read_time);
+ }
+ /*
+ 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.
+ */
+ *handled_fanout= firstmatch_need_tables;
+ /* *record_count and *read_time were set by the above call */
+ *strategy= SJ_OPT_FIRST_MATCH;
+ return TRUE;
+ }
+ }
+ }
+ else
+ invalidate_firstmatch_prefix();
+ return FALSE;
+}
+
+
+void Duplicate_weedout_picker::set_from_prev(POSITION *prev)
+{
+ if (prev->dups_weedout_picker.is_used)
+ set_empty();
+ else
+ {
+ dupsweedout_tables= prev->dups_weedout_picker.dupsweedout_tables;
+ first_dupsweedout_table= prev->dups_weedout_picker.first_dupsweedout_table;
+ }
+ is_used= FALSE;
+}
+
+
+bool Duplicate_weedout_picker::check_qep(JOIN *join,
+ uint idx,
+ table_map remaining_tables,
+ const JOIN_TAB *new_join_tab,
+ double *record_count,
+ double *read_time,
+ table_map *handled_fanout,
+ sj_strategy_enum *strategy,
+ POSITION *loose_scan_pos
+ )
+{
+ TABLE_LIST *nest;
+ if ((nest= new_join_tab->emb_sj_nest))
+ {
+ if (!dupsweedout_tables)
+ first_dupsweedout_table= idx;
+
+ dupsweedout_tables |= nest->sj_inner_tables |
+ nest->nested_join->sj_depends_on |
+ nest->nested_join->sj_corr_tables;
+ }
+
+ if (dupsweedout_tables)
+ {
+ /* we're in the process of constructing a DuplicateWeedout range */
+ TABLE_LIST *emb= new_join_tab->table->pos_in_table_list->embedding;
+ /* and we've entered an inner side of an outer join*/
+ if (emb && emb->on_expr)
+ dupsweedout_tables |= emb->nested_join->used_tables;
+ }
+
+ /* If this is the last table that we need for DuplicateWeedout range */
+ if (dupsweedout_tables && !(remaining_tables & ~new_join_tab->table->map &
+ 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= 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;
+ double current_fanout= prefix_rec_count;
+ for (uint j= first_dupsweedout_table; j <= idx; j++)
+ {
+ POSITION *p= join->positions + j;
+ current_fanout *= p->records_read;
+ dups_cost += p->read_time + current_fanout / TIME_FOR_COMPARE;
+ 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= get_tmp_table_lookup_cost(join->thd,
+ sj_outer_fanout,
+ temptable_rec_size);
+ double one_write_cost= get_tmp_table_write_cost(join->thd,
+ sj_outer_fanout,
+ temptable_rec_size);
+
+ double write_cost= join->positions[first_tab].prefix_record_count*
+ sj_outer_fanout * one_write_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;
+
+ *read_time= dups_cost;
+ *record_count= prefix_rec_count * sj_outer_fanout;
+ *handled_fanout= dups_removed_fanout;
+ *strategy= SJ_OPT_DUPS_WEEDOUT;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ 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 (tab->emb_sj_nest)
+ {
+ table_map subq_tables= tab->emb_sj_nest->sj_inner_tables;
+ tab->join->sjm_lookup_tables &= ~subq_tables;
+ }
+
+ if ((emb_sj_nest= tab->emb_sj_nest))
+ {
+ /* If we're removing the last SJ-inner table, remove the sj-nest */
+ 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;
+ }
+ }
+ POSITION *pos= tab->join->positions + idx;
+ tab->join->cur_dups_producing_tables= pos->prefix_dups_producing_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;
+ }
+ 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;
+}
+
+
+/*
+ Re-calculate values of join->best_positions[start..end].prefix_record_count
+*/
+
+static void recalculate_prefix_record_count(JOIN *join, uint start, uint end)
+{
+ for (uint j= start; j < end ;j++)
+ {
+ double prefix_count;
+ if (j == join->const_tables)
+ prefix_count= 1.0;
+ else
+ prefix_count= join->best_positions[j-1].prefix_record_count *
+ join->best_positions[j-1].records_read;
+
+ join->best_positions[j].prefix_record_count= prefix_count;
+ }
+}
+
+
+/*
+ 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->table_count;
+ uint tablenr;
+ table_map remaining_tables= 0;
+ table_map handled_tabs= 0;
+ join->sjm_lookup_tables= 0;
+ for (tablenr= table_count - 1 ; tablenr != join->const_tables - 1; tablenr--)
+ {
+ POSITION *pos= join->best_positions + tablenr;
+ 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);
+ recalculate_prefix_record_count(join, tablenr - sjm->tables + 1,
+ tablenr);
+ first= tablenr - sjm->tables + 1;
+ join->best_positions[first].n_sj_tables= sjm->tables;
+ join->best_positions[first].sj_strategy= SJ_OPT_MATERIALIZE;
+ join->sjm_lookup_tables|= s->table->map;
+ }
+ else if (pos->sj_strategy == SJ_OPT_MATERIALIZE_SCAN)
+ {
+ POSITION *first_inner= join->best_positions + pos->sjmat_picker.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->sjmat_picker.sjm_scan_last_inner - sjm->tables + 1;
+ memcpy(join->best_positions + first,
+ sjm->positions, sizeof(POSITION) * sjm->tables);
+ recalculate_prefix_record_count(join, first, first + 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->firstmatch_picker.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->loosescan_picker.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;
+ /*
+ If LooseScan is based on ref access (including the "degenerate"
+ one with 0 key parts), we should use full index scan.
+
+ Unfortunately, lots of code assumes that if tab->type==JT_ALL &&
+ tab->quick!=NULL, then quick select should be used. The only
+ simple way to fix this is to remove the quick select:
+ */
+ if (join->best_positions[idx].key)
+ {
+ delete join->best_positions[idx].table->quick;
+ join->best_positions[idx].table->quick= NULL;
+ }
+ }
+ }
+ 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->dups_weedout_picker.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;
+ join->join_tab[first].sj_strategy= join->best_positions[first].sj_strategy;
+ join->join_tab[first].n_sj_tables= join->best_positions[first].n_sj_tables;
+ }
+}
+
+
+/*
+ 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_part1(JOIN_TAB *sjm_tab)
+{
+ DBUG_ENTER("setup_sj_materialization");
+ JOIN_TAB *tab= sjm_tab->bush_children->start;
+ TABLE_LIST *emb_sj_nest= tab->table->pos_in_table_list->embedding;
+
+ /* Walk out of outer join nests until we reach the semi-join nest we're in */
+ while (!emb_sj_nest->sj_mat_info)
+ emb_sj_nest= emb_sj_nest->embedding;
+
+ SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info;
+ THD *thd= tab->join->thd;
+ /* First the calls come to the materialization function */
+ //List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list;
+
+ DBUG_ASSERT(sjm->is_used);
+ /*
+ Set up the table to write to, do as select_union::create_result_table does
+ */
+ sjm->sjm_table_param.init();
+ sjm->sjm_table_param.bit_fields_as_long= TRUE;
+ //List_iterator<Item> it(item_list);
+ SELECT_LEX *subq_select= emb_sj_nest->sj_subq_pred->unit->first_select();
+ Item **p_item= subq_select->ref_pointer_array;
+ Item **p_end= p_item + subq_select->item_list.elements;
+ //while((right_expr= it++))
+ for(;p_item != p_end; p_item++)
+ sjm->sjm_table_cols.push_back(*p_item);
+
+ sjm->sjm_table_param.field_count= subq_select->item_list.elements;
+ sjm->sjm_table_param.force_not_null_cols= TRUE;
+
+ 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->map= emb_sj_nest->nested_join->used_tables;
+ 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;
+ sjm_tab->table= sjm->table;
+ sjm->table->pos_in_table_list= emb_sj_nest;
+
+ DBUG_RETURN(FALSE);
+}
+
+
+bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab)
+{
+ DBUG_ENTER("setup_sj_materialization_part2");
+ JOIN_TAB *tab= sjm_tab->bush_children->start;
+ TABLE_LIST *emb_sj_nest= tab->table->pos_in_table_list->embedding;
+ /* Walk out of outer join nests until we reach the semi-join nest we're in */
+ while (!emb_sj_nest->sj_mat_info)
+ emb_sj_nest= emb_sj_nest->embedding;
+ SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info;
+ THD *thd= tab->join->thd;
+ uint i;
+ //List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list;
+ //List_iterator<Item> it(item_list);
+
+ if (!sjm->is_sj_scan)
+ {
+ 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;
+ tab_ref= &sjm_tab->ref;
+ 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 ? cur_ref_buff : 0,
+ cur_key_part->length, tab_ref->items[i],
+ FALSE);
+ cur_ref_buff+= cur_key_part->store_length;
+ }
+ *ref_key= NULL; /* End marker. */
+
+ /*
+ We don't ever have guarded conditions for SJM tables, but code at SQL
+ layer depends on cond_guards array being alloced.
+ */
+ if (!(tab_ref->cond_guards= (bool**) thd->calloc(sizeof(uint*)*tmp_key_parts)))
+ {
+ DBUG_RETURN(TRUE);
+ }
+
+ 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 */
+ sjm_tab->type= JT_EQ_REF;
+ sjm_tab->select_cond= sjm->in_equality;
+ }
+ 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();
+ Item **p_item= emb_sj_nest->sj_subq_pred->unit->first_select()->ref_pointer_array;
+ for (uint i=0; i < sjm->sjm_table_cols.elements; i++)
+ {
+ bool dummy;
+ Item_equal *item_eq;
+ //Item *item= (it++)->real_item();
+ Item *item= (*(p_item++))->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:
+
+ table | attached condition
+ ------+--------------------
+ 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> it(item_eq->equal_items);
+ /* We're interested in field items only */
+ if (item_eq->get_const())
+ it++;
+ Item *item;
+ while ((item= it++))
+ {
+ if (!(item->used_tables() & ~emb_sj_nest->sj_inner_tables))
+ {
+ DBUG_ASSERT(item->real_item()->type() == Item::FIELD_ITEM);
+ copy_to= ((Item_field *) (item->real_item()))->field;
+ break;
+ }
+ }
+ }
+ 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);
+ }
+ sjm_tab->type= JT_ALL;
+
+ /* Initialize full scan */
+ sjm_tab->read_first_record= join_read_record_no_init;
+ sjm_tab->read_record.copy_field= sjm->copy_field;
+ sjm_tab->read_record.copy_field_end= sjm->copy_field +
+ sjm->sjm_table_cols.elements;
+ sjm_tab->read_record.read_record= rr_sequential_and_unpack;
+ }
+
+ sjm_tab->bush_children->end[-1].next_select= end_sj_materialize;
+
+ 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_sj_weedout_tmp_table()
+ thd Thread handle
+
+ 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
+*/
+
+bool
+SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
+{
+ 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;
+ bool using_unique_constraint=FALSE;
+ bool use_packed_rows= FALSE;
+ Field *field, *key_field;
+ uint null_pack_length, null_count;
+ uchar *null_flags;
+ uchar *pos;
+ DBUG_ENTER("create_sj_weedout_tmp_table");
+ DBUG_ASSERT(!is_degenerate);
+
+ tmp_table= NULL;
+ uint uniq_tuple_length_arg= rowid_len + null_bytes;
+ /*
+ 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(TRUE);
+ }
+ 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->table_charset= NULL;
+ share->primary_key= MAX_KEY; // Indicate no primary key
+ share->keys_for_keyread.init();
+ share->keys_in_use.init();
+
+ /* 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);
+ }
+
+ 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;
+ table->no_rows= 1; // We don't need the data
+
+ // recinfo must point after last field
+ recinfo++;
+ if (share->db_type() == TMP_ENGINE_HTON)
+ {
+ if (create_internal_tmp_table(table, keyinfo, start_recinfo, &recinfo, 0))
+ goto err;
+ }
+ if (open_tmp_table(table))
+ goto err;
+
+ thd->mem_root= mem_root_save;
+ tmp_table= table;
+ DBUG_RETURN(FALSE);
+
+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(TRUE); /* purecov: inspected */
+}
+
+
+/*
+ SemiJoinDuplicateElimination: Reset the temporary table
+*/
+
+int SJ_TMP_TABLE::sj_weedout_delete_rows()
+{
+ DBUG_ENTER("SJ_TMP_TABLE::sj_weedout_delete_rows");
+ if (tmp_table)
+ {
+ int rc= tmp_table->file->ha_delete_all_rows();
+ DBUG_RETURN(rc);
+ }
+ have_degenerate_row= FALSE;
+ DBUG_RETURN(0);
+}
+
+
+/*
+ SemiJoinDuplicateElimination: Weed out duplicate row combinations
+
+ SYNPOSIS
+ sj_weedout_check_row()
+ thd Thread handle
+
+ 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 SJ_TMP_TABLE::sj_weedout_check_row(THD *thd)
+{
+ int error;
+ SJ_TMP_TABLE::TAB *tab= tabs;
+ SJ_TMP_TABLE::TAB *tab_end= tabs_end;
+ uchar *ptr;
+ uchar *nulls_ptr;
+
+ DBUG_ENTER("SJ_TMP_TABLE::sj_weedout_check_row");
+
+ if (is_degenerate)
+ {
+ if (have_degenerate_row)
+ DBUG_RETURN(1);
+
+ have_degenerate_row= TRUE;
+ DBUG_RETURN(0);
+ }
+
+ ptr= tmp_table->record[0] + 1;
+
+ /* Put the the rowids tuple into table->record[0]: */
+
+ // 1. Store the length
+ if (((Field_varstring*)(tmp_table->field[0]))->length_bytes == 1)
+ {
+ *ptr= (uchar)(rowid_len + null_bytes);
+ ptr++;
+ }
+ else
+ {
+ int2store(ptr, rowid_len + null_bytes);
+ ptr += 2;
+ }
+
+ nulls_ptr= ptr;
+ // 2. Zero the null bytes
+ if (null_bytes)
+ {
+ bzero(ptr, null_bytes);
+ ptr += 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= tmp_table->file->ha_write_tmp_row(tmp_table->record[0]);
+ if (error)
+ {
+ /* create_internal_tmp_table_from_heap will generate error if needed */
+ if (!tmp_table->file->is_fatal_error(error, HA_CHECK_DUP))
+ DBUG_RETURN(1); /* Duplicate */
+ if (create_internal_tmp_table_from_heap(thd, tmp_table, start_recinfo,
+ &recinfo, error, 1))
+ DBUG_RETURN(-1);
+ }
+ DBUG_RETURN(0);
+}
+
+
+int init_dups_weedout(JOIN *join, uint first_table, int first_fanout_table, uint n_tables)
+{
+ THD *thd= join->thd;
+ DBUG_ENTER("init_dups_weedout");
+ 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 + first_table + n_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 */
+ {
+ size_t 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;
+ if (sjtbl->create_sj_weedout_tmp_table(thd))
+ DBUG_RETURN(TRUE);
+ 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;
+ }
+
+ sjtbl->next_flush_table= join->join_tab[first_table].flush_weedout_table;
+ join->join_tab[first_table].flush_weedout_table= sjtbl;
+ join->join_tab[first_fanout_table].first_weedout_table= sjtbl;
+ join->join_tab[first_table + n_tables - 1].check_weed_out_table= sjtbl;
+ 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;
+ DBUG_ENTER("setup_semijoin_dups_elimination");
+
+ join->complex_firstmatch_tables= table_map(0);
+
+ POSITION *pos= join->best_positions + join->const_tables;
+ for (i= join->const_tables ; i < join->top_join_tab_count; )
+ {
+ 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+= 1;// It used to be pos->n_sj_tables, but now they are embedded in a nest
+ pos += 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;
+
+ /* LooseScan requires records to be produced in order */
+ if (tab->select && tab->select->quick)
+ tab->select->quick->need_sorted_output();
+
+ for (uint j= i; j < i + pos->n_sj_tables; j++)
+ join->join_tab[j].inside_loosescan_range= TRUE;
+
+ /* Calculate key length */
+ keylen= 0;
+ keyno= pos->loosescan_picker.loosescan_key;
+ for (uint kp=0; kp < pos->loosescan_picker.loosescan_parts; kp++)
+ keylen += tab->table->key_info[keyno].key_part[kp].store_length;
+
+ tab->loosescan_key= keyno;
+ 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;
+ pos+= 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 > 2 && (js_tab->type == JT_REF ||
+ js_tab->type == JT_EQ_REF))))
+ {
+ /* Looks like we'll be using join buffer */
+ first_table= join->const_tables;
+ /*
+ Make sure that possible sorting of rows from the head table
+ is not to be employed.
+ */
+ if (join->get_sort_by_join_tab())
+ {
+ join->simple_order= 0;
+ join->simple_group= 0;
+ join->need_tmp= join->test_if_need_tmp_table();
+ }
+ break;
+ }
+ }
+
+ init_dups_weedout(join, first_table, i, i + pos->n_sj_tables - first_table);
+ i+= pos->n_sj_tables;
+ pos+= pos->n_sj_tables;
+ break;
+ }
+ case SJ_OPT_FIRST_MATCH:
+ {
+ JOIN_TAB *j;
+ JOIN_TAB *jump_to= tab-1;
+
+ bool complex_range= FALSE;
+ table_map tables_in_range= table_map(0);
+
+ for (j= tab; j != tab + pos->n_sj_tables; j++)
+ {
+ tables_in_range |= j->table->map;
+ if (!j->emb_sj_nest)
+ {
+ /*
+ Got a table that's not within any semi-join nest. This is a case
+ like this:
+
+ SELECT * FROM ot1, nt1 WHERE ot1.col IN (SELECT expr FROM it1, it2)
+
+ with a join order of
+
+ +----- FirstMatch range ----+
+ | |
+ ot1 it1 nt1 nt2 it2 it3 ...
+ | ^
+ | +-------- 'j' points here
+ +------------- SJ_OPT_FIRST_MATCH was set for this table as
+ it's the first one that produces duplicates
+
+ */
+ DBUG_ASSERT(j != tab); /* table ntX must have an itX before it */
+
+ /*
+ If the table right before us is an inner table (like it1 in the
+ picture), it should be set to jump back to previous outer-table
+ */
+ if (j[-1].emb_sj_nest)
+ j[-1].do_firstmatch= jump_to;
+
+ jump_to= j; /* Jump back to us */
+ complex_range= TRUE;
+ }
+ 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;
+ pos+= pos->n_sj_tables;
+
+ if (complex_range)
+ join->complex_firstmatch_tables|= tables_in_range;
+ break;
+ }
+ case SJ_OPT_NONE:
+ i++;
+ pos++;
+ 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 */
+ free_io_cache(table);
+ filesort_free_buffers(table,0);
+ }
+
+ 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?
+ */
+ /* TODO: In order to use these more efficient subquery engines in more cases,
+ the following problems need to be solved:
+ - the code that removes GROUP BY (group_list), also adds an ORDER BY
+ (order), thus GROUP BY queries (almost?) never pass through this branch.
+ Solution: remove the test below '!join->order', because we remove the
+ ORDER clase for subqueries anyway.
+ - in order to set a more efficient engine, the optimizer needs to both
+ decide to remove GROUP BY, *and* select one of the JT_[EQ_]REF[_OR_NULL]
+ access methods, *and* loose scan should be more expensive or
+ inapliccable. When is that possible?
+ - Consider expanding the applicability of this rewrite for loose scan
+ for group by queries.
+ */
+ if (!join->group_list && !join->order &&
+ join->unit->item &&
+ join->unit->item->substype() == Item_subselect::IN_SUBS &&
+ join->table_count == 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;
+ }
+}
+
+
+
+
+/**
+ Optimize all subqueries of a query that were not flattened into a semijoin.
+
+ @details
+ Optimize all immediate children subqueries of a query.
+
+ 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::optimize_unflattened_subqueries()
+{
+ return select_lex->optimize_unflattened_subqueries();
+}
+
+
+/*
+ Join tab execution startup function.
+
+ SYNOPSIS
+ join_tab_execution_startup()
+ tab Join tab to perform startup actions for
+
+ DESCRIPTION
+ Join tab execution startup function. This is different from
+ tab->read_first_record in the regard that this has actions that are to be
+ done once per join execution.
+
+ Currently there are only two possible startup functions, so we have them
+ both here inside if (...) branches. In future we could switch to function
+ pointers.
+
+ TODO: consider moving this together with JOIN_TAB::preread_init
+
+ RETURN
+ NESTED_LOOP_OK - OK
+ NESTED_LOOP_ERROR| NESTED_LOOP_KILLED - Error, abort the join execution
+*/
+
+enum_nested_loop_state join_tab_execution_startup(JOIN_TAB *tab)
+{
+ Item_in_subselect *in_subs;
+ DBUG_ENTER("join_tab_execution_startup");
+
+ if (tab->table->pos_in_table_list &&
+ (in_subs= tab->table->pos_in_table_list->jtbm_subselect))
+ {
+ /* It's a non-merged SJM nest */
+ DBUG_ASSERT(in_subs->engine->engine_type() ==
+ subselect_engine::HASH_SJ_ENGINE);
+ subselect_hash_sj_engine *hash_sj_engine=
+ ((subselect_hash_sj_engine*)in_subs->engine);
+ if (!hash_sj_engine->is_materialized)
+ {
+ hash_sj_engine->materialize_join->exec();
+ hash_sj_engine->is_materialized= TRUE;
+
+ if (hash_sj_engine->materialize_join->error || tab->join->thd->is_fatal_error)
+ DBUG_RETURN(NESTED_LOOP_ERROR);
+ }
+ }
+ else if (tab->bush_children)
+ {
+ /* It's a merged SJM nest */
+ enum_nested_loop_state rc;
+ SJ_MATERIALIZATION_INFO *sjm= tab->bush_children->start->emb_sj_nest->sj_mat_info;
+
+ if (!sjm->materialized)
+ {
+ JOIN *join= tab->join;
+ JOIN_TAB *join_tab= tab->bush_children->start;
+ JOIN_TAB *save_return_tab= join->return_tab;
+ /*
+ 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/* no EOF */)) < 0 ||
+ (rc= sub_select(join, join_tab, TRUE/* now EOF */)) < 0)
+ {
+ join->return_tab= save_return_tab;
+ DBUG_RETURN(rc); /* it's NESTED_LOOP_(ERROR|KILLED)*/
+ }
+ join->return_tab= save_return_tab;
+ sjm->materialized= TRUE;
+ }
+ }
+
+ DBUG_RETURN(NESTED_LOOP_OK);
+}
+
+
+/*
+ Create a dummy temporary table, useful only for the sake of having a
+ TABLE* object with map,tablenr and maybe_null properties.
+
+ This is used by non-mergeable semi-join materilization code to handle
+ degenerate cases where materialized subquery produced "Impossible WHERE"
+ and thus wasn't materialized.
+*/
+
+TABLE *create_dummy_tmp_table(THD *thd)
+{
+ DBUG_ENTER("create_dummy_tmp_table");
+ TABLE *table;
+ TMP_TABLE_PARAM sjm_table_param;
+ sjm_table_param.init();
+ sjm_table_param.field_count= 1;
+ List<Item> sjm_table_cols;
+ Item *column_item= new Item_int(1);
+ sjm_table_cols.push_back(column_item);
+ if (!(table= create_tmp_table(thd, &sjm_table_param,
+ sjm_table_cols, (ORDER*) 0,
+ TRUE /* distinct */,
+ 1, /*save_sum_fields*/
+ thd->options | TMP_TABLE_ALL_COLUMNS,
+ HA_POS_ERROR /*rows_limit */,
+ (char*)"dummy", TRUE /* Do not open */)))
+ {
+ DBUG_RETURN(NULL);
+ }
+ DBUG_RETURN(table);
+}
+
+
+/*
+ A class that is used to catch one single tuple that is sent to the join
+ output, and save it in Item_cache element(s).
+
+ It is very similar to select_singlerow_subselect but doesn't require a
+ Item_singlerow_subselect item.
+*/
+
+class select_value_catcher :public select_subselect
+{
+public:
+ select_value_catcher(Item_subselect *item_arg)
+ :select_subselect(item_arg)
+ {}
+ int send_data(List<Item> &items);
+ int setup(List<Item> *items);
+ bool assigned; /* TRUE <=> we've caught a value */
+ uint n_elements; /* How many elements we get */
+ Item_cache **row; /* Array of cache elements */
+};
+
+
+int select_value_catcher::setup(List<Item> *items)
+{
+ assigned= FALSE;
+ n_elements= items->elements;
+
+ if (!(row= (Item_cache**) sql_alloc(sizeof(Item_cache*)*n_elements)))
+ return TRUE;
+
+ Item *sel_item;
+ List_iterator<Item> li(*items);
+ for (uint i= 0; (sel_item= li++); i++)
+ {
+ if (!(row[i]= Item_cache::get_cache(sel_item)))
+ return TRUE;
+ row[i]->setup(sel_item);
+ }
+ return FALSE;
+}
+
+
+int select_value_catcher::send_data(List<Item> &items)
+{
+ DBUG_ENTER("select_value_catcher::send_data");
+ DBUG_ASSERT(!assigned);
+ DBUG_ASSERT(items.elements == n_elements);
+
+ if (unit->offset_limit_cnt)
+ { // Using limit offset,count
+ unit->offset_limit_cnt--;
+ DBUG_RETURN(0);
+ }
+
+ Item *val_item;
+ List_iterator_fast<Item> li(items);
+ for (uint i= 0; (val_item= li++); i++)
+ {
+ row[i]->store(val_item);
+ row[i]->cache_value();
+ }
+ assigned= TRUE;
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Setup JTBM join tabs for execution
+*/
+
+bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
+ Item **join_where)
+{
+ TABLE_LIST *table;
+ NESTED_JOIN *nested_join;
+ List_iterator<TABLE_LIST> li(*join_list);
+ DBUG_ENTER("setup_jtbm_semi_joins");
+
+ while ((table= li++))
+ {
+ Item_in_subselect *item;
+
+ if ((item= table->jtbm_subselect))
+ {
+ Item_in_subselect *subq_pred= item;
+ double rows;
+ double read_time;
+
+ /*
+ Perform optimization of the subquery, so that we know estmated
+ - cost of materialization process
+ - how many records will be in the materialized temp.table
+ */
+ if (subq_pred->optimize(&rows, &read_time))
+ DBUG_RETURN(TRUE);
+
+ subq_pred->jtbm_read_time= read_time;
+ subq_pred->jtbm_record_count=rows;
+ JOIN *subq_join= subq_pred->unit->first_select()->join;
+
+ if (!subq_join->tables_list || !subq_join->table_count)
+ {
+ /*
+ A special case; subquery's join is degenerate, and it either produces
+ 0 or 1 record. Examples of both cases:
+
+ select * from ot where col in (select ... from it where 2>3)
+ select * from ot where col in (select min(it.key) from it)
+
+ in this case, the subquery predicate has not been setup for
+ materialization. In particular, there is no materialized temp.table.
+ We'll now need to
+ 1. Check whether 1 or 0 records are produced, setup this as a
+ constant join tab.
+ 2. Create a dummy temporary table, because all of the join
+ optimization code relies on TABLE object being present (here we
+ follow a bad tradition started by derived tables)
+ */
+ DBUG_ASSERT(subq_pred->engine->engine_type() ==
+ subselect_engine::SINGLE_SELECT_ENGINE);
+ subselect_single_select_engine *engine=
+ (subselect_single_select_engine*)subq_pred->engine;
+ select_value_catcher *new_sink;
+ if (!(new_sink= new select_value_catcher(subq_pred)))
+ DBUG_RETURN(TRUE);
+ if (new_sink->setup(&engine->select_lex->join->fields_list) ||
+ engine->select_lex->join->change_result(new_sink) ||
+ engine->exec())
+ {
+ DBUG_RETURN(TRUE);
+ }
+ subq_pred->is_jtbm_const_tab= TRUE;
+
+ if (new_sink->assigned)
+ {
+ subq_pred->jtbm_const_row_found= TRUE;
+ /*
+ Subselect produced one row, which is saved in new_sink->row.
+ Inject "left_expr[i] == row[i] equalities into parent's WHERE.
+ */
+ Item *eq_cond;
+ for (uint i= 0; i < subq_pred->left_expr->cols(); i++)
+ {
+ eq_cond= new Item_func_eq(subq_pred->left_expr->element_index(i),
+ new_sink->row[i]);
+ if (!eq_cond || eq_cond->fix_fields(join->thd, &eq_cond))
+ DBUG_RETURN(1);
+
+ (*join_where)= and_items(*join_where, eq_cond);
+ }
+ }
+ else
+ {
+ /* Subselect produced no rows. Just set the flag, */
+ subq_pred->jtbm_const_row_found= FALSE;
+ }
+
+ /* Set up a dummy TABLE*, optimizer code needs JOIN_TABs to have TABLE */
+ TABLE *dummy_table;
+ if (!(dummy_table= create_dummy_tmp_table(join->thd)))
+ DBUG_RETURN(1);
+ table->table= dummy_table;
+ table->table->pos_in_table_list= table;
+ setup_table_map(table->table, table, table->jtbm_table_no);
+ }
+ else
+ {
+ DBUG_ASSERT(subq_pred->test_set_strategy(SUBS_MATERIALIZATION));
+ subq_pred->is_jtbm_const_tab= FALSE;
+ subselect_hash_sj_engine *hash_sj_engine=
+ ((subselect_hash_sj_engine*)item->engine);
+
+ table->table= hash_sj_engine->tmp_table;
+ table->table->pos_in_table_list= table;
+
+ setup_table_map(table->table, table, table->jtbm_table_no);
+
+ Item *sj_conds= hash_sj_engine->semi_join_conds;
+
+ (*join_where)= and_items(*join_where, sj_conds);
+ if (!(*join_where)->fixed)
+ (*join_where)->fix_fields(join->thd, join_where);
+ }
+ }
+
+ if ((nested_join= table->nested_join))
+ {
+ if (setup_jtbm_semi_joins(join, &nested_join->join_list, join_where))
+ DBUG_RETURN(TRUE);
+ }
+ }
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Choose an optimal strategy to execute an IN/ALL/ANY subquery predicate
+ based on cost.
+
+ @param join_tables the set of tables joined in the subquery
+
+ @notes
+ The method chooses between the materialization and IN=>EXISTS rewrite
+ strategies for the execution of a non-flattened subquery IN predicate.
+ The cost-based decision is made as follows:
+
+ 1. compute materialize_strategy_cost based on the unmodified subquery
+ 2. reoptimize the subquery taking into account the IN-EXISTS predicates
+ 3. compute in_exists_strategy_cost based on the reoptimized plan
+ 4. compare and set the cheaper strategy
+ if (materialize_strategy_cost >= in_exists_strategy_cost)
+ in_strategy = MATERIALIZATION
+ else
+ in_strategy = IN_TO_EXISTS
+ 5. if in_strategy = MATERIALIZATION and it is not possible to initialize it
+ revert to IN_TO_EXISTS
+ 6. if (in_strategy == MATERIALIZATION)
+ revert the subquery plan to the original one before reoptimizing
+ else
+ inject the IN=>EXISTS predicates into the new EXISTS subquery plan
+
+ The implementation itself is a bit more complicated because it takes into
+ account two more factors:
+ - whether the user allowed both strategies through an optimizer_switch, and
+ - if materialization was the cheaper strategy, whether it can be executed
+ or not.
+
+ @retval FALSE success.
+ @retval TRUE error occurred.
+*/
+
+bool JOIN::choose_subquery_plan(table_map join_tables)
+{
+ enum_reopt_result reopt_result= REOPT_NONE;
+ Item_in_subselect *in_subs;
+
+ /*
+ IN/ALL/ANY optimizations are not applicable for so called fake select
+ (this select exists only to filter results of union if it is needed).
+ */
+ if (select_lex == select_lex->master_unit()->fake_select_lex)
+ return 0;
+
+ if (is_in_subquery())
+ {
+ in_subs= (Item_in_subselect*) unit->item;
+ if (in_subs->create_in_to_exists_cond(this))
+ return true;
+ }
+ else
+ return false;
+
+ /* A strategy must be chosen earlier. */
+ DBUG_ASSERT(in_subs->has_strategy());
+ DBUG_ASSERT(in_to_exists_where || in_to_exists_having);
+ DBUG_ASSERT(!in_to_exists_where || in_to_exists_where->fixed);
+ DBUG_ASSERT(!in_to_exists_having || in_to_exists_having->fixed);
+
+ /* The original QEP of the subquery. */
+ Join_plan_state save_qep(table_count);
+
+ /*
+ Compute and compare the costs of materialization and in-exists if both
+ strategies are possible and allowed by the user (checked during the prepare
+ phase.
+ */
+ if (in_subs->test_strategy(SUBS_MATERIALIZATION) &&
+ in_subs->test_strategy(SUBS_IN_TO_EXISTS))
+ {
+ JOIN *outer_join;
+ JOIN *inner_join= this;
+ /* Number of unique value combinations filtered by the IN predicate. */
+ double outer_lookup_keys;
+ /* Cost and row count of the unmodified subquery. */
+ double inner_read_time_1, inner_record_count_1;
+ /* Cost of the subquery with injected IN-EXISTS predicates. */
+ double inner_read_time_2;
+ /* The cost to compute IN via materialization. */
+ double materialize_strategy_cost;
+ /* The cost of the IN->EXISTS strategy. */
+ double in_exists_strategy_cost;
+ double dummy;
+
+ /*
+ A. Estimate the number of rows of the outer table that will be filtered
+ by the IN predicate.
+ */
+ outer_join= unit->outer_select() ? unit->outer_select()->join : NULL;
+ if (outer_join && outer_join->table_count > 0)
+ {
+ /*
+ TODO:
+ Currently outer_lookup_keys is computed as the number of rows in
+ the partial join including the JOIN_TAB where the IN predicate is
+ pushed to. In the general case this is a gross overestimate because
+ due to caching we are interested only in the number of unique keys.
+ The search key may be formed by columns from much fewer than all
+ tables in the partial join. Example:
+ select * from t1, t2 where t1.c1 = t2.key AND t2.c2 IN (select ...);
+ If the join order: t1, t2, the number of unique lookup keys is ~ to
+ the number of unique values t2.c2 in the partial join t1 join t2.
+ */
+ outer_join->get_partial_cost_and_fanout(in_subs->get_join_tab_idx(),
+ table_map(-1),
+ &dummy,
+ &outer_lookup_keys);
+ }
+ else
+ {
+ /*
+ TODO: outer_join can be NULL for DELETE statements.
+ How to compute its cost?
+ */
+ outer_lookup_keys= 1;
+ }
+
+ /*
+ B. Estimate the cost and number of records of the subquery both
+ unmodified, and with injected IN->EXISTS predicates.
+ */
+ inner_read_time_1= inner_join->best_read;
+ inner_record_count_1= inner_join->record_count;
+
+ if (in_to_exists_where && const_tables != table_count)
+ {
+ /*
+ Re-optimize and cost the subquery taking into account the IN-EXISTS
+ conditions.
+ */
+ reopt_result= reoptimize(in_to_exists_where, join_tables, &save_qep);
+ if (reopt_result == REOPT_ERROR)
+ return TRUE;
+
+ /* Get the cost of the modified IN-EXISTS plan. */
+ inner_read_time_2= inner_join->best_read;
+
+ }
+ else
+ {
+ /* Reoptimization would not produce any better plan. */
+ inner_read_time_2= inner_read_time_1;
+ }
+
+ /*
+ C. Compute execution costs.
+ */
+ /* C.1 Compute the cost of the materialization strategy. */
+ //uint rowlen= get_tmp_table_rec_length(unit->first_select()->item_list);
+ uint rowlen= get_tmp_table_rec_length(ref_pointer_array,
+ select_lex->item_list.elements);
+ /* The cost of writing one row into the temporary table. */
+ double write_cost= get_tmp_table_write_cost(thd, inner_record_count_1,
+ rowlen);
+ /* The cost of a lookup into the unique index of the materialized table. */
+ double lookup_cost= get_tmp_table_lookup_cost(thd, inner_record_count_1,
+ rowlen);
+ /*
+ The cost of executing the subquery and storing its result in an indexed
+ temporary table.
+ */
+ double materialization_cost= inner_read_time_1 +
+ write_cost * inner_record_count_1;
+
+ materialize_strategy_cost= materialization_cost +
+ outer_lookup_keys * lookup_cost;
+
+ /* C.2 Compute the cost of the IN=>EXISTS strategy. */
+ in_exists_strategy_cost= outer_lookup_keys * inner_read_time_2;
+
+ /* C.3 Compare the costs and choose the cheaper strategy. */
+ if (materialize_strategy_cost >= in_exists_strategy_cost)
+ in_subs->set_strategy(SUBS_IN_TO_EXISTS);
+ else
+ in_subs->set_strategy(SUBS_MATERIALIZATION);
+
+ DBUG_PRINT("info",
+ ("mat_strategy_cost: %.2f, mat_cost: %.2f, write_cost: %.2f, lookup_cost: %.2f",
+ materialize_strategy_cost, materialization_cost, write_cost, lookup_cost));
+ DBUG_PRINT("info",
+ ("inx_strategy_cost: %.2f, inner_read_time_2: %.2f",
+ in_exists_strategy_cost, inner_read_time_2));
+ DBUG_PRINT("info",("outer_lookup_keys: %.2f", outer_lookup_keys));
+ }
+
+ /*
+ If (1) materialization is a possible strategy based on semantic analysis
+ during the prepare phase, then if
+ (2) it is more expensive than the IN->EXISTS transformation, and
+ (3) it is not possible to create usable indexes for the materialization
+ strategy,
+ fall back to IN->EXISTS.
+ otherwise
+ use materialization.
+ */
+ if (in_subs->test_strategy(SUBS_MATERIALIZATION) &&
+ in_subs->setup_mat_engine())
+ {
+ /*
+ If materialization was the cheaper or the only user-selected strategy,
+ but it is not possible to execute it due to limitations in the
+ implementation, fall back to IN-TO-EXISTS.
+ */
+ in_subs->set_strategy(SUBS_IN_TO_EXISTS);
+ }
+
+ if (in_subs->test_strategy(SUBS_MATERIALIZATION))
+ {
+ /* Restore the original query plan used for materialization. */
+ if (reopt_result == REOPT_NEW_PLAN)
+ restore_query_plan(&save_qep);
+
+ in_subs->unit->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
+ select_lex->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
+
+ /*
+ 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.
+ */
+ in_subs->unit->global_parameters->select_limit= NULL;
+ in_subs->unit->set_limit(unit->global_parameters);
+ /*
+ Set the limit of this JOIN object as well, because normally its being
+ set in the beginning of JOIN::optimize, which was already done.
+ */
+ select_limit= in_subs->unit->select_limit_cnt;
+ }
+ else if (in_subs->test_strategy(SUBS_IN_TO_EXISTS))
+ {
+ if (reopt_result == REOPT_NONE && in_to_exists_where &&
+ const_tables != table_count)
+ {
+ /*
+ The subquery was not reoptimized with the newly injected IN-EXISTS
+ conditions either because the user allowed only the IN-EXISTS strategy,
+ or because materialization was not possible based on semantic analysis.
+ */
+ reopt_result= reoptimize(in_to_exists_where, join_tables, NULL);
+ if (reopt_result == REOPT_ERROR)
+ return TRUE;
+ }
+
+ if (in_subs->inject_in_to_exists_cond(this))
+ return TRUE;
+ /*
+ If the injected predicate is correlated the IN->EXISTS transformation
+ make the subquery dependent.
+ */
+ if ((in_to_exists_where &&
+ in_to_exists_where->used_tables() & OUTER_REF_TABLE_BIT) ||
+ (in_to_exists_having &&
+ in_to_exists_having->used_tables() & OUTER_REF_TABLE_BIT))
+ {
+ in_subs->unit->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
+ select_lex->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
+ }
+ select_limit= 1;
+ }
+ else
+ DBUG_ASSERT(FALSE);
+
+ return FALSE;
+}
+
+
+/**
+ Choose a query plan for a table-less subquery.
+
+ @notes
+
+ @retval FALSE success.
+ @retval TRUE error occurred.
+*/
+
+bool JOIN::choose_tableless_subquery_plan()
+{
+ DBUG_ASSERT(!tables_list || !table_count);
+ if (unit->item)
+ {
+ DBUG_ASSERT(unit->item->type() == Item::SUBSELECT_ITEM);
+ Item_subselect *subs_predicate= unit->item;
+
+ /*
+ If the optimizer determined that his query has an empty result,
+ in most cases the subquery predicate is a known constant value -
+ either of TRUE, FALSE or NULL. The implementation of
+ Item_subselect::no_rows_in_result() determines which one.
+ */
+ if (zero_result_cause)
+ {
+ if (!implicit_grouping)
+ {
+ /*
+ Both group by queries and non-group by queries without aggregate
+ functions produce empty subquery result. There is no need to further
+ rewrite the subquery because it will not be executed at all.
+ */
+ return FALSE;
+ }
+
+ /* @todo
+ A further optimization is possible when a non-group query with
+ MIN/MAX/COUNT is optimized by opt_sum_query. Then, if there are
+ only MIN/MAX functions over an empty result set, the subquery
+ result is a NULL value/row, thus the value of subs_predicate is
+ NULL.
+ */
+ }
+
+ /*
+ For IN subqueries, use IN->EXISTS transfomation, unless the subquery
+ has been converted to a JTBM semi-join. In that case, just leave
+ everything as-is, setup_jtbm_semi_joins() has special handling for cases
+ like this.
+ */
+ if (subs_predicate->is_in_predicate() &&
+ !(subs_predicate->substype() == Item_subselect::IN_SUBS &&
+ ((Item_in_subselect*)subs_predicate)->is_jtbm_merged))
+ {
+ Item_in_subselect *in_subs;
+ in_subs= (Item_in_subselect*) subs_predicate;
+ in_subs->set_strategy(SUBS_IN_TO_EXISTS);
+ if (in_subs->create_in_to_exists_cond(this) ||
+ in_subs->inject_in_to_exists_cond(this))
+ return TRUE;
+ tmp_having= having;
+ }
+ }
+ return FALSE;
+}
diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h
new file mode 100644
index 00000000000..eca7b1acb3b
--- /dev/null
+++ b/sql/opt_subselect.h
@@ -0,0 +1,381 @@
+/*
+ Semi-join subquery optimization code definitions
+*/
+
+#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);
+bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
+ Item **join_where);
+
+// 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
+{
+ /* 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;
+
+public:
+ 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 &&
+ (keyuse->table->file->index_flags(keyuse->key, 0, 1 ) & HA_READ_ORDER))
+
+ {
+ 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)
+ PREV_BITS(key_part_map, max_loose_keypart+1) && // (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_picker.loosescan_key= best_loose_scan_key;
+ pos->loosescan_picker.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, 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_part1(JOIN_TAB *sjm_tab);
+bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab);
+
+
+/*
+ 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;
+
+ SJ_TMP_TABLE *next_flush_table;
+
+ int sj_weedout_delete_rows();
+ int sj_weedout_check_row(THD *thd);
+ bool create_sj_weedout_tmp_table(THD *thd);
+};
+
+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);
+
+
+void get_delayed_table_estimates(TABLE *table,
+ ha_rows *out_rows,
+ double *scan_time,
+ double *startup_cost);
+
+enum_nested_loop_state join_tab_execution_startup(JOIN_TAB *tab);
+
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 35986cf7fc0..b6aca56f047 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -76,10 +76,12 @@ static int maxmin_in_range(bool max_fl, Field* field, COND *cond);
# Multiplication of number of rows in all tables
*/
-static ulonglong get_exact_record_count(TABLE_LIST *tables)
+static ulonglong get_exact_record_count(List<TABLE_LIST> &tables)
{
ulonglong count= 1;
- for (TABLE_LIST *tl= tables; tl; tl= tl->next_leaf)
+ TABLE_LIST *tl;
+ List_iterator<TABLE_LIST> ti(tables);
+ while ((tl= ti++))
{
ha_rows tmp= tl->table->file->records();
if ((tmp == HA_POS_ERROR))
@@ -236,9 +238,11 @@ static int get_index_max_value(TABLE *table, TABLE_REF *ref, uint range_fl)
*/
int opt_sum_query(THD *thd,
- TABLE_LIST *tables, List<Item> &all_fields, COND *conds)
+ List<TABLE_LIST> &tables, List<Item> &all_fields, COND *conds)
{
List_iterator_fast<Item> it(all_fields);
+ List_iterator<TABLE_LIST> ti(tables);
+ TABLE_LIST *tl;
int const_result= 1;
bool recalc_const_item= 0;
ulonglong count= 1;
@@ -246,7 +250,7 @@ int opt_sum_query(THD *thd,
table_map removed_tables= 0, outer_tables= 0, used_tables= 0;
table_map where_tables= 0;
Item *item;
- int error;
+ int error= 0;
DBUG_ENTER("opt_sum_query");
if (conds)
@@ -256,7 +260,7 @@ int opt_sum_query(THD *thd,
Analyze outer join dependencies, and, if possible, compute the number
of returned rows.
*/
- for (TABLE_LIST *tl= tables; tl; tl= tl->next_leaf)
+ while ((tl= ti++))
{
TABLE_LIST *embedded;
for (embedded= tl ; embedded; embedded= embedded->embedding)
@@ -297,6 +301,15 @@ int opt_sum_query(THD *thd,
is_exact_count= FALSE;
count= 1; // ensure count != 0
}
+ else if (tl->is_materialized_derived() ||
+ tl->jtbm_subselect)
+ {
+ /*
+ Can't remove a derived table as it's number of rows is just an
+ estimate.
+ */
+ DBUG_RETURN(0);
+ }
else
{
error= tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
@@ -486,30 +499,32 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
/* MULT_EQUAL_FUNC */
{
Item_equal *item_equal= (Item_equal *) func_item;
- Item_equal_iterator it(*item_equal);
- args[0]= it++;
- if (it++)
- return 0;
if (!(args[1]= item_equal->get_const()))
return 0;
+ Item_equal_fields_iterator it(*item_equal);
+ if (!(item= it++))
+ return 0;
+ args[0]= item->real_item();
if (args[0]->max_length < args[1]->max_length)
return 0;
+ if (it++)
+ return 0;
}
break;
case 1:
/* field IS NULL */
- item= func_item->arguments()[0];
+ item= func_item->arguments()[0]->real_item();
if (item->type() != Item::FIELD_ITEM)
return 0;
args[0]= item;
break;
case 2:
/* 'field op const' or 'const op field' */
- item= func_item->arguments()[0];
+ item= func_item->arguments()[0]->real_item();
if (item->type() == Item::FIELD_ITEM)
{
args[0]= item;
- item= func_item->arguments()[1];
+ item= func_item->arguments()[1]->real_item();
if (!item->const_item())
return 0;
args[1]= item;
@@ -517,7 +532,7 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
else if (item->const_item())
{
args[1]= item;
- item= func_item->arguments()[1];
+ item= func_item->arguments()[1]->real_item();
if (item->type() != Item::FIELD_ITEM)
return 0;
args[0]= item;
@@ -530,13 +545,13 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
break;
case 3:
/* field BETWEEN const AND const */
- item= func_item->arguments()[0];
+ item= func_item->arguments()[0]->real_item();
if (item->type() == Item::FIELD_ITEM)
{
args[0]= item;
for (int i= 1 ; i <= 2; i++)
{
- item= func_item->arguments()[i];
+ item= func_item->arguments()[i]->real_item();
if (!item->const_item())
return 0;
args[i]= item;
@@ -624,8 +639,10 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
test(cond->used_tables() & ~PSEUDO_TABLE_BITS))
{
/* Condition doesn't restrict the used table */
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(!cond->const_item());
}
+ else if (cond->is_expensive())
+ DBUG_RETURN(FALSE);
if (cond->type() == Item::COND_ITEM)
{
if (((Item_cond*) cond)->functype() == Item_func::COND_OR_FUNC)
diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc
index 65a7d662425..545001c9df1 100644
--- a/sql/opt_table_elimination.cc
+++ b/sql/opt_table_elimination.cc
@@ -588,10 +588,8 @@ void eliminate_tables(JOIN *join)
if (!join->outer_join)
DBUG_VOID_RETURN;
-#ifndef DBUG_OFF
if (!optimizer_flag(thd, OPTIMIZER_SWITCH_TABLE_ELIMINATION))
DBUG_VOID_RETURN; /* purecov: inspected */
-#endif
/* Find the tables that are referred to from WHERE/HAVING */
used_tables= (join->conds? join->conds->used_tables() : 0) |
@@ -727,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();
}
}
@@ -920,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]))
{
@@ -1205,15 +1208,16 @@ void build_eq_mods_for_cond(Dep_analysis_context *ctx,
if (!(fvl= new List<Dep_value_field>))
break; /* purecov: inspected */
- Item_equal_iterator it(*item_equal);
- Item_field *item;
+ Item_equal_fields_iterator it(*item_equal);
+ Item *item;
Item *bound_item= item_equal->get_const();
while ((item= it++))
{
+ Field *equal_field= it.get_curr_field();
if ((item->used_tables() & ctx->usable_tables))
{
Dep_value_field *field_val;
- if ((field_val= ctx->get_field_value(item->field)))
+ if ((field_val= ctx->get_field_value(equal_field)))
fvl->push_back(field_val);
}
else
@@ -1229,7 +1233,7 @@ void build_eq_mods_for_cond(Dep_analysis_context *ctx,
if (fvl->elements)
{
- exchange_sort<Dep_value_field>(fvl, compare_field_values, NULL);
+ bubble_sort<Dep_value_field>(fvl, compare_field_values, NULL);
add_module_expr(ctx, eq_mod, *and_level, NULL, bound_item, fvl);
}
break;
diff --git a/sql/parse_file.cc b/sql/parse_file.cc
index e5b2953e969..761ab9ee10a 100644
--- a/sql/parse_file.cc
+++ b/sql/parse_file.cc
@@ -86,6 +86,40 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s)
return FALSE;
}
+static ulonglong view_algo_to_frm(ulonglong val)
+{
+ switch(val)
+ {
+ case VIEW_ALGORITHM_UNDEFINED:
+ return VIEW_ALGORITHM_UNDEFINED_FRM;
+ case VIEW_ALGORITHM_MERGE:
+ return VIEW_ALGORITHM_MERGE_FRM;
+ case VIEW_ALGORITHM_TMPTABLE:
+ return VIEW_ALGORITHM_TMPTABLE_FRM;
+ }
+ DBUG_ASSERT(0); /* Should never happen */
+ return VIEW_ALGORITHM_UNDEFINED;
+}
+
+static ulonglong view_algo_from_frm(ulonglong val)
+{
+ switch(val)
+ {
+ case VIEW_ALGORITHM_UNDEFINED_FRM:
+ return VIEW_ALGORITHM_UNDEFINED;
+ case VIEW_ALGORITHM_MERGE_FRM:
+ return VIEW_ALGORITHM_MERGE;
+ case VIEW_ALGORITHM_TMPTABLE_FRM:
+ return VIEW_ALGORITHM_TMPTABLE;
+ }
+
+ /*
+ Early versions of MariaDB 5.2/5.3 had identical in-memory and frm values
+ Return input value.
+ */
+ return val;
+}
+
/**
Write parameter value to IO_CACHE.
@@ -124,8 +158,14 @@ write_parameter(IO_CACHE *file, uchar* base, File_option *parameter)
break;
}
case FILE_OPTIONS_ULONGLONG:
+ case FILE_OPTIONS_VIEW_ALGO:
{
- num.set(*((ulonglong *)(base + parameter->offset)), &my_charset_bin);
+ ulonglong val= *(ulonglong *)(base + parameter->offset);
+
+ if (parameter->type == FILE_OPTIONS_VIEW_ALGO)
+ val= view_algo_to_frm(val);
+
+ num.set(val, &my_charset_bin);
if (my_b_append(file, (const uchar *)num.ptr(), num.length()))
DBUG_RETURN(TRUE);
break;
@@ -384,7 +424,7 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root,
DBUG_RETURN(0);
}
- if (!(parser->buff= (char*) alloc_root(mem_root, stat_info.st_size+1)))
+ if (!(parser->buff= (char*) alloc_root(mem_root, (size_t)(stat_info.st_size+1))))
{
DBUG_RETURN(0);
}
@@ -395,7 +435,7 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root,
}
if ((len= my_read(file, (uchar *)parser->buff,
- stat_info.st_size, MYF(MY_WME))) ==
+ (size_t) stat_info.st_size, MYF(MY_WME))) ==
MY_FILE_ERROR)
{
my_close(file, MYF(MY_WME));
@@ -766,6 +806,7 @@ File_parser::parse(uchar* base, MEM_ROOT *mem_root,
break;
}
case FILE_OPTIONS_ULONGLONG:
+ case FILE_OPTIONS_VIEW_ALGO:
if (!(eol= strchr(ptr, '\n')))
{
my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0),
@@ -774,8 +815,12 @@ File_parser::parse(uchar* base, MEM_ROOT *mem_root,
}
{
int not_used;
- *((ulonglong*)(base + parameter->offset))=
- my_strtoll10(ptr, 0, &not_used);
+ ulonglong val= (ulonglong)my_strtoll10(ptr, 0, &not_used);
+
+ if (parameter->type == FILE_OPTIONS_VIEW_ALGO)
+ val= view_algo_from_frm(val);
+
+ *((ulonglong*)(base + parameter->offset))= val;
}
ptr= eol+1;
break;
diff --git a/sql/parse_file.h b/sql/parse_file.h
index 2ebcd2ec987..a435a4e66fd 100644
--- a/sql/parse_file.h
+++ b/sql/parse_file.h
@@ -26,6 +26,7 @@ enum file_opt_type {
FILE_OPTIONS_STRING, /**< String (LEX_STRING) */
FILE_OPTIONS_ESTRING, /**< Escaped string (LEX_STRING) */
FILE_OPTIONS_ULONGLONG, /**< ulonglong parameter (ulonglong) */
+ FILE_OPTIONS_VIEW_ALGO, /**< Similar to longlong, but needs conversion */
FILE_OPTIONS_TIMESTAMP, /**< timestamp (LEX_STRING have to be
allocated with length 20 (19+1) */
FILE_OPTIONS_STRLIST, /**< list of escaped strings
diff --git a/sql/plistsort.c b/sql/plistsort.c
new file mode 100644
index 00000000000..71d287e7b45
--- /dev/null
+++ b/sql/plistsort.c
@@ -0,0 +1,166 @@
+/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software 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 */
+
+
+/*
+things to define before including the file:
+
+#define LS_LIST_ITEM ListItem
+#define LS_COMPARE_FUNC_DECL compare_func var_name,
+#define LS_COMPARE_FUNC_CALL(list_el1, list_el2) (*var_name)(list_el1, list_el2)
+#define LS_NEXT(A) (A)->next
+#define LS_SET_NEXT(A,val) (A)->next= val
+#define LS_P_NEXT(A) &(A)->next
+#define LS_NAME plistsort
+#define LS_SCOPE static
+#define LS_STRUCT_NAME ls_struct_name
+*/
+
+typedef struct LS_STRUCT_NAME
+{
+ LS_LIST_ITEM *list1;
+ int list_len;
+ int return_point;
+} LS_STRUCT_NAME;
+
+LS_SCOPE LS_LIST_ITEM* LS_NAME(LS_COMPARE_FUNC_DECL LS_LIST_ITEM *list, int list_len)
+{
+ LS_LIST_ITEM *list_end;
+ LS_LIST_ITEM *sorted_list;
+
+ struct LS_STRUCT_NAME stack[63], *sp= stack;
+
+ if (list_len < 2)
+ return list;
+
+ sp->list_len= list_len;
+ sp->return_point= 2;
+
+recursion_point:
+
+ if (sp->list_len < 4)
+ {
+ LS_LIST_ITEM *e1, *e2;
+ sorted_list= list;
+ e1= LS_NEXT(sorted_list);
+ list_end= LS_NEXT(e1);
+ if (LS_COMPARE_FUNC_CALL(sorted_list, e1))
+ {
+ sorted_list= e1;
+ e1= list;
+ }
+ if (sp->list_len == 2)
+ {
+ LS_SET_NEXT(sorted_list, e1);
+ LS_SET_NEXT(e1, NULL);
+ goto exit_point;
+ }
+ e2= list_end;
+ list_end= LS_NEXT(e2);
+ if (LS_COMPARE_FUNC_CALL(e1, e2))
+ {
+ {
+ LS_LIST_ITEM *tmp_e= e1;
+ e1= e2;
+ e2= tmp_e;
+ }
+ if (LS_COMPARE_FUNC_CALL(sorted_list, e1))
+ {
+ LS_LIST_ITEM *tmp_e= sorted_list;
+ sorted_list= e1;
+ e1= tmp_e;
+ }
+ }
+
+ LS_SET_NEXT(sorted_list, e1);
+ LS_SET_NEXT(e1, e2);
+ LS_SET_NEXT(e2, NULL);
+ goto exit_point;
+ }
+
+ {
+ register struct LS_STRUCT_NAME *sp0= sp++;
+ sp->list_len= sp0->list_len >> 1;
+ sp0->list_len-= sp->list_len;
+ sp->return_point= 0;
+ }
+ goto recursion_point;
+return_point0:
+ sp->list1= sorted_list;
+ {
+ register struct LS_STRUCT_NAME *sp0= sp++;
+ list= list_end;
+ sp->list_len= sp0->list_len;
+ sp->return_point= 1;
+ }
+ goto recursion_point;
+return_point1:
+ {
+ register LS_LIST_ITEM **hook= &sorted_list;
+ register LS_LIST_ITEM *list1= sp->list1;
+ register LS_LIST_ITEM *list2= sorted_list;
+
+ if (LS_COMPARE_FUNC_CALL(list1, list2))
+ {
+ LS_LIST_ITEM *tmp_e= list2;
+ list2= list1;
+ list1= tmp_e;
+ }
+ for (;;)
+ {
+ *hook= list1;
+ do
+ {
+ if (!(list1= *(hook= LS_P_NEXT(list1))))
+ {
+ *hook= list2;
+ goto exit_point;
+ }
+ } while (LS_COMPARE_FUNC_CALL(list2, list1));
+
+ *hook= list2;
+ do
+ {
+ if (!(list2= *(hook= LS_P_NEXT(list2))))
+ {
+ *hook= list1;
+ goto exit_point;
+ }
+ } while (LS_COMPARE_FUNC_CALL(list1, list2));
+ }
+ }
+
+exit_point:
+ switch ((sp--)->return_point)
+ {
+ case 0: goto return_point0;
+ case 1: goto return_point1;
+ default:;
+ }
+
+ return sorted_list;
+}
+
+
+#undef LS_LIST_ITEM
+#undef LS_NEXT
+#undef LS_SET_NEXT
+#undef LS_P_NEXT
+#undef LS_NAME
+#undef LS_STRUCT_NAME
+#undef LS_SCOPE
+#undef LS_COMPARE_FUNC_DECL
+#undef LS_COMPARE_FUNC_CALL
+
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 1c91cdf0369..f7420c64a7c 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -517,6 +517,56 @@ void net_end_statement(THD *thd)
}
+/**
+ Send a progress report to the client
+
+ What we send is:
+ header (255,255,255,1)
+ stage, max_stage as on byte integers
+ percentage withing the stage as percentage*1000
+ (that is, ratio*100000) as a 3 byte integer
+ proc_info as a string
+*/
+
+const uchar progress_header[2]= {(uchar) 255, (uchar) 255 };
+
+void net_send_progress_packet(THD *thd)
+{
+ uchar buff[200], *pos;
+ const char *proc_info= thd->proc_info ? thd->proc_info : "";
+ uint length= strlen(proc_info);
+ ulonglong progress;
+ DBUG_ENTER("net_send_progress_packet");
+
+ if (unlikely(!thd->net.vio))
+ DBUG_VOID_RETURN; // Socket is closed
+
+ pos= buff;
+ /*
+ Store number of strings first. This allows us to later expand the
+ progress indicator if needed.
+ */
+ *pos++= (uchar) 1; // Number of strings
+ *pos++= (uchar) thd->progress.stage + 1;
+ /*
+ We have the max() here to avoid problems if max_stage is not set,
+ which may happen during automatic repair of table
+ */
+ *pos++= (uchar) max(thd->progress.max_stage, thd->progress.stage + 1);
+ progress= 0;
+ if (thd->progress.max_counter)
+ progress= 100000ULL * thd->progress.counter / thd->progress.max_counter;
+ int3store(pos, progress); // Between 0 & 100000
+ pos+= 3;
+ pos= net_store_data(pos, (const uchar*) proc_info,
+ min(length, sizeof(buff)-7));
+ net_write_command(&thd->net, (uchar) 255, progress_header,
+ sizeof(progress_header), (uchar*) buff,
+ (uint) (pos - buff));
+ DBUG_VOID_RETURN;
+}
+
+
/****************************************************************************
Functions used by the protocol functions (like net_send_ok) to store
strings and numbers in the header result packet.
@@ -619,7 +669,7 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
Protocol_text prot(thd);
String *local_packet= prot.storage_packet();
CHARSET_INFO *thd_charset= thd->variables.character_set_results;
- DBUG_ENTER("send_fields");
+ DBUG_ENTER("Protocol::send_fields");
if (flags & SEND_NUM_ROWS)
{ // Packet with number of elements
@@ -1045,13 +1095,7 @@ bool Protocol_text::store(Field *field)
}
-/**
- @todo
- Second_part format ("%06") needs to change when
- we support 0-6 decimals for time.
-*/
-
-bool Protocol_text::store(MYSQL_TIME *tm)
+bool Protocol_text::store(MYSQL_TIME *tm, int decimals)
{
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
@@ -1059,18 +1103,8 @@ bool Protocol_text::store(MYSQL_TIME *tm)
field_types[field_pos] == MYSQL_TYPE_TIMESTAMP);
field_pos++;
#endif
- char buff[40];
- uint length;
- length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d",
- (int) tm->year,
- (int) tm->month,
- (int) tm->day,
- (int) tm->hour,
- (int) tm->minute,
- (int) tm->second));
- if (tm->second_part)
- length+= my_sprintf(buff+length,(buff+length, ".%06d",
- (int)tm->second_part));
+ char buff[MAX_DATE_STRING_REP_LENGTH];
+ uint length= my_datetime_to_str(tm, buff, decimals);
return net_store_data((uchar*) buff, length);
}
@@ -1088,29 +1122,15 @@ bool Protocol_text::store_date(MYSQL_TIME *tm)
}
-/**
- @todo
- Second_part format ("%06") needs to change when
- we support 0-6 decimals for time.
-*/
-
-bool Protocol_text::store_time(MYSQL_TIME *tm)
+bool Protocol_text::store_time(MYSQL_TIME *tm, int decimals)
{
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_TIME);
field_pos++;
#endif
- char buff[40];
- uint length;
- uint day= (tm->year || tm->month) ? 0 : tm->day;
- length= my_sprintf(buff,(buff, "%s%02ld:%02d:%02d",
- tm->neg ? "-" : "",
- (long) day*24L+(long) tm->hour,
- (int) tm->minute,
- (int) tm->second));
- if (tm->second_part)
- length+= my_sprintf(buff+length,(buff+length, ".%06d", (int)tm->second_part));
+ char buff[MAX_DATE_STRING_REP_LENGTH];
+ uint length= my_time_to_str(tm, buff, decimals);
return net_store_data((uchar*) buff, length);
}
@@ -1267,7 +1287,7 @@ bool Protocol_binary::store(Field *field)
}
-bool Protocol_binary::store(MYSQL_TIME *tm)
+bool Protocol_binary::store(MYSQL_TIME *tm, int decimals)
{
char buff[12],*pos;
uint length;
@@ -1280,6 +1300,10 @@ bool Protocol_binary::store(MYSQL_TIME *tm)
pos[4]= (uchar) tm->hour;
pos[5]= (uchar) tm->minute;
pos[6]= (uchar) tm->second;
+ DBUG_ASSERT(decimals == AUTO_SEC_PART_DIGITS ||
+ (decimals >= 0 && decimals <= TIME_SECOND_PART_DIGITS));
+ if (decimals != AUTO_SEC_PART_DIGITS)
+ tm->second_part= sec_part_truncate(tm->second_part, decimals);
int4store(pos+7, tm->second_part);
if (tm->second_part)
length=11;
@@ -1297,11 +1321,11 @@ bool Protocol_binary::store_date(MYSQL_TIME *tm)
{
tm->hour= tm->minute= tm->second=0;
tm->second_part= 0;
- return Protocol_binary::store(tm);
+ return Protocol_binary::store(tm, 0);
}
-bool Protocol_binary::store_time(MYSQL_TIME *tm)
+bool Protocol_binary::store_time(MYSQL_TIME *tm, int decimals)
{
char buff[13], *pos;
uint length;
@@ -1310,7 +1334,6 @@ bool Protocol_binary::store_time(MYSQL_TIME *tm)
pos[0]= tm->neg ? 1 : 0;
if (tm->hour >= 24)
{
- /* Fix if we come from Item::send */
uint days= tm->hour/24;
tm->hour-= days*24;
tm->day+= days;
@@ -1319,6 +1342,10 @@ bool Protocol_binary::store_time(MYSQL_TIME *tm)
pos[5]= (uchar) tm->hour;
pos[6]= (uchar) tm->minute;
pos[7]= (uchar) tm->second;
+ DBUG_ASSERT(decimals == AUTO_SEC_PART_DIGITS ||
+ (decimals >= 0 && decimals <= TIME_SECOND_PART_DIGITS));
+ if (decimals != AUTO_SEC_PART_DIGITS)
+ tm->second_part= sec_part_truncate(tm->second_part, decimals);
int4store(pos+8, tm->second_part);
if (tm->second_part)
length=12;
diff --git a/sql/protocol.h b/sql/protocol.h
index 1560f7272b5..bd7462a1280 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -94,9 +94,9 @@ public:
CHARSET_INFO *fromcs, CHARSET_INFO *tocs)=0;
virtual bool store(float from, uint32 decimals, String *buffer)=0;
virtual bool store(double from, uint32 decimals, String *buffer)=0;
- virtual bool store(MYSQL_TIME *time)=0;
+ virtual bool store(MYSQL_TIME *time, int decimals)=0;
virtual bool store_date(MYSQL_TIME *time)=0;
- virtual bool store_time(MYSQL_TIME *time)=0;
+ virtual bool store_time(MYSQL_TIME *time, int decimals)=0;
virtual bool store(Field *field)=0;
#ifdef EMBEDDED_LIBRARY
int begin_dataset();
@@ -133,9 +133,9 @@ public:
virtual bool store(const char *from, size_t length, CHARSET_INFO *cs);
virtual bool store(const char *from, size_t length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
- virtual bool store(MYSQL_TIME *time);
+ virtual bool store(MYSQL_TIME *time, int decimals);
virtual bool store_date(MYSQL_TIME *time);
- virtual bool store_time(MYSQL_TIME *time);
+ virtual bool store_time(MYSQL_TIME *time, int decimals);
virtual bool store(float nr, uint32 decimals, String *buffer);
virtual bool store(double from, uint32 decimals, String *buffer);
virtual bool store(Field *field);
@@ -168,9 +168,9 @@ public:
virtual bool store(const char *from, size_t length, CHARSET_INFO *cs);
virtual bool store(const char *from, size_t length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
- virtual bool store(MYSQL_TIME *time);
+ virtual bool store(MYSQL_TIME *time, int decimals);
virtual bool store_date(MYSQL_TIME *time);
- virtual bool store_time(MYSQL_TIME *time);
+ virtual bool store_time(MYSQL_TIME *time, int decimals);
virtual bool store(float nr, uint32 decimals, String *buffer);
virtual bool store(double from, uint32 decimals, String *buffer);
virtual bool store(Field *field);
@@ -180,6 +180,7 @@ public:
void send_warning(THD *thd, uint sql_errno, const char *err=0);
bool net_send_error(THD *thd, uint sql_errno=0, const char *err=0);
void net_end_statement(THD *thd);
+void net_send_progress_packet(THD *thd);
uchar *net_store_data(uchar *to,const uchar *from, size_t length);
uchar *net_store_data(uchar *to,int32 from);
uchar *net_store_data(uchar *to,longlong from);
diff --git a/sql/records.cc b/sql/records.cc
index 208405b0657..5c495a16562 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -61,7 +61,6 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
bzero((char*) info,sizeof(*info));
info->thd= thd;
info->table= table;
- info->file= table->file;
info->record= table->record[0];
info->print_error= print_error;
info->unlock_row= rr_unlock_row;
@@ -171,7 +170,6 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
bzero((char*) info,sizeof(*info));
info->thd=thd;
info->table=table;
- info->file= table->file;
info->forms= &info->table; /* Only one table */
if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE &&
@@ -292,9 +290,10 @@ void end_read_record(READ_RECORD *info)
if (info->table)
{
filesort_free_buffers(info->table,0);
- (void) info->file->extra(HA_EXTRA_NO_CACHE);
+ if (info->table->created)
+ (void) info->table->file->extra(HA_EXTRA_NO_CACHE);
if (info->read_record != rr_quick) // otherwise quick_range does it
- (void) info->file->ha_index_or_rnd_end();
+ (void) info->table->file->ha_index_or_rnd_end();
info->table=0;
}
}
@@ -333,7 +332,8 @@ static int rr_quick(READ_RECORD *info)
break;
}
}
- update_virtual_fields(info->thd, info->table);
+ if (info->table->vfield)
+ update_virtual_fields(info->thd, info->table);
return tmp;
}
@@ -353,7 +353,7 @@ static int rr_quick(READ_RECORD *info)
static int rr_index_first(READ_RECORD *info)
{
- int tmp= info->file->ha_index_first(info->record);
+ int tmp= info->table->file->ha_index_first(info->record);
info->read_record= rr_index;
if (tmp)
tmp= rr_handle_error(info, tmp);
@@ -379,7 +379,7 @@ static int rr_index_first(READ_RECORD *info)
static int rr_index(READ_RECORD *info)
{
- int tmp= info->file->ha_index_next(info->record);
+ int tmp= info->table->file->ha_index_next(info->record);
if (tmp)
tmp= rr_handle_error(info, tmp);
return tmp;
@@ -389,7 +389,7 @@ static int rr_index(READ_RECORD *info)
int rr_sequential(READ_RECORD *info)
{
int tmp;
- while ((tmp= info->file->ha_rnd_next(info->record)))
+ while ((tmp= info->table->file->ha_rnd_next(info->record)))
{
/*
rnd_next can return RECORD_DELETED for MyISAM when one thread is
@@ -401,7 +401,7 @@ int rr_sequential(READ_RECORD *info)
break;
}
}
- if (!tmp)
+ if (!tmp && info->table->vfield)
update_virtual_fields(info->thd, info->table);
return tmp;
}
@@ -414,7 +414,7 @@ static int rr_from_tempfile(READ_RECORD *info)
{
if (my_b_read(info->io_cache,info->ref_pos,info->ref_length))
return -1; /* End of file */
- if (!(tmp= info->file->ha_rnd_pos(info->record,info->ref_pos)))
+ if (!(tmp= info->table->file->ha_rnd_pos(info->record,info->ref_pos)))
break;
/* The following is extremely unlikely to happen */
if (tmp == HA_ERR_RECORD_DELETED ||
@@ -448,7 +448,8 @@ static int rr_unpack_from_tempfile(READ_RECORD *info)
if (my_b_read(info->io_cache, info->rec_buf, info->ref_length))
return -1;
TABLE *table= info->table;
- (*table->sort.unpack)(table->sort.addon_field, info->rec_buf);
+ (*table->sort.unpack)(table->sort.addon_field, info->rec_buf,
+ info->rec_buf + info->ref_length);
return 0;
}
@@ -465,7 +466,7 @@ static int rr_from_pointers(READ_RECORD *info)
cache_pos= info->cache_pos;
info->cache_pos+= info->ref_length;
- if (!(tmp= info->file->ha_rnd_pos(info->record,cache_pos)))
+ if (!(tmp= info->table->file->ha_rnd_pos(info->record,cache_pos)))
break;
/* The following is extremely unlikely to happen */
@@ -499,7 +500,8 @@ static int rr_unpack_from_buffer(READ_RECORD *info)
if (info->cache_pos == info->cache_end)
return -1; /* End of buffer */
TABLE *table= info->table;
- (*table->sort.unpack)(table->sort.addon_field, info->cache_pos);
+ (*table->sort.unpack)(table->sort.addon_field, info->cache_pos,
+ info->cache_end);
info->cache_pos+= info->ref_length;
return 0;
@@ -598,7 +600,7 @@ static int rr_from_cache(READ_RECORD *info)
record=uint3korr(position);
position+=3;
record_pos=info->cache+record*info->reclength;
- if ((error=(int16) info->file->ha_rnd_pos(record_pos,info->ref_pos)))
+ if ((error=(int16) info->table->file->ha_rnd_pos(record_pos,info->ref_pos)))
{
record_pos[info->error_offset]=1;
shortstore(record_pos,error);
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 374ef77c297..fee8a538fa9 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -246,7 +246,8 @@ static int find_target_pos(LEX_MASTER_INFO *mi, IO_CACHE *log, char *errmsg)
for (;;)
{
Log_event* ev;
- if (!(ev = Log_event::read_log_event(log, (pthread_mutex_t*) 0, 0)))
+ if (!(ev = Log_event::read_log_event(log, (pthread_mutex_t*) 0, 0,
+ opt_slave_sql_verify_checksum)))
{
if (log->error > 0)
strmov(errmsg, "Binary log truncated in the middle of event");
@@ -420,7 +421,8 @@ static Slave_log_event* find_slave_event(IO_CACHE* log,
for (i = 0; i < 2; i++)
{
- if (!(ev = Log_event::read_log_event(log, (pthread_mutex_t*)0, 0)))
+ if (!(ev = Log_event::read_log_event(log, (pthread_mutex_t*)0, 0,
+ opt_slave_sql_verify_checksum)))
{
my_snprintf(errmsg, SLAVE_ERRMSG_SIZE,
"Error reading event in log '%s'",
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc
index 7011f59adf0..3239c64d6c8 100644
--- a/sql/rpl_mi.cc
+++ b/sql/rpl_mi.cc
@@ -26,7 +26,8 @@
Master_info::Master_info()
:Slave_reporting_capability("I/O"),
- ssl(0), ssl_verify_server_cert(0), fd(-1), io_thd(0), inited(0),
+ ssl(0), ssl_verify_server_cert(0), fd(-1), io_thd(0),
+ checksum_alg_before_fd(BINLOG_CHECKSUM_ALG_UNDEF), inited(0),
abort_slave(0),slave_running(0),
slave_run_id(0)
{
diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h
index 8bb1757d917..05d3fc412d9 100644
--- a/sql/rpl_mi.h
+++ b/sql/rpl_mi.h
@@ -85,6 +85,12 @@ class Master_info : public Slave_reporting_capability
Relay_log_info rli;
uint port;
uint connect_retry;
+ /*
+ to hold checksum alg in use until IO thread has received FD.
+ Initialized to novalue, then set to the queried from master
+ @@global.binlog_checksum and deactivated once FD has been received.
+ */
+ uint8 checksum_alg_before_fd;
#ifndef DBUG_OFF
int events_till_disconnect;
#endif
diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc
index 5a33b62538b..ea8324a1fc7 100644
--- a/sql/rpl_record.cc
+++ b/sql/rpl_record.cc
@@ -106,7 +106,7 @@ pack_row(TABLE *table, MY_BITMAP const* cols,
const uchar *old_pack_ptr= pack_ptr;
#endif
pack_ptr= field->pack(pack_ptr, field->ptr + offset,
- field->max_data_length(), TRUE);
+ field->max_data_length());
DBUG_PRINT("debug", ("field: %s; pack_ptr: 0x%lx;"
" pack_ptr':0x%lx; bytes: %d",
field->field_name, (ulong) old_pack_ptr,
@@ -176,13 +176,15 @@ pack_row(TABLE *table, MY_BITMAP const* cols,
@retval ER_NO_DEFAULT_FOR_FIELD
Returned if one of the fields existing on the slave but not on the
master does not have a default value (and isn't nullable)
-
+ @retval ER_SLAVE_CORRUPT_EVENT
+ Found error when trying to unpack fields.
*/
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
int
unpack_row(Relay_log_info const *rli,
TABLE *table, uint const colcnt,
- uchar const *const row_data, MY_BITMAP const *cols,
+ uchar const *const row_data, uchar const *const row_buffer_end,
+ MY_BITMAP const *cols,
uchar const **const row_end, ulong *const master_reclength)
{
DBUG_ENTER("unpack_row");
@@ -224,9 +226,6 @@ unpack_row(Relay_log_info const *rli,
DBUG_ASSERT(null_mask & 0xFF); // One of the 8 LSB should be set
- /* Field...::unpack() cannot return 0 */
- DBUG_ASSERT(pack_ptr != NULL);
-
if (null_bits & null_mask)
{
if (f->maybe_null())
@@ -272,14 +271,21 @@ unpack_row(Relay_log_info const *rli,
#ifndef DBUG_OFF
uchar const *const old_pack_ptr= pack_ptr;
#endif
- pack_ptr= f->unpack(f->ptr, pack_ptr, metadata, TRUE);
+ pack_ptr= f->unpack(f->ptr, pack_ptr, row_buffer_end, metadata);
DBUG_PRINT("debug", ("field: %s; metadata: 0x%x;"
" pack_ptr: 0x%lx; pack_ptr': 0x%lx; bytes: %d",
f->field_name, metadata,
(ulong) old_pack_ptr, (ulong) pack_ptr,
(int) (pack_ptr - old_pack_ptr)));
+ if (!pack_ptr)
+ {
+ rli->report(ERROR_LEVEL, ER_SLAVE_CORRUPT_EVENT,
+ "Could not read field `%s` of table `%s`.`%s`",
+ f->field_name, table->s->db.str,
+ table->s->table_name.str);
+ DBUG_RETURN(ER_SLAVE_CORRUPT_EVENT);
+ }
}
-
null_mask <<= 1;
}
i++;
diff --git a/sql/rpl_record.h b/sql/rpl_record.h
index 6005d57daf3..eefcdebc114 100644
--- a/sql/rpl_record.h
+++ b/sql/rpl_record.h
@@ -29,7 +29,8 @@ size_t pack_row(TABLE* table, MY_BITMAP const* cols,
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
int unpack_row(Relay_log_info const *rli,
TABLE *table, uint const colcnt,
- uchar const *const row_data, MY_BITMAP const *cols,
+ uchar const *const row_data, uchar const *row_buffer_end,
+ MY_BITMAP const *cols,
uchar const **const row_end, ulong *const master_reclength);
// Fill table's record[0] with default values.
diff --git a/sql/rpl_record_old.cc b/sql/rpl_record_old.cc
index f861ffb10f7..6709c4f6e1a 100644
--- a/sql/rpl_record_old.cc
+++ b/sql/rpl_record_old.cc
@@ -82,12 +82,15 @@ pack_row_old(TABLE *table, MY_BITMAP const* cols,
ER_NO_DEFAULT_FOR_FIELD
Returned if one of the fields existing on the slave but not on
the master does not have a default value (and isn't nullable)
+ ER_SLAVE_CORRUPT_EVENT
+ Wrong data for field found.
*/
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
int
unpack_row_old(Relay_log_info *rli,
TABLE *table, uint const colcnt, uchar *record,
- uchar const *row, MY_BITMAP const *cols,
+ uchar const *row, const uchar *row_buffer_end,
+ MY_BITMAP const *cols,
uchar const **row_end, ulong *master_reclength,
MY_BITMAP* const rw_set, Log_event_type const event_type)
{
@@ -133,10 +136,16 @@ unpack_row_old(Relay_log_info *rli,
if (bitmap_is_set(cols, field_ptr - begin_ptr))
{
f->move_field_offset(offset);
- ptr= f->unpack(f->ptr, ptr);
+ ptr= f->unpack(f->ptr, ptr, row_buffer_end, 0);
f->move_field_offset(-offset);
- /* Field...::unpack() cannot return 0 */
- DBUG_ASSERT(ptr != NULL);
+ if (!ptr)
+ {
+ rli->report(ERROR_LEVEL, ER_SLAVE_CORRUPT_EVENT,
+ "Could not read field `%s` of table `%s`.`%s`",
+ f->field_name, table->s->db.str,
+ table->s->table_name.str);
+ return(ER_SLAVE_CORRUPT_EVENT);
+ }
}
else
bitmap_clear_bit(rw_set, field_ptr - begin_ptr);
diff --git a/sql/rpl_record_old.h b/sql/rpl_record_old.h
index 300c9d9a1a6..c9c2f5739cb 100644
--- a/sql/rpl_record_old.h
+++ b/sql/rpl_record_old.h
@@ -23,7 +23,8 @@ size_t pack_row_old(TABLE *table, MY_BITMAP const* cols,
#ifdef HAVE_REPLICATION
int unpack_row_old(Relay_log_info *rli,
TABLE *table, uint const colcnt, uchar *record,
- uchar const *row, MY_BITMAP const *cols,
+ uchar const *row, uchar const *row_buffer_end,
+ MY_BITMAP const *cols,
uchar const **row_end, ulong *master_reclength,
MY_BITMAP* const rw_set,
Log_event_type const event_type);
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index eb05aca7e97..17071ef1627 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -42,7 +42,8 @@ Relay_log_info::Relay_log_info()
tables_to_lock(0), tables_to_lock_count(0),
last_event_start_time(0),
deferred_events(NULL),
- m_flags(0)
+ m_flags(0),
+ m_annotate_event(0)
{
DBUG_ENTER("Relay_log_info::Relay_log_info");
@@ -76,6 +77,7 @@ Relay_log_info::~Relay_log_info()
pthread_cond_destroy(&stop_cond);
pthread_cond_destroy(&log_space_cond);
relay_log.cleanup();
+ free_annotate_event();
DBUG_VOID_RETURN;
}
@@ -178,6 +180,9 @@ a file name for --relay-log-index option", opt_relaylog_index_name);
"this problem.", ln);
name_warning_sent= 1;
}
+
+ rli->relay_log.is_relay_log= TRUE;
+
/*
note, that if open() fails, we'll still have index file open
but a destructor will take care of that
@@ -191,7 +196,6 @@ a file name for --relay-log-index option", opt_relaylog_index_name);
sql_print_error("Failed in open_log() called from init_relay_log_info()");
DBUG_RETURN(1);
}
- rli->relay_log.is_relay_log= TRUE;
}
/* if file does not exist */
@@ -537,8 +541,9 @@ int init_relay_log_pos(Relay_log_info* rli,const char* log,
Because of we have rli->data_lock and log_lock, we can safely read an
event
*/
- if (!(ev=Log_event::read_log_event(rli->cur_log,0,
- rli->relay_log.description_event_for_exec)))
+ if (!(ev= Log_event::read_log_event(rli->cur_log, 0,
+ rli->relay_log.description_event_for_exec,
+ opt_slave_sql_verify_checksum)))
{
DBUG_PRINT("info",("could not read event, rli->cur_log->error=%d",
rli->cur_log->error));
@@ -1174,11 +1179,7 @@ void Relay_log_info::stmt_done(my_off_t event_master_log_pos,
is that value may take some time to display in
Seconds_Behind_Master - not critical).
*/
-#ifndef DBUG_OFF
- if (!(event_creation_time == 0 && debug_not_change_ts_if_art_event > 0))
-#else
- if (event_creation_time != 0)
-#endif
+ if (!(event_creation_time == 0 IF_DBUG(&& debug_not_change_ts_if_art_event > 0)))
last_master_timestamp= event_creation_time;
}
}
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
index 4d0b6c39d19..e92cb3e87d9 100644
--- a/sql/rpl_rli.h
+++ b/sql/rpl_rli.h
@@ -473,8 +473,46 @@ public:
(m_flags & (1UL << IN_STMT));
}
+ /**
+ Save pointer to Annotate_rows event and switch on the
+ binlog_annotate_row_events for this sql thread.
+ To be called when sql thread recieves an Annotate_rows event.
+ */
+ inline void set_annotate_event(Annotate_rows_log_event *event)
+ {
+ free_annotate_event();
+ m_annotate_event= event;
+ sql_thd->variables.binlog_annotate_row_events= 1;
+ }
+
+ /**
+ Returns pointer to the saved Annotate_rows event or NULL if there is
+ no saved event.
+ */
+ inline Annotate_rows_log_event* get_annotate_event()
+ {
+ return m_annotate_event;
+ }
+
+ /**
+ Delete saved Annotate_rows event (if any) and switch off the
+ binlog_annotate_row_events for this sql thread.
+ To be called when sql thread has applied the last (i.e. with
+ STMT_END_F flag) rbr event.
+ */
+ inline void free_annotate_event()
+ {
+ if (m_annotate_event)
+ {
+ sql_thd->variables.binlog_annotate_row_events= 0;
+ delete m_annotate_event;
+ m_annotate_event= 0;
+ }
+ }
+
private:
uint32 m_flags;
+ Annotate_rows_log_event *m_annotate_event;
};
diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc
index dad2309981f..3571a03fe50 100644
--- a/sql/rpl_utility.cc
+++ b/sql/rpl_utility.cc
@@ -16,6 +16,8 @@
*/
#include "rpl_utility.h"
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
#include "rpl_rli.h"
/*********************************************************************
@@ -135,7 +137,7 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const
always read the length in little-endian order.
*/
Field_blob fb(m_field_metadata[col]);
- length= fb.get_packed_size(master_data, TRUE);
+ length= fb.get_packed_size(master_data);
#else
/*
Compute the length of the data. We cannot use get_length() here
@@ -227,7 +229,6 @@ table_def::compatible_with(Relay_log_info const *rli_arg, TABLE *table)
return error;
}
-#ifndef MYSQL_CLIENT
Deferred_log_events::Deferred_log_events(Relay_log_info *rli) : last_added(NULL)
{
my_init_dynamic_array(&array, sizeof(Log_event *), 32, 16);
@@ -286,4 +287,62 @@ void Deferred_log_events::rewind()
}
}
+#endif /* MYSQL_CLIENT */
+
+
+/**
+ @param even_buf point to the buffer containing serialized event
+ @param event_len length of the event accounting possible checksum alg
+
+ @return TRUE if test fails
+ FALSE as success
+*/
+bool event_checksum_test(uchar *event_buf, ulong event_len, uint8 alg)
+{
+ bool res= FALSE;
+ uint16 flags= 0; // to store in FD's buffer flags orig value
+
+ if (alg != BINLOG_CHECKSUM_ALG_OFF && alg != BINLOG_CHECKSUM_ALG_UNDEF)
+ {
+ ha_checksum incoming;
+ ha_checksum computed;
+
+ if (event_buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT)
+ {
+#ifndef DBUG_OFF
+ int8 fd_alg= event_buf[event_len - BINLOG_CHECKSUM_LEN -
+ BINLOG_CHECKSUM_ALG_DESC_LEN];
#endif
+ /*
+ FD event is checksummed and therefore verified w/o the binlog-in-use flag
+ */
+ flags= uint2korr(event_buf + FLAGS_OFFSET);
+ if (flags & LOG_EVENT_BINLOG_IN_USE_F)
+ event_buf[FLAGS_OFFSET] &= ~LOG_EVENT_BINLOG_IN_USE_F;
+ /*
+ The only algorithm currently is CRC32. Zero indicates
+ the binlog file is checksum-free *except* the FD-event.
+ */
+ DBUG_ASSERT(fd_alg == BINLOG_CHECKSUM_ALG_CRC32 || fd_alg == 0);
+ DBUG_ASSERT(alg == BINLOG_CHECKSUM_ALG_CRC32);
+ /*
+ Complile time guard to watch over the max number of alg
+ */
+ compile_time_assert(BINLOG_CHECKSUM_ALG_ENUM_END <= 0x80);
+ }
+ incoming= uint4korr(event_buf + event_len - BINLOG_CHECKSUM_LEN);
+ computed= my_checksum(0L, NULL, 0);
+ /* checksum the event content but the checksum part itself */
+ computed= my_checksum(computed, (const uchar*) event_buf,
+ event_len - BINLOG_CHECKSUM_LEN);
+ if (flags != 0)
+ {
+ /* restoring the orig value of flags of FD */
+ DBUG_ASSERT(event_buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT);
+ event_buf[FLAGS_OFFSET]= (uchar) flags;
+ }
+ res= !(computed == incoming);
+ }
+ return DBUG_EVALUATE_IF("simulate_checksum_test_failure", TRUE, res);
+}
+
diff --git a/sql/scheduler.cc b/sql/scheduler.cc
index d301b205b58..2f8aa2bef11 100644
--- a/sql/scheduler.cc
+++ b/sql/scheduler.cc
@@ -376,9 +376,7 @@ void libevent_kill_thd_callback(int Fd, short, void*)
{
THD *thd= (THD*)list->data;
list= list_rest(list);
- if (thd->killed == THD::KILL_CONNECTION ||
- thd->killed == THD::KILL_SYSTEM_THREAD ||
- thd->killed == THD::KILL_SERVER)
+ if ((int) thd->killed >= (int) KILL_CONNECTION)
{
/*
Delete from libevent and add to the processing queue.
@@ -512,7 +510,7 @@ static void libevent_connection_close(THD *thd)
DBUG_ENTER("libevent_connection_close");
DBUG_PRINT("enter", ("thd: %p", thd));
- thd->killed= THD::KILL_CONNECTION; // Avoid error messages
+ thd->killed= KILL_CONNECTION; // Avoid error messages
if (thd->net.vio->type != VIO_CLOSED) // not already closed
{
@@ -535,8 +533,7 @@ static bool libevent_should_close_connection(THD* thd)
{
return (thd->net.error ||
thd->net.vio == 0 ||
- thd->killed == THD::KILL_CONNECTION ||
- thd->killed == THD::KILL_SERVER);
+ (int) thd->killed >= (int) KILL_CONNECTION);
}
diff --git a/sql/set_var.cc b/sql/set_var.cc
index ab5412adec7..94a1b6a1cef 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -67,6 +67,7 @@
#include <my_dir.h>
#include <waiting_threads.h>
#include "events.h"
+#include "sql_show.h" // opt_ignore_db_dirs
/* WITH_NDBCLUSTER_STORAGE_ENGINE */
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
@@ -130,9 +131,11 @@ static void fix_net_read_timeout(THD *thd, enum_var_type type);
static void fix_net_write_timeout(THD *thd, enum_var_type type);
static void fix_net_retry_count(THD *thd, enum_var_type type);
static void fix_max_join_size(THD *thd, enum_var_type type);
-static void fix_query_cache_size(THD *thd, enum_var_type type);
#ifdef HAVE_QUERY_CACHE
+static void fix_query_cache_size(THD *thd, enum_var_type type);
static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type);
+static int check_query_cache_type(THD *thd, set_var *var);
+static void fix_query_cache_type(THD *thd, enum_var_type type);
#endif
static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type);
static void fix_max_binlog_size(THD *thd, enum_var_type type);
@@ -156,6 +159,7 @@ static bool sys_update_slow_log_path(THD *thd, set_var * var);
static void sys_default_slow_log_path(THD *thd, enum_var_type type);
static void fix_sys_log_slow_filter(THD *thd, enum_var_type);
static uchar *get_myisam_mmap_size(THD *thd);
+static uchar *in_transaction(THD *thd);
static int check_max_allowed_packet(THD *thd, set_var *var);
static int check_net_buffer_length(THD *thd, set_var *var);
@@ -187,6 +191,9 @@ static sys_var_const sys_back_log(&vars, "back_log",
OPT_GLOBAL, SHOW_LONG,
(uchar*) &back_log);
static sys_var_const_os_str sys_basedir(&vars, "basedir", mysql_home);
+static sys_var_thd_bool
+sys_binlog_annotate_row_events(&vars, "binlog_annotate_row_events",
+ &SV::binlog_annotate_row_events);
static sys_var_long_ptr sys_binlog_cache_size(&vars, "binlog_cache_size",
&binlog_cache_size);
static sys_var_thd_binlog_format sys_binlog_format(&vars, "binlog_format",
@@ -261,6 +268,9 @@ static sys_var_thd_ulong sys_deadlock_timeout_long(&vars,
&SV::wt_timeout_long);
#ifndef DBUG_OFF
static sys_var_thd_dbug sys_dbug(&vars, "debug");
+static sys_var_long_ptr sys_var_debug_binlog_fsync_sleep(&vars,
+ "debug_binlog_fsync_sleep",
+ &opt_binlog_dbug_fsync_sleep);
#endif
static sys_var_enum sys_delay_key_write(&vars, "delay_key_write",
&delay_key_write_options,
@@ -325,6 +335,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",
@@ -463,8 +478,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);
@@ -522,6 +535,11 @@ 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);
+
+static sys_var_thd_ulong sys_progress_report_time(&vars,
+ "progress_report_time",
+ &SV::progress_report_time);
+
static sys_var_const sys_pid_file(&vars, "pid_file",
OPT_GLOBAL, SHOW_CHAR,
(uchar*) pidfile_name);
@@ -545,16 +563,18 @@ 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",
&rpl_recovery_rank);
-static sys_var_long_ptr sys_query_cache_size(&vars, "query_cache_size",
- &query_cache_size,
- fix_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);
@@ -616,17 +636,25 @@ sys_var_enum_const sys_thread_handling(&vars, "thread_handling",
&thread_handling_typelib);
#ifdef HAVE_QUERY_CACHE
+static sys_var_long_ptr sys_query_cache_size(&vars, "query_cache_size",
+ &query_cache_size,
+ fix_query_cache_size);
static sys_var_long_ptr sys_query_cache_limit(&vars, "query_cache_limit",
- &query_cache.query_cache_limit);
-static sys_var_long_ptr sys_query_cache_min_res_unit(&vars, "query_cache_min_res_unit",
- &query_cache_min_res_unit,
- fix_query_cache_min_res_unit);
+ &query_cache.query_cache_limit);
+static sys_var_long_ptr
+ sys_query_cache_min_res_unit(&vars, "query_cache_min_res_unit",
+ &query_cache_min_res_unit,
+ fix_query_cache_min_res_unit);
static sys_var_thd_enum sys_query_cache_type(&vars, "query_cache_type",
&SV::query_cache_type,
- &query_cache_type_typelib);
+ &query_cache_type_typelib,
+ fix_query_cache_type,
+ check_query_cache_type);
static sys_var_thd_bool
sys_query_cache_wlock_invalidate(&vars, "query_cache_wlock_invalidate",
&SV::query_cache_wlock_invalidate);
+static sys_var_bool_ptr sys_query_cache_strip_comments(&vars, "query_cache_strip_comments",
+ &opt_query_cache_strip_comments);
#endif /* HAVE_QUERY_CACHE */
static sys_var_bool_ptr sys_secure_auth(&vars, "secure_auth", &opt_secure_auth);
static sys_var_const_str_ptr sys_secure_file_priv(&vars, "secure_file_priv",
@@ -982,6 +1010,14 @@ static sys_var_enum_const sys_plugin_maturity(&vars, "plugin_maturity",
&plugin_maturity,
&plugin_maturity_values);
+static sys_var_readonly sys_in_transaction(&vars, "in_transaction",
+ OPT_SESSION, SHOW_BOOL,
+ in_transaction);
+
+static sys_var_const_str_ptr sys_ignore_db_dirs(&vars, "ignore_db_dirs",
+ &opt_ignore_db_dirs);
+
+
bool sys_var::check(THD *thd, set_var *var)
{
var->save_result.ulonglong_value= var->value->val_int();
@@ -1208,10 +1244,9 @@ static void fix_net_retry_count(THD *thd __attribute__((unused)),
{}
#endif /* HAVE_REPLICATION */
-
+#ifdef HAVE_QUERY_CACHE
static void fix_query_cache_size(THD *thd, enum_var_type type)
{
-#ifdef HAVE_QUERY_CACHE
ulong new_cache_size= query_cache.resize(query_cache_size);
/*
@@ -1225,11 +1260,60 @@ static void fix_query_cache_size(THD *thd, enum_var_type type)
query_cache_size, new_cache_size);
query_cache_size= new_cache_size;
-#endif
}
-#ifdef HAVE_QUERY_CACHE
+/**
+ Trigger before query_cache_type variable is updated.
+ @param thd Thread handler
+ @param var Pointer to the new variable status
+
+ @return Status code
+ @retval TRUE Failure
+ @retval FALSE Success
+*/
+
+static int check_query_cache_type(THD *thd, set_var *var)
+{
+ /*
+ Don't allow changes of the query_cache_type if the query cache
+ is disabled.
+ */
+ if (query_cache.is_disable_in_progress())
+ {
+ my_error(ER_QUERY_CACHE_IS_DISABLED, MYF(0));
+ return TRUE;
+ }
+ if (var->type != OPT_GLOBAL &&
+ global_system_variables.query_cache_type == 0 &&
+ var->value->val_int() != 0)
+ {
+ my_error(ER_QUERY_CACHE_IS_GLOBALY_DISABLED, MYF(0));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static void fix_query_cache_type(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ {
+ if (global_system_variables.query_cache_type != 0 &&
+ query_cache.is_disabled())
+ {
+ /* if disabling in progress variable will not be set */
+ DBUG_ASSERT(!query_cache.is_disable_in_progress());
+ /* Enable query cache because it was disabled */
+ fix_query_cache_size(thd, type);
+ }
+ else if (global_system_variables.query_cache_type == 0)
+ query_cache.disable_query_cache(thd);
+ }
+}
+
+
static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type)
{
query_cache_min_res_unit=
@@ -2837,38 +2921,43 @@ int set_var_collation_client::update(THD *thd)
bool sys_var_timestamp::check(THD *thd, set_var *var)
{
- longlong val;
- var->save_result.ulonglong_value= var->value->val_int();
- val= (longlong) var->save_result.ulonglong_value;
- if (val != 0 && // this is how you set the default value
- (val < TIMESTAMP_MIN_VALUE || val > TIMESTAMP_MAX_VALUE))
+ ulonglong sec;
+ ulong sec_part;
+ char buf[64], *errval= 0;
+ if (var->value->get_seconds(&sec, &sec_part))
+ errval= llstr(sec, buf);
+ else if (sec > TIMESTAMP_MAX_VALUE)
+ errval= ullstr(sec, buf);
+
+ if (errval)
{
- char buf[64];
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "timestamp", llstr(val, buf));
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "timestamp", errval);
return TRUE;
}
+ var->save_result.ulonglong_value= hrtime_from_time(sec)+sec_part;
return FALSE;
}
bool sys_var_timestamp::update(THD *thd, set_var *var)
{
- thd->set_time((time_t) var->save_result.ulonglong_value);
+ my_hrtime_t hrtime = { var->save_result.ulonglong_value };
+ thd->set_time(hrtime);
return FALSE;
}
void sys_var_timestamp::set_default(THD *thd, enum_var_type type)
{
- thd->user_time=0;
+ thd->user_time.val= 0;
}
uchar *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type,
LEX_STRING *base)
{
- thd->sys_var_tmp.long_value= (long) thd->start_time;
- return (uchar*) &thd->sys_var_tmp.long_value;
+ thd->sys_var_tmp.double_value= thd->start_time + thd->start_time_sec_part/1e6;
+ return (uchar*) &thd->sys_var_tmp.double_value;
}
@@ -3003,7 +3092,19 @@ void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type)
bool sys_var_max_user_conn::check(THD *thd, set_var *var)
{
if (var->type == OPT_GLOBAL)
+ {
+ if (! max_user_connections_checking)
+ {
+ /*
+ We can't change the value of max_user_connections from 0 as then
+ connect counting would be wrong.
+ */
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
+ "--max-user-connections=0");
+ return TRUE;
+ }
return sys_var_thd::check(thd, var);
+ }
else
{
/*
@@ -3019,7 +3120,7 @@ bool sys_var_max_user_conn::update(THD *thd, set_var *var)
{
DBUG_ASSERT(var->type == OPT_GLOBAL);
pthread_mutex_lock(&LOCK_global_system_variables);
- max_user_connections= (uint)var->save_result.ulonglong_value;
+ max_user_connections= (int) var->save_result.ulonglong_value;
pthread_mutex_unlock(&LOCK_global_system_variables);
return 0;
}
@@ -3121,7 +3222,7 @@ void sys_var_thd_lc_time_names::set_default(THD *thd, enum_var_type type)
}
/*
- Handling of microseoncds given as seconds.part_seconds
+ Handling of microseconds given as seconds.part_seconds
NOTES
The argument to long query time is in seconds in decimal
@@ -3167,10 +3268,10 @@ void sys_var_microseconds::set_default(THD *thd, enum_var_type type)
uchar *sys_var_microseconds::value_ptr(THD *thd, enum_var_type type,
LEX_STRING *base)
{
- thd->tmp_double_value= (double) ((type == OPT_GLOBAL) ?
+ thd->sys_var_tmp.double_value= (double) ((type == OPT_GLOBAL) ?
global_system_variables.*offset :
thd->variables.*offset) / 1000000.0;
- return (uchar*) &thd->tmp_double_value;
+ return (uchar*) &thd->sys_var_tmp.double_value;
}
@@ -3201,35 +3302,26 @@ static bool set_option_log_bin_bit(THD *thd, set_var *var)
static bool set_option_autocommit(THD *thd, set_var *var)
{
- /* The test is negative as the flag we use is NOT autocommit */
-
- ulonglong org_options= thd->options;
+ ulonglong new_options= thd->options;
- if (var->save_result.ulong_value != 0)
- thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag;
+ /* The test is negative as the flag we use is NOT autocommit */
+ if (var->save_result.ulong_value)
+ new_options&= ~OPTION_NOT_AUTOCOMMIT;
else
- thd->options|= ((sys_var_thd_bit*) var->var)->bit_flag;
+ new_options|= OPTION_NOT_AUTOCOMMIT;
- if ((org_options ^ thd->options) & OPTION_NOT_AUTOCOMMIT)
+ if ((new_options ^ thd->options) & OPTION_NOT_AUTOCOMMIT)
{
- if ((org_options & OPTION_NOT_AUTOCOMMIT))
+ if ((thd->options & OPTION_NOT_AUTOCOMMIT))
{
- /* We changed to auto_commit mode */
- if (thd->transaction.xid_state.xa_state != XA_NOTR)
- {
- thd->options= org_options;
- my_error(ER_XAER_RMFAIL, MYF(0),
- xa_state_names[thd->transaction.xid_state.xa_state]);
+ if (end_active_trans(thd))
return 1;
- }
- thd->options&= ~(ulonglong) (OPTION_BEGIN | OPTION_KEEP_LOG);
- thd->transaction.all.modified_non_trans_table= FALSE;
thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
- if (ha_commit(thd))
- return 1;
+ thd->options= new_options;
}
else
{
+ thd->options= new_options;
thd->transaction.all.modified_non_trans_table= FALSE;
thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
}
@@ -3331,6 +3423,12 @@ static uchar *get_myisam_mmap_size(THD *thd)
return (uchar *)&myisam_mmap_size;
}
+static uchar *in_transaction(THD *thd)
+{
+ thd->sys_var_tmp.my_bool_value=
+ test(thd->server_status & SERVER_STATUS_IN_TRANS);
+ return (uchar*) &thd->sys_var_tmp.my_bool_value;
+}
/****************************************************************************
Main handling of variables:
@@ -3653,6 +3751,16 @@ bool not_all_support_one_shot(List<set_var_base> *var_list)
Functions to handle SET mysql_internal_variable=const_expr
*****************************************************************************/
+/**
+ Verify that the supplied value is correct.
+
+ @param thd Thread handler
+
+ @return status code
+ @retval -1 Failure
+ @retval 0 Success
+*/
+
int set_var::check(THD *thd)
{
if (var->is_readonly())
@@ -4046,7 +4154,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;
@@ -4305,7 +4413,7 @@ bool sys_var_opt_readonly::update(THD *thd, set_var *var)
can cause to wait on a read lock, it's required for the client application
to unlock everything, and acceptable for the server to wait on all locks.
*/
- if ((result= close_cached_tables(thd, NULL, FALSE, TRUE, TRUE)))
+ if ((result= close_cached_tables_set_readonly(thd)))
goto end_with_read_lock;
if ((result= make_global_read_lock_block_commit(thd)))
diff --git a/sql/set_var.h b/sql/set_var.h
index 95885357b83..c591ab5b866 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -516,10 +516,15 @@ public:
{ chain_sys_var(chain); }
bool check(THD *thd, set_var *var)
{
- int ret= 0;
- if (check_func)
- ret= (*check_func)(thd, var);
- return ret ? ret : check_enum(thd, var, enum_names);
+ /*
+ check_enum fails if the character representation supplied was wrong
+ or that the integer value was wrong or missing.
+ */
+ if (check_enum(thd, var, enum_names))
+ return TRUE;
+ if ((check_func && (*check_func)(thd, var)))
+ return TRUE;
+ return FALSE;
}
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
@@ -675,8 +680,12 @@ public:
void set_default(THD *thd, enum_var_type type);
bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
bool check_default(enum_var_type type) { return 0; }
- SHOW_TYPE show_type() { return SHOW_LONG; }
+ SHOW_TYPE show_type() { return SHOW_DOUBLE; }
uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+ virtual bool check_update_type(Item_result type)
+ {
+ return type != INT_RESULT && type != REAL_RESULT && type != DECIMAL_RESULT;
+ }
};
diff --git a/sql/share/Makefile.am b/sql/share/Makefile.am
index 892a720900e..8b7792481e6 100644
--- a/sql/share/Makefile.am
+++ b/sql/share/Makefile.am
@@ -49,6 +49,7 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/charsets/*.xml $(DESTDIR)$(pkgdatadir)/charsets
# FIXME maybe shouldn't remove, could be needed by other installation?
+# Note that this removes the directory that support-files are using!
uninstall-local:
@RM@ -f -r $(DESTDIR)$(pkgdatadir)
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index d3d038e9b82..e8d9f8b8e01 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5321,7 +5321,7 @@ ER_NO_DEFAULT_FOR_FIELD
ER_DIVISION_BY_ZERO 22012
eng "Division by 0"
ger "Division durch 0"
-ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
+ER_TRUNCATED_WRONG_VALUE_FOR_FIELD 22007
eng "Incorrect %-.32s value: '%-.128s' for column '%.192s' at row %lu"
ger "Falscher %-.32s-Wert: '%-.128s' für Feld '%.192s' in Zeile %lu"
ER_ILLEGAL_VALUE_FOR_TYPE 22007
@@ -5513,11 +5513,11 @@ ER_SP_NO_RECURSION
eng "Recursive stored functions and triggers are not allowed."
ger "Rekursive gespeicherte Routinen und Triggers sind nicht erlaubt"
ER_TOO_BIG_SCALE 42000 S1009
- eng "Too big scale %d specified for column '%-.192s'. Maximum is %lu."
- ger "Zu großer Skalierungsfaktor %d für Feld '%-.192s' angegeben. Maximum ist %lu"
+ eng "Too big scale %u specified for '%-.192s'. Maximum is %lu."
+ ger "Zu großer Skalierungsfaktor %u für '%-.192s' angegeben. Maximum ist %lu"
ER_TOO_BIG_PRECISION 42000 S1009
- eng "Too big precision %d specified for column '%-.192s'. Maximum is %lu."
- ger "Zu große Genauigkeit %d für Feld '%-.192s' angegeben. Maximum ist %lu"
+ eng "Too big precision %u specified for '%-.192s'. Maximum is %lu."
+ ger "Zu große Genauigkeit %u für '%-.192s' angegeben. Maximum ist %lu"
ER_M_BIGGER_THAN_D 42000 S1009
eng "For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '%-.192s')."
ger "Für FLOAT(M,D), DOUBLE(M,D) oder DECIMAL(M,D) muss M >= D sein (Feld '%-.192s')"
@@ -5555,8 +5555,8 @@ ER_WARN_CANT_DROP_DEFAULT_KEYCACHE
eng "Cannot drop default keycache"
ger "Der vorgabemäßige Schlüssel-Cache kann nicht gelöscht werden"
ER_TOO_BIG_DISPLAYWIDTH 42000 S1009
- eng "Display width out of range for column '%-.192s' (max = %lu)"
- ger "Anzeigebreite außerhalb des zulässigen Bereichs für Spalte '%-.192s' (Maximum: %lu)"
+ eng "Display width out of range for '%-.192s' (max = %lu)"
+ ger "Anzeigebreite außerhalb des zulässigen Bereichs für '%-.192s' (Maximum: %lu)"
ER_XAER_DUPID XAE08
eng "XAER_DUPID: The XID already exists"
ger "XAER_DUPID: Die XID existiert bereits"
@@ -6214,6 +6214,19 @@ ER_DEBUG_SYNC_HIT_LIMIT
eng "debug sync point hit limit reached"
ger "Debug Sync Point Hit Limit erreicht"
+#
+# MariaDB error messages section starts here
+#
+
+# The following is here to allow us to detect if there was missing
+# error messages in the errmsg.sys file
+
+ER_LAST_MYSQL_ERROR_MESSAGE
+ eng ""
+
+# MariaDB error numbers starts from 1900
+start-error-number 1900
+
ER_VCOL_BASED_ON_VCOL
eng "A computed column cannot be based on a computed column"
@@ -6249,3 +6262,38 @@ ER_UNKNOWN_OPTION
eng "Unknown option '%-.64s'"
ER_BAD_OPTION_VALUE
eng "Incorrect value '%-.64s' for option '%-.64s'"
+ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE
+ eng "Replication event checksum verification failed while reading from network."
+ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE
+ eng "Replication event checksum verification failed while reading from a log file."
+ER_CANT_DO_ONLINE
+ eng "Can't execute the given '%s' command as online"
+ER_DATA_OVERFLOW 22003
+ eng "Got overflow when converting '%-.128s' to %-.32s. Value truncated."
+ER_DATA_TRUNCATED 22003
+ eng "Truncated value '%-.128s' when converting to %-.32s"
+ER_BAD_DATA 22007
+ eng "Encountered illegal value '%-.128s' when converting to %-.32s"
+ER_DYN_COL_WRONG_FORMAT
+ eng "Encountered illegal format of dynamic column string"
+ER_DYN_COL_IMPLEMENTATION_LIMIT
+ eng "Dynamic column implementation limit reached"
+ER_DYN_COL_DATA 22007
+ eng "Illegal value used as argument of dynamic column function"
+ER_DYN_COL_WRONG_CHARSET
+ eng "Dynamic column contains unknown character set"
+ER_ILLEGAL_SUBQUERY_OPTIMIZER_SWITCHES
+ eng "At least one of the 'in_to_exists' or 'materialization' optimizer_switch flags must be 'on'."
+ER_QUERY_CACHE_IS_DISABLED
+ eng "Query cache is disabled (resize or similar command in progress); repeat this command later"
+ER_QUERY_CACHE_IS_GLOBALY_DISABLED
+ eng "Query cache is globally disabled and you can't enable it only for this session"
+ER_VIEW_ORDERBY_IGNORED
+ eng "View '%-.192s'.'%-.192s' ORDER BY clause ignored because there is other ORDER BY clause already."
+ER_CONNECTION_KILLED 70100
+ eng "Connection was killed"
+ER_INTERNAL_ERROR
+ eng "Internal error: '%-.192s'"
+ER_SPATIAL_MUST_HAVE_GEOM_COL 42000
+ eng "A SPATIAL index may only contain a geometrical type column"
+
diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc
index 3546efa9ee1..66cf240f695 100644
--- a/sql/signal_handler.cc
+++ b/sql/signal_handler.cc
@@ -102,6 +102,8 @@ extern "C" sig_handler handle_fatal_signal(int sig)
"diagnose the problem, but since we have already crashed, \n"
"something is definitely wrong and this may fail.\n\n");
+ set_server_version();
+ my_safe_printf_stderr("Server version: %s\n", server_version);
my_safe_printf_stderr("key_buffer_size=%lu\n",
(ulong) dflt_key_cache->key_cache_mem_size);
@@ -166,37 +168,53 @@ extern "C" sig_handler handle_fatal_signal(int sig)
{
const char *kreason= "UNKNOWN";
switch (thd->killed) {
- case THD::NOT_KILLED:
+ case NOT_KILLED:
+ case KILL_HARD_BIT:
kreason= "NOT_KILLED";
break;
- case THD::KILL_BAD_DATA:
+ case KILL_BAD_DATA:
+ case KILL_BAD_DATA_HARD:
kreason= "KILL_BAD_DATA";
break;
- case THD::KILL_CONNECTION:
+ case KILL_CONNECTION:
+ case KILL_CONNECTION_HARD:
kreason= "KILL_CONNECTION";
break;
- case THD::KILL_QUERY:
+ case KILL_QUERY:
+ case KILL_QUERY_HARD:
kreason= "KILL_QUERY";
break;
- case THD::KILL_SYSTEM_THREAD:
+ case KILL_SYSTEM_THREAD:
+ case KILL_SYSTEM_THREAD_HARD:
kreason= "KILL_SYSTEM_THREAD";
break;
- case THD::KILL_SERVER:
+ case KILL_SERVER:
+ case KILL_SERVER_HARD:
kreason= "KILL_SERVER";
break;
- case THD::KILLED_NO_VALUE:
- kreason= "KILLED_NO_VALUE";
- break;
}
my_safe_printf_stderr("%s", "\n"
"Trying to get some variables.\n"
"Some pointers may be invalid and cause the dump to abort.\n");
my_safe_printf_stderr("Query (%p): ", thd->query());
- my_safe_print_str(thd->query(), min(1024U, thd->query_length()));
+ my_safe_print_str(thd->query(), min(65535, thd->query_length()));
my_safe_printf_stderr("Connection ID (thread ID): %lu\n",
(ulong) thd->thread_id);
- my_safe_printf_stderr("Status: %s\n\n", kreason);
+ my_safe_printf_stderr("Status: %s\n", kreason);
+
+ ulonglong optsw= thd->variables.optimizer_switch;
+ const char **optimizer_switch_names= optimizer_switch_typelib.type_names;
+ my_safe_printf_stderr("Optimizer switch: ");
+ for (uint i= 0; optimizer_switch_names[i+1]; i++, optsw >>= 1)
+ {
+ if (i)
+ my_safe_printf_stderr(",");
+ my_safe_printf_stderr("%s=%s",
+ optimizer_switch_names[i],
+ optsw & 1 ? "on" : "off");
+ }
+ my_safe_printf_stderr("\n\n");
}
my_safe_printf_stderr("%s",
"The manual page at "
diff --git a/sql/slave.cc b/sql/slave.cc
index 5abb09b797c..436e52e64fe 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -526,7 +526,7 @@ terminate_slave_thread(THD *thd,
IF_DBUG(int err= ) pthread_kill(thd->real_id, thr_client_alarm);
DBUG_ASSERT(err != EINVAL);
#endif
- thd->awake(THD::NOT_KILLED);
+ thd->awake(KILL_CONNECTION);
pthread_mutex_unlock(&thd->LOCK_thd_kill);
/*
@@ -843,6 +843,7 @@ bool is_network_error(uint errorno)
errorno == CR_SERVER_GONE_ERROR ||
errorno == CR_SERVER_LOST ||
errorno == ER_CON_COUNT_ERROR ||
+ errorno == ER_CONNECTION_KILLED ||
errorno == ER_NEW_ABORTING_CONNECTION ||
errorno == ER_SERVER_SHUTDOWN)
return TRUE;
@@ -945,6 +946,48 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
}
/*
+ FD_q's (A) is set initially from RL's (A): FD_q.(A) := RL.(A).
+ It's necessary to adjust FD_q.(A) at this point because in the following
+ course FD_q is going to be dumped to RL.
+ Generally FD_q is derived from a received FD_m (roughly FD_q := FD_m)
+ in queue_event and the master's (A) is installed.
+ At one step with the assignment the Relay-Log's checksum alg is set to
+ a new value: RL.(A) := FD_q.(A). If the slave service is stopped
+ the last time assigned RL.(A) will be passed over to the restarting
+ service (to the current execution point).
+ RL.A is a "codec" to verify checksum in queue_event() almost all the time
+ the first fake Rotate event.
+ Starting from this point IO thread will executes the following checksum
+ warmup sequence of actions:
+
+ FD_q.A := RL.A,
+ A_m^0 := master.@@global.binlog_checksum,
+ {queue_event(R_f): verifies(R_f, A_m^0)},
+ {queue_event(FD_m): verifies(FD_m, FD_m.A), dump(FD_q), rotate(RL),
+ FD_q := FD_m, RL.A := FD_q.A)}
+
+ See legends definition on MYSQL_BIN_LOG::relay_log_checksum_alg
+ docs lines (binlog.h).
+ In above A_m^0 - the value of master's
+ @@binlog_checksum determined in the upcoming handshake (stored in
+ mi->checksum_alg_before_fd).
+
+
+ After the warm-up sequence IO gets to "normal" checksum verification mode
+ to use RL.A in
+
+ {queue_event(E_m): verifies(E_m, RL.A)}
+
+ until it has received a new FD_m.
+ */
+ mi->rli.relay_log.description_event_for_queue->checksum_alg=
+ mi->rli.relay_log.relay_log_checksum_alg;
+
+ DBUG_ASSERT(mi->rli.relay_log.description_event_for_queue->checksum_alg !=
+ BINLOG_CHECKSUM_ALG_UNDEF);
+ DBUG_ASSERT(mi->rli.relay_log.relay_log_checksum_alg !=
+ BINLOG_CHECKSUM_ALG_UNDEF);
+ /*
Compare the master and slave's clock. Do not die if master's clock is
unavailable (very old master not supporting UNIX_TIMESTAMP()?).
*/
@@ -1183,6 +1226,103 @@ when it try to get the value of TIME_ZONE global variable from master.";
}
}
+ /*
+ Querying if master is capable to checksum and notifying it about own
+ CRC-awareness. The master's side instant value of @@global.binlog_checksum
+ is stored in the dump thread's uservar area as well as cached locally
+ to become known in consensus by master and slave.
+ */
+ DBUG_EXECUTE_IF("simulate_slave_unaware_checksum",
+ mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_OFF;
+ goto past_checksum;);
+ {
+ int rc;
+ const char query[]= "SET @master_binlog_checksum= @@global.binlog_checksum";
+ master_res= NULL;
+ mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_UNDEF; //initially undefined
+ /*
+ @c checksum_alg_before_fd is queried from master in this block.
+ If master is old checksum-unaware the value stays undefined.
+ Once the first FD will be received its alg descriptor will replace
+ the being queried one.
+ */
+ rc= mysql_real_query(mysql, query, strlen(query));
+ if (rc != 0)
+ {
+ if (check_io_slave_killed(mi->io_thd, mi, NULL))
+ goto slave_killed_err;
+
+ if (mysql_errno(mysql) == ER_UNKNOWN_SYSTEM_VARIABLE)
+ {
+ // this is tolerable as OM -> NS is supported
+ mi->report(WARNING_LEVEL, mysql_errno(mysql),
+ "Notifying master by %s failed with "
+ "error: %s", query, mysql_error(mysql));
+ }
+ else
+ {
+ if (is_network_error(mysql_errno(mysql)))
+ {
+ mi->report(WARNING_LEVEL, mysql_errno(mysql),
+ "Notifying master by %s failed with "
+ "error: %s", query, mysql_error(mysql));
+ mysql_free_result(mysql_store_result(mysql));
+ goto network_err;
+ }
+ else
+ {
+ errmsg= "The slave I/O thread stops because a fatal error is encountered "
+ "when it tried to SET @master_binlog_checksum on master.";
+ err_code= ER_SLAVE_FATAL_ERROR;
+ sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
+ mysql_free_result(mysql_store_result(mysql));
+ goto err;
+ }
+ }
+ }
+ else
+ {
+ mysql_free_result(mysql_store_result(mysql));
+ if (!mysql_real_query(mysql,
+ STRING_WITH_LEN("SELECT @master_binlog_checksum")) &&
+ (master_res= mysql_store_result(mysql)) &&
+ (master_row= mysql_fetch_row(master_res)) &&
+ (master_row[0] != NULL))
+ {
+ mi->checksum_alg_before_fd= (uint8)
+ find_type(master_row[0], &binlog_checksum_typelib, 1) - 1;
+ // valid outcome is either of
+ DBUG_ASSERT(mi->checksum_alg_before_fd == BINLOG_CHECKSUM_ALG_OFF ||
+ mi->checksum_alg_before_fd == BINLOG_CHECKSUM_ALG_CRC32);
+ }
+ else if (check_io_slave_killed(mi->io_thd, mi, NULL))
+ goto slave_killed_err;
+ else if (is_network_error(mysql_errno(mysql)))
+ {
+ mi->report(WARNING_LEVEL, mysql_errno(mysql),
+ "Get master BINLOG_CHECKSUM failed with error: %s", mysql_error(mysql));
+ goto network_err;
+ }
+ else
+ {
+ errmsg= "The slave I/O thread stops because a fatal error is encountered "
+ "when it tried to SELECT @master_binlog_checksum.";
+ err_code= ER_SLAVE_FATAL_ERROR;
+ sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
+ mysql_free_result(mysql_store_result(mysql));
+ goto err;
+ }
+ }
+ if (master_res)
+ {
+ mysql_free_result(master_res);
+ master_res= NULL;
+ }
+ }
+
+#ifndef DBUG_OFF
+past_checksum:
+#endif
err:
if (errmsg)
{
@@ -1199,6 +1339,11 @@ network_err:
if (master_res)
mysql_free_result(master_res);
DBUG_RETURN(2);
+
+slave_killed_err:
+ if (master_res)
+ mysql_free_result(master_res);
+ DBUG_RETURN(2);
}
/*
@@ -1924,6 +2069,9 @@ static int request_dump(MYSQL* mysql, Master_info* mi,
*suppress_warnings= FALSE;
+ if (opt_log_slave_updates && opt_replicate_annotate_row_events)
+ binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
+
// TODO if big log files: Change next to int8store()
int4store(buf, (ulong) mi->master_log_pos);
int2store(buf + 4, binlog_flags);
@@ -2169,7 +2317,11 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli)
thd->set_time(); // time the query
thd->lex->current_select= 0;
if (!ev->when)
- ev->when= my_time(0);
+ {
+ my_hrtime_t hrtime= my_hrtime();
+ ev->when= hrtime_to_my_time(hrtime);
+ ev->when_sec_part= hrtime_sec_part(hrtime);
+ }
ev->thd = thd; // because up to this point, ev->thd == 0
int reason= ev->shall_skip(rli);
@@ -2318,18 +2470,42 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
}
exec_res= apply_event_and_update_pos(ev, thd, rli);
- /*
- Format_description_log_event should not be deleted because it will be
- used to read info about the relay log's format; it will be deleted when
- the SQL thread does not need it, i.e. when this thread terminates.
- */
- if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT &&
- !rli->is_deferred_event(ev))
- {
- DBUG_PRINT("info", ("Deleting the event after it has been executed"));
- delete ev;
+ switch (ev->get_type_code()) {
+ case FORMAT_DESCRIPTION_EVENT:
+ /*
+ Format_description_log_event should not be deleted because it
+ will be used to read info about the relay log's format;
+ it will be deleted when the SQL thread does not need it,
+ i.e. when this thread terminates.
+ */
+ break;
+ case ANNOTATE_ROWS_EVENT:
+ /*
+ Annotate_rows event should not be deleted because after it has
+ been applied, thd->query points to the string inside this event.
+ The thd->query will be used to generate new Annotate_rows event
+ during applying the subsequent Rows events.
+ */
+ rli->set_annotate_event((Annotate_rows_log_event*) ev);
+ break;
+ case DELETE_ROWS_EVENT:
+ case UPDATE_ROWS_EVENT:
+ case WRITE_ROWS_EVENT:
+ /*
+ After the last Rows event has been applied, the saved Annotate_rows
+ event (if any) is not needed anymore and can be deleted.
+ */
+ if (((Rows_log_event*)ev)->get_flags(Rows_log_event::STMT_END_F))
+ rli->free_annotate_event();
+ /* fall through */
+ default:
+ DBUG_PRINT("info", ("Deleting the event after it has been executed"));
+ if (!rli->is_deferred_event(ev))
+ delete ev;
+ break;
}
+
/*
update_log_pos failed: this should not happen, so we don't
retry.
@@ -2557,9 +2733,8 @@ pthread_handler_t handle_slave_io(void *arg)
if (init_slave_thread(thd, SLAVE_THD_IO))
{
pthread_cond_broadcast(&mi->start_cond);
- pthread_mutex_unlock(&mi->run_lock);
sql_print_error("Failed during slave I/O thread initialization");
- goto err;
+ goto err_during_init;
}
pthread_mutex_lock(&LOCK_thread_count);
threads.append(thd);
@@ -2828,6 +3003,7 @@ err:
thd_proc_info(thd, "Waiting for slave mutex on exit");
pthread_mutex_lock(&mi->run_lock);
+err_during_init:
/* Forget the relay log's format */
delete mi->rli.relay_log.description_event_for_queue;
mi->rli.relay_log.description_event_for_queue= 0;
@@ -2951,10 +3127,9 @@ pthread_handler_t handle_slave_sql(void *arg)
will be stuck if we fail here
*/
pthread_cond_broadcast(&rli->start_cond);
- pthread_mutex_unlock(&rli->run_lock);
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
"Failed during slave thread initialization");
- goto err;
+ goto err_during_init;
}
thd->init_for_queries();
thd->rli_slave= rli;
@@ -2965,6 +3140,12 @@ pthread_handler_t handle_slave_sql(void *arg)
thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
set_thd_in_use_temporary_tables(rli); // (re)set sql_thd in use for saved temp tables
+ /*
+ binlog_annotate_row_events must be TRUE only after an Annotate_rows event
+ has been recieved and only till the last corresponding rbr event has been
+ applied. In all other cases it must be FALSE.
+ */
+ thd->variables.binlog_annotate_row_events= 0;
pthread_mutex_lock(&LOCK_thread_count);
threads.append(thd);
pthread_mutex_unlock(&LOCK_thread_count);
@@ -3207,6 +3388,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
thd->reset_db(NULL, 0);
thd_proc_info(thd, "Waiting for slave mutex on exit");
pthread_mutex_lock(&rli->run_lock);
+err_during_init:
/* We need data_lock, at least to wake up any waiting master_pos_wait() */
pthread_mutex_lock(&rli->data_lock);
DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun
@@ -3417,10 +3599,15 @@ static int process_io_rotate(Master_info *mi, Rotate_log_event *rev)
*/
if (mi->rli.relay_log.description_event_for_queue->binlog_version >= 4)
{
+ DBUG_ASSERT(mi->rli.relay_log.description_event_for_queue->checksum_alg ==
+ mi->rli.relay_log.relay_log_checksum_alg);
+
delete mi->rli.relay_log.description_event_for_queue;
/* start from format 3 (MySQL 4.0) again */
mi->rli.relay_log.description_event_for_queue= new
Format_description_log_event(3);
+ mi->rli.relay_log.description_event_for_queue->checksum_alg=
+ mi->rli.relay_log.relay_log_checksum_alg;
}
/*
Rotate the relay log makes binlog format detection easier (at next slave
@@ -3447,7 +3634,7 @@ static int queue_binlog_ver_1_event(Master_info *mi, const char *buf,
If we get Load event, we need to pass a non-reusable buffer
to read_log_event, so we do a trick
*/
- if (buf[EVENT_TYPE_OFFSET] == LOAD_EVENT)
+ if ((uchar)buf[EVENT_TYPE_OFFSET] == LOAD_EVENT)
{
if (unlikely(!(tmp_buf=(char*)my_malloc(event_len+1,MYF(MY_WME)))))
{
@@ -3473,8 +3660,9 @@ static int queue_binlog_ver_1_event(Master_info *mi, const char *buf,
Append_block/Exec_load (the SQL thread needs the data, as that thread is not
connected to the master).
*/
- Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg,
- mi->rli.relay_log.description_event_for_queue);
+ Log_event *ev=
+ Log_event::read_log_event(buf, event_len, &errmsg,
+ mi->rli.relay_log.description_event_for_queue, 0);
if (unlikely(!ev))
{
sql_print_error("Read invalid event from master: '%s',\
@@ -3561,8 +3749,9 @@ static int queue_binlog_ver_3_event(Master_info *mi, const char *buf,
DBUG_ENTER("queue_binlog_ver_3_event");
/* read_log_event() will adjust log_pos to be end_log_pos */
- Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg,
- mi->rli.relay_log.description_event_for_queue);
+ Log_event *ev=
+ Log_event::read_log_event(buf,event_len, &errmsg,
+ mi->rli.relay_log.description_event_for_queue, 0);
if (unlikely(!ev))
{
sql_print_error("Read invalid event from master: '%s',\
@@ -3588,6 +3777,7 @@ static int queue_binlog_ver_3_event(Master_info *mi, const char *buf,
inc_pos= event_len;
break;
}
+
if (unlikely(rli->relay_log.append(ev)))
{
delete ev;
@@ -3649,18 +3839,79 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
ulong inc_pos;
Relay_log_info *rli= &mi->rli;
pthread_mutex_t *log_lock= rli->relay_log.get_log_lock();
+ bool unlock_data_lock= TRUE;
+ /*
+ FD_q must have been prepared for the first R_a event
+ inside get_master_version_and_clock()
+ Show-up of FD:s affects checksum_alg at once because
+ that changes FD_queue.
+ */
+ uint8 checksum_alg= mi->checksum_alg_before_fd != BINLOG_CHECKSUM_ALG_UNDEF ?
+ mi->checksum_alg_before_fd :
+ mi->rli.relay_log.relay_log_checksum_alg;
+
+ char *save_buf= NULL; // needed for checksumming the fake Rotate event
+ char rot_buf[LOG_EVENT_HEADER_LEN + ROTATE_HEADER_LEN + FN_REFLEN];
+
+ DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_OFF ||
+ checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
+ checksum_alg == BINLOG_CHECKSUM_ALG_CRC32);
+
DBUG_ENTER("queue_event");
+ /*
+ FD_queue checksum alg description does not apply in a case of
+ FD itself. The one carries both parts of the checksum data.
+ */
+ if (buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT)
+ {
+ checksum_alg= get_checksum_alg(buf, event_len);
+ }
+ else if (buf[EVENT_TYPE_OFFSET] == START_EVENT_V3)
+ {
+ // checksum behaviour is similar to the pre-checksum FD handling
+ mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_UNDEF;
+ mi->rli.relay_log.description_event_for_queue->checksum_alg=
+ mi->rli.relay_log.relay_log_checksum_alg= checksum_alg=
+ BINLOG_CHECKSUM_ALG_OFF;
+ }
+
+ // does not hold always because of old binlog can work with NM
+ // DBUG_ASSERT(checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
+
+ // should hold unless manipulations with RL. Tests that do that
+ // will have to refine the clause.
+ DBUG_ASSERT(mi->rli.relay_log.relay_log_checksum_alg !=
+ BINLOG_CHECKSUM_ALG_UNDEF);
+
+ // Emulate the network corruption
+ DBUG_EXECUTE_IF("corrupt_queue_event",
+ if (buf[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT)
+ {
+ char *debug_event_buf_c = (char*) buf;
+ int debug_cor_pos = rand() % (event_len - BINLOG_CHECKSUM_LEN);
+ debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
+ DBUG_PRINT("info", ("Corrupt the event at queue_event: byte on position %d", debug_cor_pos));
+ DBUG_SET("-d,corrupt_queue_event");
+ }
+ );
+
+ if (event_checksum_test((uchar *) buf, event_len, checksum_alg))
+ {
+ error= ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE;
+ unlock_data_lock= FALSE;
+ goto err;
+ }
LINT_INIT(inc_pos);
if (mi->rli.relay_log.description_event_for_queue->binlog_version<4 &&
- buf[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT /* a way to escape */)
+ (uchar)buf[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT /* a way to escape */)
DBUG_RETURN(queue_old_event(mi,buf,event_len));
LINT_INIT(inc_pos);
pthread_mutex_lock(&mi->data_lock);
- switch (buf[EVENT_TYPE_OFFSET]) {
+ switch ((uchar)buf[EVENT_TYPE_OFFSET]) {
case STOP_EVENT:
/*
We needn't write this event to the relay log. Indeed, it just indicates a
@@ -3677,12 +3928,67 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
goto err;
case ROTATE_EVENT:
{
- Rotate_log_event rev(buf,event_len,mi->rli.relay_log.description_event_for_queue);
- if (unlikely(process_io_rotate(mi,&rev)))
+ Rotate_log_event rev(buf, checksum_alg != BINLOG_CHECKSUM_ALG_OFF ?
+ event_len - BINLOG_CHECKSUM_LEN : event_len,
+ mi->rli.relay_log.description_event_for_queue);
+
+ if (unlikely(process_io_rotate(mi, &rev)))
{
error= 1;
goto err;
}
+ /*
+ Checksum special cases for the fake Rotate (R_f) event caused by the protocol
+ of events generation and serialization in RL where Rotate of master is
+ queued right next to FD of slave.
+ Since it's only FD that carries the alg desc of FD_s has to apply to R_m.
+ Two special rules apply only to the first R_f which comes in before any FD_m.
+ The 2nd R_f should be compatible with the FD_s that must have taken over
+ the last seen FD_m's (A).
+
+ RSC_1: If OM \and fake Rotate \and slave is configured to
+ to compute checksum for its first FD event for RL
+ the fake Rotate gets checksummed here.
+ */
+ if (uint4korr(&buf[0]) == 0 && checksum_alg == BINLOG_CHECKSUM_ALG_OFF &&
+ mi->rli.relay_log.relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
+ {
+ ha_checksum rot_crc= my_checksum(0L, NULL, 0);
+ event_len += BINLOG_CHECKSUM_LEN;
+ memcpy(rot_buf, buf, event_len - BINLOG_CHECKSUM_LEN);
+ int4store(&rot_buf[EVENT_LEN_OFFSET],
+ uint4korr(&rot_buf[EVENT_LEN_OFFSET]) + BINLOG_CHECKSUM_LEN);
+ rot_crc= my_checksum(rot_crc, (const uchar *) rot_buf,
+ event_len - BINLOG_CHECKSUM_LEN);
+ int4store(&rot_buf[event_len - BINLOG_CHECKSUM_LEN], rot_crc);
+ DBUG_ASSERT(event_len == uint4korr(&rot_buf[EVENT_LEN_OFFSET]));
+ DBUG_ASSERT(mi->rli.relay_log.description_event_for_queue->checksum_alg ==
+ mi->rli.relay_log.relay_log_checksum_alg);
+ /* the first one */
+ DBUG_ASSERT(mi->checksum_alg_before_fd != BINLOG_CHECKSUM_ALG_UNDEF);
+ save_buf= (char *) buf;
+ buf= rot_buf;
+ }
+ else
+ /*
+ RSC_2: If NM \and fake Rotate \and slave does not compute checksum
+ the fake Rotate's checksum is stripped off before relay-logging.
+ */
+ if (uint4korr(&buf[0]) == 0 && checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
+ mi->rli.relay_log.relay_log_checksum_alg == BINLOG_CHECKSUM_ALG_OFF)
+ {
+ event_len -= BINLOG_CHECKSUM_LEN;
+ memcpy(rot_buf, buf, event_len);
+ int4store(&rot_buf[EVENT_LEN_OFFSET],
+ uint4korr(&rot_buf[EVENT_LEN_OFFSET]) - BINLOG_CHECKSUM_LEN);
+ DBUG_ASSERT(event_len == uint4korr(&rot_buf[EVENT_LEN_OFFSET]));
+ DBUG_ASSERT(mi->rli.relay_log.description_event_for_queue->checksum_alg ==
+ mi->rli.relay_log.relay_log_checksum_alg);
+ /* the first one */
+ DBUG_ASSERT(mi->checksum_alg_before_fd != BINLOG_CHECKSUM_ALG_UNDEF);
+ save_buf= (char *) buf;
+ buf= rot_buf;
+ }
/*
Now the I/O thread has just changed its mi->master_log_name, so
incrementing mi->master_log_pos is nonsense.
@@ -3703,15 +4009,24 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
*/
Format_description_log_event* tmp;
const char* errmsg;
+ // mark it as undefined that is irrelevant anymore
+ mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_UNDEF;
if (!(tmp= (Format_description_log_event*)
Log_event::read_log_event(buf, event_len, &errmsg,
- mi->rli.relay_log.description_event_for_queue)))
+ mi->rli.relay_log.description_event_for_queue,
+ 1)))
{
error= 2;
goto err;
}
delete mi->rli.relay_log.description_event_for_queue;
mi->rli.relay_log.description_event_for_queue= tmp;
+ if (tmp->checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF)
+ tmp->checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
+
+ /* installing new value of checksum Alg for relay log */
+ mi->rli.relay_log.relay_log_checksum_alg= tmp->checksum_alg;
+
/*
Though this does some conversion to the slave's format, this will
preserve the master's binlog format version, and number of event types.
@@ -3763,9 +4078,9 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
the master's binlog (i.e. Format_desc, Rotate & Stop) should not increment
mi->master_log_pos.
*/
- if (buf[EVENT_TYPE_OFFSET]!=FORMAT_DESCRIPTION_EVENT &&
- buf[EVENT_TYPE_OFFSET]!=ROTATE_EVENT &&
- buf[EVENT_TYPE_OFFSET]!=STOP_EVENT)
+ if ((uchar)buf[EVENT_TYPE_OFFSET]!=FORMAT_DESCRIPTION_EVENT &&
+ (uchar)buf[EVENT_TYPE_OFFSET]!=ROTATE_EVENT &&
+ (uchar)buf[EVENT_TYPE_OFFSET]!=STOP_EVENT)
{
mi->master_log_pos+= inc_pos;
memcpy(rli->ign_master_log_name_end, mi->master_log_name, FN_REFLEN);
@@ -3788,12 +4103,15 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
else
error= 3;
rli->ign_master_log_name_end[0]= 0; // last event is not ignored
+ if (save_buf != NULL)
+ buf= save_buf;
}
pthread_mutex_unlock(log_lock);
err:
- pthread_mutex_unlock(&mi->data_lock);
+ if (unlock_data_lock)
+ pthread_mutex_unlock(&mi->data_lock);
DBUG_PRINT("info", ("error: %d", error));
DBUG_RETURN(error);
}
@@ -4183,8 +4501,9 @@ static Log_event* next_event(Relay_log_info* rli)
But if the relay log is created by new_file(): then the solution is:
MYSQL_BIN_LOG::open() will write the buffered description event.
*/
- if ((ev=Log_event::read_log_event(cur_log,0,
- rli->relay_log.description_event_for_exec)))
+ if ((ev= Log_event::read_log_event(cur_log,0,
+ rli->relay_log.description_event_for_exec,
+ opt_slave_sql_verify_checksum)))
{
DBUG_ASSERT(thd==rli->sql_thd);
@@ -4610,9 +4929,9 @@ bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report,
{37426, { 5, 1, 0 }, { 5, 1, 26 } },
};
const uchar *master_ver=
- rli->relay_log.description_event_for_exec->server_version_split;
+ rli->relay_log.description_event_for_exec->server_version_split.ver;
- DBUG_ASSERT(sizeof(rli->relay_log.description_event_for_exec->server_version_split) == 3);
+ DBUG_ASSERT(sizeof(rli->relay_log.description_event_for_exec->server_version_split.ver) == 3);
for (uint i= 0;
i < sizeof(versions_for_all_bugs)/sizeof(*versions_for_all_bugs);i++)
diff --git a/sql/slave.h b/sql/slave.h
index f174b40c108..30574f42d69 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -108,6 +108,7 @@ extern MYSQL_PLUGIN_IMPORT char *relay_log_info_file;
extern char *opt_relay_logname, *opt_relaylog_index_name;
extern my_bool opt_skip_slave_start, opt_reckless_slave;
extern my_bool opt_log_slave_updates;
+extern my_bool opt_replicate_annotate_row_events;
extern ulonglong relay_log_space_limit;
/*
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 57143080ee3..9dab75645cd 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -51,19 +51,7 @@ static void reset_start_time_for_sp(THD *thd)
constant during the execution of those.
*/
if (!thd->in_sub_stmt)
- {
- /*
- First investigate if there is a cached time stamp
- */
- if (thd->user_time)
- {
- thd->start_time= thd->user_time;
- }
- else
- {
- my_micro_time_and_time(&thd->start_time);
- }
- }
+ thd->set_time();
}
Item_result
@@ -1036,17 +1024,18 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
buffer :==
<statement> The input statement(s)
'\0' Terminating null char
- <length> Length of following current database name (size_t)
+ <length> Length of following current database name 2
<db_name> Name of current database
<flags> Flags struct
*/
- buf_len= qbuf.length() + 1 + sizeof(size_t) + thd->db_length +
- QUERY_CACHE_FLAGS_SIZE + 1;
+ buf_len= (qbuf.length() + 1 + QUERY_CACHE_DB_LENGTH_SIZE + thd->db_length +
+ QUERY_CACHE_FLAGS_SIZE + 1);
if ((pbuf= (char *) alloc_root(thd->mem_root, buf_len)))
{
+ char *ptr= pbuf + qbuf.length();
memcpy(pbuf, qbuf.ptr(), qbuf.length());
- pbuf[qbuf.length()]= 0;
- memcpy(pbuf+qbuf.length()+1, (char *) &thd->db_length, sizeof(size_t));
+ *ptr= 0;
+ int2store(ptr+1, thd->db_length);
}
else
DBUG_RETURN(TRUE);
@@ -1336,7 +1325,7 @@ sp_head::execute(THD *thd)
ctx->enter_handler(hip);
thd->clear_error();
thd->is_fatal_error= 0;
- thd->killed= THD::NOT_KILLED;
+ thd->killed= NOT_KILLED;
thd->mysys_var->abort= 0;
continue;
}
@@ -1386,10 +1375,7 @@ sp_head::execute(THD *thd)
If the DB has changed, the pointer has changed too, but the
original thd->db will then have been freed
*/
- if (cur_db_changed &&
- thd->killed != THD::KILL_CONNECTION &&
- thd->killed != THD::KILL_SERVER &&
- thd->killed != THD::KILL_SYSTEM_THREAD)
+ if (cur_db_changed && thd->killed < KILL_CONNECTION)
{
/*
Force switching back to the saved current database, because it may be
@@ -1823,7 +1809,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
thd->options= binlog_save_options;
if (thd->binlog_evt_union.unioned_events)
{
- int errcode = query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode = query_error_code(thd, thd->killed == NOT_KILLED);
Query_log_event qinfo(thd, binlog_buf.ptr(), binlog_buf.length(),
thd->binlog_evt_union.unioned_events_trans, FALSE, errcode);
if (mysql_bin_log.write(&qinfo) &&
@@ -2878,6 +2864,9 @@ int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
result= -1;
else
result= 0;
+ /* Prepare all derived tables/views to catch possible errors. */
+ if (!result)
+ result= mysql_handle_derived(thd->lex, DT_PREPARE) ? -1 : 0;
return result;
}
diff --git a/sql/spatial.cc b/sql/spatial.cc
index eec028eaef1..0da2fdf40b3 100644
--- a/sql/spatial.cc
+++ b/sql/spatial.cc
@@ -40,7 +40,7 @@
17
*/
-#define MAX_DIGITS_IN_DOUBLE 22
+#define MAX_DIGITS_IN_DOUBLE 30
/***************************** Gis_class_info *******************************/
@@ -180,6 +180,7 @@ Geometry *Geometry::create_from_wkt(Geometry_buffer *buffer,
{
LEX_STRING name;
Class_info *ci;
+ char next_sym;
if (trs->get_next_word(&name))
{
@@ -192,9 +193,13 @@ Geometry *Geometry::create_from_wkt(Geometry_buffer *buffer,
Geometry *result= (*ci->m_create_func)(buffer->data);
wkt->q_append((char) wkb_ndr);
wkt->q_append((uint32) result->get_class_info()->m_type_id);
- if (trs->check_next_symbol('(') ||
+ if (!(next_sym= trs->next_symbol()))
+ return NULL;
+ if (!(next_sym= trs->next_symbol()))
+ return NULL;
+ if ((next_sym == '(' && trs->check_next_symbol('(')) ||
result->init_from_wkt(trs, wkt) ||
- trs->check_next_symbol(')'))
+ (next_sym == '(' && trs->check_next_symbol(')')))
return NULL;
if (init_stream)
{
@@ -205,6 +210,22 @@ Geometry *Geometry::create_from_wkt(Geometry_buffer *buffer,
}
+int Geometry::as_wkt(String *wkt, const char **end)
+{
+ uint32 len= (uint) get_class_info()->m_name.length;
+ if (wkt->reserve(len + 2, 512))
+ return 1;
+ wkt->qs_append(get_class_info()->m_name.str, len);
+ if (get_class_info() != &geometrycollection_class)
+ wkt->qs_append('(');
+ if (get_data_as_wkt(wkt, end))
+ return 1;
+ if (get_class_info() != &geometrycollection_class)
+ wkt->qs_append(')');
+ return 0;
+}
+
+
static double wkb_get_double(const char *ptr, Geometry::wkbByteOrder bo)
{
double res;
@@ -266,12 +287,37 @@ Geometry *Geometry::create_from_wkb(Geometry_buffer *buffer,
}
+int Geometry::create_from_opresult(Geometry_buffer *g_buf,
+ String *res, Gcalc_result_receiver &rr)
+{
+ uint32 geom_type= rr.get_result_typeid();
+ Geometry *obj= create_by_typeid(g_buf, geom_type);
+
+ if (!obj || res->reserve(WKB_HEADER_SIZE, 512))
+ return 1;
+
+ res->q_append((char) wkb_ndr);
+ res->q_append(geom_type);
+ return obj->init_from_opresult(res, rr.result(), rr.length());
+}
+
+
bool Geometry::envelope(String *result) const
{
MBR mbr;
const char *end;
- if (get_mbr(&mbr, &end) || result->reserve(1+4*3+SIZEOF_STORED_DOUBLE*10))
+ if (get_mbr(&mbr, &end))
+ {
+ /* Empty geometry */
+ if (result->reserve(1 + 4*2))
+ return 1;
+ result->q_append((char) wkb_ndr);
+ result->q_append((uint32) wkb_geometrycollection);
+ result->q_append((uint32) 0);
+ return 0;
+ }
+ if (result->reserve(1 + 4 * 3 + SIZEOF_STORED_DOUBLE * 10))
return 1;
result->q_append((char) wkb_ndr);
@@ -308,13 +354,13 @@ bool Geometry::envelope(String *result) const
bool Geometry::create_point(String *result, const char *data) const
{
- if (no_data(data, SIZEOF_STORED_DOUBLE * 2) ||
- result->reserve(1 + 4 + SIZEOF_STORED_DOUBLE * 2))
+ if (no_data(data, POINT_DATA_SIZE) ||
+ result->reserve(1 + 4 + POINT_DATA_SIZE))
return 1;
result->q_append((char) wkb_ndr);
result->q_append((uint32) wkb_point);
/* Copy two double in same format */
- result->q_append(data, SIZEOF_STORED_DOUBLE*2);
+ result->q_append(data, POINT_DATA_SIZE);
return 0;
}
@@ -334,7 +380,7 @@ bool Geometry::create_point(String *result, const char *data) const
bool Geometry::create_point(String *result, double x, double y) const
{
- if (result->reserve(1 + 4 + SIZEOF_STORED_DOUBLE * 2))
+ if (result->reserve(1 + 4 + POINT_DATA_SIZE))
return 1;
result->q_append((char) wkb_ndr);
@@ -366,7 +412,7 @@ const char *Geometry::append_points(String *txt, uint32 n_points,
double x,y;
data+= offset;
get_point(&x, &y, data);
- data+= SIZEOF_STORED_DOUBLE * 2;
+ data+= POINT_DATA_SIZE;
txt->qs_append(x);
txt->qs_append(' ');
txt->qs_append(y);
@@ -401,7 +447,7 @@ const char *Geometry::get_mbr_for_points(MBR *mbr, const char *data,
points= uint4korr(data);
data+= 4;
- if (no_data(data, (SIZEOF_STORED_DOUBLE * 2 + offset) * points))
+ if (no_data(data, (POINT_DATA_SIZE + offset) * points))
return 0;
/* Calculate MBR for points */
@@ -409,7 +455,7 @@ const char *Geometry::get_mbr_for_points(MBR *mbr, const char *data,
{
data+= offset;
mbr->add_xy(data, data + SIZEOF_STORED_DOUBLE);
- data+= SIZEOF_STORED_DOUBLE * 2;
+ data+= POINT_DATA_SIZE;
}
return data;
}
@@ -427,7 +473,7 @@ bool Gis_point::init_from_wkt(Gis_read_stream *trs, String *wkb)
{
double x, y;
if (trs->get_next_number(&x) || trs->get_next_number(&y) ||
- wkb->reserve(SIZEOF_STORED_DOUBLE * 2))
+ wkb->reserve(POINT_DATA_SIZE))
return 1;
wkb->q_append(x);
wkb->q_append(y);
@@ -474,6 +520,31 @@ bool Gis_point::get_mbr(MBR *mbr, const char **end) const
return 0;
}
+
+int Gis_point::area(double *ar, const char **end) const
+{
+ *ar= 0;
+ *end= m_data+ POINT_DATA_SIZE;
+ return 0;
+}
+
+
+int Gis_point::geom_length(double *len, const char **end) const
+{
+ *len= 0;
+ *end= m_data+ POINT_DATA_SIZE;
+ return 0;
+}
+
+
+int Gis_point::store_shapes(Gcalc_shape_transporter *trn) const
+{
+ double x, y;
+
+ return get_xy(&x, &y) || trn->single_point(x, y);
+}
+
+
const Geometry::Class_info *Gis_point::get_class_info() const
{
return &point_class;
@@ -557,7 +628,7 @@ bool Gis_line_string::get_data_as_wkt(String *txt, const char **end) const
data += 4;
if (n_points < 1 ||
- no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points) ||
+ no_data(data, POINT_DATA_SIZE * n_points) ||
txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points))
return 1;
@@ -565,7 +636,7 @@ bool Gis_line_string::get_data_as_wkt(String *txt, const char **end) const
{
double x, y;
get_point(&x, &y, data);
- data+= SIZEOF_STORED_DOUBLE * 2;
+ data+= POINT_DATA_SIZE;
txt->qs_append(x);
txt->qs_append(' ');
txt->qs_append(y);
@@ -583,7 +654,7 @@ bool Gis_line_string::get_mbr(MBR *mbr, const char **end) const
}
-int Gis_line_string::geom_length(double *len) const
+int Gis_line_string::geom_length(double *len, const char **end) const
{
uint32 n_points;
double prev_x, prev_y;
@@ -594,21 +665,35 @@ int Gis_line_string::geom_length(double *len) const
return 1;
n_points= uint4korr(data);
data+= 4;
- if (n_points < 1 || no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points))
+ if (n_points < 1 || no_data(data, POINT_DATA_SIZE * n_points))
return 1;
get_point(&prev_x, &prev_y, data);
- data+= SIZEOF_STORED_DOUBLE*2;
-
+ data+= POINT_DATA_SIZE;
while (--n_points)
{
double x, y;
get_point(&x, &y, data);
- data+= SIZEOF_STORED_DOUBLE * 2;
+ data+= POINT_DATA_SIZE;
*len+= sqrt(pow(prev_x-x,2)+pow(prev_y-y,2));
prev_x= x;
prev_y= y;
}
+ *end= data;
+ return 0;
+}
+
+
+int Gis_line_string::area(double *ar, const char **end) const
+{
+ uint32 n_points;
+ *ar= 0.0;
+
+ /* read number of points */
+ if (no_data(m_data, 4))
+ return 1;
+ n_points= uint4korr(m_data);
+ *end= m_data + 4 + POINT_DATA_SIZE * n_points;
return 0;
}
@@ -629,14 +714,14 @@ int Gis_line_string::is_closed(int *closed) const
}
data+= 4;
if (n_points == 0 ||
- no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points))
+ no_data(data, POINT_DATA_SIZE * n_points))
return 1;
/* Get first point */
get_point(&x1, &y1, data);
/* get last point */
- data+= SIZEOF_STORED_DOUBLE*2 + (n_points-2)*POINT_DATA_SIZE;
+ data+= POINT_DATA_SIZE + (n_points-2)*POINT_DATA_SIZE;
get_point(&x2, &y2, data);
*closed= (x1==x2) && (y1==y2);
@@ -680,6 +765,42 @@ int Gis_line_string::point_n(uint32 num, String *result) const
return create_point(result, m_data + 4 + (num - 1) * POINT_DATA_SIZE);
}
+
+int Gis_line_string::store_shapes(Gcalc_shape_transporter *trn) const
+{
+ uint32 n_points;
+ double x, y;
+ double prev_x= 0.0;
+ double prev_y= 0.0;
+ int first_point= 1;
+ const char *data= m_data;
+
+ if (no_data(m_data, 4))
+ return 1;
+ n_points= uint4korr(data);
+ data+= 4;
+ if (n_points < 1 || no_data(data, POINT_DATA_SIZE * n_points))
+ return 1;
+
+ trn->start_line();
+
+ while (n_points--)
+ {
+ get_point(&x, &y, data);
+ data+= POINT_DATA_SIZE;
+ if (!first_point && x == prev_x && y == prev_y)
+ continue;
+ if (trn->add_point(x, y))
+ return 1;
+ first_point= 0;
+ prev_x= x;
+ prev_y= y;
+ }
+
+ return trn->complete_line();
+}
+
+
const Geometry::Class_info *Gis_line_string::get_class_info() const
{
return &linestring_class;
@@ -741,6 +862,52 @@ bool Gis_polygon::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
+uint Gis_polygon::init_from_opresult(String *bin,
+ const char *opres, uint res_len)
+{
+ const char *opres_orig= opres;
+ uint32 position= bin->length();
+ uint32 poly_shapes= 0;
+
+ if (bin->reserve(4, 512))
+ return 0;
+ bin->q_append(poly_shapes);
+
+ while (opres_orig + res_len > opres)
+ {
+ uint32 n_points, proper_length;
+ const char *op_end, *p1_position;
+ Gis_point p;
+ Gcalc_function::shape_type st;
+
+ st= (Gcalc_function::shape_type) uint4korr(opres);
+ if (poly_shapes && st != Gcalc_function::shape_hole)
+ break;
+ poly_shapes++;
+ n_points= uint4korr(opres + 4) + 1; /* skip shape type id */
+ proper_length= 4 + n_points * POINT_DATA_SIZE;
+
+ if (bin->reserve(proper_length, 512))
+ return 0;
+
+ bin->q_append(n_points);
+ op_end= opres + 8 + (n_points-1) * 8 * 2;
+ p1_position= (opres+= 8);
+ for (; opres<op_end; opres+= POINT_DATA_SIZE)
+ {
+ if (!p.init_from_wkb(opres, POINT_DATA_SIZE, wkb_ndr, bin))
+ return 0;
+ }
+ if (!p.init_from_wkb(p1_position, POINT_DATA_SIZE, wkb_ndr, bin))
+ return 0;
+ }
+
+ bin->write_at_position(position, poly_shapes);
+
+ return (uint) (opres - opres_orig);
+}
+
+
uint Gis_polygon::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo,
String *res)
{
@@ -750,9 +917,7 @@ uint Gis_polygon::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo,
if (len < 4)
return 0;
- if (!(n_linear_rings= wkb_get_uint(wkb, bo)))
- return 0;
-
+ n_linear_rings= wkb_get_uint(wkb, bo);
if (res->reserve(4, 512))
return 0;
wkb+= 4;
@@ -798,7 +963,7 @@ bool Gis_polygon::get_data_as_wkt(String *txt, const char **end) const
return 1;
n_points= uint4korr(data);
data+= 4;
- if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points) ||
+ if (no_data(data, POINT_DATA_SIZE * n_points) ||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
return 1;
txt->qs_append('(');
@@ -852,16 +1017,16 @@ int Gis_polygon::area(double *ar, const char **end_of_data) const
if (no_data(data, 4))
return 1;
n_points= uint4korr(data);
- if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points))
+ if (no_data(data, POINT_DATA_SIZE * n_points))
return 1;
get_point(&prev_x, &prev_y, data+4);
- data+= (4+SIZEOF_STORED_DOUBLE*2);
+ data+= (4+POINT_DATA_SIZE);
while (--n_points) // One point is already read
{
double x, y;
get_point(&x, &y, data);
- data+= (SIZEOF_STORED_DOUBLE*2);
+ data+= POINT_DATA_SIZE;
lr_area+= (prev_x + x)* (prev_y - y);
prev_x= x;
prev_y= y;
@@ -888,7 +1053,7 @@ int Gis_polygon::exterior_ring(String *result) const
n_points= uint4korr(data);
data+= 4;
length= n_points * POINT_DATA_SIZE;
- if (no_data(data, length) || result->reserve(1+4+4+ length))
+ if (no_data(data, length) || result->reserve(1 + 4 + 4 + length))
return 1;
result->q_append((char) wkb_ndr);
@@ -934,7 +1099,7 @@ int Gis_polygon::interior_ring_n(uint32 num, String *result) const
n_points= uint4korr(data);
points_size= n_points * POINT_DATA_SIZE;
data+= 4;
- if (no_data(data, points_size) || result->reserve(1+4+4+ points_size))
+ if (no_data(data, points_size) || result->reserve(1 + 4 + 4 + points_size))
return 1;
result->q_append((char) wkb_ndr);
@@ -973,16 +1138,16 @@ int Gis_polygon::centroid_xy(double *x, double *y) const
return 1;
org_n_points= n_points= uint4korr(data);
data+= 4;
- if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points))
+ if (no_data(data, POINT_DATA_SIZE * n_points))
return 1;
get_point(&prev_x, &prev_y, data);
- data+= (SIZEOF_STORED_DOUBLE*2);
+ data+= POINT_DATA_SIZE;
while (--n_points) // One point is already read
{
double tmp_x, tmp_y;
get_point(&tmp_x, &tmp_y, data);
- data+= (SIZEOF_STORED_DOUBLE*2);
+ data+= POINT_DATA_SIZE;
cur_area+= (prev_x + tmp_x) * (prev_y - tmp_y);
cur_cx+= tmp_x;
cur_cy+= tmp_y;
@@ -1022,6 +1187,74 @@ int Gis_polygon::centroid(String *result) const
return create_point(result, x, y);
}
+
+int Gis_polygon::store_shapes(Gcalc_shape_transporter *trn) const
+{
+ uint32 n_linear_rings;
+ const char *data= m_data;
+ double first_x, first_y;
+ double prev_x, prev_y;
+ int was_equal_first= 0;
+
+ if (trn->start_poly())
+ return 1;
+
+ if (no_data(data, 4))
+ return 1;
+ n_linear_rings= uint4korr(data);
+ data+= 4;
+
+ while (n_linear_rings--)
+ {
+ uint32 n_points;
+
+ if (no_data(data, 4))
+ return 1;
+ n_points= uint4korr(data);
+ data+= 4;
+ if (!n_points || no_data(data, POINT_DATA_SIZE * n_points))
+ return 1;
+
+ trn->start_ring();
+ get_point(&first_x, &first_y, data);
+ data+= POINT_DATA_SIZE;
+ n_points--;
+ prev_x= first_x;
+ prev_y= first_y;
+ if (trn->add_point(first_x, first_y))
+ return 1;
+ while (--n_points)
+ {
+ double x, y;
+ get_point(&x, &y, data);
+ data+= POINT_DATA_SIZE;
+ if (x == prev_x && y == prev_y)
+ continue;
+ prev_x= x;
+ prev_y= y;
+ if (was_equal_first)
+ {
+ if (trn->add_point(first_x, first_y))
+ return 1;
+ was_equal_first= 0;
+ }
+ if (x == first_x && y == first_y)
+ {
+ was_equal_first= 1;
+ continue;
+ }
+ if (trn->add_point(x, y))
+ return 1;
+ }
+ data+= POINT_DATA_SIZE;
+ trn->complete_ring();
+ }
+
+ trn->complete_poly();
+ return 0;
+}
+
+
const Geometry::Class_info *Gis_polygon::get_class_info() const
{
return &polygon_class;
@@ -1050,7 +1283,7 @@ bool Gis_multi_point::init_from_wkt(Gis_read_stream *trs, String *wkb)
for (;;)
{
- if (wkb->reserve(1+4, 512))
+ if (wkb->reserve(1 + 4, 512))
return 1;
wkb->q_append((char) wkb_ndr);
wkb->q_append((uint32) wkb_point);
@@ -1065,6 +1298,32 @@ bool Gis_multi_point::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
+uint Gis_multi_point::init_from_opresult(String *bin,
+ const char *opres, uint res_len)
+{
+ uint bin_size, n_points;
+ Gis_point p;
+ const char *opres_end;
+
+ n_points= res_len/(4+8*2);
+ bin_size= n_points * (WKB_HEADER_SIZE + POINT_DATA_SIZE) + 4;
+
+ if (bin->reserve(bin_size, 512))
+ return 0;
+
+ bin->q_append(n_points);
+ opres_end= opres + res_len;
+ for (; opres < opres_end; opres+= (4 + 8*2))
+ {
+ bin->q_append((char)wkb_ndr);
+ bin->q_append((uint32)wkb_point);
+ if (!p.init_from_wkb(opres + 4, POINT_DATA_SIZE, wkb_ndr, bin))
+ return 0;
+ }
+ return res_len;
+}
+
+
uint Gis_multi_point::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo,
String *res)
{
@@ -1103,7 +1362,7 @@ bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end) const
n_points= uint4korr(m_data);
if (no_data(m_data+4,
- n_points * (SIZEOF_STORED_DOUBLE * 2 + WKB_HEADER_SIZE)) ||
+ n_points * (POINT_DATA_SIZE + WKB_HEADER_SIZE)) ||
txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
return 1;
*end= append_points(txt, n_points, m_data+4, WKB_HEADER_SIZE);
@@ -1144,6 +1403,35 @@ int Gis_multi_point::geometry_n(uint32 num, String *result) const
return 0;
}
+
+int Gis_multi_point::store_shapes(Gcalc_shape_transporter *trn) const
+{
+ uint32 n_points;
+ Gis_point pt;
+ const char *data= m_data;
+
+ if (no_data(data, 4))
+ return 1;
+ n_points= uint4korr(data);
+ data+= 4;
+
+ if (trn->start_collection(n_points))
+ return 1;
+
+ while (n_points--)
+ {
+ if (no_data(data, WKB_HEADER_SIZE))
+ return 1;
+ data+= WKB_HEADER_SIZE;
+ pt.set_data_ptr(data, (uint32) (m_data_end - data));
+ if (pt.store_shapes(trn))
+ return 1;
+ data+= pt.get_data_size();
+ }
+ return 0;
+}
+
+
const Geometry::Class_info *Gis_multi_point::get_class_info() const
{
return &multipoint_class;
@@ -1186,10 +1474,9 @@ bool Gis_multi_line_string::init_from_wkt(Gis_read_stream *trs, String *wkb)
{
Gis_line_string ls;
- if (wkb->reserve(1+4, 512))
+ if (wkb->reserve(1 + 4, 512))
return 1;
- wkb->q_append((char) wkb_ndr);
- wkb->q_append((uint32) wkb_linestring);
+ wkb->q_append((char) wkb_ndr); wkb->q_append((uint32) wkb_linestring);
if (trs->check_next_symbol('(') ||
ls.init_from_wkt(trs, wkb) ||
@@ -1204,15 +1491,48 @@ bool Gis_multi_line_string::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
+uint Gis_multi_line_string::init_from_opresult(String *bin,
+ const char *opres, uint res_len)
+{
+ const char *opres_orig= opres;
+ int ns_pos= bin->length();
+ uint n_linestring= 0;
+
+ if (bin->reserve(4, 512))
+ return 0;
+ bin->q_append(n_linestring);
+
+ while (res_len)
+ {
+ Gis_line_string ls;
+ int ls_len;
+
+ if (bin->reserve(WKB_HEADER_SIZE, 512))
+ return 0;
+
+ bin->q_append((char) wkb_ndr);
+ bin->q_append((uint32) wkb_linestring);
+
+ if (!(ls_len= ls.init_from_opresult(bin, opres, res_len)))
+ return 0;
+ opres+= ls_len;
+ res_len-= ls_len;
+ n_linestring++;
+ }
+ bin->write_at_position(ns_pos, n_linestring);
+ return (uint) (opres - opres_orig);
+}
+
+
uint Gis_multi_line_string::init_from_wkb(const char *wkb, uint len,
wkbByteOrder bo, String *res)
{
uint32 n_line_strings;
const char *wkb_orig= wkb;
- if (len < 4)
+ if (len < 4 ||
+ (n_line_strings= wkb_get_uint(wkb, bo))< 1)
return 0;
- n_line_strings= wkb_get_uint(wkb, bo);
if (res->reserve(4, 512))
return 0;
@@ -1260,7 +1580,7 @@ bool Gis_multi_line_string::get_data_as_wkt(String *txt,
return 1;
n_points= uint4korr(data + WKB_HEADER_SIZE);
data+= WKB_HEADER_SIZE + 4;
- if (no_data(data, n_points * (SIZEOF_STORED_DOUBLE*2)) ||
+ if (no_data(data, n_points * POINT_DATA_SIZE) ||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
return 1;
txt->qs_append('(');
@@ -1331,10 +1651,11 @@ int Gis_multi_line_string::geometry_n(uint32 num, String *result) const
}
-int Gis_multi_line_string::geom_length(double *len) const
+int Gis_multi_line_string::geom_length(double *len, const char **end) const
{
uint32 n_line_strings;
const char *data= m_data;
+ const char *line_end;
if (no_data(data, 4))
return 1;
@@ -1348,7 +1669,7 @@ int Gis_multi_line_string::geom_length(double *len) const
Gis_line_string ls;
data+= WKB_HEADER_SIZE;
ls.set_data_ptr(data, (uint32) (m_data_end - data));
- if (ls.geom_length(&ls_len))
+ if (ls.geom_length(&ls_len, &line_end))
return 1;
*len+= ls_len;
/*
@@ -1357,6 +1678,7 @@ int Gis_multi_line_string::geom_length(double *len) const
*/
data+= ls.get_data_size();
}
+ *end= data;
return 0;
}
@@ -1390,6 +1712,35 @@ int Gis_multi_line_string::is_closed(int *closed) const
return 0;
}
+
+int Gis_multi_line_string::store_shapes(Gcalc_shape_transporter *trn) const
+{
+ uint32 n_lines;
+ Gis_line_string ls;
+ const char *data= m_data;
+
+ if (no_data(data, 4))
+ return 1;
+ n_lines= uint4korr(data);
+ data+= 4;
+
+ if (trn->start_collection(n_lines))
+ return 1;
+
+ while (n_lines--)
+ {
+ if (no_data(data, WKB_HEADER_SIZE))
+ return 1;
+ data+= WKB_HEADER_SIZE;
+ ls.set_data_ptr(data, (uint32) (m_data_end - data));
+ if (ls.store_shapes(trn))
+ return 1;
+ data+= ls.get_data_size();
+ }
+ return 0;
+}
+
+
const Geometry::Class_info *Gis_multi_line_string::get_class_info() const
{
return &multilinestring_class;
@@ -1440,7 +1791,7 @@ bool Gis_multi_polygon::init_from_wkt(Gis_read_stream *trs, String *wkb)
for (;;)
{
- if (wkb->reserve(1+4, 512))
+ if (wkb->reserve(1 + 4, 512))
return 1;
wkb->q_append((char) wkb_ndr);
wkb->q_append((uint32) wkb_polygon);
@@ -1495,6 +1846,36 @@ uint Gis_multi_polygon::init_from_wkb(const char *wkb, uint len,
}
+uint Gis_multi_polygon::init_from_opresult(String *bin,
+ const char *opres, uint res_len)
+{
+ Gis_polygon p;
+ const char *opres_orig= opres;
+ uint p_len;
+ uint32 n_poly= 0;
+ uint32 np_pos= bin->length();
+
+ if (bin->reserve(4, 512))
+ return 0;
+
+ bin->q_append(n_poly);
+ while (res_len)
+ {
+ if (bin->reserve(1 + 4, 512))
+ return 0;
+ bin->q_append((char)wkb_ndr);
+ bin->q_append((uint32)wkb_polygon);
+ if (!(p_len= p.init_from_opresult(bin, opres, res_len)))
+ return 0;
+ opres+= p_len;
+ res_len-= p_len;
+ n_poly++;
+ }
+ bin->write_at_position(np_pos, n_poly);
+ return opres - opres_orig;
+}
+
+
bool Gis_multi_polygon::get_data_as_wkt(String *txt, const char **end) const
{
uint32 n_polygons;
@@ -1521,7 +1902,7 @@ bool Gis_multi_polygon::get_data_as_wkt(String *txt, const char **end) const
return 1;
uint32 n_points= uint4korr(data);
data+= 4;
- if (no_data(data, (SIZEOF_STORED_DOUBLE * 2) * n_points) ||
+ if (no_data(data, POINT_DATA_SIZE * n_points) ||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points,
512))
return 1;
@@ -1682,6 +2063,35 @@ int Gis_multi_polygon::centroid(String *result) const
return create_point(result, res_cx, res_cy);
}
+
+int Gis_multi_polygon::store_shapes(Gcalc_shape_transporter *trn) const
+{
+ uint32 n_polygons;
+ Gis_polygon p;
+ const char *data= m_data;
+
+ if (no_data(data, 4))
+ return 1;
+ n_polygons= uint4korr(data);
+ data+= 4;
+
+ if (trn->start_collection(n_polygons))
+ return 1;
+
+ while (n_polygons--)
+ {
+ if (no_data(data, WKB_HEADER_SIZE))
+ return 1;
+ data+= WKB_HEADER_SIZE;
+ p.set_data_ptr(data, (uint32) (m_data_end - data));
+ if (p.store_shapes(trn))
+ return 1;
+ data+= p.get_data_size();
+ }
+ return 0;
+}
+
+
const Geometry::Class_info *Gis_multi_polygon::get_class_info() const
{
return &multipolygon_class;
@@ -1728,24 +2138,41 @@ bool Gis_geometry_collection::init_from_wkt(Gis_read_stream *trs, String *wkb)
uint32 no_pos= wkb->length();
Geometry_buffer buffer;
Geometry *g;
+ char next_sym;
if (wkb->reserve(4, 512))
return 1;
wkb->length(wkb->length()+4); // Reserve space for points
- for (;;)
+ if (!(next_sym= trs->next_symbol()))
+ return 1;
+
+ if (next_sym != ')')
{
- if (!(g= create_from_wkt(&buffer, trs, wkb)))
+ LEX_STRING next_word;
+ if (trs->lookup_next_word(&next_word))
return 1;
- if (g->get_class_info()->m_type_id == wkb_geometrycollection)
+ if (next_word.length != 5 ||
+ (my_strnncoll(&my_charset_latin1,
+ (const uchar*) "empty", 5,
+ (const uchar*) next_word.str, 5) != 0))
{
- trs->set_error_msg("Unexpected GEOMETRYCOLLECTION");
- return 1;
+ for (;;)
+ {
+ if (!(g= create_from_wkt(&buffer, trs, wkb)))
+ return 1;
+
+ if (g->get_class_info()->m_type_id == wkb_geometrycollection)
+ {
+ trs->set_error_msg("Unexpected GEOMETRYCOLLECTION");
+ return 1;
+ }
+ n_objects++;
+ if (trs->skip_char(',')) // Didn't find ','
+ break;
+ }
}
- n_objects++;
- if (trs->skip_char(',')) // Didn't find ','
- break;
}
wkb->write_at_position(no_pos, n_objects);
@@ -1753,6 +2180,50 @@ bool Gis_geometry_collection::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
+uint Gis_geometry_collection::init_from_opresult(String *bin,
+ const char *opres,
+ uint res_len)
+{
+ const char *opres_orig= opres;
+ Geometry_buffer buffer;
+ Geometry *geom;
+ int g_len;
+ uint32 wkb_type;
+ int no_pos= bin->length();
+ uint32 n_objects= 0;
+
+ if (bin->reserve(4, 512))
+ return 0;
+ bin->q_append(n_objects);
+
+ while (res_len)
+ {
+ switch ((Gcalc_function::shape_type) uint4korr(opres))
+ {
+ case Gcalc_function::shape_point: wkb_type= wkb_point; break;
+ case Gcalc_function::shape_line: wkb_type= wkb_linestring; break;
+ case Gcalc_function::shape_polygon: wkb_type= wkb_polygon; break;
+ default: wkb_type= 0; DBUG_ASSERT(FALSE);
+ };
+
+ if (bin->reserve(WKB_HEADER_SIZE, 512))
+ return 0;
+
+ bin->q_append((char) wkb_ndr);
+ bin->q_append(wkb_type);
+
+ if (!(geom= create_by_typeid(&buffer, wkb_type)) ||
+ !(g_len= geom->init_from_opresult(bin, opres, res_len)))
+ return 0;
+ opres+= g_len;
+ res_len-= g_len;
+ n_objects++;
+ }
+ bin->write_at_position(no_pos, n_objects);
+ return (uint) (opres - opres_orig);
+}
+
+
uint Gis_geometry_collection::init_from_wkb(const char *wkb, uint len,
wkbByteOrder bo, String *res)
{
@@ -1808,6 +2279,13 @@ bool Gis_geometry_collection::get_data_as_wkt(String *txt,
n_objects= uint4korr(data);
data+= 4;
+ if (n_objects == 0)
+ {
+ txt->append(STRING_WITH_LEN(" EMPTY"), 512);
+ goto exit;
+ }
+
+ txt->qs_append('(');
while (n_objects--)
{
uint32 wkb_type;
@@ -1822,10 +2300,11 @@ bool Gis_geometry_collection::get_data_as_wkt(String *txt,
geom->set_data_ptr(data, (uint) (m_data_end - data));
if (geom->as_wkt(txt, &data))
return 1;
- if (txt->append(STRING_WITH_LEN(","), 512))
+ if (n_objects && txt->append(STRING_WITH_LEN(","), 512))
return 1;
}
- txt->length(txt->length() - 1);
+ txt->qs_append(')');
+exit:
*end= data;
return 0;
}
@@ -1842,6 +2321,8 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
return 1;
n_objects= uint4korr(data);
data+= 4;
+ if (n_objects == 0)
+ return 1;
while (n_objects--)
{
@@ -1863,6 +2344,82 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
}
+int Gis_geometry_collection::area(double *ar, const char **end) const
+{
+ uint32 n_objects;
+ const char *data= m_data;
+ Geometry_buffer buffer;
+ Geometry *geom;
+ double result;
+
+ if (no_data(data, 4))
+ return 1;
+ n_objects= uint4korr(data);
+ data+= 4;
+ if (n_objects == 0)
+ return 1;
+
+ result= 0.0;
+ while (n_objects--)
+ {
+ uint32 wkb_type;
+
+ if (no_data(data, WKB_HEADER_SIZE))
+ return 1;
+ wkb_type= uint4korr(data + 1);
+ data+= WKB_HEADER_SIZE;
+
+ if (!(geom= create_by_typeid(&buffer, wkb_type)))
+ return 1;
+ geom->set_data_ptr(data, (uint32) (m_data_end - data));
+ if (geom->area(ar, &data))
+ return 1;
+ result+= *ar;
+ }
+ *end= data;
+ *ar= result;
+ return 0;
+}
+
+
+int Gis_geometry_collection::geom_length(double *len, const char **end) const
+{
+ uint32 n_objects;
+ const char *data= m_data;
+ Geometry_buffer buffer;
+ Geometry *geom;
+ double result;
+
+ if (no_data(data, 4))
+ return 1;
+ n_objects= uint4korr(data);
+ data+= 4;
+ if (n_objects == 0)
+ return 1;
+
+ result= 0.0;
+ while (n_objects--)
+ {
+ uint32 wkb_type;
+
+ if (no_data(data, WKB_HEADER_SIZE))
+ return 1;
+ wkb_type= uint4korr(data + 1);
+ data+= WKB_HEADER_SIZE;
+
+ if (!(geom= create_by_typeid(&buffer, wkb_type)))
+ return 1;
+ geom->set_data_ptr(data, (uint32) (m_data_end - data));
+ if (geom->geom_length(len, &data))
+ return 1;
+ result+= *len;
+ }
+ *end= data;
+ *len= result;
+ return 0;
+}
+
+
int Gis_geometry_collection::num_geometries(uint32 *num) const
{
if (no_data(m_data, 4))
@@ -1902,7 +2459,7 @@ int Gis_geometry_collection::geometry_n(uint32 num, String *result) const
} while (--num);
/* Copy found object to result */
- if (result->reserve(1+4+length))
+ if (result->reserve(1 + 4 + length))
return 1;
result->q_append((char) wkb_ndr);
result->q_append((uint32) wkb_type);
@@ -1963,6 +2520,48 @@ bool Gis_geometry_collection::dimension(uint32 *res_dim, const char **end) const
return 0;
}
+
+int Gis_geometry_collection::store_shapes(Gcalc_shape_transporter *trn) const
+{
+ uint32 n_objects;
+ const char *data= m_data;
+ Geometry_buffer buffer;
+ Geometry *geom;
+
+ if (no_data(data, 4))
+ return 1;
+ n_objects= uint4korr(data);
+ data+= 4;
+
+ if (!n_objects)
+ {
+ trn->empty_shape();
+ return 0;
+ }
+
+ if (trn->start_collection(n_objects))
+ return 1;
+
+ while (n_objects--)
+ {
+ uint32 wkb_type;
+
+ if (no_data(data, WKB_HEADER_SIZE))
+ return 1;
+ wkb_type= uint4korr(data + 1);
+ data+= WKB_HEADER_SIZE;
+ if (!(geom= create_by_typeid(&buffer, wkb_type)))
+ return 1;
+ geom->set_data_ptr(data, (uint32) (m_data_end - data));
+ if (geom->store_shapes(trn))
+ return 1;
+
+ data+= geom->get_data_size();
+ }
+ return 0;
+}
+
+
const Geometry::Class_info *Gis_geometry_collection::get_class_info() const
{
return &geometrycollection_class;
diff --git a/sql/spatial.h b/sql/spatial.h
index 20b3856ca9a..6850cc804d0 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -18,8 +18,13 @@
#ifndef _spatial_h
#define _spatial_h
+#include "sql_string.h" /* String, LEX_STRING */
+#include <my_compiler.h>
+
#ifdef HAVE_SPATIAL
+#include "gcalc_tools.h"
+
const uint SRID_SIZE= 4;
const uint SIZEOF_STORED_DOUBLE= 8;
const uint POINT_DATA_SIZE= SIZEOF_STORED_DOUBLE*2;
@@ -95,6 +100,13 @@ struct MBR
if (mbr->ymax > ymax)
ymax= mbr->ymax;
}
+ void buffer(double d)
+ {
+ xmin-= d;
+ ymin-= d;
+ xmax+= d;
+ ymax+= d;
+ }
int equals(const MBR *mbr)
{
@@ -244,16 +256,19 @@ public:
virtual const Class_info *get_class_info() const=0;
virtual uint32 get_data_size() const=0;
virtual bool init_from_wkt(Gis_read_stream *trs, String *wkb)=0;
-
/* returns the length of the wkb that was read */
virtual uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo,
String *res)=0;
+ virtual uint init_from_opresult(String *bin,
+ const char *opres, uint res_len)
+ { return init_from_wkb(opres + 4, UINT_MAX32, wkb_ndr, bin) + 4; }
+
virtual bool get_data_as_wkt(String *txt, const char **end) const=0;
virtual bool get_mbr(MBR *mbr, const char **end) const=0;
virtual bool dimension(uint32 *dim, const char **end) const=0;
virtual int get_x(double *x) const { return -1; }
virtual int get_y(double *y) const { return -1; }
- virtual int geom_length(double *len) const { return -1; }
+ virtual int geom_length(double *len, const char **end) const { return -1; }
virtual int area(double *ar, const char **end) const { return -1;}
virtual int is_closed(int *closed) const { return -1; }
virtual int num_interior_ring(uint32 *n_int_rings) const { return -1; }
@@ -266,28 +281,21 @@ public:
virtual int point_n(uint32 num, String *result) const { return -1; }
virtual int interior_ring_n(uint32 num, String *result) const { return -1; }
virtual int geometry_n(uint32 num, String *result) const { return -1; }
+ virtual int store_shapes(Gcalc_shape_transporter *trn) const=0;
public:
static Geometry *create_by_typeid(Geometry_buffer *buffer, int type_id);
+
static Geometry *construct(Geometry_buffer *buffer,
const char *data, uint32 data_len);
static Geometry *create_from_wkt(Geometry_buffer *buffer,
Gis_read_stream *trs, String *wkt,
bool init_stream=1);
- static Geometry *create_from_wkb(Geometry_buffer *buffer, const char *wkb,
- uint32 len, String *res);
- int as_wkt(String *wkt, const char **end)
- {
- uint32 len= (uint) get_class_info()->m_name.length;
- if (wkt->reserve(len + 2, 512))
- return 1;
- wkt->qs_append(get_class_info()->m_name.str, len);
- wkt->qs_append('(');
- if (get_data_as_wkt(wkt, end))
- return 1;
- wkt->qs_append(')');
- return 0;
- }
+ static Geometry *create_from_wkb(Geometry_buffer *buffer,
+ const char *wkb, uint32 len, String *res);
+ static int create_from_opresult(Geometry_buffer *g_buf,
+ String *res, Gcalc_result_receiver &rr);
+ int as_wkt(String *wkt, const char **end);
inline void set_data_ptr(const char *data, uint32 data_len)
{
@@ -365,12 +373,15 @@ public:
return 0;
}
+ int geom_length(double *len, const char **end) const;
+ int area(double *ar, const char **end) const;
bool dimension(uint32 *dim, const char **end) const
{
*dim= 0;
*end= 0; /* No default end */
return 0;
}
+ int store_shapes(Gcalc_shape_transporter *trn) const;
const Class_info *get_class_info() const;
};
@@ -391,7 +402,8 @@ public:
uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);
bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const;
- int geom_length(double *len) const;
+ int geom_length(double *len, const char **end) const;
+ int area(double *ar, const char **end) const;
int is_closed(int *closed) const;
int num_points(uint32 *n_points) const;
int start_point(String *point) const;
@@ -403,6 +415,7 @@ public:
*end= 0; /* No default end */
return 0;
}
+ int store_shapes(Gcalc_shape_transporter *trn) const;
const Class_info *get_class_info() const;
};
@@ -417,6 +430,7 @@ public:
uint32 get_data_size() const;
bool init_from_wkt(Gis_read_stream *trs, String *wkb);
uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);
+ uint init_from_opresult(String *bin, const char *opres, uint res_len);
bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const;
int area(double *ar, const char **end) const;
@@ -431,6 +445,7 @@ public:
*end= 0; /* No default end */
return 0;
}
+ int store_shapes(Gcalc_shape_transporter *trn) const;
const Class_info *get_class_info() const;
};
@@ -449,6 +464,7 @@ public:
uint32 get_data_size() const;
bool init_from_wkt(Gis_read_stream *trs, String *wkb);
uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);
+ uint init_from_opresult(String *bin, const char *opres, uint res_len);
bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const;
int num_geometries(uint32 *num) const;
@@ -459,6 +475,7 @@ public:
*end= 0; /* No default end */
return 0;
}
+ int store_shapes(Gcalc_shape_transporter *trn) const;
const Class_info *get_class_info() const;
};
@@ -473,11 +490,12 @@ public:
uint32 get_data_size() const;
bool init_from_wkt(Gis_read_stream *trs, String *wkb);
uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);
+ uint init_from_opresult(String *bin, const char *opres, uint res_len);
bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const;
int num_geometries(uint32 *num) const;
int geometry_n(uint32 num, String *result) const;
- int geom_length(double *len) const;
+ int geom_length(double *len, const char **end) const;
int is_closed(int *closed) const;
bool dimension(uint32 *dim, const char **end) const
{
@@ -485,6 +503,7 @@ public:
*end= 0; /* No default end */
return 0;
}
+ int store_shapes(Gcalc_shape_transporter *trn) const;
const Class_info *get_class_info() const;
};
@@ -511,7 +530,9 @@ public:
*end= 0; /* No default end */
return 0;
}
+ int store_shapes(Gcalc_shape_transporter *trn) const;
const Class_info *get_class_info() const;
+ uint init_from_opresult(String *bin, const char *opres, uint res_len);
};
@@ -525,11 +546,15 @@ public:
uint32 get_data_size() const;
bool init_from_wkt(Gis_read_stream *trs, String *wkb);
uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);
+ uint init_from_opresult(String *bin, const char *opres, uint res_len);
bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const;
+ int area(double *ar, const char **end) const;
+ int geom_length(double *len, const char **end) const;
int num_geometries(uint32 *num) const;
int geometry_n(uint32 num, String *result) const;
bool dimension(uint32 *dim, const char **end) const;
+ int store_shapes(Gcalc_shape_transporter *trn) const;
const Class_info *get_class_info() const;
};
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 29922aa5321..31af9f1c137 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -2116,7 +2116,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
table->field[next_field+2]->store((longlong) mqh.conn_per_hour, TRUE);
if (table->s->fields >= 36 &&
(mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS))
- table->field[next_field+3]->store((longlong) mqh.user_conn, TRUE);
+ table->field[next_field+3]->store((longlong) mqh.user_conn, FALSE);
mqh_used= mqh_used || mqh.questions || mqh.updates || mqh.conn_per_hour;
next_field+=4;
@@ -3093,7 +3093,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
class LEX_COLUMN *column;
List_iterator <LEX_COLUMN> column_iter(columns);
- if (open_and_lock_tables(thd, table_list))
+ if (open_and_lock_tables(thd, table_list) ||
+ mysql_handle_derived(thd->lex, DT_PREPARE))
DBUG_RETURN(TRUE);
while ((column = column_iter++))
@@ -4623,7 +4624,8 @@ ulong get_column_grant(THD *thd, GRANT_INFO *grant,
/* Help function for mysql_show_grants */
-static void add_user_option(String *grant, ulong value, const char *name)
+static void add_user_option(String *grant, long value, const char *name,
+ my_bool is_signed)
{
if (value)
{
@@ -4631,7 +4633,7 @@ static void add_user_option(String *grant, ulong value, const char *name)
grant->append(' ');
grant->append(name, strlen(name));
grant->append(' ');
- p=int10_to_str(value, buff, 10);
+ p=int10_to_str(value, buff, is_signed ? -10 : 10);
grant->append(buff,p-buff);
}
}
@@ -4813,13 +4815,13 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (want_access & GRANT_ACL)
global.append(STRING_WITH_LEN(" GRANT OPTION"));
add_user_option(&global, acl_user->user_resource.questions,
- "MAX_QUERIES_PER_HOUR");
+ "MAX_QUERIES_PER_HOUR", 0);
add_user_option(&global, acl_user->user_resource.updates,
- "MAX_UPDATES_PER_HOUR");
+ "MAX_UPDATES_PER_HOUR", 0);
add_user_option(&global, acl_user->user_resource.conn_per_hour,
- "MAX_CONNECTIONS_PER_HOUR");
+ "MAX_CONNECTIONS_PER_HOUR", 0);
add_user_option(&global, acl_user->user_resource.user_conn,
- "MAX_USER_CONNECTIONS");
+ "MAX_USER_CONNECTIONS", 1);
}
protocol->prepare_for_resend();
protocol->store(global.ptr(),global.length(),global.charset());
@@ -7543,7 +7545,6 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
THD *thd= mpvio->thd;
NET *net= &thd->net;
char *end;
-
DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE);
if (pkt_len < MIN_HANDSHAKE_SIZE)
@@ -8242,10 +8243,16 @@ bool acl_authenticate(THD *thd, uint connect_errors,
DBUG_RETURN(1);
}
- /* Don't allow the user to connect if he has done too many queries */
- if ((acl_user->user_resource.questions || acl_user->user_resource.updates ||
+ /*
+ Don't allow the user to connect if he has done too many queries.
+ As we are testing max_user_connections == 0 here, it means that we
+ can't let the user change max_user_connections from 0 in the server
+ without a restart as it would lead to wrong connect counting.
+ */
+ if ((acl_user->user_resource.questions ||
+ acl_user->user_resource.updates ||
acl_user->user_resource.conn_per_hour ||
- acl_user->user_resource.user_conn || max_user_connections) &&
+ acl_user->user_resource.user_conn || max_user_connections_checking) &&
get_or_create_user_conn(thd,
(opt_old_style_user_limits ? sctx->user : sctx->priv_user),
(opt_old_style_user_limits ? sctx->host_or_ip : sctx->priv_host),
@@ -8258,7 +8265,7 @@ bool acl_authenticate(THD *thd, uint connect_errors,
if (thd->user_connect &&
(thd->user_connect->user_resources.conn_per_hour ||
thd->user_connect->user_resources.user_conn ||
- max_user_connections) &&
+ max_user_connections_checking) &&
check_for_max_user_connections(thd, thd->user_connect))
{
/* Ensure we don't decrement thd->user_connections->connections twice */
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 8a8ba1f18d5..50e00dfa041 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>
@@ -678,7 +679,7 @@ void close_handle_and_leave_table_as_lock(TABLE *table)
*/
if (table->child_l || table->parent)
detach_merge_children(table, FALSE);
- table->file->close();
+ table->file->ha_close();
table->db_stat= 0; // Mark file closed
release_table_share(table->s, RELEASE_NORMAL);
table->s= share;
@@ -857,8 +858,10 @@ void free_io_cache(TABLE *table)
and tables must be NULL.
*/
-bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
- bool wait_for_refresh, bool wait_for_placeholders)
+static bool int_close_cached_tables(THD *thd, TABLE_LIST *tables,
+ bool have_lock,
+ bool wait_for_refresh, bool wait_for_placeholders,
+ bool set_readonly_mode)
{
bool result=0;
DBUG_ENTER("close_cached_tables");
@@ -868,7 +871,10 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
VOID(pthread_mutex_lock(&LOCK_open));
if (!tables)
{
- refresh_version++; // Force close of open tables
+ /* No need to close the open tables if we just set the readonly state */
+ if (!set_readonly_mode)
+ refresh_version++; // Force close of open tables
+
while (unused_tables)
{
#ifdef EXTRA_DEBUG
@@ -928,7 +934,16 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
for (uint idx=0 ; idx < open_cache.records ; idx++)
{
TABLE *table=(TABLE*) hash_element(&open_cache,idx);
- if (table->in_use)
+ /*
+ We don't increment the refresh_version when set_readonly_mode,
+ but we still need non-transactional tables to be reopened.
+ So we set their versions as 'refresh_version - 1', which marks
+ them for the 'needs_reopen_or_table_lock()'
+ */
+ if (set_readonly_mode && !table->file->has_transactions())
+ table->s->version= 0;
+ if (table->in_use &&
+ (!set_readonly_mode || !table->file->has_transactions()))
table->in_use->some_tables_deleted= 1;
}
}
@@ -1033,6 +1048,20 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
}
+bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
+ bool wait_for_refresh, bool wait_for_placeholders)
+{
+ return int_close_cached_tables(thd, tables, have_lock, wait_for_refresh,
+ wait_for_placeholders, FALSE);
+}
+
+
+bool close_cached_tables_set_readonly(THD *thd)
+{
+ return int_close_cached_tables(thd, NULL, FALSE, TRUE, TRUE, TRUE);
+}
+
+
/*
Close all tables which match specified connection string or
if specified string is NULL, then any table with a connection string.
@@ -1386,10 +1415,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)
{
@@ -1702,11 +1731,12 @@ TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
t_name= table->table_name;
t_alias= table->alias;
+retry:
DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name));
- for (;;)
+ for (TABLE_LIST *tl= table_list;;)
{
- if (((! (res= find_table_in_global_list(table_list, d_name, t_name))) &&
- (! (res= mysql_lock_have_duplicate(thd, table, table_list)))) ||
+ if (((! (res= find_table_in_global_list(tl, d_name, t_name))) &&
+ (! (res= mysql_lock_have_duplicate(thd, table, tl)))) ||
((!res->table || res->table != table->table) &&
(!check_alias || !(lower_case_table_names ?
my_strcasecmp(files_charset_info, t_alias, res->alias) :
@@ -1719,10 +1749,23 @@ TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
processed in derived table or top select of multi-update/multi-delete
(exclude_from_table_unique_test) or prelocking placeholder.
*/
- table_list= res->next_global;
+ tl= res->next_global;
DBUG_PRINT("info",
("found same copy of table or table which we should skip"));
}
+ if (res && res->belong_to_derived)
+ {
+ /* Try to fix */
+ TABLE_LIST *derived= res->belong_to_derived;
+ if (derived->is_merged_derived())
+ {
+ DBUG_PRINT("info",
+ ("convert merged to materialization to resolve the conflict"));
+ derived->change_refs_to_fields();
+ derived->set_materialized_derived();
+ goto retry;
+ }
+ }
DBUG_RETURN(res);
}
@@ -2968,7 +3011,9 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
}
error= open_unireg_entry(thd, table, table_list, alias, key, key_length,
- mem_root, (flags & OPEN_VIEW_NO_PARSE));
+ mem_root,
+ (flags & (OPEN_VIEW_NO_PARSE |
+ MYSQL_LOCK_IGNORE_FLUSH)));
if (error > 0)
{
my_free((uchar*)table, MYF(0));
@@ -3037,6 +3082,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
*/
DBUG_ASSERT(table->file->pushed_cond == NULL);
table->reginfo.impossible_range= 0;
+ table->created= TRUE;
/* Catch wrong handling of the auto_increment_field_not_null. */
DBUG_ASSERT(!table->auto_increment_field_not_null);
table->auto_increment_field_not_null= FALSE;
@@ -3045,13 +3091,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);
}
@@ -3802,7 +3854,7 @@ TABLE *drop_locked_tables(THD *thd,const char *db, const char *table_name)
if (table->db_stat)
{
table->db_stat= 0;
- table->file->close();
+ table->file->ha_close();
}
}
else
@@ -4050,8 +4102,11 @@ retry:
HA_GET_INDEX | HA_TRY_READ_ONLY),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD |
(flags & OPEN_VIEW_NO_PARSE),
- thd->open_options, entry, table_list,
- mem_root);
+ thd->open_options |
+ (thd->version == 0 &&
+ (flags & MYSQL_LOCK_IGNORE_FLUSH) ?
+ HA_OPEN_FOR_STATUS : 0),
+ entry, table_list, mem_root);
if (error)
goto err;
/* TODO: Don't free this */
@@ -4089,7 +4144,11 @@ retry:
HA_TRY_READ_ONLY),
(READ_KEYINFO | COMPUTE_TYPES |
EXTRA_RECORD),
- thd->open_options, entry, FALSE)))
+ thd->open_options |
+ (thd->version == 0 &&
+ (flags & MYSQL_LOCK_IGNORE_FLUSH) ?
+ HA_OPEN_FOR_STATUS : 0),
+ entry, FALSE)))
{
if (error == 7) // Table def changed
{
@@ -4656,7 +4715,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
temporary mem_root for new .frm parsing.
TODO: variables for size
*/
- init_sql_alloc(&new_frm_mem, 8024, 8024);
+ init_sql_alloc(&new_frm_mem, 8024, 0);
thd->current_tablenr= 0;
restart:
@@ -5200,9 +5259,10 @@ int open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool derived)
close_tables_for_reopen(thd, &tables);
}
if (derived &&
- (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
- (thd->fill_derived_tables() &&
- mysql_handle_derived(thd->lex, &mysql_derived_filling))))
+ (mysql_handle_derived(thd->lex, DT_INIT)))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+ if (thd->prepare_derived_at_open && derived &&
+ (mysql_handle_derived(thd->lex, DT_PREPARE)))
DBUG_RETURN(TRUE); /* purecov: inspected */
DBUG_RETURN(0);
}
@@ -5218,6 +5278,7 @@ int open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool derived)
flags - bitmap of flags to modify how the tables will be open:
MYSQL_LOCK_IGNORE_FLUSH - open table even if someone has
done a flush on it.
+ dt_phases - set of flags to pass to the mysql_handle_derived
RETURN
FALSE - ok
@@ -5228,13 +5289,14 @@ int open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool derived)
data from the tables.
*/
-bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags)
+bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags,
+ uint dt_phases)
{
uint counter;
DBUG_ENTER("open_normal_and_derived_tables");
DBUG_ASSERT(!thd->fill_derived_tables());
if (open_tables(thd, &tables, &counter, flags) ||
- mysql_handle_derived(thd->lex, &mysql_derived_prepare))
+ mysql_handle_derived(thd->lex, dt_phases))
DBUG_RETURN(TRUE); /* purecov: inspected */
DBUG_RETURN(0);
}
@@ -5922,9 +5984,7 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
Field_iterator_view field_it;
field_it.set(table_list);
Query_arena *arena= 0, backup;
-
- DBUG_ASSERT(table_list->schema_table_reformed ||
- (ref != 0 && table_list->view != 0));
+
for (; !field_it.end_of_fields(); field_it.next())
{
if (!my_strcasecmp(system_charset_info, field_it.name(), name))
@@ -5943,6 +6003,8 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
if (!item)
DBUG_RETURN(0);
+ if (!ref)
+ DBUG_RETURN((Field*) view_ref_found);
/*
*ref != NULL means that *ref contains the item that we need to
replace. If the item was aliased by the user, set the alias to
@@ -5951,10 +6013,22 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
*/
if (*ref && !(*ref)->is_autogenerated_name)
{
- item->set_name((*ref)->name, (*ref)->name_length,
- system_charset_info);
- item->real_item()->set_name((*ref)->name, (*ref)->name_length,
- system_charset_info);
+ if (register_tree_change)
+ {
+ item->set_name_for_rollback(thd, (*ref)->name,
+ (*ref)->name_length,
+ system_charset_info);
+ item->real_item()->set_name_for_rollback(thd, (*ref)->name,
+ (*ref)->name_length,
+ system_charset_info);
+ }
+ else
+ {
+ item->set_name((*ref)->name, (*ref)->name_length,
+ system_charset_info);
+ item->real_item()->set_name((*ref)->name, (*ref)->name_length,
+ system_charset_info);
+ }
}
if (register_tree_change)
thd->change_item_tree(ref, item);
@@ -6347,6 +6421,8 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
Field *field_to_set= NULL;
if (fld == view_ref_found)
{
+ if (!ref)
+ DBUG_RETURN(fld);
Item *it= (*ref)->real_item();
if (it->type() == Item::FIELD_ITEM)
field_to_set= ((Item_field*)it)->field;
@@ -6354,6 +6430,8 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
{
if (thd->mark_used_columns == MARK_COLUMNS_READ)
it->walk(&Item::register_field_in_read_map, 1, (uchar *) 0);
+ else
+ it->walk(&Item::register_field_in_write_map, 1, (uchar *) 0);
}
}
else
@@ -6493,8 +6571,11 @@ find_field_in_tables(THD *thd, Item_ident *item,
find_field_in_table even in the case of information schema tables
when table_ref->field_translation != NULL.
*/
- if (table_ref->table && !table_ref->view)
+ if (table_ref->table && !table_ref->view &&
+ (!table_ref->is_merged_derived() ||
+ (!table_ref->is_multitable() && table_ref->merged_for_insert)))
{
+
found= find_field_in_table(thd, table_ref->table, name, length,
TRUE, &(item->cached_field_index));
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -6519,21 +6600,40 @@ find_field_in_tables(THD *thd, Item_ident *item,
Only views fields should be marked as dependent, not an underlying
fields.
*/
- if (!table_ref->belong_to_view)
+ if (!table_ref->belong_to_view &&
+ !table_ref->belong_to_derived)
{
SELECT_LEX *current_sel= thd->lex->current_select;
SELECT_LEX *last_select= table_ref->select_lex;
+ bool all_merged= TRUE;
+ for (SELECT_LEX *sl= current_sel; sl && sl!=last_select;
+ sl=sl->outer_select())
+ {
+ Item *subs= sl->master_unit()->item;
+ if (subs->type() == Item::SUBSELECT_ITEM &&
+ ((Item_subselect*)subs)->substype() == Item_subselect::IN_SUBS &&
+ ((Item_in_subselect*)subs)->test_strategy(SUBS_SEMI_JOIN))
+ {
+ continue;
+ }
+ all_merged= FALSE;
+ break;
+ }
/*
If the field was an outer referencee, mark all selects using this
sub query as dependent on the outer query
*/
- if (current_sel != last_select)
+ if (!all_merged && current_sel != last_select)
+ {
mark_select_range_as_dependent(thd, last_select, current_sel,
found, *ref, item);
+ }
}
return found;
}
}
+ else
+ item->can_be_depended= TRUE;
if (db && lower_case_table_names)
{
@@ -7105,6 +7205,10 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
*/
if (nj_col_2 && (!using_fields ||is_using_column_1))
{
+ /*
+ Create non-fixed fully qualified field and let fix_fields to
+ resolve it.
+ */
Item *item_1= nj_col_1->create_item(thd);
Item *item_2= nj_col_2->create_item(thd);
Field *field_1= nj_col_1->field();
@@ -7204,6 +7308,14 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
*/
result= FALSE;
+ /*
+ Save the lists made during natural join matching (because
+ the matching done only once but we need the list in case
+ of prepared statements).
+ */
+ table_ref_1->persistent_used_items= table_ref_1->used_items;
+ table_ref_2->persistent_used_items= table_ref_2->used_items;
+
err:
if (arena)
thd->restore_active_arena(arena, &backup);
@@ -7558,7 +7670,11 @@ static bool setup_natural_join_row_types(THD *thd,
for (left_neighbor= table_ref_it++; left_neighbor ; )
{
table_ref= left_neighbor;
- left_neighbor= table_ref_it++;
+ do
+ {
+ left_neighbor= table_ref_it++;
+ }
+ while (left_neighbor && left_neighbor->sj_subq_pred);
/*
Do not redo work if already done:
1) for stored procedures,
@@ -7602,13 +7718,11 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
List<Item> *sum_func_list,
uint wild_num)
{
- if (!wild_num)
- return(0);
-
Item *item;
List_iterator<Item> it(fields);
Query_arena *arena, backup;
DBUG_ENTER("setup_wild");
+ DBUG_ASSERT(wild_num != 0);
/*
Don't use arena if we are not in prepared statements or stored procedures
@@ -7697,6 +7811,7 @@ bool setup_fields(THD *thd, Item **ref_pointer_array,
List_iterator<Item> it(fields);
bool save_is_item_list_lookup;
DBUG_ENTER("setup_fields");
+ DBUG_PRINT("enter", ("ref_pointer_array: %p", ref_pointer_array));
thd->mark_used_columns= mark_used_columns;
DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
@@ -7774,27 +7889,36 @@ bool setup_fields(THD *thd, Item **ref_pointer_array,
make_leaves_list()
list pointer to pointer on list first element
tables table list
+ full_table_list whether to include tables from mergeable derived table/view.
+ we need them for checks for INSERT/UPDATE statements only.
RETURN pointer on pointer to next_leaf of last element
*/
-TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
+void make_leaves_list(List<TABLE_LIST> &list, TABLE_LIST *tables,
+ bool full_table_list, TABLE_LIST *boundary)
+
{
for (TABLE_LIST *table= tables; table; table= table->next_local)
{
- if (table->merge_underlying_list)
+ if (table == boundary)
+ full_table_list= !full_table_list;
+ if (full_table_list && table->is_merged_derived())
{
- DBUG_ASSERT(table->view &&
- table->effective_algorithm == VIEW_ALGORITHM_MERGE);
- list= make_leaves_list(list, table->merge_underlying_list);
+ SELECT_LEX *select_lex= table->get_single_select();
+ /*
+ It's safe to use select_lex->leaf_tables because all derived
+ tables/views were already prepared and has their leaf_tables
+ set properly.
+ */
+ make_leaves_list(list, select_lex->get_table_list(),
+ full_table_list, boundary);
}
else
{
- *list= table;
- list= &table->next_leaf;
+ list.push_back(table);
}
}
- return list;
}
/*
@@ -7809,6 +7933,7 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
leaves List of join table leaves list (select_lex->leaf_tables)
refresh It is onle refresh for subquery
select_insert It is SELECT ... INSERT command
+ full_table_list a parameter to pass to the make_leaves_list function
NOTE
Check also that the 'used keys' and 'ignored keys' exists and set up the
@@ -7827,9 +7952,13 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
bool setup_tables(THD *thd, Name_resolution_context *context,
List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
- TABLE_LIST **leaves, bool select_insert)
+ List<TABLE_LIST> &leaves, bool select_insert,
+ bool full_table_list)
{
uint tablenr= 0;
+ List_iterator<TABLE_LIST> ti(leaves);
+ TABLE_LIST *table_list;
+
DBUG_ENTER("setup_tables");
DBUG_ASSERT ((select_insert && !tables->next_name_resolution_table) || !tables ||
@@ -7841,40 +7970,86 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
TABLE_LIST *first_select_table= (select_insert ?
tables->next_local:
0);
- if (!(*leaves))
- make_leaves_list(leaves, tables);
-
- TABLE_LIST *table_list;
- for (table_list= *leaves;
- table_list;
- table_list= table_list->next_leaf, tablenr++)
+ SELECT_LEX *select_lex= select_insert ? &thd->lex->select_lex :
+ thd->lex->current_select;
+ if (select_lex->first_cond_optimization)
{
- TABLE *table= table_list->table;
- table->pos_in_table_list= table_list;
- if (first_select_table &&
- table_list->top_table() == first_select_table)
+ leaves.empty();
+ if (!select_lex->is_prep_leaf_list_saved)
{
- /* new counting for SELECT of INSERT ... SELECT command */
- first_select_table= 0;
- tablenr= 0;
+ make_leaves_list(leaves, tables, full_table_list, first_select_table);
+ select_lex->leaf_tables_exec.empty();
}
- setup_table_map(table, table_list, tablenr);
- if (table_list->process_index_hints(table))
+ else
+ {
+ List_iterator_fast <TABLE_LIST> ti(select_lex->leaf_tables_prep);
+ while ((table_list= ti++))
+ leaves.push_back(table_list);
+ }
+
+ while ((table_list= ti++))
+ {
+ TABLE *table= table_list->table;
+ if (table)
+ table->pos_in_table_list= table_list;
+ if (first_select_table &&
+ table_list->top_table() == first_select_table)
+ {
+ /* new counting for SELECT of INSERT ... SELECT command */
+ first_select_table= 0;
+ thd->lex->select_lex.insert_tables= tablenr;
+ tablenr= 0;
+ }
+ if(table_list->jtbm_subselect)
+ {
+ table_list->jtbm_table_no= tablenr;
+ }
+ else if (table)
+ {
+ table->pos_in_table_list= table_list;
+ setup_table_map(table, table_list, tablenr);
+
+ if (table_list->process_index_hints(table))
+ DBUG_RETURN(1);
+ }
+ tablenr++;
+ }
+ if (tablenr > MAX_TABLES)
+ {
+ my_error(ER_TOO_MANY_TABLES,MYF(0), (int) MAX_TABLES);
DBUG_RETURN(1);
+ }
}
- if (tablenr > MAX_TABLES)
- {
- my_error(ER_TOO_MANY_TABLES, MYF(0), static_cast<int>(MAX_TABLES));
- DBUG_RETURN(1);
- }
+ else
+ {
+ List_iterator_fast <TABLE_LIST> ti(select_lex->leaf_tables_exec);
+ select_lex->leaf_tables.empty();
+ while ((table_list= ti++))
+ {
+ if(table_list->jtbm_subselect)
+ {
+ table_list->jtbm_table_no= table_list->tablenr_exec;
+ }
+ else
+ {
+ table_list->table->tablenr= table_list->tablenr_exec;
+ table_list->table->map= table_list->map_exec;
+ table_list->table->maybe_null= table_list->maybe_null_exec;
+ table_list->table->pos_in_table_list= table_list;
+ if (table_list->process_index_hints(table_list->table))
+ DBUG_RETURN(1);
+ }
+ select_lex->leaf_tables.push_back(table_list);
+ }
+ }
+
for (table_list= tables;
table_list;
table_list= table_list->next_local)
{
if (table_list->merge_underlying_list)
{
- DBUG_ASSERT(table_list->view &&
- table_list->effective_algorithm == VIEW_ALGORITHM_MERGE);
+ DBUG_ASSERT(table_list->is_merged_derived());
Query_arena *arena= thd->stmt_arena, backup;
bool res;
if (arena->is_conventional())
@@ -7887,6 +8062,17 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
if (res)
DBUG_RETURN(1);
}
+
+ if (table_list->jtbm_subselect)
+ {
+ Item *item= table_list->jtbm_subselect->optimizer;
+ if (table_list->jtbm_subselect->optimizer->fix_fields(thd, &item))
+ {
+ my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES); /* psergey-todo: WHY ER_TOO_MANY_TABLES ???*/
+ DBUG_RETURN(1);
+ }
+ DBUG_ASSERT(item == table_list->jtbm_subselect->optimizer);
+ }
}
/* Precompute and store the row types of NATURAL/USING joins. */
@@ -7901,7 +8087,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
prepare tables and check access for the view tables
SYNOPSIS
- setup_tables_and_check_view_access()
+ setup_tables_and_check_access()
thd Thread handler
context name resolution contest to setup table list there
from_clause Top-level list of table references in the FROM clause
@@ -7911,6 +8097,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
refresh It is onle refresh for subquery
select_insert It is SELECT ... INSERT command
want_access what access is needed
+ full_table_list a parameter to pass to the make_leaves_list function
NOTE
a wrapper for check_tables that will also check the resulting
@@ -7924,33 +8111,33 @@ bool setup_tables_and_check_access(THD *thd,
Name_resolution_context *context,
List<TABLE_LIST> *from_clause,
TABLE_LIST *tables,
- TABLE_LIST **leaves,
+ List<TABLE_LIST> &leaves,
bool select_insert,
ulong want_access_first,
- ulong want_access)
+ ulong want_access,
+ bool full_table_list)
{
- TABLE_LIST *leaves_tmp= NULL;
bool first_table= true;
+ DBUG_ENTER("setup_tables_and_check_access");
if (setup_tables(thd, context, from_clause, tables,
- &leaves_tmp, select_insert))
- return TRUE;
-
- if (leaves)
- *leaves= leaves_tmp;
+ leaves, select_insert, full_table_list))
+ DBUG_RETURN(TRUE);
- for (; leaves_tmp; leaves_tmp= leaves_tmp->next_leaf)
+ List_iterator<TABLE_LIST> ti(leaves);
+ TABLE_LIST *table_list;
+ while((table_list= ti++))
{
- if (leaves_tmp->belong_to_view &&
+ if (table_list->belong_to_view && !table_list->view &&
check_single_table_access(thd, first_table ? want_access_first :
- want_access, leaves_tmp, FALSE))
+ want_access, table_list, FALSE))
{
tables->hide_view_error(thd);
- return TRUE;
+ DBUG_RETURN(TRUE);
}
first_table= 0;
}
- return FALSE;
+ DBUG_RETURN(FALSE);
}
@@ -8086,8 +8273,10 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
information_schema table, or a nested table reference. See the comment
for TABLE_LIST.
*/
- if (!((table && !tables->view && (table->grant.privilege & SELECT_ACL)) ||
- (tables->view && (tables->grant.privilege & SELECT_ACL))) &&
+ if (!((table && tables->is_non_derived() &&
+ (table->grant.privilege & SELECT_ACL)) ||
+ ((!tables->is_non_derived() &&
+ (tables->grant.privilege & SELECT_ACL)))) &&
!any_privileges)
{
field_iterator.set(tables);
@@ -8117,7 +8306,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
if (!(item= field_iterator.create_item(thd)))
DBUG_RETURN(TRUE);
- DBUG_ASSERT(item->fixed);
+// DBUG_ASSERT(item->fixed);
/* cache the table for the Item_fields inserted by expanding stars */
if (item->type() == Item::FIELD_ITEM && tables->cacheable_table)
((Item_field *)item)->cached_table= tables;
@@ -8162,6 +8351,11 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
}
}
#endif
+ /*
+ field_iterator.create_item() builds used_items which we
+ have to save because changes made once and they are persistent
+ */
+ tables->persistent_used_items= tables->used_items;
if ((field= field_iterator.field()))
{
@@ -8229,6 +8423,29 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
}
+/**
+ Wrap Item_ident
+
+ @param thd thread handle
+ @param conds pointer to the condition which should be wrapped
+*/
+
+void wrap_ident(THD *thd, Item **conds)
+{
+ Item_direct_ref_to_ident *wrapper;
+ DBUG_ASSERT((*conds)->type() == Item::FIELD_ITEM || (*conds)->type() == Item::REF_ITEM);
+ Query_arena *arena= thd->stmt_arena, backup;
+ if (arena->is_conventional())
+ arena= 0;
+ else
+ thd->set_n_backup_active_arena(arena, &backup);
+ if ((wrapper= new Item_direct_ref_to_ident((Item_ident *)(*conds))))
+ (*conds)= (Item*) wrapper;
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+}
+
+
/*
Fix all conditions and outer join expressions.
@@ -8247,12 +8464,13 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
FALSE if all is OK
*/
-int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
+int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
COND **conds)
{
SELECT_LEX *select_lex= thd->lex->current_select;
Query_arena *arena= thd->stmt_arena, backup;
TABLE_LIST *table= NULL; // For HP compilers
+ List_iterator<TABLE_LIST> ti(leaves);
/*
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
@@ -8264,9 +8482,15 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
bool it_is_update= (select_lex == &thd->lex->select_lex) &&
thd->lex->which_check_option_applicable();
bool save_is_item_list_lookup= select_lex->is_item_list_lookup;
- select_lex->is_item_list_lookup= 0;
+ TABLE_LIST *derived= select_lex->master_unit()->derived;
DBUG_ENTER("setup_conds");
+ /* Do not fix conditions for the derived tables that have been merged */
+ if (derived && derived->merged)
+ DBUG_RETURN(0);
+
+ select_lex->is_item_list_lookup= 0;
+
if (select_lex->conds_processed_with_permanent_arena ||
arena->is_conventional())
arena= 0; // For easier test
@@ -8279,13 +8503,27 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
for (table= tables; table; table= table->next_local)
{
- if (table->prepare_where(thd, conds, FALSE))
+ if (select_lex == &thd->lex->select_lex &&
+ select_lex->first_cond_optimization &&
+ table->merged_for_insert &&
+ table->prepare_where(thd, conds, FALSE))
goto err_no_arena;
}
if (*conds)
{
thd->where="where clause";
+ DBUG_EXECUTE("where",
+ print_where(*conds,
+ "WHERE in setup_conds",
+ QT_ORDINARY););
+ /*
+ Wrap alone field in WHERE clause in case it will be outer field of subquery
+ which need persistent pointer on it, but conds could be changed by optimizer
+ */
+ if ((*conds)->type() == Item::FIELD_ITEM && !derived)
+ wrap_ident(thd, conds);
+ (*conds)->mark_as_condition_AND_part(NO_JOIN_NEST);
if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) ||
(*conds)->check_cols(1))
goto err_no_arena;
@@ -8295,7 +8533,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
Apply fix_fields() to all ON clauses at all levels of nesting,
including the ones inside view definitions.
*/
- for (table= leaves; table; table= table->next_leaf)
+ while ((table= ti++))
{
TABLE_LIST *embedded; /* The table at the current level of nesting. */
TABLE_LIST *embedding= table; /* The parent nested table reference. */
@@ -8306,12 +8544,24 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
{
/* Make a join an a expression */
thd->where="on clause";
+ embedded->on_expr->mark_as_condition_AND_part(embedded);
if ((!embedded->on_expr->fixed &&
embedded->on_expr->fix_fields(thd, &embedded->on_expr)) ||
embedded->on_expr->check_cols(1))
goto err_no_arena;
select_lex->cond_count++;
}
+ /*
+ If it's a semi-join nest, fix its "left expression", as it is used by
+ the SJ-Materialization
+ */
+ if (embedded->sj_subq_pred)
+ {
+ Item **left_expr= &embedded->sj_subq_pred->left_expr;
+ if (!(*left_expr)->fixed && (*left_expr)->fix_fields(thd, left_expr))
+ goto err_no_arena;
+ }
+
embedding= embedded->embedding;
}
while (embedding &&
@@ -8384,9 +8634,11 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
Item *value, *fld;
Item_field *field;
TABLE *table= 0, *vcol_table= 0;
- bool abort_on_warning_saved= thd->abort_on_warning;
+ bool save_abort_on_warning= thd->abort_on_warning;
+ bool save_no_errors= thd->no_errors;
DBUG_ENTER("fill_record");
+ thd->no_errors= ignore_errors;
/*
Reset the table->auto_increment_field_not_null as it is valid for
only one row.
@@ -8426,15 +8678,13 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
value->type() != Item::NULL_ITEM &&
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
{
- thd->abort_on_warning= FALSE;
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
rfield->field_name, table->s->table_name.str);
- thd->abort_on_warning= abort_on_warning_saved;
}
if ((!rfield->vcol_info || rfield->stored_in_db) &&
- (value->save_in_field(rfield, 0) < 0) && !ignore_errors)
+ (value->save_in_field(rfield, 0)) < 0 && !ignore_errors)
{
my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
goto err;
@@ -8444,20 +8694,18 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
}
/* Update virtual fields*/
thd->abort_on_warning= FALSE;
- if (vcol_table)
- {
- if (vcol_table->vfield)
- {
- if (update_virtual_fields(thd, vcol_table,
- vcol_table->triggers ? VCOL_UPDATE_ALL :
- VCOL_UPDATE_FOR_WRITE))
- goto err;
- }
- }
- thd->abort_on_warning= abort_on_warning_saved;
+ if (vcol_table && vcol_table->vfield &&
+ update_virtual_fields(thd, vcol_table,
+ vcol_table->triggers ? VCOL_UPDATE_ALL :
+ VCOL_UPDATE_FOR_WRITE))
+ goto err;
+ thd->abort_on_warning= save_abort_on_warning;
+ thd->no_errors= save_no_errors;
DBUG_RETURN(thd->is_error());
+
err:
- thd->abort_on_warning= abort_on_warning_saved;
+ thd->abort_on_warning= save_abort_on_warning;
+ thd->no_errors= save_no_errors;
if (table)
table->auto_increment_field_not_null= FALSE;
DBUG_RETURN(TRUE);
@@ -8532,6 +8780,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
@@ -8544,7 +8793,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;
@@ -8584,15 +8834,17 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors)
value->type() != Item::NULL_ITEM &&
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
{
- thd->abort_on_warning= FALSE;
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
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;
}
/* Update virtual fields*/
thd->abort_on_warning= FALSE;
@@ -8641,7 +8893,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)));
/*
@@ -8858,7 +9110,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
{
if (!in_use->killed)
{
- in_use->killed= THD::KILL_SYSTEM_THREAD;
+ in_use->killed= KILL_SYSTEM_THREAD;
pthread_mutex_lock(&in_use->mysys_var->mutex);
if (in_use->mysys_var->current_cond)
{
@@ -9194,7 +9446,7 @@ void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table
if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
! in_use->killed)
{
- in_use->killed= THD::KILL_SYSTEM_THREAD;
+ in_use->killed= KILL_SYSTEM_THREAD;
pthread_mutex_lock(&in_use->mysys_var->mutex);
if (in_use->mysys_var->current_cond)
{
@@ -9452,13 +9704,12 @@ open_performance_schema_table(THD *thd, TABLE_LIST *one_table,
else
{
/*
- If error in mysql_lock_tables(), open_ltable doesn't close the
- table. Thread kill during mysql_lock_tables() is such error. But
- open tables cannot be accepted when restoring the open tables
- state.
+ This can happen during a thd->kill or while we are trying to log
+ data for a stored procedure/trigger and someone causes the table
+ to be flushed (for example by creating a new trigger for the
+ table)
*/
- if (thd->killed)
- close_thread_tables(thd);
+ close_thread_tables(thd);
thd->restore_backup_open_tables_state(backup);
}
@@ -9518,6 +9769,61 @@ void close_performance_schema_table(THD *thd, Open_tables_state *backup)
thd->restore_backup_open_tables_state(backup);
}
+
+/**
+ @brief
+ Remove 'fixed' flag from items in a list
+
+ @param items list of items to un-fix
+
+ @details
+ This function sets to 0 the 'fixed' flag for items in the 'items' list.
+ It's needed to force correct marking of views' fields for INSERT/UPDATE
+ statements.
+*/
+
+void unfix_fields(List<Item> &fields)
+{
+ List_iterator<Item> li(fields);
+ Item *item;
+ while ((item= li++))
+ item->fixed= 0;
+}
+
+
+/**
+ Check result of dynamic column function and issue error if it is needed
+
+ @param rc The result code of dynamic column function
+
+ @return the result code which was get as an argument\
+*/
+
+int dynamic_column_error_message(enum_dyncol_func_result rc)
+{
+ switch (rc) {
+ case ER_DYNCOL_YES:
+ case ER_DYNCOL_OK:
+ break; // it is not an error
+ case ER_DYNCOL_FORMAT:
+ my_error(ER_DYN_COL_WRONG_FORMAT, MYF(0));
+ break;
+ case ER_DYNCOL_LIMIT:
+ my_error(ER_DYN_COL_IMPLEMENTATION_LIMIT, MYF(0));
+ break;
+ case ER_DYNCOL_RESOURCE:
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
+ break;
+ case ER_DYNCOL_DATA:
+ my_error(ER_DYN_COL_DATA, MYF(0));
+ break;
+ case ER_DYNCOL_UNKNOWN_CHARSET:
+ my_error(ER_DYN_COL_WRONG_CHARSET, MYF(0));
+ break;
+ }
+ return rc;
+}
+
/**
@} (end of group Data_Dictionary)
*/
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index 1624a9639a1..58683a5f1e9 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -176,7 +176,7 @@ void mysql_client_binlog_statement(THD* thd)
*/
if (!have_fd_event)
{
- int type = bufptr[EVENT_TYPE_OFFSET];
+ int type = (uchar)bufptr[EVENT_TYPE_OFFSET];
if (type == FORMAT_DESCRIPTION_EVENT || type == START_EVENT_V3)
have_fd_event= TRUE;
else
@@ -188,7 +188,8 @@ void mysql_client_binlog_statement(THD* thd)
}
ev= Log_event::read_log_event(bufptr, event_len, &error,
- rli->relay_log.description_event_for_exec);
+ rli->relay_log.description_event_for_exec,
+ 0);
DBUG_PRINT("info",("binlog base64 err=%s", error));
if (!ev)
diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h
index 5385acc934f..25725ff6c42 100644
--- a/sql/sql_bitmap.h
+++ b/sql/sql_bitmap.h
@@ -91,6 +91,10 @@ public:
DBUG_ASSERT(sizeof(buffer) >= 4);
return (ulonglong) uint4korr(buffer);
}
+ uint bits_set()
+ {
+ return bitmap_bits_set(&map);
+ }
};
/* An iterator to quickly walk over bits in unlonglong bitmap. */
@@ -169,5 +173,16 @@ public:
public:
Iterator(Bitmap<64> &bmp) : Table_map_iterator(bmp.map) {}
};
+ uint bits_set()
+ {
+ //TODO: use my_count_bits()
+ uint res= 0, i= 0;
+ for (; i < 64 ; i++)
+ {
+ if (map & ((ulonglong)1<<i))
+ res++;
+ }
+ return res;
+ }
};
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 4939ca3d13b..7b5d5eeb96a 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -288,6 +288,7 @@ functions:
if (and only if) this query has a registered result set writer
(thd->net.query_cache_query).
4. Query_cache::invalidate
+ Query_cache::invalidate_locked_for_write
- Called from various places to invalidate query cache based on data-
base, table and myisam file name. During an on going invalidation
the query cache is temporarily disabled.
@@ -336,6 +337,8 @@ TODO list:
#include "../storage/myisammrg/ha_myisammrg.h"
#include "../storage/myisammrg/myrg_def.h"
+const uchar *query_state_map;
+
#ifdef EMBEDDED_LIBRARY
#include "emb_qcache.h"
#endif
@@ -390,7 +393,7 @@ static void debug_wait_for_kill(const char *info)
sql_print_information("%s", info);
while(!thd->killed)
my_sleep(1000);
- thd->killed= THD::NOT_KILLED;
+ thd->killed= NOT_KILLED;
/*
Remove the set debug variable, to ensure we don't get stuck on it again
This is needed as for MyISAM, invalidate_table() may be called twice
@@ -424,6 +427,141 @@ TYPELIB query_cache_type_typelib=
};
+/*
+ Check if character is a white space.
+*/
+
+inline bool is_white_space(char c)
+{
+ return (query_state_map[(uint) ((uchar) c)] == MY_LEX_SKIP);
+}
+
+
+/**
+ Generate a query_string without query comments or duplicated space
+
+ @param new_query New query without 'fluff' is stored here
+ @param query Original query
+ @param query_length Length of original query
+ @param additional_length Extra space for query cache we need to allocate
+ in new_query buffer.
+
+ Note:
+ If there is no space to allocate new_query, we will put original query
+ into new_query.
+*/
+
+static void make_base_query(String *new_query,
+ const char *query, size_t query_length,
+ size_t additional_length)
+{
+ char *buffer;
+ const char *query_end, *last_space;
+
+ /* The following is guaranteed by the query_cache interface */
+ DBUG_ASSERT(query[query_length] == 0);
+ DBUG_ASSERT(!is_white_space(query[0]));
+
+ new_query->length(0); // Don't copy anything from old buffer
+ if (new_query->realloc(query_length + additional_length))
+ {
+ /*
+ We could not allocate the query. Use original query for
+ the query cache; Better than nothing....
+ */
+ new_query->set(query, query_length, system_charset_info);
+ return;
+ }
+
+ buffer= (char*) new_query->ptr(); // Store base query here
+ query_end= query + query_length;
+ last_space= 0; // No space found yet
+
+ while (query < query_end)
+ {
+ char current = *(query++);
+ switch (current) {
+ case '\'':
+ case '`':
+ case '"':
+ *(buffer++)= current; // copy first quote
+ while (query < query_end)
+ {
+ *(buffer++)= *query;
+ if (*(query++) == current) // found pair quote
+ break;
+ }
+ continue; // Continue with next symbol
+ case '/': // Start of comment ?
+ /*
+ Comment of format /#!number #/ or /#M!number #/, must be skipped.
+ These may include '"' and other comments, but it should
+ be safe to parse the content as a normal string.
+ */
+ if (query[0] != '*' || query[1] == '!' ||
+ (query[1] == 'M' && query[2] == '!'))
+ break;
+
+ query++; // skip "/"
+ while (++query < query_end)
+ {
+ if (query[0] == '*' && query[1] == '/')
+ {
+ query+= 2;
+ goto insert_space;
+ }
+ }
+ continue; // Will end outer loop
+ case '-':
+ if (*query != '-' || !is_white_space(query[1])) // Not a comment
+ break;
+ query++; // skip second "-", and go to search of "\n"
+ /* fall through */
+ case '#':
+ while (query < query_end)
+ {
+ if (*(query++) == '\n')
+ goto insert_space;
+ }
+ continue; // Will end outer loop
+ default:
+ if (is_white_space(current))
+ goto insert_space;
+ break;
+ }
+ *(buffer++)= current;
+ continue;
+
+insert_space:
+ if (buffer != last_space)
+ {
+ *(buffer++)= ' ';
+ last_space= buffer;
+ }
+ }
+ if (buffer == last_space)
+ buffer--; // Remove the last space
+ *buffer= 0; // End zero after query
+ new_query->length((size_t) (buffer - new_query->ptr()));
+
+ /* Copy db_length */
+ memcpy(buffer+1, query_end+1, QUERY_CACHE_DB_LENGTH_SIZE);
+}
+
+
+/**
+ Check and change local variable if global one is switched
+
+ @param thd thread handle
+*/
+
+void inline fix_local_query_cache_mode(THD *thd)
+{
+ if (global_system_variables.query_cache_type == 0)
+ thd->variables.query_cache_type= 0;
+}
+
+
/**
Serialize access to the query cache.
If the lock cannot be granted the thread hangs in a conditional wait which
@@ -433,31 +571,47 @@ TYPELIB query_cache_type_typelib=
effect by another thread. This enables a quick path in execution to skip waits
when the outcome is known.
- @param use_timeout TRUE if the lock can abort because of a timeout.
+ @param mode TIMEOUT the lock can abort because of a timeout
+ TRY the lock can abort because it is locked now
+ WAIT wait for lock (default)
- @note use_timeout is optional and default value is FALSE.
+ @note mode is optional and default value is WAIT.
@return
@retval FALSE An exclusive lock was taken
@retval TRUE The locking attempt failed
*/
-bool Query_cache::try_lock(bool use_timeout)
+bool Query_cache::try_lock(THD *thd, Cache_try_lock_mode mode)
{
- bool interrupt= FALSE;
+ bool interrupt= TRUE;
+ const char* old_proc_info;
DBUG_ENTER("Query_cache::try_lock");
+ old_proc_info= thd->proc_info;
+ thd_proc_info(thd,"Waiting on query cache mutex");
+
pthread_mutex_lock(&structure_guard_mutex);
+ DBUG_EXECUTE_IF("status_wait_query_cache_mutex_sleep", {
+ sleep(5);
+ });
+ if (m_cache_status == DISABLED)
+ {
+ pthread_mutex_unlock(&structure_guard_mutex);
+ thd->proc_info= old_proc_info;
+ DBUG_RETURN(TRUE);
+ }
+ m_requests_in_progress++;
+ fix_local_query_cache_mode(thd);
while (1)
{
if (m_cache_lock_status == Query_cache::UNLOCKED)
{
m_cache_lock_status= Query_cache::LOCKED;
#ifndef DBUG_OFF
- THD *thd= current_thd;
- if (thd)
- m_cache_lock_thread_id= thd->thread_id;
+ m_cache_lock_thread_id= thd->thread_id;
#endif
+ interrupt= FALSE;
break;
}
else if (m_cache_lock_status == Query_cache::LOCKED_NO_WAIT)
@@ -466,7 +620,6 @@ bool Query_cache::try_lock(bool use_timeout)
If query cache is protected by a LOCKED_NO_WAIT lock this thread
should avoid using the query cache as it is being evicted.
*/
- interrupt= TRUE;
break;
}
else
@@ -476,25 +629,36 @@ bool Query_cache::try_lock(bool use_timeout)
To prevent send_result_to_client() and query_cache_insert() from
blocking execution for too long a timeout is put on the lock.
*/
- if (use_timeout)
+ if (mode == WAIT)
+ {
+ pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
+ }
+ else if (mode == TIMEOUT)
{
struct timespec waittime;
set_timespec_nsec(waittime,(ulong)(50000000L)); /* Wait for 50 msec */
int res= pthread_cond_timedwait(&COND_cache_status_changed,
&structure_guard_mutex,&waittime);
if (res == ETIMEDOUT)
- {
- interrupt= TRUE;
break;
- }
}
else
{
- pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
+ /**
+ If we are here, then mode is == TRY and there was someone else using
+ the query cache. (m_cache_lock_status != Query_cache::UNLOCKED).
+ Signal that we didn't get a lock.
+ */
+ DBUG_ASSERT(m_requests_in_progress > 1);
+ DBUG_ASSERT(mode == TRY);
+ break;
}
}
}
+ if (interrupt)
+ m_requests_in_progress--;
pthread_mutex_unlock(&structure_guard_mutex);
+ thd->proc_info = old_proc_info;
DBUG_RETURN(interrupt);
}
@@ -516,10 +680,12 @@ void Query_cache::lock_and_suspend(void)
DBUG_ENTER("Query_cache::lock_and_suspend");
pthread_mutex_lock(&structure_guard_mutex);
+ m_requests_in_progress++;
while (m_cache_lock_status != Query_cache::UNLOCKED)
pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
m_cache_lock_status= Query_cache::LOCKED_NO_WAIT;
#ifndef DBUG_OFF
+ /* Here thd may not be set during shutdown */
THD *thd= current_thd;
if (thd)
m_cache_lock_thread_id= thd->thread_id;
@@ -539,18 +705,18 @@ void Query_cache::lock_and_suspend(void)
It is used by all methods which invalidates one or more tables.
*/
-void Query_cache::lock(void)
+void Query_cache::lock(THD *thd)
{
DBUG_ENTER("Query_cache::lock");
pthread_mutex_lock(&structure_guard_mutex);
+ m_requests_in_progress++;
+ fix_local_query_cache_mode(thd);
while (m_cache_lock_status != Query_cache::UNLOCKED)
pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
m_cache_lock_status= Query_cache::LOCKED;
#ifndef DBUG_OFF
- THD *thd= current_thd;
- if (thd)
- m_cache_lock_thread_id= thd->thread_id;
+ m_cache_lock_thread_id= thd->thread_id;
#endif
pthread_mutex_unlock(&structure_guard_mutex);
@@ -567,6 +733,7 @@ void Query_cache::unlock(void)
DBUG_ENTER("Query_cache::unlock");
pthread_mutex_lock(&structure_guard_mutex);
#ifndef DBUG_OFF
+ /* Thd may not be set in resize() at mysqld start */
THD *thd= current_thd;
if (thd)
DBUG_ASSERT(m_cache_lock_thread_id == thd->thread_id);
@@ -576,6 +743,14 @@ void Query_cache::unlock(void)
m_cache_lock_status= Query_cache::UNLOCKED;
DBUG_PRINT("Query_cache",("Sending signal"));
pthread_cond_signal(&COND_cache_status_changed);
+ DBUG_ASSERT(m_requests_in_progress > 0);
+ m_requests_in_progress--;
+ if (m_requests_in_progress == 0 && m_cache_status == DISABLE_REQUEST)
+ {
+ /* No clients => just free query cache */
+ free_cache();
+ m_cache_status= DISABLED;
+ }
pthread_mutex_unlock(&structure_guard_mutex);
DBUG_VOID_RETURN;
}
@@ -592,25 +767,24 @@ void Query_cache::unlock(void)
@retval FALSE No directive found.
*/
-static bool has_no_cache_directive(char *sql)
+static bool has_no_cache_directive(const char *sql)
{
- int i=0;
- while (sql[i] == ' ')
- ++i;
+ while (is_white_space(*sql))
+ sql++;
- if (my_toupper(system_charset_info, sql[i]) == 'S' &&
- my_toupper(system_charset_info, sql[i+1]) == 'Q' &&
- my_toupper(system_charset_info, sql[i+2]) == 'L' &&
- my_toupper(system_charset_info, sql[i+3]) == '_' &&
- my_toupper(system_charset_info, sql[i+4]) == 'N' &&
- my_toupper(system_charset_info, sql[i+5]) == 'O' &&
- my_toupper(system_charset_info, sql[i+6]) == '_' &&
- my_toupper(system_charset_info, sql[i+7]) == 'C' &&
- my_toupper(system_charset_info, sql[i+8]) == 'A' &&
- my_toupper(system_charset_info, sql[i+9]) == 'C' &&
- my_toupper(system_charset_info, sql[i+10]) == 'H' &&
- my_toupper(system_charset_info, sql[i+11]) == 'E' &&
- my_toupper(system_charset_info, sql[i+12]) == ' ')
+ if (my_toupper(system_charset_info, sql[0]) == 'S' &&
+ my_toupper(system_charset_info, sql[1]) == 'Q' &&
+ my_toupper(system_charset_info, sql[2]) == 'L' &&
+ my_toupper(system_charset_info, sql[3]) == '_' &&
+ my_toupper(system_charset_info, sql[4]) == 'N' &&
+ my_toupper(system_charset_info, sql[5]) == 'O' &&
+ my_toupper(system_charset_info, sql[6]) == '_' &&
+ my_toupper(system_charset_info, sql[7]) == 'C' &&
+ my_toupper(system_charset_info, sql[8]) == 'A' &&
+ my_toupper(system_charset_info, sql[9]) == 'C' &&
+ my_toupper(system_charset_info, sql[10]) == 'H' &&
+ my_toupper(system_charset_info, sql[11]) == 'E' &&
+ my_isspace(system_charset_info, sql[12]))
return TRUE;
return FALSE;
@@ -868,14 +1042,23 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
{
DBUG_ENTER("query_cache_insert");
- /* See the comment on double-check locking usage above. */
if (net->query_cache_query == 0)
DBUG_VOID_RETURN;
+ DBUG_ASSERT(current_thd);
+
DBUG_EXECUTE_IF("wait_in_query_cache_insert",
debug_wait_for_kill("wait_in_query_cache_insert"); );
- if (query_cache.try_lock())
+ /* First we check if query cache is disable without doing a mutex lock */
+ if(query_cache.is_disabled())
+ DBUG_VOID_RETURN;
+
+ /*
+ Lock the cache with try_lock(). try_lock() will fail if
+ cache was disabled between the above test and lock.
+ */
+ if (query_cache.try_lock(current_thd, Query_cache::WAIT))
DBUG_VOID_RETURN;
Query_cache_block *query_block= (Query_cache_block*)net->query_cache_query;
@@ -933,7 +1116,7 @@ void query_cache_abort(NET *net)
if (net->query_cache_query == 0)
DBUG_VOID_RETURN;
- if (query_cache.try_lock())
+ if (query_cache.try_lock(current_thd, Query_cache::WAIT))
{
net->query_cache_query = 0;
DBUG_VOID_RETURN;
@@ -986,7 +1169,7 @@ void query_cache_end_of_result(THD *thd)
emb_count_querycache_size(thd));
#endif
- if (query_cache.try_lock())
+ if (query_cache.try_lock(thd, Query_cache::WAIT))
{
thd->net.query_cache_query= 0;
DBUG_VOID_RETURN;
@@ -1075,6 +1258,7 @@ Query_cache::Query_cache(ulong query_cache_limit_arg,
query_cache_limit(query_cache_limit_arg),
queries_in_cache(0), hits(0), inserts(0), refused(0),
total_blocks(0), lowmem_prunes(0),
+ m_cache_status(OK),
min_allocation_unit(ALIGN_SIZE(min_allocation_unit_arg)),
min_result_data_size(ALIGN_SIZE(min_result_data_size_arg)),
def_query_hash_size(ALIGN_SIZE(def_query_hash_size_arg)),
@@ -1098,6 +1282,13 @@ ulong Query_cache::resize(ulong query_cache_size_arg)
query_cache_size_arg));
DBUG_ASSERT(initialized);
+ if (global_system_variables.query_cache_type == 0)
+ {
+ if (query_cache_size_arg != 0)
+ my_error(ER_QUERY_CACHE_IS_DISABLED, MYF(0));
+ DBUG_RETURN(0);
+ }
+
lock_and_suspend();
/*
@@ -1130,8 +1321,17 @@ ulong Query_cache::resize(ulong query_cache_size_arg)
query_cache_size= query_cache_size_arg;
new_query_cache_size= init_cache();
+ /*
+ m_cache_status is internal query cache switch so switching it on/off
+ will not be reflected on global_system_variables.query_cache_type
+ */
if (new_query_cache_size)
+ {
DBUG_EXECUTE("check_querycache",check_integrity(1););
+ m_cache_status= OK; // size > 0 => enable cache
+ }
+ else
+ m_cache_status= DISABLED; // size 0 means the cache disabled
unlock();
DBUG_RETURN(new_query_cache_size);
@@ -1150,6 +1350,9 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
{
TABLE_COUNTER_TYPE local_tables;
ulong tot_length;
+ const char *query;
+ size_t query_length;
+ uint8 tables_type;
DBUG_ENTER("Query_cache::store_query");
/*
Testing 'query_cache_size' without a lock here is safe: the thing
@@ -1159,12 +1362,23 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
See also a note on double-check locking usage above.
*/
- if (thd->locked_tables || query_cache_size == 0)
+ if (!thd->query_cache_is_applicable || query_cache_size == 0)
+ {
+ DBUG_PRINT("qcache", ("Query cache not ready"));
+ DBUG_VOID_RETURN;
+ }
+ if (thd->lex->sql_command != SQLCOM_SELECT)
+ {
+ DBUG_PRINT("qcache", ("Ignoring not SELECT command"));
DBUG_VOID_RETURN;
- uint8 tables_type= 0;
+ }
+
+ /* The following assert fails if we haven't called send_result_to_client */
+ DBUG_ASSERT(thd->base_query.is_alloced() ||
+ thd->base_query.ptr() == thd->query());
- if ((local_tables= is_cacheable(thd, thd->query_length(),
- thd->query(), thd->lex, tables_used,
+ tables_type= 0;
+ if ((local_tables= is_cacheable(thd, thd->lex, tables_used,
&tables_type)))
{
NET *net= &thd->net;
@@ -1238,10 +1452,10 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
In case the wait time can't be determined there is an upper limit which
causes try_lock() to abort with a time out.
- The 'TRUE' parameter indicate that the lock is allowed to timeout
+ The 'TIMEOUT' parameter indicate that the lock is allowed to timeout
*/
- if (try_lock(TRUE))
+ if (try_lock(thd, Query_cache::TIMEOUT))
DBUG_VOID_RETURN;
if (query_cache_size == 0)
{
@@ -1257,10 +1471,13 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
DBUG_VOID_RETURN;
}
+ query= thd->base_query.ptr();
+ query_length= thd->base_query.length();
+
/* Key is query + database + flag */
if (thd->db_length)
{
- memcpy(thd->query() + thd->query_length() + 1 + sizeof(size_t),
+ memcpy((char*) (query + query_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE),
thd->db, thd->db_length);
DBUG_PRINT("qcache", ("database: %s length: %u",
thd->db, (unsigned) thd->db_length));
@@ -1269,24 +1486,24 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
{
DBUG_PRINT("qcache", ("No active database"));
}
- tot_length= thd->query_length() + thd->db_length + 1 +
- sizeof(size_t) + QUERY_CACHE_FLAGS_SIZE;
+ tot_length= (query_length + thd->db_length + 1 +
+ QUERY_CACHE_DB_LENGTH_SIZE + QUERY_CACHE_FLAGS_SIZE);
/*
We should only copy structure (don't use it location directly)
because of alignment issue
*/
- memcpy((void*) (thd->query() + (tot_length - QUERY_CACHE_FLAGS_SIZE)),
+ memcpy((void*) (query + (tot_length - QUERY_CACHE_FLAGS_SIZE)),
&flags, QUERY_CACHE_FLAGS_SIZE);
/* Check if another thread is processing the same query? */
Query_cache_block *competitor = (Query_cache_block *)
- hash_search(&queries, (uchar*) thd->query(), tot_length);
+ hash_search(&queries, (uchar*) query, tot_length);
DBUG_PRINT("qcache", ("competitor 0x%lx", (ulong) competitor));
if (competitor == 0)
{
/* Query is not in cache and no one is working with it; Store it */
Query_cache_block *query_block;
- query_block= write_block_data(tot_length, (uchar*) thd->query(),
+ query_block= write_block_data(tot_length, (uchar*) query,
ALIGN_SIZE(sizeof(Query_cache_query)),
Query_cache_block::QUERY, local_tables);
if (query_block != 0)
@@ -1343,7 +1560,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
DBUG_PRINT("qcache", ("Another thread process same query"));
}
}
- else if (thd->lex->sql_command == SQLCOM_SELECT)
+ else
statistic_increment(refused, &structure_guard_mutex);
end:
@@ -1418,7 +1635,7 @@ send_data_in_chunks(NET *net, const uchar *packet, ulong len)
*/
int
-Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
+Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
{
ulonglong engine_data;
Query_cache_query *query;
@@ -1429,6 +1646,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
Query_cache_block_table *block_table, *block_table_end;
ulong tot_length;
Query_cache_query_flags flags;
+ const char *sql, *sql_end, *found_brace= 0;
DBUG_ENTER("Query_cache::send_result_to_client");
/*
@@ -1438,52 +1656,115 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
See also a note on double-check locking usage above.
*/
- if (thd->locked_tables || thd->variables.query_cache_type == 0 ||
- query_cache_size == 0)
+ if (is_disabled() || thd->locked_tables ||
+ thd->variables.query_cache_type == 0)
goto err;
+ /*
+ The following can only happen for prepared statements that was found
+ during parsing or later that the query was not cacheable.
+ */
if (!thd->lex->safe_to_cache_query)
{
DBUG_PRINT("qcache", ("SELECT is non-cacheable"));
goto err;
}
- {
- uint i= 0;
- /*
- Skip '(' characters in queries like following:
- (select a from t1) union (select a from t1);
- */
- while (sql[i]=='(')
- i++;
+ DBUG_ASSERT(query_cache_size != 0); // otherwise cache would be disabled
- /*
- Test if the query is a SELECT
- (pre-space is removed in dispatch_command).
+ thd->query_cache_is_applicable= 1;
+ sql= org_sql; sql_end= sql + query_length;
- First '/' looks like comment before command it is not
- frequently appeared in real life, consequently we can
- check all such queries, too.
- */
- if ((my_toupper(system_charset_info, sql[i]) != 'S' ||
- my_toupper(system_charset_info, sql[i + 1]) != 'E' ||
- my_toupper(system_charset_info, sql[i + 2]) != 'L') &&
- sql[i] != '/')
- {
- DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached"));
- goto err;
- }
-
- if (query_length > 20 && has_no_cache_directive(&sql[i+6]))
+ /*
+ Skip all comments at start of query. The following tests is false for
+ all normal queries.
+ */
+ if (!my_isalpha(system_charset_info, *sql))
+ {
+ while (sql < sql_end)
{
- /*
- We do not increase 'refused' statistics here since it will be done
- later when the query is parsed.
- */
- DBUG_PRINT("qcache", ("The statement has a SQL_NO_CACHE directive"));
- goto err;
+ char current= *sql;
+ switch (current) {
+ case '/':
+ if (sql[1] != '*')
+ break;
+ sql+= 2; // Skip '/*'
+ if (*sql == '!')
+ {
+ /*
+ Found / *!number comment; Skip number to see if sql
+ starts with 'select'
+ */
+ sql++;
+ while (my_isdigit(system_charset_info, *sql))
+ sql++;
+ }
+ else
+ {
+ while (sql++ < sql_end)
+ {
+ if (sql[-1] == '*' && *sql == '/')
+ {
+ sql++;
+ break;
+ }
+ }
+ }
+ continue;
+ case '-':
+ if (sql[1] != '-' || !is_white_space(sql[2])) // Not a comment
+ break;
+ sql++; // Skip first '-'
+ /* Fall through */
+ case '#':
+ while (++sql < sql_end)
+ {
+ if (*sql == '\n')
+ {
+ sql++; // Skip '\n'
+ break;
+ }
+ }
+ /* Continue with analyzing current symbol */
+ continue;
+ case '\r':
+ case '\n':
+ case '\t':
+ case ' ':
+ sql++;
+ continue;
+ case '(': // To handle (select a from t1) union (select a from t1);
+ if (!found_brace)
+ {
+ found_brace= sql;
+ sql++;
+ continue;
+ }
+ /* fall trough */
+ default:
+ break;
+ }
+ /* We only come here when we found the first word of the sql */
+ break;
}
}
+ if ((my_toupper(system_charset_info, sql[0]) != 'S' ||
+ my_toupper(system_charset_info, sql[1]) != 'E' ||
+ my_toupper(system_charset_info, sql[2]) != 'L'))
+ {
+ DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached"));
+ goto err;
+ }
+
+ if ((sql_end - sql) > 20 && has_no_cache_directive(sql+6))
+ {
+ /*
+ We do not increase 'refused' statistics here since it will be done
+ later when the query is parsed.
+ */
+ DBUG_PRINT("qcache", ("The statement has a SQL_NO_CACHE directive"));
+ goto err;
+ }
{
/*
We have allocated buffer space (in alloc_query) to hold the
@@ -1493,8 +1774,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
sure the new current database has a name with the same length
as the previous one.
*/
- size_t db_len;
- memcpy((char *) &db_len, (sql + query_length + 1), sizeof(size_t));
+ size_t db_len= uint2korr(sql_end+1);
if (thd->db_length != db_len)
{
/*
@@ -1512,9 +1792,9 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
disabled or if a full cache flush is in progress, the attempt to
get the lock is aborted.
- The 'TRUE' parameter indicate that the lock is allowed to timeout
+ The TIMEOUT parameter indicate that the lock is allowed to timeout.
*/
- if (try_lock(TRUE))
+ if (try_lock(thd, Query_cache::TIMEOUT))
goto err;
if (query_cache_size == 0)
@@ -1527,15 +1807,31 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
DBUG_ASSERT(thd->net.query_cache_query == 0);
Query_cache_block *query_block;
+ if (opt_query_cache_strip_comments)
+ {
+ if (found_brace)
+ sql= found_brace;
+ make_base_query(&thd->base_query, sql, (size_t) (sql_end - sql),
+ thd->db_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE +
+ QUERY_CACHE_FLAGS_SIZE);
+ sql= thd->base_query.ptr();
+ query_length= thd->base_query.length();
+ }
+ else
+ {
+ sql= org_sql;
+ thd->base_query.set(sql, query_length, system_charset_info);
+ }
- tot_length= query_length + 1 + sizeof(size_t) +
- thd->db_length + QUERY_CACHE_FLAGS_SIZE;
+ tot_length= (query_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE +
+ thd->db_length + QUERY_CACHE_FLAGS_SIZE);
if (thd->db_length)
{
- memcpy(sql + query_length + 1 + sizeof(size_t), thd->db, thd->db_length);
+ memcpy((uchar*) sql + query_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE,
+ thd->db, thd->db_length);
DBUG_PRINT("qcache", ("database: '%s' length: %u",
- thd->db, (unsigned)thd->db_length));
+ thd->db, (uint) thd->db_length));
}
else
{
@@ -1657,14 +1953,15 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
{
DBUG_PRINT("qcache",
("Temporary table detected: '%s.%s'",
- table_list.db, table_list.alias));
+ tmptable->s->db.str, tmptable->alias.c_ptr()));
unlock();
/*
We should not store result of this query because it contain
temporary tables => assign following variable to make check
faster.
*/
- thd->lex->safe_to_cache_query=0;
+ thd->query_cache_is_applicable= 0; // Query can't be cached
+ thd->lex->safe_to_cache_query= 0; // For prepared statements
BLOCK_UNLOCK_RD(query_block);
DBUG_RETURN(-1);
}
@@ -1680,7 +1977,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
("probably no SELECT access to %s.%s => return to normal processing",
table_list.db, table_list.alias));
unlock();
- thd->lex->safe_to_cache_query=0; // Don't try to cache this
+ thd->query_cache_is_applicable= 0; // Query can't be cached
+ thd->lex->safe_to_cache_query= 0; // For prepared statements
BLOCK_UNLOCK_RD(query_block);
DBUG_RETURN(-1); // Privilege error
}
@@ -1689,7 +1987,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
DBUG_PRINT("qcache", ("Need to check column privileges for %s.%s",
table_list.db, table_list.alias));
BLOCK_UNLOCK_RD(query_block);
- thd->lex->safe_to_cache_query= 0; // Don't try to cache this
+ thd->query_cache_is_applicable= 0; // Query can't be cached
+ thd->lex->safe_to_cache_query= 0; // For prepared statements
goto err_unlock; // Parse query
}
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
@@ -1713,7 +2012,13 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
table->key_length());
}
else
- thd->lex->safe_to_cache_query= 0; // Don't try to cache this
+ {
+ /*
+ As this can change from call to call, don't reset set
+ thd->lex->safe_to_cache_query
+ */
+ thd->query_cache_is_applicable= 0; // Query can't be cached
+ }
goto err_unlock; // Parse query
}
else
@@ -1764,12 +2069,15 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
err_unlock:
unlock();
-err:
/*
query_plan_flags doesn't have to be changed here as it contains
QPLAN_QC_NO by default
*/
DBUG_RETURN(0); // Query was not cached
+
+err:
+ thd->query_cache_is_applicable= 0; // Query can't be cached
+ DBUG_RETURN(0); // Query was not cached
}
@@ -1781,6 +2089,8 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
my_bool using_transactions)
{
DBUG_ENTER("Query_cache::invalidate (table list)");
+ if (is_disabled())
+ DBUG_VOID_RETURN;
using_transactions= using_transactions &&
(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
@@ -1808,10 +2118,12 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
DBUG_VOID_RETURN;
}
-void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
+void Query_cache::invalidate(THD *thd, CHANGED_TABLE_LIST *tables_used)
{
DBUG_ENTER("Query_cache::invalidate (changed table list)");
- THD *thd= current_thd;
+ if (is_disabled())
+ DBUG_VOID_RETURN;
+
for (; tables_used; tables_used= tables_used->next)
{
thd_proc_info(thd, "invalidating query cache entries (table list)");
@@ -1834,10 +2146,13 @@ void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
NOTE
can be used only for opened tables
*/
-void Query_cache::invalidate_locked_for_write(TABLE_LIST *tables_used)
+void Query_cache::invalidate_locked_for_write(THD *thd,
+ TABLE_LIST *tables_used)
{
- THD *thd= current_thd;
DBUG_ENTER("Query_cache::invalidate_locked_for_write");
+ if (is_disabled())
+ DBUG_VOID_RETURN;
+
for (; tables_used; tables_used= tables_used->next_local)
{
thd_proc_info(thd, "invalidating query cache entries (table)");
@@ -1858,7 +2173,9 @@ void Query_cache::invalidate(THD *thd, TABLE *table,
my_bool using_transactions)
{
DBUG_ENTER("Query_cache::invalidate (table)");
-
+ if (is_disabled())
+ DBUG_VOID_RETURN;
+
using_transactions= using_transactions &&
(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
if (using_transactions &&
@@ -1875,6 +2192,8 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
my_bool using_transactions)
{
DBUG_ENTER("Query_cache::invalidate (key)");
+ if (is_disabled())
+ DBUG_VOID_RETURN;
using_transactions= using_transactions &&
(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
@@ -1891,18 +2210,19 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
Remove all cached queries that uses the given database.
*/
-void Query_cache::invalidate(char *db)
+void Query_cache::invalidate(THD *thd, char *db)
{
- bool restart= FALSE;
+ bool restart;
DBUG_ENTER("Query_cache::invalidate (db)");
+ if (is_disabled())
+ DBUG_VOID_RETURN;
+ restart= FALSE;
/*
Lock the query cache and queue all invalidation attempts to avoid
the risk of a race between invalidation, cache inserts and flushes.
*/
- lock();
-
- THD *thd= current_thd;
+ lock(thd);
if (query_cache_size > 0)
{
@@ -1980,6 +2300,9 @@ void Query_cache::invalidate_by_MyISAM_filename(const char *filename)
void Query_cache::flush()
{
DBUG_ENTER("Query_cache::flush");
+ if (is_disabled())
+ DBUG_VOID_RETURN;
+
DBUG_EXECUTE_IF("wait_in_query_cache_flush1",
debug_wait_for_kill("wait_in_query_cache_flush1"););
@@ -2007,7 +2330,7 @@ void Query_cache::flush()
*/
-void Query_cache::pack(ulong join_limit, uint iteration_limit)
+void Query_cache::pack(THD *thd, ulong join_limit, uint iteration_limit)
{
DBUG_ENTER("Query_cache::pack");
@@ -2015,7 +2338,7 @@ void Query_cache::pack(ulong join_limit, uint iteration_limit)
If the entire qc is being invalidated we can bail out early
instead of waiting for the lock.
*/
- if (try_lock())
+ if (try_lock(thd, Query_cache::WAIT))
DBUG_VOID_RETURN;
if (query_cache_size == 0)
@@ -2052,11 +2375,25 @@ void Query_cache::destroy()
pthread_cond_destroy(&COND_cache_status_changed);
pthread_mutex_destroy(&structure_guard_mutex);
initialized = 0;
+ DBUG_ASSERT(m_requests_in_progress == 0);
}
DBUG_VOID_RETURN;
}
+void Query_cache::disable_query_cache(THD *thd)
+{
+ m_cache_status= DISABLE_REQUEST;
+ /*
+ If there is no requests in progress try to free buffer.
+ try_lock(TRY) will exit immediately if there is lock.
+ unlock() should free block.
+ */
+ if (m_requests_in_progress == 0 && !try_lock(thd, TRY))
+ unlock();
+}
+
+
/*****************************************************************************
init/destroy
*****************************************************************************/
@@ -2067,7 +2404,21 @@ void Query_cache::init()
pthread_mutex_init(&structure_guard_mutex,MY_MUTEX_INIT_FAST);
pthread_cond_init(&COND_cache_status_changed, NULL);
m_cache_lock_status= Query_cache::UNLOCKED;
+ m_cache_status= Query_cache::OK;
+ m_requests_in_progress= 0;
initialized = 1;
+ query_state_map= default_charset_info->state_map;
+ /*
+ If we explicitly turn off query cache from the command line query
+ cache will be disabled for the reminder of the server life
+ time. This is because we want to avoid locking the QC specific
+ mutex if query cache isn't going to be used.
+ */
+ if (global_system_variables.query_cache_type == 0)
+ {
+ free_cache();
+ m_cache_status= DISABLED;
+ }
DBUG_VOID_RETURN;
}
@@ -2773,7 +3124,7 @@ void Query_cache::invalidate_table(THD *thd, uchar * key, uint32 key_length)
Lock the query cache and queue all invalidation attempts to avoid
the risk of a race between invalidation, cache inserts and flushes.
*/
- lock();
+ lock(thd);
DBUG_EXECUTE_IF("wait_in_query_cache_invalidate2",
debug_wait_for_kill("wait_in_query_cache_invalidate2"); );
@@ -3554,7 +3905,8 @@ Query_cache::process_and_count_tables(THD *thd, TABLE_LIST *tables_used,
{
DBUG_PRINT("qcache", ("Don't cache statement as it refers to "
"tables with column privileges."));
- thd->lex->safe_to_cache_query= 0;
+ thd->query_cache_is_applicable= 0; // Query can't be cached
+ thd->lex->safe_to_cache_query= 0; // For prepared statements
DBUG_RETURN(0);
}
#endif
@@ -3567,16 +3919,17 @@ Query_cache::process_and_count_tables(THD *thd, TABLE_LIST *tables_used,
}
else
{
- DBUG_PRINT("qcache", ("table: %s db: %s type: %u",
- tables_used->table->s->table_name.str,
- tables_used->table->s->db.str,
- tables_used->table->s->db_type()->db_type));
if (tables_used->derived)
{
+ DBUG_PRINT("qcache", ("table: %s", tables_used->alias));
table_count--;
DBUG_PRINT("qcache", ("derived table skipped"));
continue;
}
+ DBUG_PRINT("qcache", ("table: %s db: %s type: %u",
+ tables_used->table->s->table_name.str,
+ tables_used->table->s->db.str,
+ tables_used->table->s->db_type()->db_type));
*tables_type|= tables_used->table->file->table_cache_type();
/*
@@ -3619,13 +3972,13 @@ Query_cache::process_and_count_tables(THD *thd, TABLE_LIST *tables_used,
*/
TABLE_COUNTER_TYPE
-Query_cache::is_cacheable(THD *thd, uint32 query_len, char *query, LEX *lex,
+Query_cache::is_cacheable(THD *thd, LEX *lex,
TABLE_LIST *tables_used, uint8 *tables_type)
{
TABLE_COUNTER_TYPE table_count;
DBUG_ENTER("Query_cache::is_cacheable");
- if (query_cache_is_cacheable_query(lex) &&
+ if (thd->lex->safe_to_cache_query &&
(thd->variables.query_cache_type == 1 ||
(thd->variables.query_cache_type == 2 && (lex->select_lex.options &
OPTION_TO_QUERY_CACHE))))
@@ -3690,7 +4043,11 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
{
DBUG_PRINT("qcache", ("Handler does not allow caching for %s.%s",
tables_used->db, tables_used->alias));
- thd->lex->safe_to_cache_query= 0; // Don't try to cache this
+ /*
+ As this can change from call to call, don't reset set
+ thd->lex->safe_to_cache_query
+ */
+ thd->query_cache_is_applicable= 0; // Query can't be cached
DBUG_RETURN(1);
}
}
@@ -4148,7 +4505,7 @@ void Query_cache::wreck(uint line, const char *message)
DBUG_PRINT("warning", ("%5d QUERY CACHE WRECK => DISABLED",line));
DBUG_PRINT("warning", ("=================================="));
if (thd)
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_CONNECTION;
cache_dump();
/* check_integrity(0); */ /* Can't call it here because of locks */
bins_dump();
@@ -4783,3 +5140,4 @@ err2:
#endif /* DBUG_OFF */
#endif /*HAVE_QUERY_CACHE*/
+
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
index a3a91127129..b2e88a3c619 100644
--- a/sql/sql_cache.h
+++ b/sql/sql_cache.h
@@ -279,8 +279,11 @@ private:
my_thread_id m_cache_lock_thread_id;
#endif
pthread_cond_t COND_cache_status_changed;
+ uint m_requests_in_progress;
enum Cache_lock_status { UNLOCKED, LOCKED_NO_WAIT, LOCKED };
Cache_lock_status m_cache_lock_status;
+ enum Cache_staus {OK, DISABLE_REQUEST, DISABLED};
+ Cache_staus m_cache_status;
void free_query_internal(Query_cache_block *point);
void invalidate_table_internal(THD *thd, uchar *key, uint32 key_length);
@@ -295,7 +298,7 @@ protected:
2. query block (for operation inside query (query block/results))
Thread doing cache flush releases the mutex once it sets
- m_cache_status flag, so other threads may bypass the cache as
+ m_cache_lock_status flag, so other threads may bypass the cache as
if it is disabled, not waiting for reset to finish. The exception
is other threads that were going to do cache flush---they'll wait
till the end of a flush operation.
@@ -410,7 +413,7 @@ protected:
If query is cacheable return number tables in query
(query without tables not cached)
*/
- TABLE_COUNTER_TYPE is_cacheable(THD *thd, uint32 query_len, char *query,
+ TABLE_COUNTER_TYPE is_cacheable(THD *thd,
LEX *lex, TABLE_LIST *tables_used,
uint8 *tables_type);
TABLE_COUNTER_TYPE process_and_count_tables(THD *thd,
@@ -426,6 +429,10 @@ protected:
uint def_query_hash_size = QUERY_CACHE_DEF_QUERY_HASH_SIZE,
uint def_table_hash_size = QUERY_CACHE_DEF_TABLE_HASH_SIZE);
+ inline bool is_disabled(void) { return m_cache_status != OK; }
+ inline bool is_disable_in_progress(void)
+ { return m_cache_status == DISABLE_REQUEST; }
+
/* initialize cache (mutex) */
void init();
/* resize query cache (return real query size, 0 if disabled) */
@@ -445,22 +452,23 @@ protected:
int send_result_to_client(THD *thd, char *query, uint query_length);
/* Remove all queries that uses any of the listed following tables */
- void invalidate(THD* thd, TABLE_LIST *tables_used,
+ void invalidate(THD *thd, TABLE_LIST *tables_used,
my_bool using_transactions);
- void invalidate(CHANGED_TABLE_LIST *tables_used);
- void invalidate_locked_for_write(TABLE_LIST *tables_used);
- void invalidate(THD* thd, TABLE *table, my_bool using_transactions);
+ void invalidate(THD *thd, CHANGED_TABLE_LIST *tables_used);
+ void invalidate_locked_for_write(THD *thd, TABLE_LIST *tables_used);
+ void invalidate(THD *thd, TABLE *table, my_bool using_transactions);
void invalidate(THD *thd, const char *key, uint32 key_length,
my_bool using_transactions);
/* Remove all queries that uses any of the tables in following database */
- void invalidate(char *db);
+ void invalidate(THD *thd, char *db);
/* Remove all queries that uses any of the listed following table */
void invalidate_by_MyISAM_filename(const char *filename);
void flush();
- void pack(ulong join_limit = QUERY_CACHE_PACK_LIMIT,
+ void pack(THD *thd,
+ ulong join_limit = QUERY_CACHE_PACK_LIMIT,
uint iteration_limit = QUERY_CACHE_PACK_ITERATION);
void destroy();
@@ -488,10 +496,13 @@ protected:
const char *name);
my_bool in_blocks(Query_cache_block * point);
- bool try_lock(bool use_timeout= FALSE);
- void lock(void);
+ enum Cache_try_lock_mode {WAIT, TIMEOUT, TRY};
+ bool try_lock(THD *thd, Cache_try_lock_mode mode= WAIT);
+ void lock(THD *thd);
void lock_and_suspend(void);
void unlock(void);
+
+ void disable_query_cache(THD *thd);
};
extern Query_cache query_cache;
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 5831a4d6251..5b0d0470370 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -44,7 +44,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
@@ -664,7 +666,7 @@ THD::THD()
/* statement id */ 0),
Open_tables_state(refresh_version), rli_fake(NULL), rli_slave(NULL),
lock_id(&main_lock_id),
- user_time(0), in_sub_stmt(0),
+ in_sub_stmt(0),
sql_log_bin_toplevel(false), log_all_errors(0),
binlog_table_maps(0), binlog_flags(0UL),
table_map_for_update(0),
@@ -675,6 +677,7 @@ THD::THD()
stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE),
examined_row_count(0),
global_read_lock(0),
+ global_disable_checkpoint(0),
failed_com_change_user(0),
is_fatal_error(0),
transaction_rollback_request(0),
@@ -705,8 +708,8 @@ 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;
- query_start_used= 0;
+ some_tables_deleted=no_errors=password= 0;
+ query_start_used= query_start_sec_part_used= 0;
count_cuted_fields= CHECK_FIELD_IGNORE;
killed= NOT_KILLED;
col_access=0;
@@ -722,9 +725,11 @@ THD::THD()
#endif
// Must be reset to handle error with THD's created for init of mysqld
lex->current_select= 0;
- start_time=(time_t) 0;
+ user_time.val= start_time= start_time_sec_part= 0;
start_utime= prior_thr_create_utime= 0L;
utime_after_lock= 0L;
+ progress.report_to_client= 0;
+ progress.max_counter= 0;
current_linfo = 0;
slave_thread = 0;
bzero(&variables, sizeof(variables));
@@ -764,6 +769,8 @@ THD::THD()
active_vio = 0;
#endif
pthread_mutex_init(&LOCK_thd_data, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&LOCK_wakeup_ready, MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&COND_wakeup_ready, 0);
pthread_mutex_init(&LOCK_thd_kill, MY_MUTEX_INIT_FAST);
/* Variables with default values */
@@ -812,6 +819,9 @@ THD::THD()
m_binlog_invoker= FALSE;
memset(&invoker_user, 0, sizeof(invoker_user));
memset(&invoker_host, 0, sizeof(invoker_host));
+ prepare_derived_at_open= FALSE;
+ create_tmp_table_for_derived= FALSE;
+ save_prep_leaf_list= FALSE;
}
@@ -985,17 +995,21 @@ void THD::update_stats(void)
void THD::update_all_stats()
{
- time_t save_time;
ulonglong end_cpu_time, end_utime;
double busy_time, cpu_time;
+ /* Reset status variables used by information_schema.processlist */
+ progress.max_counter= 0;
+ progress.max_stage= 0;
+ progress.report= 0;
+
/* This is set at start of query if opt_userstat_running was set */
if (!userstat_running)
return;
end_cpu_time= my_getcputime();
- end_utime= my_micro_time_and_time(&save_time);
- busy_time= (end_utime - start_utime) / 1000000.0;
+ end_utime= microsecond_interval_timer();
+ busy_time= (end_utime - start_utime) / 1000000.0;
cpu_time= (end_cpu_time - start_cpu_time) / 10000000.0;
/* In case there are bad values, 2629743 is the #seconds in a month. */
if (cpu_time > 2629743.0)
@@ -1003,7 +1017,8 @@ void THD::update_all_stats()
status_var_add(status_var.cpu_time, cpu_time);
status_var_add(status_var.busy_time, busy_time);
- update_global_user_stats(this, TRUE, save_time);
+ update_global_user_stats(this, TRUE, my_time(0));
+ // Has to be updated after update_global_user_stats()
userstat_running= 0;
}
@@ -1158,6 +1173,8 @@ THD::~THD()
free_root(&transaction.mem_root,MYF(0));
#endif
mysys_var=0; // Safety (shouldn't be needed)
+ pthread_cond_destroy(&COND_wakeup_ready);
+ pthread_mutex_destroy(&LOCK_wakeup_ready);
pthread_mutex_destroy(&LOCK_thd_data);
pthread_mutex_destroy(&LOCK_thd_kill);
#ifndef DBUG_OFF
@@ -1206,6 +1223,7 @@ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
to_var->bytes_sent+= from_var->bytes_sent;
to_var->rows_read+= from_var->rows_read;
to_var->rows_sent+= from_var->rows_sent;
+ to_var->rows_tmp_read+= from_var->rows_tmp_read;
to_var->binlog_bytes_written+= from_var->binlog_bytes_written;
to_var->cpu_time+= from_var->cpu_time;
to_var->busy_time+= from_var->busy_time;
@@ -1241,6 +1259,7 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
to_var->bytes_sent+= from_var->bytes_sent - dec_var->bytes_sent;
to_var->rows_read+= from_var->rows_read - dec_var->rows_read;
to_var->rows_sent+= from_var->rows_sent - dec_var->rows_sent;
+ to_var->rows_tmp_read+= from_var->rows_tmp_read - dec_var->rows_tmp_read;
to_var->binlog_bytes_written+= from_var->binlog_bytes_written -
dec_var->binlog_bytes_written;
to_var->cpu_time+= from_var->cpu_time - dec_var->cpu_time;
@@ -1256,7 +1275,7 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
#endif
-void THD::awake(THD::killed_state state_to_set)
+void THD::awake(killed_state state_to_set)
{
DBUG_ENTER("THD::awake");
DBUG_PRINT("enter", ("this: 0x%lx thread_id=%lu killed_state=%d",
@@ -1275,7 +1294,7 @@ void THD::awake(THD::killed_state state_to_set)
"KILLED");
}
killed= state_to_set;
- if (state_to_set != THD::KILL_QUERY)
+ if (state_to_set >= KILL_CONNECTION)
{
thr_alarm_kill(thread_id);
if (!slave_thread)
@@ -1357,6 +1376,38 @@ void THD::awake(THD::killed_state state_to_set)
DBUG_VOID_RETURN;
}
+
+/*
+ Get error number for killed state
+ Note that the error message can't have any parameters.
+ See thd::kill_message()
+*/
+
+int killed_errno(killed_state killed)
+{
+ switch (killed) {
+ case NOT_KILLED:
+ case KILL_HARD_BIT:
+ return 0; // Probably wrong usage
+ case KILL_BAD_DATA:
+ case KILL_BAD_DATA_HARD:
+ return 0; // Not a real error
+ case KILL_CONNECTION:
+ case KILL_CONNECTION_HARD:
+ case KILL_SYSTEM_THREAD:
+ case KILL_SYSTEM_THREAD_HARD:
+ return ER_CONNECTION_KILLED;
+ case KILL_QUERY:
+ case KILL_QUERY_HARD:
+ return ER_QUERY_INTERRUPTED;
+ case KILL_SERVER:
+ case KILL_SERVER_HARD:
+ return ER_SERVER_SHUTDOWN;
+ }
+ return 0; // Keep compiler happy
+}
+
+
/*
Remember the location of thread info, the structure needed for
sql_alloc() and the structure for the net buffer
@@ -2448,7 +2499,6 @@ int 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;
@@ -2551,7 +2601,8 @@ int select_singlerow_subselect::send_data(List<Item> &items)
Item_singlerow_subselect *it= (Item_singlerow_subselect *)item;
if (it->assigned())
{
- my_message(ER_SUBQUERY_NO_1_ROW, ER(ER_SUBQUERY_NO_1_ROW), MYF(0));
+ my_message(ER_SUBQUERY_NO_1_ROW, ER(ER_SUBQUERY_NO_1_ROW),
+ MYF(current_thd->lex->ignore ? ME_JUST_WARNING : 0));
DBUG_RETURN(1);
}
if (unit->offset_limit_cnt)
@@ -2608,6 +2659,7 @@ int select_max_min_finder_subselect::send_data(List<Item> &items)
op= &select_max_min_finder_subselect::cmp_decimal;
break;
case ROW_RESULT:
+ case TIME_RESULT:
case IMPOSSIBLE_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
@@ -2753,6 +2805,7 @@ void Query_arena::free_items()
for (; free_list; free_list= next)
{
next= free_list->next;
+ DBUG_ASSERT(free_list != next);
free_list->delete_self();
}
/* Postcondition: free_list is 0 */
@@ -3096,6 +3149,99 @@ 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,
+ bool create_table)
+{
+ 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
+*/
+
+int 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;
+ int res;
+
+ if ((res= select_union::send_data(items)))
+ return res;
+ if (table->null_catch_flags & REJECT_ROW_DUE_TO_NULL_FIELDS)
+ {
+ table->null_catch_flags&= ~REJECT_ROW_DUE_TO_NULL_FIELDS;
+ return 0;
+ }
+ /* 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_result())
+ {
+ ++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
****************************************************************************/
@@ -3109,6 +3255,10 @@ void TMP_TABLE_PARAM::init()
quick_group= 1;
table_charset= 0;
precomputed_group_by= 0;
+ bit_fields_as_long= 0;
+ materialized_subquery= 0;
+ force_not_null_cols= 0;
+ skip_create_table= 0;
DBUG_VOID_RETURN;
}
@@ -3322,15 +3472,128 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
@param thd user thread
@retval 0 the user thread is active
@retval 1 the user thread has been killed
+
+ This is used to signal a storage engine if it should be killed.
*/
+
extern "C" int thd_killed(const MYSQL_THD thd)
{
- if (thd->killed == THD::NOT_KILLED || thd->killed == THD::KILL_BAD_DATA ||
- thd->killed == THD::KILL_SYSTEM_THREAD)
+ if (!(thd->killed & KILL_HARD_BIT))
return 0;
return thd->killed;
}
+
+/**
+ Send an out-of-band progress report to the client
+
+ The report is sent every 'thd->...progress_report_time' second,
+ however not more often than global.progress_report_time.
+ If global.progress_report_time is 0, then don't send progress reports, but
+ check every second if the value has changed
+*/
+
+static void thd_send_progress(THD *thd)
+{
+ /* Check if we should send the client a progress report */
+ ulonglong report_time= my_interval_timer();
+ if (report_time > thd->progress.next_report_time)
+ {
+ uint seconds_to_next= max(thd->variables.progress_report_time,
+ global_system_variables.progress_report_time);
+ if (seconds_to_next == 0) // Turned off
+ seconds_to_next= 1; // Check again after 1 second
+
+ thd->progress.next_report_time= (report_time +
+ seconds_to_next * 1000000000ULL);
+ if (global_system_variables.progress_report_time &&
+ thd->variables.progress_report_time)
+ net_send_progress_packet(thd);
+ }
+}
+
+
+/** Initialize progress report handling **/
+
+extern "C" void thd_progress_init(MYSQL_THD thd, uint max_stage)
+{
+ /*
+ Send progress reports to clients that supports it, if the command
+ is a high level command (like ALTER TABLE) and we are not in a
+ stored procedure
+ */
+ thd->progress.report= ((thd->client_capabilities & CLIENT_PROGRESS) &&
+ thd->progress.report_to_client &&
+ !thd->in_sub_stmt);
+ thd->progress.next_report_time= 0;
+ thd->progress.stage= 0;
+ thd->progress.counter= thd->progress.max_counter= 0;
+ thd->progress.max_stage= max_stage;
+}
+
+
+/* Inform processlist and the client that some progress has been made */
+
+extern "C" void thd_progress_report(MYSQL_THD thd,
+ ulonglong progress, ulonglong max_progress)
+{
+ if (thd->progress.max_counter != max_progress) // Simple optimization
+ {
+ pthread_mutex_lock(&thd->LOCK_thd_data);
+ thd->progress.counter= progress;
+ thd->progress.max_counter= max_progress;
+ pthread_mutex_unlock(&thd->LOCK_thd_data);
+ }
+ else
+ thd->progress.counter= progress;
+
+ if (thd->progress.report)
+ thd_send_progress(thd);
+}
+
+/**
+ Move to next stage in process list handling
+
+ This will reset the timer to ensure the progress is sent to the client
+ if client progress reports are activated.
+*/
+
+extern "C" void thd_progress_next_stage(MYSQL_THD thd)
+{
+ pthread_mutex_lock(&thd->LOCK_thd_data);
+ thd->progress.stage++;
+ thd->progress.counter= 0;
+ DBUG_ASSERT(thd->progress.stage < thd->progress.max_stage);
+ pthread_mutex_unlock(&thd->LOCK_thd_data);
+ if (thd->progress.report)
+ {
+ thd->progress.next_report_time= 0; // Send new stage info
+ thd_send_progress(thd);
+ }
+}
+
+/**
+ Disable reporting of progress in process list.
+
+ @note
+ This function is safe to call even if one has not called thd_progress_init.
+
+ This function should be called by all parts that does progress
+ reporting to ensure that progress list doesn't contain 100 % done
+ forever.
+*/
+
+
+extern "C" void thd_progress_end(MYSQL_THD thd)
+{
+ /*
+ It's enough to reset max_counter to set disable progress indicator
+ in processlist.
+ */
+ thd->progress.max_counter= 0;
+}
+
+
/**
Return the thread id of a user thread
@param thd user thread
@@ -3590,16 +3853,6 @@ void mark_transaction_to_rollback(THD *thd, bool all)
{
thd->is_fatal_sub_stmt_error= TRUE;
thd->transaction_rollback_request= all;
- /*
- Aborted transactions can not be IGNOREd.
- Switch off the IGNORE flag for the current
- SELECT_LEX. This should allow my_error()
- to report the error and abort the execution
- flow, even in presence
- of IGNORE clause.
- */
- if (thd->lex->current_select)
- thd->lex->current_select->no_error= FALSE;
}
}
/***************************************************************************
@@ -4220,6 +4473,25 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
DBUG_RETURN(0);
}
+void
+THD::wait_for_wakeup_ready()
+{
+ pthread_mutex_lock(&LOCK_wakeup_ready);
+ while (!wakeup_ready)
+ pthread_cond_wait(&COND_wakeup_ready, &LOCK_wakeup_ready);
+ pthread_mutex_unlock(&LOCK_wakeup_ready);
+}
+
+void
+THD::signal_wakeup_ready()
+{
+ pthread_mutex_lock(&LOCK_wakeup_ready);
+ wakeup_ready= true;
+ pthread_mutex_unlock(&LOCK_wakeup_ready);
+ pthread_cond_signal(&COND_wakeup_ready);
+}
+
+
bool Discrete_intervals_list::append(ulonglong start, ulonglong val,
ulonglong incr)
{
diff --git a/sql/sql_class.h b/sql/sql_class.h
index d55200efea4..48d8560dcfc 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -26,6 +26,92 @@
#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 List_iterator_fast for Items
+*/
+
+class Item_iterator_list: public Item_iterator
+{
+ List_iterator<Item> list;
+public:
+ Item_iterator_list(List_iterator<Item> &arg_list):
+ list(arg_list) {}
+ void open() { list.rewind(); }
+ Item *next() { return (list++); }
+ void close() {}
+};
+
+
+/**
+ Item iterator over Item interface for rows
+*/
+
+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
@@ -120,7 +206,7 @@ typedef struct st_user_var_events
#define RP_LOCK_LOG_IS_ALREADY_LOCKED 1
#define RP_FORCE_ROTATE 2
-
+#define RP_BINLOG_CHECKSUM_ALG_CHANGE 4
/*
The COPY_INFO structure is used by INSERT/REPLACE code.
The schema of the row counting by the INSERT/INSERT ... ON DUPLICATE KEY
@@ -278,6 +364,38 @@ public:
LEX_COLUMN (const String& x,const uint& y ): column (x),rights (y) {}
};
+
+/* Note: these states are actually bit coded with HARD */
+enum killed_state
+{
+ NOT_KILLED= 0,
+ KILL_HARD_BIT= 1, /* Bit for HARD KILL */
+ KILL_BAD_DATA= 2,
+ KILL_BAD_DATA_HARD= 3,
+ KILL_QUERY= 4,
+ KILL_QUERY_HARD= 5,
+ /*
+ All of the following killed states will kill the connection
+ KILL_CONNECTION must be the first of these!
+ */
+ KILL_CONNECTION= 6,
+ KILL_CONNECTION_HARD= 7,
+ KILL_SYSTEM_THREAD= 8,
+ KILL_SYSTEM_THREAD_HARD= 9,
+ KILL_SERVER= 10,
+ KILL_SERVER_HARD= 11
+};
+
+extern int killed_errno(killed_state killed);
+#define killed_mask_hard(killed) ((killed_state) ((killed) & ~KILL_HARD_BIT))
+
+enum killed_type
+{
+ KILL_TYPE_ID,
+ KILL_TYPE_USER
+};
+
+
#include "sql_lex.h" /* Must be here */
class Delayed_insert;
@@ -313,11 +431,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;
@@ -325,7 +445,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;
@@ -344,8 +463,12 @@ struct system_variables
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 */
@@ -370,6 +493,8 @@ struct system_variables
ulong ndb_index_stat_cache_entries;
ulong ndb_index_stat_update_freq;
ulong binlog_format; // binlog format for this thd (see enum_binlog_format)
+ ulong progress_report_time;
+ my_bool binlog_annotate_row_events;
my_bool binlog_direct_non_trans_update;
/*
In slave thread we need to know in behalf of which
@@ -446,10 +571,25 @@ typedef struct system_status_var
ulong ha_read_prev_count;
ulong ha_read_rnd_count;
ulong ha_read_rnd_next_count;
+ ulong ha_read_rnd_deleted_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_mrr_init_count;
+ ulong ha_mrr_key_refills_count;
+ ulong ha_mrr_rowid_refills_count;
+
ulong ha_rollback_count;
ulong ha_update_count;
ulong ha_write_count;
+ /* The following are for internal temporary tables */
+ ulong ha_tmp_update_count;
+ ulong ha_tmp_write_count;
ulong ha_prepare_count;
+ ulong ha_icp_attempts;
+ ulong ha_icp_match;
ulong ha_discover_count;
ulong ha_savepoint_count;
ulong ha_savepoint_rollback_count;
@@ -501,6 +641,7 @@ typedef struct system_status_var
ulonglong bytes_sent;
ulonglong rows_read;
ulonglong rows_sent;
+ ulonglong rows_tmp_read;
ulonglong binlog_bytes_written;
double last_query_cost;
double cpu_time, busy_time;
@@ -678,8 +819,12 @@ public:
ENGINE INNODB STATUS.
*/
LEX_STRING query_string;
+ /*
+ If opt_query_cache_strip_comments is set, this contains query without
+ comments. If not set, it contains pointer to query_string.
+ */
+ String base_query;
Server_side_cursor *cursor;
-
inline char *query() { return query_string.str; }
inline uint32 query_length() { return (uint32)query_string.length; }
void set_query_inner(char *query_arg, uint32 query_length_arg);
@@ -700,7 +845,8 @@ public:
char *db;
size_t db_length;
-public:
+ /* This is set to 1 of last call to send_result_to_client() was ok */
+ my_bool query_cache_is_applicable;
/* This constructor is called for backup statements */
Statement() {}
@@ -1445,7 +1591,6 @@ public:
*/
const char *where;
- double tmp_double_value; /* Used in set_var.cc */
ulong client_capabilities; /* What the client supports */
ulong max_client_packet_length;
@@ -1469,11 +1614,32 @@ public:
uint32 file_id; // for LOAD DATA INFILE
/* remote (peer) port */
uint16 peer_port;
- time_t start_time, user_time;
+ my_time_t start_time; // start_time and its sec_part
+ ulong start_time_sec_part; // are almost always used separately
+ my_hrtime_t user_time;
// track down slow pthread_create
ulonglong prior_thr_create_utime, thr_create_utime;
ulonglong start_utime, utime_after_lock;
+ // Process indicator
+ struct {
+ /*
+ true, if the currently running command can send progress report
+ packets to a client. Set by mysql_execute_command() for safe commands
+ See CF_REPORT_PROGRESS
+ */
+ bool report_to_client;
+ /*
+ true, if we will send progress report packets to a client
+ (client has requested them, see CLIENT_PROGRESS; report_to_client
+ is true; not in sub-statement)
+ */
+ bool report;
+ uint stage, max_stage;
+ ulonglong counter, max_counter;
+ ulonglong next_report_time;
+ } progress;
+
thr_lock_type update_lock_default;
Delayed_insert *di;
@@ -1489,6 +1655,16 @@ public:
/* container for handler's private per-connection data */
Ha_data ha_data[MAX_HA];
+ bool prepare_derived_at_open;
+
+ /*
+ To signal that the tmp table to be created is created for materialized
+ derived table or a view.
+ */
+ bool create_tmp_table_for_derived;
+
+ bool save_prep_leaf_list;
+
#ifndef MYSQL_CLIENT
int binlog_setup_trx_data();
@@ -1497,7 +1673,8 @@ public:
*/
void binlog_start_trans_and_stmt();
void binlog_set_stmt_begin();
- int binlog_write_table_map(TABLE *table, bool is_transactional);
+ int binlog_write_table_map(TABLE *table, bool is_transactional,
+ my_bool *with_annotate= 0);
int binlog_write_row(TABLE* table, bool is_transactional,
MY_BITMAP const* cols, size_t colcnt,
const uchar *buf);
@@ -1831,7 +2008,7 @@ public:
ulong query_plan_fsort_passes;
pthread_t real_id; /* For debugging */
my_thread_id thread_id;
- uint tmp_table, global_read_lock;
+ uint tmp_table, global_read_lock, global_disable_checkpoint;
uint server_status,open_options;
enum enum_thread_type system_thread;
uint select_number; //number of select (used for EXPLAIN)
@@ -1842,16 +2019,6 @@ public:
DYNAMIC_ARRAY user_var_events; /* For user variables replication */
MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */
- enum killed_state
- {
- NOT_KILLED=0,
- KILL_BAD_DATA=1,
- KILL_CONNECTION=ER_SERVER_SHUTDOWN,
- KILL_SYSTEM_THREAD=ER_NEW_ABORTING_CONNECTION, /* Kill connection nicely */
- KILL_QUERY=ER_QUERY_INTERRUPTED,
- KILL_SERVER, /* Placeholder for shortdown */
- KILLED_NO_VALUE /* means neither of the states */
- };
killed_state volatile killed;
/* scramble - random string sent to client on handshake */
@@ -1860,7 +2027,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 */
@@ -1893,6 +2060,7 @@ public:
*/
bool is_fatal_sub_stmt_error;
bool query_start_used, rand_used, time_zone_used;
+ bool query_start_sec_part_used;
/* for IS NULL => = last_insert_id() fix in remove_eq_conds() */
bool substitute_null_with_insert_id;
bool in_lock_tables;
@@ -1953,6 +2121,7 @@ public:
long long_value;
ulong ulong_value;
ulonglong ulonglong_value;
+ double double_value;
} sys_var_tmp;
struct {
@@ -2034,7 +2203,7 @@ public:
}
void close_active_vio();
#endif
- void awake(THD::killed_state state_to_set);
+ void awake(killed_state state_to_set);
#ifndef MYSQL_CLIENT
enum enum_binlog_query_type {
@@ -2092,30 +2261,41 @@ public:
proc_info = old_msg;
pthread_mutex_unlock(&mysys_var->mutex);
}
- inline time_t query_start() { query_start_used=1; return start_time; }
+ inline my_time_t query_start() { query_start_used=1; return start_time; }
+ inline ulong query_start_sec_part()
+ { query_start_sec_part_used=1; return start_time_sec_part; }
+ inline void set_current_time()
+ {
+ my_hrtime_t hrtime= my_hrtime();
+ start_time= hrtime_to_my_time(hrtime);
+ start_time_sec_part= hrtime_sec_part(hrtime);
+ }
inline void set_time()
{
- if (user_time)
+ if (user_time.val)
{
- start_time= user_time;
- start_utime= utime_after_lock= my_micro_time();
+ start_time= hrtime_to_my_time(user_time);
+ start_time_sec_part= hrtime_sec_part(user_time);
}
else
- start_utime= utime_after_lock= my_micro_time_and_time(&start_time);
+ set_current_time();
+ start_utime= utime_after_lock= microsecond_interval_timer();
}
- inline void set_current_time() { start_time= my_time(MY_WME); }
- inline void set_time(time_t t)
+ inline void set_time(my_hrtime_t t)
{
- start_time= user_time= t;
- start_utime= utime_after_lock= my_micro_time();
+ user_time= t;
+ start_time= hrtime_to_my_time(user_time);
+ start_time_sec_part= hrtime_sec_part(user_time);
+ start_utime= utime_after_lock= microsecond_interval_timer();
}
- /*TODO: this will be obsolete when we have support for 64 bit my_time_t */
- inline bool is_valid_time()
- {
- return (IS_TIME_T_VALID_FOR_TIMESTAMP(start_time));
+ inline void set_time(my_time_t t, ulong sec_part)
+ {
+ my_hrtime_t hrtime= { hrtime_from_time(t) + sec_part };
+ set_time(hrtime);
}
- void set_time_after_lock() { utime_after_lock= my_micro_time(); }
- ulonglong current_utime() { return my_micro_time(); }
+ void set_time_after_lock() { utime_after_lock= microsecond_interval_timer(); }
+ ulonglong current_utime() { return microsecond_interval_timer(); }
+
inline ulonglong found_rows(void)
{
return limit_found_rows;
@@ -2237,7 +2417,11 @@ public:
{
if (!stmt_arena->is_conventional())
check_and_register_item_tree_change(place, new_value, mem_root);
- *place= *new_value;
+ /*
+ We have to use memcpy instead of *place= *new_value merge to
+ avoid problems with strict aliasing.
+ */
+ memcpy((char*) place, new_value, sizeof(*new_value));
}
void nocheck_register_item_tree_change(Item **place, Item *old_value,
MEM_ROOT *runtime_memroot);
@@ -2252,18 +2436,13 @@ public:
void end_statement();
inline int killed_errno() const
{
- killed_state killed_val; /* to cache the volatile 'killed' */
- return (killed_val= killed) != KILL_BAD_DATA ? killed_val : 0;
+ return ::killed_errno(killed);
}
inline void send_kill_message() const
{
int err= killed_errno();
if (err)
- {
- if ((err == KILL_CONNECTION) && !shutdown_in_progress)
- err = KILL_QUERY;
my_message(err, ER(err), MYF(0));
- }
}
/* return TRUE if we will abort query if we make a warning now */
inline bool really_abort_on_warning()
@@ -2467,6 +2646,14 @@ public:
return backup;
}
+ void clear_wakeup_ready() { wakeup_ready= false; }
+ /*
+ Sleep waiting for others to wake us up with signal_wakeup_ready().
+ Must call clear_wakeup_ready() before waiting.
+ */
+ void wait_for_wakeup_ready();
+ /* Wake this thread up from wait_for_wakeup_ready(). */
+ void signal_wakeup_ready();
private:
/** The current internal error handler for this thread, or NULL. */
Internal_error_handler *m_internal_handler;
@@ -2505,6 +2692,16 @@ private:
*/
LEX_STRING invoker_user;
LEX_STRING invoker_host;
+ /*
+ Flag, mutex and condition for a thread to wait for a signal from another
+ thread.
+
+ Currently used to wait for group commit to complete, can also be used for
+ other purposes.
+ */
+ bool wakeup_ready;
+ pthread_mutex_t LOCK_wakeup_ready;
+ pthread_cond_t COND_wakeup_ready;
};
/** A short cut for thd->main_da.set_ok_status(). */
@@ -2533,6 +2730,27 @@ my_eof(THD *thd)
/*
+ These functions are for making it later easy to add strict
+ checking for all date handling.
+*/
+
+extern my_bool strict_date_checking;
+
+inline ulong sql_mode_for_dates(THD *thd)
+{
+ if (unlikely(strict_date_checking))
+ return (thd->variables.sql_mode &
+ (MODE_NO_ZERO_DATE | MODE_NO_ZERO_IN_DATE |
+ MODE_INVALID_DATES));
+ return (thd->variables.sql_mode & MODE_INVALID_DATES);
+}
+
+inline ulong sql_mode_for_dates()
+{
+ return sql_mode_for_dates(current_thd);
+}
+
+/*
Used to hold information about file and file structure in exchange
via non-DB file (...INTO OUTFILE..., ...LOAD DATA...)
XXX: We never call destructor for objects of this class.
@@ -2615,6 +2833,7 @@ public:
#else
void begin_dataset() {}
#endif
+ virtual void update_used_tables() {}
};
@@ -2627,7 +2846,12 @@ public:
class select_result_interceptor: public select_result
{
public:
- select_result_interceptor() {} /* Remove gcc warning */
+ select_result_interceptor()
+ {
+ DBUG_ENTER("select_result_interceptor::select_result_interceptor");
+ DBUG_PRINT("enter", ("this 0x%lx", (ulong) this));
+ DBUG_VOID_RETURN;
+ } /* Remove gcc warning */
uint field_count(List<Item> &fields) const { return 0; }
bool send_fields(List<Item> &fields, uint flag) { return FALSE; }
};
@@ -2870,6 +3094,10 @@ public:
uint convert_blob_length;
CHARSET_INFO *table_charset;
bool schema_table;
+ /* TRUE if the temp table is created for subquery materialization. */
+ bool materialized_subquery;
+ /* TRUE if all columns of the table are guaranteed to be non-nullable */
+ bool force_not_null_cols;
/*
True if GROUP BY and its aggregate functions are already computed
by a table access method (e.g. by loose index scan). In this case
@@ -2878,11 +3106,24 @@ 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), materialized_subquery(0), force_not_null_cols(0),
+ precomputed_group_by(0),
+ force_copy_fields(0), bit_fields_as_long(0), skip_create_table(0)
{}
~TMP_TABLE_PARAM()
{
@@ -2902,19 +3143,25 @@ public:
class select_union :public select_result_interceptor
{
+public:
TMP_TABLE_PARAM tmp_table_param;
+ int write_err; /* Error code from the last send_data->ha_write_row call. */
public:
TABLE *table;
+ ha_rows records;
- select_union() :table(0) {}
+ select_union() :write_err(0), table(0), records(0) { tmp_table_param.init(); }
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
int 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,
+ bool create_table);
+ TMP_TABLE_PARAM *get_tmp_table_param() { return &tmp_table_param; }
};
/* Base subselect interface class */
@@ -2938,6 +3185,74 @@ public:
int 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() { tmp_table_param.init(); }
+ bool create_result_table(THD *thd, List<Item> *column_types,
+ bool is_distinct, ulonglong options,
+ const char *alias,
+ bool bit_fields_as_long,
+ bool create_table);
+ bool init_result_table(ulonglong select_options);
+ int 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
{
@@ -2967,6 +3282,67 @@ public:
int 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 {
@@ -3050,6 +3426,7 @@ class user_var_entry
DTCollation collation;
};
+
/*
Unique -- class for unique (removing of duplicates).
Puts all values to the TREE. If the tree becomes too big,
@@ -3066,30 +3443,46 @@ class Unique :public Sql_alloc
IO_CACHE file;
TREE tree;
uchar *record_pointers;
+ ulong filtered_out_elems;
bool flush();
uint size;
+ uint full_size;
+ uint min_dupl_count; /* always 0 for unions, > 0 for intersections */
bool merge(TABLE *table, uchar *buff, bool without_last_merge);
public:
ulong elements;
Unique(qsort_cmp2 comp_func, void *comp_func_fixed_arg,
- uint size_arg, ulonglong max_in_memory_size_arg);
+ uint size_arg, ulonglong max_in_memory_size_arg,
+ uint min_dupl_count_arg= 0);
~Unique();
ulong elements_in_tree() { return tree.elements_in_tree; }
inline bool unique_add(void *ptr)
{
DBUG_ENTER("unique_add");
DBUG_PRINT("info", ("tree %u - %lu", tree.elements_in_tree, max_elements));
- if (tree.elements_in_tree > max_elements && flush())
+ if (!(tree.flag & TREE_ONLY_DUPS) &&
+ tree.elements_in_tree >= max_elements && flush())
DBUG_RETURN(1);
DBUG_RETURN(!tree_insert(&tree, ptr, 0, tree.custom_arg));
}
+ bool is_in_memory() { return (my_b_tell(&file) == 0); }
+ void close_for_expansion() { tree.flag= TREE_ONLY_DUPS; }
+
bool get(TABLE *table);
- static double get_use_cost(uint *buffer, uint nkeys, uint key_size,
- ulonglong max_in_memory_size);
- inline static int get_cost_calc_buff_size(ulong nkeys, uint key_size,
+
+ /* Cost of searching for an element in the tree */
+ inline static double get_search_cost(ulonglong tree_elems, uint compare_factor)
+ {
+ return log((double) tree_elems) / (compare_factor * M_LN2);
+ }
+
+ static double get_use_cost(uint *buffer, size_t nkeys, uint key_size,
+ ulonglong max_in_memory_size, uint compare_factor,
+ bool intersect_fl, bool *in_memory);
+ inline static int get_cost_calc_buff_size(size_t nkeys, uint key_size,
ulonglong max_in_memory_size)
{
register ulonglong max_elems_in_tree=
@@ -3105,6 +3498,11 @@ public:
friend int unique_write_to_file(uchar* key, element_count count, Unique *unique);
friend int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique);
+
+ friend int unique_write_to_file_with_count(uchar* key, element_count count,
+ Unique *unique);
+ friend int unique_intersect_write_to_ptrs(uchar* key, element_count count,
+ Unique *unique);
};
@@ -3144,7 +3542,7 @@ public:
class multi_update :public select_result_interceptor
{
TABLE_LIST *all_tables; /* query/update command tables */
- TABLE_LIST *leaves; /* list of leves of join table tree */
+ List<TABLE_LIST> *leaves; /* list of leves of join table tree */
TABLE_LIST *update_tables, *table_being_updated;
TABLE **tmp_tables, *main_table, *table_to_update;
TMP_TABLE_PARAM *tmp_table_param;
@@ -3170,7 +3568,7 @@ class multi_update :public select_result_interceptor
bool error_handled;
public:
- multi_update(TABLE_LIST *ut, TABLE_LIST *leaves_list,
+ multi_update(TABLE_LIST *ut, List<TABLE_LIST> *leaves_list,
List<Item> *fields, List<Item> *values,
enum_duplicates handle_duplicates, bool ignore);
~multi_update();
@@ -3181,6 +3579,7 @@ public:
int do_updates();
bool send_eof();
virtual void abort();
+ void update_used_tables();
};
class my_var : public Sql_alloc {
@@ -3232,6 +3631,7 @@ public:
#define CF_STATUS_COMMAND 4
#define CF_SHOW_TABLE_COMMAND 8
#define CF_WRITE_LOGS_COMMAND 16
+
/**
Must be set for SQL statements that may contain
Item expressions and/or use joins and tables.
@@ -3246,6 +3646,7 @@ public:
joins are currently prohibited in these statements.
*/
#define CF_REEXECUTION_FRAGILE 32
+#define CF_REPORT_PROGRESS 64
/* Functions in sql_class.cc */
@@ -3281,16 +3682,24 @@ inline int handler::ha_index_read_map(uchar * buf, const uchar * key,
return error;
}
+
+/*
+ @note: Other index lookup/navigation functions require prior
+ handler->index_init() call. This function is different, it requires
+ that the scan is not initialized, and accepts "uint index" as an argument.
+*/
+
inline int handler::ha_index_read_idx_map(uchar * buf, uint index,
const uchar * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
+ DBUG_ASSERT(inited==NONE);
increment_statistics(&SSV::ha_read_key_count);
int error= index_read_idx_map(buf, index, key, keypart_map, find_flag);
if (!error)
{
- rows_read++;
+ update_rows_read();
index_rows_read[index]++;
}
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -3357,17 +3766,25 @@ inline int handler::ha_ft_read(uchar *buf)
{
int error= ft_read(buf);
if (!error)
- rows_read++;
+ update_rows_read();
+
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
inline int handler::ha_rnd_next(uchar *buf)
{
- increment_statistics(&SSV::ha_read_rnd_next_count);
int error= rnd_next(buf);
if (!error)
- rows_read++;
+ {
+ update_rows_read();
+ increment_statistics(&SSV::ha_read_rnd_next_count);
+ }
+ else if (error == HA_ERR_RECORD_DELETED)
+ increment_statistics(&SSV::ha_read_rnd_deleted_count);
+ else
+ increment_statistics(&SSV::ha_read_rnd_next_count);
+
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
@@ -3377,7 +3794,7 @@ inline int handler::ha_rnd_pos(uchar *buf, uchar *pos)
increment_statistics(&SSV::ha_read_rnd_count);
int error= rnd_pos(buf, pos);
if (!error)
- rows_read++;
+ update_rows_read();
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
@@ -3386,7 +3803,7 @@ inline int handler::ha_rnd_pos_by_record(uchar *buf)
{
int error= rnd_pos_by_record(buf);
if (!error)
- rows_read++;
+ update_rows_read();
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
@@ -3395,10 +3812,21 @@ inline int handler::ha_read_first_row(uchar *buf, uint primary_key)
{
int error= read_first_row(buf, primary_key);
if (!error)
- rows_read++;
+ update_rows_read();
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
+inline int handler::ha_write_tmp_row(uchar *buf)
+{
+ increment_statistics(&SSV::ha_tmp_write_count);
+ return write_row(buf);
+}
+
+inline int handler::ha_update_tmp_row(const uchar *old_data, uchar *new_data)
+{
+ increment_statistics(&SSV::ha_tmp_update_count);
+ return update_row(old_data, new_data);
+}
#endif /* MYSQL_SERVER */
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 511fbe07459..89df1835704 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -115,8 +115,11 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc)
DBUG_ENTER("check_for_max_user_connections");
(void) pthread_mutex_lock(&LOCK_user_conn);
+
+ /* Root is not affected by the value of max_user_connections */
if (max_user_connections && !uc->user_resources.user_conn &&
- max_user_connections < (uint) uc->connections)
+ max_user_connections < uc->connections &&
+ !(thd->security_ctx->master_access & SUPER_ACL))
{
my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user);
goto end;
@@ -204,7 +207,7 @@ void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
/* If more than a hour since last check, reset resource checking */
if (check_time - uc->reset_utime >= LL(3600000000))
{
- uc->questions=1;
+ uc->questions=0;
uc->updates=0;
uc->conn_per_hour=0;
uc->reset_utime= check_time;
@@ -233,7 +236,7 @@ bool check_mqh(THD *thd, uint check_command)
if (uc->user_resources.questions &&
uc->questions++ >= uc->user_resources.questions)
{
- my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_questions",
+ my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_queries_per_hour",
(long) uc->user_resources.questions);
error=1;
goto end;
@@ -245,7 +248,7 @@ bool check_mqh(THD *thd, uint check_command)
(sql_command_flags[check_command] & CF_CHANGES_DATA) &&
uc->updates++ >= uc->user_resources.updates)
{
- my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_updates",
+ my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_updates_per_hour",
(long) uc->user_resources.updates);
error=1;
goto end;
@@ -691,6 +694,7 @@ static void update_global_user_stats_with_user(THD *thd,
user_stats->binlog_bytes_written+=
(thd->status_var.binlog_bytes_written -
thd->org_status_var.binlog_bytes_written);
+ /* We are not counting rows in internal temporary tables here ! */
user_stats->rows_read+= (thd->status_var.rows_read -
thd->org_status_var.rows_read);
user_stats->rows_sent+= (thd->status_var.rows_sent -
@@ -1137,7 +1141,7 @@ void prepare_new_connection_state(THD* thd)
thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
net_end_statement(thd);
- thd->killed = THD::KILL_CONNECTION;
+ thd->killed = KILL_CONNECTION;
return;
}
@@ -1169,7 +1173,9 @@ pthread_handler_t handle_one_connection(void *arg)
{
THD *thd= (THD*) arg;
- thd->thr_create_utime= my_micro_time();
+ thd->thr_create_utime= microsecond_interval_timer();
+ /* We need to set this because of time_out_user_resource_limits */
+ thd->start_utime= thd->thr_create_utime;
if (thread_scheduler.init_new_connection_thread())
{
@@ -1220,8 +1226,7 @@ pthread_handler_t handle_one_connection(void *arg)
prepare_new_connection_state(thd);
while (!net->error && net->vio != 0 &&
- thd->killed != THD::KILL_CONNECTION &&
- thd->killed != THD::KILL_SERVER)
+ thd->killed < KILL_CONNECTION)
{
if (do_command(thd))
break;
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 630ba787c72..c171017a993 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -365,7 +365,6 @@ Sensitive_cursor::open(JOIN *join_arg)
join= join_arg;
THD *thd= join->thd;
/* First non-constant table */
- JOIN_TAB *join_tab= join->join_tab + join->const_tables;
DBUG_ENTER("Sensitive_cursor::open");
join->change_result(result);
@@ -383,26 +382,29 @@ Sensitive_cursor::open(JOIN *join_arg)
/* Prepare JOIN for reading rows. */
join->tmp_table= 0;
- join->join_tab[join->tables-1].next_select= setup_end_select_func(join);
+ join->join_tab[join->top_join_tab_count - 1].next_select= setup_end_select_func(join);
join->send_records= 0;
join->fetch_limit= join->unit->offset_limit_cnt;
/* Disable JOIN CACHE as it is not working with cursors yet */
- for (JOIN_TAB *tab= join_tab;
- tab != join->join_tab + join->tables - 1;
- tab++)
+ for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
+ tab != join->join_tab + join->top_join_tab_count - 1;
+ tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
if (tab->next_select == sub_select_cache)
tab->next_select= sub_select;
}
- DBUG_ASSERT(join_tab->table->reginfo.not_exists_optimize == 0);
- DBUG_ASSERT(join_tab->not_used_in_distinct == 0);
+#ifndef DBUG_OFF
+ JOIN_TAB *first_tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
+ DBUG_ASSERT(first_tab->table->reginfo.not_exists_optimize == 0);
+ DBUG_ASSERT(first_tab->not_used_in_distinct == 0);
/*
null_row is set only if row not found and it's outer join: should never
happen for the first table in join_tab list
*/
- DBUG_ASSERT(join_tab->table->null_row == 0);
+ DBUG_ASSERT(first_tab->table->null_row == 0);
+#endif
DBUG_RETURN(0);
}
@@ -721,8 +723,9 @@ 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, ""))
- return TRUE;
+ FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, "",
+ FALSE, TRUE))
+ return TRUE;
materialized_cursor= new (&table->mem_root)
Materialized_cursor(result, table);
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 3ca35159244..b7b0a853233 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -24,6 +24,7 @@
#include "sp_head.h"
#include "sp.h"
#include "events.h"
+#include "sql_handler.h"
#include <my_dir.h>
#include <m_ctype.h>
#include "log.h"
@@ -968,7 +969,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
{
ha_drop_database(path);
tmp_disable_binlog(thd);
- query_cache_invalidate1(db);
+ query_cache_invalidate1(thd, db);
(void) sp_drop_db_routines(thd, db); /* @todo Do not ignore errors */
#ifdef HAVE_EVENT_SCHEDULER
Events::drop_schema_events(thd, db);
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 90ca139d17b..480868241f7 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -25,6 +25,7 @@
#include "sql_select.h"
#include "sp_head.h"
#include "sql_trigger.h"
+#include "sql_handler.h"
/**
Implement DELETE SQL word.
@@ -50,7 +51,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
bool triggers_applicable;
uint usable_index= MAX_KEY;
SELECT_LEX *select_lex= &thd->lex->select_lex;
- THD::killed_state killed_status= THD::NOT_KILLED;
+ killed_state killed_status= NOT_KILLED;
DBUG_ENTER("mysql_delete");
bool save_binlog_row_based;
@@ -61,10 +62,21 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
- if (!(table= table_list->table))
+
+ if (mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT))
+ DBUG_RETURN(TRUE);
+ if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE))
+ DBUG_RETURN(TRUE);
+
+ if (!table_list->single_table_updatable())
{
- my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
- table_list->view_db.str, table_list->view_name.str);
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE");
+ DBUG_RETURN(TRUE);
+ }
+ if (!(table= table_list->table) || !table->created)
+ {
+ my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
+ table_list->view_db.str, table_list->view_name.str);
DBUG_RETURN(TRUE);
}
thd_proc_info(thd, "init");
@@ -73,6 +85,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (mysql_prepare_delete(thd, table_list, &conds))
DBUG_RETURN(TRUE);
+ if (thd->lex->current_select->first_cond_optimization)
+ {
+ thd->lex->current_select->save_leaf_tables(thd);
+ thd->lex->current_select->first_cond_optimization= 0;
+ }
/* check ORDER BY even if it can be ignored */
if (order && order->elements)
{
@@ -94,6 +111,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
}
}
+ /* Apply the IN=>EXISTS transformation to all subqueries and optimize them. */
+ if (select_lex->optimize_unflattened_subqueries())
+ DBUG_RETURN(TRUE);
+
const_cond= (!conds || conds->const_item());
safe_update=test(thd->options & OPTION_SAFE_UPDATES);
if (safe_update && const_cond)
@@ -103,8 +124,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DBUG_RETURN(TRUE);
}
- select_lex->no_error= thd->lex->ignore;
-
const_cond_result= const_cond && (!conds || conds->val_int());
if (thd->is_error())
{
@@ -313,9 +332,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
while (!(error=info.read_record(&info)) && !thd->killed &&
! thd->is_error())
{
- update_virtual_fields(thd, table,
- triggers_applicable ? VCOL_UPDATE_ALL :
- VCOL_UPDATE_FOR_READ);
+ if (table->vfield)
+ update_virtual_fields(thd, table,
+ triggers_applicable ? VCOL_UPDATE_ALL :
+ VCOL_UPDATE_FOR_READ);
thd->examined_row_count++;
// thd->is_error() is tested to disallow delete row on error
if (!select || select->skip_record(thd) > 0)
@@ -346,16 +366,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
}
else
{
- table->file->print_error(error,MYF(0));
- /*
- In < 4.0.14 we set the error number to 0 here, but that
- was not sensible, because then MySQL would not roll back the
- failed DELETE, and also wrote it to the binlog. For MyISAM
- tables a DELETE probably never should fail (?), but for
- InnoDB it can fail in a FOREIGN KEY error or an
- out-of-tablespace error.
- */
- if (!select_lex->no_error)
+ table->file->print_error(error,
+ MYF(thd->lex->ignore ? ME_JUST_WARNING : 0));
+ if (thd->is_error())
{
error= 1;
break;
@@ -366,7 +379,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
table->file->unlock_row(); // Row failed selection, release lock on it
}
killed_status= thd->killed;
- if (killed_status != THD::NOT_KILLED || thd->is_error())
+ if (killed_status != NOT_KILLED || thd->is_error())
error= 1; // Aborted
if (will_batch && (loc_error= table->file->end_bulk_delete()))
{
@@ -404,6 +417,12 @@ cleanup:
query_cache_invalidate3(thd, table_list, 1);
}
+ if (thd->lex->current_select->first_cond_optimization)
+ {
+ thd->lex->current_select->save_leaf_tables(thd);
+ thd->lex->current_select->first_cond_optimization= 0;
+ }
+
delete select;
transactional_table= table->file->has_transactions();
@@ -427,7 +446,7 @@ cleanup:
if (error < 0)
thd->clear_error();
else
- errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ errcode= query_error_code(thd, killed_status == NOT_KILLED);
/*
[binlog]: If 'handler::delete_all_rows()' was called and the
@@ -505,8 +524,8 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list,
table_list,
- &select_lex->leaf_tables, FALSE,
- DELETE_ACL, SELECT_ACL) ||
+ select_lex->leaf_tables, FALSE,
+ DELETE_ACL, SELECT_ACL, TRUE) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
setup_ftfuncs(select_lex))
DBUG_RETURN(TRUE);
@@ -529,7 +548,7 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
DBUG_RETURN(TRUE);
- select_lex->fix_prepare_information(thd, conds, &fake_conds);
+ select_lex->fix_prepare_information(thd, conds, &fake_conds);
DBUG_RETURN(FALSE);
}
@@ -565,6 +584,12 @@ int mysql_multi_delete_prepare(THD *thd)
TABLE_LIST *target_tbl;
DBUG_ENTER("mysql_multi_delete_prepare");
+ if (mysql_handle_derived(lex, DT_INIT))
+ DBUG_RETURN(TRUE);
+ if (mysql_handle_derived(lex, DT_MERGE_FOR_INSERT))
+ DBUG_RETURN(TRUE);
+ if (mysql_handle_derived(lex, DT_PREPARE))
+ DBUG_RETURN(TRUE);
/*
setup_tables() need for VIEWs. JOIN::prepare() will not do it second
time.
@@ -574,10 +599,12 @@ int mysql_multi_delete_prepare(THD *thd)
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list,
lex->query_tables,
- &lex->select_lex.leaf_tables, FALSE,
- DELETE_ACL, SELECT_ACL))
+ lex->select_lex.leaf_tables, FALSE,
+ DELETE_ACL, SELECT_ACL, FALSE))
DBUG_RETURN(TRUE);
+ if (lex->select_lex.handle_derived(thd->lex, DT_MERGE))
+ DBUG_RETURN(TRUE);
/*
Multi-delete can't be constructed over-union => we always have
@@ -589,16 +616,14 @@ int mysql_multi_delete_prepare(THD *thd)
target_tbl;
target_tbl= target_tbl->next_local)
{
- if (!(target_tbl->table= target_tbl->correspondent_table->table))
+
+ target_tbl->table= target_tbl->correspondent_table->table;
+ if (target_tbl->correspondent_table->is_multitable())
{
- DBUG_ASSERT(target_tbl->correspondent_table->view &&
- target_tbl->correspondent_table->merge_underlying_list &&
- target_tbl->correspondent_table->merge_underlying_list->
- next_local);
- my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
- target_tbl->correspondent_table->view_db.str,
- target_tbl->correspondent_table->view_name.str);
- DBUG_RETURN(TRUE);
+ my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
+ target_tbl->correspondent_table->view_db.str,
+ target_tbl->correspondent_table->view_name.str);
+ DBUG_RETURN(TRUE);
}
if (!target_tbl->correspondent_table->single_table_updatable() ||
@@ -628,6 +653,10 @@ int mysql_multi_delete_prepare(THD *thd)
with further calls to unique_table
*/
lex->select_lex.exclude_from_table_unique_test= FALSE;
+
+ if (lex->select_lex.save_prep_leaf_tables(thd))
+ DBUG_RETURN(TRUE);
+
DBUG_RETURN(FALSE);
}
@@ -648,6 +677,12 @@ multi_delete::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
unit= u;
do_delete= 1;
thd_proc_info(thd, "deleting from main table");
+ SELECT_LEX *select_lex= u->first_select();
+ if (select_lex->first_cond_optimization)
+ {
+ if (select_lex->handle_derived(thd->lex, DT_MERGE))
+ DBUG_RETURN(TRUE);
+ }
DBUG_RETURN(0);
}
@@ -681,9 +716,10 @@ multi_delete::initialize_tables(JOIN *join)
walk= delete_tables;
- for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
- tab < end;
- tab++)
+
+ for (JOIN_TAB *tab= first_linear_tab(join, WITH_CONST_TABLES);
+ tab;
+ tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
{
if (tab->table->map & tables_to_delete_from)
{
@@ -768,7 +804,7 @@ int multi_delete::send_data(List<Item> &values)
TABLE_LIST *del_table;
DBUG_ENTER("multi_delete::send_data");
- bool ignore= thd->lex->current_select->no_error;
+ bool ignore= thd->lex->ignore;
for (del_table= delete_tables;
del_table;
@@ -877,7 +913,7 @@ void multi_delete::abort()
*/
if (mysql_bin_log.is_open())
{
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
/* possible error of writing binary log is ignored deliberately */
(void) thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
@@ -917,11 +953,11 @@ int multi_delete::do_deletes()
table_being_deleted= table_being_deleted->next_local, counter++)
{
TABLE *table = table_being_deleted->table;
+ int local_error;
if (tempfiles[counter]->get(table))
DBUG_RETURN(1);
- int local_error=
- do_table_deletes(table, thd->lex->current_select->no_error);
+ local_error= do_table_deletes(table, thd->lex->ignore);
if (thd->killed && !local_error)
DBUG_RETURN(1);
@@ -1027,7 +1063,7 @@ int multi_delete::do_table_deletes(TABLE *table, bool ignore)
bool multi_delete::send_eof()
{
- THD::killed_state killed_status= THD::NOT_KILLED;
+ killed_state killed_status= NOT_KILLED;
thd_proc_info(thd, "deleting from reference tables");
/* Does deletes for the last n - 1 tables, returns 0 if ok */
@@ -1035,7 +1071,7 @@ bool multi_delete::send_eof()
/* compute a total error to know if something failed */
local_error= local_error || error;
- killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
+ killed_status= (local_error == 0)? NOT_KILLED : thd->killed;
/* reset used flags */
thd_proc_info(thd, "end");
@@ -1055,7 +1091,7 @@ bool multi_delete::send_eof()
if (local_error == 0)
thd->clear_error();
else
- errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ errcode= query_error_code(thd, killed_status == NOT_KILLED);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode) &&
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 713a9d86863..99d20090623 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -25,38 +25,82 @@
#include "mysql_priv.h"
#include "sql_select.h"
+typedef bool (*dt_processor)(THD *thd, LEX *lex, TABLE_LIST *derived);
+bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived);
+bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived);
+bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived);
+bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived);
+bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived);
+bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived);
+bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived);
+bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived);
+
+
+dt_processor processors[]=
+{
+ &mysql_derived_init,
+ &mysql_derived_prepare,
+ &mysql_derived_optimize,
+ &mysql_derived_merge,
+ &mysql_derived_merge_for_insert,
+ &mysql_derived_create,
+ &mysql_derived_fill,
+ &mysql_derived_reinit,
+};
/*
- Call given derived table processor (preparing or filling tables)
+ @brief
+ Run specified phases on all derived tables/views in given LEX.
- SYNOPSIS
- mysql_handle_derived()
- lex LEX for this thread
- processor procedure of derived table processing
+ @param lex LEX for this thread
+ @param phases phases to run derived tables/views through
- RETURN
- FALSE OK
- TRUE Error
+ @return FALSE OK
+ @return TRUE Error
*/
-
bool
-mysql_handle_derived(LEX *lex, bool (*processor)(THD*, LEX*, TABLE_LIST*))
+mysql_handle_derived(LEX *lex, uint phases)
{
bool res= FALSE;
- if (lex->derived_tables)
+ THD *thd= lex->thd;
+ if (!lex->derived_tables)
+ return FALSE;
+
+ lex->thd->derived_tables_processing= TRUE;
+
+ for (uint phase= 0; phase < DT_PHASES && !res; phase++)
{
- lex->thd->derived_tables_processing= TRUE;
+ uint phase_flag= DT_INIT << phase;
+ if (phase_flag > phases)
+ break;
+ if (!(phases & phase_flag))
+ continue;
+ if (phase_flag >= DT_CREATE && !thd->fill_derived_tables())
+ break;
+
for (SELECT_LEX *sl= lex->all_selects_list;
- sl;
+ sl && !res;
sl= sl->next_select_in_list())
{
for (TABLE_LIST *cursor= sl->get_table_list();
- cursor;
+ cursor && !res;
cursor= cursor->next_local)
{
- if ((res= (*processor)(lex->thd, lex, cursor)))
- goto out;
+ if (!cursor->is_view_or_derived() && phases == DT_MERGE_FOR_INSERT)
+ continue;
+ uint8 allowed_phases= (cursor->is_merged_derived() ? DT_PHASES_MERGE :
+ DT_PHASES_MATERIALIZE | DT_MERGE_FOR_INSERT);
+ /*
+ Skip derived tables to which the phase isn't applicable.
+ TODO: mark derived at the parse time, later set it's type
+ (merged or materialized)
+ */
+ if ((phase_flag != DT_PREPARE && !(allowed_phases & phase_flag)) ||
+ (cursor->merged_for_insert && phase_flag != DT_REINIT &&
+ phase_flag != DT_PREPARE))
+ continue;
+ res= (*processors[phase])(lex->thd, lex, cursor);
}
if (lex->describe)
{
@@ -69,30 +113,441 @@ mysql_handle_derived(LEX *lex, bool (*processor)(THD*, LEX*, TABLE_LIST*))
}
}
}
-out:
+ lex->thd->derived_tables_processing= FALSE;
+ return res;
+}
+
+/*
+ @brief
+ Run through phases for the given derived table/view.
+
+ @param lex LEX for this thread
+ @param derived the derived table to handle
+ @param phase_map phases to process tables/views through
+
+ @details
+
+ This function process the derived table (view) 'derived' to performs all
+ actions that are to be done on the table at the phases specified by
+ phase_map. The processing is carried out starting from the actions
+ performed at the earlier phases (those having smaller ordinal numbers).
+
+ @note
+ This function runs specified phases of the derived tables handling on the
+ given derived table/view. This function is used in the chain of calls:
+ SELECT_LEX::handle_derived ->
+ TABLE_LIST::handle_derived ->
+ mysql_handle_single_derived
+ This chain of calls implements the bottom-up handling of the derived tables:
+ i.e. most inner derived tables/views are handled first. This order is
+ required for the all phases except the merge and the create steps.
+ For the sake of code simplicity this order is kept for all phases.
+
+ @return FALSE ok
+ @return TRUE error
+*/
+
+bool
+mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases)
+{
+ bool res= FALSE;
+ THD *thd= lex->thd;
+ uint8 allowed_phases= (derived->is_merged_derived() ? DT_PHASES_MERGE :
+ DT_PHASES_MATERIALIZE);
+ if (!lex->derived_tables)
+ return FALSE;
+
+ lex->thd->derived_tables_processing= TRUE;
+
+ for (uint phase= 0; phase < DT_PHASES; phase++)
+ {
+ uint phase_flag= DT_INIT << phase;
+ if (phase_flag > phases)
+ break;
+ if (!(phases & phase_flag))
+ continue;
+ /* Skip derived tables to which the phase isn't applicable. */
+ if (phase_flag != DT_PREPARE &&
+ !(allowed_phases & phase_flag))
+ continue;
+ if (phase_flag >= DT_CREATE && !thd->fill_derived_tables())
+ break;
+
+ if ((res= (*processors[phase])(lex->thd, lex, derived)))
+ break;
+ }
lex->thd->derived_tables_processing= FALSE;
return res;
}
/**
- @brief Create temporary table structure (but do not fill it).
+ @brief
+ Run specified phases for derived tables/views in the given list
- @param thd Thread handle
- @param lex LEX for this thread
- @param orig_table_list TABLE_LIST for the upper SELECT
+ @param lex LEX for this thread
+ @param table_list list of derived tables/view to handle
+ @param phase_map phases to process tables/views through
- @details
+ @details
+ This function runs phases specified by the 'phases_map' on derived
+ tables/views found in the 'dt_list' with help of the
+ TABLE_LIST::handle_derived function.
+ 'lex' is passed as an argument to the TABLE_LIST::handle_derived.
- This function is called before any command containing derived tables is
- executed. Currently the function is used for derived tables, i.e.
+ @return FALSE ok
+ @return TRUE error
+*/
- - Anonymous derived tables, or
- - Named derived tables (aka views) with the @c TEMPTABLE algorithm.
-
- The table reference, contained in @c orig_table_list, is updated with the
- fields of a new temporary table.
+bool
+mysql_handle_list_of_derived(LEX *lex, TABLE_LIST *table_list, uint phases)
+{
+ for (TABLE_LIST *tl= table_list; tl; tl= tl->next_local)
+ {
+ if (tl->is_view_or_derived() &&
+ tl->handle_derived(lex, phases))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/**
+ @brief
+ Merge a derived table/view into the embedding select
+
+ @param thd thread handle
+ @param lex LEX of the embedding query.
+ @param derived reference to the derived table.
+
+ @details
+ This function merges the given derived table / view into the parent select
+ construction. Any derived table/reference to view occurred in the FROM
+ clause of the embedding select is represented by a TABLE_LIST structure a
+ pointer to which is passed to the function as in the parameter 'derived'.
+ This structure contains the number/map, alias, a link to SELECT_LEX of the
+ derived table and other info. If the 'derived' table is used in a nested join
+ then additionally the structure contains a reference to the ON expression
+ for this join.
+
+ The merge process results in elimination of the derived table (or the
+ reference to a view) such that:
+ - the FROM list of the derived table/view is wrapped into a nested join
+ after which the nest is added to the FROM list of the embedding select
+ - the WHERE condition of the derived table (view) is ANDed with the ON
+ condition attached to the table.
+
+ @note
+ Tables are merged into the leaf_tables list, original derived table is removed
+ from this list also. SELECT_LEX::table_list list is left untouched.
+ Where expression is merged with derived table's on_expr and can be found after
+ the merge through the SELECT_LEX::table_list.
+
+ Examples of the derived table/view merge:
+
+ Schema:
+ Tables: t1(f1), t2(f2), t3(f3)
+ View v1: SELECT f1 FROM t1 WHERE f1 < 1
+
+ Example with a view:
+ Before merge:
+
+ The query (Q1): SELECT f1,f2 FROM t2 LEFT JOIN v1 ON f1 = f2
+
+ (LEX of the main query)
+ |
+ (select_lex)
+ |
+ (FROM table list)
+ |
+ (join list)= t2, v1
+ / \
+ / (on_expr)= (f1 = f2)
+ |
+ (LEX of the v1 view)
+ |
+ (select_lex)= SELECT f1 FROM t1 WHERE f1 < 1
+
+
+ After merge:
+
+ The rewritten query Q1 (Q1'):
+ SELECT f1,f2 FROM t2 LEFT JOIN (t1) ON ((f1 = f2) and (f1 < 1))
+
+ (LEX of the main query)
+ |
+ (select_lex)
+ |
+ (FROM table list)
+ |
+ (join list)= t2, (t1)
+ \
+ (on_expr)= (f1 = f2) and (f1 < 1)
+
+ In this example table numbers are assigned as follows:
+ (outer select): t2 - 1, v1 - 2
+ (inner select): t1 - 1
+ After the merge table numbers will be:
+ (outer select): t2 - 1, t1 - 2
+
+ Example with a derived table:
+ The query Q2:
+ SELECT f1,f2
+ FROM (SELECT f1 FROM t1, t3 WHERE f1=f3 and f1 < 1) tt, t2
+ WHERE f1 = f2
+
+ Before merge:
+ (LEX of the main query)
+ |
+ (select_lex)
+ / \
+ (FROM table list) (WHERE clause)= (f1 = f2)
+ |
+ (join list)= tt, t2
+ / \
+ / (on_expr)= (empty)
+ /
+ (select_lex)= SELECT f1 FROM t1, t3 WHERE f1 = f3 and f1 < 1
+
+ After merge:
+
+ The rewritten query Q2 (Q2'):
+ SELECT f1,f2
+ FROM (t1, t3) JOIN t2 ON (f1 = f3 and f1 < 1)
+ WHERE f1 = f2
+
+ (LEX of the main query)
+ |
+ (select_lex)
+ / \
+ (FROM table list) (WHERE clause)= (f1 = f2)
+ |
+ (join list)= t2, (t1, t3)
+ \
+ (on_expr)= (f1 = f3 and f1 < 1)
+
+ In this example table numbers are assigned as follows:
+ (outer select): tt - 1, t2 - 2
+ (inner select): t1 - 1, t3 - 2
+ After the merge table numbers will be:
+ (outer select): t1 - 1, t2 - 2, t3 - 3
+
+ @return FALSE if derived table/view were successfully merged.
+ @return TRUE if an error occur.
+*/
+
+bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
+{
+ bool res= FALSE;
+ SELECT_LEX *dt_select= derived->get_single_select();
+ table_map map;
+ uint tablenr;
+ SELECT_LEX *parent_lex= derived->select_lex;
+ Query_arena *arena, backup;
+
+ if (derived->merged)
+ return FALSE;
+
+ if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
+ thd->lex->sql_command == SQLCOM_DELETE_MULTI)
+ thd->save_prep_leaf_list= TRUE;
+
+ arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test
+ derived->merged= TRUE;
+
+ if (!derived->merged_for_insert ||
+ (derived->is_multitable() &&
+ (thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
+ thd->lex->sql_command == SQLCOM_DELETE_MULTI)))
+ {
+ /*
+ Check whether there is enough free bits in table map to merge subquery.
+ If not - materialize it. This check isn't cached so when there is a big
+ and small subqueries, and the bigger one can't be merged it wouldn't
+ block the smaller one.
+ */
+ if (parent_lex->get_free_table_map(&map, &tablenr))
+ {
+ /* There is no enough table bits, fall back to materialization. */
+ derived->change_refs_to_fields();
+ derived->set_materialized_derived();
+ goto exit_merge;
+ }
+
+ if (dt_select->leaf_tables.elements + tablenr > MAX_TABLES)
+ {
+ /* There is no enough table bits, fall back to materialization. */
+ derived->change_refs_to_fields();
+ derived->set_materialized_derived();
+ goto exit_merge;
+ }
+
+ if (dt_select->options & OPTION_SCHEMA_TABLE)
+ parent_lex->options |= OPTION_SCHEMA_TABLE;
+
+ parent_lex->cond_count+= dt_select->cond_count;
+
+ if (!derived->get_unit()->prepared)
+ {
+ dt_select->leaf_tables.empty();
+ make_leaves_list(dt_select->leaf_tables, derived, TRUE, 0);
+ }
+
+ derived->nested_join= (NESTED_JOIN*) thd->calloc(sizeof(NESTED_JOIN));
+ if (!derived->nested_join)
+ {
+ res= TRUE;
+ goto exit_merge;
+ }
+
+ /* Merge derived table's subquery in the parent select. */
+ if (parent_lex->merge_subquery(thd, derived, dt_select, tablenr, map))
+ {
+ res= TRUE;
+ goto exit_merge;
+ }
+
+ /*
+ exclude select lex so it doesn't show up in explain.
+ do this only for derived table as for views this is already done.
+
+ From sql_view.cc
+ Add subqueries units to SELECT into which we merging current view.
+ unit(->next)* chain starts with subqueries that are used by this
+ view and continues with subqueries that are used by other views.
+ We must not add any subquery twice (otherwise we'll form a loop),
+ to do this we remember in end_unit the first subquery that has
+ been already added.
+ */
+ derived->get_unit()->exclude_level();
+ if (parent_lex->join)
+ parent_lex->join->table_count+= dt_select->join->table_count - 1;
+ }
+ if (derived->get_unit()->prepared)
+ {
+ Item *expr= derived->on_expr;
+ expr= and_conds(expr, dt_select->join ? dt_select->join->conds : 0);
+ if (expr && (derived->prep_on_expr || expr != derived->on_expr))
+ {
+ derived->on_expr= expr;
+ derived->prep_on_expr= expr->copy_andor_structure(thd);
+ }
+ if (derived->on_expr &&
+ ((!derived->on_expr->fixed &&
+ derived->on_expr->fix_fields(thd, &derived->on_expr)) ||
+ derived->on_expr->check_cols(1)))
+ {
+ res= TRUE; /* purecov: inspected */
+ goto exit_merge;
+ }
+ // Update used tables cache according to new table map
+ if (derived->on_expr)
+ {
+ derived->on_expr->fix_after_pullout(parent_lex, &derived->on_expr);
+ fix_list_after_tbl_changes(parent_lex, &derived->nested_join->join_list);
+ }
+ }
+
+exit_merge:
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ return res;
+}
+
+
+/**
+ @brief
+ Merge a view for the embedding INSERT/UPDATE/DELETE
+
+ @param thd thread handle
+ @param lex LEX of the embedding query.
+ @param derived reference to the derived table.
+
+ @details
+ This function substitutes the derived table for the first table from
+ the query of the derived table thus making it a correct target table for the
+ INSERT/UPDATE/DELETE statements. As this operation is correct only for
+ single table views only, for multi table views this function does nothing.
+ The derived parameter isn't checked to be a view as derived tables aren't
+ allowed for INSERT/UPDATE/DELETE statements.
+
+ @return FALSE if derived table/view were successfully merged.
+ @return TRUE if an error occur.
+*/
+
+bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived)
+{
+ if (derived->merged_for_insert)
+ return FALSE;
+ if (derived->is_materialized_derived())
+ return mysql_derived_prepare(thd, lex, derived);
+ if (!derived->is_multitable())
+ {
+ if (!derived->single_table_updatable())
+ return derived->create_field_translation(thd);
+ if (derived->merge_underlying_list)
+ {
+ derived->table= derived->merge_underlying_list->table;
+ derived->schema_table= derived->merge_underlying_list->schema_table;
+ derived->merged_for_insert= TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+/*
+ @brief
+ Initialize a derived table/view
+
+ @param thd Thread handle
+ @param lex LEX of the embedding query.
+ @param derived reference to the derived table.
+
+ @detail
+ Fill info about derived table/view without preparing an
+ underlying select. Such as: create a field translation for views, mark it as
+ a multitable if it is and so on.
+
+ @return
+ false OK
+ true Error
+*/
+
+
+bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived)
+{
+ SELECT_LEX_UNIT *unit= derived->get_unit();
+ DBUG_ENTER("mysql_derived_init");
+
+ // Skip already prepared views/DT
+ if (!unit || unit->prepared)
+ DBUG_RETURN(FALSE);
+
+ DBUG_RETURN(derived->init_derived(thd, TRUE));
+}
+
+
+/*
+ @brief
+ Create temporary table structure (but do not fill it)
+
+ @param thd Thread handle
+ @param lex LEX of the embedding query.
+ @param derived reference to the derived table.
+
+ @detail
+ Prepare underlying select for a derived table/view. To properly resolve
+ names in the embedding query the TABLE structure is created. Actual table
+ is created later by the mysql_derived_create function.
+ This function is called before any command containing derived table
+ is executed. All types of derived tables are handled by this function:
+ - Anonymous derived tables, or
+ - Named derived tables (aka views).
+
+ The table reference, contained in @c derived, is updated with the
+ fields of a new temporary table.
Derived tables are stored in @c thd->derived_tables and closed by
close_thread_tables().
@@ -116,200 +571,366 @@ out:
the state of privilege checking (GRANT_INFO struct) is copied as-is to the
temporary table.
- This function implements a signature called "derived table processor", and
- is passed as a function pointer to mysql_handle_derived().
+ Only the TABLE structure is created here, actual table is created by the
+ mysql_derived_create function.
@note This function sets @c SELECT_ACL for @c TEMPTABLE views as well as
anonymous derived tables, but this is ok since later access checking will
distinguish between them.
- @see mysql_handle_derived(), mysql_derived_filling(), GRANT_INFO
+ @see mysql_handle_derived(), mysql_derived_fill(), GRANT_INFO
@return
false OK
true Error
*/
-bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
+bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
{
- SELECT_LEX_UNIT *unit= orig_table_list->derived;
- ulonglong create_options;
+ SELECT_LEX_UNIT *unit= derived->get_unit();
DBUG_ENTER("mysql_derived_prepare");
bool res= FALSE;
- if (unit)
+
+ // Skip already prepared views/DT
+ if (!unit || unit->prepared ||
+ (derived->merged_for_insert &&
+ !(derived->is_multitable() &&
+ (thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
+ thd->lex->sql_command == SQLCOM_DELETE_MULTI))))
+ DBUG_RETURN(FALSE);
+
+ Query_arena *arena= thd->stmt_arena, backup;
+ if (arena->is_conventional())
+ arena= 0; // For easier test
+ else
+ thd->set_n_backup_active_arena(arena, &backup);
+
+ SELECT_LEX *first_select= unit->first_select();
+
+ /* prevent name resolving out of derived table */
+ for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select())
{
- SELECT_LEX *first_select= unit->first_select();
- TABLE *table= 0;
- select_union *derived_result;
-
- /* prevent name resolving out of derived table */
- for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select())
- sl->context.outer_context= 0;
-
- if (!(derived_result= new select_union))
- DBUG_RETURN(TRUE); // out of memory
-
- lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED;
- // st_select_lex_unit::prepare correctly work for single select
- if ((res= unit->prepare(thd, derived_result, 0)))
- goto exit;
- lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_DERIVED;
- if ((res= check_duplicate_names(unit->types, 0)))
- goto exit;
-
- create_options= (first_select->options | thd->options |
- TMP_TABLE_ALL_COLUMNS);
- /*
- Temp table is created so that it hounours if UNION without ALL is to be
- processed
-
- As 'distinct' parameter we always pass FALSE (0), because underlying
- query will control distinct condition by itself. Correct test of
- distinct underlying query will be is_union &&
- !unit->union_distinct->next_select() (i.e. it is union and last distinct
- SELECT is last SELECT of UNION).
- */
- if ((res= derived_result->create_result_table(thd, &unit->types, FALSE,
- create_options,
- orig_table_list->alias)))
- goto exit;
+ sl->context.outer_context= 0;
+ // Prepare underlying views/DT first.
+ sl->handle_derived(lex, DT_PREPARE);
+ }
- table= derived_result->table;
+ unit->derived= derived;
+
+ if (!(derived->derived_result= new select_union))
+ DBUG_RETURN(TRUE); // out of memory
+
+ lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED;
+ // st_select_lex_unit::prepare correctly work for single select
+ if ((res= unit->prepare(thd, derived->derived_result, 0)))
+ goto exit;
+ lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_DERIVED;
+ if ((res= check_duplicate_names(unit->types, 0)))
+ goto exit;
+
+ /*
+ Check whether we can merge this derived table into main select.
+ Depending on the result field translation will or will not
+ be created.
+ */
+ if (derived->init_derived(thd, FALSE))
+ goto exit;
+
+ /*
+ Temp table is created so that it hounours if UNION without ALL is to be
+ processed
+
+ As 'distinct' parameter we always pass FALSE (0), because underlying
+ query will control distinct condition by itself. Correct test of
+ distinct underlying query will be is_union &&
+ !unit->union_distinct->next_select() (i.e. it is union and last distinct
+ SELECT is last SELECT of UNION).
+ */
+ thd->create_tmp_table_for_derived= TRUE;
+ if (derived->derived_result->create_result_table(thd, &unit->types, FALSE,
+ (first_select->options |
+ thd->options |
+ TMP_TABLE_ALL_COLUMNS),
+ derived->alias,
+ FALSE, FALSE))
+ {
+ thd->create_tmp_table_for_derived= FALSE;
+ goto exit;
+ }
+ thd->create_tmp_table_for_derived= FALSE;
+
+ derived->table= derived->derived_result->table;
+ if (derived->is_derived() && derived->is_merged_derived())
+ first_select->mark_as_belong_to_derived(derived);
exit:
- /* Hide "Unknown column" or "Unknown function" error */
- if (orig_table_list->view)
- {
- if (thd->is_error() &&
+ /* Hide "Unknown column" or "Unknown function" error */
+ if (derived->view)
+ {
+ if (thd->is_error() &&
(thd->main_da.sql_errno() == ER_BAD_FIELD_ERROR ||
- thd->main_da.sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION ||
- thd->main_da.sql_errno() == ER_SP_DOES_NOT_EXIST))
- {
- thd->clear_error();
- my_error(ER_VIEW_INVALID, MYF(0), orig_table_list->db,
- orig_table_list->table_name);
- }
- }
-
- /*
- if it is preparation PS only or commands that need only VIEW structure
- then we do not need real data and we can skip execution (and parameters
- is not defined, too)
- */
- if (res)
+ thd->main_da.sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION ||
+ thd->main_da.sql_errno() == ER_SP_DOES_NOT_EXIST))
{
- if (table)
- free_tmp_table(thd, table);
- delete derived_result;
+ thd->clear_error();
+ my_error(ER_VIEW_INVALID, MYF(0), derived->db,
+ derived->table_name);
}
+ }
+
+ /*
+ if it is preparation PS only or commands that need only VIEW structure
+ then we do not need real data and we can skip execution (and parameters
+ is not defined, too)
+ */
+ if (res)
+ {
+ if (derived->table)
+ free_tmp_table(thd, derived->table);
+ delete derived->derived_result;
+ }
+ else
+ {
+ TABLE *table= derived->table;
+ table->derived_select_number= first_select->select_number;
+ table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ if (derived->referencing_view)
+ table->grant= derived->grant;
else
{
- if (!thd->fill_derived_tables())
- {
- delete derived_result;
- derived_result= NULL;
- }
- orig_table_list->derived_result= derived_result;
- orig_table_list->table= table;
- table->derived_select_number= first_select->select_number;
- table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (orig_table_list->referencing_view)
- table->grant= orig_table_list->grant;
- else
- table->grant.privilege= SELECT_ACL;
-#endif
- orig_table_list->db= (char *)"";
- orig_table_list->db_length= 0;
- // Force read of table stats in the optimizer
- table->file->info(HA_STATUS_VARIABLE);
- /* Add new temporary table to list of open derived tables */
- table->next= thd->derived_tables;
- thd->derived_tables= table;
+ table->grant.privilege= SELECT_ACL;
+ if (derived->is_derived())
+ derived->grant.privilege= SELECT_ACL;
}
+#endif
+ /* Add new temporary table to list of open derived tables */
+ table->next= thd->derived_tables;
+ thd->derived_tables= table;
}
- else if (orig_table_list->merge_underlying_list)
- orig_table_list->set_underlying_merge();
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
DBUG_RETURN(res);
}
-/*
- fill derived table
-
- SYNOPSIS
- mysql_derived_filling()
- thd Thread handle
- lex LEX for this thread
- unit node that contains all SELECT's for derived tables
- orig_table_list TABLE_LIST for the upper SELECT
-
- IMPLEMENTATION
- Derived table is resolved with temporary table. It is created based on the
- queries defined. After temporary table is filled, if this is not EXPLAIN,
- then the entire unit / node is deleted. unit is deleted if UNION is used
- for derived table and node is deleted is it is a simple SELECT.
- If you use this function, make sure it's not called at prepare.
- Due to evaluation of LIMIT clause it can not be used at prepared stage.
-
- RETURN
- FALSE OK
- TRUE Error
+/**
+ @brief
+ Runs optimize phase for a derived table/view.
+
+ @param thd thread handle
+ @param lex LEX of the embedding query.
+ @param derived reference to the derived table.
+
+ @details
+ Runs optimize phase for given 'derived' derived table/view.
+ If optimizer finds out that it's of the type "SELECT a_constant" then this
+ functions also materializes it.
+
+ @return FALSE ok.
+ @return TRUE if an error occur.
*/
-bool mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
+bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
{
- TABLE *table= orig_table_list->table;
- SELECT_LEX_UNIT *unit= orig_table_list->derived;
+ SELECT_LEX_UNIT *unit= derived->get_unit();
+ SELECT_LEX *first_select= unit->first_select();
+ SELECT_LEX *save_current_select= lex->current_select;
+
bool res= FALSE;
- /*check that table creation pass without problem and it is derived table */
- if (table && unit)
+ if (unit->optimized)
+ return FALSE;
+ lex->current_select= first_select;
+
+ if (unit->is_union())
{
- SELECT_LEX *first_select= unit->first_select();
- select_union *derived_result= orig_table_list->derived_result;
- SELECT_LEX *save_current_select= lex->current_select;
- if (unit->is_union())
- {
- // execute union without clean up
- res= unit->exec();
- }
- else
+ // optimize union without execution
+ res= unit->optimize();
+ }
+ else if (unit->derived)
+ {
+ if (!derived->is_merged_derived())
{
+ JOIN *join= first_select->join;
unit->set_limit(first_select);
- if (unit->select_limit_cnt == HA_POS_ERROR)
- first_select->options&= ~OPTION_FOUND_ROWS;
-
- lex->current_select= first_select;
- res= mysql_select(thd, &first_select->ref_pointer_array,
- first_select->table_list.first,
- first_select->with_wild,
- first_select->item_list, first_select->where,
- (first_select->order_list.elements+
- first_select->group_list.elements),
- first_select->order_list.first,
- first_select->group_list.first,
- first_select->having, (ORDER*) NULL,
- (first_select->options | thd->options |
- SELECT_NO_UNLOCK),
- derived_result, unit, first_select);
+ unit->optimized= TRUE;
+ if ((res= join->optimize()))
+ goto err;
+ if (join->table_count == join->const_tables)
+ derived->fill_me= TRUE;
}
-
- if (!res)
+ }
+ /*
+ Materialize derived tables/views of the "SELECT a_constant" type.
+ Such tables should be materialized at the optimization phase for
+ correct constant evaluation.
+ */
+ if (!res && derived->fill_me && !derived->merged_for_insert)
+ {
+ if (derived->is_merged_derived())
{
- /*
- Here we entirely fix both TABLE_LIST and list of SELECT's as
- there were no derived tables
- */
- if (derived_result->flush())
- res= TRUE;
-
- if (!lex->describe)
- unit->cleanup();
+ derived->change_refs_to_fields();
+ derived->set_materialized_derived();
}
- else
- unit->cleanup();
- lex->current_select= save_current_select;
+ if ((res= mysql_derived_create(thd, lex, derived)))
+ goto err;
+ if ((res= mysql_derived_fill(thd, lex, derived)))
+ goto err;
+ }
+err:
+ lex->current_select= save_current_select;
+ return res;
+}
+
+
+/**
+ @brief
+ Actually create result table for a materialized derived table/view.
+
+ @param thd thread handle
+ @param lex LEX of the embedding query.
+ @param derived reference to the derived table.
+
+ @details
+ This function actually creates the result table for given 'derived'
+ table/view, but it doesn't fill it.
+ 'thd' and 'lex' parameters are not used by this function.
+
+ @return FALSE ok.
+ @return TRUE if an error occur.
+*/
+
+bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
+{
+ TABLE *table= derived->table;
+ SELECT_LEX_UNIT *unit= derived->get_unit();
+
+ if (table->created)
+ return FALSE;
+ select_union *result= (select_union*)unit->result;
+ if (table->s->db_type() == TMP_ENGINE_HTON)
+ {
+ result->tmp_table_param.keyinfo= table->s->key_info;
+ if (create_internal_tmp_table(table, result->tmp_table_param.keyinfo,
+ result->tmp_table_param.start_recinfo,
+ &result->tmp_table_param.recinfo,
+ (unit->first_select()->options |
+ thd->options | TMP_TABLE_ALL_COLUMNS)))
+ return(TRUE);
+ }
+ if (open_tmp_table(table))
+ return TRUE;
+ table->file->extra(HA_EXTRA_WRITE_CACHE);
+ table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+ return FALSE;
+}
+
+
+/*
+ @brief
+ Execute subquery of a materialized derived table/view and fill the result
+ table.
+
+ @param thd Thread handle
+ @param lex LEX for this thread
+ @param derived reference to the derived table.
+
+ @details
+ Execute subquery of given 'derived' table/view and fill the result
+ table. After result table is filled, if this is not the EXPLAIN statement,
+ the entire unit / node is deleted. unit is deleted if UNION is used
+ for derived table and node is deleted is it is a simple SELECT.
+ 'lex' is unused and 'thd' is passed as an argument to an underlying function.
+
+ @note
+ If you use this function, make sure it's not called at prepare.
+ Due to evaluation of LIMIT clause it can not be used at prepared stage.
+
+ @return FALSE OK
+ @return TRUE Error
+*/
+
+bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
+{
+ SELECT_LEX_UNIT *unit= derived->get_unit();
+ bool res= FALSE;
+
+ if (unit->executed && !unit->uncacheable && !unit->describe)
+ return FALSE;
+ /*check that table creation passed without problems. */
+ DBUG_ASSERT(derived->table && derived->table->created);
+ SELECT_LEX *first_select= unit->first_select();
+ select_union *derived_result= derived->derived_result;
+ SELECT_LEX *save_current_select= lex->current_select;
+ if (unit->is_union())
+ {
+ // execute union without clean up
+ res= unit->exec();
+ }
+ else
+ {
+ unit->set_limit(first_select);
+ if (unit->select_limit_cnt == HA_POS_ERROR)
+ first_select->options&= ~OPTION_FOUND_ROWS;
+
+ lex->current_select= first_select;
+ res= mysql_select(thd, &first_select->ref_pointer_array,
+ (TABLE_LIST*) first_select->table_list.first,
+ first_select->with_wild,
+ first_select->item_list, first_select->where,
+ (first_select->order_list.elements+
+ first_select->group_list.elements),
+ (ORDER *) first_select->order_list.first,
+ (ORDER *) first_select->group_list.first,
+ first_select->having, (ORDER*) NULL,
+ (first_select->options | thd->options |
+ SELECT_NO_UNLOCK),
+ derived_result, unit, first_select);
+ }
+
+ if (!res)
+ {
+ if (derived_result->flush())
+ res= TRUE;
+ unit->executed= TRUE;
}
+ if (res || !lex->describe)
+ unit->cleanup();
+ lex->current_select= save_current_select;
+
return res;
}
+
+
+/**
+ @brief
+ Re-initialize given derived table/view for the next execution.
+
+ @param thd thread handle
+ @param lex LEX for this thread
+ @param derived reference to the derived table.
+
+ @details
+ Re-initialize given 'derived' table/view for the next execution.
+ All underlying views/derived tables are recursively reinitialized prior
+ to re-initialization of given derived table.
+ 'thd' and 'lex' are passed as arguments to called functions.
+
+ @return FALSE OK
+ @return TRUE Error
+*/
+
+bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived)
+{
+ st_select_lex_unit *unit= derived->get_unit();
+
+ if (derived->table)
+ derived->merged_for_insert= FALSE;
+ unit->unclean();
+ unit->types.empty();
+ /* for derived tables & PS (which can't be reset by Item_subquery) */
+ unit->reinit_exec_mechanism();
+ unit->set_thd(thd);
+ return FALSE;
+}
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 55d85625eae..a4c98daac1f 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -134,7 +134,7 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
thd->no_warnings_for_error= 1;
thd->spcont= NULL;
- thd->killed= THD::KILL_BAD_DATA;
+ thd->killed= KILL_BAD_DATA;
my_message(code, msg, MYF(0));
thd->spcont= spcont;
diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc
new file mode 100644
index 00000000000..4174f72f080
--- /dev/null
+++ b/sql/sql_expression_cache.cc
@@ -0,0 +1,322 @@
+/* Copyright (C) 2010-2011 Monty Program Ab & Oleksandr Byelkin
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "mysql_priv.h"
+#include "sql_select.h"
+
+/**
+ Minimum hit ration to proceed on disk if in memory table overflowed.
+ hit_rate = hit / (miss + hit);
+*/
+#define EXPCACHE_MIN_HIT_RATE_FOR_DISK_TABLE 0.7
+/**
+ Minimum hit ratio to keep in memory table (do not switch cache off)
+ hit_rate = hit / (miss + hit);
+*/
+#define EXPCACHE_MIN_HIT_RATE_FOR_MEM_TABLE 0.2
+/**
+ Number of cache miss to check hit ratio (maximum cache performance
+ impact in the case when the cache is not applicable)
+*/
+#define EXPCACHE_CHECK_HIT_RATIO_AFTER 200
+
+/*
+ Expression cache is used only for caching subqueries now, so its statistic
+ variables we call subquery_cache*.
+*/
+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), items(dependants), val(value),
+ hit(0), miss(0), inited (0)
+{
+ DBUG_ENTER("Expression_cache_tmptable::Expression_cache_tmptable");
+ DBUG_VOID_RETURN;
+};
+
+
+/**
+ Disable cache
+*/
+
+void Expression_cache_tmptable::disable_cache()
+{
+ free_tmp_table(table_thd, cache_table);
+ cache_table= NULL;
+}
+
+
+/**
+ Field enumerator for TABLE::add_tmp_key
+
+ @param arg reference variable with current field number
+
+ @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(items);
+ Item_iterator_list it(li);
+ uint field_counter;
+ DBUG_ENTER("Expression_cache_tmptable::init");
+ DBUG_ASSERT(!inited);
+ inited= TRUE;
+ cache_table= NULL;
+
+ if (items.elements == 0)
+ {
+ DBUG_PRINT("info", ("All parameters were removed by optimizer."));
+ DBUG_VOID_RETURN;
+ }
+
+ /* add result field */
+ items.push_front(val);
+
+ cache_table_param.init();
+ /* dependent items and result */
+ cache_table_param.field_count= items.elements;
+ /* postpone table creation to index description */
+ cache_table_param.skip_create_table= 1;
+
+ if (!(cache_table= create_tmp_table(table_thd, &cache_table_param,
+ items, (ORDER*) NULL,
+ FALSE, TRUE,
+ ((table_thd->options |
+ TMP_TABLE_ALL_COLUMNS) &
+ ~(OPTION_BIG_TABLES |
+ TMP_TABLE_FORCE_MYISAM)),
+ HA_POS_ERROR,
+ (char *)"subquery-cache-table",
+ TRUE)))
+ {
+ 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;
+ }
+
+ 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, 1 /* skip result field*/))
+ {
+ DBUG_PRINT("error", ("creating index failed"));
+ goto error;
+ }
+ cache_table->s->keys= 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:
+ disable_cache();
+ DBUG_VOID_RETURN;
+}
+
+
+Expression_cache_tmptable::~Expression_cache_tmptable()
+{
+ /* Add accumulated statistics */
+ statistic_add(subquery_cache_miss, miss, &LOCK_status);
+ statistic_add(subquery_cache_hit, hit, &LOCK_status);
+
+ if (cache_table)
+ disable_cache();
+}
+
+
+/**
+ 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");
+
+ 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)
+ {
+ if (((++miss) == EXPCACHE_CHECK_HIT_RATIO_AFTER) &&
+ ((double)hit / ((double)hit + miss)) <
+ EXPCACHE_MIN_HIT_RATE_FOR_MEM_TABLE)
+ {
+ DBUG_PRINT("info",
+ ("Early check: hit rate is not so good to keep the cache"));
+ disable_cache();
+ }
+
+ DBUG_RETURN(MISS);
+ }
+
+ 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_tmp_row(cache_table->record[0])))
+ {
+ /* create_myisam_from_heap will generate error if needed */
+ if (cache_table->file->is_fatal_error(error, HA_CHECK_DUP))
+ goto err;
+ else
+ {
+ double hit_rate= ((double)hit / ((double)hit + miss));
+ DBUG_ASSERT(miss > 0);
+ if (hit_rate < EXPCACHE_MIN_HIT_RATE_FOR_MEM_TABLE)
+ {
+ DBUG_PRINT("info", ("hit rate is not so good to keep the cache"));
+ disable_cache();
+ DBUG_RETURN(FALSE);
+ }
+ else if (hit_rate < EXPCACHE_MIN_HIT_RATE_FOR_DISK_TABLE)
+ {
+ DBUG_PRINT("info", ("hit rate is not so good to go to disk"));
+ if (cache_table->file->ha_delete_all_rows() ||
+ cache_table->file->ha_write_tmp_row(cache_table->record[0]))
+ goto err;
+ }
+ else
+ {
+ if (create_internal_tmp_table_from_heap(table_thd, cache_table,
+ cache_table_param.start_recinfo,
+ &cache_table_param.recinfo,
+ error, 1))
+ goto err;
+ }
+ }
+ }
+ cache_table->status= 0; /* cache_table->record contains an existed record */
+ ref.has_record= TRUE; /* the same as above */
+ DBUG_PRINT("info", ("has_record: TRUE status: 0"));
+
+ DBUG_RETURN(FALSE);
+
+err:
+ disable_cache();
+ DBUG_RETURN(TRUE);
+}
+
+
+void Expression_cache_tmptable::print(String *str, enum_query_type query_type)
+{
+ List_iterator<Item> li(items);
+ Item *item;
+ bool is_first= TRUE;
+
+ str->append('<');
+ li++; // skip result field
+ while ((item= li++))
+ {
+ if (!is_first)
+ str->append(',');
+ item->print(str, query_type);
+ 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..32aecc61dc9
--- /dev/null
+++ b/sql/sql_expression_cache.h
@@ -0,0 +1,95 @@
+#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;
+
+ /**
+ Is this cache initialized
+ */
+ virtual bool is_inited()= 0;
+ /**
+ Initialize this cache
+ */
+ virtual void init()= 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);
+ bool is_inited() { return inited; };
+ void init();
+
+private:
+ void disable_cache();
+
+ /* 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 parameter items */
+ List<Item> &items;
+ /* Value Item example */
+ Item *val;
+ /* hit/miss counters */
+ uint hit, miss;
+ /* Set on if the object has been succesfully initialized with init() */
+ bool inited;
+};
+
+#endif /* SQL_EXPRESSION_CACHE_INCLUDED */
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 60d3740931e..47d78abdb68 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -58,9 +58,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
@@ -68,6 +72,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
@@ -86,11 +112,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;
}
@@ -108,9 +134,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;
}
/**
@@ -122,14 +148,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
@@ -137,13 +170,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))
@@ -154,17 +192,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();
}
/*
@@ -180,7 +216,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.
@@ -189,17 +225,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)
{
@@ -212,7 +248,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,
@@ -290,8 +326,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;
@@ -299,36 +337,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);
@@ -336,10 +407,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);
}
@@ -364,17 +438,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
{
@@ -389,6 +463,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.str);
+ 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.
@@ -415,153 +650,76 @@ 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)
+ int 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
@@ -586,9 +744,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 */
@@ -605,7 +761,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);
@@ -624,54 +780,28 @@ 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, ...) */
DBUG_ASSERT(keyname != 0);
- error= table->file->ha_index_next_same(table->record[0], key, key_len);
+ error= table->file->ha_index_next_same(table->record[0], key,
+ handler->key_len);
break;
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:
@@ -691,12 +821,14 @@ retry:
"table '%s'",
error, tables->table_name);
table->file->print_error(error,MYF(0));
+ table->file->ha_index_or_rnd_end();
goto err;
}
goto ok;
}
/* Generate values for virtual fields */
- update_virtual_fields(thd, table);
+ if (table->vfield)
+ update_virtual_fields(thd, table);
if (cond && !cond->val_int())
continue;
if (num_rows >= offset_limit_cnt)
@@ -718,13 +850,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);
@@ -732,6 +864,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.
@@ -742,30 +896,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);
}
@@ -782,18 +938,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;
}
@@ -813,16 +969,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;
@@ -839,14 +995,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_help.cc b/sql/sql_help.cc
index a93fd23a57f..7879c3c74b7 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -639,7 +639,7 @@ bool mysqld_help(THD *thd, const char *mask)
Protocol *protocol= thd->protocol;
SQL_SELECT *select;
st_find_field used_fields[array_elements(init_used_fields)];
- TABLE_LIST *leaves= 0;
+ List<TABLE_LIST> leaves;
TABLE_LIST tables[4];
List<String> topics_list, categories_list, subcategories_list;
String name, description, example;
@@ -678,7 +678,7 @@ bool mysqld_help(THD *thd, const char *mask)
thd->lex->select_lex.context.first_name_resolution_table= &tables[0];
if (setup_tables(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list,
- tables, &leaves, FALSE))
+ tables, leaves, FALSE, FALSE))
goto error;
memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 53948f11923..7ab2ed8e1b6 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -119,7 +119,7 @@ bool check_view_single_update(List<Item> &fields, List<Item> *values,
{
it.init(*values);
while ((item= it++))
- tables|= item->used_tables();
+ tables|= item->view_used_tables(view);
}
/* Convert to real table bits */
@@ -135,6 +135,11 @@ bool check_view_single_update(List<Item> &fields, List<Item> *values,
if (view->check_single_table(&tbl, tables, view) || tbl == 0)
goto error;
+ /*
+ A buffer for the insert values was allocated for the merged view.
+ Use it.
+ */
+ tbl->table->insert_values= view->table->insert_values;
view->table= tbl->table;
if (!tbl->single_table_updatable())
{
@@ -246,6 +251,10 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
*/
table_list->next_local= 0;
context->resolve_in_table_list_only(table_list);
+ /* 'Unfix' fields to allow correct marking by the setup_fields function. */
+ if (table_list->is_view())
+ unfix_fields(fields);
+
res= setup_fields(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0);
/* Restore the current context. */
@@ -255,7 +264,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
if (res)
return -1;
- if (table_list->effective_algorithm == VIEW_ALGORITHM_MERGE)
+ if (table_list->is_view() && table_list->is_merged_derived())
{
if (check_view_single_update(fields,
fields_and_values_from_different_maps ?
@@ -344,7 +353,8 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
if (setup_fields(thd, 0, update_fields, MARK_COLUMNS_WRITE, 0, 0))
return -1;
- if (insert_table_list->effective_algorithm == VIEW_ALGORITHM_MERGE &&
+ if (insert_table_list->is_view() &&
+ insert_table_list->is_merged_derived() &&
check_view_single_update(update_fields, &update_values,
insert_table_list, map, false))
return -1;
@@ -634,8 +644,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))
@@ -644,6 +653,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
table_list->table_name);
DBUG_RETURN(TRUE);
}
+ /*
+ mark the table_list as a target for insert, to skip the DT/view prepare phase
+ for correct access rights checks
+ TODO: remove this hack
+ */
+ table_list->skip_prepare_derived= TRUE;
if (table_list->lock_type == TL_WRITE_DELAYED)
{
@@ -655,6 +670,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
}
+
lock_type= table_list->lock_type;
thd_proc_info(thd, "init");
@@ -820,7 +836,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)
@@ -934,7 +955,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
thd->clear_error();
}
else
- errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ errcode= query_error_code(thd, thd->killed == NOT_KILLED);
/* bug#22725:
@@ -948,7 +969,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
routines did not result in any error due to the KILLED. In
such case the flag is ignored for constructing binlog event.
*/
- DBUG_ASSERT(thd->killed != THD::KILL_BAD_DATA || error > 0);
+ DBUG_ASSERT(thd->killed != KILL_BAD_DATA || error > 0);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
transactional_table, FALSE,
@@ -1013,6 +1034,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
::my_ok(thd, (ulong) thd->row_count_func, id, buff);
}
thd->abort_on_warning= 0;
+ if (thd->lex->current_select->first_cond_optimization)
+ {
+ thd->lex->current_select->save_leaf_tables(thd);
+ thd->lex->current_select->first_cond_optimization= 0;
+ }
+
DBUG_RETURN(FALSE);
abort:
@@ -1141,6 +1168,11 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
bool insert_into_view= (table_list->view != 0);
DBUG_ENTER("mysql_prepare_insert_check_table");
+ if (!table_list->single_table_updatable())
+ {
+ my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT");
+ DBUG_RETURN(TRUE);
+ }
/*
first table in list is the one we'll INSERT into, requires INSERT_ACL.
all others require SELECT_ACL only. the ACL requirement below is for
@@ -1151,14 +1183,16 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list,
table_list,
- &thd->lex->select_lex.leaf_tables,
- select_insert, INSERT_ACL, SELECT_ACL))
+ thd->lex->select_lex.leaf_tables,
+ select_insert, INSERT_ACL, SELECT_ACL,
+ TRUE))
DBUG_RETURN(TRUE);
if (insert_into_view && !fields.elements)
{
thd->lex->empty_field_list_on_rset= 1;
- if (!table_list->table)
+ if (!thd->lex->select_lex.leaf_tables.head()->table ||
+ table_list->is_multitable())
{
my_error(ER_VIEW_NO_INSERT_FIELD_LIST, MYF(0),
table_list->view_db.str, table_list->view_name.str);
@@ -1249,6 +1283,12 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
/* INSERT should have a SELECT or VALUES clause */
DBUG_ASSERT (!select_insert || !values);
+ if (mysql_handle_derived(thd->lex, DT_INIT))
+ DBUG_RETURN(TRUE);
+ if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
+ DBUG_RETURN(TRUE);
+ if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE))
+ DBUG_RETURN(TRUE);
/*
For subqueries in VALUES() we should not see the table in which we are
inserting (for INSERT ... SELECT this is done by changing table_list,
@@ -1548,11 +1588,12 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
else
error= 0;
/*
- If ON DUP KEY UPDATE updates a row instead of inserting one, it's
- like a regular UPDATE statement: it should not affect the value of a
- next SELECT LAST_INSERT_ID() or mysql_insert_id().
- Except if LAST_INSERT_ID(#) was in the INSERT query, which is
- handled separately by THD::arg_of_last_insert_id_function.
+ If ON DUP KEY UPDATE updates a row instead of inserting
+ one, it's like a regular UPDATE statement: it should not
+ affect the value of a next SELECT LAST_INSERT_ID() or
+ mysql_insert_id(). Except if LAST_INSERT_ID(#) was in the
+ INSERT query, which is handled separately by
+ THD::arg_of_last_insert_id_function.
*/
insert_id_for_cur_row= table->file->insert_id_for_cur_row= 0;
trg_error= (table->triggers &&
@@ -1629,11 +1670,12 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
}
/*
- If more than one iteration of the above while loop is done, from the second
- one the row being inserted will have an explicit value in the autoinc field,
- which was set at the first call of handler::update_auto_increment(). This
- value is saved to avoid thd->insert_id_for_cur_row becoming 0. Use this saved
- autoinc value.
+ If more than one iteration of the above while loop is done, from
+ the second one the row being inserted will have an explicit
+ value in the autoinc field, which was set at the first call of
+ handler::update_auto_increment(). This value is saved to avoid
+ thd->insert_id_for_cur_row becoming 0. Use this saved autoinc
+ value.
*/
if (table->file->insert_id_for_cur_row == 0)
table->file->insert_id_for_cur_row= insert_id_for_cur_row;
@@ -1673,9 +1715,6 @@ ok_or_after_trg_err:
err:
info->last_errno= error;
- /* current_select is NULL if this is a delayed insert */
- if (thd->lex->current_select)
- thd->lex->current_select->no_error= 0; // Give error
table->file->print_error(error,MYF(0));
before_trg_err:
@@ -1741,10 +1780,11 @@ class delayed_row :public ilink {
public:
char *record;
enum_duplicates dup;
- time_t start_time;
+ my_time_t start_time;
+ ulong start_time_sec_part;
ulong sql_mode;
bool auto_increment_field_not_null;
- bool query_start_used, ignore, log_query;
+ bool query_start_used, ignore, log_query, query_start_sec_part_used;
bool stmt_depends_on_first_successful_insert_id_in_prev_stmt;
ulonglong first_successful_insert_id_in_prev_stmt;
ulonglong forced_insert_id;
@@ -1981,6 +2021,11 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
pthread_mutex_lock(&LOCK_thread_count);
thread_count++;
pthread_mutex_unlock(&LOCK_thread_count);
+ /*
+ Annotating delayed inserts is not supported.
+ */
+ di->thd.variables.binlog_annotate_row_events= 0;
+
di->thd.set_db(table_list->db, (uint) strlen(table_list->db));
di->thd.set_query(my_strdup(table_list->table_name, MYF(MY_WME)), 0);
if (di->thd.db == NULL || di->thd.query() == NULL)
@@ -2269,8 +2314,10 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic,
if (!(row->record= (char*) my_malloc(table->s->reclength, MYF(MY_WME))))
goto err;
memcpy(row->record, table->record[0], table->s->reclength);
- row->start_time= thd->start_time;
- row->query_start_used= thd->query_start_used;
+ row->start_time= thd->start_time;
+ row->query_start_used= thd->query_start_used;
+ row->start_time_sec_part= thd->start_time_sec_part;
+ row->query_start_sec_part_used= thd->query_start_sec_part_used;
/*
those are for the binlog: LAST_INSERT_ID() has been evaluated at this
time, so record does not need it, but statement-based binlogging of the
@@ -2358,7 +2405,7 @@ void kill_delayed_threads(void)
Delayed_insert *di;
while ((di= it++))
{
- di->thd.killed= THD::KILL_SYSTEM_THREAD;
+ di->thd.killed= KILL_SYSTEM_THREAD;
pthread_mutex_lock(&di->thd.LOCK_thd_data);
if (di->thd.mysys_var)
{
@@ -2443,8 +2490,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
for (;;)
{
- if (thd->killed == THD::KILL_CONNECTION ||
- thd->killed == THD::KILL_SYSTEM_THREAD || thd->killed == THD::KILL_SERVER)
+ if (thd->killed >= KILL_CONNECTION)
{
uint lock_count;
/*
@@ -2492,7 +2538,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
break;
if (error == ETIMEDOUT || error == ETIME)
{
- thd->killed= THD::KILL_SYSTEM_THREAD;
+ thd->killed= KILL_SYSTEM_THREAD;
break;
}
}
@@ -2525,7 +2571,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
{
/* Fatal error */
di->dead= 1;
- thd->killed= THD::KILL_SYSTEM_THREAD;
+ thd->killed= KILL_SYSTEM_THREAD;
}
pthread_cond_broadcast(&di->cond_client);
}
@@ -2535,7 +2581,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
{
/* Some fatal error */
di->dead= 1;
- thd->killed= THD::KILL_SYSTEM_THREAD;
+ thd->killed= KILL_SYSTEM_THREAD;
}
}
di->status=0;
@@ -2595,7 +2641,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
thd->set_current_time();
threads.append(thd);
- thd->killed=abort_loop ? THD::KILL_SYSTEM_THREAD : THD::NOT_KILLED;
+ thd->killed=abort_loop ? KILL_SYSTEM_THREAD : NOT_KILLED;
pthread_mutex_unlock(&LOCK_thread_count);
/*
@@ -2629,7 +2675,7 @@ end:
di->table=0;
di->dead= 1; // If error
- thd->killed= THD::KILL_SYSTEM_THREAD; // If error
+ thd->killed= KILL_SYSTEM_THREAD; // If error
pthread_mutex_unlock(&di->mutex);
close_thread_tables(thd); // Free the table
@@ -2708,7 +2754,7 @@ bool Delayed_insert::handle_inserts(void)
max_rows= delayed_insert_limit;
if (thd.killed || table->needs_reopen_or_name_lock())
{
- thd.killed= THD::KILL_SYSTEM_THREAD;
+ thd.killed= KILL_SYSTEM_THREAD;
max_rows= ULONG_MAX; // Do as much as possible
}
@@ -2729,6 +2775,8 @@ bool Delayed_insert::handle_inserts(void)
thd.start_time=row->start_time;
thd.query_start_used=row->query_start_used;
+ thd.start_time_sec_part=row->start_time_sec_part;
+ thd.query_start_sec_part_used=row->query_start_sec_part_used;
/*
To get the exact auto_inc interval to store in the binlog we must not
use values from the previous interval (of the previous rows).
@@ -2819,7 +2867,7 @@ bool Delayed_insert::handle_inserts(void)
/* if the delayed insert was killed, the killed status is
ignored while binlogging */
int errcode= 0;
- if (thd.killed == THD::NOT_KILLED)
+ if (thd.killed == NOT_KILLED)
errcode= query_error_code(&thd, TRUE);
/*
@@ -2965,9 +3013,9 @@ bool mysql_insert_select_prepare(THD *thd)
{
LEX *lex= thd->lex;
SELECT_LEX *select_lex= &lex->select_lex;
- TABLE_LIST *first_select_leaf_table;
DBUG_ENTER("mysql_insert_select_prepare");
+
/*
Statement-based replication of INSERT ... SELECT ... LIMIT is not safe
as order of rows is not defined, so in mixed mode we go to row-based.
@@ -2993,21 +3041,38 @@ bool mysql_insert_select_prepare(THD *thd)
&select_lex->where, TRUE, FALSE, FALSE))
DBUG_RETURN(TRUE);
+ DBUG_ASSERT(select_lex->leaf_tables.elements != 0);
+ List_iterator<TABLE_LIST> ti(select_lex->leaf_tables);
+ TABLE_LIST *table;
+ uint insert_tables;
+
+ if (select_lex->first_cond_optimization)
+ {
+ /* Back up leaf_tables list. */
+ Query_arena *arena= thd->stmt_arena, backup;
+ arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test
+
+ insert_tables= select_lex->insert_tables;
+ while ((table= ti++) && insert_tables--)
+ {
+ select_lex->leaf_tables_exec.push_back(table);
+ table->tablenr_exec= table->table->tablenr;
+ table->map_exec= table->table->map;
+ table->maybe_null_exec= table->table->maybe_null;
+ }
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ }
+ ti.rewind();
/*
exclude first table from leaf tables list, because it belong to
INSERT
*/
- DBUG_ASSERT(select_lex->leaf_tables != 0);
- lex->leaf_tables_insert= select_lex->leaf_tables;
/* skip all leaf tables belonged to view where we are insert */
- for (first_select_leaf_table= select_lex->leaf_tables->next_leaf;
- first_select_leaf_table &&
- first_select_leaf_table->belong_to_view &&
- first_select_leaf_table->belong_to_view ==
- lex->leaf_tables_insert->belong_to_view;
- first_select_leaf_table= first_select_leaf_table->next_leaf)
- {}
- select_lex->leaf_tables= first_select_leaf_table;
+ insert_tables= select_lex->insert_tables;
+ while ((table= ti++) && insert_tables--)
+ ti.remove();
+
DBUG_RETURN(FALSE);
}
@@ -3050,8 +3115,6 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
*/
lex->current_select= &lex->select_lex;
- /* Errors during check_insert_fields() should not be ignored. */
- lex->current_select->no_error= FALSE;
res= (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0) ||
check_insert_fields(thd, table_list, *fields, values,
!insert_into_view, 1, &map));
@@ -3224,7 +3287,7 @@ void select_insert::cleanup()
select_insert::~select_insert()
{
DBUG_ENTER("~select_insert");
- if (table)
+ if (table && table->created)
{
table->next_number_field=0;
table->auto_increment_field_not_null= FALSE;
@@ -3331,7 +3394,7 @@ bool select_insert::send_eof()
bool const trans_table= table->file->has_transactions();
ulonglong id;
bool changed;
- THD::killed_state killed_status= thd->killed;
+ killed_state killed_status= thd->killed;
DBUG_ENTER("select_insert::send_eof");
DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'",
trans_table, table->file->table_type()));
@@ -3366,7 +3429,7 @@ bool select_insert::send_eof()
if (!error)
thd->clear_error();
else
- errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ errcode= query_error_code(thd, killed_status == NOT_KILLED);
if (write_to_binlog(trans_table, errcode))
{
@@ -3440,7 +3503,7 @@ void select_insert::abort() {
{
if (mysql_bin_log.is_open())
{
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
/* error of writing binary log is ignored */
write_to_binlog(transactional_table, errcode);
}
@@ -3625,9 +3688,6 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
tmp_table.s->db_create_options=0;
tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
- tmp_table.s->db_low_byte_first=
- test(create_info->db_type == myisam_hton ||
- create_info->db_type == heap_hton);
tmp_table.null_row= 0;
tmp_table.maybe_null= 0;
@@ -3803,7 +3863,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
!table->s->tmp_table &&
!ptr->get_create_info()->table_existed)
{
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
if (int error= ptr->binlog_show_create_table(tables, count, errcode))
return error;
}
@@ -3846,7 +3906,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
create_table->table_name);
if (thd->current_stmt_binlog_row_based)
{
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
binlog_show_create_table(&(create_table->table), 1, errcode);
}
table= create_table->table;
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
new file mode 100644
index 00000000000..1121c591c3b
--- /dev/null
+++ b/sql/sql_join_cache.cc
@@ -0,0 +1,4661 @@
+/* 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)
+
+static void save_or_restore_used_tabs(JOIN_TAB *join_tab, bool save);
+
+/*****************************************************************************
+ * 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;
+}
+
+/*
+ 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;
+
+ if (prev_cache)
+ tab= prev_cache->join_tab;
+ else
+ {
+ if (join_tab->bush_root_tab)
+ {
+ /*
+ --ot1--SJM1--------------ot2--...
+ |
+ |
+ +-it1--...--itN
+ ^____________ this->join_tab is somewhere here,
+ inside an sjm nest.
+
+ The join buffer should store the values of it1.*, it2.*, ..
+ It should not store values of ot1.*.
+ */
+ tab= join_tab->bush_root_tab->bush_children->start;
+ }
+ else
+ {
+ /*
+ -ot1--ot2--SJM1--SJM2--------------ot3--...--otN
+ | | ^
+ | +-it21--...--it2N |
+ | \-- we're somewhere here,
+ +-it11--...--it1N at the top level
+
+ The join buffer should store the values of
+
+ ot1.*, ot2.*, it1{i}, it2{j}.*, ot3.*, ...
+
+ that is, we should start from the first non-const top-level table.
+
+ We will need to store columns of SJ-inner tables (it_X_Y.*), but we're
+ not interested in storing the columns of materialization tables
+ themselves. Beause of that, if the first non-const top-level table is a
+ materialized table, we move to its bush_children:
+ */
+ tab= join->join_tab + join->const_tables;
+ if (tab->bush_children)
+ tab= tab->bush_children->start;
+ }
+ }
+ DBUG_ASSERT(!tab->bush_children);
+
+ start_tab= tab;
+ fields= 0;
+ blobs= 0;
+ flag_fields= 0;
+ data_field_count= 0;
+ data_field_ptr_count= 0;
+ referenced_fields= 0;
+
+ /*
+ The following loop will get inside SJM nests, because data may be unpacked
+ to sjm-inner tables.
+ */
+ for (; tab != join_tab ; tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
+ {
+ 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;
+ }
+ 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->start_tab; tab != cache->join_tab;
+ tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
+ {
+ 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= start_tab; tab != join_tab;
+ tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
+ {
+ 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->start_tab; tab != cache->join_tab;
+ tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
+ {
+ 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= start_tab; tab != join_tab;
+ tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
+ {
+ 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= start_tab; tab != join_tab;
+ tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
+ {
+ 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;
+ if (copy->str)
+ copy->length= table->file->ref_length;
+ else
+ {
+ /* This may happen only for materialized derived tables and views */
+ copy->length= 0;
+ copy->str= (uchar *) table;
+ }
+ copy->type= CACHE_ROWID;
+ copy->field= 0;
+ copy->referenced_field_no= 0;
+ /*
+ Note: this may seem odd, but at this point we have
+ table->file->ref==NULL while table->file->ref_length is already set
+ to correct value.
+ */
+ length += table->file->ref_length;
+ data_field_count++;
+ copy++;
+ }
+ }
+}
+
+
+
+/*
+ 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);
+ /*
+ The values of size_of_rec_ofs, size_of_rec_len, size_of_fld_ofs,
+ base_prefix_length, pack_length, pack_length_with_blob_ptrs
+ will be recalculated later in this function when we get the estimate
+ for the actual value of the join buffer size.
+ */
+ size_of_rec_ofs= size_of_rec_len= size_of_fld_ofs= 4;
+ base_prefix_length= (with_length ? size_of_rec_len : 0) +
+ (prev_cache ? prev_cache->get_size_of_rec_offset() : 0);
+ pack_length= (with_length ? size_of_rec_len : 0) +
+ (prev_cache ? prev_cache->get_size_of_rec_offset() : 0) +
+ length + fields*sizeof(uint);
+ pack_length_with_blob_ptrs= pack_length + blobs*sizeof(uchar *);
+ min_buff_size= 0;
+ min_records= 1;
+ buff_size= max(join->thd->variables.join_buff_size,
+ get_min_join_buffer_size());
+ 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)
+ {
+ size_t len= 0;
+ size_t len_last= 0;
+ for (JOIN_TAB *tab= start_tab; tab != join_tab;
+ tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
+ {
+ len+= tab->get_max_used_fieldlength();
+ len_last=+ tab->get_used_fieldlength();
+ }
+ size_t len_addon= get_record_max_affix_length() +
+ get_max_key_addon_space_per_record();
+ len+= len_addon;
+ len_last+= len_addon;
+ size_t min_sz= len*(min_records-1) + len_last;
+ min_sz+= pack_length_with_blob_ptrs;
+ size_t 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;
+ set_if_bigger(min_sz, 1);
+ 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()
+
+ optimize_buff_size FALSE <-> do not take more memory than needed for
+ the estimated number of records in the partial join
+
+ DESCRIPTION
+ At the first its invocation for the cache the function calculates the
+ maximum possible size of join buffer for the cache. If the parameter
+ optimize_buff_size true then this value does not exceed the size of the
+ space needed for the estimated 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(bool optimize_buff_size)
+{
+ if (!max_buff_size)
+ {
+ size_t max_sz;
+ size_t min_sz= get_min_join_buffer_size();
+ size_t len= 0;
+ for (JOIN_TAB *tab= start_tab; tab != join_tab;
+ tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
+ {
+ 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;
+
+ size_t 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 (!optimize_buff_size)
+ max_sz= limit_sz;
+ else
+ {
+ 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;
+ bool optimize_buff_size=
+ optimizer_flag(join->thd, OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE);
+ 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= (size_t) (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(optimize_buff_size);
+
+ for (tab= start_tab; tab!= join_tab;
+ tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
+ {
+ 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();
+ }
+ }
+ curr_min_buff_space_sz+= min_buff_size;
+ curr_buff_space_sz+= buff_size;
+
+ if (curr_min_buff_space_sz > join_buff_space_limit ||
+ (curr_buff_space_sz > join_buff_space_limit &&
+ (!optimize_buff_size ||
+ 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)
+{
+ size_t next_buff_size;
+ if (n < d)
+ return FALSE;
+ next_buff_size= (size_t) ((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_REF *ref= &join_tab->ref;
+ KEY *keyinfo= join_tab->get_keyinfo_by_key_no(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);
+ size_t 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;
+ DBUG_ASSERT(cp + size_of_rec_len <= buff + buff_size);
+ 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)
+ {
+ DBUG_ASSERT(cp + prev_cache->get_size_of_rec_offset() <= buff + buff_size);
+ cp+= prev_cache->get_size_of_rec_offset();
+ prev_cache->store_rec_ref(cp, link);
+ }
+
+ 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++)
+ {
+ DBUG_ASSERT(cp + copy->length <= buff + buff_size);
+ 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())
+ {
+ 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 */
+ DBUG_ASSERT(cp + copy->length + sizeof(char*) <= buff + buff_size);
+ blob_field->get_image(cp, copy->length+sizeof(char*),
+ blob_field->charset());
+ cp+= copy->length+sizeof(char*);
+ }
+ else
+ {
+ /* First put down the length of the blob and then copy the data */
+ blob_field->get_image(cp, copy->length,
+ blob_field->charset());
+ DBUG_ASSERT(cp + copy->length + copy->blob_length <= buff + buff_size);
+ memcpy(cp+copy->length, copy->str, copy->blob_length);
+ cp+= copy->length+copy->blob_length;
+ }
+ }
+ else
+ {
+ switch (copy->type) {
+ case CACHE_VARSTR1:
+ /* Copy the significant part of the short varstring field */
+ len= (uint) copy->str[0] + 1;
+ DBUG_ASSERT(cp + len <= buff + buff_size);
+ memcpy(cp, copy->str, len);
+ cp+= len;
+ break;
+ case CACHE_VARSTR2:
+ /* Copy the significant part of the long varstring field */
+ len= uint2korr(copy->str) + 2;
+ DBUG_ASSERT(cp + len <= buff + buff_size);
+ memcpy(cp, copy->str, len);
+ cp+= len;
+ break;
+ 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);
+ DBUG_ASSERT(cp + len + 2 <= buff + buff_size);
+ int2store(cp, len);
+ memcpy(cp+2, str, len);
+ cp+= len+2;
+ break;
+ }
+ case CACHE_ROWID:
+ if (!copy->length)
+ {
+ /*
+ This may happen only for ROWID fields of materialized
+ derived tables and views.
+ */
+ TABLE *table= (TABLE *) copy->str;
+ copy->str= table->file->ref;
+ copy->length= table->file->ref_length;
+ if (!copy->str)
+ {
+ /*
+ If table is an empty inner table of an outer join and it is
+ a materialized derived table then table->file->ref == NULL.
+ */
+ cp+= copy->length;
+ break;
+ }
+ }
+ /* fall through */
+ default:
+ /* Copy the entire image of the field from the record buffer */
+ DBUG_ASSERT(cp + copy->length <= buff + buff_size);
+ if (copy->str)
+ 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++;
+ }
+ }
+ DBUG_ASSERT(cp + size_of_fld_ofs*cnt <= buff + buff_size);
+ 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;
+ case CACHE_ROWID:
+ if (!copy->str)
+ {
+ len= copy->length;
+ break;
+ }
+ /* fall through */
+ default:
+ /* Copy the entire image of the field from the record buffer */
+ len= copy->length;
+ 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();
+ DBUG_ENTER("JOIN_CACHE::join_records");
+
+ 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 (skip_last)
+ {
+ DBUG_ASSERT(!is_key_access());
+ /*
+ Restore the last record from the join buffer to generate
+ all extentions for it.
+ */
+ get_record();
+ }
+
+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;
+ }
+ restore_last_record();
+ reset(TRUE);
+ DBUG_PRINT("exit", ("rc: %d", rc));
+ DBUG_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();
+ DBUG_ENTER("JOIN_CACHE::join_matching_records");
+
+ /* Return at once if there are no records in the join buffer */
+ if (!records)
+ DBUG_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;
+ }
+
+ if ((rc= join_tab_execution_startup(join_tab)) < 0)
+ goto finish2;
+
+ /* Prepare to retrieve all records of the joined table */
+ if ((error= join_tab_scan->open()))
+ {
+ /*
+ TODO: if we get here, we will assert in net_send_statement(). Add test
+ coverage and fix.
+ */
+ goto finish;
+ }
+
+ 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;
+finish2:
+ join_tab_scan->close();
+ DBUG_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;
+ DBUG_ENTER("JOIN_CACHE::generate_full_extensions");
+
+ /*
+ 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= join_tab->check_weed_out_table->sj_weedout_check_row(join->thd)))
+ {
+ 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);
+ DBUG_RETURN(rc);
+ }
+ }
+ if (res == -1)
+ {
+ rc= NESTED_LOOP_ERROR;
+ DBUG_RETURN(rc);
+ }
+ }
+ else if (join->thd->is_error())
+ rc= NESTED_LOOP_ERROR;
+ DBUG_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
+ In this case the caller must also check thd->is_error() to see
+ if there was a fatal error for the query.
+*/
+
+inline bool JOIN_CACHE::check_match(uchar *rec_ptr)
+{
+ /* Check whether pushdown conditions are satisfied */
+ DBUG_ENTER("JOIN_CACHE:check_match");
+
+ if (join_tab->select && join_tab->select->skip_record(join->thd) <= 0)
+ DBUG_RETURN(FALSE);
+
+ if (!join_tab->is_last_inner_table())
+ DBUG_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)
+ DBUG_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)
+ DBUG_RETURN(FALSE);
+ }
+ }
+ while ((first_inner= first_inner->first_upper) &&
+ first_inner->last_inner == join_tab);
+ DBUG_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)
+{
+ ulonglong cnt;
+ enum_nested_loop_state rc= NESTED_LOOP_OK;
+ bool is_first_inner= join_tab == join_tab->first_unmatched;
+ DBUG_ENTER("JOIN_CACHE::join_null_complements");
+
+ /* Return at once if there are no records in the join buffer */
+ if (!records)
+ DBUG_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:
+ DBUG_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(")"));
+}
+
+/**
+ get thread handle.
+*/
+
+THD *JOIN_CACHE::thd()
+{
+ return join->thd;
+}
+
+
+static void add_mrr_explain_info(String *str, uint mrr_mode, handler *file)
+{
+ char mrr_str_buf[128]={0};
+ int len;
+ len= file->multi_range_read_explain_info(mrr_mode, mrr_str_buf,
+ sizeof(mrr_str_buf));
+ if (len > 0)
+ {
+ str->append(STRING_WITH_LEN("; "));
+ str->append(mrr_str_buf, len);
+ }
+}
+
+
+void JOIN_CACHE_BKA::print_explain_comment(String *str)
+{
+ JOIN_CACHE::print_explain_comment(str);
+ add_mrr_explain_info(str, mrr_mode, join_tab->table->file);
+}
+
+
+void JOIN_CACHE_BKAH::print_explain_comment(String *str)
+{
+ JOIN_CACHE::print_explain_comment(str);
+ add_mrr_explain_info(str, mrr_mode, join_tab->table->file);
+}
+
+
+/*
+ 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->get_keyinfo_by_key_no(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()
+{
+ save_or_restore_used_tabs(join_tab, FALSE);
+ 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;
+ TABLE *table= join_tab->table;
+ THD *thd= join->thd;
+
+ if (is_first_record)
+ is_first_record= FALSE;
+ else
+ err= info->read_record(info);
+ if (!err && table->vfield)
+ update_virtual_fields(thd, table);
+ while (!err && select && (skip_rc= select->skip_record(thd)) <= 0)
+ {
+ if (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 && table->vfield)
+ update_virtual_fields(thd, table);
+ }
+ return err;
+}
+
+
+/*
+ Walk back in join order from join_tab until we encounter a join tab with
+ tab->cache!=NULL, and save/restore tab->table->status along the way.
+
+ @param save TRUE save
+ FALSE restore
+*/
+
+static void save_or_restore_used_tabs(JOIN_TAB *join_tab, bool save)
+{
+ JOIN_TAB *first= join_tab->bush_root_tab?
+ join_tab->bush_root_tab->bush_children->start :
+ join_tab->join->join_tab + join_tab->join->const_tables;
+
+ for (JOIN_TAB *tab= join_tab-1; tab != first && !tab->cache; tab--)
+ {
+ if (tab->bush_children)
+ {
+ for (JOIN_TAB *child= tab->bush_children->start;
+ child != tab->bush_children->end;
+ child++)
+ {
+ if (save)
+ child->table->status= child->status;
+ else
+ {
+ tab->status= tab->table->status;
+ tab->table->status= 0;
+ }
+ }
+ }
+
+ if (save)
+ tab->table->status= tab->status;
+ else
+ {
+ tab->status= tab->table->status;
+ tab->table->status= 0;
+ }
+ }
+}
+
+
+/*
+ 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()
+{
+ save_or_restore_used_tabs(join_tab, TRUE);
+}
+
+
+/*
+ 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= join_tab->get_keyinfo_by_key_no(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, TRUE);
+ /* 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);
+
+ save_or_restore_used_tabs(join_tab, FALSE);
+
+ 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();
+
+ DBUG_ASSERT(sizeof(range_id_t) == sizeof(*ptr));
+ int rc= join_tab->table->file->multi_range_read_next((range_id_t*)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((!(mrr_mode & HA_MRR_NO_ASSOCIATION))?
+ (cache->buff <= (uchar *) (*ptr) &&
+ (uchar *) (*ptr) <= cache->end_pos): TRUE);
+ if (join_tab->table->vfield)
+ 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, range_id_t 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, range_id_t range_info)
+{
+ DBUG_ENTER("bka_skip_index_tuple");
+ JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq;
+ THD *thd= cache->thd();
+ bool res;
+ status_var_increment(thd->status_var.ha_icp_attempts);
+ if (!(res= cache->skip_index_tuple(range_info)))
+ status_var_increment(thd->status_var.ha_icp_match);
+ DBUG_RETURN(res);
+}
+
+
+/*
+ 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(range_id_t 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, range_id_t 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, range_id_t range_info)
+{
+ DBUG_ENTER("bka_unique_skip_index_tuple");
+ JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) rseq;
+ THD *thd= cache->thd();
+ bool res;
+ status_var_increment(thd->status_var.ha_icp_attempts);
+ if (!(res= cache->skip_index_tuple(range_info)))
+ status_var_increment(thd->status_var.ha_icp_match);
+ DBUG_RETURN(res);
+}
+
+
+/*
+ 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(range_id_t 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..ba8e4ba8e4a
--- /dev/null
+++ b/sql/sql_join_cache.h
@@ -0,0 +1,1414 @@
+/*
+ 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) */
+#define CACHE_ROWID 5 /* ROWID field */
+
+/*
+ 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;
+
+ /*
+ JOIN_TAB of the first table that can have it's fields in the join cache.
+ That is, tables in the [start_tab, tab) range can have their fields in the
+ join cache.
+ If a join tab in the range represents an SJM-nest, then all tables from the
+ nest can have their fields in the join cache, too.
+ */
+ JOIN_TAB *start_tab;
+
+ /*
+ 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
+ */
+ size_t avg_record_length;
+
+ /* The expected size of the space per record in the auxiliary buffer */
+ size_t avg_aux_buffer_incr;
+
+ /* Expected join buffer space used for one record */
+ size_t 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.
+ */
+ size_t buff_size;
+ /* The minimal join buffer size when join buffer still makes sense to use */
+ size_t min_buff_size;
+ /* The maximum expected size if the join buffer to be used */
+ size_t max_buff_size;
+ /* Size of the auxiliary buffer */
+ size_t aux_buff_size;
+
+ /* The number of records put into the join buffer */
+ size_t records;
+ /*
+ The number of records in the fully refilled join buffer of
+ the minimal size equal to min_buff_size
+ */
+ size_t min_records;
+ /*
+ The maximum expected number of records to be put in the join buffer
+ at one refill
+ */
+ size_t 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 size_t 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 */
+ size_t get_join_buffer_size() { return buff_size; }
+ /* Set the size of the cache join buffer to a new value */
+ void set_join_buffer_size(size_t 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(bool optimize_buff_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 */
+ virtual void print_explain_comment(String *str);
+
+ THD *thd();
+
+ virtual ~JOIN_CACHE() {}
+ void reset_join(JOIN *j) { join= j; }
+ void free()
+ {
+ x_free(buff);
+ buff= 0;
+ }
+
+ 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.
+ */
+ size_t 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 (uint)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(range_id_t range_info);
+
+ void print_explain_comment(String *str);
+};
+
+
+
+/*
+ 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(range_id_t range_info);
+
+ void print_explain_comment(String *str);
+};
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 47dd392346c..5bacb675644 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -26,6 +26,7 @@
#include <hash.h>
#include "sp_head.h"
#include "sp.h"
+#include "sql_select.h"
/*
We are using pointer to this variable for distinguishing between assignment
@@ -314,7 +315,6 @@ void lex_start(THD *thd)
lex->derived_tables= 0;
lex->lock_option= TL_READ;
lex->safe_to_cache_query= 1;
- lex->leaf_tables_insert= 0;
lex->parsing_options.reset();
lex->empty_field_list_on_rset= 0;
lex->select_lex.select_number= 1;
@@ -344,6 +344,7 @@ void lex_start(THD *thd)
lex->event_parse_data= NULL;
lex->profile_options= PROFILE_NONE;
lex->nest_level=0 ;
+ lex->select_lex.nest_level_base= &lex->unit;
lex->allow_sum_func= 0;
lex->in_sum_func= NULL;
lex->protect_against_global_read_lock= FALSE;
@@ -824,45 +825,48 @@ int MYSQLlex(void *arg, void *yythd)
yylval->lex_str.length=2;
return NULL_SYM;
}
+ /* Fall through */
case MY_LEX_CHAR: // Unknown or single char token
case MY_LEX_SKIP: // This should not happen
- if (c == '-' && lip->yyPeek() == '-' &&
+ if (c != ')')
+ lip->next_state= MY_LEX_START; // Allow signed numbers
+ return((int) c);
+
+ case MY_LEX_MINUS_OR_COMMENT:
+ if (lip->yyPeek() == '-' &&
(my_isspace(cs,lip->yyPeekn(1)) ||
my_iscntrl(cs,lip->yyPeekn(1))))
{
state=MY_LEX_COMMENT;
break;
}
+ lip->next_state= MY_LEX_START; // Allow signed numbers
+ return((int) c);
- if (c != ')')
- lip->next_state= MY_LEX_START; // Allow signed numbers
-
- if (c == ',')
- {
- /*
- Warning:
- This is a work around, to make the "remember_name" rule in
- sql/sql_yacc.yy work properly.
- The problem is that, when parsing "select expr1, expr2",
- the code generated by bison executes the *pre* action
- remember_name (see select_item) *before* actually parsing the
- first token of expr2.
- */
- lip->restart_token();
- }
- else
- {
- /*
- Check for a placeholder: it should not precede a possible identifier
- because of binlogging: when a placeholder is replaced with
- its value in a query for the binlog, the query must stay
- grammatically correct.
- */
- if (c == '?' && lip->stmt_prepare_mode &&
- !ident_map[(uchar) lip->yyPeek()])
+ case MY_LEX_PLACEHOLDER:
+ /*
+ Check for a placeholder: it should not precede a possible identifier
+ because of binlogging: when a placeholder is replaced with
+ its value in a query for the binlog, the query must stay
+ grammatically correct.
+ */
+ lip->next_state= MY_LEX_START; // Allow signed numbers
+ if (lip->stmt_prepare_mode && !ident_map[(uchar) lip->yyPeek()])
return(PARAM_MARKER);
- }
+ return((int) c);
+ case MY_LEX_COMMA:
+ lip->next_state= MY_LEX_START; // Allow signed numbers
+ /*
+ Warning:
+ This is a work around, to make the "remember_name" rule in
+ sql/sql_yacc.yy work properly.
+ The problem is that, when parsing "select expr1, expr2",
+ the code generated by bison executes the *pre* action
+ remember_name (see select_item) *before* actually parsing the
+ first token of expr2.
+ */
+ lip->restart_token();
return((int) c);
case MY_LEX_IDENT_OR_NCHAR:
@@ -1275,39 +1279,39 @@ int MYSQLlex(void *arg, void *yythd)
lip->save_in_comment_state();
+ if (lip->yyPeekn(2) == 'M' && lip->yyPeekn(3) == '!')
+ {
+ /* Skip MariaDB unique marker */
+ lip->set_echo(FALSE);
+ lip->yySkip();
+ /* The following if will be true */
+ }
if (lip->yyPeekn(2) == '!')
{
lip->in_comment= DISCARD_COMMENT;
/* Accept '/' '*' '!', but do not keep this marker. */
lip->set_echo(FALSE);
- lip->yySkip();
- lip->yySkip();
- lip->yySkip();
+ lip->yySkipn(3);
/*
The special comment format is very strict:
- '/' '*' '!', followed by exactly
+ '/' '*' '!', followed by an optional 'M' and exactly
1 digit (major), 2 digits (minor), then 2 digits (dot).
32302 -> 3.23.02
50032 -> 5.0.32
50114 -> 5.1.14
*/
- char version_str[6];
- version_str[0]= lip->yyPeekn(0);
- version_str[1]= lip->yyPeekn(1);
- version_str[2]= lip->yyPeekn(2);
- version_str[3]= lip->yyPeekn(3);
- version_str[4]= lip->yyPeekn(4);
- version_str[5]= 0;
- if ( my_isdigit(cs, version_str[0])
- && my_isdigit(cs, version_str[1])
- && my_isdigit(cs, version_str[2])
- && my_isdigit(cs, version_str[3])
- && my_isdigit(cs, version_str[4])
+ if ( my_isdigit(cs, lip->yyPeekn(0))
+ && my_isdigit(cs, lip->yyPeekn(1))
+ && my_isdigit(cs, lip->yyPeekn(2))
+ && my_isdigit(cs, lip->yyPeekn(3))
+ && my_isdigit(cs, lip->yyPeekn(4))
)
{
ulong version;
- version=strtol(version_str, NULL, 10);
+ char *end_ptr= (char*) lip->get_ptr()+5;
+ int error;
+ version= (ulong) my_strtoll10(lip->get_ptr(), &end_ptr, &error);
if (version <= MYSQL_VERSION_ID)
{
@@ -1571,7 +1575,7 @@ void st_select_lex_node::init_query()
options= 0;
sql_cache= SQL_CACHE_UNSPECIFIED;
linkage= UNSPECIFIED_TYPE;
- no_error= no_table_names_allowed= 0;
+ no_table_names_allowed= 0;
uncacheable= 0;
}
@@ -1597,6 +1601,7 @@ void st_select_lex_unit::init_query()
describe= 0;
found_rows_for_union= 0;
insert_table_with_stored_vcol= 0;
+ derived= 0;
}
void st_select_lex::init_query()
@@ -1605,7 +1610,9 @@ void st_select_lex::init_query()
table_list.empty();
top_join_list.empty();
join_list= &top_join_list;
- embedding= leaf_tables= 0;
+ embedding= 0;
+ leaf_tables_prep.empty();
+ leaf_tables.empty();
item_list.empty();
join= 0;
having= prep_having= where= prep_where= 0;
@@ -1640,6 +1647,9 @@ void st_select_lex::init_query()
nest_level= 0;
link_next= 0;
lock_option= TL_READ_DEFAULT;
+ is_prep_leaf_list_saved= FALSE;
+
+ bzero((char*) expr_cache_may_be_used, sizeof(expr_cache_may_be_used));
m_non_agg_field_used= false;
m_agg_func_used= false;
}
@@ -1647,6 +1657,8 @@ void st_select_lex::init_query()
void st_select_lex::init_select()
{
st_select_lex_node::init_select();
+ sj_nests.empty();
+ sj_subselects.empty();
group_list.empty();
if (group_list_ptrs)
group_list_ptrs->clear();
@@ -1674,6 +1686,8 @@ void st_select_lex::init_select()
non_agg_fields.empty();
cond_value= having_value= Item::COND_UNDEF;
inner_refs_list.empty();
+ insert_tables= 0;
+ merged_into= 0;
m_non_agg_field_used= false;
m_agg_func_used= false;
}
@@ -1693,6 +1707,31 @@ void st_select_lex_node::include_down(st_select_lex_node *upper)
slave= 0;
}
+
+void st_select_lex_node::add_slave(st_select_lex_node *slave_arg)
+{
+ for (; slave; slave= slave->next)
+ if (slave == slave_arg)
+ return;
+
+ if (slave)
+ {
+ st_select_lex_node *slave_arg_slave= slave_arg->slave;
+ /* Insert in the front of list of slaves if any. */
+ slave_arg->include_neighbour(slave);
+ /* include_neighbour() sets slave_arg->slave=0, restore it. */
+ slave_arg->slave= slave_arg_slave;
+ /* Count on include_neighbour() setting the master. */
+ DBUG_ASSERT(slave_arg->master == this);
+ }
+ else
+ {
+ slave= slave_arg;
+ slave_arg->master= this;
+ }
+}
+
+
/*
include on level down (but do not link)
@@ -1744,17 +1783,29 @@ void st_select_lex_node::fast_exclude()
}
+
+/*
+ Exclude a node from the tree lex structure, but leave it in the global
+ list of nodes.
+*/
+
+void st_select_lex_node::exclude_from_tree()
+{
+ if ((*prev= next))
+ next->prev= prev;
+}
+
+
/*
- excluding select_lex structure (except first (first select can't be
+ Exclude select_lex structure (except first (first select can't be
deleted, because it is most upper select))
*/
void st_select_lex_node::exclude()
{
- //exclude from global list
+ /* exclude from global list */
fast_exclude();
- //exclude from other structures
- if ((*prev= next))
- next->prev= prev;
+ /* exclude from other structures */
+ exclude_from_tree();
/*
We do not need following statements, because prev pointer of first
list element point to master->slave
@@ -1853,9 +1904,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);
@@ -1866,28 +1916,31 @@ void st_select_lex::mark_as_dependent(st_select_lex *last, Item *dependency)
SELECT_LEX *s= this;
do
{
- if (!(s->uncacheable & UNCACHEABLE_DEPENDENT))
+ if (!(s->uncacheable & UNCACHEABLE_DEPENDENT_GENERATED))
{
// Select is dependent of outer select
s->uncacheable= (s->uncacheable & ~UNCACHEABLE_UNITED) |
- UNCACHEABLE_DEPENDENT;
+ UNCACHEABLE_DEPENDENT_GENERATED;
SELECT_LEX_UNIT *munit= s->master_unit();
munit->uncacheable= (munit->uncacheable & ~UNCACHEABLE_UNITED) |
- UNCACHEABLE_DEPENDENT;
+ UNCACHEABLE_DEPENDENT_GENERATED;
for (SELECT_LEX *sl= munit->first_select(); sl ; sl= sl->next_select())
{
if (sl != s &&
- !(sl->uncacheable & (UNCACHEABLE_DEPENDENT | UNCACHEABLE_UNITED)))
+ !(sl->uncacheable & (UNCACHEABLE_DEPENDENT_GENERATED |
+ UNCACHEABLE_UNITED)))
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; }
@@ -2012,23 +2065,25 @@ ulong st_select_lex::get_table_join_options()
bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
{
+ DBUG_ENTER("st_select_lex::setup_ref_array");
+
if (ref_pointer_array)
- return 0;
+ DBUG_RETURN(0);
// find_order_in_list() may need some extra space, so multiply by two.
order_group_num*= 2;
/*
- We have to create array in prepared statement memory if it is
+ We have to create array in prepared statement memory if it is a
prepared statement
*/
- Query_arena *arena= thd->stmt_arena;
- return (ref_pointer_array=
- (Item **)arena->alloc(sizeof(Item*) * (n_child_sum_items +
- item_list.elements +
- select_n_having_items +
- select_n_where_fields +
- order_group_num)*5)) == 0;
+ ref_pointer_array=
+ (Item **)thd->stmt_arena->alloc(sizeof(Item*) * (n_child_sum_items +
+ item_list.elements +
+ select_n_having_items +
+ select_n_where_fields +
+ order_group_num)*5);
+ DBUG_RETURN(ref_pointer_array == 0);
}
@@ -2073,9 +2128,27 @@ void st_select_lex::print_order(String *str,
{
if (order->counter_used)
{
- char buffer[20];
- size_t length= my_snprintf(buffer, 20, "%d", order->counter);
- str->append(buffer, (uint) length);
+ if (query_type != QT_VIEW_INTERNAL)
+ {
+ char buffer[20];
+ size_t length= my_snprintf(buffer, 20, "%d", order->counter);
+ str->append(buffer, (uint) length);
+ }
+ else
+ {
+ /* replace numeric reference with expression */
+ if (order->item[0]->type() == Item::INT_ITEM &&
+ order->item[0]->basic_const_item())
+ {
+ char buffer[20];
+ size_t length= my_snprintf(buffer, 20, "%d", order->counter);
+ str->append(buffer, (uint) length);
+ /* make it expression instead of integer constant */
+ str->append(STRING_WITH_LEN("+0"));
+ }
+ else
+ (*order->item)->print(str, query_type);
+ }
}
else
(*order->item)->print(str, query_type);
@@ -2093,16 +2166,17 @@ 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)
+ {
+ return;
+ }
}
-
if (explicit_limit)
{
str->append(STRING_WITH_LEN(" limit "));
@@ -2115,6 +2189,7 @@ void st_select_lex::print_limit(THD *thd,
}
}
+
/**
@brief Restore the LEX and THD in case of a parse error.
@@ -2816,6 +2891,7 @@ void st_lex::cleanup_after_one_table_open()
if (all_selects_list != &select_lex)
{
derived_tables= 0;
+ select_lex.exclude_from_table_unique_test= false;
/* cleunup underlying units (units of VIEW) */
for (SELECT_LEX_UNIT *un= select_lex.first_inner_unit();
un;
@@ -2910,7 +2986,11 @@ static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl)
thd->check_and_register_item_tree(&tbl->prep_on_expr, &tbl->on_expr);
tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
}
- fix_prepare_info_in_table_list(thd, tbl->merge_underlying_list);
+ if (tbl->is_view_or_derived() && tbl->is_merged_derived())
+ {
+ SELECT_LEX *sel= tbl->get_single_select();
+ fix_prepare_info_in_table_list(thd, sel->get_table_list());
+ }
}
}
@@ -3040,6 +3120,659 @@ bool st_select_lex::add_index_hint (THD *thd, char *str, uint length)
str, length));
}
+
+bool st_select_lex::optimize_unflattened_subqueries()
+{
+ for (SELECT_LEX_UNIT *un= first_inner_unit(); un; un= un->next_unit())
+ {
+ Item_subselect *subquery_predicate= un->item;
+
+ if (subquery_predicate)
+ {
+ if (subquery_predicate->substype() == Item_subselect::IN_SUBS)
+ {
+ Item_in_subselect *in_subs=(Item_in_subselect*)subquery_predicate;
+ if (in_subs->is_jtbm_merged)
+ continue;
+ }
+
+ bool empty_union_result= true;
+ /*
+ If the subquery is a UNION, optimize all the subqueries in the UNION. If
+ there is no UNION, then the loop will execute once for the subquery.
+ */
+ for (SELECT_LEX *sl= un->first_select(); sl; sl= sl->next_select())
+ {
+ JOIN *inner_join= sl->join;
+ if (!inner_join)
+ continue;
+ SELECT_LEX *save_select= un->thd->lex->current_select;
+ ulonglong save_options;
+ int res;
+ /* We need only 1 row to determine existence */
+ un->set_limit(un->global_parameters);
+ un->thd->lex->current_select= sl;
+ save_options= inner_join->select_options;
+ if (options & SELECT_DESCRIBE)
+ {
+ /* Optimize the subquery in the context of EXPLAIN. */
+ sl->set_explain_type();
+ sl->options|= SELECT_DESCRIBE;
+ inner_join->select_options|= SELECT_DESCRIBE;
+ }
+ res= inner_join->optimize();
+ inner_join->select_options= save_options;
+ un->thd->lex->current_select= save_select;
+ if (empty_union_result)
+ {
+ /*
+ If at least one subquery in a union is non-empty, the UNION result
+ is non-empty. If there is no UNION, the only subquery is non-empy.
+ */
+ empty_union_result= inner_join->empty_result();
+ }
+ if (res)
+ return TRUE;
+ }
+ if (empty_union_result)
+ subquery_predicate->no_rows_in_result();
+ }
+ }
+ return FALSE;
+}
+
+
+
+/**
+ @brief Process all derived tables/views of the SELECT.
+
+ @param lex LEX of this thread
+ @param phase phases to run derived tables/views through
+
+ @details
+ This function runs specified 'phases' on all tables from the
+ table_list of this select.
+
+ @return FALSE ok.
+ @return TRUE an error occur.
+*/
+
+bool st_select_lex::handle_derived(struct st_lex *lex, uint phases)
+{
+ for (TABLE_LIST *cursor= (TABLE_LIST*) table_list.first;
+ cursor;
+ cursor= cursor->next_local)
+ {
+ if (cursor->is_view_or_derived() && cursor->handle_derived(lex, phases))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/**
+ @brief
+ Returns first unoccupied table map and table number
+
+ @param map [out] return found map
+ @param tablenr [out] return found tablenr
+
+ @details
+ Returns first unoccupied table map and table number in this select.
+ Map and table are returned in *'map' and *'tablenr' accordingly.
+
+ @retrun TRUE no free table map/table number
+ @return FALSE found free table map/table number
+*/
+
+bool st_select_lex::get_free_table_map(table_map *map, uint *tablenr)
+{
+ *map= 0;
+ *tablenr= 0;
+ TABLE_LIST *tl;
+ List_iterator<TABLE_LIST> ti(leaf_tables);
+ while ((tl= ti++))
+ {
+ if (tl->table->map > *map)
+ *map= tl->table->map;
+ if (tl->table->tablenr > *tablenr)
+ *tablenr= tl->table->tablenr;
+ }
+ (*map)<<= 1;
+ (*tablenr)++;
+ if (*tablenr >= MAX_TABLES)
+ return TRUE;
+ return FALSE;
+}
+
+
+/**
+ @brief
+ Append given table to the leaf_tables list.
+
+ @param link Offset to which list in table structure to use
+ @param table Table to append
+
+ @details
+ Append given 'table' to the leaf_tables list using the 'link' offset.
+ If the 'table' is linked with other tables through next_leaf/next_local
+ chains then whole list will be appended.
+*/
+
+void st_select_lex::append_table_to_list(TABLE_LIST *TABLE_LIST::*link,
+ TABLE_LIST *table)
+{
+ TABLE_LIST *tl;
+ for (tl= leaf_tables.head(); tl->*link; tl= tl->*link) ;
+ tl->*link= table;
+}
+
+
+/*
+ @brief
+ Replace given table from the leaf_tables list for a list of tables
+
+ @param table Table to replace
+ @param list List to substititute the table for
+
+ @details
+ Replace 'table' from the leaf_tables list for a list of tables 'tbl_list'.
+*/
+
+void st_select_lex::replace_leaf_table(TABLE_LIST *table, List<TABLE_LIST> &tbl_list)
+{
+ TABLE_LIST *tl;
+ List_iterator<TABLE_LIST> ti(leaf_tables);
+ while ((tl= ti++))
+ {
+ if (tl == table)
+ {
+ ti.replace(tbl_list);
+ break;
+ }
+ }
+}
+
+
+/**
+ @brief
+ Assigns new table maps to tables in the leaf_tables list
+
+ @param derived Derived table to take initial table map from
+ @param map table map to begin with
+ @param tablenr table number to begin with
+ @param parent_lex new parent select_lex
+
+ @details
+ Assign new table maps/table numbers to all tables in the leaf_tables list.
+ 'map'/'tablenr' are used for the first table and shifted to left/
+ increased for each consequent table in the leaf_tables list.
+ If the 'derived' table is given then it's table map/number is used for the
+ first table in the list and 'map'/'tablenr' are used for the second and
+ all consequent tables.
+ The 'parent_lex' is set as the new parent select_lex for all tables in the
+ list.
+*/
+
+void st_select_lex::remap_tables(TABLE_LIST *derived, table_map map,
+ uint tablenr, SELECT_LEX *parent_lex)
+{
+ bool first_table= TRUE;
+ TABLE_LIST *tl;
+ table_map first_map;
+ uint first_tablenr;
+
+ if (derived && derived->table)
+ {
+ first_map= derived->table->map;
+ first_tablenr= derived->table->tablenr;
+ }
+ else
+ {
+ first_map= map;
+ map<<= 1;
+ first_tablenr= tablenr++;
+ }
+ /*
+ Assign table bit/table number.
+ To the first table of the subselect the table bit/tablenr of the
+ derived table is assigned. The rest of tables are getting bits
+ sequentially, starting from the provided table map/tablenr.
+ */
+ List_iterator<TABLE_LIST> ti(leaf_tables);
+ while ((tl= ti++))
+ {
+ if (first_table)
+ {
+ first_table= FALSE;
+ tl->table->set_table_map(first_map, first_tablenr);
+ }
+ else
+ {
+ tl->table->set_table_map(map, tablenr);
+ tablenr++;
+ map<<= 1;
+ }
+ SELECT_LEX *old_sl= tl->select_lex;
+ tl->select_lex= parent_lex;
+ for(TABLE_LIST *emb= tl->embedding;
+ emb && emb->select_lex == old_sl;
+ emb= emb->embedding)
+ emb->select_lex= parent_lex;
+ }
+}
+
+/**
+ @brief
+ Merge a subquery into this select.
+
+ @param derived derived table of the subquery to be merged
+ @param subq_select select_lex of the subquery
+ @param map table map for assigning to merged tables from subquery
+ @param table_no table number for assigning to merged tables from subquery
+
+ @details
+ This function merges a subquery into its parent select. In short the
+ merge operation appends the subquery FROM table list to the parent's
+ FROM table list. In more details:
+ .) the top_join_list of the subquery is wrapped into a join_nest
+ and attached to 'derived'
+ .) subquery's leaf_tables list is merged with the leaf_tables
+ list of this select_lex
+ .) the table maps and table numbers of the tables merged from
+ the subquery are adjusted to reflect their new binding to
+ this select
+
+ @return TRUE an error occur
+ @return FALSE ok
+*/
+
+bool SELECT_LEX::merge_subquery(THD *thd, TABLE_LIST *derived,
+ SELECT_LEX *subq_select,
+ uint table_no, table_map map)
+{
+ derived->wrap_into_nested_join(subq_select->top_join_list);
+
+ ftfunc_list->concat(subq_select->ftfunc_list);
+ if (join ||
+ thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
+ thd->lex->sql_command == SQLCOM_DELETE_MULTI)
+ {
+ List_iterator_fast<Item_in_subselect> li(subq_select->sj_subselects);
+ Item_in_subselect *in_subq;
+ while ((in_subq= li++))
+ {
+ sj_subselects.push_back(in_subq);
+ if (in_subq->emb_on_expr_nest == NO_JOIN_NEST)
+ in_subq->emb_on_expr_nest= derived;
+ }
+ }
+
+ /* Walk through child's tables and adjust table map, tablenr,
+ * parent_lex */
+ subq_select->remap_tables(derived, map, table_no, this);
+ subq_select->merged_into= this;
+
+ replace_leaf_table(derived, subq_select->leaf_tables);
+
+ return FALSE;
+}
+
+
+/**
+ @brief
+ Mark tables from the leaf_tables list as belong to a derived table.
+
+ @param derived tables will be marked as belonging to this derived
+
+ @details
+ Run through the leaf_list and mark all tables as belonging to the 'derived'.
+*/
+
+void SELECT_LEX::mark_as_belong_to_derived(TABLE_LIST *derived)
+{
+ /* Mark tables as belonging to this DT */
+ TABLE_LIST *tl;
+ List_iterator<TABLE_LIST> ti(leaf_tables);
+ while ((tl= ti++))
+ {
+ tl->skip_temporary= 1;
+ tl->belong_to_derived= derived;
+ }
+}
+
+
+/**
+ @brief
+ Update used_tables cache for this select
+
+ @details
+ This function updates used_tables cache of ON expressions of all tables
+ in the leaf_tables list and of the conds expression (if any).
+*/
+
+void SELECT_LEX::update_used_tables()
+{
+ TABLE_LIST *tl;
+ List_iterator<TABLE_LIST> ti(leaf_tables);
+
+ while ((tl= ti++))
+ {
+ if (tl->table && !tl->is_view_or_derived())
+ {
+ TABLE_LIST *embedding= tl->embedding;
+ for (embedding= tl->embedding; embedding; embedding=embedding->embedding)
+ {
+ if (embedding->is_view_or_derived())
+ {
+ DBUG_ASSERT(embedding->is_merged_derived());
+ TABLE *tab= tl->table;
+ tab->covering_keys= tab->s->keys_for_keyread;
+ tab->covering_keys.intersect(tab->keys_in_use_for_query);
+ tab->merge_keys.clear_all();
+ bitmap_clear_all(tab->read_set);
+ bitmap_clear_all(tab->vcol_set);
+ break;
+ }
+ }
+ }
+ }
+
+ ti.rewind();
+ while ((tl= ti++))
+ {
+ TABLE_LIST *embedding= tl;
+ do
+ {
+ bool maybe_null;
+ if ((maybe_null= test(embedding->outer_join)))
+ {
+ tl->table->maybe_null= maybe_null;
+ break;
+ }
+ }
+ while ((embedding= embedding->embedding));
+ if (tl->on_expr)
+ {
+ tl->on_expr->update_used_tables();
+ tl->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
+ }
+ embedding= tl->embedding;
+ while (embedding)
+ {
+ if (embedding->on_expr &&
+ embedding->nested_join->join_list.head() == tl)
+ {
+ embedding->on_expr->update_used_tables();
+ embedding->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
+ }
+ tl= embedding;
+ embedding= tl->embedding;
+ }
+ }
+
+ if (join->conds)
+ {
+ join->conds->update_used_tables();
+ join->conds->walk(&Item::eval_not_null_tables, 0, NULL);
+ }
+ if (join->having)
+ {
+ join->having->update_used_tables();
+ }
+
+ Item *item;
+ List_iterator_fast<Item> it(join->fields_list);
+ while ((item= it++))
+ {
+ item->update_used_tables();
+ }
+ Item_outer_ref *ref;
+ List_iterator_fast<Item_outer_ref> ref_it(inner_refs_list);
+ while ((ref= ref_it++))
+ {
+ item= ref->outer_ref;
+ item->update_used_tables();
+ }
+ for (ORDER *order= group_list.first; order; order= order->next)
+ (*order->item)->update_used_tables();
+ if (!master_unit()->is_union())
+ {
+ for (ORDER *order= order_list.first; order; order= order->next)
+ (*order->item)->update_used_tables();
+ }
+ join->result->update_used_tables();
+}
+
+
+/**
+ Set the EXPLAIN type for this subquery.
+*/
+
+void st_select_lex::set_explain_type()
+{
+ bool is_primary= FALSE;
+ if (next_select())
+ is_primary= TRUE;
+
+ if (!is_primary && first_inner_unit())
+ {
+ /*
+ If there is at least one materialized derived|view then it's a PRIMARY select.
+ Otherwise, all derived tables/views were merged and this select is a SIMPLE one.
+ */
+ for (SELECT_LEX_UNIT *un= first_inner_unit(); un; un= un->next_unit())
+ {
+ if ((!un->derived || un->derived->is_materialized_derived()))
+ {
+ is_primary= TRUE;
+ break;
+ }
+ }
+ }
+
+ SELECT_LEX *first= master_unit()->first_select();
+ /* drop UNCACHEABLE_EXPLAIN, because it is for internal usage only */
+ uint8 is_uncacheable= (uncacheable & ~UNCACHEABLE_EXPLAIN);
+
+ bool using_materialization= FALSE;
+ Item_subselect *parent_item;
+ if ((parent_item= master_unit()->item) &&
+ parent_item->substype() == Item_subselect::IN_SUBS)
+ {
+ Item_in_subselect *in_subs= (Item_in_subselect*)parent_item;
+ /*
+ Surprisingly, in_subs->is_set_strategy() can return FALSE here,
+ even for the last invocation of this function for the select.
+ */
+ if (in_subs->test_strategy(SUBS_MATERIALIZATION))
+ using_materialization= TRUE;
+ }
+
+ if (&master_unit()->thd->lex->select_lex == this)
+ {
+ type= is_primary ? "PRIMARY" : "SIMPLE";
+ }
+ else
+ {
+ if (this == first)
+ {
+ /* If we're a direct child of a UNION, we're the first sibling there */
+ if (linkage == DERIVED_TABLE_TYPE)
+ type= "DERIVED";
+ else if (using_materialization)
+ type= "MATERIALIZED";
+ else
+ {
+ if (is_uncacheable & UNCACHEABLE_DEPENDENT)
+ type= "DEPENDENT SUBQUERY";
+ else
+ {
+ type= is_uncacheable? "UNCACHEABLE SUBQUERY" :
+ "SUBQUERY";
+ }
+ }
+ }
+ else
+ {
+ /* This a non-first sibling in UNION */
+ if (is_uncacheable & UNCACHEABLE_DEPENDENT)
+ type= "DEPENDENT UNION";
+ else if (using_materialization)
+ type= "MATERIALIZED UNION";
+ else
+ {
+ type= is_uncacheable ? "UNCACHEABLE UNION": "UNION";
+ }
+ }
+ }
+ options|= SELECT_DESCRIBE;
+}
+
+
+/**
+ @brief
+ Increase estimated number of records for a derived table/view
+
+ @param records number of records to increase estimate by
+
+ @details
+ This function increases estimated number of records by the 'records'
+ for the derived table to which this select belongs to.
+*/
+
+void SELECT_LEX::increase_derived_records(ha_rows records)
+{
+ SELECT_LEX_UNIT *unit= master_unit();
+ DBUG_ASSERT(unit->derived);
+
+ select_union *result= (select_union*)unit->result;
+ result->records+= records;
+}
+
+
+/**
+ @brief
+ Mark select's derived table as a const one.
+
+ @param empty Whether select has an empty result set
+
+ @details
+ Mark derived table/view of this select as a constant one (to
+ materialize it at the optimization phase) unless this select belongs to a
+ union. Estimated number of rows is incremented if this select has non empty
+ result set.
+*/
+
+void SELECT_LEX::mark_const_derived(bool empty)
+{
+ TABLE_LIST *derived= master_unit()->derived;
+ if (!join->thd->lex->describe && derived)
+ {
+ if (!empty)
+ increase_derived_records(1);
+ if (!master_unit()->is_union() && !derived->is_merged_derived())
+ derived->fill_me= TRUE;
+ }
+}
+
+
+bool st_select_lex::save_leaf_tables(THD *thd)
+{
+ Query_arena *arena= thd->stmt_arena, backup;
+ if (arena->is_conventional())
+ arena= 0;
+ else
+ thd->set_n_backup_active_arena(arena, &backup);
+
+ List_iterator_fast<TABLE_LIST> li(leaf_tables);
+ TABLE_LIST *table;
+ while ((table= li++))
+ {
+ if (leaf_tables_exec.push_back(table))
+ return 1;
+ table->tablenr_exec= table->get_tablenr();
+ table->map_exec= table->get_map();
+ if (join && (join->select_options & SELECT_DESCRIBE))
+ table->maybe_null_exec= 0;
+ else
+ table->maybe_null_exec= table->table? table->table->maybe_null: 0;
+ }
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+
+ return 0;
+}
+
+
+bool st_select_lex::save_prep_leaf_tables(THD *thd)
+{
+ if (!thd->save_prep_leaf_list)
+ return 0;
+
+ Query_arena *arena= thd->stmt_arena, backup;
+ if (arena->is_conventional())
+ arena= 0;
+ else
+ thd->set_n_backup_active_arena(arena, &backup);
+
+ List_iterator_fast<TABLE_LIST> li(leaf_tables);
+ TABLE_LIST *table;
+ while ((table= li++))
+ {
+ if (leaf_tables_prep.push_back(table))
+ return 1;
+ }
+ thd->lex->select_lex.is_prep_leaf_list_saved= TRUE;
+ thd->save_prep_leaf_list= FALSE;
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+
+ return 0;
+}
+
+
+/*
+ Return true if this select_lex has been converted into a semi-join nest
+ within 'ancestor'.
+
+ We need a loop to check this because there could be several nested
+ subselects, like
+
+ SELECT ... FROM grand_parent
+ WHERE expr1 IN (SELECT ... FROM parent
+ WHERE expr2 IN ( SELECT ... FROM child)
+
+ which were converted into:
+
+ SELECT ...
+ FROM grand_parent SEMI_JOIN (parent JOIN child)
+ WHERE
+ expr1 AND expr2
+
+ In this case, both parent and child selects were merged into the parent.
+*/
+
+bool st_select_lex::is_merged_child_of(st_select_lex *ancestor)
+{
+ bool all_merged= TRUE;
+ for (SELECT_LEX *sl= this; sl && sl!=ancestor;
+ sl=sl->outer_select())
+ {
+ Item *subs= sl->master_unit()->item;
+ if (subs && subs->type() == Item::SUBSELECT_ITEM &&
+ ((Item_subselect*)subs)->substype() == Item_subselect::IN_SUBS &&
+ ((Item_in_subselect*)subs)->test_strategy(SUBS_SEMI_JOIN))
+ {
+ continue;
+ }
+ all_merged= FALSE;
+ break;
+ }
+ return all_merged;
+}
+
+
/**
A routine used by the parser to decide whether we are specifying a full
partitioning or if only partitions to add or to split.
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 10fcccc7a2d..a3240d3bcab 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -425,7 +425,8 @@ public:
/*
result of this query can't be cached, bit field, can be :
- UNCACHEABLE_DEPENDENT
+ UNCACHEABLE_DEPENDENT_GENERATED
+ UNCACHEABLE_DEPENDENT_INJECTED
UNCACHEABLE_RAND
UNCACHEABLE_SIDEEFFECT
UNCACHEABLE_EXPLAIN
@@ -434,7 +435,6 @@ public:
uint8 uncacheable;
enum sub_select_type linkage;
bool no_table_names_allowed; /* used for global order by */
- bool no_error; /* suppress error message (convert it to warnings) */
static void *operator new(size_t size) throw ()
{
@@ -450,10 +450,12 @@ public:
virtual void init_query();
virtual void init_select();
void include_down(st_select_lex_node *upper);
+ void add_slave(st_select_lex_node *slave_arg);
void include_neighbour(st_select_lex_node *before);
void include_standalone(st_select_lex_node *sel, st_select_lex_node **ref);
void include_global(st_select_lex_node **plink);
void exclude();
+ void exclude_from_tree();
virtual st_select_lex_unit* master_unit()= 0;
virtual st_select_lex* outer_select()= 0;
@@ -477,6 +479,11 @@ public:
friend bool mysql_new_select(struct st_lex *lex, bool move_down);
friend bool mysql_make_view(THD *thd, File_parser *parser,
TABLE_LIST *table, uint flags);
+ friend bool mysql_derived_prepare(THD *thd, st_lex *lex,
+ TABLE_LIST *orig_table_list);
+ friend bool mysql_derived_merge(THD *thd, st_lex *lex,
+ TABLE_LIST *orig_table_list);
+ friend bool TABLE_LIST::init_derived(THD *thd, bool init_view);
private:
void fast_exclude();
};
@@ -495,13 +502,12 @@ class st_select_lex_unit: public st_select_lex_node {
protected:
TABLE_LIST result_table_list;
select_union *union_result;
- TABLE *table; /* temporary table using for appending UNION results */
-
- select_result *result;
ulonglong found_rows_for_union;
bool saved_error;
public:
+ TABLE *table; /* temporary table using for appending UNION results */
+ select_result *result;
bool prepared, // prepare phase already performed for UNION (unit)
optimized, // optimize phase already performed for UNION (unit)
executed, // already executed
@@ -528,6 +534,11 @@ public:
ha_rows select_limit_cnt, offset_limit_cnt;
/* not NULL if unit used in subselect, point to subselect item */
Item_subselect *item;
+ /*
+ TABLE_LIST representing this union in the embedding select. Used for
+ derived tables/views handling.
+ */
+ TABLE_LIST *derived;
/* thread handler */
THD *thd;
/*
@@ -564,6 +575,7 @@ public:
/* UNION methods */
bool prepare(THD *thd, select_result *result, ulong additional_options);
+ bool optimize();
bool exec();
bool cleanup();
inline void unclean() { cleaned= 0; }
@@ -574,11 +586,14 @@ 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 ();
+ void set_unique_exclude();
+
friend void lex_start(THD *thd);
friend int subselect_union_engine::exec();
@@ -628,12 +643,30 @@ 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
by TABLE_LIST::next_leaf, so leaf_tables points to the left-most leaf.
+
+ List of all base tables local to a subquery including all view
+ tables. Unlike 'next_local', this in this list views are *not*
+ leaves. Created in setup_tables() -> make_leaves_list().
+ */
+ /*
+ Subqueries that will need to be converted to semi-join nests, including
+ those converted to jtbm nests. The list is emptied when conversion is done.
*/
- TABLE_LIST *leaf_tables;
+ List<Item_in_subselect> sj_subselects;
+
+ List<TABLE_LIST> leaf_tables;
+ List<TABLE_LIST> leaf_tables_exec;
+ List<TABLE_LIST> leaf_tables_prep;
+ bool is_prep_leaf_list_saved;
+ uint insert_tables;
+ st_select_lex *merged_into; /* select which this select is merged into */
+ /* (not 0 only for views/derived tables) */
+
const char *type; /* type of select for EXPLAIN */
SQL_I_List<ORDER> order_list; /* ORDER clause */
@@ -667,6 +700,13 @@ public:
ulong table_join_options;
uint in_sum_expr;
uint select_number; /* number of select (used for EXPLAIN) */
+
+ /*
+ nest_levels are local to the query or VIEW,
+ and that view merge procedure does not re-calculate them.
+ So we also have to remember unit against which we count levels.
+ */
+ SELECT_LEX_UNIT *nest_level_base;
int nest_level; /* nesting level of select */
Item_sum *inner_sum_func_list; /* list of sum func in nested selects */
uint with_wild; /* item list contain '*' */
@@ -683,6 +723,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
*/
@@ -761,7 +806,7 @@ 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);
bool set_braces(bool value);
bool inc_in_sum_expr();
@@ -846,6 +891,38 @@ public:
}
void clear_index_hints(void) { index_hints= NULL; }
+ bool is_part_of_union() { return master_unit()->is_union(); }
+ /*
+ Optimize all subqueries that have not been flattened into semi-joins.
+ This functionality is a method of SELECT_LEX instead of JOIN because
+ some SQL statements as DELETE do not have a corresponding JOIN object.
+ */
+ bool optimize_unflattened_subqueries();
+ /* Set the EXPLAIN type for this subquery. */
+ void set_explain_type();
+ bool handle_derived(struct st_lex *lex, uint phases);
+ void append_table_to_list(TABLE_LIST *TABLE_LIST::*link, TABLE_LIST *table);
+ bool get_free_table_map(table_map *map, uint *tablenr);
+ void replace_leaf_table(TABLE_LIST *table, List<TABLE_LIST> &tbl_list);
+ void remap_tables(TABLE_LIST *derived, table_map map,
+ uint tablenr, st_select_lex *parent_lex);
+ bool merge_subquery(THD *thd, TABLE_LIST *derived, st_select_lex *subq_lex,
+ uint tablenr, table_map map);
+ inline bool is_mergeable()
+ {
+ return (next_select() == 0 && group_list.elements == 0 &&
+ having == 0 && with_sum_func == 0 &&
+ table_list.elements >= 1 && !(options & SELECT_DISTINCT) &&
+ select_limit == 0);
+ }
+ void mark_as_belong_to_derived(TABLE_LIST *derived);
+ void increase_derived_records(ha_rows records);
+ void update_used_tables();
+ void mark_const_derived(bool empty);
+
+ bool save_leaf_tables(THD *thd);
+ bool save_prep_leaf_tables(THD *thd);
+ bool is_merged_child_of(st_select_lex *ancestor);
/*
For MODE_ONLY_FULL_GROUP_BY we need to maintain two flags:
@@ -1633,8 +1710,6 @@ typedef struct st_lex : public Query_tables_list
CHARSET_INFO *charset;
bool text_string_is_7bit;
- /* store original leaf_tables for INSERT SELECT and PS/SP */
- TABLE_LIST *leaf_tables_insert;
/** SELECT of CREATE VIEW statement */
LEX_STRING create_view_select;
@@ -1691,6 +1766,9 @@ typedef struct st_lex : public Query_tables_list
LEX_SERVER_OPTIONS server_options;
USER_RESOURCES mqh;
ulong type;
+ /* The following is used by KILL */
+ killed_state kill_signal;
+ killed_type kill_type;
/*
This variable is used in post-parse stage to declare that sum-functions,
or functions which have sense only if GROUP BY is present, are allowed.
@@ -1751,7 +1829,7 @@ typedef struct st_lex : public Query_tables_list
DERIVED_SUBQUERY and DERIVED_VIEW).
*/
uint8 derived_tables;
- uint8 create_view_algorithm;
+ uint16 create_view_algorithm;
uint8 create_view_check;
bool drop_if_exists, drop_temporary, local_file, one_shot_set;
bool autocommit;
@@ -1761,7 +1839,7 @@ typedef struct st_lex : public Query_tables_list
uint8 context_analysis_only;
bool safe_to_cache_query;
- bool subqueries, ignore;
+ bool subqueries, ignore, online;
st_parsing_options parsing_options;
Alter_info alter_info;
/* Prepared statements SQL syntax:*/
@@ -1899,6 +1977,7 @@ typedef struct st_lex : public Query_tables_list
{
return (context_analysis_only &
(CONTEXT_ANALYSIS_ONLY_PREPARE |
+ CONTEXT_ANALYSIS_ONLY_VCOL_EXPR |
CONTEXT_ANALYSIS_ONLY_VIEW));
}
@@ -1948,6 +2027,8 @@ typedef struct st_lex : public Query_tables_list
switch (sql_command) {
case SQLCOM_UPDATE:
case SQLCOM_UPDATE_MULTI:
+ case SQLCOM_DELETE:
+ case SQLCOM_DELETE_MULTI:
case SQLCOM_INSERT:
case SQLCOM_INSERT_SELECT:
case SQLCOM_REPLACE:
diff --git a/sql/sql_lifo_buffer.h b/sql/sql_lifo_buffer.h
new file mode 100644
index 00000000000..34f9624436d
--- /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)
+ {
+ size_t elem_size= size1 + size2;
+ size_t 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_list.h b/sql/sql_list.h
index 975a860b3f5..6ffed441f8d 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -153,6 +153,7 @@ struct list_node :public Sql_alloc
}
};
+typedef bool List_eq(void *a, void *b);
extern MYSQL_PLUGIN_IMPORT list_node end_of_list;
@@ -244,6 +245,11 @@ public:
{
if (!list->is_empty())
{
+ if (is_empty())
+ {
+ *this= *list;
+ return;
+ }
*last= list->first;
last= list->last;
elements+= list->elements;
@@ -258,25 +264,35 @@ public:
last= &first;
return tmp->info;
}
- inline void disjoin(base_list *list)
+
+ /*
+ Remove from this list elements that are contained in the passed list.
+ We assume that the passed list is a tail of this list (that is, the whole
+ list_node* elements are shared).
+ */
+ inline void disjoin(const base_list *list)
{
list_node **prev= &first;
list_node *node= first;
list_node *list_first= list->first;
elements=0;
- while (node && node != list_first)
+ while (node != &end_of_list && node != list_first)
{
prev= &node->next;
node= node->next;
elements++;
+ if (node == &end_of_list)
+ return;
}
- *prev= *last;
+ *prev= &end_of_list;
last= prev;
}
inline void prepand(base_list *list)
{
if (!list->is_empty())
{
+ if (is_empty())
+ last= list->last;
*list->last= first;
first= list->first;
elements+= list->elements;
@@ -297,10 +313,40 @@ public:
inline void **head_ref() { return first != &end_of_list ? &first->info : 0; }
inline bool is_empty() { return first == &end_of_list ; }
inline list_node *last_ref() { return &end_of_list; }
+ inline bool add_unique(void *info, List_eq *eq)
+ {
+ list_node *node= first;
+ for (;
+ node != &end_of_list && (!(*eq)(node->info, info));
+ node= node->next) ;
+ if (node == &end_of_list)
+ return push_back(info);
+ return 1;
+ }
friend class base_list_iterator;
friend class error_list;
friend class error_list_iterator;
+ /*
+ Debugging help: return N-th element in the list, or NULL if the list has
+ less than N elements.
+ */
+ inline void *nth_element(int n)
+ {
+ list_node *node= first;
+ void *data= NULL;
+ for (int i=0; i <= n; i++)
+ {
+ if (node == &end_of_list)
+ {
+ data= NULL;
+ break;
+ }
+ data= node->info;
+ node= node->next;
+ }
+ return data;
+ }
#ifdef LIST_EXTRA_DEBUG
/*
Check list invariants and print results into trace. Invariants are:
@@ -467,6 +513,8 @@ public:
inline void concat(List<T> *list) { base_list::concat(list); }
inline void disjoin(List<T> *list) { base_list::disjoin(list); }
inline void prepand(List<T> *list) { base_list::prepand(list); }
+ inline bool add_unique(T *a, bool (*eq)(T *a, T *b))
+ { return base_list::add_unique(a, (List_eq *)eq); }
void delete_elements(void)
{
list_node *element,*next;
@@ -477,6 +525,7 @@ public:
}
empty();
}
+ inline T *nth_element(int n) { return (T*)base_list::nth_element(n); }
};
@@ -519,36 +568,40 @@ public:
/*
- Exchange sort algorithm for List<T>.
+ Bubble sort algorithm for List<T>.
+ This sort function is supposed to be used only for very short list.
+ Currently it is used for the lists of Item_equal objects and
+ for some lists in the table elimination algorithms. In both
+ cases the sorted lists are very short.
*/
+
template <class T>
-inline void exchange_sort(List<T> *list_to_sort,
- int (*sort_func)(T *a, T *b, void *arg), void *arg)
+inline void bubble_sort(List<T> *list_to_sort,
+ int (*sort_func)(T *a, T *b, void *arg), void *arg)
{
bool swap;
+ T **ref1= 0;
+ T **ref2= 0;
List_iterator<T> it(*list_to_sort);
do
{
+ T **last_ref= ref1;
T *item1= it++;
- T **ref1= it.ref();
+ ref1= it.ref();
T *item2;
swap= FALSE;
- while ((item2= it++))
+ while ((item2= it++) && (ref2= it.ref()) != last_ref)
{
- T **ref2= it.ref();
if (sort_func(item1, item2, arg) < 0)
{
- T *item= *ref1;
- *ref1= *ref2;
- *ref2= item;
+ *ref1= item2;
+ *ref2= item1;
swap= TRUE;
}
else
- {
item1= item2;
- ref1= ref2;
- }
+ ref1= ref2;
}
it.rewind();
} while (swap);
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 8a7c422ede7..9eef9ece13f 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -66,6 +66,8 @@ public:
::end_io_cache(&cache);
need_end_io_cache = 0;
}
+ my_off_t file_length() { return cache.end_of_file; }
+ my_off_t position() { return my_b_tell(&cache); }
/*
Either this method, or we need to make cache public
@@ -131,7 +133,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
bool is_fifo=0;
#ifndef EMBEDDED_LIBRARY
LOAD_FILE_INFO lf_info;
- THD::killed_state killed_status;
+ killed_state killed_status;
#endif
char *db = table_list->db; // This is never null
/*
@@ -175,15 +177,18 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
+ if (mysql_handle_single_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) ||
+ mysql_handle_single_derived(thd->lex, table_list, DT_PREPARE))
+ DBUG_RETURN(TRUE);
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list,
table_list,
- &thd->lex->select_lex.leaf_tables, FALSE,
+ thd->lex->select_lex.leaf_tables, FALSE,
INSERT_ACL | UPDATE_ACL,
- INSERT_ACL | UPDATE_ACL))
+ INSERT_ACL | UPDATE_ACL, FALSE))
DBUG_RETURN(-1);
if (!table_list->table || // do not suport join view
- !table_list->updatable || // and derived tables
+ !table_list->single_table_updatable() || // and derived tables
check_key_in_view(thd, table_list))
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD");
@@ -416,9 +421,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
}
}
+ thd_proc_info(thd, "reading file");
if (!(error=test(read_info.error)))
{
-
table->next_number_field=table->found_next_number_field;
if (ignore ||
handle_duplicates == DUP_REPLACE)
@@ -436,6 +441,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
(MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES)));
+ thd_progress_init(thd, 2);
if (!field_term->length() && !enclosed->length())
error= read_fixed_length(thd, info, table_list, fields_vars,
set_fields, set_values, read_info,
@@ -444,6 +450,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
error= read_sep_field(thd, info, table_list, fields_vars,
set_fields, set_values, read_info,
*enclosed, skip_lines, ignore);
+
+ thd_proc_info(thd, "End bulk insert");
+ thd_progress_next_stage(thd);
if (!thd->prelocked_mode && table->file->ha_end_bulk_insert() && !error)
{
table->file->print_error(my_errno, MYF(0));
@@ -465,11 +474,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
DBUG_EXECUTE_IF("simulate_kill_bug27571",
{
error=1;
- thd->killed= THD::KILL_QUERY;
+ thd->killed= KILL_QUERY;
};);
#ifndef EMBEDDED_LIBRARY
- killed_status= (error == 0) ? THD::NOT_KILLED : thd->killed;
+ killed_status= (error == 0) ? NOT_KILLED : thd->killed;
#endif
/*
@@ -513,7 +522,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
/* If the file was not empty, wrote_create_file is true */
if (lf_info.wrote_create_file)
{
- int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, killed_status == NOT_KILLED);
/* since there is already an error, the possible error of
writing binary log will be ignored */
@@ -564,7 +573,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
read_info.end_io_cache();
if (lf_info.wrote_create_file)
{
- int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, killed_status == NOT_KILLED);
error= write_execute_load_query_log_event(thd, ex,
table_list->db, table_list->table_name,
handle_duplicates, ignore,
@@ -712,9 +721,16 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List_iterator_fast<Item> it(fields_vars);
Item_field *sql_field;
TABLE *table= table_list->table;
- bool err;
+ bool err, progress_reports;
+ ulonglong counter, time_to_report_progress;
DBUG_ENTER("read_fixed_length");
+ counter= 0;
+ time_to_report_progress= MY_HOW_OFTEN_TO_WRITE/10;
+ progress_reports= 1;
+ if ((thd->progress.max_counter= read_info.file_length()) == ~(my_off_t) 0)
+ progress_reports= 0;
+
while (!read_info.read_fixed_length())
{
if (thd->killed)
@@ -722,6 +738,16 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
thd->send_kill_message();
DBUG_RETURN(1);
}
+ if (progress_reports)
+ {
+ thd->progress.counter= read_info.position();
+ if (++counter >= time_to_report_progress)
+ {
+ time_to_report_progress+= MY_HOW_OFTEN_TO_WRITE/10;
+ thd_progress_report(thd, thd->progress.counter,
+ thd->progress.max_counter);
+ }
+ }
if (skip_lines)
{
/*
@@ -840,11 +866,18 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
Item *item;
TABLE *table= table_list->table;
uint enclosed_length;
- bool err;
+ bool err, progress_reports;
+ ulonglong counter, time_to_report_progress;
DBUG_ENTER("read_sep_field");
enclosed_length=enclosed.length();
+ counter= 0;
+ time_to_report_progress= MY_HOW_OFTEN_TO_WRITE/10;
+ progress_reports= 1;
+ if ((thd->progress.max_counter= read_info.file_length()) == ~(my_off_t) 0)
+ progress_reports= 0;
+
for (;;it.rewind())
{
if (thd->killed)
@@ -853,6 +886,16 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(1);
}
+ if (progress_reports)
+ {
+ thd->progress.counter= read_info.position();
+ if (++counter >= time_to_report_progress)
+ {
+ time_to_report_progress+= MY_HOW_OFTEN_TO_WRITE/10;
+ thd_progress_report(thd, thd->progress.counter,
+ thd->progress.max_counter);
+ }
+ }
restore_record(table, s->default_values);
while ((item= it++))
@@ -962,7 +1005,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_olap.cc b/sql/sql_olap.cc
index ddc287c1b6d..a7a847cf286 100644
--- a/sql/sql_olap.cc
+++ b/sql/sql_olap.cc
@@ -155,8 +155,7 @@ int handle_olaps(LEX *lex, SELECT_LEX *select_lex)
if (setup_tables(lex->thd, &select_lex->context, &select_lex->top_join_list,
- select_lex->table_list.first
- &select_lex->leaf_tables, FALSE) ||
+ FALSE, FALSE) ||
setup_fields(lex->thd, 0, select_lex->item_list, MARK_COLUMNS_READ,
&all_fields,1) ||
setup_fields(lex->thd, 0, item_list_copy, MARK_COLUMNS_READ,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 0c47b7a8bb3..1c16e055d30 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -31,6 +31,7 @@
#include "events.h"
#include "sql_trigger.h"
#include "debug_sync.h"
+#include "sql_handler.h"
#include <rpl_mi.h>
#ifdef WITH_ARIA_STORAGE_ENGINE
@@ -269,17 +270,17 @@ void init_update_queries(void)
bzero((uchar*) &sql_command_flags, sizeof(sql_command_flags));
sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
- sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA;
- sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
+ sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA | CF_REPORT_PROGRESS;
+ sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND | CF_REPORT_PROGRESS;
sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA;
- sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_REPORT_PROGRESS;
sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_BACKUP_TABLE]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_RESTORE_TABLE]= CF_CHANGES_DATA;
- sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA | CF_REPORT_PROGRESS;
sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
sql_command_flags[SQLCOM_DROP_VIEW]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_CREATE_EVENT]= CF_CHANGES_DATA;
@@ -372,9 +373,11 @@ void init_update_queries(void)
The following admin table operations are allowed
on log tables.
*/
- sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND;
- sql_command_flags[SQLCOM_OPTIMIZE]= CF_WRITE_LOGS_COMMAND;
- sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND;
+ sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND | CF_REPORT_PROGRESS;
+ sql_command_flags[SQLCOM_OPTIMIZE]= CF_WRITE_LOGS_COMMAND | CF_REPORT_PROGRESS;
+ sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND | CF_REPORT_PROGRESS;
+ sql_command_flags[SQLCOM_CHECK]= CF_REPORT_PROGRESS;
+ sql_command_flags[SQLCOM_CHECKSUM]= CF_REPORT_PROGRESS;
}
@@ -506,10 +509,10 @@ static void handle_bootstrap_impl(THD *thd)
query= (char *) thd->memdup_w_gap(buff, length + 1,
thd->db_length + 1 +
+ QUERY_CACHE_DB_LENGTH_SIZE +
QUERY_CACHE_FLAGS_SIZE);
- size_t db_len= 0;
- memcpy(query + length + 1, (char *) &db_len, sizeof(size_t));
thd->set_query(query, length);
+ int2store(query + length + 1, 0); // No db in bootstrap
DBUG_PRINT("query",("%-.4096s", thd->query()));
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
thd->profiling.start_new_query();
@@ -797,7 +800,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
my_error(thd->killed_errno(), MYF(0));
else if ((res == 0) && do_release)
{
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_CONNECTION;
if (global_system_variables.log_warnings > 3)
{
Security_context *sctx= &thd->main_security_ctx;
@@ -1024,6 +1027,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
DBUG_ENTER("dispatch_command");
DBUG_PRINT("info", ("command: %d", command));
+ DBUG_EXECUTE_IF("crash_dispatch_command_before",
+ { DBUG_PRINT("crash_dispatch_command_before", ("now"));
+ DBUG_ABORT(); });
+
thd->command=command;
/*
Commands which always take a long time are logged into
@@ -1033,18 +1040,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->query_plan_flags= QPLAN_INIT;
thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
thd->set_time();
- if (!thd->is_valid_time())
- {
- /*
- If the time has got past 2038 we need to shut this server down
- We do this by making sure every command is a shutdown and we
- have enough privileges to shut the server down
-
- TODO: remove this when we have full 64 bit my_time_t support
- */
- thd->security_ctx->master_access|= SHUTDOWN_ACL;
- command= COM_SHUTDOWN;
- }
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id= global_query_id;
@@ -1067,7 +1062,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
thread_running++;
- /* TODO: set thd->lex->sql_command to SQLCOM_END here */
VOID(pthread_mutex_unlock(&LOCK_thread_count));
/**
@@ -1238,6 +1232,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
@@ -1282,15 +1277,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
thd->set_query(beginning_of_next_stmt, length);
- VOID(pthread_mutex_lock(&LOCK_thread_count));
/*
Count each statement from the client.
*/
statistic_increment(thd->status_var.questions, &LOCK_status);
+ thd->set_time(); /* Reset the query start time for next query. */
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id= next_query_id();
- thd->set_time(); /* Reset the query start time. */
- /* TODO: set thd->lex->sql_command to SQLCOM_END here */
VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ /* TODO: set thd->lex->sql_command to SQLCOM_END here */
mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
}
@@ -1390,54 +1385,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:
{
@@ -1522,10 +1469,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
packet[0].
*/
enum mysql_enum_shutdown_level level;
- if (!thd->is_valid_time())
- level= SHUTDOWN_DEFAULT;
- else
- level= (enum mysql_enum_shutdown_level) (uchar) packet[0];
+ level= (enum mysql_enum_shutdown_level) (uchar) packet[0];
if (level == SHUTDOWN_DEFAULT)
level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
@@ -1617,7 +1561,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
status_var_increment(thd->status_var.com_stat[SQLCOM_KILL]);
ulong id=(ulong) uint4korr(packet);
- sql_kill(thd,id,false);
+ sql_kill(thd,id, KILL_CONNECTION_HARD);
break;
}
case COM_SET_OPTION:
@@ -1659,15 +1603,18 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
/* report error issued during command execution */
- if (thd->killed_errno())
+ if (thd->killed)
{
- if (! thd->main_da.is_set())
- thd->send_kill_message();
- }
- if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
- {
- thd->killed= THD::NOT_KILLED;
- thd->mysys_var->abort= 0;
+ if (thd->killed_errno())
+ {
+ if (! thd->main_da.is_set())
+ thd->send_kill_message();
+ }
+ if (thd->killed < KILL_CONNECTION)
+ {
+ thd->killed= NOT_KILLED;
+ thd->mysys_var->abort= 0;
+ }
}
/* If commit fails, we should be able to reset the OK status. */
@@ -1952,7 +1899,8 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length)
*/
if (! (query= (char*) thd->memdup_w_gap(packet,
packet_length,
- 1 + sizeof(size_t) + thd->db_length +
+ 1 + thd->db_length +
+ QUERY_CACHE_DB_LENGTH_SIZE +
QUERY_CACHE_FLAGS_SIZE)))
return TRUE;
query[packet_length]= '\0';
@@ -1961,8 +1909,7 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length)
also store this length, in case current database is changed during
execution. We might need to reallocate the 'query' buffer
*/
- char *len_pos = (query + packet_length + 1);
- memcpy(len_pos, (char *) &thd->db_length, sizeof(size_t));
+ int2store(query + packet_length + 1, thd->db_length);
thd->set_query(query, packet_length);
@@ -2295,6 +2242,8 @@ mysql_execute_command(THD *thd)
} /* endif unlikely slave */
#endif
status_var_increment(thd->status_var.com_stat[lex->sql_command]);
+ thd->progress.report_to_client= test(sql_command_flags[lex->sql_command] &
+ CF_REPORT_PROGRESS);
DBUG_ASSERT(thd->transaction.stmt.modified_non_trans_table == FALSE);
@@ -2410,11 +2359,7 @@ mysql_execute_command(THD *thd)
goto error;
}
it= new Item_func_unix_timestamp(it);
- /*
- it is OK only emulate fix_fieds, because we need only
- value of constant
- */
- it->quick_fix_field();
+ it->fix_fields(thd, &it);
res = purge_master_logs_before_date(thd, (ulong)it->val_int());
break;
}
@@ -2924,7 +2869,7 @@ end_with_restore_list:
res= mysql_alter_table(thd, first_table->db, first_table->table_name,
&create_info, first_table, &alter_info,
- 0, (ORDER*) 0, 0);
+ 0, (ORDER*) 0, 0, 0);
break;
}
#ifdef HAVE_REPLICATION
@@ -3041,7 +2986,7 @@ end_with_restore_list:
&alter_info,
select_lex->order_list.elements,
(ORDER *) select_lex->order_list.first,
- lex->ignore);
+ lex->ignore, lex->online);
break;
}
case SQLCOM_RENAME_TABLE:
@@ -3134,6 +3079,7 @@ end_with_restore_list:
thd->enable_slow_log= opt_log_slow_admin_statements;
thd->query_plan_flags|= QPLAN_ADMIN;
res= mysql_analyze_table(thd, first_table, &lex->check_opt);
+
/* ! we write after unlocking the table */
if (!res && !lex->no_write_to_binlog)
{
@@ -3358,6 +3304,10 @@ end_with_restore_list:
if (!(res= open_and_lock_tables(thd, all_tables)))
{
+ /*
+ Only the INSERT table should be merged. Other will be handled by
+ select.
+ */
/* Skip first table, which is the table we are inserting in */
TABLE_LIST *second_table= first_table->next_local;
select_lex->table_list.first= second_table;
@@ -3671,7 +3621,7 @@ end_with_restore_list:
{
#ifdef HAVE_QUERY_CACHE
if (thd->variables.query_cache_wlock_invalidate)
- query_cache.invalidate_locked_for_write(first_table);
+ query_cache.invalidate_locked_for_write(thd, first_table);
#endif /*HAVE_QUERY_CACHE*/
thd->locked_tables=thd->lock;
thd->lock=0;
@@ -4151,8 +4101,6 @@ end_with_restore_list:
}
case SQLCOM_KILL:
{
- Item *it= (Item *)lex->value_list.head();
-
if (lex->table_or_sp_used())
{
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
@@ -4160,13 +4108,20 @@ end_with_restore_list:
break;
}
- if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
+ if (lex->kill_type == KILL_TYPE_ID)
{
- my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
- MYF(0));
- goto error;
+ Item *it= (Item *)lex->value_list.head();
+ if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
+ {
+ my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
+ MYF(0));
+ goto error;
+ }
+ sql_kill(thd, (ulong) it->val_int(), lex->kill_signal);
}
- sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
+ else
+ sql_kill_user(thd, get_current_user(thd, lex->users_list.head()),
+ lex->kill_signal);
break;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -5912,6 +5867,7 @@ void mysql_reset_thd_for_next_command(THD *thd, my_bool calculate_userstat)
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
thd->query_start_used= 0;
+ thd->query_start_sec_part_used= 0;
thd->is_fatal_error= thd->time_zone_used= 0;
/*
Clear the status flag that are expected to be cleared at the
@@ -6021,6 +5977,7 @@ mysql_new_select(LEX *lex, bool move_down)
DBUG_RETURN(1);
}
select_lex->nest_level= lex->nest_level;
+ select_lex->nest_level_base= &thd->lex->unit;
if (move_down)
{
SELECT_LEX_UNIT *unit;
@@ -6370,17 +6327,6 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
DBUG_RETURN(1);
}
- if (type == MYSQL_TYPE_TIMESTAMP && length)
- {
- /* Display widths are no longer supported for TIMSTAMP as of MySQL 4.1.
- In other words, for declarations such as TIMESTAMP(2), TIMESTAMP(4),
- and so on, the display width is ignored.
- */
- char buf[32];
- my_snprintf(buf, sizeof(buf), "TIMESTAMP(%s)", length);
- WARN_DEPRECATED(thd, "6.0", buf, "'TIMESTAMP'");
- }
-
if (!(new_field= new Create_field()) ||
new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
default_value, on_update_value, comment, change,
@@ -7158,7 +7104,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
#ifdef HAVE_QUERY_CACHE
if (options & REFRESH_QUERY_CACHE_FREE)
{
- query_cache.pack(); // FLUSH QUERY CACHE
+ query_cache.pack(thd); // FLUSH QUERY CACHE
options &= ~REFRESH_QUERY_CACHE; // Don't flush cache, just free memory
}
if (options & (REFRESH_TABLES | REFRESH_QUERY_CACHE))
@@ -7216,6 +7162,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
unlock_global_read_lock(thd);
return 1;
}
+ if (options & REFRESH_CHECKPOINT)
+ disable_checkpoints(thd);
}
else
{
@@ -7323,12 +7271,13 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
This is written such that we have a short lock on LOCK_thread_count
*/
-uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
+uint kill_one_thread(THD *thd, ulong id, killed_state kill_signal)
{
THD *tmp;
uint error=ER_NO_SUCH_THREAD;
DBUG_ENTER("kill_one_thread");
- DBUG_PRINT("enter", ("id=%lu only_kill=%d", id, only_kill_query));
+ DBUG_PRINT("enter", ("id: %lu signal: %u", id, (uint) kill_signal));
+
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
I_List_iterator<THD> it(threads);
while ((tmp=it++))
@@ -7369,7 +7318,7 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
thd->security_ctx->user_matches(tmp->security_ctx))
{
DEBUG_SYNC(thd, "kill_one_thread_before_kill");
- tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
+ tmp->awake(kill_signal);
error=0;
}
else
@@ -7381,6 +7330,86 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
}
+/**
+ kill all threads from one user
+
+ @param thd Thread class
+ @param user_name User name for threads we should kill
+ @param only_kill_query Should it kill the query or the connection
+
+ @note
+ This is written such that we have a short lock on LOCK_thread_count
+
+ If we can't kill all threads because of security issues, no threads
+ are killed.
+*/
+
+static uint kill_threads_for_user(THD *thd, LEX_USER *user,
+ killed_state kill_signal, ha_rows *rows)
+{
+ THD *tmp;
+ List<THD> threads_to_kill;
+ DBUG_ENTER("kill_threads_for_user");
+
+ *rows= 0;
+
+ if (thd->is_fatal_error) // If we run out of memory
+ DBUG_RETURN(ER_OUT_OF_RESOURCES);
+
+ DBUG_PRINT("enter", ("user: %s signal: %u", user->user.str,
+ (uint) kill_signal));
+
+ VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
+ I_List_iterator<THD> it(threads);
+ while ((tmp=it++))
+ {
+ if (tmp->command == COM_DAEMON)
+ continue;
+ /*
+ Check that hostname (if given) and user name matches.
+
+ host.str[0] == '%' means that host name was not given. See sql_yacc.yy
+ */
+ if (((user->host.str[0] == '%' && !user->host.str[1]) ||
+ !strcmp(tmp->security_ctx->host, user->host.str)) &&
+ !strcmp(tmp->security_ctx->user, user->user.str))
+ {
+ if (!(thd->security_ctx->master_access & SUPER_ACL) &&
+ !thd->security_ctx->user_matches(tmp->security_ctx))
+ {
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ DBUG_RETURN(ER_KILL_DENIED_ERROR);
+ }
+ if (!threads_to_kill.push_back(tmp, tmp->mem_root))
+ pthread_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
+ }
+ }
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ if (!threads_to_kill.is_empty())
+ {
+ List_iterator_fast<THD> it(threads_to_kill);
+ THD *next_ptr;
+ THD *ptr= it++;
+ do
+ {
+ ptr->awake(kill_signal);
+ /*
+ Careful here: The list nodes are allocated on the memroots of the
+ THDs to be awakened.
+ But those THDs may be terminated and deleted as soon as we release
+ LOCK_thd_data, which will make the list nodes invalid.
+ Since the operation "it++" dereferences the "next" pointer of the
+ previous list node, we need to do this while holding LOCK_thd_data.
+ */
+ next_ptr= it++;
+ pthread_mutex_unlock(&ptr->LOCK_thd_data);
+ (*rows)++;
+ } while ((ptr= next_ptr));
+ }
+ DBUG_RETURN(0);
+}
+
+
/*
kills a thread and sends response
@@ -7391,16 +7420,33 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
only_kill_query Should it kill the query or the connection
*/
-void sql_kill(THD *thd, ulong id, bool only_kill_query)
+void sql_kill(THD *thd, ulong id, killed_state state)
{
uint error;
- if (!(error= kill_one_thread(thd, id, only_kill_query)))
+ if (!(error= kill_one_thread(thd, id, state)))
my_ok(thd);
else
my_error(error, MYF(0), id);
}
+void sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
+{
+ uint error;
+ ha_rows rows;
+ if (!(error= kill_threads_for_user(thd, user, state, &rows)))
+ my_ok(thd, rows);
+ else
+ {
+ /*
+ This is probably ER_OUT_OF_RESOURCES, but in the future we may
+ want to write the name of the user we tried to kill
+ */
+ my_error(error, MYF(0), user->host.str, user->user.str);
+ }
+}
+
+
/** If pointer is not a null pointer, append filename to it. */
bool append_file_to_dir(THD *thd, const char **filename_ptr,
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 67c59322a55..1547e576eca 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1648,8 +1648,11 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
if (simple_open_n_lock_tables(new_thd, &tables))
{
DBUG_PRINT("error",("Can't open plugin table"));
- sql_print_error("Can't open the mysql.plugin table. Please "
- "run mysql_upgrade to create it.");
+ if (!opt_help)
+ sql_print_error("Can't open the mysql.plugin table. Please "
+ "run mysql_upgrade to create it.");
+ else
+ sql_print_warning("Could not open mysql.plugin table. Some options may be missing from the help text");
goto end;
}
table= tables.table;
@@ -2200,7 +2203,7 @@ static int check_func_bool(THD *thd, struct st_mysql_sys_var *var,
{
if (value->val_int(value, &tmp) < 0)
goto err;
- if (tmp > 1)
+ if (tmp != 0 && tmp != 1)
{
llstr(tmp, buff);
strvalue= buff;
@@ -2208,7 +2211,7 @@ static int check_func_bool(THD *thd, struct st_mysql_sys_var *var,
}
result= (int) tmp;
}
- *(my_bool *) save= -result;
+ *(my_bool *) save= result ? 1 : 0;
return 0;
err:
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
@@ -2389,7 +2392,7 @@ err:
static void update_func_bool(THD *thd, struct st_mysql_sys_var *var,
void *tgt, const void *save)
{
- *(my_bool *) tgt= *(my_bool *) save ? TRUE : FALSE;
+ *(my_bool *) tgt= *(my_bool *) save ? 1 : 0;
}
diff --git a/sql/sql_plugin_services.h b/sql/sql_plugin_services.h
index 14a2a16561a..497e2c8d6bc 100644
--- a/sql/sql_plugin_services.h
+++ b/sql/sql_plugin_services.h
@@ -22,6 +22,8 @@ struct st_service_ref {
void *service;
};
+#ifdef HAVE_DLOPEN
+
static struct my_snprintf_service_st my_snprintf_handler = {
my_snprintf,
my_vsnprintf
@@ -36,9 +38,18 @@ static struct thd_alloc_service_st thd_alloc_handler= {
thd_make_lex_string
};
+static struct progress_report_service_st progress_report_handler= {
+ thd_progress_init,
+ thd_progress_report,
+ thd_progress_next_stage,
+ thd_progress_end,
+ set_thd_proc_info
+};
+
static struct st_service_ref list_of_services[] __attribute__((unused)) =
{
{ "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
- { "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler }
+ { "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler },
+ { "progress_report_service", VERSION_progress_report, &progress_report_handler }
};
-
+#endif
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index c269b262ff4..d91d03d24ee 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -96,6 +96,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.
@@ -244,6 +245,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);
@@ -488,8 +491,7 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len)
}
else
set_zero_time(&tm, MYSQL_TIMESTAMP_TIME);
- param->set_time(&tm, MYSQL_TIMESTAMP_TIME,
- MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
+ param->set_time(&tm, MYSQL_TIMESTAMP_TIME, MAX_TIME_FULL_WIDTH);
*pos+= length;
}
@@ -1174,7 +1176,7 @@ static bool mysql_test_insert(Prepared_statement *stmt,
If we would use locks, then we have to ensure we are not using
TL_WRITE_DELAYED as having two such locks can cause table corruption.
*/
- if (open_normal_and_derived_tables(thd, table_list, 0))
+ if (open_normal_and_derived_tables(thd, table_list, 0, DT_INIT))
goto error;
if ((values= its++))
@@ -1258,7 +1260,10 @@ static int mysql_test_update(Prepared_statement *stmt,
open_tables(thd, &table_list, &table_count, 0))
goto error;
- if (table_list->multitable_view)
+ if (mysql_handle_derived(thd->lex, DT_INIT))
+ goto error;
+
+ if (table_list->is_multitable())
{
DBUG_ASSERT(table_list->view != 0);
DBUG_PRINT("info", ("Switch to multi-update"));
@@ -1272,8 +1277,16 @@ static int mysql_test_update(Prepared_statement *stmt,
thd->fill_derived_tables() is false here for sure (because it is
preparation of PS, so we even do not check it).
*/
- if (mysql_handle_derived(thd->lex, &mysql_derived_prepare))
+ if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
+ goto error;
+ if (table_list->handle_derived(thd->lex, DT_PREPARE))
+ goto error;
+
+ if (!table_list->single_table_updatable())
+ {
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
goto error;
+ }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Force privilege re-checking for views after they have been opened. */
@@ -1327,15 +1340,28 @@ error:
static bool mysql_test_delete(Prepared_statement *stmt,
TABLE_LIST *table_list)
{
+ uint table_count= 0;
THD *thd= stmt->thd;
LEX *lex= stmt->lex;
DBUG_ENTER("mysql_test_delete");
if (delete_precheck(thd, table_list) ||
- open_normal_and_derived_tables(thd, table_list, 0))
+ open_tables(thd, &table_list, &table_count, 0))
+ goto error;
+
+ if (mysql_handle_derived(thd->lex, DT_INIT))
+ goto error;
+ if (mysql_handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
+ goto error;
+ if (mysql_handle_derived(thd->lex, DT_PREPARE))
goto error;
- if (!table_list->table)
+ if (!table_list->single_table_updatable())
+ {
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE");
+ goto error;
+ }
+ if (!table_list->table || !table_list->table->created)
{
my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
table_list->view_db.str, table_list->view_name.str);
@@ -1390,7 +1416,8 @@ static int mysql_test_select(Prepared_statement *stmt,
goto error;
}
- if (open_normal_and_derived_tables(thd, tables, 0))
+ if (open_normal_and_derived_tables(thd, tables, 0,
+ DT_PREPARE | DT_CREATE))
goto error;
thd->lex->used_tables= 0; // Updated by setup_fields
@@ -1450,7 +1477,8 @@ static bool mysql_test_do_fields(Prepared_statement *stmt,
if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
DBUG_RETURN(TRUE);
- if (open_normal_and_derived_tables(thd, tables, 0))
+ if (open_normal_and_derived_tables(thd, tables, 0,
+ DT_PREPARE | DT_CREATE))
DBUG_RETURN(TRUE);
DBUG_RETURN(setup_fields(thd, 0, *values, MARK_COLUMNS_NONE, 0, 0));
}
@@ -1480,7 +1508,8 @@ static bool mysql_test_set_fields(Prepared_statement *stmt,
if ((tables &&
check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) ||
- open_normal_and_derived_tables(thd, tables, 0))
+ open_normal_and_derived_tables(thd, tables, 0,
+ DT_PREPARE | DT_CREATE))
goto error;
while ((var= it++))
@@ -1517,7 +1546,7 @@ static bool mysql_test_call_fields(Prepared_statement *stmt,
if ((tables &&
check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) ||
- open_normal_and_derived_tables(thd, tables, 0))
+ open_normal_and_derived_tables(thd, tables, 0, DT_PREPARE))
goto err;
while ((item= it++))
@@ -1592,6 +1621,7 @@ select_like_stmt_test_with_open(Prepared_statement *stmt,
int (*specific_prepare)(THD *thd),
ulong setup_tables_done_option)
{
+ uint table_count= 0;
DBUG_ENTER("select_like_stmt_test_with_open");
/*
@@ -1600,7 +1630,8 @@ select_like_stmt_test_with_open(Prepared_statement *stmt,
prepared EXPLAIN yet so derived tables will clean up after
themself.
*/
- if (open_normal_and_derived_tables(stmt->thd, tables, 0))
+ THD *thd= stmt->thd;
+ if (open_tables(thd, &tables, &table_count, 0))
DBUG_RETURN(TRUE);
DBUG_RETURN(select_like_stmt_test(stmt, specific_prepare,
@@ -1645,7 +1676,8 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
create_table->skip_temporary= true;
}
- if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0))
+ if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0,
+ DT_PREPARE | DT_CREATE))
DBUG_RETURN(TRUE);
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
@@ -1663,7 +1695,8 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
we validate metadata of all CREATE TABLE statements,
which keeps metadata validation code simple.
*/
- if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0))
+ if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0,
+ DT_PREPARE))
DBUG_RETURN(TRUE);
}
@@ -1698,7 +1731,7 @@ static bool mysql_test_create_view(Prepared_statement *stmt)
if (create_view_precheck(thd, tables, view, lex->create_view_mode))
goto err;
- if (open_normal_and_derived_tables(thd, tables, 0))
+ if (open_normal_and_derived_tables(thd, tables, 0, DT_PREPARE))
goto err;
lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
@@ -1843,6 +1876,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
@@ -1957,6 +2040,11 @@ 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(res == 1 ? TRUE : FALSE);
+
/*
Note that we don't need to have cases in this list if they are
marked with CF_STATUS_COMMAND in sql_command_flags
@@ -2359,14 +2447,24 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
*/
if (sl->prep_where)
{
- sl->where= sl->prep_where->copy_andor_structure(thd);
+ /*
+ We need this rollback because memory allocated in
+ copy_andor_structure() will be freed
+ */
+ thd->change_item_tree((Item**)&sl->where,
+ sl->prep_where->copy_andor_structure(thd));
sl->where->cleanup();
}
else
sl->where= NULL;
if (sl->prep_having)
{
- sl->having= sl->prep_having->copy_andor_structure(thd);
+ /*
+ We need this rollback because memory allocated in
+ copy_andor_structure() will be freed
+ */
+ thd->change_item_tree((Item**)&sl->having,
+ sl->prep_having->copy_andor_structure(thd));
sl->having->cleanup();
}
else
@@ -2387,9 +2485,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
/* Fix ORDER list */
for (order= sl->order_list.first; order; order= order->next)
order->item= &order->item_ptr;
-
- /* clear the no_error flag for INSERT/UPDATE IGNORE */
- sl->no_error= FALSE;
+ sl->handle_derived(lex, DT_REINIT);
}
{
SELECT_LEX_UNIT *unit= sl->master_unit();
@@ -2430,9 +2526,6 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
}
lex->current_select= &lex->select_lex;
- /* restore original list used in INSERT ... SELECT */
- if (lex->leaf_tables_insert)
- lex->select_lex.leaf_tables= lex->leaf_tables_insert;
if (lex->result)
{
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index 1d43e5898b0..790fff70c7e 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -239,7 +239,7 @@ void PROF_MEASUREMENT::set_label(const char *status_arg,
*/
void PROF_MEASUREMENT::collect()
{
- time_usecs= (double) my_getsystime() / 10.0; /* 1 sec was 1e7, now is 1e6 */
+ time_usecs= my_interval_timer() / 1e3; /* ns to us */
#ifdef HAVE_GETRUSAGE
getrusage(RUSAGE_SELF, &rusage);
#elif defined(__WIN__)
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index cab41b1df07..2cf4eca447c 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -21,7 +21,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_repl.cc b/sql/sql_repl.cc
index f852bf0377e..ee624598ee3 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2008-2011 Monty Program Ab
+ Copyright (c) 2008, 2011, Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -32,6 +32,9 @@ my_bool opt_sporadic_binlog_dump_fail = 0;
static int binlog_dump_count = 0;
#endif
+extern TYPELIB binlog_checksum_typelib;
+
+
/*
fake_rotate_event() builds a fake (=which does not exist physically in any
binlog) Rotate event, which contains the name of the binlog we are going to
@@ -51,10 +54,21 @@ static int binlog_dump_count = 0;
*/
static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
- ulonglong position, const char** errmsg)
+ ulonglong position, const char** errmsg,
+ uint8 checksum_alg_arg)
{
DBUG_ENTER("fake_rotate_event");
char header[LOG_EVENT_HEADER_LEN], buf[ROTATE_HEADER_LEN+100];
+
+ /*
+ this Rotate is to be sent with checksum if and only if
+ slave's get_master_version_and_clock time handshake value
+ of master's @@global.binlog_checksum was TRUE
+ */
+
+ my_bool do_checksum= checksum_alg_arg != BINLOG_CHECKSUM_ALG_OFF &&
+ checksum_alg_arg != BINLOG_CHECKSUM_ALG_UNDEF;
+
/*
'when' (the timestamp) is set to 0 so that slave could distinguish between
real and fake Rotate events (if necessary)
@@ -64,7 +78,8 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
char* p = log_file_name+dirname_length(log_file_name);
uint ident_len = (uint) strlen(p);
- ulong event_len = ident_len + LOG_EVENT_HEADER_LEN + ROTATE_HEADER_LEN;
+ ulong event_len = ident_len + LOG_EVENT_HEADER_LEN + ROTATE_HEADER_LEN +
+ (do_checksum ? BINLOG_CHECKSUM_LEN : 0);
int4store(header + SERVER_ID_OFFSET, server_id);
int4store(header + EVENT_LEN_OFFSET, event_len);
int2store(header + FLAGS_OFFSET, LOG_EVENT_ARTIFICIAL_F);
@@ -75,7 +90,19 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
packet->append(header, sizeof(header));
int8store(buf+R_POS_OFFSET,position);
packet->append(buf, ROTATE_HEADER_LEN);
- packet->append(p,ident_len);
+ packet->append(p, ident_len);
+
+ if (do_checksum)
+ {
+ char b[BINLOG_CHECKSUM_LEN];
+ ha_checksum crc= my_checksum(0L, NULL, 0);
+ crc= my_checksum(crc, (uchar*)header, sizeof(header));
+ crc= my_checksum(crc, (uchar*)buf, ROTATE_HEADER_LEN);
+ crc= my_checksum(crc, (uchar*)p, ident_len);
+ int4store(b, crc);
+ packet->append(b, sizeof(b));
+ }
+
if (my_net_write(net, (uchar*) packet->ptr(), packet->length()))
{
*errmsg = "failed on my_net_write()";
@@ -157,6 +184,86 @@ static int send_file(THD *thd)
}
+/**
+ Internal to mysql_binlog_send() routine that recalculates checksum for
+ a FD event (asserted) that needs additional arranment prior sending to slave.
+*/
+inline void fix_checksum(String *packet, ulong ev_offset)
+{
+ /* recalculate the crc for this event */
+ uint data_len = uint4korr(packet->ptr() + ev_offset + EVENT_LEN_OFFSET);
+ ha_checksum crc= my_checksum(0L, NULL, 0);
+ DBUG_ASSERT(data_len ==
+ LOG_EVENT_MINIMAL_HEADER_LEN + FORMAT_DESCRIPTION_HEADER_LEN +
+ BINLOG_CHECKSUM_ALG_DESC_LEN + BINLOG_CHECKSUM_LEN);
+ crc= my_checksum(crc, (uchar *)packet->ptr() + ev_offset, data_len -
+ BINLOG_CHECKSUM_LEN);
+ int4store(packet->ptr() + ev_offset + data_len - BINLOG_CHECKSUM_LEN, crc);
+}
+
+
+static user_var_entry * get_binlog_checksum_uservar(THD * thd)
+{
+ LEX_STRING name= { C_STRING_WITH_LEN("master_binlog_checksum")};
+ user_var_entry *entry=
+ (user_var_entry*) my_hash_search(&thd->user_vars, (uchar*) name.str,
+ name.length);
+ return entry;
+}
+
+/**
+ Function for calling in mysql_binlog_send
+ to check if slave initiated checksum-handshake.
+
+ @param[in] thd THD to access a user variable
+
+ @return TRUE if handshake took place, FALSE otherwise
+*/
+
+static bool is_slave_checksum_aware(THD * thd)
+{
+ DBUG_ENTER("is_slave_checksum_aware");
+ user_var_entry *entry= get_binlog_checksum_uservar(thd);
+ DBUG_RETURN(entry? true : false);
+}
+
+/**
+ Function for calling in mysql_binlog_send
+ to get the value of @@binlog_checksum of the master at
+ time of checksum-handshake.
+
+ The value tells the master whether to compute or not, and the slave
+ to verify or not the first artificial Rotate event's checksum.
+
+ @param[in] thd THD to access a user variable
+
+ @return value of @@binlog_checksum alg according to
+ @c enum enum_binlog_checksum_alg
+*/
+
+static uint8 get_binlog_checksum_value_at_connect(THD * thd)
+{
+ uint8 ret;
+
+ DBUG_ENTER("get_binlog_checksum_value_at_connect");
+ user_var_entry *entry= get_binlog_checksum_uservar(thd);
+ if (!entry)
+ {
+ ret= BINLOG_CHECKSUM_ALG_UNDEF;
+ }
+ else
+ {
+ DBUG_ASSERT(entry->type == STRING_RESULT);
+ String str;
+ uint dummy_errors;
+ str.copy(entry->value, entry->length, &my_charset_bin, &my_charset_bin,
+ &dummy_errors);
+ ret= (uint8) find_type ((char*) str.ptr(), &binlog_checksum_typelib, 1) - 1;
+ DBUG_ASSERT(ret <= BINLOG_CHECKSUM_ALG_CRC32); // while it's just on CRC32 alg
+ }
+ DBUG_RETURN(ret);
+}
+
/*
Adjust the position pointer in the binary log file for all running slaves
@@ -331,6 +438,9 @@ Increase max_allowed_packet on master";
case LOG_READ_TRUNC:
*errmsg = "binlog truncated in the middle of event";
break;
+ case LOG_READ_CHECKSUM_FAILURE:
+ *errmsg = "event read from binlog did not pass crc check";
+ break;
default:
*errmsg = "unknown error reading log event on the master";
break;
@@ -357,10 +467,11 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
NET* net = &thd->net;
pthread_mutex_t *log_lock;
bool binlog_can_be_corrupted= FALSE;
+ uint8 current_checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF;
+ int old_max_allowed_packet= thd->variables.max_allowed_packet;
#ifndef DBUG_OFF
int left_events = max_binlog_dump_events;
#endif
- int old_max_allowed_packet= thd->variables.max_allowed_packet;
DBUG_ENTER("mysql_binlog_send");
DBUG_PRINT("enter",("log_ident: '%s' pos: %ld", log_ident, (long) pos));
@@ -454,7 +565,8 @@ impossible position";
given that we want minimum modification of 4.0, we send the normal
and fake Rotates.
*/
- if (fake_rotate_event(net, packet, log_file_name, pos, &errmsg))
+ if (fake_rotate_event(net, packet, log_file_name, pos, &errmsg,
+ get_binlog_checksum_value_at_connect(thd)))
{
/*
This error code is not perfect, as fake_rotate_event() does not
@@ -484,8 +596,8 @@ impossible position";
Try to find a Format_description_log_event at the beginning of
the binlog
*/
- if (!(error = Log_event::read_log_event(&log, packet, log_lock)))
- {
+ if (!(error = Log_event::read_log_event(&log, packet, log_lock, 0)))
+ {
/*
The packet has offsets equal to the normal offsets in a binlog
event +1 (the first character is \0).
@@ -493,8 +605,25 @@ impossible position";
DBUG_PRINT("info",
("Looked for a Format_description_log_event, found event type %d",
(*packet)[EVENT_TYPE_OFFSET+1]));
- if ((*packet)[EVENT_TYPE_OFFSET+1] == FORMAT_DESCRIPTION_EVENT)
+ if ((uchar)(*packet)[EVENT_TYPE_OFFSET+1] == FORMAT_DESCRIPTION_EVENT)
{
+ current_checksum_alg= get_checksum_alg(packet->ptr() + 1,
+ packet->length() - 1);
+ DBUG_ASSERT(current_checksum_alg == BINLOG_CHECKSUM_ALG_OFF ||
+ current_checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
+ current_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32);
+ if (!is_slave_checksum_aware(thd) &&
+ current_checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
+ current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
+ {
+ my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
+ errmsg= "Slave can not handle replication events with the checksum "
+ "that master is configured to log";
+ sql_print_warning("Master is configured to log replication events "
+ "with checksum, but will not send such events to "
+ "slaves that cannot process them");
+ goto err;
+ }
binlog_can_be_corrupted= test((*packet)[FLAGS_OFFSET+1] &
LOG_EVENT_BINLOG_IN_USE_F);
(*packet)[FLAGS_OFFSET+1] &= ~LOG_EVENT_BINLOG_IN_USE_F;
@@ -510,6 +639,12 @@ impossible position";
*/
int4store((char*) packet->ptr()+LOG_EVENT_MINIMAL_HEADER_LEN+
ST_CREATED_OFFSET+1, (ulong) 0);
+
+ /* fix the checksum due to latest changes in header */
+ if (current_checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
+ current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
+ fix_checksum(packet, 1);
+
/* send it */
if (my_net_write(net, (uchar*) packet->ptr(), packet->length()))
{
@@ -549,7 +684,8 @@ impossible position";
while (!net->error && net->vio != 0 && !thd->killed)
{
my_off_t prev_pos= pos;
- while (!(error = Log_event::read_log_event(&log, packet, log_lock)))
+ while (!(error = Log_event::read_log_event(&log, packet, log_lock,
+ current_checksum_alg)))
{
prev_pos= my_b_tell(&log);
#ifndef DBUG_OFF
@@ -561,7 +697,6 @@ impossible position";
goto err;
}
#endif
-
DBUG_EXECUTE_IF("dump_thread_wait_before_send_xid",
{
if ((*packet)[EVENT_TYPE_OFFSET+1] == XID_EVENT)
@@ -571,7 +706,7 @@ impossible position";
"now "
"wait_for signal.continue";
DBUG_ASSERT(opt_debug_sync_timeout > 0);
- DBUG_ASSERT(!debug_sync_set_action(current_thd,
+ DBUG_ASSERT(!debug_sync_set_action(thd,
STRING_WITH_LEN(act)));
const char act2[]=
"now "
@@ -581,40 +716,61 @@ impossible position";
}
});
- if ((*packet)[EVENT_TYPE_OFFSET+1] == FORMAT_DESCRIPTION_EVENT)
+ if ((uchar) (*packet)[EVENT_TYPE_OFFSET+1] == FORMAT_DESCRIPTION_EVENT)
{
+ current_checksum_alg= get_checksum_alg(packet->ptr() + 1,
+ packet->length() - 1);
+ DBUG_ASSERT(current_checksum_alg == BINLOG_CHECKSUM_ALG_OFF ||
+ current_checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
+ current_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32);
+ if (!is_slave_checksum_aware(thd) &&
+ current_checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
+ current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
+ {
+ my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
+ errmsg= "Slave can not handle replication events with the checksum "
+ "that master is configured to log";
+ sql_print_warning("Master is configured to log replication events "
+ "with checksum, but will not send such events to "
+ "slaves that cannot process them");
+ goto err;
+ }
binlog_can_be_corrupted= test((*packet)[FLAGS_OFFSET+1] &
LOG_EVENT_BINLOG_IN_USE_F);
(*packet)[FLAGS_OFFSET+1] &= ~LOG_EVENT_BINLOG_IN_USE_F;
}
- else if ((*packet)[EVENT_TYPE_OFFSET+1] == STOP_EVENT)
+ else if ((uchar)(*packet)[EVENT_TYPE_OFFSET+1] == STOP_EVENT)
binlog_can_be_corrupted= FALSE;
- if (my_net_write(net, (uchar*) packet->ptr(), packet->length()))
+ if ((uchar)(*packet)[EVENT_TYPE_OFFSET+1] != ANNOTATE_ROWS_EVENT ||
+ (flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT))
{
- errmsg = "Failed on my_net_write()";
- my_errno= ER_UNKNOWN_ERROR;
- goto err;
- }
+ if (my_net_write(net, (uchar*) packet->ptr(), packet->length()))
+ {
+ errmsg = "Failed on my_net_write()";
+ my_errno= ER_UNKNOWN_ERROR;
+ goto err;
+ }
- DBUG_EXECUTE_IF("dump_thread_wait_before_send_xid",
- {
- if ((*packet)[EVENT_TYPE_OFFSET+1] == XID_EVENT)
+ DBUG_EXECUTE_IF("dump_thread_wait_before_send_xid",
{
- net_flush(net);
- }
- });
-
- DBUG_PRINT("info", ("log event code %d",
- (*packet)[LOG_EVENT_OFFSET+1] ));
- if ((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
- {
- if (send_file(thd))
- {
- errmsg = "failed in send_file()";
- my_errno= ER_UNKNOWN_ERROR;
- goto err;
- }
+ if ((*packet)[EVENT_TYPE_OFFSET+1] == XID_EVENT)
+ {
+ net_flush(net);
+ }
+ });
+
+ DBUG_PRINT("info", ("log event code %d",
+ (*packet)[LOG_EVENT_OFFSET+1] ));
+ if ((uchar) (*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
+ {
+ if (send_file(thd))
+ {
+ errmsg = "failed in send_file()";
+ my_errno= ER_UNKNOWN_ERROR;
+ goto err;
+ }
+ }
}
packet->set("\0", 1, &my_charset_bin);
}
@@ -624,7 +780,8 @@ impossible position";
of a crash ?). treat any corruption as EOF
*/
if (binlog_can_be_corrupted &&
- error != LOG_READ_MEM && error != LOG_READ_EOF)
+ (error != LOG_READ_MEM && error != LOG_READ_CHECKSUM_FAILURE &&
+ error != LOG_READ_EOF))
{
my_b_seek(&log, prev_pos);
error=LOG_READ_EOF;
@@ -683,7 +840,8 @@ impossible position";
*/
pthread_mutex_lock(log_lock);
- switch (error= Log_event::read_log_event(&log, packet, (pthread_mutex_t*) 0)) {
+ switch (error= Log_event::read_log_event(&log, packet, (pthread_mutex_t*) 0,
+ current_checksum_alg)) {
case 0:
/* we read successfully, so we'll need to send it to the slave */
pthread_mutex_unlock(log_lock);
@@ -715,23 +873,27 @@ impossible position";
if (read_packet)
{
- thd_proc_info(thd, "Sending binlog event to slave");
- if (my_net_write(net, (uchar*) packet->ptr(), packet->length()) )
- {
- errmsg = "Failed on my_net_write()";
- my_errno= ER_UNKNOWN_ERROR;
- goto err;
- }
-
- if ((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
- {
- if (send_file(thd))
+ if ((uchar)(*packet)[EVENT_TYPE_OFFSET+1] != ANNOTATE_ROWS_EVENT ||
+ (flags & BINLOG_SEND_ANNOTATE_ROWS_EVENT))
+ {
+ thd_proc_info(thd, "Sending binlog event to slave");
+ if (my_net_write(net, (uchar*) packet->ptr(), packet->length()) )
{
- errmsg = "failed in send_file()";
+ errmsg = "Failed on my_net_write()";
my_errno= ER_UNKNOWN_ERROR;
goto err;
}
- }
+
+ if ((uchar)(*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
+ {
+ if (send_file(thd))
+ {
+ errmsg = "failed in send_file()";
+ my_errno= ER_UNKNOWN_ERROR;
+ goto err;
+ }
+ }
+ }
packet->set("\0", 1, &my_charset_bin);
/*
No need to net_flush because we will get to flush later when
@@ -780,7 +942,7 @@ impossible position";
*/
if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0 ||
fake_rotate_event(net, packet, log_file_name, BIN_LOG_HEADER_SIZE,
- &errmsg))
+ &errmsg, current_checksum_alg))
{
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err;
@@ -1121,9 +1283,9 @@ err:
idle, then this could last long, and if the slave reconnects, we could have 2
Binlog_dump threads in SHOW PROCESSLIST, until a query is written to the
binlog. To avoid this, when the slave reconnects and sends COM_BINLOG_DUMP,
- the master kills any existing thread with the slave's server id (if this id is
- not zero; it will be true for real slaves, but false for mysqlbinlog when it
- sends COM_BINLOG_DUMP to get a remote binlog dump).
+ the master kills any existing thread with the slave's server id (if this id
+ is not zero; it will be true for real slaves, but false for mysqlbinlog when
+ it sends COM_BINLOG_DUMP to get a remote binlog dump).
SYNOPSIS
kill_zombie_dump_threads()
@@ -1155,7 +1317,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id)
it will be slow because it will iterate through the list
again. We just to do kill the thread ourselves.
*/
- tmp->awake(THD::KILL_QUERY);
+ tmp->awake(KILL_QUERY);
pthread_mutex_unlock(&tmp->LOCK_thd_kill);
}
}
@@ -1534,7 +1696,8 @@ bool mysql_show_binlog_events(THD* thd)
This code will fail on a mixed relay log (one which has Format_desc then
Rotate then Format_desc).
*/
- ev = Log_event::read_log_event(&log,(pthread_mutex_t*)0,description_event);
+ ev = Log_event::read_log_event(&log,(pthread_mutex_t*)0,description_event,
+ opt_master_verify_checksum);
if (ev)
{
if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
@@ -1556,8 +1719,12 @@ bool mysql_show_binlog_events(THD* thd)
for (event_count = 0;
(ev = Log_event::read_log_event(&log,(pthread_mutex_t*) 0,
- description_event)); )
+ description_event,
+ opt_master_verify_checksum)); )
{
+ if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
+ description_event->checksum_alg= ev->checksum_alg;
+
if (event_count >= limit_start &&
ev->net_send(thd, protocol, linfo.log_file_name, pos))
{
@@ -1819,6 +1986,11 @@ static sys_var_chain vars = { NULL, NULL };
static sys_var_const sys_log_slave_updates(&vars, "log_slave_updates",
OPT_GLOBAL, SHOW_MY_BOOL,
(uchar*) &opt_log_slave_updates);
+static sys_var_const
+sys_replicate_annotate_row_events(&vars,
+ "replicate_annotate_row_events",
+ OPT_GLOBAL, SHOW_MY_BOOL,
+ (uchar*) &opt_replicate_annotate_row_events);
static sys_var_const sys_relay_log(&vars, "relay_log",
OPT_GLOBAL, SHOW_CHAR_PTR,
(uchar*) &opt_relay_logname);
@@ -1847,6 +2019,12 @@ static sys_var_long_ptr sys_slave_trans_retries(&vars, "slave_transaction_retrie
&slave_trans_retries);
static sys_var_sync_binlog_period sys_sync_binlog_period(&vars, "sync_binlog", &sync_binlog_period);
static sys_var_slave_skip_counter sys_slave_skip_counter(&vars, "sql_slave_skip_counter");
+static sys_var_bool_ptr sys_master_verify_checksum(&vars,
+ "master_verify_checksum",
+ &opt_master_verify_checksum);
+static sys_var_bool_ptr sys_slave_sql_verify_checksum(&vars,
+ "slave_sql_verify_checksum",
+ &opt_slave_sql_verify_checksum);
bool sys_var_slave_skip_counter::check(THD *thd, set_var *var)
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 95b10f6a44a..d308bef19c2 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -32,54 +32,53 @@
#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
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
"MAYBE_REF","ALL","range","index","fulltext",
"ref_or_null","unique_subquery","index_subquery",
- "index_merge"
-};
+ "index_merge", "hash_ALL", "hash_range",
+ "hash_index", "hash_index_merge" };
+
+const char *copy_to_tmp_table= "Copying to tmp table";
struct st_sargable_param;
static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
-static bool make_join_statistics(JOIN *join, TABLE_LIST *leaves, COND *conds,
- DYNAMIC_ARRAY *keyuse);
+static bool make_join_statistics(JOIN *join, List<TABLE_LIST> &leaves,
+ COND *conds, DYNAMIC_ARRAY *keyuse);
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
JOIN_TAB *join_tab,
uint tables, COND *conds,
- COND_EQUAL *cond_equal,
table_map table_map, SELECT_LEX *select_lex,
st_sargable_param **sargables);
+static bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse,
+ bool skip_unprefixed_keyparts);
static int sort_keyuse(KEYUSE *a,KEYUSE *b);
+static bool are_tables_local(JOIN_TAB *jtab, table_map used_tables);
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);
-
-static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
- table_map remaining_tables, uint idx,
- double record_count, double read_time);
+ bool allow_full_scan, table_map used_tables);
+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);
+ uint depth, uint prune_level);
static bool best_extension_by_limited_search(JOIN *join,
table_map remaining_tables,
uint idx, double record_count,
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.
@@ -87,33 +86,39 @@ static int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
static bool find_best(JOIN *join,table_map rest_tables,uint index,
double record_count,double read_time);
static uint cache_record_length(JOIN *join,uint index);
-static double prev_record_reads(JOIN *join, uint idx, table_map found_ref);
-static bool get_best_combination(JOIN *join);
+bool get_best_combination(JOIN *join);
static store_key *get_store_key(THD *thd,
KEYUSE *keyuse, table_map used_tables,
KEY_PART_INFO *key_part, uchar *key_buff,
uint maybe_null);
-static void make_outerjoin_info(JOIN *join);
+static bool make_outerjoin_info(JOIN *join);
+static Item*
+make_cond_after_sjm(Item *root_cond, Item *cond, table_map tables,
+ table_map sjm_tables, bool inside_or_clause);
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);
+static void update_depend_map_for_order(JOIN *join, ORDER *order);
static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond,
bool change_list, bool *simple_order);
-static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
+static int return_zero_rows(JOIN *join, select_result *res,
+ List<TABLE_LIST> &tables,
List<Item> &fields, bool send_row,
ulonglong select_options, const char *info,
Item *having, List<Item> &all_fields);
-static COND *build_equal_items(THD *thd, COND *cond,
+static COND *build_equal_items(JOIN *join, COND *cond,
COND_EQUAL *inherited,
List<TABLE_LIST> *join_list,
+ bool ignore_on_conds,
COND_EQUAL **cond_equal_ref);
-static COND* substitute_for_best_equal_field(COND *cond,
+static COND* substitute_for_best_equal_field(JOIN_TAB *context_tab,
+ 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 +127,13 @@ static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
static COND *optimize_cond(JOIN *join, COND *conds,
List<TABLE_LIST> *join_list,
- Item::cond_result *cond_value);
+ bool ignore_on_conds,
+ Item::cond_result *cond_value,
+ COND_EQUAL **cond_equal);
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,24 @@ 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(THD *thd, Item *cond,table_map table,
+ table_map used_table,
+ int join_tab_idx_arg,
+ bool exclude_expensive_cond,
+ bool retain_ref_cond);
+static COND *make_cond_for_table_from_pred(THD *thd, Item *root_cond,
+ Item *cond,
+ table_map tables,
+ table_map used_table,
+ int join_tab_idx_arg,
+ 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);
@@ -195,18 +206,11 @@ static int create_sort_index(THD *thd, JOIN *join, ORDER *order,
static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields,
Item *having);
static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
- ulong offset,Item *having);
+ 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,
@@ -214,7 +218,7 @@ static ORDER *create_distinct_group(THD *thd, Item **ref_pointer_array,
List<Item> &all_fields,
bool *all_order_by_fields_used);
static bool test_if_subpart(ORDER *a,ORDER *b);
-static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables);
+static TABLE *get_sort_by_table(ORDER *a,ORDER *b,List<TABLE_LIST> &tables);
static void calc_group_buffer(JOIN *join,ORDER *group);
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
static bool alloc_group_fields(JOIN *join,ORDER *group);
@@ -237,10 +241,14 @@ 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);
+static uint make_join_orderinfo(JOIN *join);
+static bool generate_derived_keys(DYNAMIC_ARRAY *keyuse_array);
+Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field,
+ bool *inherited_fl);
+JOIN_TAB *first_depth_first_tab(JOIN* join);
+JOIN_TAB *next_depth_first_tab(JOIN* join, JOIN_TAB* tab);
/**
This handles SELECT with and without UNION.
@@ -422,11 +430,78 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
}
/**
+ The following clauses are redundant for subqueries:
+
+ DISTINCT
+ GROUP BY if there are no aggregate functions and no HAVING
+ clause
+
+ Because redundant clauses are removed both from JOIN and
+ select_lex, the removal is permanent. Thus, it only makes sense to
+ call this function for normal queries and on first execution of
+ SP/PS
+
+ @param subq_select_lex select_lex that is part of a subquery
+ predicate. This object and the associated
+ join is modified.
+*/
+
+static
+void remove_redundant_subquery_clauses(st_select_lex *subq_select_lex)
+{
+ Item_subselect *subq_predicate= subq_select_lex->master_unit()->item;
+ /*
+ The removal should happen for IN, ALL, ANY and EXISTS subqueries,
+ which means all but single row subqueries. Example single row
+ subqueries:
+ a) SELECT * FROM t1 WHERE t1.a = (<single row subquery>)
+ b) SELECT a, (<single row subquery) FROM t1
+ */
+ if (subq_predicate->substype() == Item_subselect::SINGLEROW_SUBS)
+ return;
+
+ /* A subquery that is not single row should be one of IN/ALL/ANY/EXISTS. */
+ DBUG_ASSERT (subq_predicate->substype() == Item_subselect::EXISTS_SUBS ||
+ subq_predicate->is_in_predicate());
+
+ if (subq_select_lex->options & SELECT_DISTINCT)
+ {
+ subq_select_lex->join->select_distinct= false;
+ subq_select_lex->options&= ~SELECT_DISTINCT;
+ }
+
+ /*
+ Remove GROUP BY if there are no aggregate functions and no HAVING
+ clause
+ */
+ if (subq_select_lex->group_list.elements &&
+ !subq_select_lex->with_sum_func && !subq_select_lex->join->having)
+ {
+ subq_select_lex->join->group_list= NULL;
+ subq_select_lex->group_list.empty();
+ }
+
+ /*
+ TODO: This would prevent processing quries with ORDER BY ... LIMIT
+ therefore we disable this optimization for now.
+ Remove GROUP BY if there are no aggregate functions and no HAVING
+ clause
+ if (subq_select_lex->group_list.elements &&
+ !subq_select_lex->with_sum_func && !subq_select_lex->join->having)
+ {
+ subq_select_lex->join->group_list= NULL;
+ subq_select_lex->group_list.empty();
+ }
+ */
+}
+
+
+/**
Function to setup clauses without sum functions.
*/
inline int setup_without_group(THD *thd, Item **ref_pointer_array,
TABLE_LIST *tables,
- TABLE_LIST *leaves,
+ List<TABLE_LIST> &leaves,
List<Item> &fields,
List<Item> &all_fields,
COND **conds,
@@ -464,6 +539,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).
@@ -502,29 +578,89 @@ JOIN::prepare(Item ***rref_pointer_array,
join_list= &select_lex->top_join_list;
union_part= unit_arg->is_union();
+ if (select_lex->handle_derived(thd->lex, DT_PREPARE))
+ DBUG_RETURN(1);
+
thd->lex->current_select->is_item_list_lookup= 1;
/*
If we have already executed SELECT, then it have not sense to prevent
its table from update (see unique_table())
+ Affects only materialized derived tables.
*/
- if (thd->derived_tables_processing)
- select_lex->exclude_from_table_unique_test= TRUE;
-
/* Check that all tables, fields, conds and order are ok */
-
if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
setup_tables_and_check_access(thd, &select_lex->context, join_list,
- tables_list, &select_lex->leaf_tables,
- FALSE, SELECT_ACL, SELECT_ACL))
+ tables_list, select_lex->leaf_tables,
+ FALSE, SELECT_ACL, SELECT_ACL, FALSE))
DBUG_RETURN(-1);
+
+ /*
+ Permanently remove redundant parts from the query if
+ 1) This is a subquery
+ 2) This is the first time this query is optimized (since the
+ transformation is permanent
+ 3) Not normalizing a view. Removal should take place when a
+ query involving a view is optimized, not when the view
+ is created
+ */
+ if (select_lex->master_unit()->item && // 1)
+ select_lex->first_cond_optimization && // 2)
+ !(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)) // 3)
+ {
+ remove_redundant_subquery_clauses(select_lex);
+ }
+
+ /*
+ TRUE if the SELECT list mixes elements with and without grouping,
+ and there is no GROUP BY clause. Mixing non-aggregated fields with
+ aggregate functions in the SELECT list is a MySQL exptenstion that
+ is allowed only if the ONLY_FULL_GROUP_BY sql mode is not set.
+ */
+ bool mixed_implicit_grouping= false;
+ if ((~thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) &&
+ select_lex->with_sum_func && !group_list)
+ {
+ List_iterator_fast <Item> select_it(fields_list);
+ Item *select_el; /* Element of the SELECT clause, can be an expression. */
+ bool found_field_elem= false;
+ bool found_sum_func_elem= false;
+
+ while ((select_el= select_it++))
+ {
+ if (select_el->with_sum_func)
+ found_sum_func_elem= true;
+ if (select_el->with_field)
+ found_field_elem= true;
+ if (found_sum_func_elem && found_field_elem)
+ {
+ mixed_implicit_grouping= true;
+ break;
+ }
+ }
+ }
+
+ table_count= select_lex->leaf_tables.elements;
- TABLE_LIST *table_ptr;
- for (table_ptr= select_lex->leaf_tables;
- table_ptr;
- table_ptr= table_ptr->next_leaf)
- tables++;
+ TABLE_LIST *tbl;
+ List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
+ while ((tbl= li++))
+ {
+ //table_count++; /* Count the number of tables in the join. */
+ /*
+ If the query uses implicit grouping where the select list contains both
+ aggregate functions and non-aggregate fields, any non-aggregated field
+ may produce a NULL value. Set all fields of each table as nullable before
+ semantic analysis to take into account this change of nullability.
+
+ Note: this loop doesn't touch tables inside merged semi-joins, because
+ subquery-to-semijoin conversion has not been done yet. This is intended.
+ */
+ if (mixed_implicit_grouping)
+ tbl->table->maybe_null= 1;
+ }
- if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
+ if ((wild_num && setup_wild(thd, tables_list, fields_list, &all_fields,
+ wild_num)) ||
select_lex->setup_ref_array(thd, og_num) ||
setup_fields(thd, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
&all_fields, 1) ||
@@ -542,6 +678,13 @@ JOIN::prepare(Item ***rref_pointer_array,
thd->where="having clause";
thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
select_lex->having_fix_field= 1;
+ /*
+ Wrap alone field in HAVING clause in case it will be outer field of subquery
+ which need persistent pointer on it, but having could be changed by optimizer
+ */
+ if (having->type() == Item::REF_ITEM &&
+ ((Item_ref *)having)->ref_type() == Item_ref::REF)
+ wrap_ident(thd, &having);
bool having_fix_rc= (!having->fixed &&
(having->fix_fields(thd, &having) ||
having->check_cols(1)));
@@ -552,25 +695,13 @@ JOIN::prepare(Item ***rref_pointer_array,
DBUG_RETURN(-1); /* purecov: inspected */
thd->lex->allow_sum_func= save_allow_sum_func;
}
-
- if (!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) &&
- !(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)
{
@@ -645,15 +776,15 @@ JOIN::prepare(Item ***rref_pointer_array,
}
}
- if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
- DBUG_RETURN(-1);
-
-
/*
Check if there are references to un-aggregated columns when computing
aggregate functions with implicit grouping (there is no GROUP BY).
*/
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && !group_list &&
+ !(select_lex->master_unit()->item &&
+ select_lex->master_unit()->item->is_in_predicate() &&
+ ((Item_in_subselect*)select_lex->master_unit()->item)->
+ test_set_strategy(SUBS_MAXMIN_INJECTED)) &&
select_lex->non_agg_field_used() &&
select_lex->agg_func_used())
{
@@ -708,11 +839,36 @@ JOIN::prepare(Item ***rref_pointer_array,
if (!procedure && result && result->prepare(fields_list, unit_arg))
goto err; /* purecov: inspected */
+ unit= unit_arg;
+ if (prepare_stage2())
+ goto err;
+
+ DBUG_RETURN(0); // All OK
+
+err:
+ delete procedure; /* purecov: inspected */
+ procedure= 0;
+ DBUG_RETURN(-1); /* purecov: inspected */
+}
+
+
+/**
+ Second phase of prepare where we collect some statistic.
+
+ @details
+ We made this part separate to be able recalculate some statistic after
+ transforming subquery on optimization phase.
+*/
+
+bool JOIN::prepare_stage2()
+{
+ bool res= TRUE;
+ DBUG_ENTER("JOIN::prepare_stage2");
+
/* Init join struct */
count_field_types(select_lex, &tmp_table_param, all_fields, 0);
ref_pointer_array_size= all_fields.elements*sizeof(Item*);
this->group= group_list != 0;
- unit= unit_arg;
if (tmp_table_param.sum_func_count && !group_list)
implicit_grouping= TRUE;
@@ -729,94 +885,9 @@ JOIN::prepare(Item ***rref_pointer_array,
if (alloc_func_list())
goto err;
- DBUG_RETURN(0); // All OK
-
+ res= FALSE;
err:
- delete procedure; /* purecov: inspected */
- procedure= 0;
- DBUG_RETURN(-1); /* purecov: inspected */
-}
-
-
-/*
- 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;
- }
- }
+ DBUG_RETURN(res); /* purecov: inspected */
}
@@ -835,23 +906,59 @@ 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");
+ do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
// to prevent double initialization on EXPLAIN
if (optimized)
DBUG_RETURN(0);
optimized= 1;
-
thd_proc_info(thd, "optimizing");
+
+ set_allowed_join_cache_types();
+
+ /* Run optimize phase for all derived tables/views used in this SELECT. */
+ if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE))
+ DBUG_RETURN(1);
+
+ if (select_lex->first_cond_optimization)
+ {
+ //Do it only for the first execution
+ /* Merge all mergeable derived tables/views in this SELECT. */
+ if (select_lex->handle_derived(thd->lex, DT_MERGE))
+ DBUG_RETURN(TRUE);
+ table_count= select_lex->leaf_tables.elements;
+ select_lex->update_used_tables();
+ }
+
+ if (transform_max_min_subquery())
+ DBUG_RETURN(1); /* purecov: inspected */
+
+ if (select_lex->first_cond_optimization)
+ {
+ /* 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); */
+ select_lex->update_used_tables();
+
+ }
+
+ eval_select_list_used_tables();
+
+ table_count= select_lex->leaf_tables.elements;
+
+ if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
+ DBUG_RETURN(-1);
+
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 */
select_limit= unit->select_limit_cnt;
if (having || (select_options & OPTION_FOUND_ROWS))
select_limit= HA_POS_ERROR;
- do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
- // Ignore errors of execution if option IGNORE present
- if (thd->lex->ignore)
- thd->lex->current_select->no_error= 1;
#ifdef HAVE_REF_TO_FIELDS // Not done yet
/* Add HAVING to WHERE if possible */
if (having && !group_list && !sum_func_count)
@@ -874,7 +981,8 @@ JOIN::optimize()
}
}
#endif
- SELECT_LEX *sel= thd->lex->current_select;
+
+ SELECT_LEX *sel= select_lex;
if (sel->first_cond_optimization)
{
/*
@@ -891,16 +999,25 @@ 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);
+ if (select_lex->save_leaf_tables(thd))
+ DBUG_RETURN(1);
build_bitmap_for_nested_joins(join_list, 0);
sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0;
+ sel->where= conds;
+
if (arena)
thd->restore_active_arena(arena, &backup);
}
+
+ if (setup_jtbm_semi_joins(this, join_list, &conds))
+ DBUG_RETURN(1);
- conds= optimize_cond(this, conds, join_list, &cond_value);
+ conds= optimize_cond(this, conds, join_list, FALSE,
+ &cond_value, &cond_equal);
+
if (thd->is_error())
{
error= 1;
@@ -909,7 +1026,9 @@ JOIN::optimize()
}
{
- having= optimize_cond(this, having, join_list, &having_value);
+ having= optimize_cond(this, having, join_list, TRUE,
+ &having_value, &having_equal);
+
if (thd->is_error())
{
error= 1;
@@ -917,10 +1036,17 @@ JOIN::optimize()
DBUG_RETURN(1);
}
if (select_lex->where)
+ {
select_lex->cond_value= cond_value;
+ if (sel->where != conds && cond_value == Item::COND_OK)
+ thd->change_item_tree(&sel->where, conds);
+ }
if (select_lex->having)
+ {
select_lex->having_value= having_value;
-
+ if (sel->having != having && having_value == Item::COND_OK)
+ thd->change_item_tree(&sel->having, having);
+ }
if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE ||
(!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS)))
{ /* Impossible cond */
@@ -928,16 +1054,17 @@ JOIN::optimize()
"Impossible HAVING" : "Impossible WHERE"));
zero_result_cause= having_value == Item::COND_FALSE ?
"Impossible HAVING" : "Impossible WHERE";
- tables= 0;
+ table_count= top_join_tab_count= 0;
error= 0;
- DBUG_RETURN(0);
+ goto setup_subq_exit;
}
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
{
TABLE_LIST *tbl;
- for (tbl= select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
+ List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
+ while ((tbl= li++))
{
/*
If tbl->embedding!=NULL that means that this table is in the inner
@@ -974,13 +1101,14 @@ JOIN::optimize()
*/
if ((res=opt_sum_query(thd, select_lex->leaf_tables, all_fields, conds)))
{
+ DBUG_ASSERT(res >= 0);
if (res == HA_ERR_KEY_NOT_FOUND)
{
DBUG_PRINT("info",("No matching min/max row"));
zero_result_cause= "No matching min/max row";
- tables= 0;
+ table_count= top_join_tab_count= 0;
error=0;
- DBUG_RETURN(0);
+ goto setup_subq_exit;
}
if (res > 1)
{
@@ -988,18 +1116,11 @@ JOIN::optimize()
DBUG_PRINT("error",("Error from opt_sum_query"));
DBUG_RETURN(1);
}
- if (res < 0)
- {
- DBUG_PRINT("info",("No matching min/max row"));
- zero_result_cause= "No matching min/max row";
- tables= 0;
- error=0;
- DBUG_RETURN(0);
- }
+
DBUG_PRINT("info",("Select tables optimized away"));
zero_result_cause= "Select tables optimized away";
tables_list= 0; // All tables resolved
- const_tables= tables;
+ const_tables= top_join_tab_count= table_count;
/*
Extract all table-independent conditions and replace the WHERE
clause with them. All other conditions were computed by opt_sum_query
@@ -1013,7 +1134,8 @@ 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(thd, conds, PSEUDO_TABLE_BITS, 0, -1,
+ FALSE, FALSE);
DBUG_EXECUTE("where",
print_where(table_independent_conds,
"where after opt_sum_query()",
@@ -1026,7 +1148,7 @@ JOIN::optimize()
{
DBUG_PRINT("info",("No tables"));
error= 0;
- DBUG_RETURN(0);
+ goto setup_subq_exit;
}
error= -1; // Error is sent to client
sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
@@ -1040,6 +1162,9 @@ JOIN::optimize()
DBUG_RETURN(1);
}
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_WITH_KEYS))
+ drop_unused_derived_keys();
+
if (rollup.state != ROLLUP::STATE_NONE)
{
if (rollup_process_const_fields())
@@ -1051,7 +1176,7 @@ JOIN::optimize()
else
{
/* Remove distinct if only const tables */
- select_distinct= select_distinct && (const_tables != tables);
+ select_distinct= select_distinct && (const_tables != table_count);
}
thd_proc_info(thd, "preparing");
@@ -1067,7 +1192,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 &&
@@ -1095,7 +1220,10 @@ JOIN::optimize()
}
reset_nj_counters(this, join_list);
- make_outerjoin_info(this);
+ if (make_outerjoin_info(this))
+ {
+ DBUG_RETURN(1);
+ }
/*
Among the equal fields belonging to the same multiple equality
@@ -1105,7 +1233,8 @@ JOIN::optimize()
*/
if (conds)
{
- conds= substitute_for_best_equal_field(conds, cond_equal, map2table);
+ conds= substitute_for_best_equal_field(NO_PARTICULAR_TAB, conds,
+ cond_equal, map2table);
conds->update_used_tables();
DBUG_EXECUTE("where",
print_where(conds,
@@ -1114,20 +1243,77 @@ JOIN::optimize()
}
/*
- Permorm the the optimization on fields evaluation mentioned above
+ Perform the optimization on fields evaluation mentioned above
for all on expressions.
- */
- for (JOIN_TAB *tab= join_tab + const_tables; tab < join_tab + tables ; tab++)
+ */
+ for (JOIN_TAB *tab= first_linear_tab(this, WITHOUT_CONST_TABLES); tab;
+ tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
{
if (*tab->on_expr_ref)
{
- *tab->on_expr_ref= substitute_for_best_equal_field(*tab->on_expr_ref,
+ *tab->on_expr_ref= substitute_for_best_equal_field(NO_PARTICULAR_TAB,
+ *tab->on_expr_ref,
tab->cond_equal,
map2table);
(*tab->on_expr_ref)->update_used_tables();
}
}
+ /*
+ Perform the optimization on fields evaliation mentioned above
+ for all used ref items.
+ */
+ for (JOIN_TAB *tab= first_linear_tab(this, WITHOUT_CONST_TABLES); tab;
+ tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
+ {
+ uint key_copy_index=0;
+ for (uint i=0; i < tab->ref.key_parts; i++)
+ {
+ Item **ref_item_ptr= tab->ref.items+i;
+ Item *ref_item= *ref_item_ptr;
+ if (!ref_item->used_tables() && !(select_options & SELECT_DESCRIBE))
+ continue;
+ COND_EQUAL *equals= cond_equal;
+ JOIN_TAB *first_inner= tab->first_inner;
+ while (equals)
+ {
+ ref_item= substitute_for_best_equal_field(tab, ref_item,
+ equals, map2table);
+ if (first_inner)
+ {
+ equals= first_inner->cond_equal;
+ first_inner= first_inner->first_upper;
+ }
+ else
+ equals= 0;
+ }
+ ref_item->update_used_tables();
+ if (*ref_item_ptr != ref_item)
+ {
+ *ref_item_ptr= ref_item;
+ Item *item= ref_item->real_item();
+ store_key *key_copy= tab->ref.key_copy[key_copy_index];
+ if (key_copy->type() == store_key::FIELD_STORE_KEY)
+ {
+ if (item->basic_const_item())
+ {
+ /* It is constant propagated here */
+ tab->ref.key_copy[key_copy_index]=
+ new store_key_const_item(*tab->ref.key_copy[key_copy_index],
+ item);
+ }
+ else
+ {
+ store_key_field *field_copy= ((store_key_field *)key_copy);
+ DBUG_ASSERT(item->type() == Item::FIELD_ITEM);
+ field_copy->change_source_field((Item_field *) item);
+ }
+ }
+ }
+ key_copy_index++;
+ }
+ }
+
if (conds && const_table_map != found_const_table_map &&
(select_options & SELECT_DESCRIBE))
{
@@ -1138,7 +1324,8 @@ JOIN::optimize()
{
zero_result_cause=
"Impossible WHERE noticed after reading const tables";
- DBUG_RETURN(0); // error == 0
+ select_lex->mark_const_derived(zero_result_cause);
+ goto setup_subq_exit;
}
error= -1; /* if goto err */
@@ -1173,7 +1360,7 @@ JOIN::optimize()
The FROM clause must contain a single non-constant table.
*/
- if (tables - const_tables == 1 && (group_list || select_distinct) &&
+ if (table_count - const_tables == 1 && (group_list || select_distinct) &&
!tmp_table_param.sum_func_count &&
(!join_tab[const_tables].select ||
!join_tab[const_tables].select->quick ||
@@ -1224,7 +1411,7 @@ JOIN::optimize()
if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE)
select_distinct=0;
}
- else if (select_distinct && tables - const_tables == 1 &&
+ else if (select_distinct && table_count - const_tables == 1 &&
rollup.state == ROLLUP::STATE_NONE)
{
/*
@@ -1328,7 +1515,7 @@ JOIN::optimize()
order=0;
// Can't use sort on head table if using join buffering
- if (full_join)
+ if (full_join || hash_join)
{
TABLE *stable= (sort_by_table == (TABLE *) 1 ?
join_tab[const_tables].table : sort_by_table);
@@ -1345,93 +1532,39 @@ JOIN::optimize()
}
}
+ need_tmp= test_if_need_tmp_table();
+
/*
- Check if we need to create a temporary table.
- This has to be done if all tables are not already read (const tables)
- and one of the following conditions holds:
- - We are using DISTINCT (simple distinct's are already optimized away)
- - We are using an ORDER BY or GROUP BY on fields not in the first table
- - We are using different ORDER BY and GROUP BY orders
- - The user wants us to buffer the result.
- When the WITH ROLLUP modifier is present, we cannot skip temporary table
- creation for the DISTINCT clause just because there are only const tables.
+ 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.
*/
- need_tmp= ((const_tables != tables &&
- ((select_distinct || !simple_order || !simple_group) ||
- (group_list && order) ||
- 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));
+ no_jbuf_after= 1 ? table_count : 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)));
- }
+ if (optimize_unflattened_subqueries())
+ 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
@@ -1440,13 +1573,16 @@ JOIN::optimize()
*/
if (need_tmp || select_distinct || group_list || order)
{
- for (uint i = const_tables; i < tables; i++)
- join_tab[i].table->prepare_for_position();
+ for (uint i= 0; i < table_count; i++)
+ {
+ if (!(table[i]->map & const_table_map))
+ table[i]->prepare_for_position();
+ }
}
DBUG_EXECUTE("info",TEST_join(this););
- if (const_tables != tables)
+ if (const_tables != table_count)
{
/*
Because filesort always does a full table scan or a quick range scan
@@ -1502,7 +1638,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;
@@ -1516,7 +1652,7 @@ JOIN::optimize()
if (select_options & SELECT_DESCRIBE)
{
error= 0;
- DBUG_RETURN(0);
+ goto derived_exit;
}
having= 0;
@@ -1534,6 +1670,41 @@ JOIN::optimize()
if (join_tab->is_using_loose_index_scan())
tmp_table_param.precomputed_group_by= TRUE;
+ error= 0;
+
+ DBUG_RETURN(0);
+
+setup_subq_exit:
+ /* Choose an execution strategy for this JOIN. */
+ if (!tables_list || !table_count)
+ choose_tableless_subquery_plan();
+ /*
+ Even with zero matching rows, subqueries in the HAVING clause may
+ need to be evaluated if there are aggregate functions in the query.
+ */
+ if (optimize_unflattened_subqueries())
+ DBUG_RETURN(1);
+ error= 0;
+
+derived_exit:
+ select_lex->mark_const_derived(zero_result_cause);
+ DBUG_RETURN(0);
+}
+
+
+/**
+ Create and initialize objects neeed for the execution of a query plan.
+ Evaluate constant expressions not evaluated during optimization.
+*/
+
+int JOIN::init_execution()
+{
+ DBUG_ENTER("JOIN::init_execution");
+
+ DBUG_ASSERT(optimized);
+ DBUG_ASSERT(!(select_options & SELECT_DESCRIBE));
+ initialized= true;
+
/* Create a tmp table if distinct or if the sort is too complicated */
if (need_tmp)
{
@@ -1566,7 +1737,7 @@ JOIN::optimize()
select_options,
tmp_rows_limit,
(char *) "")))
- {
+ {
DBUG_RETURN(1);
}
@@ -1627,8 +1798,8 @@ JOIN::optimize()
if (exec_tmp_table1->distinct)
{
- table_map used_tables= thd->lex->used_tables;
- JOIN_TAB *last_join_tab= join_tab+tables-1;
+ table_map used_tables= select_list_used_tables;
+ JOIN_TAB *last_join_tab= join_tab + top_join_tab_count - 1;
do
{
if (used_tables & last_join_tab->table->map)
@@ -1652,12 +1823,101 @@ JOIN::optimize()
DBUG_RETURN(-1); /* purecov: inspected */
}
- 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= first_linear_tab(this, WITHOUT_CONST_TABLES);
+ tab; tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
+ {
+ 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);
+}
+
+
+/**
Restore values in temporary join.
*/
void JOIN::restore_tmp()
@@ -1668,6 +1928,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)
+ {
+ size_t 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((size_t)needed_space);
+
+ return FALSE;
+}
+
+
int
JOIN::reinit()
{
@@ -1693,16 +2009,22 @@ 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);
if (join_tab_save)
- memcpy(join_tab, join_tab_save, sizeof(JOIN_TAB) * tables);
+ memcpy(join_tab, join_tab_save, sizeof(JOIN_TAB) * table_count);
/* need to reset ref access state (see join_read_key) */
if (join_tab)
- for (uint i= 0; i < tables; i++)
- join_tab[i].ref.key_err= TRUE;
+ {
+ for (JOIN_TAB *tab= first_linear_tab(this, WITH_CONST_TABLES); tab;
+ tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
+ {
+ tab->ref.key_err= TRUE;
+ }
+ }
if (tmp_join)
restore_tmp();
@@ -1759,7 +2081,7 @@ JOIN::save_join_tab()
if (!join_tab_save && select_lex->master_unit()->uncacheable)
{
if (!(join_tab_save= (JOIN_TAB*)thd->memdup((uchar*) join_tab,
- sizeof(JOIN_TAB) * tables)))
+ sizeof(JOIN_TAB) * table_count)))
return 1;
}
return 0;
@@ -1799,7 +2121,7 @@ JOIN::exec()
}
(void) result->prepare2(); // Currently, this cannot fail.
- if (!tables_list && (tables || !select_lex->with_sum_func))
+ if (!tables_list && (table_count || !select_lex->with_sum_func))
{ // Only test of functions
if (select_options & SELECT_DESCRIBE)
select_describe(this, FALSE, FALSE, FALSE,
@@ -1852,9 +2174,28 @@ JOIN::exec()
FOUND_ROWS() may be called. Never reset the examined row count here.
It must be accumulated from all join iterations of all join parts.
*/
- if (tables)
+ if (table_count)
thd->limit_found_rows= 0;
+ /*
+ Evaluate expensive constant conditions that were not evaluated during
+ optimization. Do not evaluate them for EXPLAIN statements as these
+ condtions may be arbitrarily costly, and because the optimize phase
+ might not have produced a complete executable plan for EXPLAINs.
+ */
+ if (exec_const_cond && !(select_options & SELECT_DESCRIBE) &&
+ !exec_const_cond->val_int())
+ zero_result_cause= "Impossible WHERE noticed after reading const tables";
+
+ /*
+ We've called exec_const_cond->val_int(). This may have caused an error.
+ */
+ if (thd->is_error())
+ {
+ error= thd->is_error();
+ DBUG_VOID_RETURN;
+ }
+
if (zero_result_cause)
{
(void) return_zero_rows(this, result, select_lex->leaf_tables,
@@ -1862,10 +2203,31 @@ JOIN::exec()
send_row_on_empty_set(),
select_options,
zero_result_cause,
- having, all_fields);
+ having ? having : tmp_having, all_fields);
DBUG_VOID_RETURN;
}
+ /*
+ Evaluate all constant expressions with subqueries in the ORDER/GROUP clauses
+ to make sure that all subqueries return a single row. The evaluation itself
+ will trigger an error if that is not the case.
+ */
+ if (exec_const_order_group_cond.elements &&
+ !(select_options & SELECT_DESCRIBE))
+ {
+ List_iterator_fast<Item> const_item_it(exec_const_order_group_cond);
+ Item *cur_const_item;
+ while ((cur_const_item= const_item_it++))
+ {
+ cur_const_item->val_str(&cur_const_item->str_value);
+ if (thd->is_error())
+ {
+ error= thd->is_error();
+ DBUG_VOID_RETURN;
+ }
+ }
+ }
+
if ((this->select_lex->options & OPTION_SCHEMA_TABLE) &&
get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC))
DBUG_VOID_RETURN;
@@ -1889,7 +2251,7 @@ JOIN::exec()
}
if (order &&
(order != group_list || !(select_options & SELECT_BIG_RESULT)) &&
- (const_tables == tables ||
+ (const_tables == table_count ||
((simple_order || skip_sort_order) &&
test_if_skip_sort_order(&join_tab[const_tables], order,
select_limit, 0,
@@ -1900,14 +2262,24 @@ JOIN::exec()
select_describe(this, need_tmp,
order != 0 && !skip_sort_order,
select_distinct,
- !tables ? "No tables used" : NullS);
+ !table_count ? "No tables used" : NullS);
DBUG_VOID_RETURN;
}
+ else
+ {
+ /* it's a const select, materialize it. */
+ select_lex->mark_const_derived(zero_result_cause);
+ }
+
+ if (!initialized && init_execution())
+ DBUG_VOID_RETURN;
JOIN *curr_join= this;
List<Item> *curr_all_fields= &all_fields;
List<Item> *curr_fields_list= &fields_list;
TABLE *curr_tmp_table= 0;
+ bool tmp_having_used_tables_updated= FALSE;
+
/*
Initialize examined rows here because the values from all join parts
must be accumulated in examined_row_count. Hence every join
@@ -1931,11 +2303,14 @@ JOIN::exec()
curr_tmp_table= exec_tmp_table1;
/* Copy data to the temporary table */
- thd_proc_info(thd, "Copying to tmp table");
+ thd_proc_info(thd, copy_to_tmp_table);
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;
+ curr_join->const_tables != curr_join->table_count)
+ {
+ JOIN_TAB *first_tab= curr_join->join_tab + curr_join->const_tables;
+ first_tab->sorted= test(first_tab->loosescan_match_tab);
+ }
Procedure *save_proc= curr_join->procedure;
tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table, 0);
@@ -2086,7 +2461,6 @@ JOIN::exec()
thd_proc_info(thd, "Copying to group table");
DBUG_PRINT("info", ("%s", thd->proc_info));
- tmp_error= -1;
if (curr_join != this)
{
if (sum_funcs2)
@@ -2106,8 +2480,12 @@ JOIN::exec()
DBUG_VOID_RETURN;
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;
+ curr_join->const_tables != curr_join->table_count)
+ {
+ JOIN_TAB *first_tab= curr_join->join_tab + curr_join->const_tables;
+ first_tab->sorted= test(first_tab->loosescan_match_tab);
+ }
+ tmp_error= -1;
if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
(tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table,
0)))
@@ -2116,7 +2494,7 @@ JOIN::exec()
DBUG_VOID_RETURN;
}
end_read_record(&curr_join->join_tab->read_record);
- curr_join->const_tables= curr_join->tables; // Mark free for cleanup()
+ curr_join->const_tables= curr_join->table_count; // Mark free for cleanup()
curr_join->join_tab[0].table= 0; // Table is freed
// No sum funcs anymore
@@ -2149,12 +2527,22 @@ JOIN::exec()
if (curr_tmp_table->distinct)
curr_join->select_distinct=0; /* Each row is unique */
+
+ /*
+ curr_join->join_free() will call JOIN::cleanup(full=TRUE). It will not
+ be safe to call update_used_tables() after that.
+ */
+ if (curr_join->tmp_having)
+ {
+ curr_join->tmp_having->update_used_tables();
+ tmp_having_used_tables_updated= TRUE;
+ }
+
curr_join->join_free(); /* Free quick selects */
+
if (curr_join->select_distinct && ! curr_join->group_list)
{
thd_proc_info(thd, "Removing duplicates");
- if (curr_join->tmp_having)
- curr_join->tmp_having->update_used_tables();
if (remove_duplicates(curr_join, curr_tmp_table,
*curr_fields_list, curr_join->tmp_having))
DBUG_VOID_RETURN;
@@ -2227,14 +2615,16 @@ JOIN::exec()
! curr_join->sort_and_group)
{
// Some tables may have been const
- curr_join->tmp_having->update_used_tables();
+ if (!tmp_having_used_tables_updated)
+ curr_join->tmp_having->update_used_tables();
JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables];
table_map used_tables= (curr_join->const_table_map |
curr_table->table->map);
- Item* sort_table_cond= make_cond_for_table(curr_join->tmp_having,
+ Item* sort_table_cond= make_cond_for_table(thd, curr_join->tmp_having,
used_tables,
- (table_map) 0);
+ (table_map)0, -1,
+ FALSE, FALSE);
if (sort_table_cond)
{
if (!curr_table->select)
@@ -2248,16 +2638,33 @@ JOIN::exec()
new Item_cond_and(curr_table->select->cond,
sort_table_cond)))
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 (sort_table_cond->type() == Item::COND_ITEM)
+ sort_table_cond= sort_table_cond->copy_andor_structure(thd);
+ 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;
+ }
+ if (curr_table->select->cond && !curr_table->select->cond->fixed)
+ curr_table->select->cond->fix_fields(thd, 0);
+ if (curr_table->pre_idx_push_select_cond &&
+ !curr_table->pre_idx_push_select_cond->fixed)
+ curr_table->pre_idx_push_select_cond->fix_fields(thd, 0);
+
+ curr_table->select->pre_idx_push_select_cond=
+ curr_table->pre_idx_push_select_cond;
+ curr_table->set_select_cond(curr_table->select->cond, __LINE__);
curr_table->select_cond->top_level_item();
DBUG_EXECUTE("where",print_where(curr_table->select->cond,
"select and having",
QT_ORDINARY););
- curr_join->tmp_having= make_cond_for_table(curr_join->tmp_having,
+ curr_join->tmp_having= make_cond_for_table(thd, curr_join->tmp_having,
~ (table_map) 0,
- ~used_tables);
+ ~used_tables, -1,
+ FALSE, FALSE);
DBUG_EXECUTE("where",print_where(curr_join->tmp_having,
"having after sort",
QT_ORDINARY););
@@ -2273,7 +2680,7 @@ JOIN::exec()
WHERE clause for any tables after the sorted one.
*/
JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables+1];
- JOIN_TAB *end_table= &curr_join->join_tab[curr_join->tables];
+ JOIN_TAB *end_table= &curr_join->join_tab[curr_join->top_join_tab_count];
for (; curr_table < end_table ; curr_table++)
{
/*
@@ -2311,7 +2718,7 @@ JOIN::exec()
curr_join->group_list ? TRUE : FALSE))
DBUG_VOID_RETURN;
sortorder= curr_join->sortorder;
- if (curr_join->const_tables != curr_join->tables &&
+ if (curr_join->const_tables != curr_join->table_count &&
!curr_join->join_tab[curr_join->const_tables].table->sort.io_cache)
{
/*
@@ -2333,7 +2740,7 @@ JOIN::exec()
curr_join->fields= curr_fields_list;
curr_join->procedure= procedure;
- if (is_top_level_join() && thd->cursor && tables != const_tables)
+ if (is_top_level_join() && thd->cursor && table_count != const_tables)
{
/*
We are here if this is JOIN::exec for the last select of the main unit
@@ -2400,9 +2807,11 @@ JOIN::destroy()
{
if (join_tab != tmp_join->join_tab)
{
- JOIN_TAB *tab, *end;
- for (tab= join_tab, end= tab+tables ; tab != end ; tab++)
+ for (JOIN_TAB *tab= first_linear_tab(this, WITH_CONST_TABLES); tab;
+ tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
+ {
tab->cleanup();
+ }
}
tmp_join->tmp_join= 0;
/*
@@ -2415,6 +2824,7 @@ JOIN::destroy()
DBUG_RETURN(tmp_join->destroy());
}
cond_equal= 0;
+ having_equal= 0;
cleanup(1);
/* Cleanup items referencing temporary table columns */
@@ -2425,6 +2835,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);
@@ -2433,6 +2844,7 @@ JOIN::destroy()
void JOIN::cleanup_item_list(List<Item> &items) const
{
+ DBUG_ENTER("JOIN::cleanup_item_list");
if (!items.is_empty())
{
List_iterator_fast<Item> it(items);
@@ -2440,6 +2852,7 @@ void JOIN::cleanup_item_list(List<Item> &items) const
while ((item= it++))
item->cleanup();
}
+ DBUG_VOID_RETURN;
}
@@ -2602,6 +3015,7 @@ err:
DBUG_RETURN(join->error);
}
+
/*****************************************************************************
Create JOIN_TABS, make a guess about the table types,
Approximate how many records will be used in each table
@@ -2623,7 +3037,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)
{
@@ -2649,6 +3063,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.
@@ -2659,29 +3074,42 @@ typedef struct st_sargable_param
*/
static bool
-make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
- DYNAMIC_ARRAY *keyuse_array)
+make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
+ COND *conds, DYNAMIC_ARRAY *keyuse_array)
{
- int error;
+ int error= 0;
TABLE *table;
- TABLE_LIST *tables= tables_arg;
uint i,table_count,const_count,key;
table_map found_const_table_map, all_table_map, found_ref, refs;
key_map const_ref, eq_part;
+ bool has_expensive_keyparts;
TABLE **table_vector;
- JOIN_TAB *stat,*stat_end,*s,**stat_ref;
+ JOIN_TAB *stat,*stat_end,*s,**stat_ref, **stat_vector;
KEYUSE *keyuse,*start_keyuse;
table_map outer_join=0;
table_map no_rows_const_tables= 0;
SARGABLE_PARAM *sargables= 0;
- JOIN_TAB *stat_vector[MAX_TABLES+1];
+ List_iterator<TABLE_LIST> ti(tables_list);
+ TABLE_LIST *tables;
DBUG_ENTER("make_join_statistics");
- table_count=join->tables;
- stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*table_count);
- stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
+ LINT_INIT(table); /* inited in all loops */
+ table_count=join->table_count;
+
+ stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*(table_count));
+ stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*
+ (MAX_TABLES + table_count + 1));
+ stat_vector= stat_ref + MAX_TABLES;
table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2));
- if (!stat || !stat_ref || !table_vector)
+ join->positions= new (join->thd->mem_root) POSITION[(table_count+1)];
+ /*
+ best_positions is ok to allocate with alloc() as we copy things to it with
+ memcpy()
+ */
+ join->best_positions= (POSITION*) join->thd->alloc(sizeof(POSITION)*
+ (table_count +1));
+
+ if (join->thd->is_fatal_error)
DBUG_RETURN(1); // Eom /* purecov: inspected */
join->best_ref=stat_vector;
@@ -2690,9 +3118,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
found_const_table_map= all_table_map=0;
const_count=0;
- for (s= stat, i= 0;
- tables;
- s++, tables= tables->next_leaf, i++)
+ for (s= stat, i= 0; (tables= ti++); s++, i++)
{
TABLE_LIST *embedding= tables->embedding;
stat_vector[i]=s;
@@ -2702,7 +3128,8 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
s->needed_reg.init();
table_vector[i]=s->table=table=tables->table;
table->pos_in_table_list= tables;
- error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
+ error= tables->fetch_number_of_rows();
+
#ifdef WITH_PARTITION_STORAGE_ENGINE
const bool no_partitions_used= table->no_partitions_used;
#else
@@ -2717,22 +3144,21 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
goto error;
}
});
-
if (error)
{
table->file->print_error(error, MYF(0));
goto error;
}
table->quick_keys.clear_all();
+ table->intersect_keys.clear_all();
table->reginfo.join_tab=s;
table->reginfo.not_exists_optimize=0;
bzero((char*) table->const_key_parts, sizeof(key_part_map)*table->s->keys);
all_table_map|= table->map;
+ s->preread_init_done= FALSE;
s->join=join;
- s->info=0; // For describe
s->dependent= tables->dep_tables;
- s->key_dependent= 0;
if (tables->schema_table)
table->file->stats.records= 2;
table->quick_condition_rows= table->file->stats.records;
@@ -2741,7 +3167,8 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
if (*s->on_expr_ref)
{
/* s is the only inner table of an outer join */
- if (((!table->file->stats.records &&
+ if (!table->is_filled_at_execution() &&
+ ((!table->file->stats.records &&
(table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT)) ||
no_partitions_used) && !embedding)
{ // Empty table
@@ -2760,8 +3187,19 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
{
/* s belongs to a nested join, maybe to several embedded joins */
s->embedding_map= 0;
+ bool inside_an_outer_join= FALSE;
do
{
+ /*
+ If this is a semi-join nest, skip it, and proceed upwards. Maybe
+ we're in some outer join nest
+ */
+ if (embedding->sj_on_expr)
+ {
+ embedding= embedding->embedding;
+ continue;
+ }
+ inside_an_outer_join= TRUE;
NESTED_JOIN *nested_join= embedding->nested_join;
s->embedding_map|=nested_join->nj_map;
s->dependent|= embedding->dep_tables;
@@ -2769,9 +3207,11 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
outer_join|= nested_join->used_tables;
}
while (embedding);
- continue;
+ if (inside_an_outer_join)
+ continue;
}
- if ((table->s->system ||
+ if (!table->is_filled_at_execution() &&
+ (table->s->system ||
(table->file->stats.records <= 1 &&
(table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT)) ||
no_partitions_used) &&
@@ -2781,7 +3221,16 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
set_position(join,const_count++,s,(KEYUSE*) 0);
no_rows_const_tables |= table->map;
}
+
+ /* SJ-Materialization handling: */
+ if (table->pos_in_table_list->jtbm_subselect &&
+ table->pos_in_table_list->jtbm_subselect->is_jtbm_const_tab)
+ {
+ set_position(join,const_count++,s,(KEYUSE*) 0);
+ no_rows_const_tables |= table->map;
+ }
}
+
stat_vector[i]=0;
join->outer_join=outer_join;
@@ -2805,6 +3254,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
if (bitmap_is_set(stat[j].dependent, i) &&
bitmap_is_set(stat[i].dependent, k))
bitmap_set_bit(stat[j].dependent, k);
+ }
}
}
*/
@@ -2825,7 +3275,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
{
if (s->dependent & s->table->map)
{
- join->tables=0; // Don't use join->table
+ join->table_count=0; // Don't use join->table
my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
goto error;
}
@@ -2834,10 +3284,24 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
}
if (conds || outer_join)
- if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
- conds, join->cond_equal,
- ~outer_join, join->select_lex, &sargables))
+ {
+ if (update_ref_and_keys(join->thd, keyuse_array, stat, join->table_count,
+ conds, ~outer_join, join->select_lex, &sargables))
goto error;
+ /*
+ Keyparts without prefixes may be useful if this JOIN is a subquery, and
+ if the subquery may be executed via the IN-EXISTS strategy.
+ */
+ bool skip_unprefixed_keyparts=
+ !(join->is_in_subquery() &&
+ ((Item_in_subselect*)join->unit->item)->test_strategy(SUBS_IN_TO_EXISTS));
+
+ if (keyuse_array->elements &&
+ sort_and_filter_keyuse(join->thd, keyuse_array,
+ skip_unprefixed_keyparts))
+ goto error;
+ DBUG_EXECUTE("opt", print_keyuse_array(keyuse_array););
+ }
join->const_table_map= no_rows_const_tables;
join->const_tables= const_count;
@@ -2884,6 +3348,9 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
{
table=s->table;
+ if (table->is_filled_at_execution())
+ continue;
+
/*
If equi-join condition by a key is null rejecting and after a
substitution of a const table the key value happens to be null
@@ -2904,7 +3371,8 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
*/
while (keyuse->table == table)
{
- if (!(keyuse->val->used_tables() & ~join->const_table_map) &&
+ if (!keyuse->is_for_hash_join() &&
+ !(keyuse->val->used_tables() & ~join->const_table_map) &&
keyuse->val->is_null() && keyuse->null_rejecting)
{
s->type= JT_CONST;
@@ -2925,7 +3393,9 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
continue;
if (table->file->stats.records <= 1L &&
(table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
- !table->pos_in_table_list->embedding)
+ !table->pos_in_table_list->embedding &&
+ !((outer_join & table->map) &&
+ (*s->on_expr_ref)->is_expensive()))
{ // system table
int tmp= 0;
s->type=JT_SYSTEM;
@@ -2947,19 +3417,29 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
s->type= JT_REF;
while (keyuse->table == table)
{
+ if (keyuse->is_for_hash_join())
+ {
+ keyuse++;
+ continue;
+ }
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();
eq_part.clear_all();
+ has_expensive_keyparts= false;
do
{
if (keyuse->val->type() != Item::NULL_ITEM && !keyuse->optimize)
{
if (!((~found_const_table_map) & keyuse->used_tables))
+ {
const_ref.set_bit(keyuse->keypart);
+ if (keyuse->val->is_expensive())
+ has_expensive_keyparts= true;
+ }
else
refs|=keyuse->used_tables;
eq_part.set_bit(keyuse->keypart);
@@ -2967,20 +3447,30 @@ 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)
{
- if (const_ref == eq_part)
+ if (const_ref == eq_part &&
+ !has_expensive_keyparts &&
+ !((outer_join & table->map) &&
+ (*s->on_expr_ref)->is_expensive()))
{ // Found everything for ref.
int tmp;
ref_changed = 1;
s->type= JT_CONST;
join->const_table_map|=table->map;
set_position(join,const_count++,s,start_keyuse);
- if (create_ref_for_key(join, s, start_keyuse,
+ if (create_ref_for_key(join, s, start_keyuse, FALSE,
found_const_table_map))
goto error;
if ((tmp=join_read_const_table(s,
@@ -3003,7 +3493,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.
@@ -3028,15 +3518,27 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
for (s=stat ; s < stat_end ; s++)
{
+ s->startup_cost= 0;
if (s->type == JT_SYSTEM || s->type == JT_CONST)
{
/* Only one matching row */
- s->found_records=s->records=s->read_time=1; s->worst_seeks=1.0;
+ s->found_records= s->records= 1;
+ s->read_time=1.0;
+ s->worst_seeks=1.0;
continue;
}
/* Approximate found rows and time to read them */
- s->found_records=s->records=s->table->file->stats.records;
- s->read_time=(ha_rows) s->table->file->scan_time();
+ if (s->table->is_filled_at_execution())
+ {
+ get_delayed_table_estimates(s->table, &s->records, &s->read_time,
+ &s->startup_cost);
+ s->found_records= s->records;
+ table->quick_condition_rows=s->records;
+ }
+ else
+ {
+ s->scan_time();
+ }
/*
Set a max range of how many seeks we can expect when using keys
@@ -3053,9 +3555,21 @@ 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).
+ Don't do range analysis for materialized subqueries (4).
+ Don't do range analysis for materialized derived tables (5)
+ */
+ 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)
+ !s->table->is_filled_at_execution() && // (4)
+ !(s->table->pos_in_table_list->derived && // (5)
+ s->table->pos_in_table_list->is_materialized_derived())) // (5)
{
ha_rows records;
SQL_SELECT *select;
@@ -3093,31 +3607,63 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
if (records != HA_POS_ERROR)
{
s->found_records=records;
- s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0);
+ s->read_time= s->quick ? s->quick->read_time : 0.0;
}
delete select;
}
}
+ 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->table= table_vector;
join->const_tables=const_count;
join->found_const_table_map=found_const_table_map;
- /* Find an optimal join order of the non-constant tables. */
- if (join->const_tables != join->tables)
- {
+ if (join->const_tables != join->table_count)
optimize_keyuse(join, keyuse_array);
- if (choose_plan(join, all_table_map & ~join->const_table_map))
- goto error;
- }
- else
+
+ if (optimize_semijoin_nests(join, all_table_map))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+
{
- memcpy((uchar*) join->best_positions,(uchar*) join->positions,
- sizeof(POSITION)*join->const_tables);
- join->best_read=1.0;
+ ha_rows records= 1;
+ SELECT_LEX_UNIT *unit= join->select_lex->master_unit();
+
+ /* Find an optimal join order of the non-constant tables. */
+ if (join->const_tables != join->table_count)
+ {
+ if (choose_plan(join, all_table_map & ~join->const_table_map))
+ goto error;
+ }
+ else
+ {
+ memcpy((uchar*) join->best_positions,(uchar*) join->positions,
+ sizeof(POSITION)*join->const_tables);
+ join->record_count= 1.0;
+ join->best_read=1.0;
+ }
+
+ if (!(join->select_options & SELECT_DESCRIBE) &&
+ unit->derived && unit->derived->is_materialized_derived())
+ {
+ /*
+ Calculate estimated number of rows for materialized derived
+ table/view.
+ */
+ for (i= 0; i < join->table_count ; i++)
+ records*= join->best_positions[i].records_read ?
+ (ha_rows)join->best_positions[i].records_read : 1;
+ set_if_smaller(records, unit->select_limit_cnt);
+ join->select_lex->increase_derived_records(records);
+ }
}
+
+ if (join->choose_subquery_plan(all_table_map & ~join->const_table_map))
+ goto error;
+
/* Generate an execution plan from the found optimal join order. */
DBUG_RETURN(join->thd->killed || get_best_combination(join));
@@ -3128,8 +3674,12 @@ error:
may not be assigned yet by this function (which is building join_tab).
Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke.
*/
- for (tables= tables_arg; tables; tables= tables->next_leaf)
- tables->table->reginfo.join_tab= NULL;
+ {
+ TABLE_LIST *table;
+ List_iterator<TABLE_LIST> ti(tables_list);
+ while ((table= ti++))
+ table->table->reginfo.join_tab= NULL;
+ }
DBUG_RETURN (1);
}
@@ -3155,12 +3705,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.
@@ -3283,15 +3830,18 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
{
/* field = expression OR field IS NULL */
old->level= and_level;
- old->optimize= KEY_OPTIMIZE_REF_OR_NULL;
+ if (old->field->maybe_null())
+ {
+ old->optimize= KEY_OPTIMIZE_REF_OR_NULL;
+ /* The referred expression can be NULL: */
+ old->null_rejecting= 0;
+ }
/*
Remember the NOT NULL value unless the value does not depend
on other tables.
*/
if (!old->val->used_tables() && old->val->is_null())
old->val= new_fields->val;
- /* The referred expression can be NULL: */
- old->null_rejecting= 0;
}
else
{
@@ -3324,6 +3874,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
@@ -3346,21 +3942,32 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
*/
static void
-add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
+add_key_field(JOIN *join,
+ KEY_FIELD **key_fields,uint and_level, Item_func *cond,
Field *field, bool eq_func, Item **value, uint num_values,
table_map usable_tables, SARGABLE_PARAM **sargables)
{
- uint exists_optimize= 0;
- if (!(field->flags & PART_KEY_FLAG))
+ uint optimize= 0;
+ if (eq_func &&
+ ((join->is_allowed_hash_join_access() &&
+ field->hash_join_is_possible() &&
+ !(field->table->pos_in_table_list->is_materialized_derived() &&
+ field->table->created)) ||
+ (field->table->pos_in_table_list->is_materialized_derived() &&
+ !field->table->created)))
+ {
+ optimize= KEY_OPTIMIZE_EQ;
+ }
+ else if (!(field->flags & PART_KEY_FLAG))
{
// Don't remove column IS NULL on a LEFT JOIN table
if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
!field->table->maybe_null || field->null_ptr)
return; // Not a key. Skip it
- exists_optimize= KEY_OPTIMIZE_EXISTS;
+ optimize= KEY_OPTIMIZE_EXISTS;
DBUG_ASSERT(num_values == 1);
}
- else
+ if (optimize != KEY_OPTIMIZE_EXISTS)
{
table_map used_tables=0;
bool optimizable=0;
@@ -3377,12 +3984,12 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
!field->table->maybe_null || field->null_ptr)
return; // Can't use left join optimize
- exists_optimize= KEY_OPTIMIZE_EXISTS;
+ optimize= KEY_OPTIMIZE_EXISTS;
}
else
{
JOIN_TAB *stat=field->table->reginfo.join_tab;
- key_map possible_keys=field->key_start;
+ key_map possible_keys=field->get_possible_keys();
possible_keys.intersect(field->table->keys_in_use_for_query);
stat[0].keys.merge(possible_keys); // Add possible keys
@@ -3397,7 +4004,8 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
Field BETWEEN ...
Field IN ...
*/
- stat[0].key_dependent|=used_tables;
+ if (field->flags & PART_KEY_FLAG)
+ stat[0].key_dependent|=used_tables;
bool is_const=1;
for (uint i=0; i<num_values; i++)
@@ -3420,30 +4028,21 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
(*sargables)->arg_value= value;
(*sargables)->num_values= num_values;
}
+
/*
- We can't always use indexes when comparing a string index to a
- number. cmp_type() is checked to allow compare of dates to numbers.
- eq_func is NEVER true when num_values > 1
+ We can't use indexes when comparing a string index to a
+ number or two strings if the effective collation
+ of the operation differ from the field collation.
*/
if (!eq_func)
return;
- if (field->result_type() == STRING_RESULT)
+
+ if (field->cmp_type() == STRING_RESULT)
{
- if ((*value)->result_type() != STRING_RESULT)
- {
- if (field->cmp_type() != (*value)->result_type())
- return;
- }
- else
- {
- /*
- We can't use indexes if the effective collation
- of the operation differ from the field collation.
- */
- if (field->cmp_type() == STRING_RESULT &&
- ((Field_str*)field)->charset() != cond->compare_collation())
+ if ((*value)->cmp_type() != STRING_RESULT)
return;
- }
+ if (((Field_str*)field)->charset() != cond->compare_collation())
+ return;
}
}
}
@@ -3456,8 +4055,8 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
(*key_fields)->field= field;
(*key_fields)->eq_func= eq_func;
(*key_fields)->val= *value;
- (*key_fields)->level= and_level;
- (*key_fields)->optimize= exists_optimize;
+ (*key_fields)->level= and_level;
+ (*key_fields)->optimize= optimize;
/*
If the condition has form "tbl.keypart = othertbl.field" and
othertbl.field can be NULL, there will be no matches if othertbl.field
@@ -3465,11 +4064,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)++;
}
@@ -3496,29 +4103,29 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
*/
static void
-add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
- Item_func *cond, Item_field *field_item,
+add_key_equal_fields(JOIN *join, KEY_FIELD **key_fields, uint and_level,
+ Item_func *cond, Item *field_item,
bool eq_func, Item **val,
uint num_values, table_map usable_tables,
SARGABLE_PARAM **sargables)
{
- Field *field= field_item->field;
- add_key_field(key_fields, and_level, cond, field,
+ Field *field= ((Item_field *) (field_item->real_item()))->field;
+ add_key_field(join, key_fields, and_level, cond, field,
eq_func, val, num_values, usable_tables, sargables);
- Item_equal *item_equal= field_item->item_equal;
+ Item_equal *item_equal= field_item->get_item_equal();
if (item_equal)
{
/*
Add to the set of possible key values every substitution of
the field for an equal field included into item_equal
*/
- Item_equal_iterator it(*item_equal);
- Item_field *item;
- while ((item= it++))
+ Item_equal_fields_iterator it(*item_equal);
+ while (it++)
{
- if (!field->eq(item->field))
+ Field *equal_field= it.get_curr_field();
+ if (!field->eq(equal_field))
{
- add_key_field(key_fields, and_level, cond, item->field,
+ add_key_field(join, key_fields, and_level, cond, equal_field,
eq_func, val, num_values, usable_tables,
sargables);
}
@@ -3543,8 +4150,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())->get_depended_from();
}
@@ -3564,7 +4171,6 @@ is_local_field (Item *field)
The primary reason for having and_level attribute is the OR operation which
uses and_level to mark KEY_FIELDs that should get into the result of the OR
operation
-
*/
static void
@@ -3676,7 +4282,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
if (is_local_field(values[0]))
{
field_item= (Item_field *) (values[0]->real_item());
- add_key_equal_fields(key_fields, *and_level, cond_func,
+ add_key_equal_fields(join, key_fields, *and_level, cond_func,
field_item, equal_func, &values[1],
num_values, usable_tables, sargables);
}
@@ -3690,7 +4296,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
if (is_local_field(values[i]))
{
field_item= (Item_field *) (values[i]->real_item());
- add_key_equal_fields(key_fields, *and_level, cond_func,
+ add_key_equal_fields(join, key_fields, *and_level, cond_func,
field_item, equal_func, values,
1, usable_tables, sargables);
}
@@ -3707,7 +4313,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
values--;
DBUG_ASSERT(cond_func->functype() != Item_func::IN_FUNC ||
cond_func->argument_count() != 2);
- add_key_equal_fields(key_fields, *and_level, cond_func,
+ add_key_equal_fields(join, key_fields, *and_level, cond_func,
(Item_field*) (cond_func->key_item()->real_item()),
0, values,
cond_func->argument_count()-1,
@@ -3722,8 +4328,9 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
if (is_local_field (cond_func->arguments()[0]))
{
- add_key_equal_fields(key_fields, *and_level, cond_func,
- (Item_field*) (cond_func->arguments()[0])->real_item(),
+ add_key_equal_fields(join, key_fields, *and_level, cond_func,
+ (Item_field*) (cond_func->arguments()[0])->
+ real_item(),
equal_func,
cond_func->arguments()+1, 1, usable_tables,
sargables);
@@ -3731,8 +4338,9 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
if (is_local_field (cond_func->arguments()[1]) &&
cond_func->functype() != Item_func::LIKE_FUNC)
{
- add_key_equal_fields(key_fields, *and_level, cond_func,
- (Item_field*) (cond_func->arguments()[1])->real_item(),
+ add_key_equal_fields(join, key_fields, *and_level, cond_func,
+ (Item_field*) (cond_func->arguments()[1])->
+ real_item(),
equal_func,
cond_func->arguments(),1,usable_tables,
sargables);
@@ -3747,17 +4355,17 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
Item *tmp=new Item_null;
if (unlikely(!tmp)) // Should never be true
return;
- add_key_equal_fields(key_fields, *and_level, cond_func,
- (Item_field*) (cond_func->arguments()[0])->real_item(),
- cond_func->functype() == Item_func::ISNULL_FUNC,
+ add_key_equal_fields(join, key_fields, *and_level, cond_func,
+ (Item_field*) (cond_func->arguments()[0])->
+ real_item(),
+ cond_func->functype() == Item_func::ISNULL_FUNC,
&tmp, 1, usable_tables, sargables);
}
break;
case Item_func::OPTIMIZE_EQUAL:
Item_equal *item_equal= (Item_equal *) cond;
Item *const_item= item_equal->get_const();
- Item_equal_iterator it(*item_equal);
- Item_field *item;
+ Item_equal_fields_iterator it(*item_equal);
if (const_item)
{
/*
@@ -3765,9 +4373,10 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
field1=const_item as a condition allowing an index access of the table
with field1 by the keys value of field1.
*/
- while ((item= it++))
+ while (it++)
{
- add_key_field(key_fields, *and_level, cond_func, item->field,
+ Field *equal_field= it.get_curr_field();
+ add_key_field(join, key_fields, *and_level, cond_func, equal_field,
TRUE, &const_item, 1, usable_tables, sargables);
}
}
@@ -3779,17 +4388,18 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
field1=field2 as a condition allowing an index access of the table
with field1 by the keys value of field2.
*/
- Item_equal_iterator fi(*item_equal);
- while ((item= fi++))
+ Item_equal_fields_iterator fi(*item_equal);
+ while (fi++)
{
- Field *field= item->field;
+ Field *field= fi.get_curr_field();
+ Item *item;
while ((item= it++))
{
- if (!field->eq(item->field))
+ Field *equal_field= it.get_curr_field();
+ if (!field->eq(equal_field))
{
- Item *tmp_item= item;
- add_key_field(key_fields, *and_level, cond_func, field,
- TRUE, &tmp_item, 1, usable_tables,
+ add_key_field(join, key_fields, *and_level, cond_func, field,
+ TRUE, &item, 1, usable_tables,
sargables);
}
}
@@ -3809,6 +4419,55 @@ max_part_bit(key_part_map bits)
return found;
}
+
+/**
+ Add a new keuse to the specified array of KEYUSE objects
+
+ @param[in,out] keyuse_array array of keyuses to be extended
+ @param[in] key_field info on the key use occurrence
+ @param[in] key key number for the keyse to be added
+ @param[in] part key part for the keyuse to be added
+
+ @note
+ The function builds a new KEYUSE object for a key use utilizing the info
+ on the left and right parts of the given key use extracted from the
+ structure key_field, the key number and key part for this key use.
+ The built object is added to the dynamic array keyuse_array.
+
+ @retval 0 the built object is succesfully added
+ @retval 1 otherwise
+*/
+
+static bool
+add_keyuse(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field,
+ uint key, uint part)
+{
+ KEYUSE keyuse;
+ Field *field= key_field->field;
+
+ keyuse.table= field->table;
+ keyuse.val= key_field->val;
+ keyuse.key= key;
+ if (!is_hash_join_key_no(key))
+ {
+ keyuse.keypart=part;
+ keyuse.keypart_map= (key_part_map) 1 << part;
+ }
+ else
+ {
+ keyuse.keypart= field->field_index;
+ keyuse.keypart_map= (key_part_map) 0;
+ }
+ 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;
+ return (insert_dynamic(keyuse_array,(uchar*) &keyuse));
+}
+
+
/*
Add all keys with uses 'field' for some keypart
If field->and_level != and_level then only mark key_part as const_part
@@ -3819,11 +4478,10 @@ max_part_bit(key_part_map bits)
*/
static bool
-add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
+add_key_part(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field)
{
Field *field=key_field->field;
TABLE *form= field->table;
- KEYUSE keyuse;
if (key_field->eq_func && !(key_field->optimize & KEY_OPTIMIZE_EXISTS))
{
@@ -3839,20 +4497,24 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
{
if (field->eq(form->key_info[key].key_part[part].field))
{
- keyuse.table= field->table;
- keyuse.val = key_field->val;
- keyuse.key = key;
- keyuse.keypart=part;
- 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.null_rejecting= key_field->null_rejecting;
- keyuse.cond_guard= key_field->cond_guard;
- if (insert_dynamic(keyuse_array,(uchar*) &keyuse))
+ if (add_keyuse(keyuse_array, key_field, key, part))
return TRUE;
}
}
}
+ if (field->hash_join_is_possible() &&
+ (key_field->optimize & KEY_OPTIMIZE_EQ) &&
+ key_field->val->used_tables())
+ {
+ /*
+ If a key use is extracted from an equi-join predicate then it is
+ added not only as a key use for every index whose component can
+ be evalusted utilizing this key use, but also as a key use for
+ hash join. Such key uses are marked with a special key number.
+ */
+ if (add_keyuse(keyuse_array, key_field, get_hash_join_key_no(), 0))
+ return TRUE;
+ }
}
return FALSE;
}
@@ -3920,6 +4582,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);
}
@@ -3932,6 +4595,9 @@ sort_keyuse(KEYUSE *a,KEYUSE *b)
return (int) (a->table->tablenr - b->table->tablenr);
if (a->key != b->key)
return (int) (a->key - b->key);
+ if (a->key == MAX_KEY && b->key == MAX_KEY &&
+ a->used_tables != b->used_tables)
+ return (int) ((ulong) a->used_tables - (ulong) b->used_tables);
if (a->keypart != b->keypart)
return (int) (a->keypart - b->keypart);
// Place const values before other ones
@@ -3984,20 +4650,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);
}
@@ -4024,11 +4704,10 @@ static void add_key_fields_for_nj(JOIN *join, TABLE_LIST *nested_join_table,
static bool
update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
- uint tables, COND *cond, COND_EQUAL *cond_equal,
- table_map normal_tables, SELECT_LEX *select_lex,
- SARGABLE_PARAM **sargables)
+ uint tables, COND *cond, table_map normal_tables,
+ SELECT_LEX *select_lex, SARGABLE_PARAM **sargables)
{
- uint and_level,i,found_eq_constant;
+ uint and_level,i;
KEY_FIELD *key_fields, *end, *field;
uint sz;
uint m= max(select_lex->max_equal_elems,1);
@@ -4068,19 +4747,21 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64))
return TRUE;
+
if (cond)
{
+ KEY_FIELD *saved_field= field;
add_key_fields(join_tab->join, &end, &and_level, cond, normal_tables,
sargables);
for (; field != end ; field++)
{
- if (add_key_part(keyuse,field))
- return TRUE;
+
/* Mark that we can optimize LEFT JOIN */
if (field->val->type() == Item::NULL_ITEM &&
!field->field->real_maybe_null())
field->field->table->reginfo.not_exists_optimize=1;
}
+ field= saved_field;
}
for (i=0 ; i < tables ; i++)
{
@@ -4124,69 +4805,85 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
return TRUE;
}
- /*
- Sort the array of possible keys and remove the following key parts:
- - ref if there is a keypart which is a ref and a const.
- (e.g. if there is a key(a,b) and the clause is a=3 and b=7 and b=t2.d,
- then we skip the key part corresponding to b=t2.d)
- - keyparts without previous keyparts
- (e.g. if there is a key(a,b,c) but only b < 5 (or a=2 and c < 3) is
- used in the query, we drop the partial key parts from consideration).
- Special treatment for ft-keys.
- */
- if (keyuse->elements)
- {
- KEYUSE key_end,*prev,*save_pos,*use;
+ return FALSE;
+}
- my_qsort(keyuse->buffer,keyuse->elements,sizeof(KEYUSE),
- (qsort_cmp) sort_keyuse);
- bzero((char*) &key_end,sizeof(key_end)); /* Add for easy testing */
- if (insert_dynamic(keyuse,(uchar*) &key_end))
- return TRUE;
+/**
+ Sort the array of possible keys and remove the following key parts:
+ - ref if there is a keypart which is a ref and a const.
+ (e.g. if there is a key(a,b) and the clause is a=3 and b=7 and b=t2.d,
+ then we skip the key part corresponding to b=t2.d)
+ - keyparts without previous keyparts
+ (e.g. if there is a key(a,b,c) but only b < 5 (or a=2 and c < 3) is
+ used in the query, we drop the partial key parts from consideration).
+ Special treatment for ft-keys.
+*/
- use=save_pos=dynamic_element(keyuse,0,KEYUSE*);
- prev= &key_end;
- found_eq_constant=0;
- for (i=0 ; i < keyuse->elements-1 ; i++,use++)
+static bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse,
+ bool skip_unprefixed_keyparts)
+{
+ KEYUSE key_end, *prev, *save_pos, *use;
+ uint found_eq_constant, i;
+
+ DBUG_ASSERT(keyuse->elements);
+
+ my_qsort(keyuse->buffer, keyuse->elements, sizeof(KEYUSE),
+ (qsort_cmp) sort_keyuse);
+
+ bzero((char*) &key_end, sizeof(key_end)); /* Add for easy testing */
+ if (insert_dynamic(keyuse, (uchar*) &key_end))
+ return TRUE;
+
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_WITH_KEYS))
+ generate_derived_keys(keyuse);
+
+ use= save_pos= dynamic_element(keyuse,0,KEYUSE*);
+ prev= &key_end;
+ found_eq_constant= 0;
+ for (i=0 ; i < keyuse->elements-1 ; i++,use++)
+ {
+ if (!use->is_for_hash_join())
{
if (!use->used_tables && use->optimize != KEY_OPTIMIZE_REF_OR_NULL)
- use->table->const_key_parts[use->key]|= use->keypart_map;
+ use->table->const_key_parts[use->key]|= use->keypart_map;
if (use->keypart != FT_KEYPART)
{
- if (use->key == prev->key && use->table == prev->table)
- {
- if (prev->keypart+1 < use->keypart ||
- (prev->keypart == use->keypart && found_eq_constant))
- continue; /* remove */
- }
- else if (use->keypart != 0) // First found must be 0
- continue;
+ if (use->key == prev->key && use->table == prev->table)
+ {
+ if ((prev->keypart+1 < use->keypart && skip_unprefixed_keyparts) ||
+ (prev->keypart == use->keypart && found_eq_constant))
+ continue; /* remove */
+ }
+ else if (use->keypart != 0 && skip_unprefixed_keyparts)
+ continue; /* remove - first found must be 0 */
}
- /*
- Old gcc used a memcpy(), which is undefined if save_pos==use:
- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19410
- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39480
- This also disables a valgrind warning, so better to have the test.
- */
- if (save_pos != use)
- *save_pos= *use;
- prev=use;
+ prev= use;
found_eq_constant= !use->used_tables;
- /* Save ptr to first use */
- if (!use->table->reginfo.join_tab->keyuse)
- use->table->reginfo.join_tab->keyuse=save_pos;
use->table->reginfo.join_tab->checked_keys.set_bit(use->key);
- save_pos++;
}
- i=(uint) (save_pos-(KEYUSE*) keyuse->buffer);
- VOID(set_dynamic(keyuse,(uchar*) &key_end,i));
- keyuse->elements=i;
+ /*
+ Old gcc used a memcpy(), which is undefined if save_pos==use:
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19410
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39480
+ This also disables a valgrind warning, so better to have the test.
+ */
+ if (save_pos != use)
+ *save_pos= *use;
+ /* Save ptr to first use */
+ if (!use->table->reginfo.join_tab->keyuse)
+ use->table->reginfo.join_tab->keyuse= save_pos;
+ save_pos++;
}
+ i= (uint) (save_pos-(KEYUSE*) keyuse->buffer);
+ VOID(set_dynamic(keyuse,(uchar*) &key_end,i));
+ keyuse->elements= i;
+
return FALSE;
}
+
/**
Update some values in keyuse for faster choose_plan() loop.
*/
@@ -4211,12 +4908,15 @@ static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
(map= (keyuse->used_tables & ~join->const_table_map &
~OUTER_REF_TABLE_BIT)))
{
- uint tablenr;
- for (tablenr=0 ; ! (map & 1) ; map>>=1, tablenr++) ;
- if (map == 1) // Only one table
+ uint n_tables= my_count_bits(map);
+ if (n_tables == 1) // Only one table
{
- TABLE *tmp_table=join->all_tables[tablenr];
- keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
+ Table_map_iterator it(map);
+ int tablenr= it.next_bit();
+ DBUG_ASSERT(tablenr != Table_map_iterator::BITMAP_END);
+ TABLE *tmp_table=join->table[tablenr];
+ if (tmp_table) // already created
+ keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
}
}
/*
@@ -4229,6 +4929,7 @@ static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
}
+
/**
Discover the indexes that can be used for GROUP BY or DISTINCT queries.
@@ -4304,6 +5005,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];
@@ -4317,6 +5022,35 @@ void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
}
+/* Estimate of the number matching candidates in the joined table */
+
+inline
+ha_rows matching_candidates_in_table(JOIN_TAB *s, bool with_found_constraint)
+{
+ ha_rows records= s->found_records;
+ /*
+ If there is a filtering condition on the table (i.e. ref analyzer found
+ at least one "table.keyXpartY= exprZ", where exprZ refers only to tables
+ preceding this table in the join order we're now considering), then
+ assume that 25% of the rows will be filtered out by this condition.
+
+ This heuristic is supposed to force tables used in exprZ to be before
+ this table in join order.
+ */
+ if (with_found_constraint)
+ records-= records/4;
+
+ /*
+ If applicable, get a more accurate estimate. Don't use the two
+ heuristics at once.
+ */
+ if (s->table->quick_condition_rows != s->found_records)
+ records= s->table->quick_condition_rows;
+
+ return records;
+}
+
+
/**
Find the best access path for an extension of a partial execution
plan and add this path to the plan.
@@ -4334,23 +5068,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;
@@ -4360,12 +5099,24 @@ best_access_path(JOIN *join,
table_map best_ref_depends_map= 0;
double tmp;
ha_rows rec;
+ bool best_uses_jbuf= FALSE;
+ MY_BITMAP *eq_join_set= &s->table->eq_join_set;
+ KEYUSE *hj_start_key= 0;
+
+ disable_jbuf= disable_jbuf || idx == join->const_tables;
+
+ Loose_scan_opt loose_scan_opt;
DBUG_ENTER("best_access_path");
+
+ bitmap_clear_all(eq_join_set);
+ loose_scan_opt.init(join, s, remaining_tables);
+
if (s->keyuse)
{ /* Use key if possible */
+ KEYUSE *keyuse;
+ KEYUSE *start_key=0;
TABLE *table= s->table;
- KEYUSE *keyuse,*start_key=0;
double best_records= DBL_MAX;
uint max_key_part=0;
@@ -4373,19 +5124,41 @@ best_access_path(JOIN *join,
rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE; // Assumed records/key
for (keyuse=s->keyuse ; keyuse->table == table ;)
{
+ KEY *keyinfo;
key_part_map found_part= 0;
table_map found_ref= 0;
uint key= keyuse->key;
- KEY *keyinfo= table->key_info+key;
bool ft_key= (keyuse->keypart == FT_KEYPART);
/* Bitmap of keyparts where the ref access is over 'keypart=const': */
key_part_map const_part= 0;
/* The or-null keypart in ref-or-null access: */
key_part_map ref_or_null_part= 0;
+ if (is_hash_join_key_no(key))
+ {
+ /*
+ Hash join as any join employing join buffer can be used to join
+ only those tables that are joined after the first non const table
+ */
+ if (!(remaining_tables & keyuse->used_tables) &&
+ idx > join->const_tables)
+ {
+ if (!hj_start_key)
+ hj_start_key= keyuse;
+ bitmap_set_bit(eq_join_set, keyuse->keypart);
+ }
+ keyuse++;
+ continue;
+ }
+
+ keyinfo= table->key_info+key;
/* 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;
@@ -4394,12 +5167,13 @@ 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
*/
if (!(remaining_tables & keyuse->used_tables) &&
+ s->access_from_tables_is_allowed(keyuse->used_tables,
+ join->sjm_lookup_tables) &&
!(ref_or_null_part && (keyuse->optimize &
KEY_OPTIMIZE_REF_OR_NULL)))
{
@@ -4407,8 +5181,8 @@ best_access_path(JOIN *join,
if (!(keyuse->used_tables & ~join->const_table_map))
const_part|= keyuse->keypart_map;
- double tmp2= prev_record_reads(join, idx, (found_ref |
- keyuse->used_tables));
+ double tmp2= prev_record_reads(join->positions, idx,
+ (found_ref | keyuse->used_tables));
if (tmp2 < best_prev_record_reads)
{
best_part_found_ref= keyuse->used_tables & ~join->const_table_map;
@@ -4423,6 +5197,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);
@@ -4432,7 +5207,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)
@@ -4447,22 +5222,22 @@ best_access_path(JOIN *join,
Really, there should be records=0.0 (yes!)
but 1.0 would be probably safer
*/
- tmp= prev_record_reads(join, idx, found_ref);
+ tmp= prev_record_reads(join->positions, idx, found_ref);
records= 1.0;
}
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 */
max_key_part= (uint) ~0;
if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
{
- tmp = prev_record_reads(join, idx, found_ref);
+ tmp = prev_record_reads(join->positions, idx, found_ref);
records=1.0;
}
else
@@ -4517,7 +5292,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])
{
@@ -4528,14 +5304,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));
+ tmp*= record_count;
}
}
else
@@ -4695,20 +5468,21 @@ 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));
+ tmp*= record_count;
}
else
tmp= best_time; // Do nothing
}
+
+ DBUG_ASSERT(tmp > 0 || record_count == 0);
+ tmp += s->startup_cost;
+ loose_scan_opt.check_ref_access_part2(key, start_key, records, tmp);
} /* not ft_key */
- 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;
@@ -4717,10 +5491,47 @@ best_access_path(JOIN *join,
best_max_key_part= max_key_part;
best_ref_depends_map= found_ref;
}
- }
+ } /* for each key */
records= best_records;
}
+ /*
+ If there is no key to access the table, but there is an equi-join
+ predicate connecting the table with the privious tables then we
+ consider the possibility of using hash join.
+ We need also to check that:
+ (1) s is inner table of semi-join -> join cache is allowed for semijoins
+ (2) s is inner table of outer join -> join cache is allowed for outer joins
+ */
+ if (idx > join->const_tables && best_key == 0 &&
+ (join->allowed_join_cache_types & JOIN_CACHE_HASHED_BIT) &&
+ join->max_allowed_join_cache_level > 2 &&
+ !bitmap_is_clear_all(eq_join_set) && !disable_jbuf &&
+ (!s->emb_sj_nest ||
+ join->allowed_semijoin_with_cache) && // (1)
+ (!(s->table->map & join->outer_join) ||
+ join->allowed_outer_join_with_cache)) // (2)
+ {
+ double join_sel= 0.1;
+ /* Estimate the cost of the hash join access to the table */
+ ha_rows rnd_records= matching_candidates_in_table(s, found_constraint);
+
+ tmp= s->quick ? s->quick->read_time : s->scan_time();
+ tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
+
+ /* We read the table as many times as join buffer becomes full. */
+ tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
+ record_count /
+ (double) thd->variables.join_buff_size));
+ best_time= tmp +
+ (record_count*join_sel) / TIME_FOR_COMPARE * rnd_records;
+ best= tmp;
+ records= rows2double(rnd_records);
+ best_key= hj_start_key;
+ best_ref_depends_map= 0;
+ best_uses_jbuf= TRUE;
+ }
+
/*
Don't test table scan if it can't be better.
Prefer key lookup if we would use the same key for scanning.
@@ -4730,7 +5541,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
@@ -4748,39 +5559,28 @@ best_access_path(JOIN *join,
Since we have a 'ref' access path, and FORCE INDEX instructs us to
choose it over ALL/index, there is no need to consider a full table
scan.
+ (5) Non-flattenable semi-joins: don't consider doing a scan of temporary
+ table if we had an option to make lookups into it. In real-world cases,
+ lookups are cheaper than full scans, but when the table is small, they
+ can be [considered to be] more expensive, which causes lookups not to
+ be used for cases with small datasets, which is annoying.
*/
if ((records >= s->found_records || best > s->read_time) && // (1)
!(s->quick && best_key && s->quick->index == best_key->key && // (2)
best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2)
!((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3)
! s->table->covering_keys.is_clear_all() && best_key && !s->quick) &&// (3)
- !(s->table->force_index && best_key && !s->quick)) // (4)
+ !(s->table->force_index && best_key && !s->quick) && // (4)
+ !(best_key && s->table->pos_in_table_list->jtbm_subselect)) // (5)
{ // Check full join
- ha_rows rnd_records= s->found_records;
- /*
- If there is a filtering condition on the table (i.e. ref analyzer found
- at least one "table.keyXpartY= exprZ", where exprZ refers only to tables
- preceding this table in the join order we're now considering), then
- assume that 25% of the rows will be filtered out by this condition.
-
- This heuristic is supposed to force tables used in exprZ to be before
- this table in join order.
- */
- if (found_constraint)
- rnd_records-= rnd_records/4;
-
- /*
- If applicable, get a more accurate estimate. Don't use the two
- heuristics at once.
- */
- if (s->table->quick_condition_rows != s->found_records)
- rnd_records= s->table->quick_condition_rows;
+ ha_rows rnd_records= matching_candidates_in_table(s, found_constraint);
/*
Range optimizer never proposes a RANGE if it isn't better
than FULL: so if RANGE is present, it's always preferred to FULL.
Here we estimate its cost.
*/
+
if (s->quick)
{
/*
@@ -4795,12 +5595,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
+ tmp= s->scan_time();
+ if ((s->table->map & join->outer_join) || disable_jbuf) // Can't use join cache
{
/*
For each record we have to:
@@ -4828,6 +5630,7 @@ best_access_path(JOIN *join,
}
}
+ tmp += s->startup_cost;
/*
We estimate the cost of evaluating WHERE clause for found records
as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus
@@ -4835,7 +5638,8 @@ best_access_path(JOIN *join,
*/
if (best == DBL_MAX ||
(tmp + record_count/(double) TIME_FOR_COMPARE*rnd_records <
- best + record_count/(double) TIME_FOR_COMPARE*records))
+ (best_key->is_for_hash_join() ? best_time :
+ best + record_count/(double) TIME_FOR_COMPARE*records)))
{
/*
If the table has a range (s->quick is set) make_join_select()
@@ -4846,15 +5650,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_picker.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 &&
@@ -4866,6 +5676,114 @@ best_access_path(JOIN *join,
}
+/*
+ Find JOIN_TAB's embedding (i.e, parent) subquery.
+ - For merged semi-joins, tables inside the semi-join nest have their
+ semi-join nest as parent. We intentionally ignore results of table
+ pullout action here.
+ - For non-merged semi-joins (JTBM tabs), the embedding subquery is the
+ JTBM join tab itself.
+*/
+
+static TABLE_LIST* get_emb_subq(JOIN_TAB *tab)
+{
+ TABLE_LIST *tlist= tab->table->pos_in_table_list;
+ if (tlist->jtbm_subselect)
+ return tlist;
+ TABLE_LIST *embedding= tlist->embedding;
+ if (!embedding || !embedding->sj_subq_pred)
+ return NULL;
+ return embedding;
+}
+
+
+/*
+ Choose initial table order that "helps" semi-join optimizations.
+
+ The idea is that we should start with the order that is the same as the one
+ we would have had if we had semijoin=off:
+ - Top-level tables go first
+ - subquery tables are grouped together by the subquery they are in,
+ - subquery tables are attached where the subquery predicate would have been
+ attached if we had semi-join off.
+
+ This function relies on join_tab_cmp()/join_tab_cmp_straight() to produce
+ certain pre-liminary ordering, see compare_embedding_subqueries() for its
+ description.
+*/
+
+static void choose_initial_table_order(JOIN *join)
+{
+ TABLE_LIST *emb_subq;
+ JOIN_TAB **tab= join->best_ref + join->const_tables;
+ JOIN_TAB **tabs_end= tab + join->table_count - join->const_tables;
+ /* Find where the top-level JOIN_TABs end and subquery JOIN_TABs start */
+ for (; tab != tabs_end; tab++)
+ {
+ if ((emb_subq= get_emb_subq(*tab)))
+ break;
+ }
+ uint n_subquery_tabs= tabs_end - tab;
+
+ if (!n_subquery_tabs)
+ return;
+
+ /* Copy the subquery JOIN_TABs to a separate array */
+ JOIN_TAB *subquery_tabs[MAX_TABLES];
+ memcpy(subquery_tabs, tab, sizeof(JOIN_TAB*) * n_subquery_tabs);
+
+ JOIN_TAB **last_top_level_tab= tab;
+ JOIN_TAB **subq_tab= subquery_tabs;
+ JOIN_TAB **subq_tabs_end= subquery_tabs + n_subquery_tabs;
+ TABLE_LIST *cur_subq_nest= NULL;
+ for (; subq_tab < subq_tabs_end; subq_tab++)
+ {
+ if (get_emb_subq(*subq_tab)!= cur_subq_nest)
+ {
+ /*
+ Reached the part of subquery_tabs that covers tables in some subquery.
+ */
+ cur_subq_nest= get_emb_subq(*subq_tab);
+
+ /* Determine how many tables the subquery has */
+ JOIN_TAB **last_tab_for_subq;
+ for (last_tab_for_subq= subq_tab;
+ last_tab_for_subq < subq_tabs_end &&
+ get_emb_subq(*last_tab_for_subq) == cur_subq_nest;
+ last_tab_for_subq++) {}
+ uint n_subquery_tables= last_tab_for_subq - subq_tab;
+
+ /*
+ Walk the original array and find where this subquery would have been
+ attached to
+ */
+ table_map need_tables= cur_subq_nest->original_subq_pred_used_tables;
+ need_tables &= ~(join->const_table_map | PSEUDO_TABLE_BITS);
+ for (JOIN_TAB **top_level_tab= join->best_ref + join->const_tables;
+ top_level_tab < last_top_level_tab;
+ //top_level_tab < join->best_ref + join->table_count;
+ top_level_tab++)
+ {
+ need_tables &= ~(*top_level_tab)->table->map;
+ /* Check if this is the place where subquery should be attached */
+ if (!need_tables)
+ {
+ /* Move away the top-level tables that are after top_level_tab */
+ uint top_tail_len= last_top_level_tab - top_level_tab - 1;
+ memmove(top_level_tab + 1 + n_subquery_tables, top_level_tab + 1,
+ sizeof(JOIN_TAB*)*top_tail_len);
+ last_top_level_tab += n_subquery_tables;
+ memcpy(top_level_tab + 1, subq_tab, sizeof(JOIN_TAB*)*n_subquery_tables);
+ break;
+ }
+ }
+ DBUG_ASSERT(!need_tables);
+ subq_tab += n_subquery_tables - 1;
+ }
+ }
+}
+
+
/**
Selects and invokes a search strategy for an optimal query plan.
@@ -4889,7 +5807,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;
@@ -4898,19 +5816,46 @@ 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);
+ 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;
+ }
+
/*
- 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.
+ psergey-todo: if we're not optimizing an SJM nest,
+ - sort that outer tables are first, and each sjm nest follows
+ - then, put each [sjm_table1, ... sjm_tableN] sub-array right where
+ WHERE clause pushdown would have put it.
*/
- 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);
-
+ my_qsort2(join->best_ref + join->const_tables,
+ join->table_count - join->const_tables, sizeof(JOIN_TAB*),
+ jtab_sort_func, (void*)join->emb_sjm_nest);
+
+ if (!join->emb_sjm_nest)
+ {
+ choose_initial_table_order(join);
+ }
+ join->cur_sj_inner_tables= 0;
+
if (straight_join)
{
optimize_straight_join(join, join_tables);
@@ -4948,6 +5893,64 @@ choose_plan(JOIN *join, table_map join_tables)
}
+/*
+ Compare two join tabs based on the subqueries they are from.
+ - top-level join tabs go first
+ - then subqueries are ordered by their select_id (we're using this
+ criteria because we need a cross-platform, deterministic ordering)
+
+ @return
+ 0 - equal
+ -1 - jt1 < jt2
+ 1 - jt1 > jt2
+*/
+
+static int compare_embedding_subqueries(JOIN_TAB *jt1, JOIN_TAB *jt2)
+{
+ /* Determine if the first table is originally from a subquery */
+ TABLE_LIST *tbl1= jt1->table->pos_in_table_list;
+ uint tbl1_select_no;
+ if (tbl1->jtbm_subselect)
+ {
+ tbl1_select_no=
+ tbl1->jtbm_subselect->unit->first_select()->select_number;
+ }
+ else if (tbl1->embedding && tbl1->embedding->sj_subq_pred)
+ {
+ tbl1_select_no=
+ tbl1->embedding->sj_subq_pred->unit->first_select()->select_number;
+ }
+ else
+ tbl1_select_no= 1; /* Top-level */
+
+ /* Same for the second table */
+ TABLE_LIST *tbl2= jt2->table->pos_in_table_list;
+ uint tbl2_select_no;
+ if (tbl2->jtbm_subselect)
+ {
+ tbl2_select_no=
+ tbl2->jtbm_subselect->unit->first_select()->select_number;
+ }
+ else if (tbl2->embedding && tbl2->embedding->sj_subq_pred)
+ {
+ tbl2_select_no=
+ tbl2->embedding->sj_subq_pred->unit->first_select()->select_number;
+ }
+ else
+ tbl2_select_no= 1; /* Top-level */
+
+ /*
+ Put top-level tables in front. Tables from within subqueries must follow,
+ grouped by their owner subquery. We don't care about the order that
+ subquery groups are in, because choose_initial_table_order() will re-order
+ the groups.
+ */
+ if (tbl1_select_no != tbl2_select_no)
+ return tbl1_select_no > tbl2_select_no ? 1 : -1;
+ return 0;
+}
+
+
/**
Compare two JOIN_TAB objects based on the number of accessed records.
@@ -4964,6 +5967,9 @@ choose_plan(JOIN *join, table_map join_tables)
a: dependent = 0x0 table->map = 0x1 found_records = 3 ptr = 0x907e6b0
b: dependent = 0x0 table->map = 0x2 found_records = 3 ptr = 0x907e838
c: dependent = 0x6 table->map = 0x10 found_records = 2 ptr = 0x907ecd0
+
+ As for subuqueries, this function must produce order that can be fed to
+ choose_initial_table_order().
@retval
1 if first is bigger
@@ -4974,11 +5980,19 @@ 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;
+ int cmp;
+ if ((cmp= compare_embedding_subqueries(jt1, jt2)) != 0)
+ return cmp;
+ /*
+ After that,
+ take care about ordering imposed by LEFT JOIN constraints,
+ possible [eq]ref accesses, and numbers of matching records in the table.
+ */
if (jt1->dependent & jt2->table->map)
return 1;
if (jt2->dependent & jt1->table->map)
@@ -4996,18 +6010,62 @@ 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);
+
+ int cmp;
+ if ((cmp= compare_embedding_subqueries(jt1, jt2)) != 0)
+ return cmp;
+
+ 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.
@@ -5043,7 +6101,7 @@ join_tab_cmp_straight(const void* ptr1, const void* ptr2)
static uint
determine_search_depth(JOIN *join)
{
- uint table_count= join->tables - join->const_tables;
+ uint table_count= join->table_count - join->const_tables;
uint search_depth;
/* TODO: this value should be determined dynamically, based on statistics: */
uint max_tables_for_exhaustive_opt= 7;
@@ -5089,28 +6147,35 @@ optimize_straight_join(JOIN *join, table_map join_tables)
{
JOIN_TAB *s;
uint idx= join->const_tables;
+ bool disable_jbuf= join->thd->variables.join_cache_level == 0;
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, disable_jbuf, 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;
+ read_time+= join->positions[idx].read_time +
+ record_count / (double) TIME_FOR_COMPARE;
+ advance_sj_state(join, join_tables, idx, &record_count, &read_time,
+ &loose_scan_pos);
+
join_tables&= ~(s->table->map);
++idx;
}
- read_time+= record_count / (double) TIME_FOR_COMPARE;
if (join->sort_by_table &&
join->sort_by_table != join->positions[join->const_tables].table->table)
read_time+= record_count; // We have to make a temp table
memcpy((uchar*) join->best_positions, (uchar*) join->positions,
sizeof(POSITION)*idx);
- join->best_read= read_time;
+ join->record_count= record_count;
+ join->best_read= read_time - 0.001;
}
@@ -5208,11 +6273,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 */
@@ -5232,7 +6303,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);
@@ -5255,11 +6326,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];
@@ -5271,7 +6343,8 @@ greedy_search(JOIN *join,
/* compute the cost of the new plan extended with 'best_table' */
record_count*= join->positions[idx].records_read;
- read_time+= join->positions[idx].read_time;
+ read_time+= join->positions[idx].read_time +
+ record_count / (double) TIME_FOR_COMPARE;
remaining_tables&= ~(best_table->table->map);
--size_remain;
@@ -5285,6 +6358,151 @@ greedy_search(JOIN *join,
/**
+ Get cost of execution and fanout produced by selected tables in the join
+ prefix (where prefix is defined as prefix in depth-first traversal)
+
+ @param end_tab_idx The number of last tab to be taken into
+ account (in depth-first traversal prefix)
+ @param filter_map Bitmap of tables whose cost/fanout are to
+ be taken into account.
+ @param read_time_arg [out] store read time here
+ @param record_count_arg [out] store record count here
+
+ @note
+
+ @returns
+ read_time_arg and record_count_arg contain the computed cost and fanout
+*/
+
+void JOIN::get_partial_cost_and_fanout(int end_tab_idx,
+ table_map filter_map,
+ double *read_time_arg,
+ double *record_count_arg)
+{
+ double record_count= 1;
+ double read_time= 0.0;
+ double sj_inner_fanout= 1.0;
+ JOIN_TAB *end_tab= NULL;
+ JOIN_TAB *tab;
+ int i;
+ int last_sj_table= MAX_TABLES;
+
+ /*
+ Handle a special case where the join is degenerate, and produces no
+ records
+ */
+ if (table_count == const_tables)
+ {
+ *read_time_arg= 0.0;
+ /*
+ We return 1, because
+ - it is the pessimistic estimate (there might be grouping)
+ - it's safer, as we're less likely to hit the edge cases in
+ calculations.
+ */
+ *record_count_arg=1.0;
+ return;
+ }
+
+ for (tab= first_depth_first_tab(this), i= const_tables;
+ tab;
+ tab= next_depth_first_tab(this, tab), i++)
+ {
+ end_tab= tab;
+ if (i == end_tab_idx)
+ break;
+ }
+
+ for (tab= first_depth_first_tab(this), i= const_tables;
+ ;
+ tab= next_depth_first_tab(this, tab), i++)
+ {
+ if (end_tab->bush_root_tab && end_tab->bush_root_tab == tab)
+ {
+ /*
+ We've entered the SJM nest that contains the end_tab. The caller is
+ - interested in fanout inside the nest (because that's how many times
+ we'll invoke the attached WHERE conditions)
+ - not interested in cost
+ */
+ record_count= 1.0;
+ read_time= 0.0;
+ }
+
+ /*
+ Ignore fanout (but not cost) from sj-inner tables, as long as
+ the range that processes them finishes before the end_tab
+ */
+ if (tab->sj_strategy != SJ_OPT_NONE)
+ {
+ sj_inner_fanout= 1.0;
+ last_sj_table= i + tab->n_sj_tables;
+ }
+
+ table_map cur_table_map;
+ if (tab->table)
+ cur_table_map= tab->table->map;
+ else
+ {
+ /* This is a SJ-Materialization nest. Check all of its tables */
+ TABLE *first_child= tab->bush_children->start->table;
+ TABLE_LIST *sjm_nest= first_child->pos_in_table_list->embedding;
+ cur_table_map= sjm_nest->nested_join->used_tables;
+ }
+ if (tab->records_read && (cur_table_map & filter_map))
+ {
+ record_count *= tab->records_read;
+ read_time += tab->read_time + record_count / (double) TIME_FOR_COMPARE;
+ if (tab->emb_sj_nest)
+ sj_inner_fanout *= tab->records_read;
+ }
+
+ if (i == last_sj_table)
+ {
+ record_count /= sj_inner_fanout;
+ sj_inner_fanout= 1.0;
+ last_sj_table= MAX_TABLES;
+ }
+
+ if (tab == end_tab)
+ break;
+ }
+ *read_time_arg= read_time;// + record_count / TIME_FOR_COMPARE;
+ *record_count_arg= record_count;
+}
+
+
+/*
+ Get prefix cost and fanout. This function is different from
+ get_partial_cost_and_fanout:
+ - it operates on a JOIN that haven't yet finished its optimization phase (in
+ particular, fix_semijoin_strategies_for_picked_join_order() and
+ get_best_combination() haven't been called)
+ - it assumes the the join prefix doesn't have any semi-join plans
+
+ These assumptions are met by the caller of the function.
+*/
+
+void JOIN::get_prefix_cost_and_fanout(uint n_tables,
+ double *read_time_arg,
+ double *record_count_arg)
+{
+ double record_count= 1;
+ double read_time= 0.0;
+ for (uint i= const_tables; i < n_tables + const_tables ; i++)
+ {
+ if (best_positions[i].records_read)
+ {
+ record_count *= best_positions[i].records_read;
+ read_time += 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.
@@ -5426,38 +6644,54 @@ best_extension_by_limited_search(JOIN *join,
JOIN_TAB *s;
double best_record_count= DBL_MAX;
double best_read_time= DBL_MAX;
+ bool disable_jbuf= join->thd->variables.join_cache_level == 0;
DBUG_EXECUTE("opt", print_plan(join, idx, record_count, read_time, read_time,
"part_plan"););
+ /*
+ If we are searching for the execution plan of a materialized semi-join nest
+ then allowed_tables contains bits only for the tables from this nest.
+ */
+ 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, disable_jbuf,
+ 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 +
+ current_record_count / (double) TIME_FOR_COMPARE;
+
+ advance_sj_state(join, remaining_tables, 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 +
- current_record_count / (double) TIME_FOR_COMPARE) >= join->best_read)
+ if (current_read_time >= join->best_read)
{
DBUG_EXECUTE("opt", print_plan(join, idx+1,
current_record_count,
read_time,
- (current_read_time +
- current_record_count /
- (double) TIME_FOR_COMPARE),
+ current_read_time,
"prune_by_cost"););
restore_prev_nj_state(s);
+ restore_prev_sj_state(remaining_tables, s, idx);
continue;
}
@@ -5470,12 +6704,12 @@ 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 &&
/* TODO: What is the reasoning behind this condition? */
- (!(s->key_dependent & remaining_tables) ||
+ (!(s->key_dependent & allowed_tables & remaining_tables) ||
join->positions[idx].records_read < 2.0))
{
best_record_count= current_record_count;
@@ -5490,11 +6724,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,
@@ -5512,16 +6747,16 @@ best_extension_by_limited_search(JOIN *join,
'join' is either the best partial QEP with 'search_depth' relations,
or the best complete QEP so far, whichever is smaller.
*/
- current_read_time+= current_record_count / (double) TIME_FOR_COMPARE;
if (join->sort_by_table &&
join->sort_by_table !=
join->positions[join->const_tables].table->table)
/* We have to make a temp table */
current_read_time+= current_record_count;
- if ((search_depth == 1) || (current_read_time < join->best_read))
+ if (current_read_time < join->best_read)
{
memcpy((uchar*) join->best_positions, (uchar*) join->positions,
sizeof(POSITION) * (idx + 1));
+ join->record_count= current_record_count;
join->best_read= current_read_time - 0.001;
}
DBUG_EXECUTE("opt", print_plan(join, idx+1,
@@ -5531,6 +6766,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);
@@ -5577,6 +6813,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
JOIN_TAB *s;
double best_record_count=DBL_MAX,best_read_time=DBL_MAX;
+ bool disable_jbuf= join->thd->variables.join_cache_level == 0;
for (JOIN_TAB **pos=join->best_ref+idx ; (s=*pos) ; pos++)
{
table_map real_table_bit=s->table->map;
@@ -5584,8 +6821,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, disable_jbuf, record_count,
+ join->positions + idx, &loose_scan_pos);
records= join->positions[idx].records_read;
best= join->positions[idx].read_time;
/*
@@ -5594,6 +6832,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, 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))
@@ -5612,6 +6853,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
}
@@ -5624,14 +6866,16 @@ 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;
+ uint null_fields,blobs,fields;
+ ulong 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))
{
@@ -5642,21 +6886,118 @@ 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)
+
+ /* Take into account that DuplicateElimination may need to store rowid */
+ uint rowid_add_size= 0;
+ if (keep_current_rowid)
+ {
+ rowid_add_size= table->file->ref_length;
+ rec_length += rowid_add_size;
+ fields++;
+ }
+
+ if (max_fl)
+ {
+ // TODO: to improve this estimate for max expected length
+ if (blobs)
+ {
+ ulong blob_length= table->file->stats.mean_rec_length;
+ if (ULONG_MAX - rec_length > blob_length)
+ rec_length+= blob_length;
+ else
+ rec_length= ULONG_MAX;
+ }
+ max_used_fieldlength= rec_length;
+ }
+ else if (table->file->stats.mean_rec_length)
+ set_if_smaller(rec_length, table->file->stats.mean_rec_length + rowid_add_size);
+
+ used_fields=fields;
+ used_fieldlength=rec_length;
+ used_blobs=blobs;
+ used_null_fields= null_fields;
+ used_uneven_bit_fields= uneven_bit_fields;
+}
+
+
+/*
+ @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(join->thd, cond,
+ join->const_table_map | table->map,
+ table->map, -1, 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);
+}
+
+
+/**
+ @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.
+
+ @note
+ At present the function is supposed to be called 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;
+ if (!is_ref_for_hash_join())
{
- 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);
+ KEY *keyinfo= table->key_info + ref.key;
+ return keyinfo->key_part[0].field->hash_join_is_possible();
}
- join_tab->used_fields=fields;
- join_tab->used_fieldlength=rec_length;
- join_tab->used_blobs=blobs;
+ return TRUE;
}
@@ -5665,16 +7006,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;
}
@@ -5731,12 +7069,12 @@ cache_record_length(JOIN *join,uint idx)
Expected number of row combinations
*/
-static double
-prev_record_reads(JOIN *join, uint idx, table_map found_ref)
+double
+prev_record_reads(POSITION *positions, uint idx, table_map found_ref)
{
double found=1.0;
- POSITION *pos_end= join->positions - 1;
- for (POSITION *pos= join->positions + idx - 1; pos != pos_end; pos--)
+ POSITION *pos_end= positions - 1;
+ for (POSITION *pos= positions + idx - 1; pos != pos_end; pos--)
{
if (pos->table->table->map & found_ref)
{
@@ -5765,14 +7103,239 @@ prev_record_reads(JOIN *join, uint idx, table_map found_ref)
}
-/**
- Set up join struct according to best position.
+/*
+ Enumerate join tabs in breadth-first fashion, including const tables.
*/
-static bool
+JOIN_TAB *first_breadth_first_tab(JOIN *join)
+{
+ return join->join_tab; /* There's always one (i.e. first) table */
+}
+
+
+JOIN_TAB *next_breadth_first_tab(JOIN *join, JOIN_TAB *tab)
+{
+ if (!tab->bush_root_tab)
+ {
+ /* We're at top level. Get the next top-level tab */
+ tab++;
+ if (tab < join->join_tab + join->top_join_tab_count)
+ return tab;
+
+ /* No more top-level tabs. Switch to enumerating SJM nest children */
+ tab= join->join_tab;
+ }
+ else
+ {
+ /* We're inside of an SJM nest */
+ if (!tab->last_leaf_in_bush)
+ {
+ /* There's one more table in the nest, return it. */
+ return ++tab;
+ }
+ else
+ {
+ /*
+ There are no more tables in this nest. Get out of it and then we'll
+ proceed to the next nest.
+ */
+ tab= tab->bush_root_tab + 1;
+ }
+ }
+
+ /*
+ Ok, "tab" points to a top-level table, and we need to find the next SJM
+ nest and enter it.
+ */
+ for (; tab < join->join_tab + join->top_join_tab_count; tab++)
+ {
+ if (tab->bush_children)
+ return tab->bush_children->start;
+ }
+ return NULL;
+}
+
+
+JOIN_TAB *first_top_level_tab(JOIN *join, enum enum_with_const_tables with_const)
+{
+ JOIN_TAB *tab= join->join_tab;
+ if (with_const == WITH_CONST_TABLES)
+ {
+ if (join->const_tables == join->table_count)
+ return NULL;
+ tab += join->const_tables;
+ }
+ return tab;
+}
+
+
+JOIN_TAB *next_top_level_tab(JOIN *join, JOIN_TAB *tab)
+{
+ tab= next_breadth_first_tab(join, tab);
+ if (tab && tab->bush_root_tab)
+ tab= NULL;
+ return tab;
+}
+
+
+JOIN_TAB *first_linear_tab(JOIN *join, enum enum_with_const_tables const_tbls)
+{
+ JOIN_TAB *first= join->join_tab;
+ if (const_tbls == WITHOUT_CONST_TABLES)
+ first+= join->const_tables;
+ if (first < join->join_tab + join->top_join_tab_count)
+ return first;
+ return NULL; /* All tables were const tables */
+}
+
+
+/*
+ A helper function to loop over all join's join_tab in sequential fashion
+
+ DESCRIPTION
+ Depending on include_bush_roots parameter, JOIN_TABs that represent
+ SJM-scan/lookups are either returned or omitted.
+
+ SJM-Bush children are returned right after (or in place of) their container
+ join tab (TODO: does anybody depend on this? A: make_join_readinfo() seems
+ to)
+
+ For example, if we have this structure:
+
+ ot1--ot2--sjm1----------------ot3-...
+ |
+ +--it1--it2--it3
+
+ calls to next_linear_tab( include_bush_roots=TRUE) will return:
+
+ ot1 ot2 sjm1 it1 it2 it3 ot3 ...
+
+ while calls to next_linear_tab( include_bush_roots=FALSE) will return:
+
+ ot1 ot2 it1 it2 it3 ot3 ...
+
+ (note that sjm1 won't be returned).
+*/
+
+JOIN_TAB *next_linear_tab(JOIN* join, JOIN_TAB* tab,
+ enum enum_with_bush_roots include_bush_roots)
+{
+ if (include_bush_roots == WITH_BUSH_ROOTS && tab->bush_children)
+ {
+ /* This JOIN_TAB is a SJM nest; Start from first table in nest */
+ return tab->bush_children->start;
+ }
+
+ DBUG_ASSERT(!tab->last_leaf_in_bush || tab->bush_root_tab);
+
+ if (tab->bush_root_tab) /* Are we inside an SJM nest */
+ {
+ /* Inside SJM nest */
+ if (!tab->last_leaf_in_bush)
+ return tab+1; /* Return next in nest */
+ /* Continue from the sjm on the top level */
+ tab= tab->bush_root_tab;
+ }
+
+ /* If no more JOIN_TAB's on the top level */
+ if (++tab == join->join_tab + join->top_join_tab_count)
+ return NULL;
+
+ if (include_bush_roots == WITHOUT_BUSH_ROOTS && tab->bush_children)
+ {
+ /* This JOIN_TAB is a SJM nest; Start from first table in nest */
+ tab= tab->bush_children->start;
+ }
+ return tab;
+}
+
+
+/*
+ Start to iterate over all join tables in bush-children-first order, excluding
+ the const tables (see next_depth_first_tab() comment for details)
+*/
+
+JOIN_TAB *first_depth_first_tab(JOIN* join)
+{
+ JOIN_TAB* tab;
+ /* This means we're starting the enumeration */
+ if (join->const_tables == join->top_join_tab_count)
+ return NULL;
+
+ tab= join->join_tab + join->const_tables;
+
+ return (tab->bush_children) ? tab->bush_children->start : tab;
+}
+
+
+/*
+ A helper function to iterate over all join tables in bush-children-first order
+
+ DESCRIPTION
+
+ For example, for this join plan
+
+ ot1--ot2--sjm1------------ot3-...
+ |
+ |
+ it1--it2--it3
+
+ call to first_depth_first_tab() will return ot1, and subsequent calls to
+ next_depth_first_tab() will return:
+
+ ot2 it1 it2 it3 sjm ot3 ...
+*/
+
+JOIN_TAB *next_depth_first_tab(JOIN* join, JOIN_TAB* tab)
+{
+ /* If we're inside SJM nest and have reached its end, get out */
+ if (tab->last_leaf_in_bush)
+ return tab->bush_root_tab;
+
+ /* Move to next tab in the array we're traversing */
+ tab++;
+
+ if (tab == join->join_tab +join->top_join_tab_count)
+ return NULL; /* Outside SJM nest and reached EOF */
+
+ if (tab->bush_children)
+ return tab->bush_children->start;
+
+ return tab;
+}
+
+
+static Item * const null_ptr= NULL;
+
+/*
+ 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.
+
+ NOTE
+ In this function we switch from pre-join-optimization JOIN_TABs to
+ post-join-optimization JOIN_TABs. This is achieved by copying the entire
+ JOIN_TAB objects.
+
+ RETURN
+ FALSE OK
+ TRUE Out of memory
+*/
+
+bool
get_best_combination(JOIN *join)
{
- uint i,tablenr;
+ uint tablenr;
table_map used_tables;
JOIN_TAB *join_tab,*j;
KEYUSE *keyuse;
@@ -5780,18 +7343,76 @@ get_best_combination(JOIN *join)
THD *thd=join->thd;
DBUG_ENTER("get_best_combination");
- table_count=join->tables;
+ table_count=join->table_count;
if (!(join->join_tab=join_tab=
(JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count)))
DBUG_RETURN(TRUE);
join->full_join=0;
+ join->hash_join= FALSE;
used_tables= OUTER_REF_TABLE_BIT; // Outer row is already read
+
+ fix_semijoin_strategies_for_picked_join_order(join);
+
+ JOIN_TAB_RANGE *root_range;
+ if (!(root_range= new JOIN_TAB_RANGE))
+ DBUG_RETURN(TRUE);
+ root_range->start= join->join_tab;
+ /* root_range->end will be set later */
+ join->join_tab_ranges.empty();
+
+ if (join->join_tab_ranges.push_back(root_range))
+ DBUG_RETURN(TRUE);
+
+ JOIN_TAB *sjm_nest_end= NULL;
+ JOIN_TAB *sjm_nest_root= NULL;
+
for (j=join_tab, tablenr=0 ; tablenr < table_count ; tablenr++,j++)
{
TABLE *form;
+ POSITION *cur_pos= &join->best_positions[tablenr];
+ if (cur_pos->sj_strategy == SJ_OPT_MATERIALIZE ||
+ cur_pos->sj_strategy == SJ_OPT_MATERIALIZE_SCAN)
+ {
+ /*
+ Ok, we've entered an SJ-Materialization semi-join (note that this can't
+ be done recursively, semi-joins are not allowed to be nested).
+ 1. Put into main join order a JOIN_TAB that represents a lookup or scan
+ in the temptable.
+ */
+ bzero(j, sizeof(JOIN_TAB));
+ j->join= join;
+ j->table= NULL; //temporary way to tell SJM tables from others.
+ j->ref.key = -1;
+ j->on_expr_ref= (Item**) &null_ptr;
+ j->keys= key_map(1); /* The unique index is always in 'possible keys' in EXPLAIN */
+
+ /*
+ 2. Proceed with processing SJM nest's join tabs, putting them into the
+ sub-order
+ */
+ SJ_MATERIALIZATION_INFO *sjm= cur_pos->table->emb_sj_nest->sj_mat_info;
+ j->records= j->records_read= (ha_rows)(sjm->is_sj_scan? sjm->rows : 1);
+ JOIN_TAB *jt;
+ JOIN_TAB_RANGE *jt_range;
+ if (!(jt= (JOIN_TAB*)join->thd->alloc(sizeof(JOIN_TAB)*sjm->tables)) ||
+ !(jt_range= new JOIN_TAB_RANGE))
+ DBUG_RETURN(TRUE);
+ jt_range->start= jt;
+ jt_range->end= jt + sjm->tables;
+ join->join_tab_ranges.push_back(jt_range);
+ j->bush_children= jt_range;
+ sjm_nest_end= jt + sjm->tables;
+ sjm_nest_root= j;
+
+ j= jt;
+ }
+
*j= *join->best_positions[tablenr].table;
+
+ j->bush_root_tab= sjm_nest_root;
+
form=join->table[tablenr]=j->table;
used_tables|= form->map;
form->reginfo.join_tab=j;
@@ -5799,45 +7420,229 @@ get_best_combination(JOIN *join)
form->reginfo.not_exists_optimize=0; // Only with LEFT JOIN
DBUG_PRINT("info",("type: %d", j->type));
if (j->type == JT_CONST)
- continue; // Handled in make_join_stat..
+ goto loop_end; // Handled in make_join_stat..
+ j->loosescan_match_tab= NULL; //non-nulls will be set later
+ j->inside_loosescan_range= FALSE;
j->ref.key = -1;
j->ref.key_parts=0;
if (j->type == JT_SYSTEM)
- continue;
- if (j->keys.is_clear_all() || !(keyuse= join->best_positions[tablenr].key))
+ goto loop_end;
+ if ( !(keyuse= join->best_positions[tablenr].key))
{
j->type=JT_ALL;
- if (tablenr != join->const_tables)
- join->full_join=1;
+ if (join->best_positions[tablenr].use_join_buffer &&
+ tablenr != join->const_tables)
+ join->full_join= 1;
}
- else if (create_ref_for_key(join, j, keyuse, used_tables))
+
+ /*if (join->best_positions[tablenr].sj_strategy == SJ_OPT_LOOSE_SCAN)
+ {
+ DBUG_ASSERT(!keyuse || keyuse->key ==
+ join->best_positions[tablenr].loosescan_picker.loosescan_key);
+ j->index= join->best_positions[tablenr].loosescan_picker.loosescan_key;
+ }*/
+
+ if (keyuse && create_ref_for_key(join, j, keyuse, TRUE, used_tables))
DBUG_RETURN(TRUE); // Something went wrong
+
+ if ((j->type == JT_REF || j->type == JT_EQ_REF) &&
+ is_hash_join_key_no(j->ref.key))
+ join->hash_join= TRUE;
+
+ loop_end:
+ /*
+ Save records_read in JOIN_TAB so that select_describe()/etc don't have
+ to access join->best_positions[].
+ */
+ j->records_read= (ha_rows)join->best_positions[tablenr].records_read;
+ join->map2table[j->table->tablenr]= j;
+
+ /* If we've reached the end of sjm nest, switch back to main sequence */
+ if (j + 1 == sjm_nest_end)
+ {
+ j->last_leaf_in_bush= TRUE;
+ j= sjm_nest_root;
+ sjm_nest_root= NULL;
+ sjm_nest_end= NULL;
+ }
}
+ root_range->end= j;
- for (i=0 ; i < table_count ; i++)
- join->map2table[join->join_tab[i].table->tablenr]=join->join_tab+i;
+ join->top_join_tab_count= join->join_tab_ranges.head()->end -
+ join->join_tab_ranges.head()->start;
update_depend_map(join);
DBUG_RETURN(0);
}
+/**
+ Create a descriptor of hash join key to access a given join table
-static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
- table_map used_tables)
+ @param join join which the join table belongs to
+ @param join_tab the join table to access
+ @param org_keyuse beginning of the key uses to join this table
+ @param used_tables bitmap of the previous tables
+
+ @details
+ This function first finds key uses that can be utilized by the hash join
+ algorithm to join join_tab to the previous tables marked in the bitmap
+ used_tables. The tested key uses are taken from the array of all key uses
+ for 'join' starting from the position org_keyuse. After all interesting key
+ uses have been found the function builds a descriptor of the corresponding
+ key that is used by the hash join algorithm would it be chosen to join
+ the table join_tab.
+
+ @retval FALSE the descriptor for a hash join key is successfully created
+ @retval TRUE otherwise
+*/
+
+static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
+ KEYUSE *org_keyuse, table_map used_tables)
{
- KEYUSE *keyuse=org_keyuse;
- bool ftkey=(keyuse->keypart == FT_KEYPART);
+ KEY *keyinfo;
+ KEY_PART_INFO *key_part_info;
+ KEYUSE *keyuse= org_keyuse;
+ uint key_parts= 0;
THD *thd= join->thd;
- uint keyparts,length,key;
+ TABLE *table= join_tab->table;
+ bool first_keyuse= TRUE;
+ DBUG_ENTER("create_hj_key_for_table");
+
+ do
+ {
+ if (!(~used_tables & keyuse->used_tables) &&
+ are_tables_local(join_tab, keyuse->used_tables))
+ {
+ if (first_keyuse)
+ {
+ key_parts++;
+ first_keyuse= FALSE;
+ }
+ else
+ {
+ KEYUSE *curr= org_keyuse;
+ for( ; curr < keyuse; curr++)
+ {
+ if (curr->keypart == keyuse->keypart &&
+ !(~used_tables & curr->used_tables) &&
+ are_tables_local(join_tab, curr->used_tables))
+ break;
+ }
+ if (curr == keyuse)
+ key_parts++;
+ }
+ }
+ keyuse++;
+ } while (keyuse->table == table && keyuse->is_for_hash_join());
+ if (!key_parts)
+ DBUG_RETURN(TRUE);
+ /* This memory is allocated only once for the joined table join_tab */
+ if (!(keyinfo= (KEY *) thd->alloc(sizeof(KEY))) ||
+ !(key_part_info = (KEY_PART_INFO *) thd->alloc(sizeof(KEY_PART_INFO)*
+ key_parts)))
+ DBUG_RETURN(TRUE);
+ keyinfo->usable_key_parts= keyinfo->key_parts = key_parts;
+ keyinfo->key_part= key_part_info;
+ keyinfo->key_length=0;
+ keyinfo->algorithm= HA_KEY_ALG_UNDEF;
+ keyinfo->flags= HA_GENERATED_KEY;
+ keyinfo->name= (char *) "$hj";
+ keyinfo->rec_per_key= (ulong*) thd->calloc(sizeof(ulong)*key_parts);
+ if (!keyinfo->rec_per_key)
+ DBUG_RETURN(TRUE);
+ keyinfo->key_part= key_part_info;
+
+ first_keyuse= TRUE;
+ keyuse= org_keyuse;
+ do
+ {
+ if (!(~used_tables & keyuse->used_tables) &&
+ are_tables_local(join_tab, keyuse->used_tables))
+ {
+ bool add_key_part= TRUE;
+ if (!first_keyuse)
+ {
+ for(KEYUSE *curr= org_keyuse; curr < keyuse; curr++)
+ {
+ if (curr->keypart == keyuse->keypart &&
+ !(~used_tables & curr->used_tables) &&
+ are_tables_local(join_tab, curr->used_tables))
+ {
+ keyuse->keypart= NO_KEYPART;
+ add_key_part= FALSE;
+ break;
+ }
+ }
+ }
+ if (add_key_part)
+ {
+ Field *field= table->field[keyuse->keypart];
+ uint fieldnr= keyuse->keypart+1;
+ table->create_key_part_by_field(keyinfo, key_part_info, field, fieldnr);
+ key_part_info++;
+ }
+ }
+ first_keyuse= FALSE;
+ keyuse++;
+ } while (keyuse->table == table && keyuse->is_for_hash_join());
+
+ join_tab->hj_key= keyinfo;
+
+ DBUG_RETURN(FALSE);
+}
+
+/*
+ Check if a set of tables specified by used_tables can be accessed when
+ we're doing scan on join_tab jtab.
+*/
+static bool are_tables_local(JOIN_TAB *jtab, table_map used_tables)
+{
+ if (jtab->bush_root_tab)
+ {
+ /*
+ jtab is inside execution join nest. We may not refer to outside tables,
+ except the const tables.
+ */
+ table_map local_tables= jtab->emb_sj_nest->nested_join->used_tables |
+ jtab->join->const_table_map |
+ OUTER_REF_TABLE_BIT;
+ return !test(used_tables & ~local_tables);
+ }
+
+ /*
+ If we got here then jtab is at top level.
+ - all other tables at top level are accessible,
+ - tables in join nests are accessible too, because all their columns that
+ are needed at top level will be unpacked when scanning the
+ materialization table.
+ */
+ return TRUE;
+}
+
+static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
+ KEYUSE *org_keyuse, bool allow_full_scan,
+ table_map used_tables)
+{
+ uint keyparts, length, key;
TABLE *table;
KEY *keyinfo;
+ KEYUSE *keyuse= org_keyuse;
+ bool ftkey= (keyuse->keypart == FT_KEYPART);
+ THD *thd= join->thd;
DBUG_ENTER("create_ref_for_key");
/* Use best key from find_best */
- table=j->table;
- key=keyuse->key;
- keyinfo=table->key_info+key;
+ table= j->table;
+ key= keyuse->key;
+ if (!is_hash_join_key_no(key))
+ keyinfo= table->key_info+key;
+ else
+ {
+ if (create_hj_key_for_table(join, j, org_keyuse, used_tables))
+ DBUG_RETURN(TRUE);
+ keyinfo= j->hj_key;
+ }
if (ftkey)
{
@@ -5858,30 +7663,45 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
*/
do
{
- if (!(~used_tables & keyuse->used_tables))
+ if (!(~used_tables & keyuse->used_tables) &&
+ j->access_from_tables_is_allowed(keyuse->used_tables,
+ join->sjm_lookup_tables))
{
- if (keyparts == keyuse->keypart &&
- !(found_part_ref_or_null & keyuse->optimize))
- {
- keyparts++;
- length+= keyinfo->key_part[keyuse->keypart].store_length;
- found_part_ref_or_null|= keyuse->optimize;
- }
+ if (are_tables_local(j, keyuse->val->used_tables()))
+ {
+ if ((is_hash_join_key_no(key) && keyuse->keypart != NO_KEYPART) ||
+ (!is_hash_join_key_no(key) && keyparts == keyuse->keypart &&
+ !(found_part_ref_or_null & keyuse->optimize)))
+ {
+ length+= keyinfo->key_part[keyparts].store_length;
+ keyparts++;
+ found_part_ref_or_null|= keyuse->optimize & ~KEY_OPTIMIZE_EQ;
+ }
+ }
}
keyuse++;
} while (keyuse->table == table && keyuse->key == key);
- DBUG_ASSERT(length > 0 && keyparts != 0);
- } /* not ftkey */
+ if (!keyparts && allow_full_scan)
+ {
+ /* It's a LooseIndexScan strategy scanning whole index */
+ j->type= JT_ALL;
+ j->index= key;
+ DBUG_RETURN(FALSE);
+ }
+
+ DBUG_ASSERT(length > 0);
+ DBUG_ASSERT(keyparts != 0);
+ } /* not ftkey */
+
/* set up fieldref */
- keyinfo=table->key_info+key;
- j->ref.key_parts=keyparts;
- j->ref.key_length=length;
- j->ref.key=(int) key;
+ j->ref.key_parts= keyparts;
+ j->ref.key_length= length;
+ j->ref.key= (int) key;
if (!(j->ref.key_buff= (uchar*) thd->calloc(ALIGN_SIZE(length)*2)) ||
!(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) *
- (keyparts+1)))) ||
- !(j->ref.items= (Item**) thd->alloc(sizeof(Item*)*keyparts)) ||
+ (keyparts+1)))) ||
+ !(j->ref.items=(Item**) thd->alloc(sizeof(Item*)*keyparts)) ||
!(j->ref.cond_guards= (bool**) thd->alloc(sizeof(uint*)*keyparts)))
{
DBUG_RETURN(TRUE);
@@ -5890,11 +7710,13 @@ 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;
+ j->ref.null_ref_part= NO_REF_PART;
keyuse=org_keyuse;
store_key **ref_key= j->ref.key_copy;
uchar *key_buff=j->ref.key_buff, *null_ref_key= 0;
+ uint null_ref_part= NO_REF_PART;
bool keyuse_uses_no_tables= TRUE;
if (ftkey)
{
@@ -5911,9 +7733,15 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
uint i;
for (i=0 ; i < keyparts ; keyuse++,i++)
{
- while (keyuse->keypart != i ||
- ((~used_tables) & keyuse->used_tables))
- keyuse++; /* Skip other parts */
+ while (((~used_tables) & keyuse->used_tables) ||
+ !j->access_from_tables_is_allowed(keyuse->used_tables,
+ join->sjm_lookup_tables) ||
+ keyuse->keypart == NO_KEYPART ||
+ (keyuse->keypart !=
+ (is_hash_join_key_no(key) ?
+ keyinfo->key_part[i].field->field_index : i)) ||
+ !are_tables_local(j, keyuse->val->used_tables()))
+ keyuse++; /* Skip other parts */
uint maybe_null= test(keyinfo->key_part[i].null_bit);
j->ref.items[i]=keyuse->val; // Save for cond removal
@@ -5921,12 +7749,15 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
if (keyuse->null_rejecting)
j->ref.null_rejecting |= 1 << i;
keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables;
- if (!keyuse->used_tables &&!thd->lex->describe)
+ if (!keyuse->val->used_tables() && !thd->lex->describe)
{ // Compare against constant
- store_key_item tmp(thd, keyinfo->key_part[i].field,
+ 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();
@@ -5942,8 +7773,11 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
instead of JT_REF_OR_NULL in case if field can't be null
*/
if ((keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) && maybe_null)
+ {
null_ref_key= key_buff;
- key_buff+=keyinfo->key_part[i].store_length;
+ null_ref_part= i;
+ }
+ key_buff+= keyinfo->key_part[i].store_length;
}
} /* not ftkey */
*ref_key=0; // end_marker
@@ -5957,6 +7791,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
/* Must read with repeat */
j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF;
j->ref.null_ref_key= null_ref_key;
+ j->ref.null_ref_part= null_ref_part;
}
else if (keyuse_uses_no_tables)
{
@@ -5991,9 +7826,10 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
}
else if (keyuse->val->type() == Item::FIELD_ITEM ||
(keyuse->val->type() == Item::REF_ITEM &&
- ((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF &&
- (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
- Item_ref::DIRECT_REF &&
+ ((((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF &&
+ (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
+ Item_ref::DIRECT_REF) ||
+ ((Item_ref*)keyuse->val)->ref_type() == Item_ref::VIEW_REF) &&
keyuse->val->real_item()->type() == Item::FIELD_ITEM))
return new store_key_field(thd,
key_part->field,
@@ -6001,13 +7837,13 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
maybe_null ? key_buff : 0,
key_part->length,
((Item_field*) keyuse->val->real_item())->field,
- keyuse->val->full_name());
+ keyuse->val->real_item()->full_name());
return new store_key_item(thd,
key_part->field,
key_buff + maybe_null,
maybe_null ? key_buff : 0,
key_part->length,
- keyuse->val);
+ keyuse->val, FALSE);
}
/**
@@ -6066,7 +7902,8 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
join_tab= parent->join_tab_reexec;
table= &parent->table_reexec[0]; parent->table_reexec[0]= temp_table;
- tables= 1;
+ table_count= top_join_tab_count= 1;
+
const_tables= 0;
const_table_map= 0;
eliminated_tables= 0;
@@ -6109,10 +7946,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();
@@ -6124,8 +7964,18 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
join_tab->ref.key = -1;
join_tab->not_used_in_distinct=0;
join_tab->read_first_record= join_init_read_record;
+ join_tab->preread_init_done= FALSE;
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;
+ join_tab->bush_root_tab= NULL;
+ join_tab->bush_children= NULL;
+ join_tab->last_leaf_in_bush= FALSE;
bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
temp_table->status=0;
temp_table->null_row=0;
@@ -6133,16 +7983,18 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
}
-inline void add_cond_and_fix(Item **e1, Item *e2)
+inline void add_cond_and_fix(THD *thd, Item **e1, Item *e2)
{
if (*e1)
{
+ if (!e2)
+ return;
Item *res;
if ((res= new Item_cond_and(*e1, e2)))
{
- *e1= res;
- res->quick_fix_field();
+ res->fix_fields(thd, 0);
res->update_used_tables();
+ *e1= res;
}
}
else
@@ -6204,12 +8056,13 @@ inline void add_cond_and_fix(Item **e1, Item *e2)
static void add_not_null_conds(JOIN *join)
{
DBUG_ENTER("add_not_null_conds");
- for (uint i=join->const_tables ; i < join->tables ; i++)
+
+ for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
+ tab;
+ tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
- 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++)
{
@@ -6217,15 +8070,26 @@ 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();
+ if (real->basic_const_item())
+ {
+ /*
+ It could be constant instead of field after constant
+ propagation.
+ */
+ DBUG_ASSERT(real->is_expensive() || // prevent early expensive eval
+ !real->is_null()); // NULLs are not propagated
+ continue;
+ }
+ 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:
UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
not_null_item is the t1.f1, but it's referred_tab is 0.
*/
- if (!referred_tab || referred_tab->join != join)
+ if (!referred_tab)
continue;
if (!(notnull= new Item_func_isnotnull(not_null_item)))
DBUG_VOID_RETURN;
@@ -6237,11 +8101,22 @@ 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.c_ptr(),
- QT_ORDINARY););
- add_cond_and_fix(&referred_tab->select_cond, notnull);
+ DBUG_EXECUTE("where",print_where(notnull,
+ referred_tab->table->alias.c_ptr(),
+ QT_ORDINARY););
+ if (!tab->first_inner)
+ {
+ COND *new_cond= referred_tab->join == join ?
+ referred_tab->select_cond :
+ join->outer_ref_cond;
+ add_cond_and_fix(join->thd, &new_cond, notnull);
+ if (referred_tab->join == join)
+ referred_tab->set_select_cond(new_cond, __LINE__);
+ else
+ join->outer_ref_cond= new_cond;
+ }
+ else
+ add_cond_and_fix(join->thd, tab->first_inner->on_expr_ref, notnull);
}
}
}
@@ -6256,6 +8131,12 @@ static void add_not_null_conds(JOIN *join)
nested outer join and so on until it reaches root_tab
(root_tab can be 0).
+ In other words:
+ add_found_match_trig_cond(tab->first_inner_tab, y, 0) is the way one should
+ wrap parts of WHERE. The idea is that the part of WHERE should be only
+ evaluated after we've finished figuring out whether outer joins.
+ ^^^ is the above correct?
+
@param tab the first inner table for most nested outer join
@param cond the predicate to be guarded (must be set)
@param root_tab the first inner table to stop
@@ -6283,6 +8164,12 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
}
+bool TABLE_LIST::is_active_sjm()
+{
+ return sj_mat_info && sj_mat_info->is_used;
+}
+
+
/**
Fill in outer join related info for the execution plan structure.
@@ -6300,6 +8187,12 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
corresponding first inner table through the field t0->on_expr_ref.
Here ti are structures of the JOIN_TAB type.
+ In other words, for each join tab, set
+ - first_inner
+ - last_inner
+ - first_upper
+ - on_expr_ref, cond_equal
+
EXAMPLE. For the query:
@code
SELECT * FROM t1
@@ -6325,14 +8218,33 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
has been chosen.
*/
-static void
+static bool
make_outerjoin_info(JOIN *join)
{
DBUG_ENTER("make_outerjoin_info");
- for (uint i=join->const_tables ; i < join->tables ; i++)
+
+ /*
+ Create temp. tables for merged SJ-Materialization nests. We need to do
+ this now, because further code relies on tab->table and
+ tab->table->pos_in_table_list being set.
+ */
+ JOIN_TAB *tab;
+ for (tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
+ tab;
+ tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
- JOIN_TAB *tab=join->join_tab+i;
- TABLE *table=tab->table;
+ if (tab->bush_children)
+ {
+ if (setup_sj_materialization_part1(tab))
+ DBUG_RETURN(TRUE);
+ tab->table->reginfo.join_tab= tab;
+ }
+ }
+
+ for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES); tab;
+ tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
+ {
+ TABLE *table= tab->table;
TABLE_LIST *tbl= table->pos_in_table_list;
TABLE_LIST *embedding= tbl->embedding;
@@ -6346,11 +8258,19 @@ make_outerjoin_info(JOIN *join)
tab->last_inner= tab->first_inner= tab;
tab->on_expr_ref= &tbl->on_expr;
tab->cond_equal= tbl->cond_equal;
- if (embedding)
+ if (embedding && !embedding->is_active_sjm())
tab->first_upper= embedding->nested_join->first_nested;
}
for ( ; embedding ; embedding= embedding->embedding)
{
+ if (embedding->is_active_sjm())
+ {
+ /* We're trying to walk out of an SJ-Materialization nest. Don't do this. */
+ break;
+ }
+ /* Ignore sj-nests: */
+ if (!(embedding->on_expr && embedding->outer_join))
+ continue;
NESTED_JOIN *nested_join= embedding->nested_join;
if (!nested_join->counter)
{
@@ -6366,13 +8286,20 @@ 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;
+ DBUG_RETURN(FALSE);
}
@@ -6385,75 +8312,133 @@ 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)
+ if (join->table_count > 1)
cond->update_used_tables(); // Tablenr may have changed
- if (join->const_tables == join->tables &&
+ if (join->const_tables == join->table_count &&
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->exec_const_cond=
+ make_cond_for_table(thd, cond,
join->const_table_map,
- (table_map) 0);
- 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++)
+ (table_map) 0, -1, FALSE, FALSE);
+ /* Add conditions added by add_not_null_conds(). */
+ for (uint i= 0 ; i < join->const_tables ; i++)
+ add_cond_and_fix(thd, &join->exec_const_cond,
+ join->join_tab[i].select_cond);
+
+ DBUG_EXECUTE("where",print_where(join->exec_const_cond,"constants",
+ QT_ORDINARY););
+ if (join->exec_const_cond && !join->exec_const_cond->is_expensive() &&
+ !join->exec_const_cond->val_int())
+ {
+ DBUG_PRINT("info",("Found impossible WHERE condition"));
+ join->exec_const_cond= NULL;
+ DBUG_RETURN(1); // Impossible const condition
+ }
+
+ if (join->table_count != join->const_tables)
{
- if (*tab->on_expr_ref)
+ COND *outer_ref_cond= make_cond_for_table(thd, cond,
+ join->const_table_map |
+ OUTER_REF_TABLE_BIT,
+ OUTER_REF_TABLE_BIT,
+ -1, FALSE, FALSE);
+ if (outer_ref_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);
- 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);
- if (!cond_tab->select_cond)
- DBUG_RETURN(1);
- cond_tab->select_cond->quick_fix_field();
- }
+ add_cond_and_fix(thd, &outer_ref_cond, join->outer_ref_cond);
+ join->outer_ref_cond= outer_ref_cond;
+ }
}
- if (const_cond && !const_cond->val_int())
+ else
{
- DBUG_PRINT("info",("Found impossible WHERE condition"));
- DBUG_RETURN(1); // Impossible const condition
+ COND *pseudo_bits_cond=
+ make_cond_for_table(thd, cond,
+ join->const_table_map |
+ PSEUDO_TABLE_BITS,
+ PSEUDO_TABLE_BITS,
+ -1, FALSE, FALSE);
+ if (pseudo_bits_cond)
+ {
+ add_cond_and_fix(thd, &pseudo_bits_cond,
+ join->pseudo_bits_cond);
+ join->pseudo_bits_cond= pseudo_bits_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);
- for (uint i=join->const_tables ; i < join->tables ; i++)
+ JOIN_TAB *tab;
+ table_map current_map;
+ uint i= join->const_tables;
+ for (tab= first_depth_first_tab(join); tab;
+ tab= next_depth_first_tab(join, tab), i++)
{
- JOIN_TAB *tab=join->join_tab+i;
+ bool is_hj;
/*
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;
+ JOIN_TAB *first_inner_tab= tab->first_inner;
+
+ if (!tab->bush_children)
+ current_map= tab->table->map;
+ else
+ current_map= tab->bush_children->start->emb_sj_nest->sj_inner_tables;
+
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
*/
- if (i == join->tables-1)
+ if (tab == join->join_tab + join->top_join_tab_count - 1)
current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
used_tables|=current_map;
if (tab->type == JT_REF && tab->quick &&
- (uint) tab->ref.key == tab->quick->index &&
- tab->ref.key_length < tab->quick->max_used_key_length)
+ (((uint) tab->ref.key == tab->quick->index &&
+ tab->ref.key_length < tab->quick->max_used_key_length) ||
+ tab->table->intersect_keys.is_set(tab->ref.key)))
{
/* Range uses longer key; Use this instead of ref on key */
tab->type=JT_ALL;
@@ -6466,16 +8451,47 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
We will use join cache here : prevent sorting of the first
table only and sort at the end.
*/
- if (i != join->const_tables && join->tables > join->const_tables + 1)
+ if (i != join->const_tables &&
+ join->table_count > join->const_tables + 1 &&
+ join->best_positions[i].use_join_buffer)
join->full_join= 1;
}
tmp= NULL;
+
if (cond)
- tmp= make_cond_for_table(cond,used_tables,current_map);
+ {
+ if (tab->bush_children)
+ {
+ // Reached the materialization tab
+ tmp= make_cond_after_sjm(cond, cond, save_used_tables, used_tables,
+ /*inside_or_clause=*/FALSE);
+ used_tables= save_used_tables | used_tables;
+ save_used_tables= 0;
+ }
+ else
+ {
+ tmp= make_cond_for_table(thd, cond, used_tables, current_map, i,
+ FALSE, FALSE);
+ }
+ /* Add conditions added by add_not_null_conds(). */
+ if (tab->select_cond)
+ add_cond_and_fix(thd, &tmp, tab->select_cond);
+ }
+
+ is_hj= (tab->type == JT_REF || tab->type == JT_EQ_REF) &&
+ (join->allowed_join_cache_types & JOIN_CACHE_HASHED_BIT) &&
+ ((join->max_allowed_join_cache_level+1)/2 == 2 ||
+ ((join->max_allowed_join_cache_level+1)/2 > 2 &&
+ is_hash_join_key_no(tab->ref.key))) &&
+ (!tab->emb_sj_nest ||
+ join->allowed_semijoin_with_cache) &&
+ (!(tab->table->map & join->outer_join) ||
+ join->allowed_outer_join_with_cache);
+
if (cond && !tmp && tab->quick)
{ // Outer join
- if (tab->type != JT_ALL)
+ if (tab->type != JT_ALL && !is_hj)
{
/*
Don't use the quick method
@@ -6497,11 +8513,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.c_ptr(),
- QT_ORDINARY););
+ DBUG_EXECUTE("where",print_where(tmp,
+ tab->table? tab->table->alias.c_ptr() :"sjm-nest",
+ QT_ORDINARY););
SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
thd->memdup((uchar*) select,
sizeof(*select)));
@@ -6521,35 +8538,47 @@ 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 */
- if (thd->variables.engine_condition_pushdown)
+ if (tab->table)
{
- COND *push_cond=
- make_cond_for_table(tmp, current_map, current_map);
- if (push_cond)
+ tab->table->file->pushed_cond= NULL;
+ if (thd->variables.engine_condition_pushdown && !first_inner_tab)
{
- /* Push condition to handler */
- if (!tab->table->file->cond_push(push_cond))
- tab->table->file->pushed_cond= push_cond;
+ COND *push_cond=
+ make_cond_for_table(thd, tmp, current_map, current_map,
+ -1, FALSE, FALSE);
+ if (push_cond)
+ {
+ /* Push condition to handler */
+ if (!tab->table->file->cond_push(push_cond))
+ tab->table->file->pushed_cond= push_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.c_ptr(),
+ print_where(tmp,
+ tab->table ? tab->table->alias.c_ptr() :
+ "(sjm-nest)",
QT_ORDINARY););
if (tab->quick)
{
/* Use quick key read if it's a constant and it's not used
with key reading */
- if (tab->needed_reg.is_clear_all() && tab->type != JT_EQ_REF
- && tab->type != JT_FT && (tab->type != JT_REF ||
- (uint) tab->ref.key == tab->quick->index))
+ if ((tab->needed_reg.is_clear_all() && tab->type != JT_EQ_REF
+ && tab->type != JT_FT &&
+ ((tab->type != JT_REF && tab->type != JT_CONST) ||
+ (uint) tab->ref.key == tab->quick->index)) || is_hj)
{
sel->quick=tab->quick; // Use value from get_quick_...
sel->quick_keys.clear_all();
@@ -6561,7 +8590,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
}
tab->quick=0;
}
- uint ref_key=(uint) sel->head->reginfo.join_tab->ref.key+1;
+ uint ref_key= sel->head? (uint) sel->head->reginfo.join_tab->ref.key+1 : 0;
if (i == join->const_tables && ref_key)
{
if (!tab->const_keys.is_clear_all() &&
@@ -6580,12 +8609,12 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
the index if we are using limit and this is the first table
*/
- if ((cond &&
- (!tab->keys.is_subset(tab->const_keys) && i > 0)) ||
- (!tab->const_keys.is_clear_all() && i == join->const_tables &&
- join->unit->select_limit_cnt <
- join->best_positions[i].records_read &&
- !(join->select_options & OPTION_FOUND_ROWS)))
+ if (!tab->table->is_filled_at_execution() &&
+ ((cond && (!tab->keys.is_subset(tab->const_keys) && i > 0)) ||
+ (!tab->const_keys.is_clear_all() && i == join->const_tables &&
+ join->unit->select_limit_cnt <
+ join->best_positions[i].records_read &&
+ !(join->select_options & OPTION_FOUND_ROWS))))
{
/* Join with outer join condition */
COND *orig_cond=sel->cond;
@@ -6602,11 +8631,13 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
sel->cond->quick_fix_field();
if (sel->test_quick_select(thd, tab->keys,
- used_tables & ~ current_map,
+ ((used_tables & ~ current_map) |
+ OUTER_REF_TABLE_BIT),
(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
@@ -6619,7 +8650,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
@@ -6646,26 +8678,17 @@ 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);
+ }
}
}
/*
- Push down conditions from all on expressions.
+ Push down conditions from all ON expressions.
Each of these conditions are guarded by a variable
that turns if off just before null complemented row for
outer joins is formed. Thus, the condition from an
@@ -6673,16 +8696,32 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
the null complemented row.
*/
- /* First push down constant conditions from on expressions */
- for (JOIN_TAB *join_tab= join->join_tab+join->const_tables;
- join_tab < join->join_tab+join->tables ; join_tab++)
+ /*
+ First push down constant conditions from ON expressions.
+ - Each pushed-down condition is wrapped into trigger which is
+ enabled only for non-NULL-complemented record
+ - The condition is attached to the first_inner_table.
+
+ With regards to join nests:
+ - if we start at top level, don't walk into nests
+ - if we start inside a nest, stay within that nest.
+ */
+ JOIN_TAB *start_from= tab->bush_root_tab?
+ tab->bush_root_tab->bush_children->start :
+ join->join_tab + join->const_tables;
+ JOIN_TAB *end_with= tab->bush_root_tab?
+ tab->bush_root_tab->bush_children->end :
+ join->join_tab + join->top_join_tab_count;
+ for (JOIN_TAB *join_tab= start_from;
+ join_tab != end_with;
+ join_tab++)
{
if (*join_tab->on_expr_ref)
{
JOIN_TAB *cond_tab= join_tab->first_inner;
- COND *tmp= make_cond_for_table(*join_tab->on_expr_ref,
+ COND *tmp= make_cond_for_table(thd, *join_tab->on_expr_ref,
join->const_table_map,
- (table_map) 0);
+ (table_map) 0, -1, FALSE, FALSE);
if (!tmp)
continue;
tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
@@ -6694,13 +8733,22 @@ 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;
}
}
- /* Push down non-constant conditions from on expressions */
+
+ /* Push down non-constant conditions from ON expressions */
JOIN_TAB *last_tab= tab;
+
+ /*
+ while we're inside of an outer join and last_tab is
+ the last of its tables ...
+ */
while (first_inner_tab && first_inner_tab->last_inner == last_tab)
- {
+ {
/*
Table tab is the last inner table of an outer join.
An on expression is always attached to it.
@@ -6709,13 +8757,54 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
table_map used_tables2= (join->const_table_map |
OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
- for (tab= join->join_tab+join->const_tables; tab <= last_tab ; tab++)
+
+ start_from= tab->bush_root_tab?
+ tab->bush_root_tab->bush_children->start :
+ join->join_tab + join->const_tables;
+ for (JOIN_TAB *tab= start_from; tab <= last_tab; tab++)
{
+ DBUG_ASSERT(tab->table);
current_map= tab->table->map;
used_tables2|= current_map;
- COND *tmp_cond= make_cond_for_table(on_expr, used_tables2,
- current_map);
- if (tmp_cond)
+ /*
+ psergey: have put the -1 below. It's bad, will need to fix it.
+ */
+ COND *tmp_cond= make_cond_for_table(thd, on_expr, used_tables2,
+ current_map, /*(tab - first_tab)*/ -1,
+ FALSE, FALSE);
+ bool is_sjm_lookup_tab= FALSE;
+ if (tab->bush_children)
+ {
+ /*
+ 'tab' is an SJ-Materialization tab, i.e. we have a join order
+ like this:
+
+ ot1 sjm_tab LEFT JOIN ot2 ot3
+ ^ ^
+ 'tab'-+ +--- left join we're adding triggers for
+
+ LEFT JOIN's ON expression may not have references to subquery
+ columns. The subquery was in the WHERE clause, so IN-equality
+ is in the WHERE clause, also.
+ However, equality propagation code may have propagated the
+ IN-equality into ON expression, and we may get things like
+
+ subquery_inner_table=const
+
+ in the ON expression. We must not check such conditions during
+ SJM-lookup, because 1) subquery_inner_table has no valid current
+ row (materialization temp.table has it instead), and 2) they
+ would be true anyway.
+ */
+ SJ_MATERIALIZATION_INFO *sjm=
+ tab->bush_children->start->emb_sj_nest->sj_mat_info;
+ if (sjm->is_used && !sjm->is_sj_scan)
+ is_sjm_lookup_tab= TRUE;
+ }
+
+ if (tab == first_inner_tab && tab->on_precond && !is_sjm_lookup_tab)
+ add_cond_and_fix(thd, &tmp_cond, tab->on_precond);
+ if (tmp_cond && !is_sjm_lookup_tab)
{
JOIN_TAB *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
Item **sel_cond_ref= tab < first_inner_tab ?
@@ -6751,7 +8840,10 @@ 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;
}
@@ -6761,6 +8853,290 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
}
+static
+uint get_next_field_for_derived_key(uchar *arg)
+{
+ KEYUSE *keyuse= *(KEYUSE **) arg;
+ if (!keyuse)
+ return (uint) (-1);
+ TABLE *table= keyuse->table;
+ uint key= keyuse->key;
+ uint fldno= keyuse->keypart;
+ uint keypart= keyuse->keypart_map == (key_part_map) 1 ?
+ 0 : (keyuse-1)->keypart+1;
+ for ( ;
+ keyuse->table == table && keyuse->key == key && keyuse->keypart == fldno;
+ keyuse++)
+ keyuse->keypart= keypart;
+ if (keyuse->key != key)
+ keyuse= 0;
+ *((KEYUSE **) arg)= keyuse;
+ return fldno;
+}
+
+
+static
+bool generate_derived_keys_for_table(KEYUSE *keyuse, uint count, uint keys)
+{
+ TABLE *table= keyuse->table;
+ if (table->alloc_keys(keys))
+ return TRUE;
+ uint key_count= 0;
+ KEYUSE *first_keyuse= keyuse;
+ uint prev_part= keyuse->keypart;
+ uint parts= 0;
+ uint i= 0;
+
+ for ( ; i < count && key_count < keys; )
+ {
+ do
+ {
+ keyuse->key= table->s->keys;
+ keyuse->keypart_map= (key_part_map) (1 << parts);
+ keyuse++;
+ i++;
+ }
+ while (i < count && keyuse->used_tables == first_keyuse->used_tables &&
+ keyuse->keypart == prev_part);
+ parts++;
+ if (i < count && keyuse->used_tables == first_keyuse->used_tables)
+ {
+ prev_part= keyuse->keypart;
+ }
+ else
+ {
+ if (table->add_tmp_key(table->s->keys, parts,
+ get_next_field_for_derived_key,
+ (uchar *) &first_keyuse,
+ FALSE))
+ return TRUE;
+ table->reginfo.join_tab->keys.set_bit(table->s->keys);
+ first_keyuse= keyuse;
+ key_count++;
+ parts= 0;
+ prev_part= keyuse->keypart;
+ }
+ }
+
+ return FALSE;
+}
+
+
+static
+bool generate_derived_keys(DYNAMIC_ARRAY *keyuse_array)
+{
+ KEYUSE *keyuse= dynamic_element(keyuse_array, 0, KEYUSE*);
+ uint elements= keyuse_array->elements;
+ TABLE *prev_table= 0;
+ for (uint i= 0; i < elements; i++, keyuse++)
+ {
+ if (!keyuse->table)
+ break;
+ KEYUSE *first_table_keyuse= NULL;
+ table_map last_used_tables= 0;
+ uint count= 0;
+ uint keys= 0;
+ TABLE_LIST *derived= NULL;
+ if (keyuse->table != prev_table)
+ derived= keyuse->table->pos_in_table_list;
+ while (derived && derived->is_materialized_derived())
+ {
+ if (keyuse->table != prev_table)
+ {
+ prev_table= keyuse->table;
+ while (keyuse->table == prev_table && keyuse->key != MAX_KEY)
+ {
+ keyuse++;
+ i++;
+ }
+ if (keyuse->table != prev_table)
+ {
+ keyuse--;
+ i--;
+ derived= NULL;
+ continue;
+ }
+ first_table_keyuse= keyuse;
+ last_used_tables= keyuse->used_tables;
+ count= 0;
+ keys= 0;
+ }
+ else if (keyuse->used_tables != last_used_tables)
+ {
+ keys++;
+ last_used_tables= keyuse->used_tables;
+ }
+ count++;
+ keyuse++;
+ i++;
+ if (keyuse->table != prev_table)
+ {
+ if (generate_derived_keys_for_table(first_table_keyuse, count, ++keys))
+ return TRUE;
+ keyuse--;
+ i--;
+ derived= NULL;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+/*
+ @brief
+ Drops unused keys for each materialized derived table/view
+
+ @details
+ For materialized derived tables only ref access can be used, it employs
+ only one index, thus we don't need the rest. For each materialized derived
+ table/view call TABLE::use_index to save one index chosen by the optimizer
+ and free others. No key is chosen then all keys will be dropped.
+*/
+
+void JOIN::drop_unused_derived_keys()
+{
+ JOIN_TAB *tab;
+ for (tab= first_linear_tab(this, WITHOUT_CONST_TABLES);
+ tab;
+ tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
+ {
+
+ TABLE *table=tab->table;
+ if (!table)
+ continue;
+ if (!table->pos_in_table_list->is_materialized_derived())
+ continue;
+ if (table->max_keys > 1)
+ table->use_index(tab->ref.key);
+ if (table->s->keys)
+ {
+ if (tab->ref.key >= 0)
+ tab->ref.key= 0;
+ else
+ table->s->keys= 0;
+ }
+ tab->keys= (key_map) (table->s->keys ? 1 : 0);
+ }
+}
+
+
+/*
+ Evaluate the bitmap of used tables for items from the select list
+*/
+
+inline void JOIN::eval_select_list_used_tables()
+{
+ select_list_used_tables= 0;
+ Item *item;
+ List_iterator_fast<Item> it(fields_list);
+ while ((item= it++))
+ {
+ select_list_used_tables|= item->used_tables();
+ }
+ Item_outer_ref *ref;
+ List_iterator_fast<Item_outer_ref> ref_it(select_lex->inner_refs_list);
+ while ((ref= ref_it++))
+ {
+ item= ref->outer_ref;
+ select_list_used_tables|= item->used_tables();
+ }
+}
+
+
+/*
+ Determine {after which table we'll produce ordered set}
+
+ 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)
+{
+ /*
+ This function needs to be fixed to take into account that we now have SJM
+ nests.
+ */
+ DBUG_ASSERT(0);
+
+ JOIN_TAB *tab;
+ if (join->need_tmp)
+ return join->table_count;
+ tab= join->get_sort_by_join_tab();
+ return tab ? tab-join->join_tab : join->table_count;
+}
+
+/*
+ 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;
+ join_tab->used_join_cache_level= 0;
+ /*
+ 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;
+ if (join_tab->type == JT_REF && join_tab->is_ref_for_hash_join())
+ {
+ join_tab->type= JT_ALL;
+ join_tab->ref.key_parts= 0;
+ }
+ join_tab->join->return_tab= join_tab;
+ }
+}
+
+
/**
The default implementation of unlock-row method of READ_RECORD,
used in all access methods.
@@ -6769,11 +9145,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
void rr_unlock_row(st_join_table *tab)
{
READ_RECORD *info= &tab->read_record;
- info->file->unlock_row();
+ info->table->file->unlock_row();
}
-
/**
Pick the appropriate access method functions
@@ -6824,47 +9199,692 @@ 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; 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; tab >= first_inner; tab--)
+ {
+ 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 Points to right after the last join_tab in materialization bush
+ 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
+*/
+
+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_tmp_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
+ options options of the join
+ no_jbuf_after don't use join buffering after table with this number
+ prev_tab previous join 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 uses
+ neither BNLH algorithm, nor BKAH algorithm to perform join operations.
+
+ If the optimizer switch join_cache_bka is off then the optimizer uses
+ neither BKA algorithm, 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.
+ If the function decides that but some reasons no join buffer can be used
+ for a table it calls the function revise_cache_usage that checks
+ whether join cache should be denied for some previous tables. In this case
+ a pointer to the first table for which join cache usage has been denied
+ is passed in join->return_val (see the function set_join_cache_denial).
+
+ The functions changes the value the fields tab->icp_other_tables_ok and
+ tab->idx_cond_fact_out to FALSE if the chosen join cache algorithm
+ requires it.
+
+ 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_incremental to 'off' 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,
+ ulonglong options,
+ uint no_jbuf_after,
+ uint table_index,
+ JOIN_TAB *prev_tab)
{
+ COST_VECT cost;
+ uint flags= 0;
+ ha_rows rows= 0;
+ uint bufsz= 4096;
+ JOIN_CACHE *prev_cache=0;
+ JOIN *join= tab->join;
+ uint cache_level= tab->used_join_cache_level;
+ bool force_unlinked_cache=
+ !(join->allowed_join_cache_types & JOIN_CACHE_INCREMENTAL_BIT);
+ bool no_hashed_cache=
+ !(join->allowed_join_cache_types & JOIN_CACHE_HASHED_BIT);
+ bool no_bka_cache=
+ !(join->allowed_join_cache_types & JOIN_CACHE_BKA_BIT);
+
+ join->return_tab= 0;
+
+ /*
+ Don't use join cache if @@join_cache_level==0 or this table is the first
+ one join suborder (either at top level or inside a bush)
+ */
+ if (cache_level == 0 || !prev_tab)
+ return 0;
+
+ if (force_unlinked_cache && (cache_level%2 == 0))
+ cache_level--;
+
+ if (options & SELECT_NO_JOIN_CACHE)
+ goto no_join_cache;
+
+ if (tab->use_quick == 2)
+ goto no_join_cache;
+
+ if (tab->table->map & join->complex_firstmatch_tables)
+ goto no_join_cache;
+
+ /*
+ Don't use join cache if we're inside a join tab range covered by LooseScan
+ strategy (TODO: LooseScan is very similar to FirstMatch so theoretically it
+ should be possible to use join buffering in the same way we're using it for
+ multi-table firstmatch ranges).
+ */
+ if (tab->inside_loosescan_range)
+ goto no_join_cache;
+
+ if (tab->is_inner_table_of_semijoin() &&
+ !join->allowed_semijoin_with_cache)
+ goto no_join_cache;
+ if (tab->is_inner_table_of_outer_join() &&
+ !join->allowed_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 is not meaningfully used currently)
+ */
+ if (table_index > no_jbuf_after)
+ goto no_join_cache;
+
+ /*
+ TODO: BNL join buffer should be perfectly ok with tab->bush_children.
+ */
+ if (tab->loosescan_match_tab || tab->bush_children)
+ 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 || !(tab-1)->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 || !(tab-1)->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 && tab != 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 != tab->first_sj_inner_tab &&
+ tab->first_sj_inner_tab == tab[-1].first_sj_inner_tab)
+ goto no_join_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()))
+ {
+ tab->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;
+ if (tab->ref.is_access_triggered())
+ goto no_join_cache;
+
+ if (!tab->is_ref_for_hash_join())
+ {
+ flags= HA_MRR_NO_NULL_ENDPOINTS | HA_MRR_SINGLE_POINT;
+ 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 ||
+ tab->is_ref_for_hash_join() ||
+ ((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)
+ prev_cache= 0;
+ if ((tab->cache= new JOIN_CACHE_BNLH(join, tab, prev_cache)) &&
+ ((options & SELECT_DESCRIBE) || !tab->cache->init()))
+ {
+ tab->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()))
+ {
+ tab->idx_cond_fact_out= FALSE;
+ return (8-test(!prev_cache));
+ }
+ goto no_join_cache;
+ }
+ }
+ goto no_join_cache;
+ default : ;
+ }
+
+no_join_cache:
+ if (tab->type != JT_ALL && tab->is_ref_for_hash_join())
+ {
+ tab->type= JT_ALL;
+ tab->ref.key_parts= 0;
+ }
+ revise_cache_usage(tab);
+ return 0;
+}
+
+
+/*
+ Check whether join buffers can be used to join tables of a join
+
+ SYNOPSIS
+ check_join_cache_usage()
+ join join whose tables are to be checked
+ options options of the join
+ no_jbuf_after don't use join buffering after table with this number
+ (The tables are assumed to be numbered in
+ first_linear_tab(join, WITHOUT_CONST_TABLES),
+ next_linear_tab(join, WITH_CONST_TABLES) order).
+
+ DESCRIPTION
+ For each table after the first non-constant table the function checks
+ whether the table can be joined using a join buffer. 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 whose level is not greater
+ than join_cache_level set for the join. To make this check the function
+ calls the function check_join_cache_usage for every non-constant table.
+
+ NOTES
+ In some situations (e.g. for nested outer joins, for nested semi-joins) only
+ incremental buffers can be used. If it turns out that for some inner table
+ no join buffer can be used then any inner table of an outer/semi-join nest
+ cannot use join buffer. In the case when already chosen buffer must be
+ denied for a table the function recalls check_join_cache_usage()
+ starting from this table. The pointer to the table from which the check
+ has to be restarted is returned in join->return_val (see the description
+ of check_join_cache_usage).
+*/
+
+void check_join_cache_usage_for_tables(JOIN *join, ulonglong options,
+ uint no_jbuf_after)
+{
+ JOIN_TAB *tab;
+ JOIN_TAB *prev_tab;
+
+ for (tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
+ tab;
+ tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
+ {
+ tab->used_join_cache_level= join->max_allowed_join_cache_level;
+ }
+
+ uint idx= join->const_tables;
+ for (tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
+ tab;
+ tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
+ {
+restart:
+ tab->icp_other_tables_ok= TRUE;
+ tab->idx_cond_fact_out= TRUE;
+
+ /*
+ Check if we have a preceding join_tab, as something that will feed us
+ records that we could buffer. We don't have it, if
+ - this is the first non-const table in the join order,
+ - this is the first table inside an SJM nest.
+ */
+ prev_tab= tab - 1;
+ if (tab == join->join_tab + join->const_tables ||
+ (tab->bush_root_tab && tab->bush_root_tab->bush_children->start == tab))
+ prev_tab= NULL;
+
+ switch (tab->type) {
+ case JT_SYSTEM:
+ case JT_CONST:
+ case JT_EQ_REF:
+ case JT_REF:
+ case JT_REF_OR_NULL:
+ case JT_ALL:
+ tab->used_join_cache_level= check_join_cache_usage(tab, options,
+ no_jbuf_after,
+ idx,
+ prev_tab);
+ tab->use_join_cache= test(tab->used_join_cache_level);
+ /*
+ psergey-merge: todo: raise the question that this is really stupid that
+ we can first allocate a join buffer, then decide not to use it and free
+ it.
+ */
+ if (join->return_tab)
+ {
+ tab= join->return_tab;
+ goto restart;
+ }
+ break;
+ default:
+ tab->used_join_cache_level= 0;
+ }
+ if (!tab->bush_children)
+ idx++;
+ }
+}
+
+
+/*
+ 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)
+{
+ JOIN_TAB *tab;
uint i;
+ DBUG_ENTER("make_join_readinfo");
+
bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
- bool ordered_set= 0;
bool sorted= 1;
- DBUG_ENTER("make_join_readinfo");
- for (i=join->const_tables ; i < join->tables ; i++)
+ join->complex_firstmatch_tables= table_map(0);
+
+ if (!join->select_lex->sj_nests.is_empty() &&
+ setup_semijoin_dups_elimination(join, options, no_jbuf_after))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+
+ /* For const tables, set partial_join_cardinality to 1. */
+ for (tab= join->join_tab; tab != join->join_tab + join->const_tables; tab++)
+ tab->partial_join_cardinality= 1;
+
+ JOIN_TAB *prev_tab= NULL;
+ for (tab= first_linear_tab(join, WITHOUT_CONST_TABLES), i= join->const_tables;
+ tab;
+ prev_tab=tab, tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
+ {
+ /*
+ 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 (tab->bush_root_tab && tab->bush_root_tab->bush_children->start == tab)
+ prev_tab= NULL;
+ DBUG_ASSERT(tab->bush_children || tab->table == join->best_positions[i].table->table);
+
+ tab->partial_join_cardinality= join->best_positions[i].records_read *
+ (prev_tab? prev_tab->partial_join_cardinality : 1);
+ if (!tab->bush_children)
+ i++;
+ }
+
+ check_join_cache_usage_for_tables(join, options, no_jbuf_after);
+
+ JOIN_TAB *first_tab;
+ for (tab= first_tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
+ tab;
+ tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
- JOIN_TAB *tab=join->join_tab+i;
+ if (tab->bush_children)
+ {
+ if (setup_sj_materialization_part2(tab))
+ return TRUE;
+ }
+
TABLE *table=tab->table;
+ uint jcl= tab->used_join_cache_level;
tab->read_record.table= table;
- tab->read_record.file=table->file;
tab->read_record.unlock_row= rr_unlock_row;
- tab->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.
+ We should not set tab->next_select for the last table in the
+ SMJ-nest, as setup_sj_materialization() has already set it to
+ end_sj_materialize.
*/
- if (!ordered_set && !join->need_tmp &&
- (table == join->sort_by_table ||
- (join->sort_by_table == (TABLE *) 1 && i != join->const_tables)))
- ordered_set= 1;
+ if (!(tab->bush_root_tab &&
+ tab->bush_root_tab->bush_children->end == tab + 1))
+ {
+ tab->next_select=sub_select; /* normal select */
+ }
- tab->sorted= sorted;
- sorted= 0; // only first must be sorted
+
+ if (tab->loosescan_match_tab)
+ {
+ if (!(tab->loosescan_buf= (uchar*)join->thd->alloc(tab->
+ loosescan_key_len)))
+ return TRUE; /* purecov: inspected */
+ tab->sorted= TRUE;
+ }
table->status=STATUS_NO_RECORD;
pick_table_access_method (tab);
+ if (jcl)
+ tab[-1].next_select=sub_select_cache;
+
+ if (tab->cache && tab->cache->get_join_alg() == JOIN_CACHE::BNLH_JOIN_ALG)
+ tab->type= JT_HASH;
+
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) && !tab->ref.is_access_triggered())
+ push_index_cond(tab, tab->ref.key);
+ 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) && !tab->ref.is_access_triggered())
+ push_index_cond(tab, tab->ref.key);
+ break;
case JT_REF_OR_NULL:
case JT_REF:
if (tab->select)
@@ -6874,27 +9894,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) && !tab->ref.is_access_triggered())
+ push_index_cond(tab, tab->ref.key);
break;
case JT_ALL:
+ case JT_HASH:
/*
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)
{
@@ -6905,8 +9918,9 @@ make_join_readinfo(JOIN *join, ulonglong options)
}
else
{
- tab->read_first_record= join_init_read_record;
- if (i == join->const_tables)
+ if (!tab->bush_children)
+ tab->read_first_record= join_init_read_record;
+ if (tab == first_tab)
{
if (tab->select && tab->select->quick)
{
@@ -6928,14 +9942,16 @@ make_join_readinfo(JOIN *join, ulonglong options)
if (tab->select && tab->select->quick)
{
if (statistics)
- status_var_increment(join->thd->status_var.select_full_range_join_count);
+ status_var_increment(join->thd->status_var.
+ select_full_range_join_count);
}
else
{
join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
if (statistics)
{
- status_var_increment(join->thd->status_var.select_full_join_count);
+ status_var_increment(join->thd->status_var.
+ select_full_join_count);
join->thd->query_plan_flags|= QPLAN_FULL_JOIN;
}
}
@@ -6949,37 +9965,80 @@ make_join_readinfo(JOIN *join, ulonglong options)
else if (!table->covering_keys.is_clear_all() &&
!(tab->select && tab->select->quick))
{ // Only read index tree
+#ifdef BAD_OPTIMIZATION
/*
- It has turned out that the below change, while speeding things
- up for disk-bound loads, slows them down for cases when the data
- is in disk cache (see BUG#35850):
- // See bug #26447: "Using the clustered index for a table scan
- // is always faster than using a secondary index".
+ It has turned out that the below change, while speeding things
+ up for disk-bound loads, slows them down for cases when the data
+ is in disk cache (see BUG#35850):
+ See bug #26447: "Using the clustered index for a table scan
+ is always faster than using a secondary index".
+ */
if (table->s->primary_key != MAX_KEY &&
table->file->primary_key_is_clustered())
tab->index= table->s->primary_key;
else
- */
+#endif
tab->index=find_shortest_key(table, & table->covering_keys);
tab->read_first_record= join_read_first;
- tab->type=JT_NEXT; // Read with index_first / index_next
+ /* Read with index_first / index_next */
+ tab->type= tab->type == JT_ALL ? JT_NEXT : JT_HASH_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);
}
break;
case JT_FT:
- case JT_SYSTEM:
break;
+ /* purecov: begin deadcode */
default:
- DBUG_PRINT("error",("Table type %d found",tab->type)); /* purecov: deadcode */
- break; /* purecov: deadcode */
+ DBUG_PRINT("error",("Table type %d found",tab->type));
+ break;
case JT_UNKNOWN:
case JT_MAYBE_REF:
- abort(); /* purecov: deadcode */
+ abort();
+ /* purecov: end */
}
}
- join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
- DBUG_VOID_RETURN;
+ uint n_top_tables= join->join_tab_ranges.head()->end -
+ join->join_tab_ranges.head()->start;
+
+ join->join_tab[n_top_tables - 1].next_select=0; /* Set by do_select */
+
+ /*
+ 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 (tab= join->join_tab + join->const_tables ;
+ tab != join->join_tab + n_top_tables ; tab++)
+ {
+ 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;
+ }
+ else if (sort_by_tab->type == JT_HASH_NEXT)
+ {
+ sort_by_tab->type= JT_HASH;
+ sort_by_tab->read_first_record= join_init_read_record;
+ }
+ }
+ break;
+ }
+ }
+
+ DBUG_RETURN(FALSE);
}
@@ -6999,14 +10058,11 @@ make_join_readinfo(JOIN *join, ulonglong options)
bool error_if_full_join(JOIN *join)
{
- for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
- tab < end;
- tab++)
+ for (JOIN_TAB *tab=first_top_level_tab(join, WITH_CONST_TABLES); tab;
+ tab= next_top_level_tab(join, tab))
{
if (tab->type == JT_ALL && (!tab->select || !tab->select->quick))
{
- /* This error should not be ignored. */
- join->select_lex->no_error= FALSE;
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
return(1);
@@ -7018,21 +10074,53 @@ bool error_if_full_join(JOIN *join)
/**
cleanup JOIN_TAB.
+
+ DESCRIPTION
+ This is invoked when we've finished all join executions.
*/
void JOIN_TAB::cleanup()
{
+ DBUG_ENTER("JOIN_TAB::cleanup");
+ DBUG_PRINT("enter", ("table %s.%s",
+ (table ? table->s->db.str : "?"),
+ (table ? table->s->table_name.str : "?")));
delete select;
select= 0;
delete quick;
quick= 0;
- x_free(cache.buff);
- cache.buff= 0;
+ if (cache)
+ {
+ cache->free();
+ cache= 0;
+ }
limit= 0;
if (table)
{
table->disable_keyread();
table->file->ha_index_or_rnd_end();
+ preread_init_done= FALSE;
+ if (table->pos_in_table_list &&
+ table->pos_in_table_list->jtbm_subselect)
+ {
+ if (table->pos_in_table_list->jtbm_subselect->is_jtbm_const_tab)
+ {
+ free_tmp_table(join->thd, table);
+ table= NULL;
+ }
+ else
+ {
+ end_read_record(&read_record);
+ table->pos_in_table_list->jtbm_subselect->cleanup();
+ /*
+ The above call freed the materializedd temptable. Set it to NULL so
+ that we don't attempt to touch it if JOIN_TAB::cleanup() is invoked
+ multiple times (it may be)
+ */
+ table=NULL;
+ }
+ DBUG_VOID_RETURN;
+ }
/*
We need to reset this for next select
(Tested in part_of_refkey)
@@ -7040,6 +10128,156 @@ void JOIN_TAB::cleanup()
table->reginfo.join_tab= 0;
}
end_read_record(&read_record);
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ Estimate the time to get rows of the joined table
+*/
+
+double JOIN_TAB::scan_time()
+{
+ double res;
+ if (table->created)
+ {
+ if (table->is_filled_at_execution())
+ {
+ get_delayed_table_estimates(table, &records, &read_time,
+ &startup_cost);
+ found_records= records;
+ table->quick_condition_rows= records;
+ }
+ else
+ {
+ found_records= records= table->file->stats.records;
+ read_time= table->file->scan_time();
+ /*
+ table->quick_condition_rows has already been set to
+ table->file->stats.records
+ */
+ }
+ res= read_time;
+ }
+ else
+ {
+ found_records= records=table->file->stats.records;
+ read_time= found_records ? (double)found_records: 10.0;// TODO:fix this stub
+ res= read_time;
+ }
+ return res;
+}
+
+/**
+ Initialize the join_tab before reading.
+ Currently only derived table/view materialization is done here.
+
+ TODO: consider moving this together with join_tab_execution_startup
+*/
+bool JOIN_TAB::preread_init()
+{
+ TABLE_LIST *derived= table->pos_in_table_list;
+ if (!derived || !derived->is_materialized_derived())
+ {
+ preread_init_done= TRUE;
+ return FALSE;
+ }
+
+ /* Materialize derived table/view. */
+ if (!derived->get_unit()->executed &&
+ mysql_handle_single_derived(join->thd->lex,
+ derived, DT_CREATE | DT_FILL))
+ return TRUE;
+ preread_init_done= TRUE;
+ if (select && select->quick)
+ select->quick->replace_handler(table->file);
+ return FALSE;
+}
+
+
+/**
+ 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
+ @param skip Number of fields from the beginning to skip
+
+ @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 skip)
+{
+ uint tmp_key_parts= tmp_key->key_parts;
+ uint i;
+ DBUG_ENTER("TABLE_REF::tmp_table_index_lookup_init");
+
+ key= 0; /* The only temp table index. */
+ 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 (i= 0; i < skip; i++) it.next();
+ for (i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
+ {
+ Item *item= it.next();
+ DBUG_ASSERT(item);
+ 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);
+}
+
+
+/*
+ Check if ref access uses "Full scan on NULL key" (i.e. it actually alternates
+ between ref access and full table scan)
+*/
+
+bool TABLE_REF::is_access_triggered()
+{
+ for (uint i = 0; i < key_parts; i++)
+ {
+ if (cond_guards[i])
+ return TRUE;
+ }
+ return FALSE;
}
@@ -7094,7 +10332,7 @@ void JOIN::join_free()
Optimization: if not EXPLAIN and we are done with the JOIN,
free all tables.
*/
- bool full= (!select_lex->uncacheable && !thd->lex->describe);
+ bool full= !(select_lex->uncacheable);
bool can_unlock= full;
DBUG_ENTER("JOIN::join_free");
@@ -7158,15 +10396,16 @@ void JOIN::join_free()
void JOIN::cleanup(bool full)
{
DBUG_ENTER("JOIN::cleanup");
+ DBUG_PRINT("enter", ("full %u", (uint) full));
if (table)
{
- JOIN_TAB *tab,*end;
+ JOIN_TAB *tab;
/*
Only a sorted table may be cached. This sorted table is always the
first non const table in join->table
*/
- if (tables > const_tables) // Test for not-const tables
+ if (table_count > const_tables) // Test for not-const tables
{
free_io_cache(table[const_tables]);
filesort_free_buffers(table[const_tables],full);
@@ -7174,16 +10413,24 @@ void JOIN::cleanup(bool full)
if (full)
{
- for (tab= join_tab, end= tab+tables; tab != end; tab++)
+ for (tab= first_linear_tab(this, WITH_CONST_TABLES); tab;
+ tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
+ {
tab->cleanup();
+ }
table= 0;
}
else
{
- for (tab= join_tab, end= tab+tables; tab != end; tab++)
+ for (tab= first_linear_tab(this, WITH_CONST_TABLES); tab;
+ tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
{
if (tab->table)
+ {
+ DBUG_PRINT("info", ("close index: %s.%s", tab->table->s->db.str,
+ tab->table->s->table_name.str));
tab->table->file->ha_index_or_rnd_end();
+ }
}
}
}
@@ -7243,6 +10490,8 @@ void JOIN::cleanup(bool full)
SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
@endcode
+
+ TODO: this function checks ORDER::used, which can only have a value of 0.
*/
static bool
@@ -7316,9 +10565,8 @@ only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables)
static void update_depend_map(JOIN *join)
{
- JOIN_TAB *join_tab=join->join_tab, *end=join_tab+join->tables;
-
- for (; join_tab != end ; join_tab++)
+ for (JOIN_TAB *join_tab= first_linear_tab(join, WITH_CONST_TABLES); join_tab;
+ join_tab= next_linear_tab(join, join_tab, WITH_BUSH_ROOTS))
{
TABLE_REF *ref= &join_tab->ref;
table_map depend_map=0;
@@ -7329,11 +10577,11 @@ static void update_depend_map(JOIN *join)
ref->depend_map=depend_map & ~OUTER_REF_TABLE_BIT;
depend_map&= ~OUTER_REF_TABLE_BIT;
for (JOIN_TAB **tab=join->map2table;
- depend_map ;
- tab++,depend_map>>=1 )
+ depend_map ;
+ tab++,depend_map>>=1 )
{
if (depend_map & 1)
- ref->depend_map|=(*tab)->ref.depend_map;
+ ref->depend_map|=(*tab)->ref.depend_map;
}
}
}
@@ -7341,7 +10589,7 @@ static void update_depend_map(JOIN *join)
/** Update the dependency map for the sort order. */
-static void update_depend_map(JOIN *join, ORDER *order)
+static void update_depend_map_for_order(JOIN *join, ORDER *order)
{
for (; order ; order=order->next)
{
@@ -7388,21 +10636,30 @@ static ORDER *
remove_const(JOIN *join,ORDER *first_order, COND *cond,
bool change_list, bool *simple_order)
{
- if (join->tables == join->const_tables)
+ if (join->table_count == join->const_tables)
return change_list ? 0 : first_order; // No need to sort
ORDER *order,**prev_ptr;
- table_map first_table= join->join_tab[join->const_tables].table->map;
+ table_map first_table;
table_map not_const_tables= ~join->const_table_map;
table_map ref;
+ bool first_is_base_table= FALSE;
DBUG_ENTER("remove_const");
+
+ LINT_INIT(first_table); /* protected by first_is_base_table */
+ if (join->join_tab[join->const_tables].table)
+ {
+ first_table= join->join_tab[join->const_tables].table->map;
+ first_is_base_table= TRUE;
+ }
+
/*
Cleanup to avoid interference of calls of this function for
ORDER BY and GROUP BY
*/
for (JOIN_TAB *tab= join->join_tab + join->const_tables;
- tab < join->join_tab + join->tables;
+ tab < join->join_tab + join->table_count;
tab++)
tab->cached_eq_ref_table= FALSE;
@@ -7411,7 +10668,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
/* NOTE: A variable of not_const_tables ^ first_table; breaks gcc 2.7 */
- update_depend_map(join, first_order);
+ update_depend_map_for_order(join, first_order);
for (order=first_order; order ; order=order->next)
{
table_map order_tables=order->item[0]->used_tables();
@@ -7426,16 +10683,21 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
table for all queries containing more than one table, ROLLUP, and an
outer join.
*/
- (join->tables > 1 && join->rollup.state == ROLLUP::STATE_INITED &&
+ (join->table_count > 1 && join->rollup.state == ROLLUP::STATE_INITED &&
join->outer_join))
*simple_order=0; // Must do a temp table to sort
else if (!(order_tables & not_const_tables))
{
- if (order->item[0]->with_subselect &&
- !(join->select_lex->options & SELECT_DESCRIBE))
- order->item[0]->val_str(&order->item[0]->str_value);
+ if (order->item[0]->with_subselect)
+ {
+ /*
+ Delay the evaluation of constant ORDER and/or GROUP expressions that
+ contain subqueries until the execution phase.
+ */
+ join->exec_const_order_group_cond.push_back(order->item[0]);
+ }
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
- continue; // skip const item
+ continue;
}
else
{
@@ -7449,7 +10711,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
continue;
}
- if ((ref=order_tables & (not_const_tables ^ first_table)))
+ if (first_is_base_table && (ref=order_tables & (not_const_tables ^ first_table)))
{
if (!(order_tables & first_table) &&
only_eq_ref_tables(join,first_order, ref))
@@ -7475,7 +10737,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
static int
-return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
+return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
List<Item> &fields, bool send_row, ulonglong select_options,
const char *info, Item *having, List<Item> &all_fields)
{
@@ -7491,10 +10753,24 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
if (send_row)
{
+ /*
+ Set all tables to have NULL row. This is needed as we will be evaluating
+ HAVING condition.
+ */
+ List_iterator<TABLE_LIST> ti(tables);
+ TABLE_LIST *table;
+ while ((table= ti++))
+ {
+ /*
+ Don't touch semi-join materialization tables, as the above join_free()
+ call has freed them (and HAVING clause can't have references to them
+ anyway).
+ */
+ if (!table->is_jtbm())
+ mark_as_null_row(table->table); // All fields are NULL
+ }
List_iterator_fast<Item> it(all_fields);
Item *item;
- for (TABLE_LIST *table= tables; table; table= table->next_leaf)
- mark_as_null_row(table->table); // All fields are NULL
/*
Inform all items (especially aggregating) to calculate HAVING correctly,
also we will need it for sending results.
@@ -7527,8 +10803,11 @@ static void clear_tables(JOIN *join)
must clear only the non-const tables, as const tables
are not re-calculated.
*/
- for (uint i=join->const_tables ; i < join->tables ; i++)
- mark_as_null_row(join->table[i]); // All fields are NULL
+ for (uint i= 0 ; i < join->table_count ; i++)
+ {
+ if (!(join->table[i]->map & join->const_table_map))
+ mark_as_null_row(join->table[i]); // All fields are NULL
+ }
}
/*****************************************************************************
@@ -7672,6 +10951,9 @@ finish:
acceptable, as this happens rarely. The implementation without
copying would be much more complicated.
+ For description of how equality propagation works with SJM nests, grep
+ for EqualityPropagationAndSjmNests.
+
@param left_item left term of the quality to be checked
@param right_item right term of the equality to be checked
@param item equality item if the equality originates from a condition
@@ -7690,24 +10972,26 @@ finish:
static bool check_simple_equality(Item *left_item, Item *right_item,
Item *item, COND_EQUAL *cond_equal)
{
+ Item *orig_left_item= left_item;
+ Item *orig_right_item= right_item;
if (left_item->type() == Item::REF_ITEM &&
((Item_ref*)left_item)->ref_type() == Item_ref::VIEW_REF)
{
- if (((Item_ref*)left_item)->depended_from)
+ if (((Item_ref*)left_item)->get_depended_from())
return FALSE;
left_item= left_item->real_item();
}
if (right_item->type() == Item::REF_ITEM &&
((Item_ref*)right_item)->ref_type() == Item_ref::VIEW_REF)
{
- if (((Item_ref*)right_item)->depended_from)
+ if (((Item_ref*)right_item)->get_depended_from())
return FALSE;
right_item= right_item->real_item();
}
if (left_item->type() == Item::FIELD_ITEM &&
right_item->type() == Item::FIELD_ITEM &&
- !((Item_field*)left_item)->depended_from &&
- !((Item_field*)right_item)->depended_from)
+ !((Item_field*)left_item)->get_depended_from() &&
+ !((Item_field*)right_item)->get_depended_from())
{
/* The predicate the form field1=field2 is processed */
@@ -7743,12 +11027,14 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
{
/* left_item_equal of an upper level contains left_item */
left_item_equal= new Item_equal(left_item_equal);
+ left_item_equal->set_context_field(((Item_field*) left_item));
cond_equal->current_level.push_back(left_item_equal);
}
if (right_copyfl)
{
/* right_item_equal of an upper level contains right_item */
right_item_equal= new Item_equal(right_item_equal);
+ right_item_equal->set_context_field(((Item_field*) right_item));
cond_equal->current_level.push_back(right_item_equal);
}
@@ -7756,7 +11042,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
{
/* left item was found in the current or one of the upper levels */
if (! right_item_equal)
- left_item_equal->add((Item_field *) right_item);
+ left_item_equal->add(orig_right_item);
else
{
/* Merge two multiple equalities forming a new one */
@@ -7771,12 +11057,14 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
{
/* left item was not found neither the current nor in upper levels */
if (right_item_equal)
- right_item_equal->add((Item_field *) left_item);
+ right_item_equal->add(orig_left_item);
else
{
/* None of the fields was found in multiple equalities */
- Item_equal *item_equal= new Item_equal((Item_field *) left_item,
- (Item_field *) right_item);
+ Item_equal *item_equal= new Item_equal(orig_left_item,
+ orig_right_item,
+ FALSE);
+ item_equal->set_context_field((Item_field*)left_item);
cond_equal->current_level.push_back(item_equal);
}
}
@@ -7787,18 +11075,21 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
/* The predicate of the form field=const/const=field is processed */
Item *const_item= 0;
Item_field *field_item= 0;
+ Item *orig_field_item= 0;
if (left_item->type() == Item::FIELD_ITEM &&
- !((Item_field*)left_item)->depended_from &&
- right_item->const_item())
+ !((Item_field*)left_item)->get_depended_from() &&
+ right_item->const_item() && !right_item->is_expensive())
{
- field_item= (Item_field*) left_item;
+ orig_field_item= orig_left_item;
+ field_item= (Item_field *) left_item;
const_item= right_item;
}
else if (right_item->type() == Item::FIELD_ITEM &&
- !((Item_field*)right_item)->depended_from &&
- left_item->const_item())
+ !((Item_field*)right_item)->get_depended_from() &&
+ left_item->const_item() && !left_item->is_expensive())
{
- field_item= (Item_field*) right_item;
+ orig_field_item= orig_right_item;
+ field_item= (Item_field *) right_item;
const_item= left_item;
}
@@ -7813,7 +11104,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
if (!item)
{
Item_func_eq *eq_item;
- if ((eq_item= new Item_func_eq(left_item, right_item)))
+ if ((eq_item= new Item_func_eq(orig_left_item, orig_right_item)))
return FALSE;
eq_item->set_cmp_func();
eq_item->quick_fix_field();
@@ -7830,6 +11121,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
{
item_equal= new Item_equal(item_equal);
cond_equal->current_level.push_back(item_equal);
+ item_equal->set_context_field(field_item);
}
if (item_equal)
{
@@ -7838,11 +11130,12 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
already contains a constant and its value is not equal to
the value of const_item.
*/
- item_equal->add(const_item, field_item);
+ item_equal->add_const(const_item, orig_field_item);
}
else
{
- item_equal= new Item_equal(const_item, field_item);
+ item_equal= new Item_equal(const_item, orig_field_item, TRUE);
+ item_equal->set_context_field(field_item);
cond_equal->current_level.push_back(item_equal);
}
return TRUE;
@@ -8084,10 +11377,10 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
List_iterator_fast<Item_equal> it(cond_equal.current_level);
while ((item_equal= it++))
{
- item_equal->fix_length_and_dec();
+ item_equal->fix_fields(thd, NULL);
item_equal->update_used_tables();
set_if_bigger(thd->lex->current_select->max_equal_elems,
- item_equal->members());
+ item_equal->n_field_items());
}
((Item_cond_and*)cond)->cond_equal= cond_equal;
@@ -8118,7 +11411,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
args->concat((List<Item> *)&cond_equal.current_level);
}
}
- else if (cond->type() == Item::FUNC_ITEM)
+ else if (cond->type() == Item::FUNC_ITEM ||
+ cond->real_item()->type() == Item::FIELD_ITEM)
{
List<Item> eq_list;
/*
@@ -8140,10 +11434,11 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
{
if ((item_equal= cond_equal.current_level.pop()))
{
- item_equal->fix_length_and_dec();
+ item_equal->fix_fields(thd, NULL);
item_equal->update_used_tables();
set_if_bigger(thd->lex->current_select->max_equal_elems,
- item_equal->members());
+ item_equal->n_field_items());
+ item_equal->upper_levels= inherited;
return item_equal;
}
@@ -8164,7 +11459,7 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
item_equal->fix_length_and_dec();
item_equal->update_used_tables();
set_if_bigger(thd->lex->current_select->max_equal_elems,
- item_equal->members());
+ item_equal->n_field_items());
}
and_cond->cond_equal= cond_equal;
args->concat((List<Item> *)&cond_equal.current_level);
@@ -8178,7 +11473,7 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
as soon the field is not of a string type or the field reference is
an argument of a comparison predicate.
*/
- uchar *is_subst_valid= (uchar *) 1;
+ uchar* is_subst_valid= (uchar *) Item::ANY_SUBST;
cond= cond->compile(&Item::subst_argument_checker,
&is_subst_valid,
&Item::equal_fields_propagator,
@@ -8248,6 +11543,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
@param inherited path to all inherited multiple equality items
@param join_list list of join tables to which the condition
refers to
+ @ignore_on_conds TRUE <-> do not build multiple equalities
+ for on expressions
@param[out] cond_equal_ref pointer to the structure to place built
equalities in
@@ -8255,11 +11552,13 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
pointer to the transformed condition containing multiple equalities
*/
-static COND *build_equal_items(THD *thd, COND *cond,
+static COND *build_equal_items(JOIN *join, COND *cond,
COND_EQUAL *inherited,
List<TABLE_LIST> *join_list,
+ bool ignore_on_conds,
COND_EQUAL **cond_equal_ref)
{
+ THD *thd= join->thd;
COND_EQUAL *cond_equal= 0;
if (cond)
@@ -8269,6 +11568,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)
{
@@ -8283,7 +11583,7 @@ static COND *build_equal_items(THD *thd, COND *cond,
}
*cond_equal_ref= cond_equal;
- if (join_list)
+ if (join_list && !ignore_on_conds)
{
TABLE_LIST *table;
List_iterator<TABLE_LIST> li(*join_list);
@@ -8298,8 +11598,8 @@ static COND *build_equal_items(THD *thd, COND *cond,
We can modify table->on_expr because its old value will
be restored before re-execution of PS/SP.
*/
- table->on_expr= build_equal_items(thd, table->on_expr, inherited,
- nested_join_list,
+ table->on_expr= build_equal_items(join, table->on_expr, inherited,
+ nested_join_list, ignore_on_conds,
&table->cond_equal);
}
}
@@ -8312,10 +11612,14 @@ static COND *build_equal_items(THD *thd, COND *cond,
/**
Compare field items by table order in the execution plan.
+ If field1 and field2 belong to different tables then
field1 considered as better than field2 if the table containing
field1 is accessed earlier than the table containing field2.
The function finds out what of two fields is better according
this criteria.
+ If field1 and field2 belong to the same table then the result
+ of comparison depends on whether the fields are parts of
+ the key that are used to access this table.
@param field1 first field item to compare
@param field2 second field item to compare
@@ -8329,18 +11633,24 @@ static COND *build_equal_items(THD *thd, COND *cond,
0 otherwise
*/
-static int compare_fields_by_table_order(Item_field *field1,
- Item_field *field2,
- void *table_join_idx)
+static int compare_fields_by_table_order(Item *field1,
+ Item *field2,
+ void *table_join_idx)
{
int cmp= 0;
bool outer_ref= 0;
- if (field2->used_tables() & OUTER_REF_TABLE_BIT)
+ Item_field *f1= (Item_field *) (field1->real_item());
+ Item_field *f2= (Item_field *) (field2->real_item());
+ if (field1->const_item() || f1->const_item())
+ return 1;
+ if (field2->const_item() || f2->const_item())
+ return -1;
+ if (f2->used_tables() & OUTER_REF_TABLE_BIT)
{
outer_ref= 1;
cmp= -1;
}
- if (field2->used_tables() & OUTER_REF_TABLE_BIT)
+ if (f1->used_tables() & OUTER_REF_TABLE_BIT)
{
outer_ref= 1;
cmp++;
@@ -8348,11 +11658,75 @@ static int compare_fields_by_table_order(Item_field *field1,
if (outer_ref)
return cmp;
JOIN_TAB **idx= (JOIN_TAB **) table_join_idx;
- cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr];
+
+ JOIN_TAB *tab1= idx[f1->field->table->tablenr];
+ JOIN_TAB *tab2= idx[f2->field->table->tablenr];
+
+ /*
+ if one of the table is inside a merged SJM nest and another one isn't,
+ compare SJM bush roots of the tables.
+ */
+ if (tab1->bush_root_tab != tab2->bush_root_tab)
+ {
+ if (tab1->bush_root_tab)
+ tab1= tab1->bush_root_tab;
+
+ if (tab2->bush_root_tab)
+ tab2= tab2->bush_root_tab;
+ }
+
+ cmp= tab2 - tab1;
+
+ if (!cmp)
+ {
+ JOIN_TAB *tab= idx[f1->field->table->tablenr];
+ 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)
+ {
+ if (f2->field->part_of_key.is_set(keyno))
+ cmp= -1;
+ if (f1->field->part_of_key.is_set(keyno))
+ cmp++;
+ if (!cmp)
+ {
+ KEY *key_info= tab->table->key_info + keyno;
+ for (uint i= 0; i < key_info->key_parts; i++)
+ {
+ Field *fld= key_info->key_part[i].field;
+ if (fld->eq(f2->field))
+ {
+ cmp= -1;
+ break;
+ }
+ if (fld->eq(f1->field))
+ {
+ cmp= 1;
+ break;
+ }
+ }
+ }
+ }
+ else
+ cmp= f2->field->field_index-f1->field->field_index;
+ }
return cmp < 0 ? -1 : (cmp ? 1 : 0);
}
+static TABLE_LIST* embedding_sjm(Item *item)
+{
+ Item_field *item_field= (Item_field *) (item->real_item());
+ 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.
@@ -8386,6 +11760,25 @@ 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.
+
+ Grep for EqualityPropagationAndSjmNests for a more verbose description.
@return
- The condition with generated simple equalities or
@@ -8393,81 +11786,181 @@ 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;
if (((Item *) item_equal)->const_item() && !item_equal->val_int())
return new Item_int((longlong) 0,1);
Item *item_const= item_equal->get_const();
- Item_equal_iterator it(*item_equal);
+ Item_equal_fields_iterator it(*item_equal);
Item *head;
- DBUG_ASSERT(!cond || cond->type() == Item::COND_ITEM);
-
+ TABLE_LIST *current_sjm= NULL;
+ Item *current_sjm_head= NULL;
+
+ DBUG_ASSERT(!cond ||
+ cond->type() == Item::INT_ITEM ||
+ (cond->type() == Item::FUNC_ITEM &&
+ ((Item_func *) cond)->functype() == Item_func::EQ_FUNC) ||
+ (cond->type() == Item::COND_ITEM &&
+ ((Item_func *) cond)->functype() == Item_func::COND_AND_FUNC));
+
+ /*
+ Pick the "head" item: the constant one or the first in the join order
+ (if the first in the join order happends to be inside an SJM nest, that's
+ ok, because this is where the value will be unpacked after
+ materialization).
+ */
if (item_const)
head= item_const;
else
{
- head= item_equal->get_first();
+ TABLE_LIST *emb_nest;
+ head= item_equal->get_first(NO_PARTICULAR_TAB, NULL);
it++;
+ if ((emb_nest= embedding_sjm(head)))
+ {
+ current_sjm= emb_nest;
+ current_sjm_head= head;
+ }
}
- Item_field *item_field;
- while ((item_field= it++))
+
+ Item *field_item;
+ /*
+ For each other item, generate "item=head" equality (except the tables that
+ are within SJ-Materialization nests, for those "head" is defined
+ differently)
+ */
+ while ((field_item= it++))
{
- Item_equal *upper= item_field->find_item_equal(upper_levels);
- Item_field *item= item_field;
- if (upper)
+ Item_equal *upper= field_item->find_item_equal(upper_levels);
+ Item *item= field_item;
+ TABLE_LIST *field_sjm= embedding_sjm(field_item);
+ if (!field_sjm)
{
+ current_sjm= NULL;
+ current_sjm_head= NULL;
+ }
+
+ /*
+ Check if "field_item=head" equality is already guaranteed to be true
+ on upper AND-levels.
+ */
+ if (upper)
+ {
+ TABLE_LIST *native_sjm= embedding_sjm(item_equal->context_field);
if (item_const && upper->get_const())
+ {
+ /* Upper item also has "field_item=const". Don't produce equality here */
item= 0;
+ }
else
{
- Item_equal_iterator li(*item_equal);
- while ((item= li++) != item_field)
+ Item_equal_fields_iterator li(*item_equal);
+ while ((item= li++) != field_item)
{
- if (item->find_item_equal(upper_levels) == upper)
+ if (embedding_sjm(item) == field_sjm &&
+ item->find_item_equal(upper_levels) == upper)
break;
}
}
+ if (embedding_sjm(field_item) != native_sjm)
+ item= NULL; /* Don't produce equality */
}
- if (item == item_field)
+
+ bool produce_equality= test(item == field_item);
+ if (!item_const && field_sjm && field_sjm != current_sjm)
+ {
+ /* Entering an SJM nest */
+ current_sjm_head= field_item;
+ 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);
+ if (eq_item && eq_list.push_back(eq_item))
+ return 0;
+
+ /*
+ If we're inside an SJM-nest (current_sjm!=NULL), and the multi-equality
+ doesn't include a constant, we should produce equality with the first
+ of the equals in this SJM.
+
+ In other cases, get the "head" item, which is either first of the
+ equals on top level, or the constant.
+ */
+ Item *head_item= (!item_const && current_sjm)? current_sjm_head: head;
+ Item *head_real_item= head_item->real_item();
+ if (head_real_item->type() == Item::FIELD_ITEM)
+ head_item= head_real_item;
+
+ eq_item= new Item_func_eq(field_item->real_item(), head_item);
+
if (!eq_item)
return 0;
eq_item->set_cmp_func();
eq_item->quick_fix_field();
}
+ current_sjm= field_sjm;
}
- if (!cond)
+ /*
+ We have produced zero, one, or more pair-wise equalities eq_i. We want to
+ return an expression in form:
+
+ cond AND eq_1 AND eq_2 AND eq_3 AND ...
+
+ 'cond' is a parameter for this function, which may be NULL, an Item_int(1),
+ or an Item_func_eq or an Item_cond_and.
+
+ We want to return a well-formed condition: no nested Item_cond_and objects,
+ or Item_cond_and with a single child:
+ - if 'cond' is an Item_cond_and, we add eq_i as its tail
+ - if 'cond' is Item_int(1), we return eq_i
+ - otherwise, we create our own Item_cond_and and put 'cond' at the front of
+ it.
+ - if we have only one condition to return, we don't create an Item_cond_and
+ */
+
+ if (eq_item && eq_list.push_back(eq_item))
+ return 0;
+ COND *res= 0;
+ switch (eq_list.elements)
+ {
+ case 0:
+ res= cond ? cond : new Item_int((longlong) 1, 1);
+ break;
+ case 1:
+ if (!cond || cond->type() == Item::INT_ITEM)
+ res= eq_item;
+ break;
+ default:
+ break;
+ }
+ if (!res)
{
- if (eq_list.is_empty())
+ if (cond)
{
- if (eq_item)
- return eq_item;
- return new Item_int((longlong) 1, 1);
+ if (cond->type() == Item::COND_ITEM)
+ {
+ res= cond;
+ ((Item_cond *) res)->add_at_end(&eq_list);
+ }
+ else if (eq_list.push_front(cond))
+ return 0;
}
- /* eq_item is always set if list is not empty */
- DBUG_ASSERT(eq_item);
- eq_list.push_back(eq_item);
- if (!(cond= new Item_cond_and(eq_list)))
- return 0; // Error
- }
- else
+ }
+ if (!res)
+ res= new Item_cond_and(eq_list);
+ if (res)
{
- if (eq_item)
- eq_list.push_back(eq_item);
- if (!eq_list.is_empty())
- ((Item_cond *) cond)->add_at_head(&eq_list);
+ res->quick_fix_field();
+ res->update_used_tables();
}
- cond->quick_fix_field();
- cond->update_used_tables();
-
- return cond;
+
+ return res;
}
@@ -8485,6 +11978,9 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
After this the function retrieves all other conjuncted
predicates substitute every field reference by the field reference
to the first equal field or equal constant if there are any.
+
+ @param context_tab Join tab that 'cond' will be attached to, or
+ NO_PARTICULAR_TAB. See notes above.
@param cond condition to process
@param cond_equal multiple equalities to take into consideration
@param table_join_idx index to tables determining field preference
@@ -8495,11 +11991,37 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
new fields in multiple equality item of lower levels. We want
the order in them to comply with the order of upper levels.
+ context_tab may be used to specify which join tab `cond` will be
+ attached to. There are two possible cases:
+
+ 1. context_tab != NO_PARTICULAR_TAB
+ We're doing substitution for an Item which will be evaluated in the
+ context of a particular item. For example, if the optimizer does a
+ ref access on "tbl1.key= expr" then
+ = equality substitution will be perfomed on 'expr'
+ = it is known in advance that 'expr' will be evaluated when
+ table t1 is accessed.
+ Note that in this kind of substution we never have to replace Item_equal
+ objects. For example, for
+
+ t.key= func(col1=col2 AND col2=const)
+
+ we will not build Item_equal or do equality substution (if we decide to,
+ this function will need to be fixed to handle it)
+
+ 2. context_tab == NO_PARTICULAR_TAB
+ We're doing substitution in WHERE/ON condition, which is not yet
+ attached to any particular join_tab. We will use information about the
+ chosen join order to make "optimal" substitions, i.e. those that allow
+ to apply filtering as soon as possible. See eliminate_item_equal() and
+ Item_equal::get_first() for details.
+
@return
The transformed condition
*/
-static COND* substitute_for_best_equal_field(COND *cond,
+static COND* substitute_for_best_equal_field(JOIN_TAB *context_tab,
+ COND *cond,
COND_EQUAL *cond_equal,
void *table_join_idx)
{
@@ -8515,7 +12037,7 @@ static COND* substitute_for_best_equal_field(COND *cond,
if (and_level)
{
cond_equal= &((Item_cond_and *) cond)->cond_equal;
- cond_list->disjoin((List<Item> *) &cond_equal->current_level);
+ cond_list->disjoin((List<Item> *) &cond_equal->current_level);/* remove Item_equal objects from the AND. */
List_iterator_fast<Item_equal> it(cond_equal->current_level);
while ((item_equal= it++))
@@ -8528,7 +12050,8 @@ static COND* substitute_for_best_equal_field(COND *cond,
Item *item;
while ((item= li++))
{
- Item *new_item= substitute_for_best_equal_field(item, cond_equal,
+ Item *new_item= substitute_for_best_equal_field(context_tab,
+ item, cond_equal,
table_join_idx);
/*
This works OK with PS/SP re-execution as changes are made to
@@ -8540,36 +12063,84 @@ static COND* substitute_for_best_equal_field(COND *cond,
if (and_level)
{
+ COND *eq_cond= 0;
List_iterator_fast<Item_equal> it(cond_equal->current_level);
+ bool false_eq_cond= FALSE;
while ((item_equal= it++))
{
- cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
- // This occurs when eliminate_item_equal() founds that cond is
- // always false and substitutes it with Item_int 0.
- // Due to this, value of item_equal will be 0, so just return it.
- if (!cond)
- return org_cond; // Error
- if (cond->type() != Item::COND_ITEM)
+ eq_cond= eliminate_item_equal(eq_cond, cond_equal->upper_levels,
+ item_equal);
+ if (!eq_cond)
+ {
+ eq_cond= 0;
break;
+ }
+ else if (eq_cond->type() == Item::INT_ITEM && !eq_cond->val_bool())
+ {
+ /*
+ This occurs when eliminate_item_equal() founds that cond is
+ always false and substitutes it with Item_int 0.
+ Due to this, value of item_equal will be 0, so just return it.
+ */
+ cond= eq_cond;
+ false_eq_cond= TRUE;
+ break;
+ }
}
- }
- if (cond->type() == Item::COND_ITEM &&
- !((Item_cond*)cond)->argument_list()->elements)
- cond= new Item_int((int32)cond->val_bool());
-
+ if (eq_cond && !false_eq_cond)
+ {
+ /* Insert the generated equalities before all other conditions */
+ if (eq_cond->type() == Item::COND_ITEM)
+ ((Item_cond *) cond)->add_at_head(
+ ((Item_cond *) eq_cond)->argument_list());
+ else
+ {
+ if (cond_list->is_empty())
+ cond= eq_cond;
+ else
+ {
+ /* Do not add an equality condition if it's always true */
+ if (eq_cond->type() != Item::INT_ITEM &&
+ cond_list->push_front(eq_cond))
+ eq_cond= 0;
+ }
+ }
+ }
+ if (!eq_cond)
+ {
+ /*
+ We are out of memory doing the transformation.
+ This is a fatal error now. However we bail out by returning the
+ original condition that we had before we started the transformation.
+ */
+ cond_list->concat((List<Item> *) &cond_equal->current_level);
+ }
+ }
}
else if (cond->type() == Item::FUNC_ITEM &&
((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
{
item_equal= (Item_equal *) cond;
item_equal->sort(&compare_fields_by_table_order, table_join_idx);
+ cond_equal= item_equal->upper_levels;
if (cond_equal && cond_equal->current_level.head() == item_equal)
- cond_equal= 0;
+ cond_equal= cond_equal->upper_levels;
cond= eliminate_item_equal(0, cond_equal, item_equal);
return cond ? cond : org_cond;
}
- else
- cond->transform(&Item::replace_equal_field, 0);
+ else
+ {
+ while (cond_equal)
+ {
+ List_iterator_fast<Item_equal> it(cond_equal->current_level);
+ while((item_equal= it++))
+ {
+ REPLACE_EQUAL_FIELD_ARG arg= {item_equal, context_tab};
+ cond= cond->transform(&Item::replace_equal_field, (uchar *) &arg);
+ }
+ cond_equal= cond_equal->upper_levels;
+ }
+ }
return cond;
}
@@ -8613,11 +12184,10 @@ static void update_const_equal_items(COND *cond, JOIN_TAB *tab, bool const_key)
if (!contained_const && item_equal->get_const())
{
/* Update keys for range analysis */
- Item_equal_iterator it(*item_equal);
- Item_field *item_field;
- while ((item_field= it++))
+ Item_equal_fields_iterator it(*item_equal);
+ while (it++)
{
- Field *field= item_field->field;
+ Field *field= it.get_curr_field();
JOIN_TAB *stat= field->table->reginfo.join_tab;
key_map possible_keys= field->key_start;
possible_keys.intersect(field->table->keys_in_use_for_query);
@@ -8634,7 +12204,7 @@ static void update_const_equal_items(COND *cond, JOIN_TAB *tab, bool const_key)
KEYUSE *use;
for (use= stat->keyuse; use && use->table == tab; use++)
if (const_key &&
- possible_keys.is_set(use->key) &&
+ !use->is_for_hash_join() && possible_keys.is_set(use->key) &&
tab->key_info[use->key].key_part[use->keypart].field ==
field)
tab->const_key_parts[use->key]|= use->keypart_map;
@@ -8728,37 +12298,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,
@@ -8796,10 +12335,10 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
{
Item_func_eq *func=(Item_func_eq*) cond;
Item **args= func->arguments();
- bool left_const= args[0]->const_item();
- bool right_const= args[1]->const_item();
+ bool left_const= args[0]->const_item() && !args[0]->is_expensive();
+ bool right_const= args[1]->const_item() && !args[1]->is_expensive();
if (!(left_const && right_const) &&
- args[0]->result_type() == args[1]->result_type())
+ args[0]->cmp_type() == args[1]->cmp_type())
{
if (right_const)
{
@@ -8820,7 +12359,6 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
}
}
-
/**
Simplify joins replacing outer joins by inner joins whenever it's
possible.
@@ -8915,13 +12453,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
@@ -8931,14 +12474,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;
@@ -8974,7 +12518,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)
{
@@ -8986,7 +12530,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: */
@@ -8996,7 +12541,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
{
if (!table->prep_on_expr)
table->prep_on_expr= table->on_expr;
- used_tables= table->table->map;
+ used_tables= table->get_map();
if (conds)
not_null_tables= conds->not_null_tables();
}
@@ -9018,7 +12563,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);
@@ -9053,7 +12598,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
}
else
- table->dep_tables&= ~table->table->map;
+ table->dep_tables&= ~table->get_map();
}
if (prev_table)
@@ -9066,7 +12611,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
prev_table->dep_tables|= table->on_expr_dep_tables;
table_map prev_used_tables= prev_table->nested_join ?
prev_table->nested_join->used_tables :
- prev_table->table->map;
+ prev_table->get_map();
/*
If on expression contains only references to inner tables
we still make the inner tables dependent on the outer tables.
@@ -9087,24 +12632,49 @@ 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.
+ */
li.rewind();
while ((table= li++))
{
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);
+
+ /*
+ Also, walk through semi-join children and mark those that are now
+ top-level
+ */
TABLE_LIST *tbl;
List_iterator<TABLE_LIST> it(nested_join->join_list);
while ((tbl= it++))
{
+ if (!tbl->on_expr && tbl->table)
+ tbl->table->maybe_null= FALSE;
+ }
+ }
+ else if (nested_join && !table->on_expr)
+ {
+ TABLE_LIST *tbl;
+ List_iterator<TABLE_LIST> it(nested_join->join_list);
+ List<TABLE_LIST> repl_list;
+ while ((tbl= it++))
+ {
tbl->embedding= table->embedding;
if (!tbl->embedding && !tbl->on_expr && tbl->table)
tbl->table->maybe_null= FALSE;
tbl->join_list= table->join_list;
+ repl_list.push_back(tbl);
tbl->dep_tables|= table->dep_tables;
}
- li.replace(nested_join->join_list);
+ li.replace(repl_list);
}
}
DBUG_RETURN(conds);
@@ -9114,8 +12684,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
@@ -9124,7 +12694,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
@@ -9153,7 +12723,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);
}
@@ -9306,28 +12878,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;
}
@@ -9389,27 +12964,130 @@ 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;
+
+ /*
+ best_access_path() optimization depends on the value of
+ join->cur_sj_inner_tables. Our goal in this function is to do a
+ re-optimization with disabled join buffering, but no other changes.
+ In order to achieve this, cur_sj_inner_tables needs have the same
+ value it had during the original invocations of best_access_path.
+
+ We know that this function, optimize_wo_join_buffering() is called to
+ re-optimize semi-join join order range, which allows to conclude that
+ the "original" value of cur_sj_inner_tables was 0.
+ */
+ table_map save_cur_sj_inner_tables= join->cur_sj_inner_tables;
+ join->cur_sj_inner_tables= 0;
+
+ 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;
}
+ join->cur_sj_inner_tables= save_cur_sj_inner_tables;
+
+ *reopt_cost= cost;
}
static COND *
-optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
- Item::cond_result *cond_value)
+optimize_cond(JOIN *join, COND *conds,
+ List<TABLE_LIST> *join_list, bool ignore_on_conds,
+ Item::cond_result *cond_value, COND_EQUAL **cond_equal)
{
THD *thd= join->thd;
DBUG_ENTER("optimize_cond");
@@ -9417,7 +13095,9 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
if (!conds)
{
*cond_value= Item::COND_TRUE;
- build_equal_items(join->thd, NULL, NULL, join_list, &join->cond_equal);
+ if (!ignore_on_conds)
+ build_equal_items(join, NULL, NULL, join_list, ignore_on_conds,
+ cond_equal);
}
else
{
@@ -9430,9 +13110,9 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
multiple equality contains a constant.
*/
DBUG_EXECUTE("where", print_where(conds, "original", QT_ORDINARY););
- conds= build_equal_items(join->thd, conds, NULL, join_list,
- &join->cond_equal);
- DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY););
+ conds= build_equal_items(join, conds, NULL, join_list, ignore_on_conds,
+ cond_equal);
+ DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY););
/* change field = field to field = const for each found field = const */
propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds);
@@ -9479,7 +13159,61 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
li.remove();
else if (item != new_item)
{
- VOID(li.replace(new_item));
+ if (and_level)
+ {
+ /*
+ Take a special care of multiple equality predicates
+ that may be part of 'cond' and 'new_item'.
+ Those multiple equalities that have common members
+ must be merged.
+ */
+ Item_cond_and *cond_and= (Item_cond_and *) cond;
+ List<Item_equal> *cond_equal_items=
+ &cond_and->cond_equal.current_level;
+ List<Item> *cond_and_list= cond_and->argument_list();
+
+ if (new_item->type() == Item::COND_ITEM &&
+ ((Item_cond*) new_item)->functype() == Item_func::COND_AND_FUNC)
+ {
+ Item_cond_and *new_item_and= (Item_cond_and *) new_item;
+ List<Item_equal> *new_item_equal_items=
+ &new_item_and->cond_equal.current_level;
+ List<Item> *new_item_and_list= new_item_and->argument_list();
+ cond_and_list->disjoin((List<Item>*) cond_equal_items);
+ new_item_and_list->disjoin((List<Item>*) new_item_equal_items);
+ Item_equal *equal_item;
+ List_iterator<Item_equal> it(*new_item_equal_items);
+ while ((equal_item= it++))
+ {
+ equal_item->merge_into_list(cond_equal_items);
+ }
+ if (new_item_and_list->is_empty())
+ li.remove();
+ else
+ li.replace(*new_item_and_list);
+ cond_and_list->concat((List<Item>*) cond_equal_items);
+ }
+ else if (new_item->type() == Item::FUNC_ITEM &&
+ ((Item_cond*) new_item)->functype() ==
+ Item_func::MULT_EQUAL_FUNC)
+ {
+ cond_and_list->disjoin((List<Item>*) cond_equal_items);
+ ((Item_equal *) new_item)->merge_into_list(cond_equal_items);
+ li.remove();
+ cond_and_list->concat((List<Item>*) cond_equal_items);
+ }
+ else
+ li.replace(new_item);
+ }
+ else
+ {
+ if (new_item->type() == Item::COND_ITEM &&
+ ((Item_cond*) new_item)->functype() ==
+ ((Item_cond*) cond)->functype())
+ li.replace(*((Item_cond*) new_item)->argument_list());
+ else
+ li.replace(new_item);
+ }
should_fix_fields=1;
}
if (*cond_value == Item::COND_UNDEF)
@@ -9585,13 +13319,13 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
}
}
}
- if (cond->const_item())
+ if (cond->const_item() && !cond->is_expensive())
{
*cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
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;
@@ -9611,40 +13345,36 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
return cond; // Point at next and level
}
-/*
+/**
Check if equality can be used in removing components of GROUP BY/DISTINCT
- SYNOPSIS
- test_if_equality_guarantees_uniqueness()
- l the left comparison argument (a field if any)
- r the right comparison argument (a const of any)
-
- DESCRIPTION
- Checks if an equality predicate can be used to take away
- DISTINCT/GROUP BY because it is known to be true for exactly one
- distinct value (e.g. <expr> == <const>).
- Arguments must be of the same type because e.g.
- <string_field> = <int_const> may match more than 1 distinct value from
- the column.
- We must take into consideration and the optimization done for various
- string constants when compared to dates etc (see Item_int_with_ref) as
- well as the collation of the arguments.
+ @param l the left comparison argument (a field if any)
+ @param r the right comparison argument (a const of any)
- RETURN VALUE
- TRUE can be used
- FALSE cannot be used
+ @details
+ Checks if an equality predicate can be used to take away
+ DISTINCT/GROUP BY because it is known to be true for exactly one
+ distinct value (e.g. <expr> == <const>).
+ Arguments must be compared in the native type of the left argument
+ and (for strings) in the native collation of the left argument.
+ Otherwise, for example,
+ <string_field> = <int_const> may match more than 1 distinct value or
+ the <string_field>.
+
+ @note We don't need to aggregate l and r collations here, because r -
+ the constant item - has already been converted to a proper collation
+ for comparison. We only need to compare this collation with field's collation.
+
+ @retval true can be used
+ @retval false cannot be used
*/
static bool
test_if_equality_guarantees_uniqueness(Item *l, Item *r)
{
return r->const_item() &&
- /* elements must be compared as dates */
- (Arg_comparator::can_compare_as_dates(l, r, 0) ||
- /* or of the same result type */
- (r->result_type() == l->result_type() &&
- /* and must have the same collation if compared as strings */
- (l->result_type() != STRING_RESULT ||
- l->collation.collation == r->collation.collation)));
+ item_cmp_type(l->cmp_type(), r->cmp_type()) == l->cmp_type() &&
+ (l->cmp_type() != STRING_RESULT ||
+ l->collation.collation == r->collation.collation);
}
/**
@@ -9826,15 +13556,12 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
case STRING_RESULT:
DBUG_ASSERT(item->collation.collation);
- enum enum_field_types type;
/*
DATE/TIME and GEOMETRY fields have STRING_RESULT result type.
To preserve type they needed to be handled separately.
*/
- if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
- type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE ||
- type == MYSQL_TYPE_NEWDATE ||
- type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_GEOMETRY)
+ if (item->cmp_type() == TIME_RESULT ||
+ item->field_type() == MYSQL_TYPE_GEOMETRY)
new_field= item->tmp_table_field_from_field_type(table, 1);
/*
Make sure that the blob fits into a Field_varstring which has
@@ -9975,13 +13702,30 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
If item have to be able to store NULLs but underlaid field can't do it,
create_tmp_field_from_field() can't be used for tmp field creation.
*/
- if (field->maybe_null && field->in_rollup && !field->field->maybe_null())
+ if (((field->maybe_null && field->in_rollup) ||
+ (thd->create_tmp_table_for_derived && /* for mat. view/dt */
+ orig_item && orig_item->maybe_null)) &&
+ !field->field->maybe_null())
{
+ bool save_maybe_null= FALSE;
+ /*
+ The item the ref points to may have maybe_null flag set while
+ the ref doesn't have it. This may happen for outer fields
+ when the outer query decided at some point after name resolution phase
+ that this field might be null. Take this into account here.
+ */
+ if (orig_item)
+ {
+ save_maybe_null= item->maybe_null;
+ item->maybe_null= orig_item->maybe_null;
+ }
result= create_tmp_field_from_item(thd, item, table, NULL,
modify_item, convert_blob_length);
*from_field= field->field;
if (result && modify_item)
field->result_field= result;
+ if (orig_item)
+ item->maybe_null= save_maybe_null;
}
else if (table_cant_handle_bit_fields && field->field->type() ==
MYSQL_TYPE_BIT)
@@ -10056,6 +13800,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);
@@ -10092,7 +13838,9 @@ void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps)
bitmap_init(&table->tmp_set,
(my_bitmap_map*) (bitmaps+ 2*bitmap_buffer_size(field_count)),
field_count, FALSE);
-
+ bitmap_init(&table->eq_join_set,
+ (my_bitmap_map*) (bitmaps+ 3*bitmap_buffer_size(field_count)),
+ field_count, FALSE);
/* write_set and all_set are copies of read_set */
table->def_write_set= table->def_read_set;
table->s->all_set= table->def_read_set;
@@ -10127,16 +13875,11 @@ 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,
+create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
ulonglong select_options, ha_rows rows_limit,
- char *table_alias)
+ char *table_alias, bool do_not_open)
{
MEM_ROOT *mem_root_save, own_root;
TABLE *table;
@@ -10200,10 +13943,26 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (group)
{
+ ORDER **prev= &group;
if (!param->quick_group)
group=0; // Can't use group key
else for (ORDER *tmp=group ; tmp ; tmp=tmp->next)
{
+ /* Exclude found constant from the list */
+ if ((*tmp->item)->const_item())
+ {
+ *prev= tmp->next;
+ param->group_parts--;
+ continue;
+ }
+ else
+ prev= &(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;
@@ -10245,7 +14004,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
&tmpname, (uint) strlen(path)+1,
&group_buff, (group && ! using_unique_constraint ?
param->group_length : 0),
- &bitmaps, bitmap_buffer_size(field_count)*3,
+ &bitmaps, bitmap_buffer_size(field_count)*4,
NullS))
{
if (temp_pool_slot != MY_BIT_NONE)
@@ -10277,7 +14036,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
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;
table->temp_pool_slot = temp_pool_slot;
table->copy_blobs= 1;
@@ -10285,13 +14043,14 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->quick_keys.init();
table->covering_keys.init();
table->merge_keys.init();
+ table->intersect_keys.init();
table->keys_in_use_for_query.init();
+ table->no_rows_with_nulls= param->force_not_null_cols;
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, MyISAM and Maria
share->table_charset= param->table_charset;
share->primary_key= MAX_KEY; // Indicate no primary key
share->keys_for_keyread.init();
@@ -10315,7 +14074,7 @@ 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 ||
+ if ((item->real_type() == Item::SUBSELECT_ITEM) ||
(item->used_tables() & ~OUTER_REF_TABLE_BIT))
{
/*
@@ -10366,6 +14125,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
thd->mem_root= mem_root_save;
arg= sum_item->set_arg(i, thd, new Item_field(new_field));
thd->mem_root= &table->mem_root;
+ if (param->force_not_null_cols)
+ {
+ new_field->flags|= NOT_NULL_FLAG;
+ new_field->null_ptr= NULL;
+ }
if (!(new_field->flags & NOT_NULL_FLAG))
{
null_count++;
@@ -10401,18 +14165,51 @@ 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,
+ force_copy_fields,
param->convert_blob_length);
if (!new_field)
{
if (thd->is_fatal_error)
goto err; // Got OOM
- continue; // Some kindf of const item
+ continue; // Some kind of const item
}
if (type == Item::SUM_FUNC_ITEM)
- ((Item_sum *) item)->result_field= new_field;
+ {
+ Item_sum *agg_item= (Item_sum *) item;
+ /*
+ Update the result field only if it has never been set, or if the
+ created temporary table is not to be used for subquery
+ materialization.
+
+ The reason is that for subqueries that require materialization as part
+ of their plan, we create the 'external' temporary table needed for IN
+ execution, after the 'internal' temporary table needed for grouping.
+ Since both the external and the internal temporary tables are created
+ for the same list of SELECT fields of the subquery, setting
+ 'result_field' for each invocation of create_tmp_table overrides the
+ previous value of 'result_field'.
+
+ The condition below prevents the creation of the external temp table
+ to override the 'result_field' that was set for the internal temp table.
+ */
+ if (!agg_item->result_field || !param->materialized_subquery)
+ agg_item->result_field= new_field;
+ }
tmp_from_field++;
+ if (param->force_not_null_cols)
+ {
+ new_field->flags|= NOT_NULL_FLAG;
+ new_field->null_ptr= NULL;
+ }
reclength+=new_field->pack_length();
if (!(new_field->flags & NOT_NULL_FLAG))
null_count++;
@@ -10466,6 +14263,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*reg_field= 0;
*blob_field= 0; // End marker
share->fields= field_count;
+ share->column_bitmap_size= bitmap_buffer_size(share->fields);
/* If result table is small; use a heap */
/* future: storage engine selection can be made dynamic? */
@@ -10645,7 +14443,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
param->copy_field_end=copy;
- param->recinfo=recinfo;
+ param->recinfo= recinfo; // Pointer to after last field
store_record(table,s->default_values); // Make empty default record
if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit
@@ -10673,9 +14471,11 @@ 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;
+ table->keys_in_use_for_query.set_bit(0);
+ share->keys_in_use.set_bit(0);
keyinfo->key_part=key_part_info;
- keyinfo->flags=HA_NOSAME;
+ keyinfo->flags=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
keyinfo->key_length=0;
keyinfo->rec_per_key=0;
@@ -10689,6 +14489,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
bool maybe_null=(*cur_group->item)->maybe_null;
key_part_info->null_bit=0;
key_part_info->field= field;
+ key_part_info->fieldnr= field->field_index + 1;
+ if (cur_group == group)
+ field->key_start.set_bit(0);
key_part_info->offset= field->offset(table->record[0]);
key_part_info->length= (uint16) field->key_length();
key_part_info->type= (uint8) field->key_type();
@@ -10760,29 +14563,41 @@ 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.
+ */
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->keys_in_use_for_query.set_bit(0);
+ share->keys_in_use.set_bit(0);
+ 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->flags=HA_NOSAME | HA_NULL_ARE_EQUAL | HA_BINARY_PACK_KEY | HA_PACK_KEY;
+ 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;
@@ -10798,6 +14613,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
key_part_info->field->init(table);
key_part_info->key_type=FIELDFLAG_BINARY;
key_part_info->type= HA_KEYTYPE_BINARY;
+ key_part_info->fieldnr= key_part_info->field->field_index + 1;
key_part_info++;
}
/* Create a distinct key over the columns we are going to return */
@@ -10805,10 +14621,47 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
i < field_count;
i++, reg_field++, key_part_info++)
{
- key_part_info->null_bit=0;
key_part_info->field= *reg_field;
+ (*reg_field)->flags |= PART_KEY_FLAG;
+ if (key_part_info == keyinfo->key_part)
+ (*reg_field)->key_start.set_bit(0);
+ key_part_info->null_bit= (*reg_field)->null_bit;
+ key_part_info->null_offset= (uint) ((*reg_field)->null_ptr -
+ (uchar*) table->record[0]);
+
key_part_info->offset= (*reg_field)->offset(table->record[0]);
key_part_info->length= (uint16) (*reg_field)->pack_length();
+ key_part_info->fieldnr= (*reg_field)->field_index + 1;
+ /* TODO:
+ The below method of computing the key format length of the
+ key part is a copy/paste from opt_range.cc, and table.cc.
+ 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;
+ key_part_info->key_part_flag |= HA_NULL_PART;
+ }
+ if ((*reg_field)->type() == MYSQL_TYPE_BLOB ||
+ (*reg_field)->real_type() == MYSQL_TYPE_VARCHAR ||
+ (*reg_field)->type() == MYSQL_TYPE_GEOMETRY)
+ {
+ if ((*reg_field)->type() == MYSQL_TYPE_BLOB ||
+ (*reg_field)->type() == MYSQL_TYPE_GEOMETRY)
+ key_part_info->key_part_flag|= HA_BLOB_PART;
+ else
+ key_part_info->key_part_flag|= HA_VAR_LENGTH_PART;
+
+ 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 ||
@@ -10821,13 +14674,20 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (thd->is_fatal_error) // If end of memory
goto err; /* purecov: inspected */
share->db_record_offset= 1;
- if (share->db_type() == TMP_ENGINE_HTON)
+ table->used_for_duplicate_elimination= (param->sum_func_count == 0 &&
+ (table->group || table->distinct));
+
+ if (!do_not_open)
{
- if (create_internal_tmp_table(table,param,select_options))
+ if (share->db_type() == TMP_ENGINE_HTON)
+ {
+ if (create_internal_tmp_table(table, param->keyinfo, param->start_recinfo,
+ &param->recinfo, select_options))
+ goto err;
+ }
+ if (open_tmp_table(table))
goto err;
}
- if (open_tmp_table(table))
- goto err;
// Make empty record so random data is not written to disk
empty_record(table);
@@ -10845,6 +14705,7 @@ err:
}
+
/****************************************************************************/
/**
@@ -10885,7 +14746,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
&share, sizeof(*share),
&field, (field_count + 1) * sizeof(Field*),
&blob_field, (field_count+1) *sizeof(uint),
- &bitmaps, bitmap_buffer_size(field_count)*3,
+ &bitmaps, bitmap_buffer_size(field_count)*4,
NullS))
return 0;
@@ -10973,7 +14834,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,
@@ -10984,22 +14845,54 @@ static bool open_tmp_table(TABLE *table)
table->db_stat=0;
return(1);
}
+ table->db_stat= HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
(void) table->file->extra(HA_EXTRA_QUICK); /* Faster */
+ table->created= TRUE;
return(0);
}
#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:
-static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
- ulonglong options)
+ 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
+*/
+
+
+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");
@@ -11017,6 +14910,13 @@ static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
keyinfo->key_parts > table->file->max_key_parts() ||
share->uniques)
{
+ if (!share->uniques && !(keyinfo->flags & HA_NOSAME))
+ {
+ my_error(ER_INTERNAL_ERROR, MYF(0),
+ "Using too big key for internal temp tables");
+ DBUG_RETURN(1);
+ }
+
/* Can't create a key; Make a unique constraint instead of a key */
share->keys= 0;
share->uniques= 1;
@@ -11027,17 +14927,17 @@ 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
{
- /* Create an unique key */
+ /* Create a key */
bzero((char*) &keydef,sizeof(keydef));
- keydef.flag=HA_NOSAME;
+ keydef.flag= keyinfo->flags & HA_NOSAME;
keydef.keysegs= keyinfo->key_parts;
keydef.seg= seg;
}
@@ -11097,13 +14997,14 @@ static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
a group by and no sum functions or if distinct is used.
*/
if ((error= maria_create(share->table_name.str,
+ table->no_rows ? NO_RECORD :
(share->reclength < 64 &&
!share->blob_fields ? STATIC_RECORD :
- ((!param->sum_func_count && table->group) ||
- table->distinct) ? DYNAMIC_RECORD : BLOCK_RECORD),
+ table->used_for_duplicate_elimination ?
+ DYNAMIC_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)))
@@ -11122,11 +15023,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");
@@ -11134,15 +15037,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");
@@ -11169,17 +15103,18 @@ 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
{
/* Create an unique key */
bzero((char*) &keydef,sizeof(keydef));
- keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
+ keydef.flag= ((keyinfo->flags & HA_NOSAME) | HA_BINARY_PACK_KEY |
+ HA_PACK_KEY);
keydef.keysegs= keyinfo->key_parts;
keydef.seg= seg;
}
@@ -11229,8 +15164,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)))
@@ -11240,7 +15175,9 @@ static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
goto err;
}
status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
+ table->in_use->query_plan_flags|= QPLAN_TMP_DISK;
share->db_record_offset= 1;
+ table->created= TRUE;
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
@@ -11252,11 +15189,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");
@@ -11273,7 +15212,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,
@@ -11282,9 +15222,8 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
TABLE new_table;
TABLE_SHARE share;
const char *save_proc_info;
- int write_err;
+ int write_err= 0;
DBUG_ENTER("create_internal_tmp_table_from_heap2");
- LINT_INIT(write_err);
if (table->s->db_type() != heap_hton ||
error != HA_ERR_RECORD_FILE_FULL)
@@ -11308,8 +15247,11 @@ 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))
+ new_table.no_rows= table->no_rows;
+ 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;
@@ -11318,24 +15260,15 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
table->file->ha_index_or_rnd_end();
if (table->file->ha_rnd_init_with_error(1))
DBUG_RETURN(1);
- if (table->no_rows)
- {
+ if (new_table.no_rows)
new_table.file->extra(HA_EXTRA_NO_ROWS);
- new_table.no_rows=1;
+ else
+ {
+ /* update table->file->stats.records */
+ table->file->info(HA_STATUS_VARIABLE);
+ new_table.file->ha_start_bulk_insert(table->file->stats.records);
}
-#ifdef TO_BE_DONE_LATER_IN_4_1
- /*
- To use start_bulk_insert() (which is new in 4.1) we need to find
- all places where a corresponding end_bulk_insert() should be put.
- */
- table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */
- new_table.file->ha_start_bulk_insert(table->file->stats.records);
-#else
- /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
- new_table.file->extra(HA_EXTRA_WRITE_CACHE);
-#endif
-
/*
copy all old rows from heap table to MyISAM table
This is the only code that uses record[1] to read/write but this
@@ -11344,7 +15277,7 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
*/
while (!table->file->ha_rnd_next(new_table.record[1]))
{
- write_err= new_table.file->ha_write_row(new_table.record[1]);
+ write_err= new_table.file->ha_write_tmp_row(new_table.record[1]);
DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;);
if (write_err)
goto err;
@@ -11354,8 +15287,10 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
goto err_killed;
}
}
+ if (!new_table.no_rows && new_table.file->ha_end_bulk_insert())
+ goto err;
/* copy row that filled HEAP table */
- if ((write_err=new_table.file->ha_write_row(table->record[0])))
+ if ((write_err=new_table.file->ha_write_tmp_row(table->record[0])))
{
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
!ignore_last_dupp_key_error)
@@ -11364,7 +15299,7 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
/* remove heap table and change to use myisam table */
(void) table->file->ha_rnd_end();
- (void) table->file->close(); // This deletes the table !
+ (void) table->file->ha_close(); // This deletes the table !
delete table->file;
table->file=0;
plugin_unlock(0, table->s->db_plugin);
@@ -11376,8 +15311,8 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
table->file->change_table_ptr(table, table->s);
table->use_all_columns();
if (save_proc_info)
- thd_proc_info(thd, (!strcmp(save_proc_info,"Copying to tmp table") ?
- "Copying to tmp table on disk" : save_proc_info));
+ thd_proc_info(thd, save_proc_info == copy_to_tmp_table ?
+ "Copying to tmp table on disk" : save_proc_info);
DBUG_RETURN(0);
err:
@@ -11385,7 +15320,7 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
table->file->print_error(write_err, MYF(0));
err_killed:
(void) table->file->ha_rnd_end();
- (void) new_table.file->close();
+ (void) new_table.file->ha_close();
err1:
new_table.file->ha_delete_table(new_table.s->table_name.str);
err2:
@@ -11407,7 +15342,7 @@ free_tmp_table(THD *thd, TABLE *entry)
save_proc_info=thd->proc_info;
thd_proc_info(thd, "removing tmp table");
- if (entry->file)
+ if (entry->file && entry->created)
{
if (entry->db_stat)
entry->file->ha_drop_table(entry->s->table_name.str);
@@ -11522,7 +15457,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)
{
@@ -11553,20 +15487,24 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
}
/* Set up select_end */
Next_select_func end_select= setup_end_select_func(join);
- if (join->tables)
+ if (join->table_count)
{
- join->join_tab[join->tables-1].next_select= end_select;
-
+ join->join_tab[join->top_join_tab_count - 1].next_select= end_select;
join_tab=join->join_tab+join->const_tables;
}
join->send_records=0;
- if (join->tables == join->const_tables)
+ if (join->table_count == join->const_tables)
{
/*
HAVING will be checked after processing aggregate functions,
- But WHERE should checkd here (we alredy have read tables)
+ But WHERE should checked here (we alredy have read tables).
+ Notice that make_join_select() splits all conditions in this case
+ into two groups exec_const_cond and outer_ref_cond.
+ If join->table_count == join->const_tables then it is
+ sufficient to check only the condition pseudo_bits_cond.
*/
- if (!join->conds || join->conds->val_int())
+ DBUG_ASSERT(join->outer_ref_cond == NULL);
+ if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_int())
{
error= (*end_select)(join, 0, 0);
if (error == NESTED_LOOP_OK || error == NESTED_LOOP_QUERY_LIMIT)
@@ -11583,15 +15521,21 @@ 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) > 0;
+ if (!join->having || join->having->val_int())
+ {
+ List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
+ fields);
+ rc= join->result->send_data(*columns_list) > 0;
+ }
}
}
else
{
- DBUG_ASSERT(join->tables);
- error= sub_select(join,join_tab,0);
+ DBUG_ASSERT(join->table_count);
+ if (join->outer_ref_cond && !join->outer_ref_cond->val_int())
+ error= NESTED_LOOP_NO_MORE_ROWS;
+ else
+ error= sub_select(join,join_tab,0);
if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS)
error= sub_select(join,join_tab,1);
if (error == NESTED_LOOP_QUERY_LIMIT)
@@ -11646,33 +15590,100 @@ 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;
+}
+
+
+/*
+ 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)
+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);
}
/**
@@ -11798,18 +15809,33 @@ 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;
+
+ for (SJ_TMP_TABLE *flush_dups_table= join_tab->flush_weedout_table;
+ flush_dups_table;
+ flush_dups_table= flush_dups_table->next_flush_table)
+ {
+ flush_dups_table->sj_weedout_delete_rows();
+ }
+
+ if (!join_tab->preread_init_done && join_tab->preread_init())
+ DBUG_RETURN(NESTED_LOOP_ERROR);
if (join->resume_nested_loop)
{
/* If not the last table, plunge down the nested loop */
- if (join_tab < join->join_tab + join->tables - 1)
+ if (join_tab < join->join_tab + join->top_join_tab_count - 1)
rc= (*join_tab->next_select)(join, join_tab + 1, 0);
else
{
@@ -11833,19 +15859,61 @@ 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 (rc != NESTED_LOOP_NO_MORE_ROWS &&
+ (rc= join_tab_execution_startup(join_tab)) < 0)
+ DBUG_RETURN(rc);
+
+ 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->loosescan_key;
+ key_copy(join_tab->loosescan_buf, join_tab->table->record[0], 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->loosescan_key].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);
}
@@ -11855,16 +15923,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
@@ -11876,18 +15951,22 @@ 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);
+ if (join_tab->table->vfield)
+ update_virtual_fields(join->thd, join_tab->table);
if (select_cond)
{
@@ -11895,7 +15974,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)
@@ -11905,7 +15984,6 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
condition is true => a match is found.
*/
bool found= 1;
- bool use_not_exists_opt= 0;
while (join_tab->first_unmatched && found)
{
/*
@@ -11921,8 +15999,6 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
first_unmatched->found= 1;
for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
{
- if (tab->table->reginfo.not_exists_optimize)
- use_not_exists_opt= 1;
/* Check all predicates that has just been activated. */
/*
Actually all predicates non-guarded by first_unmatched->found
@@ -11933,7 +16009,11 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
{
/* The condition attached to table tab is false */
if (tab == join_tab)
+ {
found= 0;
+ if (tab->table->reginfo.not_exists_optimize)
+ DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS);
+ }
else
{
/*
@@ -11941,7 +16021,10 @@ 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;
+ if (tab->table->reginfo.not_exists_optimize)
+ DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS);
+ else
+ DBUG_RETURN(NESTED_LOOP_OK);
}
}
}
@@ -11955,8 +16038,25 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
join_tab->first_unmatched= first_unmatched;
}
- if (use_not_exists_opt)
- 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= join_tab->check_weed_out_table->sj_weedout_check_row(join->thd);
+ 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
@@ -11974,16 +16074,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);
@@ -11998,10 +16101,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
@@ -12062,109 +16164,32 @@ evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab)
/*
The row complemented by nulls satisfies all conditions
attached to inner tables.
- Send the row complemented by nulls to be joined with the
- remaining tables.
*/
- 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)))
+ if (join_tab->check_weed_out_table)
{
- reset_cache_write(&join_tab->cache);
- return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
+ int res= join_tab->check_weed_out_table->sj_weedout_check_row(join->thd);
+ if (res == -1)
+ return NESTED_LOOP_ERROR;
+ else if (res == 1)
+ return NESTED_LOOP_OK;
}
-
- for (JOIN_TAB *tmp= join_tab-1;
- tmp >= join->join_tab && !tmp->cache.buff; tmp--)
+ else if (join_tab->do_firstmatch)
{
- tmp->status=tmp->table->status;
- tmp->table->status=0;
+ /*
+ We should return to the join_tab->do_firstmatch after we have
+ enumerated all the suffixes for current prefix row combination
+ */
+ if (join_tab->do_firstmatch < join->return_tab)
+ join->return_tab= join_tab->do_firstmatch;
}
- 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_tab-1;
- tmp2 >= join->join_tab && !tmp2->cache.buff; tmp2--)
- tmp2->table->status=tmp2->status;
- return NESTED_LOOP_OK;
+ /*
+ Send the row complemented by nulls to be joined with the
+ remaining tables.
+ */
+ return (*join_tab->next_select)(join, join_tab+1, 0);
}
-
/*****************************************************************************
The different ways to read a record
Returns -1 if row was not found, 0 if row was found and 1 on errors
@@ -12185,8 +16210,13 @@ int report_error(TABLE *table, int error)
*/
if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT
&& !table->in_use->killed)
+ {
+ push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_ERROR, error,
+ "Got error %d when reading table `%s`.`%s`",
+ error, table->s->db.str, table->s->table_name.str);
sql_print_error("Got error %d when reading table '%s'",
error, table->s->path.str);
+ }
table->file->print_error(error,MYF(0));
return 1;
}
@@ -12220,13 +16250,32 @@ static int
join_read_const_table(JOIN_TAB *tab, POSITION *pos)
{
int error;
+ TABLE_LIST *tbl;
DBUG_ENTER("join_read_const_table");
TABLE *table=tab->table;
table->const_table=1;
table->null_row=0;
table->status=STATUS_NO_RECORD;
- if (tab->type == JT_SYSTEM)
+ if (tab->table->pos_in_table_list->is_materialized_derived() &&
+ !tab->table->pos_in_table_list->fill_me)
+ {
+ //TODO: don't get here at all
+ /* Skip materialized derived tables/views. */
+ DBUG_RETURN(0);
+ }
+ else if (tab->table->pos_in_table_list->jtbm_subselect &&
+ tab->table->pos_in_table_list->jtbm_subselect->is_jtbm_const_tab)
+ {
+ /* Row will not be found */
+ int res;
+ if (tab->table->pos_in_table_list->jtbm_subselect->jtbm_const_row_found)
+ res= 0;
+ else
+ res= -1;
+ DBUG_RETURN(res);
+ }
+ else if (tab->type == JT_SYSTEM)
{
if ((error=join_read_system(tab)))
{ // Info for DESCRIBE
@@ -12264,7 +16313,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)
/*
@@ -12283,26 +16339,27 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
if (!table->null_row)
table->maybe_null=0;
- /* Check appearance of new constant items in Item_equal objects */
- JOIN *join= tab->join;
- if (join->conds)
- update_const_equal_items(join->conds, tab, TRUE);
- TABLE_LIST *tbl;
- for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
{
- TABLE_LIST *embedded;
- TABLE_LIST *embedding= tbl;
- do
- {
- embedded= embedding;
- if (embedded->on_expr)
- update_const_equal_items(embedded->on_expr, tab, TRUE);
- embedding= embedded->embedding;
+ JOIN *join= tab->join;
+ List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables);
+ /* Check appearance of new constant items in Item_equal objects */
+ if (join->conds)
+ update_const_equal_items(join->conds, tab, TRUE);
+ while ((tbl= ti++))
+ {
+ TABLE_LIST *embedded;
+ TABLE_LIST *embedding= tbl;
+ do
+ {
+ embedded= embedding;
+ if (embedded->on_expr)
+ update_const_equal_items(embedded->on_expr, tab, TRUE);
+ embedding= embedded->embedding;
+ }
+ while (embedding &&
+ embedding->nested_join->join_list.head() == embedded);
}
- while (embedding &&
- embedding->nested_join->join_list.head() == embedded);
}
-
DBUG_RETURN(0);
}
@@ -12333,7 +16390,8 @@ join_read_system(JOIN_TAB *tab)
empty_record(table); // Make empty record
return -1;
}
- update_virtual_fields(tab->join->thd, table);
+ if (table->vfield)
+ update_virtual_fields(tab->join->thd, table);
store_record(table,record[1]);
}
else if (!table->status) // Only happens with left join
@@ -12379,7 +16437,8 @@ join_read_const(JOIN_TAB *tab)
return report_error(table, error);
return -1;
}
- update_virtual_fields(tab->join->thd, table);
+ if (table->vfield)
+ update_virtual_fields(tab->join->thd, table);
store_record(table,record[1]);
}
else if (!(table->status & ~STATUS_NULL_ROW)) // Only happens with left join
@@ -12391,25 +16450,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;
@@ -12418,28 +16501,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;
+ tab->read_record.table->file->unlock_row();
+ 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;
@@ -12498,13 +16581,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],
@@ -12610,11 +16686,10 @@ 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;
- if (tab->read_record.file->ha_rnd_init_with_error(1))
+ if (tab->read_record.table->file->ha_rnd_init_with_error(1))
return 1;
return (*tab->read_record.read_record)(&tab->read_record);
}
@@ -12625,21 +16700,50 @@ 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;
+ if (!tab->preread_init_done && tab->preread_init())
+ return 1;
if (init_read_record(&tab->read_record, tab->join->thd, tab->table,
tab->select,1,1, FALSE))
return 1;
return (*tab->read_record.read_record)(&tab->read_record);
}
+int
+join_read_record_no_init(JOIN_TAB *tab)
+{
+ Copy_field *save_copy, *save_copy_end;
+
+ /*
+ init_read_record resets all elements of tab->read_record().
+ Remember things that we don't want to have reset.
+ */
+ save_copy= tab->read_record.copy_field;
+ save_copy_end= tab->read_record.copy_field_end;
+
+ init_read_record(&tab->read_record, tab->join->thd, tab->table,
+ tab->select,1,1, FALSE);
+
+ tab->read_record.copy_field= save_copy;
+ tab->read_record.copy_field_end= save_copy_end;
+ tab->read_record.read_record= rr_sequential_and_unpack;
+
+ return (*tab->read_record.read_record)(&tab->read_record);
+}
static int
join_read_first(JOIN_TAB *tab)
@@ -12652,7 +16756,6 @@ join_read_first(JOIN_TAB *tab)
tab->table->status=0;
tab->read_record.read_record=join_read_next;
tab->read_record.table=table;
- tab->read_record.file=table->file;
tab->read_record.index=tab->index;
tab->read_record.record=table->record[0];
if (!table->file->inited)
@@ -12673,7 +16776,7 @@ static int
join_read_next(READ_RECORD *info)
{
int error;
- if ((error= info->file->ha_index_next(info->record)))
+ if ((error= info->table->file->ha_index_next(info->record)))
return report_error(info->table, error);
return 0;
@@ -12691,7 +16794,6 @@ join_read_last(JOIN_TAB *tab)
tab->table->status=0;
tab->read_record.read_record=join_read_prev;
tab->read_record.table=table;
- tab->read_record.file=table->file;
tab->read_record.index=tab->index;
tab->read_record.record=table->record[0];
if (!table->file->inited)
@@ -12709,7 +16811,7 @@ static int
join_read_prev(READ_RECORD *info)
{
int error;
- if ((error= info->file->ha_index_prev(info->record)))
+ if ((error= info->table->file->ha_index_prev(info->record)))
return report_error(info->table, error);
return 0;
}
@@ -12743,7 +16845,7 @@ static int
join_ft_read_next(READ_RECORD *info)
{
int error;
- if ((error= info->file->ha_ft_read(info->table->record[0])))
+ if ((error= info->table->file->ha_ft_read(info->table->record[0])))
return report_error(info->table, error);
return 0;
}
@@ -12839,7 +16941,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (join->select_options & OPTION_FOUND_ROWS)
{
JOIN_TAB *jt=join->join_tab;
- if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group
+ if ((join->table_count == 1) && !join->tmp_table && !join->sort_and_group
&& !join->send_group_parts && !join->having && !jt->select_cond &&
!(jt->select && jt->select->quick) &&
(jt->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
@@ -12890,7 +16992,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)
{
@@ -13053,12 +17155,14 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
int error;
join->found_records++;
- if ((error= table->file->ha_write_row(table->record[0])))
+ if ((error= table->file->ha_write_tmp_row(table->record[0])))
{
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
}
@@ -13115,8 +17219,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{ /* Update old record */
restore_record(table,record[1]);
update_tmptable_sum_func(join->sum_funcs,table);
- if ((error= table->file->ha_update_row(table->record[1],
- table->record[0])))
+ if ((error= table->file->ha_update_tmp_row(table->record[1],
+ table->record[0])))
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
@@ -13140,10 +17244,11 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
init_tmptable_sum_functions(join->sum_funcs);
if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
- if ((error= table->file->ha_write_row(table->record[0])))
+ if ((error= table->file->ha_write_tmp_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 */
@@ -13152,7 +17257,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
table->file->print_error(error, MYF(0));/* purecov: inspected */
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
}
- join->join_tab[join->tables-1].next_select=end_unique_update;
+ join->join_tab[join->top_join_tab_count-1].next_select=end_unique_update;
}
join->send_records++;
DBUG_RETURN(NESTED_LOOP_OK);
@@ -13182,7 +17287,7 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
- if (!(error= table->file->ha_write_row(table->record[0])))
+ if (!(error= table->file->ha_write_tmp_row(table->record[0])))
join->send_records++; // New group
else
{
@@ -13198,8 +17303,8 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
}
restore_record(table,record[1]);
update_tmptable_sum_func(join->sum_funcs,table);
- if ((error= table->file->ha_update_row(table->record[1],
- table->record[0])))
+ if ((error= table->file->ha_update_tmp_row(table->record[1],
+ table->record[0])))
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
@@ -13210,7 +17315,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)
{
@@ -13242,10 +17347,12 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
join->sum_funcs_end[send_group_parts]);
if (!join->having || join->having->val_int())
{
- int error= table->file->ha_write_row(table->record[0]);
- if (error && create_internal_tmp_table_from_heap(join->thd, table,
- &join->tmp_table_param,
- error, 0))
+ int error= table->file->ha_write_tmp_row(table->record[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)
@@ -13293,18 +17400,49 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
*****************************************************************************/
/**
- @return
- 1 if right_item is used removable reference key on left_item
+ Check if "left_item=right_item" equality is guaranteed to be true by use of
+ [eq]ref access on left_item->field->table.
+
+ SYNOPSIS
+ test_if_ref()
+ root_cond
+ left_item
+ right_item
+
+ DESCRIPTION
+ Check if the given "left_item = right_item" equality is guaranteed to be
+ true by use of [eq_]ref access method.
+
+ We need root_cond as we can't remove ON expressions even if employed ref
+ access guarantees that they are true. This is because TODO
+
+ RETURN
+ TRUE if right_item is used removable reference key on left_item
+ FALSE Otherwise
+
*/
-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->is_ref_for_hash_join() &&
+ (!join_tab->first_inner ||
+ *join_tab->first_inner->on_expr_ref == root_cond))
{
+ /*
+ If ref access uses "Full scan on NULL key" (i.e. it actually alternates
+ between ref access and full table scan), then no equality can be
+ guaranteed to be true.
+ */
+ if (join_tab->ref.is_access_triggered())
+ return FALSE;
+
Item *ref_item=part_of_refkey(field->table,field);
- if (ref_item && ref_item->eq(right_item,1))
+ if (ref_item && (ref_item->eq(right_item,1) ||
+ ref_item->real_item()->eq(right_item,1)))
{
right_item= right_item->real_item();
if (right_item->type() == Item::FIELD_ITEM)
@@ -13316,7 +17454,7 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
{
/*
We can remove binary fields and numerical fields except float,
- as float comparison isn't 100 % secure
+ as float comparison isn't 100 % safe
We have to keep normal strings to be able to check for end spaces
*/
if (field->binary() &&
@@ -13332,14 +17470,24 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
return 0; // keep test
}
+
/**
Extract a condition that can be checked after reading given table
+ @fn make_cond_for_table()
@param cond Condition to analyze
@param tables Tables for which "current field values" are available
- @param used_table Table that we're extracting the condition for (may
- also include PSEUDO_TABLE_BITS, and may be zero)
- @param exclude_expensive_cond Do not push expensive conditions
+ @param used_table Table that we're extracting the condition for
+ tables Tables for which "current field values" are available (this
+ includes used_table)
+ (may also include PSEUDO_TABLE_BITS, and may be zero)
+ @param join_tab_idx_arg
+ The index of the JOIN_TAB this Item is being extracted
+ for. MAX_TABLES if there is no corresponding JOIN_TAB.
+ @param exclude_expensive_cond
+ Do not push expensive conditions
+ @param retain_ref_cond
+ Retain ref conditions
@retval <>NULL Generated condition
@retval =NULL Already checked, OR error
@@ -13369,11 +17517,32 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
make_cond_for_info_schema() uses similar algorithm as well.
*/
-static COND *
-make_cond_for_table(COND *cond, table_map tables, table_map used_table)
+static Item *
+make_cond_for_table(THD *thd, Item *cond, table_map tables,
+ table_map used_table,
+ int join_tab_idx_arg,
+ bool exclude_expensive_cond __attribute__((unused)),
+ bool retain_ref_cond)
+{
+ return make_cond_for_table_from_pred(thd, cond, cond, tables, used_table,
+ join_tab_idx_arg,
+ exclude_expensive_cond,
+ retain_ref_cond);
+}
+
+
+static Item *
+make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
+ table_map tables, table_map used_table,
+ int join_tab_idx_arg,
+ bool exclude_expensive_cond __attribute__
+ ((unused)),
+ bool retain_ref_cond)
+
{
if (used_table && !(cond->used_tables() & used_table))
return (COND*) 0; // Already checked
+
if (cond->type() == Item::COND_ITEM)
{
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
@@ -13386,7 +17555,138 @@ 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_for_table_from_pred(thd, root_cond, item,
+ tables, used_table,
+ join_tab_idx_arg,
+ 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:
+ /*
+ Call fix_fields to propagate all properties of the children to
+ the new parent Item. This should not be expensive because all
+ children of Item_cond_and should be fixed by now.
+ */
+ new_cond->fix_fields(thd, 0);
+ 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(thd, root_cond, item,
+ tables, 0L,
+ join_tab_idx_arg,
+ exclude_expensive_cond,
+ retain_ref_cond);
+ if (!fix)
+ return (COND*) 0; // Always true
+ new_cond->argument_list()->push_back(fix);
+ }
+ /*
+ Call fix_fields to propagate all properties of the children to
+ the new parent Item. This should not be expensive because all
+ children of Item_cond_and should be fixed by now.
+ */
+ new_cond->fix_fields(thd, 0);
+ 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))
+ return (COND*) 0; // Can't check this yet
+
+ if (cond->marker == 2 || cond->eq_cmp_result() == Item::COND_OK)
+ {
+ cond->set_join_tab_idx(join_tab_idx_arg);
+ 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;
+ cond->set_join_tab_idx(join_tab_idx_arg);
+ return cond;
+}
+
+
+/*
+ The difference of this from make_cond_for_table() is that we're in the
+ following state:
+ 1. conditions referring to 'tables' have been checked
+ 2. conditions referring to sjm_tables have been checked, too
+ 3. We need condition that couldn't be checked in #1 or #2 but
+ can be checked when we get both (tables | sjm_tables).
+
+*/
+static COND *
+make_cond_after_sjm(Item *root_cond, Item *cond, table_map tables,
+ table_map sjm_tables, bool inside_or_clause)
+{
+ /*
+ We assume that conditions that refer to only join prefix tables or
+ sjm_tables have already been checked.
+ */
+ if (!inside_or_clause &&
+ (!(cond->used_tables() & ~tables) ||
+ !(cond->used_tables() & ~sjm_tables)))
+ return (COND*) 0; // Already checked
+
+ /* AND/OR recursive descent */
+ 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_after_sjm(root_cond, item, tables, sjm_tables,
+ inside_or_clause);
if (fix)
new_cond->argument_list()->push_back(fix);
}
@@ -13416,7 +17716,8 @@ 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, sjm_tables,
+ /*inside_or_clause= */TRUE);
if (!fix)
return (COND*) 0; // Always true
new_cond->argument_list()->push_back(fix);
@@ -13438,23 +17739,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;
@@ -13464,22 +17769,62 @@ make_cond_for_table(COND *cond, table_map tables, table_map used_table)
return cond;
}
+
+/*
+ @brief
+
+ Check if
+ - @table uses "ref"-like access
+ - it is based on "@field=certain_item" equality
+ - the equality will be true for any record returned by the access method
+ and return the certain_item if yes.
+
+ @detail
+
+ Equality won't necessarily hold if:
+ - the used index covers only part of the @field.
+ Suppose, we have a CHAR(5) field and INDEX(field(3)). if you make a lookup
+ for 'abc', you will get both record with 'abc' and with 'abcde'.
+ - The type of access is actually ref_or_null, and so @field can be either
+ a value or NULL.
+
+ @return
+ Item that the field will be equal to
+ NULL if no such item
+*/
+
static Item *
part_of_refkey(TABLE *table,Field *field)
{
- if (!table->reginfo.join_tab)
+ JOIN_TAB *join_tab= table->reginfo.join_tab;
+ if (!join_tab)
return (Item*) 0; // field from outer non-select (UPDATE,...)
- uint ref_parts=table->reginfo.join_tab->ref.key_parts;
- if (ref_parts)
+ uint ref_parts= join_tab->ref.key_parts;
+ if (ref_parts) /* if it's ref/eq_ref/ref_or_null */
{
- KEY_PART_INFO *key_part=
- table->key_info[table->reginfo.join_tab->ref.key].key_part;
+ uint key= join_tab->ref.key;
+ KEY *key_info= join_tab->get_keyinfo_by_key_no(key);
+ KEY_PART_INFO *key_part= key_info->key_part;
for (uint part=0 ; part < ref_parts ; part++,key_part++)
- if (field->eq(key_part->field) &&
- !(key_part->key_part_flag & (HA_PART_KEY_SEG | HA_NULL_PART)))
- return table->reginfo.join_tab->ref.items[part];
+ {
+ if (field->eq(key_part->field))
+ {
+ /*
+ Found the field in the key. Check that
+ 1. ref_or_null doesn't alternate this component between a value and
+ a NULL
+ 2. index fully covers the key
+ */
+ if (part != join_tab->ref.null_ref_part && // (1)
+ !(key_part->key_part_flag & HA_PART_KEY_SEG)) // (2)
+ {
+ return join_tab->ref.items[part];
+ }
+ break;
+ }
+ }
}
return (Item*) 0;
}
@@ -13850,8 +18195,8 @@ 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)
+test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit_arg,
+ bool no_changes, const key_map *map)
{
int ref_key;
uint ref_key_parts;
@@ -13860,10 +18205,16 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
TABLE *table=tab->table;
SQL_SELECT *select=tab->select;
key_map usable_keys;
- QUICK_SELECT_I *save_quick= 0;
+ QUICK_SELECT_I *save_quick= select ? select->quick : 0;
+ Item *orig_cond= 0;
+ bool orig_cond_saved= false;
int best_key= -1;
+ bool changed_key= false;
+ ha_rows best_select_limit;
DBUG_ENTER("test_if_skip_sort_order");
+
LINT_INIT(ref_key_parts);
+ LINT_INIT(best_select_limit);
/* Check that we are always called with first non-const table */
DBUG_ASSERT(tab == tab->join->join_tab + tab->join->const_tables);
@@ -13884,7 +18235,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;
@@ -13894,27 +18245,30 @@ 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
{
int quick_type= select->quick->get_type();
- save_quick= select->quick;
/*
assume results are not ordered when index merge is used
TODO: sergeyp: Results of all index merge selects actually are ordered
by clustered PK values.
*/
- if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
+ if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
+ quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT)
- DBUG_RETURN(0);
- ref_key= select->quick->index;
- ref_key_parts= select->quick->used_key_parts;
+ ref_key= MAX_KEY;
+ else
+ {
+ ref_key= select->quick->index;
+ ref_key_parts= select->quick->used_key_parts;
+ }
}
- if (ref_key >= 0)
+ if (ref_key >= 0 && ref_key != MAX_KEY)
{
/*
We come here when there is a REF key.
@@ -13931,10 +18285,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_cond= tab->set_cond(tab->pre_idx_push_select_cond);
+ orig_cond_saved= true;
+ }
+
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 */
if (tab->ref.key >= 0)
{
/*
@@ -13948,10 +18307,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,
+ if (create_ref_for_key(tab->join, tab, keyuse, FALSE,
(tab->join->const_table_map |
OUTER_REF_TABLE_BIT)))
- DBUG_RETURN(0);
+ goto use_filesort;
pick_table_access_method(tab);
}
@@ -13961,26 +18320,41 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
The range optimizer constructed QUICK_RANGE for ref_key, and
we want to use instead new_ref_key as the index. We can't
just change the index of the quick select, because this may
- result in an incosistent QUICK_SELECT object. Below we
+ result in an inconsistent QUICK_SELECT object. Below we
create a new QUICK_SELECT from scratch so that all its
- parameres are set correctly by the range optimizer.
+ parameters are set correctly by the range optimizer.
*/
key_map new_ref_key_map;
+ COND *save_cond;
+ bool res;
new_ref_key_map.clear_all(); // Force the creation of quick select
new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
/* Reset quick; This will be restored in 'use_filesort' if needed */
select->quick= 0;
- if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
- (tab->join->select_options &
- OPTION_FOUND_ROWS) ?
- HA_POS_ERROR :
- tab->join->unit->select_limit_cnt,0) <=
- 0)
+ save_cond= select->cond;
+ if (select->pre_idx_push_select_cond)
+ select->cond= select->pre_idx_push_select_cond;
+ res= select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
+ (tab->join->select_options &
+ OPTION_FOUND_ROWS) ?
+ HA_POS_ERROR :
+ tab->join->unit->select_limit_cnt,0,
+ TRUE) <= 0;
+ if (res)
+ {
+ select->cond= save_cond;
goto use_filesort;
+ }
+ /*
+ We don't restore select->cond as we want to use the
+ original condition as index condition pushdown is not
+ active for the new index.
+ */
}
ref_key= new_ref_key;
- }
+ changed_key= true;
+ }
}
/* Check if we get the rows in requested sorted order by using the key */
if (usable_keys.is_set(ref_key) &&
@@ -14018,7 +18392,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
resolved with a key; This is because filesort() is usually faster than
retrieving all rows through an index.
*/
- if (select_limit >= table_records)
+ if (select_limit_arg >= table_records)
{
keys= *table->file->keys_to_use_for_scanning();
keys.merge(table->covering_keys);
@@ -14036,16 +18410,18 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
else
keys= usable_keys;
- if (ref_key >= 0 && table->covering_keys.is_set(ref_key))
+ if (ref_key >= 0 && ref_key != MAX_KEY &&
+ table->covering_keys.is_set(ref_key))
ref_key_quick_rows= table->quick_rows[ref_key];
read_time= join->best_positions[tablenr].read_time;
- for (uint i= tablenr+1; i < join->tables; i++)
+ for (uint i= tablenr+1; i < join->table_count; i++)
fanout*= join->best_positions[i].records_read; // fanout is always >= 1
for (nr=0; nr < table->s->keys ; nr++)
{
int direction;
+ ha_rows select_limit= select_limit_arg;
if (keys.is_set(nr) &&
(direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
@@ -14057,9 +18433,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*/
DBUG_ASSERT (ref_key != (int) nr);
- bool is_covering= table->covering_keys.is_set(nr) ||
- (nr == table->s->primary_key &&
- table->file->primary_key_is_clustered());
+ bool is_covering= (table->covering_keys.is_set(nr) ||
+ (table->file->index_flags(nr, 0, 1) &
+ HA_CLUSTERED_INDEX));
/*
Don't use an index scan with ORDER BY without limit.
@@ -14139,7 +18515,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
select_limit= table_records;
else
select_limit= (ha_rows) (select_limit*rec_per_key);
- }
+ } /* group */
+
/*
If tab=tk is not the last joined table tn then to get first
L records from the result set we can expect to retrieve
@@ -14150,8 +18527,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
and as result we'll choose an index scan when using ref/range
access + filesort will be cheaper.
*/
- select_limit= (ha_rows) (select_limit < fanout ?
- 1 : select_limit/fanout);
+ if (select_limit_arg != HA_POS_ERROR)
+ select_limit= (ha_rows) (select_limit < fanout ?
+ 1 : select_limit/fanout);
/*
We assume that each of the tested indexes is not correlated
with ref_key. Thus, to select first N records we have to scan
@@ -14183,8 +18561,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*/
index_scan_time= select_limit/rec_per_key *
min(rec_per_key, table->file->scan_time());
- if ((ref_key < 0 && is_covering) ||
- (ref_key < 0 && (group || table->force_index)) ||
+ if ((ref_key < 0 && (group || table->force_index || is_covering)) ||
index_scan_time < read_time)
{
ha_rows quick_records= table_records;
@@ -14196,7 +18573,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
if (best_key < 0 ||
(select_limit <= min(quick_records,best_records) ?
keyinfo->key_parts < best_key_parts :
- quick_records < best_records))
+ quick_records < best_records) ||
+ (!is_best_covering && is_covering))
{
best_key= nr;
best_key_parts= keyinfo->key_parts;
@@ -14204,6 +18582,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
best_records= quick_records;
is_best_covering= is_covering;
best_key_direction= direction;
+ best_select_limit= select_limit;
}
}
}
@@ -14213,42 +18592,38 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
/*
filesort() and join cache are usually faster than reading in
index order and not using join cache, except in case that chosen
- index is clustered primary key.
+ index is clustered key.
*/
- if ((select_limit >= table_records) &&
- (tab->type == JT_ALL &&
- tab->join->tables > tab->join->const_tables + 1) &&
- ((unsigned) best_key != table->s->primary_key ||
- !table->file->primary_key_is_clustered()))
+ if (best_key < 0 ||
+ ((select_limit_arg >= table_records) &&
+ (tab->type == JT_ALL &&
+ tab->join->table_count > tab->join->const_tables + 1) &&
+ !(table->file->index_flags(best_key, 0, 1) & HA_CLUSTERED_INDEX)))
goto use_filesort;
- if (best_key >= 0)
+ if (table->quick_keys.is_set(best_key) && best_key != ref_key)
{
- if (table->quick_keys.is_set(best_key) && best_key != ref_key)
- {
- key_map map;
- map.clear_all(); // Force the creation of quick select
- map.set_bit(best_key); // only best_key.
- select->quick= 0;
- select->test_quick_select(join->thd, map, 0,
- join->select_options & OPTION_FOUND_ROWS ?
- HA_POS_ERROR :
- join->unit->select_limit_cnt,
- 0);
- }
- order_direction= best_key_direction;
- /*
- saved_best_key_parts is actual number of used keyparts found by the
- test_if_order_by_key function. It could differ from keyinfo->key_parts,
- thus we have to restore it in case of desc order as it affects
- QUICK_SELECT_DESC behaviour.
- */
- used_key_parts= (order_direction == -1) ?
- saved_best_key_parts : best_key_parts;
+ key_map map;
+ map.clear_all(); // Force the creation of quick select
+ map.set_bit(best_key); // only best_key.
+ select->quick= 0;
+ select->test_quick_select(join->thd, map, 0,
+ join->select_options & OPTION_FOUND_ROWS ?
+ HA_POS_ERROR :
+ join->unit->select_limit_cnt,
+ TRUE, FALSE);
}
- else
- goto use_filesort;
- }
+ order_direction= best_key_direction;
+ /*
+ saved_best_key_parts is actual number of used keyparts found by the
+ test_if_order_by_key function. It could differ from keyinfo->key_parts,
+ thus we have to restore it in case of desc order as it affects
+ QUICK_SELECT_DESC behaviour.
+ */
+ used_key_parts= (order_direction == -1) ?
+ saved_best_key_parts : best_key_parts;
+ changed_key= true;
+ }
check_reverse_order:
DBUG_ASSERT(order_direction != 0);
@@ -14267,6 +18642,7 @@ check_reverse_order:
quick_type= select->quick->get_type();
if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
+ quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
@@ -14304,13 +18680,23 @@ check_reverse_order:
join_read_first:join_read_last;
tab->type=JT_NEXT; // Read with index_first(), index_next()
+ if (tab->pre_idx_push_select_cond)
+ {
+ tab->set_cond(tab->pre_idx_push_select_cond);
+ /*
+ orig_cond is a part of pre_idx_push_cond,
+ no need to restore it.
+ */
+ orig_cond= 0;
+ orig_cond_saved= false;
+ }
table->file->ha_index_or_rnd_end();
if (tab->join->select_options & SELECT_DESCRIBE)
{
tab->ref.key= -1;
tab->ref.key_parts= 0;
- if (select_limit < table->file->stats.records)
- tab->limit= select_limit;
+ if (best_select_limit < table->file->stats.records)
+ tab->limit= best_select_limit;
}
}
else if (tab->type != JT_ALL)
@@ -14328,6 +18714,16 @@ check_reverse_order:
tab->read_first_record= join_init_read_record;
if (tab->is_using_loose_index_scan())
tab->join->tmp_table_param.precomputed_group_by= TRUE;
+
+ /*
+ Restore the original condition as changes done by pushdown
+ condition are not relevant anymore
+ */
+ if (tab->select && tab->select->pre_idx_push_select_cond)
+ {
+ tab->set_cond(tab->select->pre_idx_push_select_cond);
+ tab->table->file->cancel_pushed_idx_cond();
+ }
/*
TODO: update the number of records in join->best_positions[tablenr]
*/
@@ -14339,18 +18735,29 @@ check_reverse_order:
if (select && select->quick)
{
QUICK_SELECT_DESC *tmp;
+ bool error= FALSE;
+
/* ORDER BY range_key DESC */
tmp= new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick),
- used_key_parts);
+ used_key_parts, &error);
if (tmp && select->quick == save_quick)
save_quick= 0; // ::QUICK_SELECT_DESC consumed it
- if (!tmp || tmp->error)
+ if (!tmp || error)
{
delete tmp;
tab->limit= 0;
goto use_filesort; // Reverse sort failed -> filesort
}
+ /*
+ Cancel Pushed Index Condition, as it doesn't work for reverse scans.
+ */
+ if (tab->select && tab->select->pre_idx_push_select_cond)
+ {
+ tab->set_cond(tab->select->pre_idx_push_select_cond);
+ tab->table->file->cancel_pushed_idx_cond();
+ }
+
select->quick= tmp;
}
else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL &&
@@ -14364,10 +18771,18 @@ check_reverse_order:
*/
tab->read_first_record= join_read_last_key;
tab->read_record.read_record= join_read_prev_same;
+ /*
+ Cancel Pushed Index Condition, as it doesn't work for reverse scans.
+ */
+ if (tab->select && tab->select->pre_idx_push_select_cond)
+ {
+ tab->set_cond(tab->select->pre_idx_push_select_cond);
+ tab->table->file->cancel_pushed_idx_cond();
+ }
}
}
else if (select && select->quick)
- select->quick->sorted= 1;
+ select->quick->need_sorted_output();
} // QEP has been modified
@@ -14384,6 +18799,11 @@ skipped_filesort:
delete save_quick;
save_quick= NULL;
}
+ if (orig_cond_saved && !changed_key)
+ tab->set_cond(orig_cond);
+ if (!no_changes && changed_key && table->file->pushed_idx_cond)
+ table->file->cancel_pushed_idx_cond();
+
DBUG_RETURN(1);
use_filesort:
@@ -14393,6 +18813,9 @@ use_filesort:
delete select->quick;
select->quick= save_quick;
}
+ if (orig_cond_saved)
+ tab->set_cond(orig_cond);
+
DBUG_RETURN(0);
}
@@ -14438,12 +18861,23 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
JOIN_TAB *tab;
DBUG_ENTER("create_sort_index");
- if (join->tables == join->const_tables)
+ if (join->table_count == join->const_tables)
DBUG_RETURN(0); // One row, no need to sort
tab= join->join_tab + join->const_tables;
table= tab->table;
select= tab->select;
+ /* Currently ORDER BY ... LIMIT is not supported in subqueries. */
+ DBUG_ASSERT(join->group_list || !join->is_in_subquery());
+
+ /*
+ If we have a select->quick object that is created outside of
+ create_sort_index() and this is part of a subquery that
+ potentially can be executed multiple times then we should not
+ delete the quick object on exit from this function.
+ */
+ bool keep_quick= select && select->quick && join->join_tab_save;
+
/*
When there is SQL_BIG_RESULT do not sort using index for GROUP BY,
and thus force sorting on disk unless a group min-max optimization
@@ -14491,10 +18925,11 @@ 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;
+ DBUG_ASSERT(!keep_quick);
}
}
@@ -14503,6 +18938,8 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX))
goto err;
+ if (!tab->preread_init_done && tab->preread_init())
+ goto err;
if (table->s->tmp_table)
table->file->info(HA_STATUS_VARIABLE); // Get record count
table->sort.found_records=filesort(thd, table,join->sortorder, length,
@@ -14524,11 +18961,28 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
tablesort_result_cache= table->sort.io_cache;
table->sort.io_cache= NULL;
-
- select->cleanup(); // filesort did select
- table->quick_keys.clear_all(); // as far as we cleanup select->quick
+ /*
+ If a quick object was created outside of create_sort_index()
+ that might be reused, then do not call select->cleanup() since
+ it will delete the quick object.
+ */
+ if (!keep_quick)
+ {
+ select->cleanup();
+ /*
+ The select object should now be ready for the next use. If it
+ is re-used then there exists a backup copy of this join tab
+ which has the pointer to it. The join tab will be restored in
+ JOIN::reset(). So here we just delete the pointer to it.
+ */
+ tab->select= NULL;
+ // If we deleted the quick select object we need to clear quick_keys
+ table->quick_keys.clear_all();
+ }
+ // Restore the output resultset
table->sort.io_cache= tablesort_result_cache;
}
+ tab->set_select_cond(NULL, __LINE__);
tab->last_inner= 0;
tab->first_unmatched= 0;
tab->type=JT_ALL; // Read with normal read_record
@@ -14552,7 +19006,9 @@ 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(join->thd, *having, used_tables,
+ used_tables, MAX_TABLES,
+ FALSE, FALSE);
if (sort_table_cond)
{
if (!table->select)
@@ -14565,12 +19021,14 @@ 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(join->thd, *having,
+ ~ (table_map) 0,~used_tables,
+ MAX_TABLES, FALSE, FALSE);
DBUG_EXECUTE("where",
print_where(*having,"having after make_cond", QT_ORDINARY););
}
@@ -14579,19 +19037,24 @@ static bool fix_having(JOIN *join, Item **having)
#endif
-/*****************************************************************************
- Remove duplicates from tmp table
- This should be recoded to add a unique index to the table and remove
- duplicates
- Table is a locked single thread table
- fields is the number of fields to check (from the end)
-*****************************************************************************/
+/**
+ Compare fields from table->record[0] and table->record[1],
+ possibly skipping few first fields.
+
+ @param table
+ @param ptr field to start the comparison from,
+ somewhere in the table->field[] array
+ @retval 1 different
+ @retval 0 identical
+*/
static bool compare_record(TABLE *table, Field **ptr)
{
for (; *ptr ; ptr++)
{
- if ((*ptr)->cmp_offset(table->s->rec_buff_length))
+ Field *f= *ptr;
+ if (f->is_null() != f->is_null(table->s->rec_buff_length) ||
+ (!f->is_null() && f->cmp_offset(table->s->rec_buff_length)))
return 1;
}
return 0;
@@ -14619,15 +19082,15 @@ static void free_blobs(Field **ptr)
static int
-remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
+remove_duplicates(JOIN *join, TABLE *table, List<Item> &fields, Item *having)
{
int error;
- ulong reclength,offset;
+ ulong keylength= 0;
uint field_count;
THD *thd= join->thd;
DBUG_ENTER("remove_duplicates");
- entry->reginfo.lock_type=TL_WRITE;
+ table->reginfo.lock_type=TL_WRITE;
/* Calculate how many saved fields there is in list */
field_count=0;
@@ -14644,24 +19107,21 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
join->unit->select_limit_cnt= 1; // Only send first row
DBUG_RETURN(0);
}
- Field **first_field=entry->field+entry->s->fields - field_count;
- offset= (field_count ?
- entry->field[entry->s->fields - field_count]->
- offset(entry->record[0]) : 0);
- reclength=entry->s->reclength-offset;
-
- free_io_cache(entry); // Safety
- entry->file->info(HA_STATUS_VARIABLE);
- if (entry->s->db_type() == heap_hton ||
- (!entry->s->blob_fields &&
- ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
+
+ Field **first_field=table->field+table->s->fields - field_count;
+ for (Field **ptr=first_field; *ptr; ptr++)
+ keylength+= (*ptr)->sort_length() + (*ptr)->maybe_null();
+
+ free_io_cache(table); // Safety
+ table->file->info(HA_STATUS_VARIABLE);
+ if (table->s->db_type() == heap_hton ||
+ (!table->s->blob_fields &&
+ ((ALIGN_SIZE(keylength) + HASH_OVERHEAD) * table->file->stats.records <
thd->variables.sortbuff_size)))
- error=remove_dup_with_hash_index(join->thd, entry,
- field_count, first_field,
- reclength, having);
+ error=remove_dup_with_hash_index(join->thd, table, field_count, first_field,
+ keylength, having);
else
- error=remove_dup_with_compare(join->thd, entry, first_field, offset,
- having);
+ error=remove_dup_with_compare(join->thd, table, first_field, having);
free_blobs(first_field);
DBUG_RETURN(error);
@@ -14669,18 +19129,13 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
- ulong offset, Item *having)
+ Item *having)
{
handler *file=table->file;
- char *org_record,*new_record;
- uchar *record;
+ uchar *record=table->record[0];
int error;
- ulong reclength= table->s->reclength-offset;
DBUG_ENTER("remove_dup_with_compare");
- org_record=(char*) (record=table->record[0])+offset;
- new_record=(char*) table->record[1]+offset;
-
if (file->ha_rnd_init_with_error(1))
DBUG_RETURN(1);
@@ -14717,7 +19172,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
error=0;
goto err;
}
- memcpy(new_record,org_record,reclength);
+ store_record(table,record[1]);
/* Read through rest of file and mark duplicated rows deleted */
bool found=0;
@@ -14776,8 +19231,9 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
int error;
handler *file= table->file;
ulong extra_length= ALIGN_SIZE(key_length)-key_length;
- uint *field_lengths,*field_length;
+ uint *field_lengths, *field_length;
HASH hash;
+ Field **ptr;
DBUG_ENTER("remove_dup_with_hash_index");
if (!my_multi_malloc(MYF(MY_WME),
@@ -14789,21 +19245,8 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
NullS))
DBUG_RETURN(1);
- {
- Field **ptr;
- ulong total_length= 0;
- for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
- {
- uint length= (*ptr)->sort_length();
- (*field_length++)= length;
- total_length+= length;
- }
- DBUG_PRINT("info",("field_count: %u key_length: %lu total_length: %lu",
- field_count, key_length, total_length));
- DBUG_ASSERT(total_length <= key_length);
- key_length= total_length;
- extra_length= ALIGN_SIZE(key_length)-key_length;
- }
+ for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
+ (*field_length++)= (*ptr)->sort_length();
if (hash_init(&hash, &my_charset_bin, (uint) file->stats.records, 0,
key_length, (hash_get_key) 0, 0, 0))
@@ -14843,13 +19286,13 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
/* copy fields to key buffer */
org_key_pos= key_pos;
field_length=field_lengths;
- for (Field **ptr= first_field ; *ptr ; ptr++)
+ for (ptr= first_field ; *ptr ; ptr++)
{
- (*ptr)->sort_string(key_pos,*field_length);
- key_pos+= *field_length++;
+ (*ptr)->make_sort_key(key_pos, *field_length);
+ key_pos+= (*ptr)->maybe_null() + *field_length++;
}
/* Check if it exists before */
- if (hash_search(&hash, org_key_pos, key_length))
+ if (my_hash_search(&hash, org_key_pos, key_length))
{
/* Duplicated found ; Remove the row */
if ((error= file->ha_delete_row(record)))
@@ -14918,277 +19361,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);
-
- 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;
-}
-
-static bool
-store_record_in_cache(JOIN_CACHE *cache)
-{
- 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++)
- {
- if (copy->type == CACHE_BLOB)
- {
- 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;
-}
+/*
+ eq_ref: Create the lookup key and check if it is the same as saved key
-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;
-}
+ 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 void
-read_cached_record(JOIN_TAB *tab)
+static bool
+cmp_buffer_with_ref(THD *thd, TABLE *table, TABLE_REF *tab_ref)
{
- 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++)
+ bool no_prev_key;
+ if (!tab_ref->disable_cache)
{
- 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 (!(no_prev_key= tab_ref->key_err))
{
- 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;
}
@@ -15281,7 +19500,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
order->in_field_list= 1;
order->counter= count;
order->counter_used= 1;
- return FALSE;
+ return FALSE;
}
/* Lookup the current GROUP/ORDER field in the SELECT clause. */
select_item= find_item_in_list(order_item, fields, &counter,
@@ -15726,8 +19945,10 @@ test_if_subpart(ORDER *a,ORDER *b)
*/
static TABLE *
-get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables)
+get_sort_by_table(ORDER *a,ORDER *b, List<TABLE_LIST> &tables)
{
+ TABLE_LIST *table;
+ List_iterator<TABLE_LIST> ti(tables);
table_map map= (table_map) 0;
DBUG_ENTER("get_sort_by_table");
@@ -15745,11 +19966,11 @@ get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables)
if (!map || (map & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT)))
DBUG_RETURN(0);
- for (; !(map & tables->table->map); tables= tables->next_leaf) ;
- if (map != tables->table->map)
+ while ((table= ti++) && !(map & table->table->map)) ;
+ if (map != table->table->map)
DBUG_RETURN(0); // More than one table
- DBUG_PRINT("exit",("sort by table: %d",tables->table->tablenr));
- DBUG_RETURN(tables->table);
+ DBUG_PRINT("exit",("sort by table: %d",table->table->tablenr));
+ DBUG_RETURN(table->table);
}
@@ -15886,7 +20107,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;
}
@@ -15896,6 +20117,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)
{
@@ -16035,7 +20288,7 @@ 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->real_type() == Item::SUBSELECT_ITEM ||
real_pos->type() == Item::CACHE_ITEM ||
real_pos->type() == Item::COND_ITEM) &&
!real_pos->with_sum_func)
@@ -16526,7 +20779,6 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
}
if (thd->is_fatal_error)
DBUG_RETURN(TRUE);
-
if (!cond->fixed)
{
Item *tmp_item= (Item*) cond;
@@ -16535,13 +20787,26 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
}
if (join_tab->select)
{
+ Item *cond_copy;
+ UNINIT_VAR(cond_copy); // used when pre_idx_push_select_cond!=NULL
+ if (join_tab->select->pre_idx_push_select_cond)
+ cond_copy= cond->copy_andor_structure(thd);
if (join_tab->select->cond)
error=(int) cond->add(join_tab->select->cond);
- join_tab->select_cond=join_tab->select->cond=cond;
+ join_tab->select->cond= cond;
+ if (join_tab->select->pre_idx_push_select_cond)
+ {
+ Item *new_cond= and_conds(cond_copy, join_tab->select->pre_idx_push_select_cond);
+ if (!new_cond->fixed && new_cond->fix_fields(thd, &new_cond))
+ error= 1;
+ join_tab->pre_idx_push_select_cond=
+ join_tab->select->pre_idx_push_select_cond= new_cond;
+ }
+ join_tab->set_select_cond(cond, __LINE__);
}
else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
&error)))
- join_tab->select_cond=cond;
+ join_tab->set_select_cond(cond, __LINE__);
DBUG_RETURN(error ? TRUE : FALSE);
}
@@ -16998,10 +21263,12 @@ int JOIN::rollup_write_data(uint idx, TABLE *table_arg)
item->save_in_result_field(1);
}
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 ((write_error= table_arg->file->ha_write_tmp_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;
}
}
@@ -17144,27 +21411,46 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
if (result->send_data(item_list))
join->error= 1;
}
- else
+ else if (!join->select_lex->master_unit()->derived ||
+ join->select_lex->master_unit()->derived->is_materialized_derived())
{
table_map used_tables=0;
- for (uint i=0 ; i < join->tables ; i++)
+
+ bool printing_materialize_nest= FALSE;
+ uint select_id= join->select_lex->select_number;
+
+ for (JOIN_TAB *tab= first_breadth_first_tab(join); tab;
+ tab= next_breadth_first_tab(join, tab))
{
- JOIN_TAB *tab=join->join_tab+i;
+ if (tab->bush_root_tab)
+ {
+ JOIN_TAB *first_sibling= tab->bush_root_tab->bush_children->start;
+ select_id= first_sibling->emb_sj_nest->sj_subq_pred->get_identifier();
+ printing_materialize_nest= TRUE;
+ }
+
TABLE *table=tab->table;
TABLE_LIST *table_list= tab->table->pos_in_table_list;
char buff[512];
- char buff1[512], buff2[512], buff3[512];
+ char buff1[512], buff2[512], buff3[512], buff4[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);
String tmp2(buff2,sizeof(buff2),cs);
String tmp3(buff3,sizeof(buff3),cs);
+ String tmp4(buff4,sizeof(buff4),cs);
+ char hash_key_prefix[]= "#hash#";
+ KEY *key_info= 0;
+ uint key_len= 0;
+ bool is_hj= tab->type == JT_HASH || tab->type ==JT_HASH_NEXT;
+
extra.length(0);
tmp1.length(0);
tmp2.length(0);
tmp3.length(0);
-
+ tmp4.length(0);
quick_type= -1;
/* Don't show eliminated tables */
@@ -17176,22 +21462,25 @@ 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));
- if (tab->type == JT_ALL && tab->select && tab->select->quick)
+ const char* stype= printing_materialize_nest? "MATERIALIZED" :
+ join->select_lex->type;
+ item_list.push_back(new Item_string(stype, strlen(stype), cs));
+
+ if ((tab->type == JT_ALL || tab->type == JT_HASH) &&
+ tab->select && tab->select->quick)
{
quick_type= tab->select->quick->get_type();
if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
+ (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT) ||
(quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
(quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
- tab->type = JT_INDEX_MERGE;
+ tab->type= tab->type == JT_ALL ? JT_INDEX_MERGE : JT_HASH_INDEX_MERGE;
else
- tab->type = JT_RANGE;
+ tab->type= tab->type == JT_ALL ? JT_RANGE : JT_HASH_RANGE;
}
+
/* table */
if (table->derived_select_number)
{
@@ -17201,6 +21490,16 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
table->derived_select_number);
item_list.push_back(new Item_string(table_name_buffer, len, cs));
}
+ else if (tab->bush_children)
+ {
+ JOIN_TAB *ctab= tab->bush_children->start;
+ /* table */
+ int len= my_snprintf(table_name_buffer,
+ sizeof(table_name_buffer)-1,
+ "<subquery%d>",
+ ctab->emb_sj_nest->sj_subq_pred->get_identifier());
+ item_list.push_back(new Item_string(table_name_buffer, len, cs));
+ }
else
{
TABLE_LIST *real_table= table->pos_in_table_list;
@@ -17253,49 +21552,71 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
item_list.push_back(item_null);
/* Build "key", "key_len", and "ref" values and add them to item_list */
- if (tab->ref.key_parts)
+ if (tab->type == JT_NEXT)
+ {
+ key_info= table->key_info+tab->index;
+ key_len= key_info->key_length;
+ }
+ else if (tab->ref.key_parts)
+ {
+ key_info= tab->get_keyinfo_by_key_no(tab->ref.key);
+ key_len= tab->ref.key_length;
+ }
+ if (key_info)
{
- KEY *key_info=table->key_info+ tab->ref.key;
register uint length;
- item_list.push_back(new Item_string(key_info->name,
- strlen(key_info->name),
- system_charset_info));
- length= (longlong10_to_str(tab->ref.key_length, keylen_str_buf, 10) -
+ if (is_hj)
+ tmp2.append(hash_key_prefix, strlen(hash_key_prefix), cs);
+ tmp2.append(key_info->name, strlen(key_info->name), cs);
+ length= (longlong10_to_str(key_len, keylen_str_buf, 10) -
keylen_str_buf);
- item_list.push_back(new Item_string(keylen_str_buf, length,
- system_charset_info));
- for (store_key **ref=tab->ref.key_copy ; *ref ; ref++)
+ tmp3.append(keylen_str_buf, length, cs);
+ if (tab->ref.key_parts)
{
- if (tmp2.length())
- tmp2.append(',');
- tmp2.append((*ref)->name(), strlen((*ref)->name()),
- system_charset_info);
- }
- item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
+ for (store_key **ref=tab->ref.key_copy ; *ref ; ref++)
+ {
+ if (tmp4.length())
+ tmp4.append(',');
+ tmp4.append((*ref)->name(), strlen((*ref)->name()), cs);
+ }
+ }
}
- else if (tab->type == JT_NEXT)
+ if (is_hj && tab->type != JT_HASH)
{
- KEY *key_info=table->key_info+ tab->index;
- register uint length;
- item_list.push_back(new Item_string(key_info->name,
- strlen(key_info->name),cs));
- length= (longlong10_to_str(key_info->key_length, keylen_str_buf, 10) -
- keylen_str_buf);
- item_list.push_back(new Item_string(keylen_str_buf,
- length,
- system_charset_info));
- item_list.push_back(item_null);
+ tmp2.append(':');
+ tmp3.append(':');
}
- else if (tab->select && tab->select->quick)
+ if (tab->type == JT_HASH_NEXT)
{
+ register uint length;
+ key_info= table->key_info+tab->index;
+ key_len= key_info->key_length;
+ tmp2.append(key_info->name, strlen(key_info->name), cs);
+ length= (longlong10_to_str(key_len, keylen_str_buf, 10) -
+ keylen_str_buf);
+ tmp3.append(keylen_str_buf, length, cs);
+ }
+ if (tab->type != JT_CONST && tab->select && tab->select->quick)
tab->select->quick->add_keys_and_lengths(&tmp2, &tmp3);
- item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
- item_list.push_back(new Item_string(tmp3.ptr(),tmp3.length(),cs));
- item_list.push_back(item_null);
+ if (key_info || (tab->select && tab->select->quick))
+ {
+ if (tmp2.length())
+ item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
+ else
+ item_list.push_back(item_null);
+ if (tmp3.length())
+ item_list.push_back(new Item_string(tmp3.ptr(),tmp3.length(),cs));
+ else
+ item_list.push_back(item_null);
+ if (key_info && tab->type != JT_NEXT)
+ item_list.push_back(new Item_string(tmp4.ptr(),tmp4.length(),cs));
+ else
+ item_list.push_back(item_null);
}
else
{
- if (table_list->schema_table &&
+ if (table_list && /* SJM bushes don't have table_list */
+ table_list->schema_table &&
table_list->schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
{
const char *tmp_buff;
@@ -17326,7 +21647,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
}
/* Add "rows" field to item_list. */
- if (table_list->schema_table)
+ if (table_list /* SJM bushes don't have table_list */ &&
+ table_list->schema_table)
{
/* in_rows */
if (join->thd->lex->describe & DESCRIBE_EXTENDED)
@@ -17339,18 +21661,28 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
ha_rows examined_rows;
if (tab->select && tab->select->quick)
examined_rows= tab->select->quick->records;
- else if (tab->type == JT_NEXT || tab->type == JT_ALL)
+ else if (tab->type == JT_NEXT || tab->type == JT_ALL || is_hj)
{
if (tab->limit)
examined_rows= tab->limit;
else
{
- tab->table->file->info(HA_STATUS_VARIABLE);
- examined_rows= tab->table->file->stats.records;
+ if (tab->table->is_filled_at_execution())
+ {
+ examined_rows= tab->records;
+ }
+ else
+ {
+ /*
+ handler->info(HA_STATUS_VARIABLE) has been called in
+ make_join_statistics()
+ */
+ examined_rows= tab->table->file->stats.records;
+ }
}
}
else
- examined_rows=(ha_rows)join->best_positions[i].records_read;
+ examined_rows=(ha_rows)tab->records_read;
item_list.push_back(new Item_int((longlong) (ulonglong) examined_rows,
MY_INT64_NUM_DECIMAL_DIGITS));
@@ -17360,14 +21692,14 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
{
float f= 0.0;
if (examined_rows)
- f= (float) (100.0 * join->best_positions[i].records_read /
- examined_rows);
+ f= (float) (100.0 * tab->records_read / examined_rows);
+ set_if_smaller(f, 100.0);
item_list.push_back(new Item_float(f, 2));
}
}
/* 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;
@@ -17397,8 +21729,21 @@ 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_INTERSECT ||
quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE)
{
extra.append(STRING_WITH_LEN("; Using "));
@@ -17433,7 +21778,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
extra.append(STRING_WITH_LEN("; Using where"));
}
}
- if (table_list->schema_table &&
+ if (table_list /* SJM bushes don't have table_list */ &&
+ table_list->schema_table &&
table_list->schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
{
if (!table_list->table_open_method)
@@ -17460,6 +21806,32 @@ 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 (quick_type == QUICK_SELECT_I::QS_TYPE_RANGE)
+ {
+ char mrr_str_buf[128];
+ mrr_str_buf[0]=0;
+ int len;
+ uint mrr_flags=
+ ((QUICK_RANGE_SELECT*)(tab->select->quick))->mrr_flags;
+ len= table->file->multi_range_read_explain_info(mrr_flags,
+ mrr_str_buf,
+ sizeof(mrr_str_buf));
+ if (len > 0)
+ {
+ extra.append(STRING_WITH_LEN("; "));
+ extra.append(mrr_str_buf, len);
+ }
+ }
+
if (need_tmp_table)
{
need_tmp_table=0;
@@ -17470,8 +21842,40 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
need_order=0;
extra.append(STRING_WITH_LEN("; Using filesort"));
}
- if (distinct & test_all_bits(used_tables, thd->lex->used_tables))
+ if (distinct & test_all_bits(used_tables,
+ join->select_list_used_tables))
extra.append(STRING_WITH_LEN("; Distinct"));
+ if (tab->loosescan_match_tab)
+ {
+ extra.append(STRING_WITH_LEN("; LooseScan"));
+ }
+
+ if (tab->first_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(")"));
+ }
+ }
for (uint part= 0; part < tab->ref.key_parts; part++)
{
@@ -17481,8 +21885,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();
@@ -17494,6 +21902,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
}
item_list.push_back(new Item_string(str, len, cs));
}
+
// For next iteration
used_tables|=table->map;
if (result->send_data(item_list))
@@ -17504,6 +21913,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))
@@ -17520,28 +21949,12 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
bool res= 0;
SELECT_LEX *first= unit->first_select();
- for (SELECT_LEX *sl= first;
- sl;
- sl= sl->next_select())
- {
- // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
- uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
- sl->type= (((&thd->lex->select_lex)==sl)?
- (sl->first_inner_unit() || sl->next_select() ?
- "PRIMARY" : "SIMPLE"):
- ((sl == first)?
- ((sl->linkage == DERIVED_TABLE_TYPE) ?
- "DERIVED":
- ((uncacheable & UNCACHEABLE_DEPENDENT) ?
- "DEPENDENT SUBQUERY":
- (uncacheable?"UNCACHEABLE SUBQUERY":
- "SUBQUERY"))):
- ((uncacheable & UNCACHEABLE_DEPENDENT) ?
- "DEPENDENT UNION":
- uncacheable?"UNCACHEABLE UNION":
- "UNION")));
+ for (SELECT_LEX *sl= first; sl; sl= sl->next_select())
+ {
+ sl->set_explain_type();
sl->options|= SELECT_DESCRIBE;
}
+
if (unit->is_union())
{
unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
@@ -17571,6 +21984,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.
@@ -17605,45 +22065,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))))
- {
- 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)
+ TABLE_LIST **end= table + tables->elements;
+ for (TABLE_LIST **t2= table; t2!=end; t2++)
{
- 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
@@ -17696,6 +22139,32 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
print_join(thd, eliminated_tables, str, &nested_join->join_list, query_type);
str->append(')');
}
+ else if (jtbm_subselect)
+ {
+ if (jtbm_subselect->engine->engine_type() ==
+ subselect_engine::SINGLE_SELECT_ENGINE)
+ {
+ /*
+ We get here when conversion into materialization didn't finish (this
+ happens when
+ - The subquery is a degenerate case which produces 0 or 1 record
+ - subquery's optimization didn't finish because of @@max_join_size
+ limits
+ - ... maybe some other cases like this
+ */
+ str->append(STRING_WITH_LEN(" <materialize> ("));
+ jtbm_subselect->engine->print(str, query_type);
+ str->append(')');
+ }
+ else
+ {
+ str->append(STRING_WITH_LEN(" <materialize> ("));
+ subselect_hash_sj_engine *hash_engine;
+ hash_engine= (subselect_hash_sj_engine*)jtbm_subselect->engine;
+ hash_engine->materialize_engine->print(str, query_type);
+ str->append(')');
+ }
+ }
else
{
const char *cmp_name; // Name to compare with alias
@@ -17778,9 +22247,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 "));
@@ -17929,6 +22396,8 @@ bool JOIN::change_result(select_result *res)
{
DBUG_ENTER("JOIN::change_result");
result= res;
+ if (tmp_join)
+ tmp_join->result= res;
if (!procedure && (result->prepare(fields_list, select_lex->master_unit()) ||
result->prepare2()))
{
@@ -17937,6 +22406,225 @@ bool JOIN::change_result(select_result *res)
DBUG_RETURN(FALSE);
}
+
+/**
+ @brief
+ Set allowed types of join caches that can be used for join operations
+
+ @details
+ The function sets a bitmap of allowed join buffers types in the field
+ allowed_join_cache_types of this JOIN structure:
+ bit 1 is set if tjoin buffers are allowed to be incremental
+ bit 2 is set if the join buffers are allowed to be hashed
+ but 3 is set if the join buffers are allowed to be used for BKA
+ join algorithms.
+ The allowed types are read from system variables.
+ Besides the function sets maximum allowed join cache level that is
+ also read from a system variable.
+*/
+
+void JOIN::set_allowed_join_cache_types()
+{
+ allowed_join_cache_types= 0;
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL))
+ allowed_join_cache_types|= JOIN_CACHE_INCREMENTAL_BIT;
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_JOIN_CACHE_HASHED))
+ allowed_join_cache_types|= JOIN_CACHE_HASHED_BIT;
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_JOIN_CACHE_BKA))
+ allowed_join_cache_types|= JOIN_CACHE_BKA_BIT;
+ allowed_semijoin_with_cache=
+ optimizer_flag(thd, OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE);
+ allowed_outer_join_with_cache=
+ optimizer_flag(thd, OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE);
+ max_allowed_join_cache_level= thd->variables.join_cache_level;
+}
+
+
+/**
+ Save a query execution plan so that the caller can revert to it if needed,
+ and reset the current query plan so that it can be reoptimized.
+
+ @param save_to The object into which the current query plan state is saved
+*/
+
+void JOIN::save_query_plan(Join_plan_state *save_to)
+{
+ if (keyuse.elements)
+ {
+ DYNAMIC_ARRAY tmp_keyuse;
+ /* Swap the current and the backup keyuse internal arrays. */
+ tmp_keyuse= keyuse;
+ keyuse= save_to->keyuse; /* keyuse is reset to an empty array. */
+ save_to->keyuse= tmp_keyuse;
+
+ for (uint i= 0; i < table_count; i++)
+ {
+ save_to->join_tab_keyuse[i]= join_tab[i].keyuse;
+ join_tab[i].keyuse= NULL;
+ save_to->join_tab_checked_keys[i]= join_tab[i].checked_keys;
+ join_tab[i].checked_keys.clear_all();
+ }
+ }
+ memcpy((uchar*) save_to->best_positions, (uchar*) best_positions,
+ sizeof(POSITION) * (table_count + 1));
+ memset(best_positions, 0, sizeof(POSITION) * (table_count + 1));
+
+ /* Save SJM nests */
+ List_iterator<TABLE_LIST> it(select_lex->sj_nests);
+ TABLE_LIST *tlist;
+ SJ_MATERIALIZATION_INFO **p_info= save_to->sj_mat_info;
+ while ((tlist= it++))
+ {
+ *(p_info++)= tlist->sj_mat_info;
+ }
+}
+
+
+/**
+ Reset a query execution plan so that it can be reoptimized in-place.
+*/
+void JOIN::reset_query_plan()
+{
+ for (uint i= 0; i < table_count; i++)
+ {
+ join_tab[i].keyuse= NULL;
+ join_tab[i].checked_keys.clear_all();
+ }
+}
+
+
+/**
+ Restore a query execution plan previously saved by the caller.
+
+ @param The object from which the current query plan state is restored.
+*/
+
+void JOIN::restore_query_plan(Join_plan_state *restore_from)
+{
+ if (restore_from->keyuse.elements)
+ {
+ DYNAMIC_ARRAY tmp_keyuse;
+ tmp_keyuse= keyuse;
+ keyuse= restore_from->keyuse;
+ restore_from->keyuse= tmp_keyuse;
+
+ for (uint i= 0; i < table_count; i++)
+ {
+ join_tab[i].keyuse= restore_from->join_tab_keyuse[i];
+ join_tab[i].checked_keys= restore_from->join_tab_checked_keys[i];
+ }
+
+ }
+ memcpy((uchar*) best_positions, (uchar*) restore_from->best_positions,
+ sizeof(POSITION) * (table_count + 1));
+ /* Restore SJM nests */
+ List_iterator<TABLE_LIST> it(select_lex->sj_nests);
+ TABLE_LIST *tlist;
+ SJ_MATERIALIZATION_INFO **p_info= restore_from->sj_mat_info;
+ while ((tlist= it++))
+ {
+ tlist->sj_mat_info= *(p_info++);
+ }
+}
+
+
+/**
+ Reoptimize a query plan taking into account an additional conjunct to the
+ WHERE clause.
+
+ @param added_where An extra conjunct to the WHERE clause to reoptimize with
+ @param join_tables The set of tables to reoptimize
+ @param save_to If != NULL, save here the state of the current query plan,
+ otherwise reuse the existing query plan structures.
+
+ @notes
+ Given a query plan that was already optimized taking into account some WHERE
+ clause 'C', reoptimize this plan with a new WHERE clause 'C AND added_where'.
+ The reoptimization works as follows:
+
+ 1. Call update_ref_and_keys *only* for the new conditions 'added_where'
+ that are about to be injected into the query.
+ 2. Expand if necessary the original KEYUSE array JOIN::keyuse to
+ accommodate the new REF accesses computed for the 'added_where' condition.
+ 3. Add the new KEYUSEs into JOIN::keyuse.
+ 4. Re-sort and re-filter the JOIN::keyuse array with the newly added
+ KEYUSE elements.
+
+ @retval REOPT_NEW_PLAN there is a new plan.
+ @retval REOPT_OLD_PLAN no new improved plan was produced, use the old one.
+ @retval REOPT_ERROR an irrecovarable error occured during reoptimization.
+*/
+
+JOIN::enum_reopt_result
+JOIN::reoptimize(Item *added_where, table_map join_tables,
+ Join_plan_state *save_to)
+{
+ DYNAMIC_ARRAY added_keyuse;
+ SARGABLE_PARAM *sargables= 0; /* Used only as a dummy parameter. */
+ uint org_keyuse_elements;
+
+ /* Re-run the REF optimizer to take into account the new conditions. */
+ if (update_ref_and_keys(thd, &added_keyuse, join_tab, table_count, added_where,
+ ~outer_join, select_lex, &sargables))
+ {
+ delete_dynamic(&added_keyuse);
+ return REOPT_ERROR;
+ }
+
+ if (!added_keyuse.elements)
+ {
+ delete_dynamic(&added_keyuse);
+ return REOPT_OLD_PLAN;
+ }
+
+ if (save_to)
+ save_query_plan(save_to);
+ else
+ reset_query_plan();
+
+ if (!keyuse.buffer &&
+ my_init_dynamic_array(&keyuse, sizeof(KEYUSE), 20, 64))
+ {
+ delete_dynamic(&added_keyuse);
+ return REOPT_ERROR;
+ }
+
+ org_keyuse_elements= save_to ? save_to->keyuse.elements : keyuse.elements;
+ allocate_dynamic(&keyuse, org_keyuse_elements + added_keyuse.elements);
+
+ /* If needed, add the access methods from the original query plan. */
+ if (save_to)
+ {
+ DBUG_ASSERT(!keyuse.elements);
+ memcpy(keyuse.buffer,
+ save_to->keyuse.buffer,
+ (size_t) save_to->keyuse.elements * keyuse.size_of_element);
+ keyuse.elements= save_to->keyuse.elements;
+ }
+
+ /* Add the new access methods to the keyuse array. */
+ memcpy(keyuse.buffer + keyuse.elements * keyuse.size_of_element,
+ added_keyuse.buffer,
+ (size_t) added_keyuse.elements * added_keyuse.size_of_element);
+ keyuse.elements+= added_keyuse.elements;
+ /* added_keyuse contents is copied, and it is no longer needed. */
+ delete_dynamic(&added_keyuse);
+
+ if (sort_and_filter_keyuse(thd, &keyuse, true))
+ return REOPT_ERROR;
+ optimize_keyuse(this, &keyuse);
+
+ if (optimize_semijoin_nests(this, join_tables))
+ return REOPT_ERROR;
+
+ /* Re-run the join optimizer to compute a new query plan. */
+ if (choose_plan(this, join_tables))
+ return REOPT_ERROR;
+
+ return REOPT_NEW_PLAN;
+}
+
+
/**
@} (end of group Query_Optimizer)
*/
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 79c07e80b25..eb064b39f22 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -15,6 +15,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#ifndef SQL_SELECT_INCLUDED
+#define SQL_SELECT_INCLUDED
/**
@file
@@ -29,6 +31,21 @@
#include "procedure.h"
#include <myisam.h>
+#if defined(WITH_ARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES)
+#include <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
+#define KEY_OPTIMIZE_EQ 4
+
+inline uint get_hash_join_key_no() { return MAX_KEY; }
+
+inline bool is_hash_join_key_no(uint key) { return key == MAX_KEY; }
+
typedef struct keyuse_t {
TABLE *table;
Item *val; /**< or value if no field */
@@ -52,10 +69,21 @@ 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;
+
+ bool is_for_hash_join() { return is_hash_join_key_no(key); }
} KEYUSE;
+#define NO_KEYPART ((uint)(-1))
+
class store_key;
+const int NO_REF_PART= uint(-1);
+
typedef struct st_table_ref
{
bool key_err;
@@ -86,39 +114,33 @@ typedef struct st_table_ref
*/
key_part_map null_rejecting;
table_map depend_map; ///< Table depends on these tables.
+
/* null byte position in the key_buf. Used for REF_OR_NULL optimization */
uchar *null_ref_key;
+ /*
+ ref_or_null optimization: number of key part that alternates between
+ the lookup value or NULL (there's only one such part).
+ If we're not using ref_or_null, the value is NO_REF_PART
+ */
+ uint null_ref_part;
+
/*
The number of times the record associated with this key was used
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, uint skip= 0);
+ bool is_access_triggered();
+} TABLE_REF;
/*
@@ -126,7 +148,8 @@ typedef struct st_join_cache {
*/
enum join_type { JT_UNKNOWN,JT_SYSTEM,JT_CONST,JT_EQ_REF,JT_REF,JT_MAYBE_REF,
JT_ALL, JT_RANGE, JT_NEXT, JT_FT, JT_REF_OR_NULL,
- JT_UNIQUE_SUBQUERY, JT_INDEX_SUBQUERY, JT_INDEX_MERGE};
+ JT_UNIQUE_SUBQUERY, JT_INDEX_SUBQUERY, JT_INDEX_MERGE,
+ JT_HASH, JT_HASH_RANGE, JT_HASH_NEXT, JT_HASH_INDEX_MERGE};
class JOIN;
@@ -138,6 +161,17 @@ enum enum_nested_loop_state
};
+/* Possible sj_strategy values */
+enum sj_strategy_enum
+{
+ SJ_OPT_NONE=0,
+ SJ_OPT_DUPS_WEEDOUT=1,
+ SJ_OPT_LOOSE_SCAN =2,
+ SJ_OPT_FIRST_MATCH =3,
+ SJ_OPT_MATERIALIZE =4,
+ SJ_OPT_MATERIALIZE_SCAN=5
+};
+
/* Values for JOIN_TAB::packed_info */
#define TAB_INFO_HAVE_VALUE 1
#define TAB_INFO_USING_INDEX 2
@@ -146,20 +180,52 @@ enum enum_nested_loop_state
typedef enum_nested_loop_state
(*Next_select_func)(JOIN *, struct st_join_table *, bool);
+
+/*
+ Function prototype for reading first record for a join tab
+
+ RETURN
+ 0 - OK
+ -1 - Record not found
+ Other - A fatal error
+*/
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);
+int rr_sequential_and_unpack(READ_RECORD *info);
+
+class JOIN_CACHE;
+class SJ_TMP_TABLE;
+class JOIN_TAB_RANGE;
typedef struct st_join_table {
st_join_table() {} /* Remove gcc warning */
TABLE *table;
KEYUSE *keyuse; /**< pointer to first used key */
+ KEY *hj_key; /**< descriptor of the used best hash join key
+ not supported by any index */
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;
- Item **on_expr_ref; /**< pointer to the associated on expression */
+ /*
+ 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;
+ /*
+ Pointer to the associated ON expression. on_expr_ref=!NULL except for
+ degenerate joins.
+ *on_expr_ref!=NULL for tables that are first inner tables within an outer
+ join.
+ */
+ Item **on_expr_ref;
COND_EQUAL *cond_equal; /**< multiple equalities for the on expression */
st_join_table *first_inner; /**< first inner table for including outerjoin */
bool found; /**< true after all matches or null complement */
@@ -167,6 +233,21 @@ typedef struct st_join_table {
st_join_table *last_inner; /**< last table table for embedding outer join */
st_join_table *first_upper; /**< first inner table for embedding outer join */
st_join_table *first_unmatched; /**< used for optimization purposes only */
+
+ /*
+ For join tabs that are inside an SJM bush: root of the bush
+ */
+ st_join_table *bush_root_tab;
+
+ /* TRUE <=> This join_tab is inside an SJM bush and is the last leaf tab here */
+ bool last_leaf_in_bush;
+
+ /*
+ ptr - this is a bush, and ptr points to description of child join_tab
+ range
+ NULL - this join tab has no bush children
+ */
+ JOIN_TAB_RANGE *bush_children;
/* Special content for EXPLAIN 'Extra' column or NULL if none */
const char *info;
@@ -204,12 +285,34 @@ typedef struct st_join_table {
method (but not 'index' for some reason), i.e. this matches method which
E(#records) is in found_records.
*/
- ha_rows read_time;
+ double read_time;
+ /* psergey-todo: make the below have type double, like POSITION::records_read? */
+ ha_rows records_read;
+
+ /* Startup cost for execution */
+ double startup_cost;
+
+ double partial_join_cardinality;
+
table_map dependent,key_dependent;
- uint use_quick,index;
+ /*
+ 1 - use quick select
+ 2 - use "Range checked for each record"
+ */
+ uint use_quick;
+ /*
+ Index to use. Note: this is valid only for 'index' access, but not range or
+ ref access.
+ */
+ uint 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_uneven_bit_fields;
enum join_type type;
bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct;
bool sorted;
@@ -220,11 +323,94 @@ typedef struct st_join_table {
*/
ha_rows limit;
TABLE_REF ref;
- JOIN_CACHE cache;
+ /* TRUE <=> condition pushdown supports other tables presence */
+ bool icp_other_tables_ok;
+ /*
+ TRUE <=> condition pushed to the index has to be factored out of
+ the condition pushed to the table
+ */
+ bool idx_cond_fact_out;
+ bool use_join_cache;
+ uint used_join_cache_level;
+ 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;
+ /* for EXPLAIN only: */
+ SJ_TMP_TABLE *first_weedout_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;
+
+ /* TRUE <=> we are inside LooseScan range */
+ bool inside_loosescan_range;
+
+ /* Buffer to save index tuple to be able to skip duplicates */
+ uchar *loosescan_buf;
+
+ /*
+ Index used by LooseScan (we store it here separately because ref access
+ stores it in tab->ref.key, while range scan stores it in tab->index, etc)
+ */
+ uint loosescan_key;
+
+ /* 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_semijoin_strategies_for_picked_join_order.
+ */
+ enum sj_strategy_enum sj_strategy;
+
+ uint n_sj_tables;
+
+ bool preread_init_done;
+
void cleanup();
inline bool is_using_loose_index_scan()
{
@@ -232,19 +418,345 @@ typedef struct st_join_table {
(select->quick->get_type() ==
QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX));
}
+ bool is_inner_table_of_semi_join_with_first_match()
+ {
+ return first_sj_inner_tab != NULL;
+ }
+ bool is_inner_table_of_semijoin()
+ {
+ return emb_sj_nest != NULL;
+ }
+ bool is_inner_table_of_outer_join()
+ {
+ return first_inner != NULL;
+ }
+ 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();
+ bool is_ref_for_hash_join() { return is_hash_join_key_no(ref.key); }
+ KEY *get_keyinfo_by_key_no(uint key)
+ {
+ return (is_hash_join_key_no(key) ? hj_key : table->key_info+key);
+ }
+ double scan_time();
+ bool preread_init();
+
+ bool is_sjm_nest() { return test(bush_children); }
+
+ bool access_from_tables_is_allowed(table_map used_tables,
+ table_map sjm_lookup_tables)
+ {
+ table_map used_sjm_lookup_tables= used_tables & sjm_lookup_tables;
+ return !used_sjm_lookup_tables ||
+ (emb_sj_nest &&
+ !(used_sjm_lookup_tables & ~emb_sj_nest->sj_inner_tables));
+ }
+
} JOIN_TAB;
+
+#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
+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);
+
+
+struct st_position;
+
+class Semi_join_strategy_picker
+{
+public:
+ /* Called when starting to build a new join prefix */
+ virtual void set_empty() = 0;
+
+ /*
+ Update internal state after another table has been added to the join
+ prefix
+ */
+ virtual void set_from_prev(struct st_position *prev) = 0;
+
+ virtual bool check_qep(JOIN *join,
+ uint idx,
+ table_map remaining_tables,
+ const JOIN_TAB *new_join_tab,
+ double *record_count,
+ double *read_time,
+ table_map *handled_fanout,
+ sj_strategy_enum *strategy,
+ struct st_position *loose_scan_pos) = 0;
+
+ virtual void mark_used() = 0;
+
+ virtual ~Semi_join_strategy_picker() {}
+};
+
+
+/*
+ Duplicate Weedout strategy optimization state
+*/
+
+class Duplicate_weedout_picker : public Semi_join_strategy_picker
+{
+ /* 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;
+
+ bool is_used;
+public:
+ void set_empty()
+ {
+ dupsweedout_tables= 0;
+ first_dupsweedout_table= MAX_TABLES;
+ is_used= FALSE;
+ }
+ void set_from_prev(struct st_position *prev);
+
+ bool check_qep(JOIN *join,
+ uint idx,
+ table_map remaining_tables,
+ const JOIN_TAB *new_join_tab,
+ double *record_count,
+ double *read_time,
+ table_map *handled_fanout,
+ sj_strategy_enum *stratey,
+ struct st_position *loose_scan_pos);
+
+ void mark_used() { is_used= TRUE; }
+ friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
+};
+
+
+class Firstmatch_picker : public Semi_join_strategy_picker
+{
+ /*
+ 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;
+
+ bool is_used;
+
+ bool in_firstmatch_prefix() { return (first_firstmatch_table != MAX_TABLES); }
+ void invalidate_firstmatch_prefix() { first_firstmatch_table= MAX_TABLES; }
+public:
+ void set_empty()
+ {
+ invalidate_firstmatch_prefix();
+ is_used= FALSE;
+ }
+
+ void set_from_prev(struct st_position *prev);
+ bool check_qep(JOIN *join,
+ uint idx,
+ table_map remaining_tables,
+ const JOIN_TAB *new_join_tab,
+ double *record_count,
+ double *read_time,
+ table_map *handled_fanout,
+ sj_strategy_enum *strategy,
+ struct st_position *loose_scan_pos);
+
+ void mark_used() { is_used= TRUE; }
+ friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
+};
+
+
+class LooseScan_picker : public Semi_join_strategy_picker
+{
+ /* 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 */
+
+ bool is_used;
+public:
+ void set_empty()
+ {
+ first_loosescan_table= MAX_TABLES;
+ is_used= FALSE;
+ }
+
+ void set_from_prev(struct st_position *prev);
+ bool check_qep(JOIN *join,
+ uint idx,
+ table_map remaining_tables,
+ const JOIN_TAB *new_join_tab,
+ double *record_count,
+ double *read_time,
+ table_map *handled_fanout,
+ sj_strategy_enum *strategy,
+ struct st_position *loose_scan_pos);
+ void mark_used() { is_used= TRUE; }
+
+ friend class Loose_scan_opt;
+ friend void best_access_path(JOIN *join,
+ JOIN_TAB *s,
+ table_map remaining_tables,
+ uint idx,
+ bool disable_jbuf,
+ double record_count,
+ struct st_position *pos,
+ struct st_position *loose_scan_pos);
+ friend bool get_best_combination(JOIN *join);
+ friend int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
+ uint no_jbuf_after);
+ friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
+};
+
+
+class Sj_materialization_picker : public Semi_join_strategy_picker
+{
+ bool is_used;
+
+ /* 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;
+
+public:
+ void set_empty()
+ {
+ sjm_scan_need_tables= 0;
+ LINT_INIT(sjm_scan_last_inner);
+ is_used= FALSE;
+ }
+ void set_from_prev(struct st_position *prev);
+ bool check_qep(JOIN *join,
+ uint idx,
+ table_map remaining_tables,
+ const JOIN_TAB *new_join_tab,
+ double *record_count,
+ double *read_time,
+ table_map *handled_fanout,
+ sj_strategy_enum *strategy,
+ struct st_position *loose_scan_pos);
+ void mark_used() { is_used= TRUE; }
+
+ friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
+};
+
/**
Information about a position of table within a join order. Used in join
optimization.
*/
-typedef struct st_position
+typedef struct st_position :public Sql_alloc
{
+ /* The table that's put into join order */
+ JOIN_TAB *table;
+
/*
The "fanout": number of output rows that will be produced (after
pushed down selection condition is applied) per each row combination of
@@ -258,7 +770,10 @@ typedef struct st_position
number the access method will be invoked.
*/
double read_time;
- JOIN_TAB *table;
+
+ /* Cumulative cost and record count for the join prefix */
+ COST_VECT prefix_cost;
+ double prefix_record_count;
/*
NULL - 'index' or 'range' or 'index_merge' or 'ALL' access is used.
@@ -268,8 +783,43 @@ typedef struct st_position
/* If ref-based access is used: bitmap of tables this table depends on */
table_map ref_depend_map;
-} POSITION;
+
+ /*
+ TRUE <=> join buffering will be used. At the moment this is based on
+ *very* imprecise guesses made in best_access_path().
+ */
+ bool use_join_buffer;
+
+ /*
+ 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.
+ */
+ enum sj_strategy_enum 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;
+ table_map prefix_dups_producing_tables;
+
+ table_map inner_tables_handled_with_other_sjs;
+
+ Duplicate_weedout_picker dups_weedout_picker;
+ Firstmatch_picker firstmatch_picker;
+ LooseScan_picker loosescan_picker;
+ Sj_materialization_picker sjmat_picker;
+} POSITION;
typedef struct st_rollup
{
@@ -281,17 +831,116 @@ typedef struct st_rollup
} ROLLUP;
+class JOIN_TAB_RANGE: public Sql_alloc
+{
+public:
+ JOIN_TAB *start;
+ JOIN_TAB *end;
+};
+
+
class JOIN :public Sql_alloc
{
+private:
JOIN(const JOIN &rhs); /**< not implemented */
JOIN& operator=(const JOIN &rhs); /**< not implemented */
+
+protected:
+
+ /**
+ The subset of the state of a JOIN that represents an optimized query
+ execution plan. Allows saving/restoring different JOIN plans for the same
+ query.
+ */
+ class Join_plan_state {
+ public:
+ DYNAMIC_ARRAY keyuse; /* Copy of the JOIN::keyuse array. */
+ POSITION *best_positions; /* Copy of JOIN::best_positions */
+ /* Copies of the JOIN_TAB::keyuse pointers for each JOIN_TAB. */
+ KEYUSE **join_tab_keyuse;
+ /* Copies of JOIN_TAB::checked_keys for each JOIN_TAB. */
+ key_map *join_tab_checked_keys;
+ SJ_MATERIALIZATION_INFO **sj_mat_info;
+ my_bool error;
+ public:
+ Join_plan_state(uint tables) : error(0)
+ {
+ keyuse.elements= 0;
+ keyuse.buffer= NULL;
+ best_positions= 0; /* To detect errors */
+ error= my_multi_malloc(MYF(MY_WME),
+ &best_positions,
+ sizeof(*best_positions) * (tables + 1),
+ &join_tab_keyuse,
+ sizeof(*join_tab_keyuse) * tables,
+ &join_tab_checked_keys,
+ sizeof(*join_tab_checked_keys) * tables,
+ &sj_mat_info,
+ sizeof(sj_mat_info) * tables,
+ NullS) == 0;
+ }
+ Join_plan_state(JOIN *join);
+ ~Join_plan_state()
+ {
+ delete_dynamic(&keyuse);
+ my_free(best_positions, MYF(0));
+ }
+ };
+
+ /* Results of reoptimizing a JOIN via JOIN::reoptimize(). */
+ enum enum_reopt_result {
+ REOPT_NEW_PLAN, /* there is a new reoptimized plan */
+ REOPT_OLD_PLAN, /* no new improved plan can be found, use the old one */
+ REOPT_ERROR, /* an irrecovarable error occured during reoptimization */
+ REOPT_NONE /* not yet reoptimized */
+ };
+
+ /* Support for plan reoptimization with rewritten conditions. */
+ enum_reopt_result reoptimize(Item *added_where, table_map join_tables,
+ Join_plan_state *save_to);
+ void save_query_plan(Join_plan_state *save_to);
+ void reset_query_plan();
+ void restore_query_plan(Join_plan_state *restore_from);
+ /* Choose a subquery plan for a table-less subquery. */
+ bool choose_tableless_subquery_plan();
+
public:
- JOIN_TAB *join_tab,**best_ref;
+ 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;
+
+ List<JOIN_TAB_RANGE> join_tab_ranges;
+
+ /*
+ Base tables participating in the join. After join optimization is done, the
+ tables are stored in the join order (but the only really important part is
+ that const tables are first).
+ */
+ TABLE **table;
+ /**
+ 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;
+ /*
+ Number of tables in the join.
+ (In MySQL, it is named 'tables' and is also the number of elements in
+ join->join_tab array. In MariaDB, the latter is not true, so we've renamed
+ the variable)
+ */
+ uint table_count;
+ uint outer_tables; /**< Number of tables that are not inside semijoin */
+ uint const_tables;
+ /*
+ Number of tables in the top join_tab array. Normally this matches
+ (join_tab_ranges.head()->end - join_tab_ranges.head()->start).
+
+ We keep it here so that it is saved/restored with JOIN::restore_tmp.
+ */
+ uint top_join_tab_count;
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.
@@ -299,7 +948,8 @@ 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 hash_join;
bool do_send_rows;
/**
TRUE when we want to resume nested loop iterations when
@@ -307,6 +957,11 @@ public:
*/
bool resume_nested_loop;
table_map const_table_map;
+ /**
+ Bitmap of semijoin tables that the current partial plan decided
+ to materialize and access by lookups
+ */
+ table_map sjm_lookup_tables;
/*
Constant tables for which we have found a row (as opposed to those for
which we didn't).
@@ -316,9 +971,12 @@ public:
/* Tables removed by table elimination. Set to 0 before the elimination. */
table_map eliminated_tables;
/*
- Bitmap of all inner tables from outer joins
+ Bitmap of all inner tables from outer joins (set at start of
+ make_join_statistics)
*/
table_map outer_join;
+ /* Bitmap of tables used in the select list items */
+ table_map select_list_used_tables;
ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
/**
Used to fetch no more than given amount of rows per one
@@ -330,15 +988,61 @@ 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;
+
+/******* 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;
- /* *
+ /*
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 *******/
+ /*
+ Tables within complex firstmatch ranges (i.e. those where inner tables are
+ interleaved with outer tables). Join buffering cannot be used for these.
+ */
+ table_map complex_firstmatch_tables;
+
+ /*
+ 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;
+ /*
+ Estimated result rows (fanout) of the join operation. If this is a subquery
+ that is reexecuted multiple times, this value includes the estiamted # of
+ reexecutions. This value is equal to the multiplication of all
+ join->positions[i].records_read of a JOIN.
+ */
+ double record_count;
List<Item> *fields;
List<Cached_item> group_fields, group_fields_cache;
TABLE *tmp_table;
@@ -353,6 +1057,15 @@ public:
Item *tmp_having; ///< To store having when processed temporary table
Item *having_history; ///< Store having for explain
ulonglong select_options;
+ /*
+ Bitmap of allowed types of the join caches that
+ can be used for join operations
+ */
+ uint allowed_join_cache_types;
+ bool allowed_semijoin_with_cache;
+ bool allowed_outer_join_with_cache;
+ /* Maximum level of the join caches that can be used for join operations */
+ uint max_allowed_join_cache_level;
select_result *result;
TMP_TABLE_PARAM tmp_table_param;
MYSQL_LOCK *lock;
@@ -438,9 +1151,25 @@ public:
ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select
COND *conds; // ---"---
Item *conds_history; // store WHERE for explain
+ COND *outer_ref_cond; ///<part of conds containing only outer references
+ COND *pseudo_bits_cond; // part of conds containing special bita
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;
+ /*
+ Constant codition computed during optimization, but evaluated during
+ join execution. Typically expensive conditions that should not be
+ evaluated at optimization time.
+ */
+ Item *exec_const_cond;
+ /*
+ Constant ORDER and/or GROUP expressions that contain subqueries. Such
+ expressions need to evaluated to verify that the subquery indeed
+ returns a single row. The evaluation of such expressions is delayed
+ until query execution.
+ */
+ List<Item> exec_const_order_group_cond;
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 +1180,19 @@ public:
bool union_part; ///< this subselect is part of union
bool optimized; ///< flag to avoid double optimization in EXPLAIN
+ bool initialized; ///< flag to avoid double init_execution calls
+
+ /*
+ Additional WHERE and HAVING predicates to be considered for IN=>EXISTS
+ subquery transformation of a JOIN object.
+ */
+ Item *in_to_exists_where;
+ Item *in_to_exists_having;
+
+ /* 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.
@@ -479,7 +1221,8 @@ public:
{
join_tab= join_tab_save= 0;
table= 0;
- tables= 0;
+ table_count= 0;
+ top_join_tab_count= 0;
const_tables= 0;
eliminated_tables= 0;
join_list= 0;
@@ -520,9 +1263,13 @@ public:
ref_pointer_array_size= 0;
zero_result_cause= 0;
optimized= 0;
+ initialized= 0;
cond_equal= 0;
+ having_equal= 0;
+ exec_const_cond= 0;
group_optimized_away= 0;
no_rows_in_result_called= 0;
+ positions= best_positions= 0;
all_fields= fields_arg;
if (&fields_list != &fields_arg) /* Avoid valgrind-warning */
@@ -533,18 +1280,27 @@ public:
rollup.state= ROLLUP::STATE_NONE;
no_const_tables= FALSE;
+ outer_ref_cond= pseudo_bits_cond= NULL;
+ in_to_exists_where= NULL;
+ in_to_exists_having= NULL;
+ emb_sjm_nest= NULL;
+ sjm_lookup_tables= 0;
}
int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
COND *conds, uint og_num, ORDER *order, ORDER *group,
Item *having, ORDER *proc_param, SELECT_LEX *select,
SELECT_LEX_UNIT *unit);
+ bool prepare_stage2();
int optimize();
int reinit();
+ int init_execution();
void exec();
int destroy();
void restore_tmp();
bool alloc_func_list();
+ bool flatten_subqueries();
+ bool optimize_unflattened_subqueries();
bool make_sum_func_list(List<Item> &all_fields, List<Item> &send_fields,
bool before_group_by, bool recompute= FALSE);
@@ -566,7 +1322,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
@@ -581,9 +1336,10 @@ public:
bool init_save_join_tab();
bool send_row_on_empty_set()
{
- return (do_send_rows && tmp_table_param.sum_func_count != 0 &&
- !group_list && having_value != Item::COND_FALSE);
+ return (do_send_rows && implicit_grouping && !group_optimized_away &&
+ having_value != Item::COND_FALSE);
}
+ bool empty_result() { return (zero_result_cause && !implicit_grouping); }
bool change_result(select_result *result);
bool is_top_level_join() const
{
@@ -592,7 +1348,63 @@ public:
}
inline table_map all_tables_map()
{
- return (table_map(1) << tables) - 1;
+ return (table_map(1) << table_count) - 1;
+ }
+ void drop_unused_derived_keys();
+ inline void eval_select_list_used_tables();
+ /*
+ Return the table for which an index scan can be used to satisfy
+ the sort order needed by the ORDER BY/(implicit) GROUP BY clause
+ */
+ 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);
+ void set_allowed_join_cache_types();
+ bool is_allowed_hash_join_access()
+ {
+ return test(allowed_join_cache_types & JOIN_CACHE_HASHED_BIT) &&
+ max_allowed_join_cache_level > JOIN_CACHE_HASHED_BIT;
+ }
+ /*
+ Check if we need to create a temporary table.
+ This has to be done if all tables are not already read (const tables)
+ and one of the following conditions holds:
+ - We are using DISTINCT (simple distinct's are already optimized away)
+ - We are using an ORDER BY or GROUP BY on fields not in the first table
+ - We are using different ORDER BY and GROUP BY orders
+ - The user wants us to buffer the result.
+ When the WITH ROLLUP modifier is present, we cannot skip temporary table
+ creation for the DISTINCT clause just because there are only const tables.
+ */
+ bool test_if_need_tmp_table()
+ {
+ return ((const_tables != table_count &&
+ ((select_distinct || !simple_order || !simple_group) ||
+ (group_list && order) ||
+ test(select_options & OPTION_BUFFER_RESULT))) ||
+ (rollup.state != ROLLUP::STATE_NONE && select_distinct));
+ }
+ bool choose_subquery_plan(table_map join_tables);
+ void get_partial_cost_and_fanout(int end_tab_idx,
+ table_map filter_map,
+ double *read_time_arg,
+ double *record_count_arg);
+ void get_prefix_cost_and_fanout(uint n_tables,
+ double *read_time_arg,
+ double *record_count_arg);
+ /* defined in opt_subselect.cc */
+ bool transform_max_min_subquery();
+ /* True if this JOIN is a subquery under an IN predicate. */
+ bool is_in_subquery()
+ {
+ return (unit->item && unit->item->is_in_predicate());
}
private:
/**
@@ -604,6 +1416,15 @@ private:
void cleanup_item_list(List<Item> &items) const;
};
+enum enum_with_bush_roots { WITH_BUSH_ROOTS, WITHOUT_BUSH_ROOTS};
+enum enum_with_const_tables { WITH_CONST_TABLES, WITHOUT_CONST_TABLES};
+
+JOIN_TAB *first_linear_tab(JOIN *join, enum enum_with_const_tables const_tbls);
+JOIN_TAB *next_linear_tab(JOIN* join, JOIN_TAB* tab,
+ enum enum_with_bush_roots include_bush_roots);
+
+JOIN_TAB *first_top_level_tab(JOIN *join, enum enum_with_const_tables with_const);
+JOIN_TAB *next_top_level_tab(JOIN *join, JOIN_TAB *tab);
typedef struct st_select_check {
uint const_ref,reg_ref;
@@ -614,11 +1435,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,
@@ -637,7 +1453,7 @@ Field* create_tmp_field_from_field(THD *thd, Field* org_field,
/* functions from opt_sum.cc */
bool simple_pred(Item_func *func_item, Item **args, bool *inv_order);
int opt_sum_query(THD* thd,
- TABLE_LIST *tables, List<Item> &all_fields, COND *conds);
+ List<TABLE_LIST> &tables, List<Item> &all_fields, COND *conds);
/* from sql_delete.cc, used by opt_range.cc */
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b);
@@ -649,6 +1465,7 @@ class store_key :public Sql_alloc
public:
bool null_key; /* TRUE <=> the value of the key has a null part */
enum store_key_result { STORE_KEY_OK, STORE_KEY_FATAL, STORE_KEY_CONV };
+ enum Type { FIELD_STORE_KEY, ITEM_STORE_KEY, CONST_ITEM_STORE_KEY };
store_key(THD *thd, Field *field_arg, uchar *ptr, uchar *null, uint length)
:null_key(0), null_ptr(null), err(0)
{
@@ -668,7 +1485,13 @@ public:
to_field=field_arg->new_key_field(thd->mem_root, field_arg->table,
ptr, null, 1);
}
+ store_key(store_key &arg)
+ :Sql_alloc(), null_key(arg.null_key), to_field(arg.to_field),
+ null_ptr(arg.null_ptr), err(arg.err)
+
+ {}
virtual ~store_key() {} /** Not actually needed */
+ virtual enum Type type() const=0;
virtual const char *name() const=0;
virtual bool store_key_is_const() { return false; }
@@ -721,15 +1544,32 @@ class store_key_field: public store_key
{
copy_field.set(to_field,from_field,0);
}
- }
+ }
+
+ enum Type type() const { return FIELD_STORE_KEY; }
const char *name() const { return field_name; }
+ void change_source_field(Item_field *fld_item)
+ {
+ copy_field.set(to_field, fld_item->field, 0);
+ field_name= fld_item->full_name();
+ }
+
protected:
enum store_key_result copy_inner()
{
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();
@@ -742,13 +1582,24 @@ 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)
{}
+ store_key_item(store_key &arg, Item *new_item, bool val)
+ :store_key(arg), item(new_item), use_value(val)
+ {}
+
+
+ enum Type type() const { return ITEM_STORE_KEY; }
const char *name() const { return "func"; }
protected:
@@ -757,7 +1608,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
@@ -779,11 +1643,16 @@ public:
store_key_const_item(THD *thd, Field *to_field_arg, uchar *ptr,
uchar *null_ptr_arg, uint length,
Item *item_arg)
- :store_key_item(thd, to_field_arg,ptr,
+ :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)
{
}
+ store_key_const_item(store_key &arg, Item *new_item)
+ :store_key_item(arg, new_item, FALSE), inited(0)
+ {}
+
+ enum Type type() const { return CONST_ITEM_STORE_KEY; }
const char *name() const { return "const"; }
bool store_key_is_const() { return true; }
@@ -794,6 +1663,9 @@ protected:
if (!inited)
{
inited=1;
+ TABLE *table= to_field->table;
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table,
+ table->write_set);
if ((res= item->save_in_field(to_field, 1)))
{
if (!err)
@@ -805,6 +1677,7 @@ protected:
*/
if (!err && to_field->table->in_use->is_error())
err= 1; /* STORE_KEY_FATAL */
+ dbug_tmp_restore_column_map(table->write_set, old_map);
}
null_key= to_field->is_null() || item->null_value;
return (err > 2 ? STORE_KEY_FATAL : (store_key_result) err);
@@ -816,12 +1689,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);
+int join_read_record_no_init(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 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);
+
+/****************************************************************************
+ 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, bool do_not_open=FALSE);
+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);
+double prev_record_reads(POSITION *positions, uint idx, table_map found_ref);
+void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist);
+
+#endif /* SQL_SELECT_INCLUDED */
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 9f021ca31c7..6ff4654e7d4 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -379,6 +379,283 @@ bool mysqld_show_privileges(THD *thd)
}
+/** Hash of LEX_STRINGs used to search for ignored db directories. */
+static HASH ignore_db_dirs_hash;
+
+/**
+ An array of LEX_STRING pointers to collect the options at
+ option parsing time.
+*/
+static DYNAMIC_ARRAY ignore_db_dirs_array;
+
+/**
+ A value for the read only system variable to show a list of
+ ignored directories.
+*/
+char *opt_ignore_db_dirs= NULL;
+
+/**
+ This flag is ON if:
+ - the list of ignored directories is not empty
+
+ - and some of the ignored directory names
+ need no tablename-to-filename conversion.
+ Otherwise, if the name of the directory contains
+ unconditional characters like '+' or '.', they
+ never can match the database directory name. So the
+ db_name_is_in_ignore_db_dirs_list() can just return at once.
+*/
+static bool skip_ignored_dir_check= TRUE;
+
+/**
+ Sets up the data structures for collection of directories at option
+ processing time.
+ We need to collect the directories in an array first, because
+ we need the character sets initialized before setting up the hash.
+
+ @return state
+ @retval TRUE failed
+ @retval FALSE success
+*/
+
+bool
+ignore_db_dirs_init()
+{
+ return my_init_dynamic_array(&ignore_db_dirs_array, sizeof(LEX_STRING *),
+ 0, 0);
+}
+
+
+/**
+ Retrieves the key (the string itself) from the LEX_STRING hash members.
+
+ Needed by hash_init().
+
+ @param data the data element from the hash
+ @param out len_ret Placeholder to return the length of the key
+ @param unused
+ @return a pointer to the key
+*/
+
+static uchar *
+db_dirs_hash_get_key(const uchar *data, size_t *len_ret,
+ my_bool __attribute__((unused)))
+{
+ LEX_STRING *e= (LEX_STRING *) data;
+
+ *len_ret= e->length;
+ return (uchar *) e->str;
+}
+
+
+/**
+ Wrap a directory name into a LEX_STRING and push it to the array.
+
+ Called at option processing time for each --ignore-db-dir option.
+
+ @param path the name of the directory to push
+ @return state
+ @retval TRUE failed
+ @retval FALSE success
+*/
+
+bool
+push_ignored_db_dir(char *path)
+{
+ LEX_STRING *new_elt;
+ char *new_elt_buffer;
+ size_t path_len= strlen(path);
+
+ if (!path_len || path_len >= FN_REFLEN)
+ return true;
+
+ // No need to normalize, it's only a directory name, not a path.
+ if (!my_multi_malloc(0,
+ &new_elt, sizeof(LEX_STRING),
+ &new_elt_buffer, path_len + 1,
+ NullS))
+ return true;
+ new_elt->str= new_elt_buffer;
+ memcpy(new_elt_buffer, path, path_len);
+ new_elt_buffer[path_len]= 0;
+ new_elt->length= path_len;
+ return insert_dynamic(&ignore_db_dirs_array, (uchar*) &new_elt);
+}
+
+
+/**
+ Clean up the directory ignore options accumulated so far.
+
+ Called at option processing time for each --ignore-db-dir option
+ with an empty argument.
+*/
+
+void
+ignore_db_dirs_reset()
+{
+ LEX_STRING **elt;
+ while (NULL!= (elt= (LEX_STRING **) pop_dynamic(&ignore_db_dirs_array)))
+ if (elt && *elt)
+ my_free(*elt, MYF(0));
+}
+
+
+/**
+ Free the directory ignore option variables.
+
+ Called at server shutdown.
+*/
+
+void
+ignore_db_dirs_free()
+{
+ if (opt_ignore_db_dirs)
+ {
+ my_free(opt_ignore_db_dirs, MYF(0));
+ opt_ignore_db_dirs= NULL;
+ }
+ ignore_db_dirs_reset();
+ delete_dynamic(&ignore_db_dirs_array);
+ my_hash_free(&ignore_db_dirs_hash);
+}
+
+
+/**
+ Initialize the ignore db directories hash and status variable from
+ the options collected in the array.
+
+ Called when option processing is over and the server's in-memory
+ structures are fully initialized.
+
+ @return state
+ @retval TRUE failed
+ @retval FALSE success
+*/
+
+static void dispose_db_dir(void *ptr)
+{
+ my_free(ptr, MYF(0));
+}
+
+
+bool
+ignore_db_dirs_process_additions()
+{
+ ulong i;
+ size_t len;
+ char *ptr;
+ LEX_STRING *dir;
+
+
+ DBUG_ASSERT(opt_ignore_db_dirs == NULL);
+
+ skip_ignored_dir_check= TRUE;
+
+ if (my_hash_init(&ignore_db_dirs_hash,
+ lower_case_table_names ?
+ character_set_filesystem : &my_charset_bin,
+ 0, 0, 0, db_dirs_hash_get_key,
+ dispose_db_dir,
+ HASH_UNIQUE))
+ return true;
+
+ /* len starts from 1 because of the terminating zero. */
+ len= 1;
+ for (i= 0; i < ignore_db_dirs_array.elements; i++)
+ {
+ get_dynamic(&ignore_db_dirs_array, (uchar *) &dir, i);
+ len+= dir->length + 1; // +1 for the comma
+ if (skip_ignored_dir_check)
+ {
+ char buff[FN_REFLEN];
+ (void) tablename_to_filename(dir->str, buff, sizeof(buff));
+ skip_ignored_dir_check= strcmp(dir->str, buff) != 0;
+ }
+ }
+
+ /* No delimiter for the last directory. */
+ if (len > 1)
+ len--;
+
+ /* +1 the terminating zero */
+ ptr= opt_ignore_db_dirs= (char *) my_malloc(len + 1, MYF(0));
+ if (!ptr)
+ return true;
+
+ /* Make sure we have an empty string to start with. */
+ *ptr= 0;
+
+ for (i= 0; i < ignore_db_dirs_array.elements; i++)
+ {
+ get_dynamic(&ignore_db_dirs_array, (uchar *) &dir, i);
+ if (my_hash_insert(&ignore_db_dirs_hash, (uchar *) dir))
+ return true;
+ ptr= strnmov(ptr, dir->str, dir->length);
+ if (i + 1 < ignore_db_dirs_array.elements)
+ ptr= strmov(ptr, ",");
+
+ /*
+ Set the transferred array element to NULL to avoid double free
+ in case of error.
+ */
+ dir= NULL;
+ set_dynamic(&ignore_db_dirs_array, (uchar *) &dir, i);
+ }
+
+ /* make sure the string is terminated */
+ DBUG_ASSERT(ptr - opt_ignore_db_dirs <= (ptrdiff_t) len);
+ *ptr= 0;
+
+ /*
+ It's OK to empty the array here as the allocated elements are
+ referenced through the hash now.
+ */
+ reset_dynamic(&ignore_db_dirs_array);
+
+ return false;
+}
+
+
+/**
+ Check if a directory name is in the hash of ignored directories.
+
+ @return search result
+ @retval TRUE found
+ @retval FALSE not found
+*/
+
+static inline bool
+is_in_ignore_db_dirs_list(const char *directory)
+{
+ return ignore_db_dirs_hash.records &&
+ NULL != my_hash_search(&ignore_db_dirs_hash, (const uchar *) directory,
+ strlen(directory));
+}
+
+
+/**
+ Check if a database name is in the hash of ignored directories.
+
+ @return search result
+ @retval TRUE found
+ @retval FALSE not found
+*/
+
+bool
+db_name_is_in_ignore_db_dirs_list(const char *directory)
+{
+ char buff[FN_REFLEN];
+ uint buff_len;
+
+ if (skip_ignored_dir_check)
+ return 0;
+
+ buff_len= tablename_to_filename(directory, buff, sizeof(buff));
+
+ return my_hash_search(&ignore_db_dirs_hash, (uchar *) buff, buff_len)!=NULL;
+}
+
+
/***************************************************************************
List all column types
***************************************************************************/
@@ -552,6 +829,9 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
if (!MY_S_ISDIR(file->mystat->st_mode))
continue;
+ if (is_in_ignore_db_dirs_list(file->name))
+ continue;
+
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
if (wild)
{
@@ -772,7 +1052,8 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
{
Show_create_error_handler view_error_suppressor(thd, table_list);
thd->push_internal_handler(&view_error_suppressor);
- bool error= open_normal_and_derived_tables(thd, table_list, 0);
+ bool error= open_normal_and_derived_tables(thd, table_list, 0,
+ DT_PREPARE | DT_CREATE);
thd->pop_internal_handler();
if (error && (thd->killed || thd->main_da.is_error()))
goto error;
@@ -949,7 +1230,8 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
DBUG_ENTER("mysqld_list_fields");
DBUG_PRINT("enter",("table: %s",table_list->table_name));
- if (open_normal_and_derived_tables(thd, table_list, 0))
+ if (open_normal_and_derived_tables(thd, table_list, 0,
+ DT_PREPARE | DT_CREATE))
DBUG_VOID_RETURN;
table= table_list->table;
@@ -1771,7 +2053,7 @@ view_store_options(THD *thd, TABLE_LIST *table, String *buff)
static void append_algorithm(TABLE_LIST *table, String *buff)
{
buff->append(STRING_WITH_LEN("ALGORITHM="));
- switch ((int8)table->algorithm) {
+ switch ((int16)table->algorithm) {
case VIEW_ALGORITHM_UNDEFINED:
buff->append(STRING_WITH_LEN("UNDEFINED "));
break;
@@ -1895,6 +2177,7 @@ public:
uint command;
const char *user,*host,*db,*proc_info,*state_info;
char *query;
+ double progress;
};
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
@@ -1923,6 +2206,11 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
field->maybe_null=1;
field_list.push_back(field=new Item_empty_string("Info",max_query_length));
field->maybe_null=1;
+ if (!thd->variables.old_mode)
+ {
+ field_list.push_back(field= new Item_float("Progress", 0.0, 3, 7));
+ field->maybe_null= 0;
+ }
if (protocol->send_fields(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_VOID_RETURN;
@@ -1962,12 +2250,10 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
pthread_mutex_lock(&tmp->LOCK_thd_data);
if ((mysys_var= tmp->mysys_var))
pthread_mutex_lock(&mysys_var->mutex);
- thd_info->proc_info= (char*) (tmp->killed != THD::NOT_KILLED &&
- tmp->killed != THD::KILL_BAD_DATA ?
+ thd_info->proc_info= (char*) (tmp->killed >= KILL_QUERY ?
"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 ? "" :
@@ -1985,6 +2271,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
thd_info->start_time= tmp->start_time;
thd_info->query=0;
+ thd_info->progress= 0.0;
+
/* Lock THD mutex that protects its data when looking at it. */
pthread_mutex_lock(&tmp->LOCK_thd_data);
if (tmp->query())
@@ -1992,6 +2280,20 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
uint length= min(max_query_length, tmp->query_length());
thd_info->query= (char*) thd->strmake(tmp->query(),length);
}
+
+ /*
+ Progress report. We need to do this under a lock to ensure that all
+ is from the same stage.
+ */
+ if (tmp->progress.max_counter)
+ {
+ uint max_stage= max(tmp->progress.max_stage, 1);
+ thd_info->progress= (((tmp->progress.stage / (double) max_stage) +
+ ((tmp->progress.counter /
+ (double) tmp->progress.max_counter) /
+ (double) max_stage)) *
+ 100.0);
+ }
pthread_mutex_unlock(&tmp->LOCK_thd_data);
thread_infos.append(thd_info);
}
@@ -2001,6 +2303,9 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
thread_info *thd_info;
time_t now= my_time(0);
+ char buff[20]; // For progress
+ String store_buffer(buff, sizeof(buff), system_charset_info);
+
while ((thd_info=thread_infos.get()))
{
protocol->prepare_for_resend();
@@ -2018,6 +2323,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
protocol->store_null();
protocol->store(thd_info->state_info, system_charset_info);
protocol->store(thd_info->query, system_charset_info);
+ if (!thd->variables.old_mode)
+ protocol->store(thd_info->progress, 3, &store_buffer);
if (protocol->write())
break; /* purecov: inspected */
}
@@ -2030,7 +2337,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
TABLE *table= tables->table;
CHARSET_INFO *cs= system_charset_info;
char *user;
- ulonglong unow= my_micro_time();
+ my_hrtime_t unow= my_hrtime();
DBUG_ENTER("fill_process_list");
user= thd->security_ctx->master_access & PROCESS_ACL ?
@@ -2048,6 +2355,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
Security_context *tmp_sctx= tmp->security_ctx;
struct st_my_thread_var *mysys_var;
const char *val;
+ ulonglong max_counter;
if ((!tmp->vio_ok() && !tmp->system_thread) ||
(user && (!tmp_sctx->user || strcmp(tmp_sctx->user, user))))
@@ -2082,20 +2390,20 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
if ((mysys_var= tmp->mysys_var))
pthread_mutex_lock(&mysys_var->mutex);
/* COMMAND */
- if ((val= (char *) ((tmp->killed != THD::NOT_KILLED &&
- tmp->killed != THD::KILL_BAD_DATA ?
+ if ((val= (char *) ((tmp->killed >= KILL_QUERY ?
"Killed" : 0))))
table->field[4]->store(val, strlen(val), cs);
else
table->field[4]->store(command_name[tmp->command].str,
command_name[tmp->command].length, cs);
/* MYSQL_TIME */
- const ulonglong utime= tmp->start_utime ? unow - tmp->start_utime : 0;
- table->field[5]->store(utime / 1000000, TRUE);
+ const ulonglong utime= (tmp->start_time ?
+ (unow.val - tmp->start_time * HRTIME_RESOLUTION -
+ tmp->start_time_sec_part) : 0);
+ table->field[5]->store(utime / HRTIME_RESOLUTION, 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 ? "" :
@@ -2116,6 +2424,9 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
if (mysys_var)
pthread_mutex_unlock(&mysys_var->mutex);
+ /* TIME_MS */
+ table->field[8]->store((double)(utime / (HRTIME_RESOLUTION / 1000.0)));
+
/* INFO */
/* Lock THD mutex that protects its data when looking at it. */
pthread_mutex_lock(&tmp->LOCK_thd_data);
@@ -2126,10 +2437,19 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
tmp->query_length()), cs);
table->field[7]->set_notnull();
}
- pthread_mutex_unlock(&tmp->LOCK_thd_data);
- /* TIME_MS */
- table->field[8]->store((double)(utime / 1000.0));
+ /*
+ Progress report. We need to do this under a lock to ensure that all
+ is from the same stage.
+ */
+ if ((max_counter= tmp->progress.max_counter))
+ {
+ table->field[9]->store((longlong) tmp->progress.stage + 1, 1);
+ table->field[10]->store((longlong) tmp->progress.max_stage, 1);
+ table->field[11]->store((double) tmp->progress.counter /
+ (double) max_counter*100.0);
+ }
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
if (schema_table_store_record(thd, table))
{
@@ -2424,7 +2744,7 @@ static bool show_status_array(THD *thd, const char *wild,
end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
break;
case SHOW_INT:
- end= int10_to_str((long) *(uint32*) value, buff, 10);
+ end= int10_to_str((long) *(int*) value, buff, -10);
break;
case SHOW_HAVE:
{
@@ -2841,11 +3161,12 @@ typedef struct st_lookup_field_values
bool schema_table_store_record(THD *thd, TABLE *table)
{
int error;
- if ((error= table->file->ha_write_row(table->record[0])))
+ if ((error= table->file->ha_write_tmp_row(table->record[0])))
{
- 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;
@@ -3032,7 +3353,7 @@ bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
else if (item->type() == Item::REF_ITEM)
return uses_only_table_name_fields(item->real_item(), table);
- if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
+ if (item->real_type() == Item::SUBSELECT_ITEM && !item->const_item())
return 0;
return 1;
@@ -3539,8 +3860,8 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
*/
lex->sql_command= SQLCOM_SHOW_FIELDS;
result= open_normal_and_derived_tables(thd, table_list,
- MYSQL_LOCK_IGNORE_FLUSH);
-
+ MYSQL_LOCK_IGNORE_FLUSH,
+ DT_PREPARE | DT_CREATE);
/*
Restore old value of sql_command back as it is being looked at in
process_table() function.
@@ -3616,46 +3937,42 @@ end:
@retval 1 error
*/
-static int fill_schema_table_names(THD *thd, TABLE *table,
+static int fill_schema_table_names(THD *thd, TABLE_LIST *tables,
LEX_STRING *db_name, LEX_STRING *table_name,
- bool with_i_schema,
- bool need_table_type)
+ bool with_i_schema)
{
- /* Avoid opening FRM files if table type is not needed. */
- if (need_table_type)
+ TABLE *table= tables->table;
+ if (with_i_schema)
{
- if (with_i_schema)
- {
- table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
+ table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
+ system_charset_info);
+ }
+ else if (tables->table_open_method != SKIP_OPEN_TABLE)
+ {
+ enum legacy_db_type not_used;
+ char path[FN_REFLEN + 1];
+ (void) build_table_filename(path, sizeof(path) - 1, db_name->str,
+ table_name->str, reg_ext, 0);
+ switch (mysql_frm_type(thd, path, &not_used)) {
+ case FRMTYPE_ERROR:
+ table->field[3]->store(STRING_WITH_LEN("ERROR"),
+ system_charset_info);
+ break;
+ case FRMTYPE_TABLE:
+ table->field[3]->store(STRING_WITH_LEN("BASE TABLE"),
system_charset_info);
+ break;
+ case FRMTYPE_VIEW:
+ table->field[3]->store(STRING_WITH_LEN("VIEW"),
+ system_charset_info);
+ break;
+ default:
+ DBUG_ASSERT(0);
}
- else
+ if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
{
- enum legacy_db_type not_used;
- char path[FN_REFLEN + 1];
- (void) build_table_filename(path, sizeof(path) - 1, db_name->str,
- table_name->str, reg_ext, 0);
- switch (mysql_frm_type(thd, path, &not_used)) {
- case FRMTYPE_ERROR:
- table->field[3]->store(STRING_WITH_LEN("ERROR"),
- system_charset_info);
- break;
- case FRMTYPE_TABLE:
- table->field[3]->store(STRING_WITH_LEN("BASE TABLE"),
- system_charset_info);
- break;
- case FRMTYPE_VIEW:
- table->field[3]->store(STRING_WITH_LEN("VIEW"),
- system_charset_info);
- break;
- default:
- DBUG_ASSERT(0);
- }
- if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
- {
- thd->clear_error();
- return 0;
- }
+ thd->clear_error();
+ return 0;
}
}
if (schema_table_store_record(thd, table))
@@ -3975,9 +4292,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
/* SHOW TABLE NAMES command */
if (schema_table_idx == SCH_TABLE_NAMES)
{
- if (fill_schema_table_names(thd, tables->table, db_name,
- table_name, with_i_schema,
- lex->verbose))
+ if (fill_schema_table_names(thd, tables, db_name,
+ table_name, with_i_schema))
continue;
}
else
@@ -3985,8 +4301,14 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
!with_i_schema)
{
- if (!fill_schema_table_from_frm(thd, table, schema_table, db_name,
- table_name, schema_table_idx))
+ my_bool res;
+ uint8 save_context_analysis_only= lex->context_analysis_only;
+ lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
+ res= fill_schema_table_from_frm(thd, table, schema_table,
+ db_name,
+ table_name, schema_table_idx);
+ lex->context_analysis_only= save_context_analysis_only;
+ if (!res)
continue;
}
@@ -4290,21 +4612,21 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
{
thd->variables.time_zone->gmt_sec_to_TIME(&time,
(my_time_t) file->stats.create_time);
- table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[14]->store_time(&time);
table->field[14]->set_notnull();
}
if (file->stats.update_time)
{
thd->variables.time_zone->gmt_sec_to_TIME(&time,
(my_time_t) file->stats.update_time);
- table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[15]->store_time(&time);
table->field[15]->set_notnull();
}
if (file->stats.check_time)
{
thd->variables.time_zone->gmt_sec_to_TIME(&time,
(my_time_t) file->stats.check_time);
- table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[16]->store_time(&time);
table->field[16]->set_notnull();
}
if (file->ha_table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
@@ -4410,7 +4732,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
end=strmov(end,grant_types.type_names[bitnr]);
}
}
- table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs);
+ table->field[18]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs);
#endif
table->field[1]->store(db_name->str, db_name->length, cs);
@@ -4419,7 +4741,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
cs);
table->field[4]->store((longlong) count, TRUE);
field->sql_type(type);
- table->field[14]->store(type.ptr(), type.length(), cs);
+ table->field[15]->store(type.ptr(), type.length(), cs);
/*
MySQL column type has the following format:
base_type [(dimension)] [unsigned] [zerofill].
@@ -4466,6 +4788,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
They are set to -1 if they should not be set (we should return NULL)
*/
+ field_length= -1;
decimals= field->decimals();
switch (field->type()) {
case MYSQL_TYPE_NEWDECIMAL:
@@ -4494,8 +4817,13 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
if (decimals == NOT_FIXED_DEC)
decimals= -1; // return NULL
break;
+ case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ case MYSQL_TYPE_DATETIME:
+ table->field[12]->store((longlong) field->decimals(), TRUE);
+ table->field[12]->set_notnull();
+ break;
default:
- field_length= decimals= -1;
break;
}
@@ -4503,40 +4831,44 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
{
table->field[10]->store((longlong) field_length, TRUE);
table->field[10]->set_notnull();
- }
- if (decimals >= 0)
- {
- table->field[11]->store((longlong) decimals, TRUE);
- table->field[11]->set_notnull();
+ if (decimals >= 0)
+ {
+ table->field[11]->store((longlong) decimals, TRUE);
+ table->field[11]->set_notnull();
+ }
}
if (field->has_charset())
{
pos=(uchar*) field->charset()->csname;
- table->field[12]->store((const char*) pos,
- strlen((const char*) pos), cs);
- table->field[12]->set_notnull();
- pos=(uchar*) field->charset()->name;
table->field[13]->store((const char*) pos,
strlen((const char*) pos), cs);
table->field[13]->set_notnull();
+ pos=(uchar*) field->charset()->name;
+ table->field[14]->store((const char*) pos,
+ strlen((const char*) pos), cs);
+ table->field[14]->set_notnull();
}
pos=(uchar*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
- table->field[15]->store((const char*) pos,
+ table->field[16]->store((const char*) pos,
strlen((const char*) pos), cs);
if (field->unireg_check == Field::NEXT_NUMBER)
- table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
+ table->field[17]->store(STRING_WITH_LEN("auto_increment"), cs);
if (show_table->timestamp_field == field &&
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
- table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
+ table->field[17]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
cs);
if (field->vcol_info)
- table->field[16]->store(STRING_WITH_LEN("VIRTUAL"), cs);
-
- table->field[18]->store(field->comment.str, field->comment.length, cs);
+ {
+ if (field->stored_in_db)
+ table->field[17]->store(STRING_WITH_LEN("PERSISTENT"), cs);
+ else
+ table->field[17]->store(STRING_WITH_LEN("VIRTUAL"), cs);
+ }
+ table->field[19]->store(field->comment.str, field->comment.length, cs);
if (schema_table_store_record(thd, table))
DBUG_RETURN(1);
}
@@ -4789,10 +5121,10 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
bzero((char *)&time, sizeof(time));
((Field_timestamp *) proc_table->field[12])->get_time(&time);
- table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[15]->store_time(&time);
bzero((char *)&time, sizeof(time));
((Field_timestamp *) proc_table->field[13])->get_time(&time);
- table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[16]->store_time(&time);
copy_field_as_string(table->field[17], proc_table->field[14]);
copy_field_as_string(table->field[18], proc_table->field[15]);
table->field[19]->store(definer.ptr(), definer.length(), cs);
@@ -5421,21 +5753,21 @@ static void store_schema_partitions_record(THD *thd, TABLE *schema_table,
{
thd->variables.time_zone->gmt_sec_to_TIME(&time,
(my_time_t)stat_info.create_time);
- table->field[18]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[18]->store_time(&time);
table->field[18]->set_notnull();
}
if (stat_info.update_time)
{
thd->variables.time_zone->gmt_sec_to_TIME(&time,
(my_time_t)stat_info.update_time);
- table->field[19]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[19]->store_time(&time);
table->field[19]->set_notnull();
}
if (stat_info.check_time)
{
thd->variables.time_zone->gmt_sec_to_TIME(&time,
(my_time_t)stat_info.check_time);
- table->field[20]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[20]->store_time(&time);
table->field[20]->set_notnull();
}
if (file->ha_table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
@@ -5816,15 +6148,13 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
/* starts & ends . STARTS is always set - see sql_yacc.yy */
et.time_zone->gmt_sec_to_TIME(&time, et.starts);
sch_table->field[ISE_STARTS]->set_notnull();
- sch_table->field[ISE_STARTS]->
- store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ sch_table->field[ISE_STARTS]->store_time(&time);
if (!et.ends_null)
{
et.time_zone->gmt_sec_to_TIME(&time, et.ends);
sch_table->field[ISE_ENDS]->set_notnull();
- sch_table->field[ISE_ENDS]->
- store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ sch_table->field[ISE_ENDS]->store_time(&time);
}
}
else
@@ -5834,8 +6164,7 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
et.time_zone->gmt_sec_to_TIME(&time, et.execute_at);
sch_table->field[ISE_EXECUTE_AT]->set_notnull();
- sch_table->field[ISE_EXECUTE_AT]->
- store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ sch_table->field[ISE_EXECUTE_AT]->store_time(&time);
}
/* status */
@@ -5865,21 +6194,19 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
sch_table->field[ISE_ON_COMPLETION]->
store(STRING_WITH_LEN("PRESERVE"), scs);
- number_to_datetime(et.created, &time, 0, &not_used);
+ number_to_datetime(et.created, 0, &time, 0, &not_used);
DBUG_ASSERT(not_used==0);
- sch_table->field[ISE_CREATED]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ sch_table->field[ISE_CREATED]->store_time(&time);
- number_to_datetime(et.modified, &time, 0, &not_used);
+ number_to_datetime(et.modified, 0, &time, 0, &not_used);
DBUG_ASSERT(not_used==0);
- sch_table->field[ISE_LAST_ALTERED]->
- store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ sch_table->field[ISE_LAST_ALTERED]->store_time(&time);
if (et.last_executed)
{
et.time_zone->gmt_sec_to_TIME(&time, et.last_executed);
sch_table->field[ISE_LAST_EXECUTED]->set_notnull();
- sch_table->field[ISE_LAST_EXECUTED]->
- store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ sch_table->field[ISE_LAST_EXECUTED]->store_time(&time);
}
sch_table->field[ISE_EVENT_COMMENT]->
@@ -6289,14 +6616,23 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
break;
case MYSQL_TYPE_DATE:
+ if (!(item=new Item_return_date_time(fields_info->field_name,
+ MAX_DATE_WIDTH,
+ fields_info->field_type)))
+ DBUG_RETURN(0);
+ break;
case MYSQL_TYPE_TIME:
+ if (!(item=new Item_return_date_time(fields_info->field_name,
+ MAX_TIME_FULL_WIDTH,
+ fields_info->field_type)))
+ DBUG_RETURN(0);
+ break;
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME:
if (!(item=new Item_return_date_time(fields_info->field_name,
+ MAX_DATETIME_WIDTH,
fields_info->field_type)))
- {
DBUG_RETURN(0);
- }
break;
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
@@ -6482,7 +6818,7 @@ int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
{
- int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
+ int fields_arr[]= {3, 15, 14, 6, 16, 5, 17, 18, 19, -1};
int *field_num= fields_arr;
ST_FIELD_INFO *field_info;
Name_resolution_context *context= &thd->lex->select_lex.context;
@@ -6490,9 +6826,9 @@ int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
for (; *field_num >= 0; field_num++)
{
field_info= &schema_table->fields_info[*field_num];
- if (!thd->lex->verbose && (*field_num == 13 ||
- *field_num == 17 ||
- *field_num == 18))
+ if (!thd->lex->verbose && (*field_num == 14 ||
+ *field_num == 18 ||
+ *field_num == 19))
continue;
Item_field *field= new Item_field(context,
NullS, NullS, field_info->field_name);
@@ -6697,14 +7033,15 @@ int make_schema_select(THD *thd, SELECT_LEX *sel,
bool get_schema_tables_result(JOIN *join,
enum enum_schema_table_state executed_place)
{
- JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
THD *thd= join->thd;
LEX *lex= thd->lex;
bool result= 0;
DBUG_ENTER("get_schema_tables_result");
thd->no_warnings_for_error= 1;
- for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
+ for (JOIN_TAB *tab= first_linear_tab(join, WITH_CONST_TABLES);
+ tab;
+ tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
{
if (!tab->table || !tab->table->pos_in_table_list)
break;
@@ -6759,13 +7096,13 @@ bool get_schema_tables_result(JOIN *join,
{
result= 1;
join->error= 1;
- tab->read_record.file= table_list->table->file;
+ tab->read_record.table->file= table_list->table->file;
table_list->schema_table_state= executed_place;
if (!thd->is_error())
my_error(ER_UNKNOWN_ERROR, MYF(0));
break;
}
- tab->read_record.file= table_list->table->file;
+ tab->read_record.table->file= table_list->table->file;
table_list->schema_table_state= executed_place;
}
}
@@ -6963,6 +7300,8 @@ ST_FIELD_INFO columns_fields_info[]=
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
{"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
+ {"DATETIME_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
+ 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
{"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, 0,
OPEN_FRM_ONLY},
{"COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, "Collation",
@@ -7356,6 +7695,10 @@ ST_FIELD_INFO processlist_fields_info[]=
SKIP_OPEN_TABLE},
{"TIME_MS", 100 * (MY_INT64_NUM_DECIMAL_DIGITS + 1) + 3, MYSQL_TYPE_DECIMAL,
0, 0, "Time_ms", SKIP_OPEN_TABLE},
+ {"STAGE", 2, MYSQL_TYPE_TINY, 0, 0, "Stage", SKIP_OPEN_TABLE},
+ {"MAX_STAGE", 2, MYSQL_TYPE_TINY, 0, 0, "Max_stage", SKIP_OPEN_TABLE},
+ {"PROGRESS", 703, MYSQL_TYPE_DECIMAL, 0, 0, "Progress",
+ SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
@@ -7576,7 +7919,7 @@ ST_SCHEMA_TABLE schema_tables[]=
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
{"TABLE_NAMES", table_names_fields_info, create_schema_table,
- get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
+ get_all_tables, make_table_names_old_format, 0, 1, 2, 1, OPTIMIZE_I_S_TABLE},
{"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
fill_schema_table_privileges, 0, 0, -1, -1, 0, 0},
{"TABLE_STATISTICS", table_stats_fields_info, create_schema_table,
diff --git a/sql/sql_show.h b/sql/sql_show.h
index fec73122e8b..e3077c560d7 100644
--- a/sql/sql_show.h
+++ b/sql/sql_show.h
@@ -41,4 +41,13 @@ int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff);
int copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table);
+
+/* Handle the ignored database directories list for SHOW/I_S. */
+bool ignore_db_dirs_init();
+void ignore_db_dirs_free();
+void ignore_db_dirs_reset();
+bool ignore_db_dirs_process_additions();
+bool push_ignored_db_dir(char *path);
+extern char *opt_ignore_db_dirs;
+
#endif /* SQL_SHOW_H */
diff --git a/sql/sql_sort.h b/sql/sql_sort.h
index f54b085eeda..fc4117e2767 100644
--- a/sql/sql_sort.h
+++ b/sql/sql_sort.h
@@ -57,6 +57,7 @@ typedef struct st_sort_param {
uint addon_length; /* Length of added packed fields */
uint res_length; /* Length of records in final sorted file/buffer */
uint keys; /* Max keys / buffer */
+ element_count min_dupl_count;
ha_rows max_rows,examined_rows;
TABLE *sort_form; /* For quicker make_sortkey */
SORT_FIELD *local_sortorder;
@@ -80,4 +81,9 @@ int merge_buffers(SORTPARAM *param,IO_CACHE *from_file,
IO_CACHE *to_file, uchar *sort_buffer,
BUFFPEK *lastbuff,BUFFPEK *Fb,
BUFFPEK *Tb,int flag);
+int merge_index(SORTPARAM *param, uchar *sort_buffer,
+ BUFFPEK *buffpek, uint maxbuffer,
+ IO_CACHE *tempfile, IO_CACHE *outfile);
+
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length);
+
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 66327051298..5941022546c 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -582,11 +582,11 @@ uint32 String::numchars()
return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
}
-int String::charpos(int i,uint32 offset)
+int String::charpos(longlong i,uint32 offset)
{
if (i <= 0)
- return i;
- return str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,i);
+ return (int)i;
+ return (int)str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,(size_t)i);
}
int String::strstr(const String &s,uint32 offset)
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 4b0aaff35b9..61003774ecc 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -193,6 +193,18 @@ public:
{ return set_int((longlong)num, true, cs); }
bool set_real(double num,uint decimals, CHARSET_INFO *cs);
+ /* Move handling of buffer from some other object to String */
+ void reassociate(char *ptr, uint32 length, uint32 alloced_length,
+ CHARSET_INFO *cs)
+ {
+ free();
+ Ptr= ptr;
+ str_length= length;
+ Alloced_length= alloced_length;
+ str_charset= cs;
+ alloced= ptr != 0;
+ }
+
/*
PMG 2004.11.12
This is a method that works the same as perl's "chop". It simply
@@ -339,7 +351,7 @@ public:
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);
+ int charpos(longlong i,uint32 offset=0);
int reserve(uint32 space_needed)
{
@@ -454,8 +466,9 @@ public:
}
};
-static inline bool check_if_only_end_space(CHARSET_INFO *cs, char *str,
- char *end)
+static inline bool check_if_only_end_space(CHARSET_INFO *cs,
+ const char *str,
+ const char *end)
{
return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 1b4c1c4875d..546bff574d1 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -26,6 +26,7 @@
#include "sql_trigger.h"
#include "sql_show.h"
#include "debug_sync.h"
+#include "sql_handler.h"
#ifdef __WIN__
#include <io.h>
@@ -37,17 +38,16 @@ const char *primary_key_name="PRIMARY";
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
-static int copy_data_between_tables(TABLE *from,TABLE *to,
- List<Create_field> &create, bool ignore,
- uint order_num, ORDER *order,
- ha_rows *copied,ha_rows *deleted,
- enum enum_enable_or_disable keys_onoff,
- bool error_if_not_empty);
+static int copy_data_between_tables(THD *thd, TABLE *,TABLE *,
+ List<Create_field> &, bool,
+ uint, ORDER *, ha_rows *,ha_rows *,
+ enum enum_enable_or_disable, bool);
static bool prepare_blob_field(THD *thd, Create_field *sql_field);
static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
static int mysql_prepare_create_table(THD *, HA_CREATE_INFO *, Alter_info *,
- bool, uint *, handler *, KEY **, uint *, int);
+ bool, uint *, handler *, KEY **, uint *,
+ int);
static bool mysql_prepare_alter_table(THD *, TABLE *, HA_CREATE_INFO *,
Alter_info *);
static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list);
@@ -61,7 +61,7 @@ static void wait_for_kill_signal(THD *thd)
while (thd->killed == 0)
sleep(1);
// Reset signal and continue as if nothing happend
- thd->killed= THD::NOT_KILLED;
+ thd->killed= NOT_KILLED;
}
#endif
@@ -3248,7 +3248,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
my_error(ER_WRONG_SUB_KEY, MYF(0));
DBUG_RETURN(TRUE);
}
-
if (!f_is_geom(sql_field->pack_flag))
{
my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX");
@@ -4717,6 +4716,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
int result_code;
bool need_repair_or_alter= 0;
DBUG_ENTER("mysql_admin_table");
+ DBUG_PRINT("enter", ("extra_open_options: %u", extra_open_options));
if (end_active_trans(thd))
DBUG_RETURN(1);
@@ -4741,9 +4741,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
bool fatal_error=0;
DBUG_PRINT("admin", ("table: '%s'.'%s'", table->db, table->table_name));
- DBUG_PRINT("admin", ("extra_open_options: %u", extra_open_options));
strxmov(table_name, db, ".", table->table_name, NullS);
- thd->open_options|= extra_open_options;
table->lock_type= lock_type;
/* open only one table from local list of command */
{
@@ -4765,12 +4763,18 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
thd->no_warnings_for_error= no_warnings_for_error;
if (view_operator_func == NULL)
table->required_type=FRMTYPE_TABLE;
-
+ if (lex->sql_command == SQLCOM_CHECK ||
+ lex->sql_command == SQLCOM_REPAIR ||
+ lex->sql_command == SQLCOM_ANALYZE ||
+ lex->sql_command == SQLCOM_OPTIMIZE)
+ thd->prepare_derived_at_open= TRUE;
+ thd->open_options|= extra_open_options;
open_and_lock_tables(thd, table);
+ thd->open_options&= ~extra_open_options;
+ thd->prepare_derived_at_open= FALSE;
thd->no_warnings_for_error= 0;
table->next_global= save_next_global;
table->next_local= save_next_local;
- thd->open_options&= ~extra_open_options;
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (table->table)
{
@@ -4864,7 +4868,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
else
/* Default failure code is corrupt table */
result_code= HA_ADMIN_CORRUPT;
- goto send_result;
+ goto send_result;
}
if (table->view)
@@ -4954,7 +4958,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
/* We use extra_open_options to be able to open crashed tables */
thd->open_options|= extra_open_options;
result_code= admin_recreate_table(thd, table);
- thd->open_options= ~extra_open_options;
+ thd->open_options&= ~extra_open_options;
goto send_result;
}
if (check_old_types || check_for_upgrade)
@@ -5863,8 +5867,8 @@ is_index_maintenance_unique (TABLE *table, Alter_info *alter_info)
that need to be dropped and/or (re-)created.
RETURN VALUES
- TRUE error
- FALSE success
+ TRUE The tables are not compatible; We have to do a full alter table
+ FALSE The tables are compatible; We only have to modify the .frm
*/
static
@@ -6004,6 +6008,9 @@ compare_tables(TABLE *table,
DBUG_ASSERT(i < table->s->fields);
create_info->fields_option_struct[i]= tmp_new_field->option_struct;
+ /* reset common markers of how field changed */
+ field->flags&= ~(FIELD_IS_RENAMED | FIELD_IN_ADD_INDEX);
+
/* Make sure we have at least the default charset in use. */
if (!new_field->charset)
new_field->charset= create_info->default_table_charset;
@@ -6038,7 +6045,6 @@ compare_tables(TABLE *table,
create_info->table_options|= HA_OPTION_PACK_RECORD;
/* Check if field was renamed */
- field->flags&= ~FIELD_IS_RENAMED;
if (my_strcasecmp(system_charset_info,
field->field_name,
tmp_new_field->field_name))
@@ -6051,8 +6057,6 @@ compare_tables(TABLE *table,
new_field->field_name));
DBUG_RETURN(0);
}
- // Clear indexed marker
- field->flags&= ~FIELD_IN_ADD_INDEX;
changes|= tmp;
}
@@ -6366,7 +6370,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
{
Alter_drop *drop;
- if (field->type() == MYSQL_TYPE_STRING)
+ if (field->type() == MYSQL_TYPE_VARCHAR)
create_info->varchar= TRUE;
/* Check if field should be dropped */
drop_it.rewind();
@@ -6709,6 +6713,7 @@ err:
order_num How many ORDER BY fields has been specified.
order List of fields to ORDER BY.
ignore Whether we have ALTER IGNORE TABLE
+ require_online Give an error if we can't do operation online
DESCRIPTION
This is a veery long function and is everything but the kitchen sink :)
@@ -6739,7 +6744,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
HA_CREATE_INFO *create_info,
TABLE_LIST *table_list,
Alter_info *alter_info,
- uint order_num, ORDER *order, bool ignore)
+ uint order_num, ORDER *order, bool ignore,
+ bool require_online)
{
TABLE *table, *new_table= 0, *name_lock= 0;
int error= 0;
@@ -7542,10 +7548,23 @@ view_err:
*/
}
+ /* Check if we can do the ALTER TABLE as online */
+ if (require_online)
+ {
+ if (index_add_count || index_drop_count ||
+ (new_table &&
+ !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER)))
+ {
+ my_error(ER_CANT_DO_ONLINE, MYF(0), "ALTER");
+ goto close_table_and_return_error;
+ }
+ }
+
/* Copy the data if necessary. */
thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
thd->cuted_fields=0L;
copied=deleted=0;
+
/*
We do not copy data for MERGE tables. Only the children have data.
MERGE tables have HA_NO_COPY_ON_ALTER set.
@@ -7555,8 +7574,7 @@ view_err:
/* We don't want update TIMESTAMP fields during ALTER TABLE. */
new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
new_table->next_number_field=new_table->found_next_number_field;
- thd_proc_info(thd, "copy to tmp table");
- error= copy_data_between_tables(table, new_table,
+ error= copy_data_between_tables(thd, table, new_table,
alter_info->create_list, ignore,
order_num, order, &copied, &deleted,
alter_info->keys_onoff,
@@ -7577,6 +7595,8 @@ view_err:
error= 1;
}
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
+ if (error)
+ goto close_table_and_return_error;
/* If we did not need to copy, we might still need to add/drop indexes. */
if (! new_table)
@@ -7670,11 +7690,11 @@ view_err:
}
/*end of if (! new_table) for add/drop index*/
+ DBUG_ASSERT(error == 0);
+
if (table->s->tmp_table != NO_TMP_TABLE)
{
/* We changed a temporary table */
- if (error)
- goto err1;
/* Close lock if this is a transactional table */
if (thd->lock)
{
@@ -7709,12 +7729,6 @@ view_err:
}
DEBUG_SYNC(thd, "alter_table_before_rename_result_table");
VOID(pthread_mutex_lock(&LOCK_open));
- if (error)
- {
- VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
- VOID(pthread_mutex_unlock(&LOCK_open));
- goto err;
- }
/*
Data is copied. Now we:
@@ -7887,6 +7901,16 @@ end_temporary:
thd->some_tables_deleted=0;
DBUG_RETURN(FALSE);
+close_table_and_return_error:
+ if (new_table && table->s->tmp_table == NO_TMP_TABLE)
+ {
+ /* This is not a temporary table, so close it the normal way */
+ new_table->s->deleting= TRUE;
+ intern_close_table(new_table);
+ my_free(new_table,MYF(0));
+ new_table= 0; // This forces call to quick_rm_table() below
+ }
+
err1:
if (new_table)
{
@@ -7957,7 +7981,7 @@ err_with_placeholders:
/* Copy all rows from one table to another */
static int
-copy_data_between_tables(TABLE *from,TABLE *to,
+copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
List<Create_field> &create,
bool ignore,
uint order_num, ORDER *order,
@@ -7969,7 +7993,6 @@ copy_data_between_tables(TABLE *from,TABLE *to,
int error= 1, errpos= 0;
Copy_field *copy= NULL, *copy_end;
ha_rows found_count= 0, delete_count= 0;
- THD *thd= current_thd;
uint length= 0;
SORT_FIELD *sortorder;
READ_RECORD info;
@@ -7979,11 +8002,14 @@ copy_data_between_tables(TABLE *from,TABLE *to,
ha_rows examined_rows;
bool auto_increment_field_copied= 0;
ulong save_sql_mode= thd->variables.sql_mode;
- ulonglong prev_insert_id;
+ ulonglong prev_insert_id, time_to_report_progress;
List_iterator<Create_field> it(create);
Create_field *def;
DBUG_ENTER("copy_data_between_tables");
+ /* Two or 3 stages; Sorting, copying data and update indexes */
+ thd_progress_init(thd, 2 + test(order));
+
/*
Turn off recovery logging since rollback of an alter table is to
delete the new table so there is no need to log the changes to it.
@@ -8038,7 +8064,8 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if (order)
{
- if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
+ if (to->s->primary_key != MAX_KEY &&
+ to->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
my_snprintf(warn_buff, sizeof(warn_buff),
@@ -8056,6 +8083,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
tables.alias= tables.table_name= from->s->table_name.str;
tables.db= from->s->db.str;
+ thd_proc_info(thd, "Sorting");
if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
&tables, fields, all_fields, order) ||
@@ -8066,8 +8094,10 @@ copy_data_between_tables(TABLE *from,TABLE *to,
HA_POS_ERROR)
goto err;
}
- };
+ thd_progress_next_stage(thd);
+ }
+ thd_proc_info(thd, "copy to tmp table");
/* Tell handler that we have values for all columns in the to table */
to->use_all_columns();
to->mark_virtual_columns_for_write(TRUE);
@@ -8078,6 +8108,10 @@ copy_data_between_tables(TABLE *from,TABLE *to,
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
thd->row_count= 0;
restore_record(to, s->default_values); // Create empty record
+
+ thd->progress.max_counter= from->file->records();
+ time_to_report_progress= MY_HOW_OFTEN_TO_WRITE/10;
+
while (!(error=info.read_record(&info)))
{
if (thd->killed)
@@ -8086,8 +8120,16 @@ copy_data_between_tables(TABLE *from,TABLE *to,
error= 1;
break;
}
- update_virtual_fields(thd, from);
+ if (from->vfield)
+ update_virtual_fields(thd, from);
thd->row_count++;
+ if (++thd->progress.counter >= time_to_report_progress)
+ {
+ time_to_report_progress+= MY_HOW_OFTEN_TO_WRITE/10;
+ thd_progress_report(thd, thd->progress.counter,
+ thd->progress.max_counter);
+ }
+
/* Return error if source table isn't empty. */
if (error_if_not_empty)
{
@@ -8107,7 +8149,8 @@ copy_data_between_tables(TABLE *from,TABLE *to,
copy_ptr->do_copy(copy_ptr);
}
prev_insert_id= to->file->next_insert_id;
- update_virtual_fields(thd, to, VCOL_UPDATE_FOR_WRITE);
+ if (to->vfield)
+ update_virtual_fields(thd, to, VCOL_UPDATE_FOR_WRITE);
if (thd->is_error())
{
error= 1;
@@ -8151,6 +8194,9 @@ err:
free_io_cache(from);
delete [] copy;
+ thd_proc_info(thd, "Enabling keys");
+ thd_progress_next_stage(thd);
+
if (error > 0)
to->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
if (errpos >= 3 && to->file->ha_end_bulk_insert() && error <= 0)
@@ -8240,7 +8286,7 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
table_list, &alter_info, 0,
- (ORDER *) 0, 0));
+ (ORDER *) 0, 0, 0));
}
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index 04adf6dcadc..010cc2f52c6 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -169,64 +169,115 @@ void TEST_filesort(SORT_FIELD *sortorder,uint s_length)
void
TEST_join(JOIN *join)
{
- uint i,ref;
+ uint ref;
+ int i;
+ List_iterator<JOIN_TAB_RANGE> it(join->join_tab_ranges);
+ JOIN_TAB_RANGE *jt_range;
DBUG_ENTER("TEST_join");
- /*
- Assemble results of all the calls to full_name() first,
- in order not to garble the tabular output below.
- */
- String ref_key_parts[MAX_TABLES];
- for (i= 0; i < join->tables; i++)
- {
- JOIN_TAB *tab= join->join_tab + i;
- for (ref= 0; ref < tab->ref.key_parts; ref++)
- {
- ref_key_parts[i].append(tab->ref.items[ref]->full_name());
- ref_key_parts[i].append(" ");
- }
- }
-
DBUG_LOCK_FILE;
VOID(fputs("\nInfo about JOIN\n",DBUG_FILE));
- for (i=0 ; i < join->tables ; i++)
+
+ while ((jt_range= it++))
{
- JOIN_TAB *tab=join->join_tab+i;
- 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.c_ptr(),
- join_type_str[tab->type],
- tab->keys.print(key_map_buff),
- tab->ref.key_parts,
- tab->ref.key,
- tab->ref.key_length);
- if (tab->select)
+ /*
+ Assemble results of all the calls to full_name() first,
+ in order not to garble the tabular output below.
+ */
+ String ref_key_parts[MAX_TABLES];
+ int tables_in_range= jt_range->end - jt_range->start;
+ for (i= 0; i < tables_in_range; i++)
{
- char buf[MAX_KEY/8+1];
- if (tab->use_quick == 2)
- fprintf(DBUG_FILE,
- " quick select checked for each record (keys: %s)\n",
- tab->select->quick_keys.print(buf));
- else if (tab->select->quick)
+ JOIN_TAB *tab= jt_range->start + i;
+ for (ref= 0; ref < tab->ref.key_parts; ref++)
{
- fprintf(DBUG_FILE, " quick select used:\n");
- tab->select->quick->dbug_dump(18, FALSE);
+ ref_key_parts[i].append(tab->ref.items[ref]->full_name());
+ ref_key_parts[i].append(" ");
}
- else
- VOID(fputs(" select used\n",DBUG_FILE));
}
- if (tab->ref.key_parts)
+
+ for (i= 0; i < tables_in_range; i++)
{
- fprintf(DBUG_FILE,
+ JOIN_TAB *tab= jt_range->start + i;
+ 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.c_ptr(),
+ join_type_str[tab->type],
+ tab->keys.print(key_map_buff),
+ tab->ref.key_parts,
+ tab->ref.key,
+ tab->ref.key_length);
+ if (tab->select)
+ {
+ char buf[MAX_KEY/8+1];
+ if (tab->use_quick == 2)
+ fprintf(DBUG_FILE,
+ " quick select checked for each record (keys: %s)\n",
+ tab->select->quick_keys.print(buf));
+ else if (tab->select->quick)
+ {
+ fprintf(DBUG_FILE, " quick select used:\n");
+ tab->select->quick->dbug_dump(18, FALSE);
+ }
+ else
+ VOID(fputs(" select used\n",DBUG_FILE));
+ }
+ if (tab->ref.key_parts)
+ {
+ fprintf(DBUG_FILE,
" refs: %s\n", ref_key_parts[i].c_ptr_safe());
+ }
}
+ VOID(fputs("\n",DBUG_FILE));
}
DBUG_UNLOCK_FILE;
DBUG_VOID_RETURN;
}
+#define FT_KEYPART (MAX_REF_PARTS+10)
+
+void print_keyuse(KEYUSE *keyuse)
+{
+ char buff[256];
+ char buf2[64];
+ const char *fieldname;
+ JOIN_TAB *join_tab= keyuse->table->reginfo.join_tab;
+ KEY *key_info= join_tab->get_keyinfo_by_key_no(keyuse->key);
+ String str(buff,(uint32) sizeof(buff), system_charset_info);
+ str.length(0);
+ keyuse->val->print(&str, QT_ORDINARY);
+ str.append('\0');
+ if (keyuse->is_for_hash_join())
+ fieldname= keyuse->table->field[keyuse->keypart]->field_name;
+ else if (keyuse->keypart == FT_KEYPART)
+ fieldname= "FT_KEYPART";
+ else
+ fieldname= key_info->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.
@@ -327,6 +378,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 13cb9f22e9a..298d4281d1c 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -21,6 +21,7 @@
#include "sp_head.h"
#include "sql_trigger.h"
#include "parse_file.h"
+#include "sql_handler.h"
#include <mysys_err.h>
/*************************************************************************/
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index a7224bd74bd..d3808610ea8 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -19,7 +19,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 bcdbf81836a..942392c4c98 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -52,19 +52,26 @@ int select_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
int 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);
+ if (table->no_rows_with_nulls)
+ table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT;
+ fill_record(thd, table->field, values, TRUE, FALSE);
if (thd->is_error())
return 1;
+ if (table->no_rows_with_nulls)
+ {
+ table->null_catch_flags&= ~CHECK_ROW_FOR_NULLS_TO_REJECT;
+ if (table->null_catch_flags)
+ return 0;
+ }
- if ((error= table->file->ha_write_row(table->record[0])))
+ if ((write_err= table->file->ha_write_tmp_row(table->record[0])))
{
- if (error == HA_ERR_FOUND_DUPP_KEY)
+ if (write_err == HA_ERR_FOUND_DUPP_KEY)
{
/*
Inform upper level that we found a duplicate key, that should not
@@ -73,8 +80,11 @@ int select_union::send_data(List<Item> &values)
return -1;
}
/* 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;
@@ -109,6 +119,9 @@ 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
+ create_table whether to physically create result table
DESCRIPTION
Create a temporary table that is used to store the result of a UNION,
@@ -122,22 +135,49 @@ 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, bool create_table)
{
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,
- options, HA_POS_ERROR, (char*) alias)))
+ options, HA_POS_ERROR, (char*) alias,
+ !create_table)))
return TRUE;
- table->file->extra(HA_EXTRA_WRITE_CACHE);
- table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+
+ table->keys_in_use_for_query.clear_all();
+ for (uint i=0; i < table->s->fields; i++)
+ table->field[i]->flags &= ~PART_KEY_FLAG;
+
+ if (create_table)
+ {
+ table->file->extra(HA_EXTRA_WRITE_CACHE);
+ table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+ }
return FALSE;
}
+/**
+ 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()
@@ -171,6 +211,8 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg)
{
(*order->item)->walk(&Item::change_context_processor, 0,
(uchar*) &fake_select_lex->context);
+ (*order->item)->walk(&Item::set_fake_select_as_master_processor, 0,
+ (uchar*) fake_select_lex);
}
}
@@ -255,6 +297,18 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
+ /*
+ Remove all references from the select_lex_units to the subqueries that
+ are inside the ORDER BY clause.
+ */
+ if (can_skip_order_by)
+ {
+ for (ORDER *ord= (ORDER *)sl->order_list.first; ord; ord= ord->next)
+ {
+ (*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL);
+ }
+ }
+
saved_error= join->prepare(&sl->ref_pointer_array,
sl->table_list.first,
sl->with_wild,
@@ -269,6 +323,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
(is_union_select ? NULL :
thd_arg->lex->proc_list.first),
sl, this);
+
/* There are no * in the statement anymore (for PS) */
sl->with_wild= 0;
last_procedure= join->procedure;
@@ -323,6 +378,9 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
List_iterator_fast<Item> tp(types);
Item *type;
ulonglong create_options;
+ uint save_tablenr= 0;
+ table_map save_map= 0;
+ uint save_maybe_null= 0;
while ((type= tp++))
{
@@ -375,12 +433,24 @@ 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, TRUE))
goto err;
+ if (fake_select_lex && !fake_select_lex->first_cond_optimization)
+ {
+ save_tablenr= result_table_list.tablenr_exec;
+ save_map= result_table_list.map_exec;
+ save_maybe_null= result_table_list.maybe_null_exec;
+ }
bzero((char*) &result_table_list, sizeof(result_table_list));
result_table_list.db= (char*) "";
result_table_list.table_name= result_table_list.alias= (char*) "union";
result_table_list.table= table= union_result->table;
+ if (fake_select_lex && !fake_select_lex->first_cond_optimization)
+ {
+ result_table_list.tablenr_exec= save_tablenr;
+ result_table_list.map_exec= save_map;
+ result_table_list.maybe_null_exec= save_maybe_null;
+ }
thd_arg->lex->current_select= lex_select_save;
if (!item_list.elements)
@@ -456,18 +526,21 @@ err:
}
-bool st_select_lex_unit::exec()
+/**
+ Run optimization phase.
+
+ @return FALSE unit successfully passed optimization phase.
+ @return TRUE an error occur.
+*/
+bool st_select_lex_unit::optimize()
{
SELECT_LEX *lex_select_save= thd->lex->current_select;
SELECT_LEX *select_cursor=first_select();
- ulonglong add_rows=0;
- ha_rows examined_rows= 0;
- DBUG_ENTER("st_select_lex_unit::exec");
+ DBUG_ENTER("st_select_lex_unit::optimize");
- if (executed && !uncacheable && !describe)
+ if (optimized && !uncacheable && !describe)
DBUG_RETURN(FALSE);
- executed= 1;
-
+
if (uncacheable || !item || !item->assigned() || describe)
{
if (item)
@@ -488,7 +561,6 @@ bool st_select_lex_unit::exec()
}
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
{
- ha_rows records_at_start= 0;
thd->lex->current_select= sl;
if (optimized)
@@ -515,6 +587,68 @@ bool st_select_lex_unit::exec()
sl->join->select_options=
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
+
+ saved_error= sl->join->optimize();
+ }
+
+ if (saved_error)
+ {
+ thd->lex->current_select= lex_select_save;
+ DBUG_RETURN(saved_error);
+ }
+ }
+ }
+ optimized= 1;
+
+ thd->lex->current_select= lex_select_save;
+ DBUG_RETURN(saved_error);
+}
+
+
+bool st_select_lex_unit::exec()
+{
+ SELECT_LEX *lex_select_save= thd->lex->current_select;
+ SELECT_LEX *select_cursor=first_select();
+ ulonglong add_rows=0;
+ ha_rows examined_rows= 0;
+ DBUG_ENTER("st_select_lex_unit::exec");
+
+ if (executed && !uncacheable && !describe)
+ DBUG_RETURN(FALSE);
+ executed= 1;
+ if (!(uncacheable & ~UNCACHEABLE_EXPLAIN) && item)
+ item->make_const();
+
+ saved_error= optimize();
+
+ if (uncacheable || !item || !item->assigned() || describe)
+ {
+ for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
+ {
+ ha_rows records_at_start= 0;
+ thd->lex->current_select= sl;
+
+ {
+ set_limit(sl);
+ if (sl == global_parameters || describe)
+ {
+ offset_limit_cnt= 0;
+ /*
+ We can't use LIMIT at this stage if we are using ORDER BY for the
+ whole query
+ */
+ if (sl->order_list.first || describe)
+ select_limit_cnt= HA_POS_ERROR;
+ }
+
+ /*
+ When using braces, SQL_CALC_FOUND_ROWS affects the whole query:
+ we don't calculate found_rows() per union part.
+ Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
+ */
+ sl->join->select_options=
+ (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
+ sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
saved_error= sl->join->optimize();
}
if (!saved_error)
@@ -534,6 +668,7 @@ bool st_select_lex_unit::exec()
if (!saved_error)
{
examined_rows+= thd->examined_row_count;
+ thd->examined_row_count= 0;
if (union_result->flush())
{
thd->lex->current_select= lex_select_save;
@@ -567,7 +702,6 @@ bool st_select_lex_unit::exec()
}
}
}
- optimized= 1;
/* Send result to 'result' */
saved_error= TRUE;
@@ -699,7 +833,8 @@ bool st_select_lex_unit::cleanup()
if ((join= fake_select_lex->join))
{
join->tables_list= 0;
- join->tables= 0;
+ join->table_count= 0;
+ join->top_join_tab_count= 0;
}
error|= fake_select_lex->cleanup();
/*
@@ -761,8 +896,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())
@@ -836,6 +971,7 @@ bool st_select_lex::cleanup()
}
non_agg_fields.empty();
inner_refs_list.empty();
+ exclude_from_table_unique_test= FALSE;
DBUG_RETURN(error);
}
@@ -852,3 +988,27 @@ void st_select_lex::cleanup_all_joins(bool full)
for (sl= unit->first_select(); sl; sl= sl->next_select())
sl->cleanup_all_joins(full);
}
+
+
+/**
+ Set exclude_from_table_unique_test for selects of this unit and all
+ underlying selects.
+
+ @note used to exclude materialized derived tables (views) from unique
+ table check.
+*/
+
+void st_select_lex_unit::set_unique_exclude()
+{
+ for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
+ {
+ sl->exclude_from_table_unique_test= TRUE;
+ for (SELECT_LEX_UNIT *unit= sl->first_inner_unit();
+ unit;
+ unit= unit->next_unit())
+ {
+ unit->set_unique_exclude();
+ }
+ }
+}
+
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 56b2c508fbc..21e5828699f 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -221,7 +221,7 @@ int mysql_update(THD *thd,
bool need_reopen;
ulonglong id;
List<Item> all_fields;
- THD::killed_state killed_status= THD::NOT_KILLED;
+ killed_state killed_status= NOT_KILLED;
DBUG_ENTER("mysql_update");
for ( ; ; )
@@ -229,7 +229,11 @@ int mysql_update(THD *thd,
if (open_tables(thd, &table_list, &table_count, 0))
DBUG_RETURN(1);
- if (table_list->multitable_view)
+ //Prepare views so they are handled correctly.
+ if (mysql_handle_derived(thd->lex, DT_INIT))
+ DBUG_RETURN(1);
+
+ if (table_list->is_multitable())
{
DBUG_ASSERT(table_list->view != 0);
DBUG_PRINT("info", ("Switch to multi-update"));
@@ -245,14 +249,19 @@ int mysql_update(THD *thd,
close_tables_for_reopen(thd, &table_list);
}
- if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
- (thd->fill_derived_tables() &&
- mysql_handle_derived(thd->lex, &mysql_derived_filling)))
+ if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
+ DBUG_RETURN(1);
+ if (table_list->handle_derived(thd->lex, DT_PREPARE))
DBUG_RETURN(1);
thd_proc_info(thd, "init");
table= table_list->table;
+ if (!table_list->single_table_updatable())
+ {
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
+ DBUG_RETURN(1);
+ }
/* Calculate "table->covering_keys" based on the WHERE */
table->covering_keys= table->s->keys_in_use;
table->quick_keys.clear_all();
@@ -271,14 +280,17 @@ int mysql_update(THD *thd,
table_list->grant.want_privilege= table->grant.want_privilege= want_privilege;
table_list->register_want_access(want_privilege);
#endif
+ /* 'Unfix' fields to allow correct marking by the setup_fields function. */
+ if (table_list->is_view())
+ unfix_fields(fields);
+
if (setup_fields_with_no_wrap(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
DBUG_RETURN(1); /* purecov: inspected */
if (table_list->view && check_fields(thd, fields))
{
DBUG_RETURN(1);
}
- if (!table_list->single_table_updatable() ||
- check_key_in_view(thd, table_list))
+ if (check_key_in_view(thd, table_list))
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
DBUG_RETURN(1);
@@ -308,6 +320,10 @@ int mysql_update(THD *thd,
DBUG_RETURN(1); /* purecov: inspected */
}
+ /* Apply the IN=>EXISTS transformation to all subqueries and optimize them. */
+ if (select_lex->optimize_unflattened_subqueries())
+ DBUG_RETURN(TRUE);
+
if (select_lex->inner_refs_list.elements &&
fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
DBUG_RETURN(1);
@@ -343,7 +359,7 @@ int mysql_update(THD *thd,
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
select= make_select(table, 0, 0, conds, 0, &error);
- if (error || !limit ||
+ if (error || !limit || thd->is_error() ||
(select && select->check_quick(thd, safe_update, limit)))
{
delete select;
@@ -490,9 +506,10 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed)
{
- update_virtual_fields(thd, table,
- table->triggers ? VCOL_UPDATE_ALL :
- VCOL_UPDATE_FOR_READ);
+ if (table->vfield)
+ update_virtual_fields(thd, table,
+ table->triggers ? VCOL_UPDATE_ALL :
+ VCOL_UPDATE_FOR_READ);
thd->examined_row_count++;
if (!select || (error= select->skip_record(thd)) > 0)
{
@@ -607,9 +624,10 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed)
{
- update_virtual_fields(thd, table,
- table->triggers ? VCOL_UPDATE_ALL :
- VCOL_UPDATE_FOR_READ);
+ if (table->vfield)
+ update_virtual_fields(thd, table,
+ table->triggers ? VCOL_UPDATE_ALL :
+ VCOL_UPDATE_FOR_READ);
thd->examined_row_count++;
if (!select || select->skip_record(thd) > 0)
{
@@ -776,9 +794,9 @@ int mysql_update(THD *thd,
// simulated killing after the loop must be ineffective for binlogging
DBUG_EXECUTE_IF("simulate_kill_bug27571",
{
- thd->killed= THD::KILL_QUERY;
+ thd->killed= KILL_QUERY;
};);
- error= (killed_status == THD::NOT_KILLED)? error : 1;
+ error= (killed_status == NOT_KILLED)? error : 1;
if (error &&
will_batch &&
@@ -839,7 +857,7 @@ int mysql_update(THD *thd,
if (error < 0)
thd->clear_error();
else
- errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ errcode= query_error_code(thd, killed_status == NOT_KILLED);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
@@ -870,6 +888,11 @@ int mysql_update(THD *thd,
}
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
thd->abort_on_warning= 0;
+ if (thd->lex->current_select->first_cond_optimization)
+ {
+ thd->lex->current_select->save_leaf_tables(thd);
+ thd->lex->current_select->first_cond_optimization= 0;
+ }
DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0);
err:
@@ -930,8 +953,8 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
if (setup_tables_and_check_access(thd, &select_lex->context,
&select_lex->top_join_list,
table_list,
- &select_lex->leaf_tables,
- FALSE, UPDATE_ACL, SELECT_ACL) ||
+ select_lex->leaf_tables,
+ FALSE, UPDATE_ACL, SELECT_ACL, TRUE) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
select_lex->setup_ref_array(thd, order_num) ||
setup_order(thd, select_lex->ref_pointer_array,
@@ -968,8 +991,8 @@ static table_map get_table_map(List<Item> *items)
Item_field *item;
table_map map= 0;
- while ((item= (Item_field *) item_it++))
- map|= item->used_tables();
+ while ((item= (Item_field *) item_it++))
+ map|= item->all_used_tables();
DBUG_PRINT("info", ("table_map: 0x%08lx", (long) map));
return map;
}
@@ -991,7 +1014,7 @@ int mysql_multi_update_prepare(THD *thd)
{
LEX *lex= thd->lex;
TABLE_LIST *table_list= lex->query_tables;
- TABLE_LIST *tl, *leaves;
+ TABLE_LIST *tl;
List<Item> *fields= &lex->select_lex.item_list;
table_map tables_for_update;
bool update_view= 0;
@@ -1014,7 +1037,7 @@ reopen_tables:
/* open tables and create derived ones, but do not lock and fill them */
if (((original_multiupdate || need_reopen) &&
open_tables(thd, &table_list, &table_count, 0)) ||
- mysql_handle_derived(lex, &mysql_derived_prepare))
+ mysql_handle_derived(lex, DT_INIT))
DBUG_RETURN(TRUE);
/*
setup_tables() need for VIEWs. JOIN::prepare() will call setup_tables()
@@ -1022,11 +1045,20 @@ reopen_tables:
call in setup_tables()).
*/
+ //We need to merge for insert prior to prepare.
+ if (mysql_handle_derived(lex, DT_MERGE_FOR_INSERT))
+ DBUG_RETURN(TRUE);
+ if (mysql_handle_derived(lex, DT_PREPARE))
+ DBUG_RETURN(TRUE);
+
if (setup_tables_and_check_access(thd, &lex->select_lex.context,
&lex->select_lex.top_join_list,
table_list,
- &lex->select_lex.leaf_tables, FALSE,
- UPDATE_ACL, SELECT_ACL))
+ lex->select_lex.leaf_tables, FALSE,
+ UPDATE_ACL, SELECT_ACL, FALSE))
+ DBUG_RETURN(TRUE);
+
+ if (lex->select_lex.handle_derived(thd->lex, DT_MERGE))
DBUG_RETURN(TRUE);
if (setup_fields_with_no_wrap(thd, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
@@ -1051,8 +1083,8 @@ reopen_tables:
/*
Setup timestamp handling and locking mode
*/
- leaves= lex->select_lex.leaf_tables;
- for (tl= leaves; tl; tl= tl->next_leaf)
+ List_iterator<TABLE_LIST> ti(lex->select_lex.leaf_tables);
+ while ((tl= ti++))
{
TABLE *table= tl->table;
/* Only set timestamp column if this is not modified */
@@ -1064,7 +1096,7 @@ reopen_tables:
/* if table will be updated then check that it is unique */
if (table->map & tables_for_update)
{
- if (!tl->updatable || check_key_in_view(thd, tl))
+ if (!tl->single_table_updatable() || check_key_in_view(thd, tl))
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), tl->alias, "UPDATE");
DBUG_RETURN(TRUE);
@@ -1094,7 +1126,7 @@ reopen_tables:
for (tl= table_list; tl; tl= tl->next_local)
{
/* Check access privileges for table */
- if (!tl->derived)
+ if (!tl->is_derived())
{
uint want_privilege= tl->updating ? UPDATE_ACL : SELECT_ACL;
if (check_access(thd, want_privilege,
@@ -1108,7 +1140,7 @@ reopen_tables:
/* check single table update for view compound from several tables */
for (tl= table_list; tl; tl= tl->next_local)
{
- if (tl->effective_algorithm == VIEW_ALGORITHM_MERGE)
+ if (tl->is_merged_derived())
{
TABLE_LIST *for_update= 0;
if (tl->check_single_table(&for_update, tables_for_update, tl))
@@ -1163,6 +1195,8 @@ reopen_tables:
*/
unit->unclean();
}
+ // Reset 'prepared' flags for all derived tables/views
+ mysql_handle_list_of_derived(thd->lex, table_list, DT_REINIT);
/*
Also we need to cleanup Natural_join_column::table_field items.
@@ -1185,7 +1219,8 @@ reopen_tables:
*/
lex->select_lex.exclude_from_table_unique_test= TRUE;
/* We only need SELECT privilege for columns in the values list */
- for (tl= leaves; tl; tl= tl->next_leaf)
+ ti.rewind();
+ while ((tl= ti++))
{
TABLE *table= tl->table;
TABLE_LIST *tlist;
@@ -1213,11 +1248,10 @@ reopen_tables:
further check in multi_update::prepare whether to use record cache.
*/
lex->select_lex.exclude_from_table_unique_test= FALSE;
-
- if (thd->fill_derived_tables() &&
- mysql_handle_derived(lex, &mysql_derived_filling))
- DBUG_RETURN(TRUE);
+ if (lex->select_lex.save_prep_leaf_tables(thd))
+ DBUG_RETURN(TRUE);
+
DBUG_RETURN (FALSE);
}
@@ -1240,7 +1274,7 @@ bool mysql_multi_update(THD *thd,
DBUG_ENTER("mysql_multi_update");
if (!(result= new multi_update(table_list,
- thd->lex->select_lex.leaf_tables,
+ &thd->lex->select_lex.leaf_tables,
fields, values,
handle_duplicates, ignore)))
DBUG_RETURN(TRUE);
@@ -1263,11 +1297,7 @@ bool mysql_multi_update(THD *thd,
DBUG_PRINT("info",("res: %d report_error: %d", res, (int) thd->is_error()));
res|= thd->is_error();
if (unlikely(res))
- {
- /* If we had a another error reported earlier then this will be ignored */
- result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR));
result->abort();
- }
delete result;
thd->abort_on_warning= 0;
DBUG_RETURN(FALSE);
@@ -1275,7 +1305,7 @@ bool mysql_multi_update(THD *thd,
multi_update::multi_update(TABLE_LIST *table_list,
- TABLE_LIST *leaves_list,
+ List<TABLE_LIST> *leaves_list,
List<Item> *field_list, List<Item> *value_list,
enum enum_duplicates handle_duplicates_arg,
bool ignore_arg)
@@ -1293,6 +1323,7 @@ multi_update::multi_update(TABLE_LIST *table_list,
int multi_update::prepare(List<Item> &not_used_values,
SELECT_LEX_UNIT *lex_unit)
+
{
TABLE_LIST *table_ref;
SQL_I_List<TABLE_LIST> update;
@@ -1302,6 +1333,7 @@ int multi_update::prepare(List<Item> &not_used_values,
List_iterator_fast<Item> value_it(*values);
uint i, max_fields;
uint leaf_table_count= 0;
+ List_iterator<TABLE_LIST> ti(*leaves);
DBUG_ENTER("multi_update::prepare");
thd->count_cuted_fields= CHECK_FIELD_WARN;
@@ -1321,7 +1353,7 @@ int multi_update::prepare(List<Item> &not_used_values,
TABLE::tmp_set by pointing TABLE::read_set to it and then restore it after
setup_fields().
*/
- for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
+ while ((table_ref= ti++))
{
TABLE *table= table_ref->table;
if (tables_to_update & table->map)
@@ -1339,7 +1371,8 @@ int multi_update::prepare(List<Item> &not_used_values,
int error= setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0);
- for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
+ ti.rewind();
+ while ((table_ref= ti++))
{
TABLE *table= table_ref->table;
if (tables_to_update & table->map)
@@ -1368,7 +1401,8 @@ int multi_update::prepare(List<Item> &not_used_values,
*/
update.empty();
- for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
+ ti.rewind();
+ while ((table_ref= ti++))
{
/* TODO: add support of view of join support */
TABLE *table=table_ref->table;
@@ -1439,6 +1473,15 @@ int multi_update::prepare(List<Item> &not_used_values,
DBUG_RETURN(thd->is_fatal_error != 0);
}
+void multi_update::update_used_tables()
+{
+ Item *item;
+ List_iterator_fast<Item> it(*values);
+ while ((item= it++))
+ {
+ item->update_used_tables();
+ }
+}
/*
Check if table is safe to update on fly
@@ -1594,9 +1637,9 @@ loop_end:
{
table_map unupdated_tables= table_ref->check_option->used_tables() &
~first_table_for_update->map;
- for (TABLE_LIST *tbl_ref =leaves;
- unupdated_tables && tbl_ref;
- tbl_ref= tbl_ref->next_leaf)
+ List_iterator<TABLE_LIST> ti(*leaves);
+ TABLE_LIST *tbl_ref;
+ while ((tbl_ref= ti++) && unupdated_tables)
{
if (unupdated_tables & tbl_ref->table->map)
unupdated_tables&= ~tbl_ref->table->map;
@@ -1834,15 +1877,17 @@ int 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]);
+ error= tmp_table->file->ha_write_tmp_row(tmp_table->record[0]);
if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
{
if (error &&
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
@@ -1903,7 +1948,7 @@ void multi_update::abort()
got caught and if happens later the killed error is written
into repl event.
*/
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
/* the error of binary logging is ignored */
(void)thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
@@ -2117,7 +2162,7 @@ bool multi_update::send_eof()
{
char buff[STRING_BUFFER_USUAL_SIZE];
ulonglong id;
- THD::killed_state killed_status= THD::NOT_KILLED;
+ killed_state killed_status= NOT_KILLED;
DBUG_ENTER("multi_update::send_eof");
thd_proc_info(thd, "updating reference tables");
@@ -2130,7 +2175,7 @@ bool multi_update::send_eof()
if local_error is not set ON until after do_updates() then
later carried out killing should not affect binlogging.
*/
- killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
+ killed_status= (local_error == 0) ? NOT_KILLED : thd->killed;
thd_proc_info(thd, "end");
/* We must invalidate the query cache before binlog writing and
@@ -2159,7 +2204,7 @@ bool multi_update::send_eof()
if (local_error == 0)
thd->clear_error();
else
- errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ errcode= query_error_code(thd, killed_status == NOT_KILLED);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode))
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 0fe1b597d82..2c9227b46f7 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -248,7 +248,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
view->definer.user= decoy.definer.user;
lex->definer= &view->definer;
}
- if (lex->create_view_algorithm == VIEW_ALGORITHM_UNDEFINED)
+ if (lex->create_view_algorithm == DTYPE_ALGORITHM_UNDEFINED)
lex->create_view_algorithm= (uint8) decoy.algorithm;
if (lex->create_view_suid == VIEW_SUID_DEFAULT)
lex->create_view_suid= decoy.view_suid ?
@@ -736,7 +736,7 @@ static File_option view_parameters[]=
FILE_OPTIONS_ULONGLONG},
{{ C_STRING_WITH_LEN("algorithm")},
my_offsetof(TABLE_LIST, algorithm),
- FILE_OPTIONS_ULONGLONG},
+ FILE_OPTIONS_VIEW_ALGO},
{{ C_STRING_WITH_LEN("definer_user")},
my_offsetof(TABLE_LIST, definer.user),
FILE_OPTIONS_STRING},
@@ -843,7 +843,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
ulong sql_mode= thd->variables.sql_mode & MODE_ANSI_QUOTES;
thd->variables.sql_mode&= ~MODE_ANSI_QUOTES;
- lex->unit.print(&view_query, QT_ORDINARY);
+ lex->unit.print(&view_query, QT_VIEW_INTERNAL);
lex->unit.print(&is_query, QT_IS);
thd->variables.sql_mode|= sql_mode;
@@ -876,7 +876,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
{
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_VIEW_MERGE,
ER(ER_WARN_VIEW_MERGE));
- lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
+ lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED;
}
view->algorithm= lex->create_view_algorithm;
view->definer.user= lex->definer->user;
@@ -1491,7 +1491,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list);
- table->effective_algorithm= VIEW_ALGORITHM_MERGE;
+ table->derived_type= VIEW_ALGORITHM_MERGE;
DBUG_PRINT("info", ("algorithm: MERGE"));
table->updatable= (table->updatable_view != 0);
table->effective_with_check=
@@ -1505,74 +1505,31 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
/* prepare view context */
lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables);
lex->select_lex.context.outer_context= 0;
- lex->select_lex.context.select_lex= table->select_lex;
lex->select_lex.select_n_having_items+=
table->select_lex->select_n_having_items;
- /*
- Tables of the main select of the view should be marked as belonging
- to the same select as original view (again we can use LEX::select_lex
- for this purprose because we don't support MERGE algorithm for views
- with unions).
- */
- for (tbl= lex->select_lex.get_table_list(); tbl; tbl= tbl->next_local)
- tbl->select_lex= table->select_lex;
-
- {
- if (view_main_select_tables->next_local)
- {
- table->multitable_view= TRUE;
- if (table->belong_to_view)
- table->belong_to_view->multitable_view= TRUE;
- }
- /* make nested join structure for view tables */
- NESTED_JOIN *nested_join;
- if (!(nested_join= table->nested_join=
- (NESTED_JOIN *) thd->calloc(sizeof(NESTED_JOIN))))
- goto err;
- nested_join->join_list= view_select->top_join_list;
-
- /* re-nest tables of VIEW */
- ti.rewind();
- while ((tbl= ti++))
- {
- tbl->join_list= &nested_join->join_list;
- tbl->embedding= table;
- }
- }
-
- /* Store WHERE clause for post-processing in setup_underlying */
table->where= view_select->where;
- /*
- Add subqueries units to SELECT into which we merging current view.
- unit(->next)* chain starts with subqueries that are used by this
- view and continues with subqueries that are used by other views.
- We must not add any subquery twice (otherwise we'll form a loop),
- to do this we remember in end_unit the first subquery that has
- been already added.
-
- NOTE: we do not support UNION here, so we take only one select
- */
- SELECT_LEX_NODE *end_unit= table->select_lex->slave;
- SELECT_LEX_UNIT *next_unit;
- for (SELECT_LEX_UNIT *unit= lex->select_lex.first_inner_unit();
- unit;
- unit= next_unit)
- {
- if (unit == end_unit)
- break;
- SELECT_LEX_NODE *save_slave= unit->slave;
- next_unit= unit->next_unit();
- unit->include_down(table->select_lex);
- unit->slave= save_slave; // fix include_down initialisation
- }
/*
We can safely ignore the VIEW's ORDER BY if we merge into union
branch, as order is not important there.
*/
- if (!table->select_lex->master_unit()->is_union())
+ if (!table->select_lex->master_unit()->is_union() &&
+ table->select_lex->order_list.elements == 0)
table->select_lex->order_list.push_back(&lex->select_lex.order_list);
+ else
+ {
+ if (old_lex->sql_command == SQLCOM_SELECT &&
+ (old_lex->describe & DESCRIBE_EXTENDED) &&
+ lex->select_lex.order_list.elements &&
+ !table->select_lex->master_unit()->is_union())
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ ER_VIEW_ORDERBY_IGNORED,
+ ER(ER_VIEW_ORDERBY_IGNORED),
+ table->db, table->table_name);
+ }
+ }
/*
This SELECT_LEX will be linked in global SELECT_LEX list
to make it processed by mysql_handle_derived(),
@@ -1582,23 +1539,22 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
goto ok;
}
- table->effective_algorithm= VIEW_ALGORITHM_TMPTABLE;
+ table->derived_type= VIEW_ALGORITHM_TMPTABLE;
DBUG_PRINT("info", ("algorithm: TEMPORARY TABLE"));
view_select->linkage= DERIVED_TABLE_TYPE;
table->updatable= 0;
table->effective_with_check= VIEW_CHECK_NONE;
old_lex->subqueries= TRUE;
- /* SELECT tree link */
- lex->unit.include_down(table->select_lex);
- lex->unit.slave= view_select; // fix include_down initialisation
-
table->derived= &lex->unit;
}
else
goto err;
ok:
+ /* SELECT tree link */
+ lex->unit.include_down(table->select_lex);
+ lex->unit.slave= view_select; // fix include_down initialisation
/* global SELECT list linking */
end= view_select; // primary SELECT_LEX is always last
end->link_next= old_lex->all_selects_list;
@@ -1766,6 +1722,8 @@ frm_type_enum mysql_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
*dbt= DB_TYPE_UNKNOWN;
+
+
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
DBUG_RETURN(FRMTYPE_ERROR);
error= my_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP));
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 4360ba14941..b1772536639 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -36,6 +36,7 @@
#define YYINITDEPTH 100
#define YYMAXDEPTH 3200 /* Because of 64K stack */
#define Lex (YYTHD->lex)
+
#define Select Lex->current_select
#include "mysql_priv.h"
#include "slave.h"
@@ -673,6 +674,8 @@ static bool add_create_index (LEX *lex, Key::Keytype type, const char *name,
sp_head *sphead;
struct p_elem_val *p_elem_value;
enum index_hint_type index_hint;
+ DYNCALL_CREATE_DEF *dyncol_def;
+ List<DYNCALL_CREATE_DEF> *dyncol_def_list;
}
%{
@@ -681,10 +684,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%pure_parser /* We have threads */
/*
- Currently there are 169 shift/reduce conflicts.
+ Currently there are 174 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
-%expect 169
+%expect 174
/*
Comments for TOKENS.
@@ -760,6 +763,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token CHANGED
%token CHARSET
%token CHAR_SYM /* SQL-2003-R */
+%token CHECKPOINT_SYM
%token CHECKSUM_SYM
%token CHECK_SYM /* SQL-2003-R */
%token CIPHER_SYM
@@ -771,6 +775,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token COLLATE_SYM /* SQL-2003-R */
%token COLLATION_SYM /* SQL-2003-N */
%token COLUMNS
+%token COLUMN_ADD_SYM
+%token COLUMN_CREATE_SYM
+%token COLUMN_DELETE_SYM
+%token COLUMN_EXISTS_SYM
+%token COLUMN_GET_SYM
+%token COLUMN_LIST_SYM
%token COLUMN_SYM /* SQL-2003-R */
%token COMMENT_SYM
%token COMMITTED_SYM /* SQL-2003-N */
@@ -893,6 +903,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token GROUP_CONCAT_SYM
%token GT_SYM /* OPERATOR */
%token HANDLER_SYM
+%token HARD_SYM
%token HASH_SYM
%token HAVING /* SQL-2003-R */
%token HELP_SYM
@@ -1043,6 +1054,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token ON /* SQL-2003-R */
%token ONE_SHOT_SYM
%token ONE_SYM
+%token ONLINE_SYM
%token OPEN_SYM /* SQL-2003-R */
%token OPTIMIZE
%token OPTIONS_SYM
@@ -1160,6 +1172,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SMALLINT /* SQL-2003-R */
%token SNAPSHOT_SYM
%token SOCKET_SYM
+%token SOFT_SYM
%token SONAME_SYM
%token SOUNDS_SYM
%token SOURCE_SYM
@@ -1338,6 +1351,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
opt_natural_language_mode opt_query_expansion
opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt
+ optional_flush_tables_arguments opt_dyncol_type dyncol_type
+ opt_time_precision kill_type kill_option int_num
%type <ulong_num>
ulong_num real_ulong_num merge_insert_types
@@ -1369,7 +1384,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
function_call_keyword
function_call_nonkeyword
function_call_generic
- function_call_conflict
+ function_call_conflict kill_expr
%type <item_num>
NUM_literal
@@ -1437,6 +1452,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <boolfunc2creator> comp_op
+%type <dyncol_def> dyncall_create_element
+
+%type <dyncol_def_list> dyncall_create_list
+
%type <NONE>
query verb_clause create change select do drop insert replace insert2
insert_values update delete truncate rename
@@ -1930,7 +1949,7 @@ create:
| CREATE
{
Lex->create_view_mode= VIEW_CREATE_NEW;
- Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
+ Lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED;
Lex->create_view_suid= TRUE;
}
view_or_trigger_or_sp_or_event
@@ -2072,7 +2091,7 @@ opt_ev_status:
ev_starts:
/* empty */
{
- Item *item= new (YYTHD->mem_root) Item_func_now_local();
+ Item *item= new (YYTHD->mem_root) Item_func_now_local(0);
if (item == NULL)
MYSQL_YYABORT;
Lex->event_parse_data->item_starts= item;
@@ -5226,7 +5245,7 @@ type:
}
| DATE_SYM
{ $$=MYSQL_TYPE_DATE; }
- | TIME_SYM
+ | TIME_SYM opt_field_length
{ $$=MYSQL_TYPE_TIME; }
| TIMESTAMP opt_field_length
{
@@ -5241,7 +5260,7 @@ type:
$$=MYSQL_TYPE_TIMESTAMP;
}
}
- | DATETIME
+ | DATETIME opt_field_length
{ $$=MYSQL_TYPE_DATETIME; }
| TINYBLOB
{
@@ -5436,7 +5455,7 @@ attribute:
| DEFAULT now_or_signed_literal { Lex->default_value=$2; }
| ON UPDATE_SYM NOW_SYM optional_braces
{
- Item *item= new (YYTHD->mem_root) Item_func_now_local();
+ Item *item= new (YYTHD->mem_root) Item_func_now_local(6);
if (item == NULL)
MYSQL_YYABORT;
Lex->on_update_value= item;
@@ -5508,7 +5527,7 @@ attribute:
now_or_signed_literal:
NOW_SYM optional_braces
{
- $$= new (YYTHD->mem_root) Item_func_now_local();
+ $$= new (YYTHD->mem_root) Item_func_now_local(6);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -5890,7 +5909,7 @@ string_list:
*/
alter:
- ALTER opt_ignore TABLE_SYM table_ident
+ ALTER alter_options TABLE_SYM table_ident
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
@@ -6003,7 +6022,7 @@ alter:
my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW");
MYSQL_YYABORT;
}
- lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
+ lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED;
lex->create_view_mode= VIEW_ALTER;
}
view_tail
@@ -6457,6 +6476,25 @@ opt_ignore:
| IGNORE_SYM { Lex->ignore= 1;}
;
+alter_options:
+ { Lex->ignore= Lex->online= 0;} alter_options_part2
+ ;
+
+alter_options_part2:
+ /* empty */
+ | alter_option_list
+ ;
+
+alter_option_list:
+ alter_option_list alter_option
+ | alter_option
+ ;
+
+alter_option:
+ IGNORE_SYM { Lex->ignore= 1;}
+ | ONLINE_SYM { Lex->online= 1;}
+
+
opt_restrict:
/* empty */ { Lex->drop_mode= DROP_DEFAULT; }
| RESTRICT { Lex->drop_mode= DROP_RESTRICT; }
@@ -7096,6 +7134,12 @@ select_alias:
| TEXT_STRING_sys { $$=$1; }
;
+opt_time_precision:
+ /* empty */ { $$= 0; }
+ | '(' ')' { $$= 0; }
+ | '(' real_ulong_num ')' { $$= $2; };
+ ;
+
optional_braces:
/* empty */ {}
| '(' ')' {}
@@ -7157,7 +7201,7 @@ expr:
| expr XOR expr %prec XOR
{
/* XOR is a proprietary extension */
- $$ = new (YYTHD->mem_root) Item_cond_xor($1, $3);
+ $$ = new (YYTHD->mem_root) Item_func_xor($1, $3);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -7511,6 +7555,133 @@ all_or_any:
| ANY_SYM { $$ = 0; }
;
+opt_dyncol_type:
+ /* empty */
+ {
+ LEX *lex= Lex;
+ $$= DYN_COL_NULL; /* automatic type */
+ lex->charset= NULL;
+ lex->length= lex->dec= 0;
+ }
+ | AS dyncol_type { $$= $2; }
+ ;
+
+dyncol_type:
+ INT_SYM
+ {
+ LEX *lex= Lex;
+ $$= DYN_COL_INT;
+ lex->charset= NULL;
+ lex->length= lex->dec= 0;
+ }
+ | UNSIGNED INT_SYM
+ {
+ LEX *lex= Lex;
+ $$= DYN_COL_UINT;
+ lex->charset= NULL;
+ lex->length= lex->dec= 0;
+ }
+ | DOUBLE_SYM
+ {
+ LEX *lex= Lex;
+ $$= DYN_COL_DOUBLE;
+ lex->charset= NULL;
+ lex->length= lex->dec= 0;
+ }
+ | REAL
+ {
+ LEX *lex= Lex;
+ $$= DYN_COL_DOUBLE;
+ lex->charset= NULL;
+ lex->length= lex->dec= 0;
+ }
+ | FLOAT_SYM
+ {
+ LEX *lex= Lex;
+ $$= DYN_COL_DOUBLE;
+ lex->charset= NULL;
+ lex->length= lex->dec= 0;
+ }
+ | DECIMAL_SYM float_options
+ {
+ $$= DYN_COL_DECIMAL;
+ Lex->charset= NULL;
+ }
+ | char opt_binary
+ {
+ LEX *lex= Lex;
+ $$= DYN_COL_STRING;
+ lex->length= lex->dec= 0;
+ }
+ | nchar
+ {
+ LEX *lex= Lex;
+ $$= DYN_COL_STRING;
+ lex->charset= national_charset_info;
+ lex->length= lex->dec= 0;
+ }
+ | DATE_SYM
+ {
+ LEX *lex= Lex;
+ $$= DYN_COL_DATE;
+ lex->charset= NULL;
+ lex->length= lex->dec= 0;
+ }
+ | TIME_SYM opt_field_length
+ {
+ LEX *lex= Lex;
+ $$= DYN_COL_TIME;
+ lex->charset= NULL;
+ lex->dec= lex->length;
+ lex->length= 0;
+ }
+ | DATETIME opt_field_length
+ {
+ LEX *lex= Lex;
+ $$= DYN_COL_DATETIME;
+ lex->charset= NULL;
+ lex->dec= lex->length;
+ lex->length= 0;
+ }
+ ;
+
+dyncall_create_element:
+ expr ',' expr opt_dyncol_type
+ {
+ LEX *lex= Lex;
+ $$= (DYNCALL_CREATE_DEF *)
+ alloc_root(YYTHD->mem_root, sizeof(DYNCALL_CREATE_DEF));
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ $$->num= $1;
+ $$->value= $3;
+ $$->type= (DYNAMIC_COLUMN_TYPE)$4;
+ $$->cs= lex->charset;
+ if (lex->length)
+ $$->len= strtoul(lex->length, NULL, 10);
+ else
+ $$->len= 0;
+ if (lex->dec)
+ $$->frac= strtoul(lex->dec, NULL, 10);
+ else
+ $$->len= 0;
+ }
+
+dyncall_create_list:
+ dyncall_create_element
+ {
+ $$= new (YYTHD->mem_root) List<DYNCALL_CREATE_DEF>;
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ $$->push_back($1);
+ }
+ | dyncall_create_list ',' dyncall_create_element
+ {
+ $1->push_back($3);
+ $$= $1;
+ }
+ ;
+
simple_expr:
simple_ident
| function_call_keyword
@@ -7774,13 +7945,13 @@ function_call_keyword:
}
| TIME_SYM '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_time_typecast($3);
+ $$= new (YYTHD->mem_root) Item_time_typecast($3, AUTO_SEC_PART_DIGITS);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TIMESTAMP '(' expr ')'
{
- $$= new (YYTHD->mem_root) Item_datetime_typecast($3);
+ $$= new (YYTHD->mem_root) Item_datetime_typecast($3, AUTO_SEC_PART_DIGITS);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -7887,16 +8058,9 @@ function_call_nonkeyword:
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
}
- | CURTIME optional_braces
+ | CURTIME opt_time_precision
{
- $$= new (YYTHD->mem_root) Item_func_curtime_local();
- if ($$ == NULL)
- MYSQL_YYABORT;
- Lex->safe_to_cache_query=0;
- }
- | CURTIME '(' expr ')'
- {
- $$= new (YYTHD->mem_root) Item_func_curtime_local($3);
+ $$= new (YYTHD->mem_root) Item_func_curtime_local($2);
if ($$ == NULL)
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
@@ -7927,16 +8091,9 @@ function_call_nonkeyword:
if ($$ == NULL)
MYSQL_YYABORT;
}
- | NOW_SYM optional_braces
+ | NOW_SYM opt_time_precision
{
- $$= new (YYTHD->mem_root) Item_func_now_local();
- if ($$ == NULL)
- MYSQL_YYABORT;
- Lex->safe_to_cache_query=0;
- }
- | NOW_SYM '(' expr ')'
- {
- $$= new (YYTHD->mem_root) Item_func_now_local($3);
+ $$= new (YYTHD->mem_root) Item_func_now_local($2);
if ($$ == NULL)
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
@@ -7984,7 +8141,7 @@ function_call_nonkeyword:
if ($$ == NULL)
MYSQL_YYABORT;
}
- | SYSDATE optional_braces
+ | SYSDATE opt_time_precision
{
/*
Unlike other time-related functions, SYSDATE() is
@@ -7995,19 +8152,9 @@ function_call_nonkeyword:
*/
Lex->set_stmt_unsafe();
if (global_system_variables.sysdate_is_now == 0)
- $$= new (YYTHD->mem_root) Item_func_sysdate_local();
+ $$= new (YYTHD->mem_root) Item_func_sysdate_local($2);
else
- $$= new (YYTHD->mem_root) Item_func_now_local();
- if ($$ == NULL)
- MYSQL_YYABORT;
- Lex->safe_to_cache_query=0;
- }
- | SYSDATE '(' expr ')'
- {
- if (global_system_variables.sysdate_is_now == 0)
- $$= new (YYTHD->mem_root) Item_func_sysdate_local($3);
- else
- $$= new (YYTHD->mem_root) Item_func_now_local($3);
+ $$= new (YYTHD->mem_root) Item_func_now_local($2);
if ($$ == NULL)
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
@@ -8031,20 +8178,65 @@ function_call_nonkeyword:
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
}
- | UTC_TIME_SYM optional_braces
+ | UTC_TIME_SYM opt_time_precision
{
- $$= new (YYTHD->mem_root) Item_func_curtime_utc();
+ $$= new (YYTHD->mem_root) Item_func_curtime_utc($2);
if ($$ == NULL)
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
}
- | UTC_TIMESTAMP_SYM optional_braces
+ | UTC_TIMESTAMP_SYM opt_time_precision
{
- $$= new (YYTHD->mem_root) Item_func_now_utc();
+ $$= new (YYTHD->mem_root) Item_func_now_utc($2);
if ($$ == NULL)
MYSQL_YYABORT;
Lex->safe_to_cache_query=0;
}
+ |
+ COLUMN_ADD_SYM '(' expr ',' dyncall_create_list ')'
+ {
+ $$= create_func_dyncol_add(YYTHD, $3, *$5);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ COLUMN_DELETE_SYM '(' expr ',' expr_list ')'
+ {
+ $$= create_func_dyncol_delete(YYTHD, $3, *$5);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ COLUMN_EXISTS_SYM '(' expr ',' expr ')'
+ {
+ $$= new (YYTHD->mem_root) Item_func_dyncol_exists($3, $5);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ COLUMN_LIST_SYM '(' expr ')'
+ {
+ $$= new (YYTHD->mem_root) Item_func_dyncol_list($3);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ COLUMN_CREATE_SYM '(' dyncall_create_list ')'
+ {
+ $$= create_func_dyncol_create(YYTHD, *$3);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')'
+ {
+ LEX *lex= Lex;
+ $$= create_func_dyncol_get(YYTHD, $3, $5, $7,
+ lex->length, lex->dec,
+ lex->charset);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
;
/*
@@ -8661,6 +8853,8 @@ cast_type:
{ $$=ITEM_CAST_CHAR; Lex->dec= 0; }
| NCHAR_SYM opt_field_length
{ $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; Lex->dec=0; }
+ | INT_SYM
+ { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
| SIGNED_SYM
{ $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
| SIGNED_SYM INT_SYM
@@ -8671,13 +8865,24 @@ cast_type:
{ $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
| DATE_SYM
{ $$=ITEM_CAST_DATE; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
- | TIME_SYM
- { $$=ITEM_CAST_TIME; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
- | DATETIME
- { $$=ITEM_CAST_DATETIME; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
+ | TIME_SYM opt_field_length
+ {
+ $$=ITEM_CAST_TIME;
+ LEX *lex= Lex;
+ lex->charset= NULL; lex->dec= lex->length; lex->length= (char*)0;
+ }
+ | DATETIME opt_field_length
+ {
+ $$=ITEM_CAST_DATETIME;
+ LEX *lex= Lex;
+ lex->charset= NULL; lex->dec= lex->length; lex->length= (char*)0;
+ }
| DECIMAL_SYM float_options
{ $$=ITEM_CAST_DECIMAL; Lex->charset= NULL; }
- ;
+ | DOUBLE_SYM
+ { Lex->charset= NULL; Lex->length= Lex->dec= 0;}
+ opt_precision
+ { $$=ITEM_CAST_DOUBLE; }
opt_expr_list:
/* empty */ { $$= NULL; }
@@ -9513,6 +9718,12 @@ delete_limit_clause:
}
;
+int_num:
+ NUM { int error; $$= (int) my_strtoll10($1.str, (char**) 0, &error); }
+ | '-' NUM { int error; $$= -(int) my_strtoll10($2.str, (char**) 0, &error); }
+ | '-' LONG_NUM { int error; $$= -(int) my_strtoll10($2.str, (char**) 0, &error); }
+ ;
+
ulong_num:
NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
| HEX_NUM { $$= (ulong) strtol($1.str, (char**) 0, 16); }
@@ -10826,8 +11037,8 @@ flush_option:
table_or_tables
{ Lex->type|= REFRESH_TABLES; }
opt_table_list {}
- | TABLES WITH READ_SYM LOCK_SYM
- { Lex->type|= REFRESH_TABLES | REFRESH_READ_LOCK; }
+ | TABLES WITH READ_SYM LOCK_SYM optional_flush_tables_arguments
+ { Lex->type|= REFRESH_TABLES | REFRESH_READ_LOCK | $5; }
| QUERY_SYM CACHE_SYM
{ Lex->type|= REFRESH_QUERY_CACHE_FREE; }
| HOSTS_SYM
@@ -10863,6 +11074,10 @@ opt_table_list:
| table_list {}
;
+optional_flush_tables_arguments:
+ /* empty */ {$$= 0;}
+ | AND_SYM DISABLE_SYM CHECKPOINT_SYM {$$= REFRESH_CHECKPOINT; }
+
reset:
RESET_SYM
{
@@ -10916,19 +11131,41 @@ purge_option:
/* kill threads */
kill:
- KILL_SYM kill_option expr
+ KILL_SYM
{
LEX *lex=Lex;
lex->value_list.empty();
- lex->value_list.push_front($3);
+ lex->users_list.empty();
lex->sql_command= SQLCOM_KILL;
}
+ kill_type kill_option kill_expr
+ {
+ Lex->kill_signal= (killed_state) ($3 | $4);
+ }
;
+kill_type:
+ /* Empty */ { $$= (int) KILL_HARD_BIT; }
+ | HARD_SYM { $$= (int) KILL_HARD_BIT; }
+ | SOFT_SYM { $$= 0; }
+
kill_option:
- /* empty */ { Lex->type= 0; }
- | CONNECTION_SYM { Lex->type= 0; }
- | QUERY_SYM { Lex->type= ONLY_KILL_QUERY; }
+ /* empty */ { $$= (int) KILL_CONNECTION; }
+ | CONNECTION_SYM { $$= (int) KILL_CONNECTION; }
+ | QUERY_SYM { $$= (int) KILL_QUERY; }
+ ;
+
+kill_expr:
+ expr
+ {
+ Lex->value_list.push_front($$);
+ Lex->kill_type= KILL_TYPE_ID;
+ }
+ | USER user
+ {
+ Lex->users_list.push_back($2);
+ Lex->kill_type= KILL_TYPE_USER;
+ }
;
/* change database */
@@ -11901,7 +12138,14 @@ keyword:
| CACHE_SYM {}
| CHARSET {}
| CHECKSUM_SYM {}
+ | CHECKPOINT_SYM {}
| CLOSE_SYM {}
+ | COLUMN_ADD_SYM {}
+ | COLUMN_CREATE_SYM {}
+ | COLUMN_DELETE_SYM {}
+ | COLUMN_EXISTS_SYM {}
+ | COLUMN_GET_SYM {}
+ | COLUMN_LIST_SYM {}
| COMMENT_SYM {}
| COMMIT_SYM {}
| CONTAINS_SYM {}
@@ -12036,6 +12280,7 @@ keyword_sp:
| GRANTS {}
| GLOBAL_SYM {}
| HASH_SYM {}
+ | HARD_SYM {}
| HOSTS_SYM {}
| HOUR_SYM {}
| IDENTIFIED_SYM {}
@@ -12112,6 +12357,7 @@ keyword_sp:
| OLD_PASSWORD {}
| ONE_SHOT_SYM {}
| ONE_SYM {}
+ | ONLINE_SYM {}
| PACK_KEYS_SYM {}
| PAGE_SYM {}
| PARTIAL {}
@@ -12166,6 +12412,7 @@ keyword_sp:
| SHUTDOWN {}
| SLOW_SYM {}
| SNAPSHOT_SYM {}
+ | SOFT_SYM {}
| SOUNDS_SYM {}
| SOURCE_SYM {}
| SQL_CACHE_SYM {}
@@ -13236,7 +13483,7 @@ grant_option:
lex->mqh.conn_per_hour= $2;
lex->mqh.specified_limits|= USER_RESOURCES::CONNECTIONS_PER_HOUR;
}
- | MAX_USER_CONNECTIONS_SYM ulong_num
+ | MAX_USER_CONNECTIONS_SYM int_num
{
LEX *lex=Lex;
lex->mqh.user_conn= $2;
@@ -13568,7 +13815,7 @@ view_replace:
view_algorithm:
ALGORITHM_SYM EQ UNDEFINED_SYM
- { Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
+ { Lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED; }
| ALGORITHM_SYM EQ MERGE_SYM
{ Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; }
| ALGORITHM_SYM EQ TEMPTABLE_SYM
diff --git a/sql/structs.h b/sql/structs.h
index ee6a2ffdcfd..c2bdf6db747 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -56,7 +56,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
@@ -78,7 +79,6 @@ typedef struct st_key {
uint key_length; /* Tot length of key */
ulong flags; /* dupp key and pack flags */
uint key_parts; /* How many key_parts */
- uint extra_length;
uint usable_key_parts; /* Should normally be = key_parts */
uint block_size;
uint name_length;
@@ -130,6 +130,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);
@@ -137,7 +152,7 @@ struct READ_RECORD { /* Parameter to read_record */
typedef int (*Read_func)(READ_RECORD*);
typedef void (*Unlock_row_func)(st_join_table *);
struct st_table *table; /* Head-form */
- handler *file;
+ // handler *file_;
struct st_table **forms; /* head and ref forms */
Read_func read_record;
@@ -153,6 +168,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;
};
@@ -204,8 +225,11 @@ typedef struct user_resources {
uint updates;
/* Maximum number of connections established per hour. */
uint conn_per_hour;
- /* Maximum number of concurrent connections. */
- uint user_conn;
+ /*
+ Maximum number of concurrent connections. If -1 then no new
+ connections allowed
+ */
+ int user_conn;
/*
Values of this enum and specified_limits member are used by the
parser to store which user limits were specified in GRANT statement.
@@ -238,7 +262,7 @@ typedef struct user_conn {
/* Total length of the key. */
uint len;
/* Current amount of concurrent connections for this account. */
- uint connections;
+ int connections;
/*
Current number of connections per hour, number of updating statements
per hour and total number of statements per hour for this account.
diff --git a/sql/table.cc b/sql/table.cc
index dfc9c2d933c..32549568086 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -24,6 +24,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")};
@@ -776,8 +778,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
share->db_record_offset= 1;
if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
share->blob_ptr_size= portable_sizeof_char_ptr;
- /* Set temporarily a good value for db_low_byte_first */
- share->db_low_byte_first= test(legacy_db_type != DB_TYPE_ISAM);
error=4;
share->max_rows= uint4korr(head+18);
share->min_rows= uint4korr(head+22);
@@ -1501,7 +1501,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
key_part->null_bit= field->null_bit;
key_part->store_length+=HA_KEY_NULL_LENGTH;
keyinfo->flags|=HA_NULL_PART_KEY;
- keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
}
if (field->type() == MYSQL_TYPE_BLOB ||
@@ -1513,7 +1512,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
key_part->key_part_flag|= HA_BLOB_PART;
else
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
- keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
key_part->store_length+=HA_KEY_BLOB_LENGTH;
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
}
@@ -1586,19 +1584,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;
/*
@@ -1713,7 +1703,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
share->can_cmp_whole_record= (share->blob_fields == 0 &&
share->varchar_fields == 0);
- share->db_low_byte_first= handler_file->low_byte_first();
share->column_bitmap_size= bitmap_buffer_size(share->fields);
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
@@ -1860,7 +1849,9 @@ bool fix_vcol_expr(THD *thd,
save_use_only_table_context= thd->lex->use_only_table_context;
thd->lex->use_only_table_context= TRUE;
/* Fix fields referenced to by the virtual column function */
+ thd->lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VCOL_EXPR;
error= func_expr->fix_fields(thd, (Item**)0);
+ thd->lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_VCOL_EXPR;
/* Restore the original context*/
thd->lex->use_only_table_context= save_use_only_table_context;
context->table_list= save_table_list;
@@ -2014,9 +2005,14 @@ bool unpack_vcol_info_from_frm(THD *thd,
vcol_arena= table->expr_arena;
if (!vcol_arena)
{
- Query_arena expr_arena(mem_root, Query_arena::INITIALIZED);
+ /*
+ We need to use CONVENTIONAL_EXECUTION here to ensure that
+ any new items created by fix_fields() are not reverted.
+ */
+ Query_arena expr_arena(mem_root,
+ Query_arena::CONVENTIONAL_EXECUTION);
if (!(vcol_arena= (Query_arena *) alloc_root(mem_root,
- sizeof(Query_arena))))
+ sizeof(Query_arena))))
goto err;
*vcol_arena= expr_arena;
table->expr_arena= vcol_arena;
@@ -2256,31 +2252,36 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
/*
Process virtual columns, if any.
*/
- if (!(vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
- (uint) ((share->vfields+1)*
- sizeof(Field*)))))
- goto err;
-
- outparam->vfield= vfield_ptr;
-
- for (field_ptr= outparam->field; *field_ptr; field_ptr++)
+ if (!share->vfields)
+ outparam->vfield= NULL;
+ else
{
- if ((*field_ptr)->vcol_info)
+ if (!(vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
+ (uint) ((share->vfields+1)*
+ sizeof(Field*)))))
+ goto err;
+
+ outparam->vfield= vfield_ptr;
+
+ for (field_ptr= outparam->field; *field_ptr; field_ptr++)
{
- if (unpack_vcol_info_from_frm(thd,
- &outparam->mem_root,
- outparam,
- *field_ptr,
- &(*field_ptr)->vcol_info->expr_str,
- &error_reported))
+ if ((*field_ptr)->vcol_info)
{
- error= 4; // in case no error is reported
- goto err;
+ if (unpack_vcol_info_from_frm(thd,
+ &outparam->mem_root,
+ outparam,
+ *field_ptr,
+ &(*field_ptr)->vcol_info->expr_str,
+ &error_reported))
+ {
+ error= 4; // in case no error is reported
+ goto err;
+ }
+ *(vfield_ptr++)= *field_ptr;
}
- *(vfield_ptr++)= *field_ptr;
}
+ *vfield_ptr= 0; // End marker
}
- *vfield_ptr= 0; // End marker
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (share->partition_info_len && outparam->file)
@@ -2363,7 +2364,7 @@ partititon_err:
/* Allocate bitmaps */
bitmap_size= share->column_bitmap_size;
- if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*4)))
+ if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*5)))
goto err;
bitmap_init(&outparam->def_read_set,
(my_bitmap_map*) bitmaps, share->fields, FALSE);
@@ -2373,6 +2374,8 @@ partititon_err:
(my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, FALSE);
bitmap_init(&outparam->tmp_set,
(my_bitmap_map*) (bitmaps+bitmap_size*3), share->fields, FALSE);
+ bitmap_init(&outparam->eq_join_set,
+ (my_bitmap_map*) (bitmaps+bitmap_size*4), share->fields, FALSE);
outparam->default_column_bitmaps();
/* The table struct is now initialized; Open the table */
@@ -2474,7 +2477,7 @@ int closefrm(register TABLE *table, bool free_share)
{
if (table->s->deleting)
table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
- error=table->file->close();
+ error=table->file->ha_close();
}
table->alias.free();
if (table->expr_arena)
@@ -2957,7 +2960,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)
@@ -3198,6 +3201,9 @@ bool check_db_name(LEX_STRING *org_name)
if (lower_case_table_names && name != any_db)
my_casedn_str(files_charset_info, name);
+ if (db_name_is_in_ignore_db_dirs_list(name))
+ return 1;
+
return check_table_name(name, name_length, check_for_path_chars);
}
@@ -3527,129 +3533,126 @@ void TABLE_LIST::calc_md5(char *buffer)
/**
- @brief Set underlying table for table place holder of view.
-
- @details
-
- Replace all views that only use one table with the table itself. This
- allows us to treat the view as a simple table and even update it (it is a
- kind of optimization).
+ @brief
+ Create field translation for mergeable derived table/view.
- @note
+ @param thd Thread handle
- This optimization is potentially dangerous as it makes views
- masquerade as base tables: Views don't have the pointer TABLE_LIST::table
- set to non-@c NULL.
+ @details
+ Create field translation for mergeable derived table/view.
- We may have the case where a view accesses tables not normally accessible
- in the current Security_context (only in the definer's
- Security_context). According to the table's GRANT_INFO (TABLE::grant),
- access is fulfilled, but this is implicitly meant in the definer's security
- context. Hence we must never look at only a TABLE's GRANT_INFO without
- looking at the one of the referring TABLE_LIST.
+ @return FALSE ok.
+ @return TRUE an error occur.
*/
-void TABLE_LIST::set_underlying_merge()
+bool TABLE_LIST::create_field_translation(THD *thd)
{
- TABLE_LIST *tbl;
+ Item *item;
+ Field_translator *transl;
+ SELECT_LEX *select= get_single_select();
+ List_iterator_fast<Item> it(select->item_list);
+ uint field_count= 0;
+ Query_arena *arena= thd->stmt_arena, backup;
+ bool res= FALSE;
+
+ if (thd->stmt_arena->is_conventional() ||
+ thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
+ {
+ /* initialize lists */
+ used_items.empty();
+ persistent_used_items.empty();
+ }
+ else
+ {
+ /*
+ Copy the list created by natural join procedure because the procedure
+ will not be repeated.
+ */
+ used_items= persistent_used_items;
+ }
- if ((tbl= merge_underlying_list))
+ if (field_translation)
{
- /* This is a view. Process all tables of view */
- DBUG_ASSERT(view && effective_algorithm == VIEW_ALGORITHM_MERGE);
- do
+ /*
+ Update items in the field translation aftet view have been prepared.
+ It's needed because some items in the select list, like IN subselects,
+ might be substituted for optimized ones.
+ */
+ if (is_view() && get_unit()->prepared && !field_translation_updated)
{
- if (tbl->merge_underlying_list) // This is a view
+ while ((item= it++))
{
- DBUG_ASSERT(tbl->view &&
- tbl->effective_algorithm == VIEW_ALGORITHM_MERGE);
- /*
- This is the only case where set_ancestor is called on an object
- that may not be a view (in which case ancestor is 0)
- */
- tbl->merge_underlying_list->set_underlying_merge();
+ field_translation[field_count++].item= item;
}
- } while ((tbl= tbl->next_local));
-
- if (!multitable_view)
- {
- table= merge_underlying_list->table;
- schema_table= merge_underlying_list->schema_table;
+ field_translation_updated= TRUE;
}
+
+ return FALSE;
}
+
+ if (arena->is_conventional())
+ arena= 0; // For easier test
+ else
+ thd->set_n_backup_active_arena(arena, &backup);
+
+ /* Create view fields translation table */
+
+ if (!(transl=
+ (Field_translator*)(thd->stmt_arena->
+ alloc(select->item_list.elements *
+ sizeof(Field_translator)))))
+ {
+ res= TRUE;
+ goto exit;
+ }
+
+ while ((item= it++))
+ {
+ transl[field_count].name= item->name;
+ transl[field_count++].item= item;
+ }
+ field_translation= transl;
+ field_translation_end= transl + field_count;
+
+exit:
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+
+ return res;
}
-/*
- setup fields of placeholder of merged VIEW
+/**
+ @brief
+ Create field translation for mergeable derived table/view.
- SYNOPSIS
- TABLE_LIST::setup_underlying()
- thd - thread handler
+ @param thd Thread handle
- DESCRIPTION
- It is:
- - preparing translation table for view columns
- If there are underlying view(s) procedure first will be called for them.
+ @details
+ Create field translation for mergeable derived table/view.
- RETURN
- FALSE - OK
- TRUE - error
+ @return FALSE ok.
+ @return TRUE an error occur.
*/
bool TABLE_LIST::setup_underlying(THD *thd)
{
DBUG_ENTER("TABLE_LIST::setup_underlying");
- if (!field_translation && merge_underlying_list)
+ if (!view || (!field_translation && merge_underlying_list))
{
- Field_translator *transl;
- SELECT_LEX *select= &view->select_lex;
- Item *item;
- TABLE_LIST *tbl;
- List_iterator_fast<Item> it(select->item_list);
- uint field_count= 0;
-
- if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*) &field_count))
- {
- DBUG_RETURN(TRUE);
- }
-
- for (tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
- {
- if (tbl->merge_underlying_list &&
- tbl->setup_underlying(thd))
- {
- DBUG_RETURN(TRUE);
- }
- }
-
- /* Create view fields translation table */
-
- if (!(transl=
- (Field_translator*)(thd->stmt_arena->
- alloc(select->item_list.elements *
- sizeof(Field_translator)))))
- {
+ SELECT_LEX *select= get_single_select();
+
+ if (create_field_translation(thd))
DBUG_RETURN(TRUE);
- }
-
- while ((item= it++))
- {
- transl[field_count].name= item->name;
- transl[field_count++].item= item;
- }
- field_translation= transl;
- field_translation_end= transl + field_count;
- /* TODO: use hash for big number of fields */
/* full text function moving to current select */
- if (view->select_lex.ftfunc_list->elements)
+ if (select->ftfunc_list->elements)
{
Item_func_match *ifm;
SELECT_LEX *current_select= thd->lex->current_select;
List_iterator_fast<Item_func_match>
- li(*(view->select_lex.ftfunc_list));
+ li(*(select_lex->ftfunc_list));
while ((ifm= li++))
current_select->ftfunc_list->push_front(ifm);
}
@@ -3659,7 +3662,7 @@ bool TABLE_LIST::setup_underlying(THD *thd)
/*
- Prepare where expression of view
+ Prepare where expression of derived table/view
SYNOPSIS
TABLE_LIST::prep_where()
@@ -3683,7 +3686,8 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds,
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
{
- if (tbl->view && tbl->prep_where(thd, conds, no_where_clause))
+ if (tbl->is_view_or_derived() &&
+ tbl->prep_where(thd, conds, no_where_clause))
{
DBUG_RETURN(TRUE);
}
@@ -3691,6 +3695,8 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds,
if (where)
{
+ if (where->fixed)
+ where->update_used_tables();
if (!where->fixed && where->fix_fields(thd, &where))
{
DBUG_RETURN(TRUE);
@@ -3723,7 +3729,13 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds,
}
}
if (tbl == 0)
+ {
+ if (*conds && !(*conds)->fixed)
+ (*conds)->fix_fields(thd, conds);
*conds= and_conds(*conds, where->copy_andor_structure(thd));
+ if (*conds && !(*conds)->fixed)
+ (*conds)->fix_fields(thd, conds);
+ }
if (arena)
thd->restore_active_arena(arena, &backup);
where_processed= TRUE;
@@ -3784,10 +3796,11 @@ merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
DBUG_PRINT("info", ("alias: %s", table->alias));
if (table->on_expr)
cond= table->on_expr->copy_andor_structure(thd);
- if (!table->nested_join)
+ if (!table->view)
DBUG_RETURN(cond);
- List_iterator<TABLE_LIST> li(table->nested_join->join_list);
- while (TABLE_LIST *tbl= li++)
+ for (TABLE_LIST *tbl= (TABLE_LIST*)table->view->select_lex.table_list.first;
+ tbl;
+ tbl= tbl->next_local)
{
if (tbl->view && !is_cascaded)
continue;
@@ -3827,7 +3840,7 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
{
DBUG_ENTER("TABLE_LIST::prep_check_option");
bool is_cascaded= check_opt_type == VIEW_CHECK_CASCADED;
-
+ TABLE_LIST *merge_underlying_list= view->select_lex.get_table_list();
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
{
/* see comment of check_opt_type parameter */
@@ -3844,7 +3857,6 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
if (where)
{
- DBUG_ASSERT(where->fixed);
check_option= where->copy_andor_structure(thd);
}
if (is_cascaded)
@@ -3940,10 +3952,14 @@ void TABLE_LIST::hide_view_error(THD *thd)
TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find)
{
/* is this real table and table which we are looking for? */
- if (table == table_to_find && merge_underlying_list == 0)
+ if (table == table_to_find && view == 0)
return this;
+ if (!view)
+ return 0;
- for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
+ for (TABLE_LIST *tbl= view->select_lex.get_table_list();
+ tbl;
+ tbl= tbl->next_local)
{
TABLE_LIST *result;
if ((result= tbl->find_underlying_table(table_to_find)))
@@ -4025,9 +4041,21 @@ bool TABLE_LIST::check_single_table(TABLE_LIST **table_arg,
table_map map,
TABLE_LIST *view_arg)
{
- for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
+ if (!select_lex)
+ return FALSE;
+ DBUG_ASSERT(is_merged_derived());
+ for (TABLE_LIST *tbl= get_single_select()->get_table_list();
+ tbl;
+ tbl= tbl->next_local)
{
- if (tbl->table)
+ /*
+ Merged view has also temporary table attached (in 5.2 if it has table
+ then it was real table), so we have filter such temporary tables out
+ by checking that it is not merged view
+ */
+ if (tbl->table &&
+ !(tbl->is_view() &&
+ tbl->is_merged_derived()))
{
if (tbl->table->map & map)
{
@@ -4067,8 +4095,10 @@ bool TABLE_LIST::set_insert_values(MEM_ROOT *mem_root)
}
else
{
- DBUG_ASSERT(view && merge_underlying_list);
- for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
+ DBUG_ASSERT(is_view_or_derived() && is_merged_derived());
+ for (TABLE_LIST *tbl= (TABLE_LIST*)view->select_lex.table_list.first;
+ tbl;
+ tbl= tbl->next_local)
if (tbl->set_insert_values(mem_root))
return TRUE;
}
@@ -4094,7 +4124,7 @@ bool TABLE_LIST::set_insert_values(MEM_ROOT *mem_root)
*/
bool TABLE_LIST::is_leaf_for_name_resolution()
{
- return (view || is_natural_join || is_join_columns_complete ||
+ return (is_merged_derived() || is_natural_join || is_join_columns_complete ||
!nested_join);
}
@@ -4232,7 +4262,11 @@ void TABLE_LIST::register_want_access(ulong want_access)
if (table)
table->grant.want_privilege= want_access;
}
- for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
+ if (!view)
+ return;
+ for (TABLE_LIST *tbl= view->select_lex.get_table_list();
+ tbl;
+ tbl= tbl->next_local)
tbl->register_want_access(want_access);
}
@@ -4384,6 +4418,81 @@ bool TABLE_LIST::prepare_security(THD *thd)
DBUG_RETURN(FALSE);
}
+#ifndef DBUG_OFF
+void TABLE_LIST::set_check_merged()
+{
+ DBUG_ASSERT(derived);
+ /*
+ It is not simple to check all, but at least this should be checked:
+ this select is not excluded or the exclusion came from above.
+ */
+ DBUG_ASSERT(!derived->first_select()->exclude_from_table_unique_test ||
+ derived->outer_select()->
+ exclude_from_table_unique_test);
+}
+#endif
+
+void TABLE_LIST::set_check_materialized()
+{
+ DBUG_ASSERT(derived);
+ if (!derived->first_select()->exclude_from_table_unique_test)
+ derived->set_unique_exclude();
+ else
+ {
+ /*
+ The subtree should be already excluded
+ */
+ DBUG_ASSERT(!derived->first_select()->first_inner_unit() ||
+ derived->first_select()->first_inner_unit()->first_select()->
+ exclude_from_table_unique_test);
+ }
+}
+
+TABLE *TABLE_LIST::get_real_join_table()
+{
+ TABLE_LIST *tbl= this;
+ while (tbl->table == NULL || tbl->table->reginfo.join_tab == NULL)
+ {
+ if (tbl->view == NULL && tbl->derived == NULL)
+ break;
+ /* we do not support merging of union yet */
+ DBUG_ASSERT(tbl->view == NULL ||
+ tbl->view->select_lex.next_select() == NULL);
+ DBUG_ASSERT(tbl->derived == NULL ||
+ tbl->derived->first_select()->next_select() == NULL);
+
+ {
+ List_iterator_fast<TABLE_LIST> ti;
+ {
+ List_iterator_fast<TABLE_LIST>
+ ti(tbl->view != NULL ?
+ tbl->view->select_lex.top_join_list :
+ tbl->derived->first_select()->top_join_list);
+ for (;;)
+ {
+ tbl= NULL;
+ /*
+ Find left table in outer join on this level
+ (the list is reverted).
+ */
+ for (TABLE_LIST *t= ti++; t; t= ti++)
+ tbl= t;
+ /*
+ It is impossible that the list is empty
+ so tbl can't be NULL after above loop.
+ */
+ if (!tbl->nested_join)
+ break;
+ /* go deeper if we've found nested join */
+ ti= tbl->nested_join->join_list;
+ }
+ }
+ }
+ }
+
+ return tbl->table;
+}
+
Natural_join_column::Natural_join_column(Field_translator *field_param,
TABLE_LIST *tab)
@@ -4462,14 +4571,23 @@ const char *Natural_join_column::db_name()
DBUG_ASSERT(!strcmp(table_ref->db,
table_ref->table->s->db.str) ||
(table_ref->schema_table &&
- table_ref->table->s->db.str[0] == 0));
+ table_ref->table->s->db.str[0] == 0) ||
+ table_ref->is_materialized_derived());
return table_ref->db;
}
GRANT_INFO *Natural_join_column::grant()
{
- if (view_field)
+/* if (view_field)
+ return &(table_ref->grant);
+ return &(table_ref->table->grant);*/
+ /*
+ Have to check algorithm because merged derived also has
+ field_translation.
+ */
+//if (table_ref->effective_algorithm == DTYPE_ALGORITHM_MERGE)
+ if (table_ref->is_merged_derived())
return &(table_ref->grant);
return &(table_ref->table->grant);
}
@@ -4551,7 +4669,17 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
{
DBUG_RETURN(field);
}
- Item *item= new Item_direct_view_ref(view, field_ref, name);
+ Item *item= new Item_direct_view_ref(&view->view->select_lex.context,
+ field_ref, view->alias,
+ name, view);
+ /*
+ Force creation of nullable item for the result tmp table for outer joined
+ views/derived tables.
+ */
+ if (view->table && view->table->maybe_null)
+ item->maybe_null= TRUE;
+ /* Save item in case we will need to fall back to materialization. */
+ view->used_items.push_front(item);
DBUG_RETURN(item);
}
@@ -4605,8 +4733,7 @@ void Field_iterator_table_ref::set_field_iterator()
/* This is a merge view, so use field_translation. */
else if (table_ref->field_translation)
{
- DBUG_ASSERT(table_ref->view &&
- table_ref->effective_algorithm == VIEW_ALGORITHM_MERGE);
+ DBUG_ASSERT(table_ref->is_merged_derived());
field_it= &view_field_it;
DBUG_PRINT("info", ("field_it for '%s' is Field_iterator_view",
table_ref->alias));
@@ -5198,6 +5325,9 @@ void st_table::mark_virtual_columns_for_write(bool insert_fl)
if (!vfield)
return;
+ if (!vfield)
+ return;
+
for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
{
tmp_vfield= *vfield_ptr;
@@ -5231,6 +5361,175 @@ void st_table::mark_virtual_columns_for_write(bool insert_fl)
file->column_bitmaps_signal();
}
+
+/**
+ @brief
+ Allocate space for keys
+
+ @param key_count number of keys to allocate additionally
+
+ @details
+ The function allocates memory to fit additionally 'key_count' keys
+ for this table.
+
+ @return FALSE space was successfully allocated
+ @return TRUE an error occur
+*/
+
+bool TABLE::alloc_keys(uint key_count)
+{
+ key_info= (KEY*) alloc_root(&mem_root, sizeof(KEY)*(s->keys+key_count));
+ if (s->keys)
+ memmove(key_info, s->key_info, sizeof(KEY)*s->keys);
+ s->key_info= key_info;
+ max_keys= s->keys+key_count;
+ return !(key_info);
+}
+
+
+void TABLE::create_key_part_by_field(KEY *keyinfo,
+ KEY_PART_INFO *key_part_info,
+ Field *field, uint fieldnr)
+{
+ field->flags|= PART_KEY_FLAG;
+ key_part_info->null_bit= field->null_bit;
+ key_part_info->null_offset= (uint) (field->null_ptr -
+ (uchar*) record[0]);
+ key_part_info->field= field;
+ key_part_info->fieldnr= fieldnr;
+ key_part_info->offset= field->offset(record[0]);
+ key_part_info->length= (uint16) field->pack_length();
+ keyinfo->key_length+= key_part_info->length;
+ 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 (field->real_maybe_null())
+ {
+ key_part_info->store_length+= HA_KEY_NULL_LENGTH;
+ keyinfo->key_length+= HA_KEY_NULL_LENGTH;
+ }
+ if (field->type() == MYSQL_TYPE_BLOB ||
+ 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->key_part_flag|=
+ field->type() == MYSQL_TYPE_BLOB ? HA_BLOB_PART: HA_VAR_LENGTH_PART;
+ }
+
+ key_part_info->type= (uint8) 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;
+}
+
+
+/**
+ @brief
+ Add one 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 TRUE <=> it is a unique index
+
+ @details
+ The function adds a new key to the table that is assumed to be a temporary
+ table. At each its invocation the call-back function must return
+ the number of the field that is used as the 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++)
+ {
+ uint fld_idx= next_field_no(arg);
+ reg_field= field + fld_idx;
+ if (key_start)
+ (*reg_field)->key_start.set_bit(key);
+ (*reg_field)->part_of_key.set_bit(key);
+ create_key_part_by_field(keyinfo, key_part_info, *reg_field, fld_idx+1);
+ key_start= FALSE;
+ key_part_info++;
+ }
+
+ set_if_bigger(s->max_key_length, keyinfo->key_length);
+ s->keys++;
+ return FALSE;
+}
+
+/*
+ @brief
+ Drop all indexes except specified one.
+
+ @param key_to_save the key to save
+
+ @details
+ Drop all indexes on this table except 'key_to_save'. The saved key becomes
+ key #0. Memory occupied by key parts of dropped keys are freed.
+ If the 'key_to_save' is negative then all keys are freed.
+*/
+
+void TABLE::use_index(int key_to_save)
+{
+ uint i= 1;
+ DBUG_ASSERT(!created && key_to_save < (int)s->keys);
+ if (key_to_save >= 0)
+ /* Save the given key. */
+ memmove(key_info, key_info + key_to_save, sizeof(KEY));
+ else
+ /* Drop all keys; */
+ i= 0;
+
+ s->keys= i;
+}
+
/**
@brief Check if this is part of a MERGE table with attached children.
@@ -5249,6 +5548,21 @@ bool st_table::is_children_attached(void)
(parent && parent->children_attached));
}
+
+/*
+ Return TRUE if the table is filled at execution phase
+
+ (and so, the optimizer must not do anything that depends on the contents of
+ the table, like range analysis or constant table detection)
+*/
+
+bool st_table::is_filled_at_execution()
+{
+ return test(pos_in_table_list->jtbm_subselect ||
+ pos_in_table_list->is_active_sjm());
+}
+
+
/*
Cleanup this table for re-execution.
@@ -5279,6 +5593,7 @@ void TABLE_LIST::reinit_before_use(THD *thd)
parent_embedding->nested_join->join_list.head() == embedded);
}
+
/*
Return subselect that contains the FROM list this table is taken from
@@ -5527,8 +5842,7 @@ int update_virtual_fields(THD *thd, TABLE *table,
DBUG_ENTER("update_virtual_fields");
Field **vfield_ptr, *vfield;
int error __attribute__ ((unused))= 0;
- if (!table || !table->vfield)
- DBUG_RETURN(0);
+ DBUG_ASSERT(table && table->vfield);
thd->reset_arena_for_cached_items(table->expr_arena);
/* Iterate over virtual fields in the table */
@@ -5553,6 +5867,305 @@ int update_virtual_fields(THD *thd, TABLE *table,
DBUG_RETURN(0);
}
+/*
+ @brief Reset const_table flag
+
+ @detail
+ Reset const_table flag for this table. If this table is a merged derived
+ table/view the flag is recursively reseted for all tables of the underlying
+ select.
+*/
+
+void TABLE_LIST::reset_const_table()
+{
+ table->const_table= 0;
+ if (is_merged_derived())
+ {
+ SELECT_LEX *select_lex= get_unit()->first_select();
+ TABLE_LIST *tl;
+ List_iterator<TABLE_LIST> ti(select_lex->leaf_tables);
+ while ((tl= ti++))
+ tl->reset_const_table();
+ }
+}
+
+
+/*
+ @brief Run derived tables/view handling phases on underlying select_lex.
+
+ @param lex LEX for this thread
+ @param phases derived tables/views handling phases to run
+ (set of DT_XXX constants)
+ @details
+ This function runs this derived table through specified 'phases'.
+ Underlying tables of this select are handled prior to this derived.
+ 'lex' is passed as an argument to called functions.
+
+ @return TRUE on error
+ @return FALSE ok
+*/
+
+bool TABLE_LIST::handle_derived(struct st_lex *lex, uint phases)
+{
+ SELECT_LEX_UNIT *unit= get_unit();
+ if (unit)
+ {
+ for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
+ if (sl->handle_derived(lex, phases))
+ return TRUE;
+ return mysql_handle_single_derived(lex, this, phases);
+ }
+ return FALSE;
+}
+
+
+/**
+ @brief
+ Return unit of this derived table/view
+
+ @return reference to a unit if it's a derived table/view.
+ @return 0 when it's not a derived table/view.
+*/
+
+st_select_lex_unit *TABLE_LIST::get_unit()
+{
+ return (view ? &view->unit : derived);
+}
+
+
+/**
+ @brief
+ Return select_lex of this derived table/view
+
+ @return select_lex of this derived table/view.
+ @return 0 when it's not a derived table.
+*/
+
+st_select_lex *TABLE_LIST::get_single_select()
+{
+ SELECT_LEX_UNIT *unit= get_unit();
+ return (unit ? unit->first_select() : 0);
+}
+
+
+/**
+ @brief
+ Attach a join table list as a nested join to this TABLE_LIST.
+
+ @param join_list join table list to attach
+
+ @details
+ This function wraps 'join_list' into a nested_join of this table, thus
+ turning it to a nested join leaf.
+*/
+
+void TABLE_LIST::wrap_into_nested_join(List<TABLE_LIST> &join_list)
+{
+ TABLE_LIST *tl;
+ /*
+ Walk through derived table top list and set 'embedding' to point to
+ the nesting table.
+ */
+ nested_join->join_list.empty();
+ List_iterator_fast<TABLE_LIST> li(join_list);
+ nested_join->join_list= join_list;
+ while ((tl= li++))
+ {
+ tl->embedding= this;
+ tl->join_list= &nested_join->join_list;
+ }
+}
+
+
+/**
+ @brief
+ Initialize this derived table/view
+
+ @param thd Thread handle
+
+ @details
+ This function makes initial preparations of this derived table/view for
+ further processing:
+ if it's a derived table this function marks it either as mergeable or
+ materializable
+ creates temporary table for name resolution purposes
+ creates field translation for mergeable derived table/view
+
+ @return TRUE an error occur
+ @return FALSE ok
+*/
+
+bool TABLE_LIST::init_derived(THD *thd, bool init_view)
+{
+ SELECT_LEX *first_select= get_single_select();
+ SELECT_LEX_UNIT *unit= get_unit();
+
+ if (!unit)
+ return FALSE;
+ /*
+ Check whether we can merge this derived table into main select.
+ Depending on the result field translation will or will not
+ be created.
+ */
+ TABLE_LIST *first_table= (TABLE_LIST *) first_select->table_list.first;
+ if (first_select->table_list.elements > 1 ||
+ (first_table && first_table->is_multitable()))
+ set_multitable();
+
+ unit->derived= this;
+ if (init_view && !view)
+ {
+ /* This is all what we can do for a derived table for now. */
+ set_derived();
+ }
+
+ if (!is_view())
+ {
+ /* A subquery might be forced to be materialized due to a side-effect. */
+ if (!is_materialized_derived() && first_select->is_mergeable() &&
+ optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_MERGE) &&
+ !(thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
+ thd->lex->sql_command == SQLCOM_DELETE_MULTI))
+ set_merged_derived();
+ else
+ set_materialized_derived();
+ }
+ /*
+ Derived tables/view are materialized prior to UPDATE, thus we can skip
+ them from table uniqueness check
+ */
+ if (is_materialized_derived())
+ {
+ set_check_materialized();
+ }
+
+ /*
+ Create field translation for mergeable derived tables/views.
+ For derived tables field translation can be created only after
+ unit is prepared so all '*' are get unrolled.
+ */
+ if (is_merged_derived())
+ {
+ if (is_view() || unit->prepared)
+ create_field_translation(thd);
+ }
+
+ return FALSE;
+}
+
+
+/**
+ @brief
+ Retrieve number of rows in the table
+
+ @details
+ Retrieve number of rows in the table referred by this TABLE_LIST and
+ store it in the table's stats.records variable. If this TABLE_LIST refers
+ to a materialized derived table/view then the estimated number of rows of
+ the derived table/view is used instead.
+
+ @return 0 ok
+ @return non zero error
+*/
+
+int TABLE_LIST::fetch_number_of_rows()
+{
+ int error= 0;
+ if (jtbm_subselect)
+ return 0;
+ if (is_materialized_derived() && !fill_me)
+
+ {
+ table->file->stats.records= ((select_union*)derived->result)->records;
+ set_if_bigger(table->file->stats.records, 2);
+ }
+ else
+ error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
+ return error;
+}
+
+/*
+ Procedure of keys generation for result tables of materialized derived
+ tables/views.
+
+ A key is generated for each equi-join pair derived table-another table.
+ Each generated key consists of fields of derived table used in equi-join.
+ Example:
+
+ SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
+ t1 ON tt.f1=t1.f3 and tt.f2.=t1.f4;
+ In this case for the derived table tt one key will be generated. It will
+ consist of two parts f1 and f2.
+ Example:
+
+ SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
+ t1 ON tt.f1=t1.f3 JOIN
+ t2 ON tt.f2=t2.f4;
+ In this case for the derived table tt two keys will be generated.
+ One key over f1 field, and another key over f2 field.
+ Currently optimizer may choose to use only one such key, thus the second
+ one will be dropped after range optimizer is finished.
+ See also JOIN::drop_unused_derived_keys function.
+ Example:
+
+ SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
+ t1 ON tt.f1=a_function(t1.f3);
+ In this case for the derived table tt one key will be generated. It will
+ consist of one field - f1.
+*/
+
+
+
+/*
+ @brief
+ Change references to underlying items of a merged derived table/view
+ for fields in derived table's result table.
+
+ @return FALSE ok
+ @return TRUE Out of memory
+*/
+bool TABLE_LIST::change_refs_to_fields()
+{
+ List_iterator<Item> li(used_items);
+ Item_direct_ref *ref;
+ Field_iterator_view field_it;
+ THD *thd= table->in_use;
+ DBUG_ASSERT(is_merged_derived());
+
+ if (!used_items.elements)
+ return FALSE;
+
+ materialized_items= (Item**)thd->calloc(sizeof(void*) * table->s->fields);
+
+ while ((ref= (Item_direct_ref*)li++))
+ {
+ uint idx;
+ Item *orig_item= *ref->ref;
+ field_it.set(this);
+ for (idx= 0; !field_it.end_of_fields(); field_it.next(), idx++)
+ {
+ if (field_it.item() == orig_item)
+ break;
+ }
+ DBUG_ASSERT(!field_it.end_of_fields());
+ if (!materialized_items[idx])
+ {
+ materialized_items[idx]= new Item_field(table->field[idx]);
+ if (!materialized_items[idx])
+ return TRUE;
+ }
+ /*
+ We need to restore the pointers after the execution of the
+ prepared statement.
+ */
+ thd->change_item_tree((Item **)&ref->ref,
+ (Item*)(materialized_items + idx));
+ }
+
+ return FALSE;
+}
+
+
/*****************************************************************************
** Instansiate templates
*****************************************************************************/
diff --git a/sql/table.h b/sql/table.h
index 80544ef3d89..d66a6a44753 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -66,7 +66,8 @@ typedef struct st_order {
bool counter_used; /* parameter was counter of columns */
Field *field; /* If tmp-table group */
char *buff; /* If tmp-table group */
- table_map used, depend_map;
+ table_map used; /* NOTE: the below is only set to 0 but is still used by eq_ref_table */
+ table_map depend_map;
} ORDER;
/**
@@ -167,13 +168,13 @@ typedef struct st_filesort_info
{
IO_CACHE *io_cache; /* If sorted through filesort */
uchar **sort_keys; /* Buffer for sorting keys */
- size_t sort_keys_size; /* Number of bytes allocated */
+ uint keys; /* Number of key pointers in buffer */
uchar *buffpek; /* Buffer for buffpek structures */
uint buffpek_len; /* Max number of buffpeks in the buffer */
uchar *addon_buf; /* Pointer to a buffer if sorted with fields */
size_t addon_length; /* Length of the buffer */
struct st_sort_addon_field *addon_field; /* Pointer to the fields info */
- void (*unpack)(struct st_sort_addon_field *, uchar *); /* To unpack back */
+ void (*unpack)(struct st_sort_addon_field *, uchar *, uchar *); /* To unpack back */
uchar *record_pointers; /* If sorted in memory */
ha_rows found_records; /* How many records in sort */
} FILESORT_INFO;
@@ -448,7 +449,6 @@ typedef struct st_table_share
bool null_field_first;
bool system; /* Set if system table (one record) */
bool crypted; /* If .frm file is crypted */
- bool db_low_byte_first; /* Portable row format */
bool crashed;
bool is_view;
bool name_lock, replace_with_name_lock;
@@ -673,6 +673,9 @@ enum index_hint_type
INDEX_HINT_FORCE
};
+#define CHECK_ROW_FOR_NULLS_TO_REJECT (1 << 0)
+#define REJECT_ROW_DUE_TO_NULL_FIELDS (1 << 1)
+
struct st_table {
st_table() {} /* Remove gcc warning */
@@ -701,7 +704,7 @@ struct st_table {
needed by the query without reading the row.
*/
key_map covering_keys;
- key_map quick_keys, merge_keys;
+ key_map quick_keys, merge_keys,intersect_keys;
/*
A set of keys that can be used in the query that references this
table.
@@ -733,6 +736,7 @@ struct st_table {
uchar *null_flags;
my_bitmap_map *bitmap_init_value;
MY_BITMAP def_read_set, def_write_set, def_vcol_set, tmp_set;
+ MY_BITMAP eq_join_set; /* used to mark equi-joined fields */
MY_BITMAP *read_set, *write_set, *vcol_set; /* Active column sets */
/*
The ID of the query that opened and is using this table. Has different
@@ -814,6 +818,26 @@ struct st_table {
NULL, including columns declared as "not null" (see maybe_null).
*/
bool null_row;
+ /*
+ No rows that contain null values can be placed into this table.
+ Currently this flag can be set to true only for a temporary table
+ that used to store the result of materialization of a subquery.
+ */
+ bool no_rows_with_nulls;
+ /*
+ This field can contain two bit flags:
+ CHECK_ROW_FOR_NULLS_TO_REJECT
+ REJECT_ROW_DUE_TO_NULL_FIELDS
+ The first flag is set for the dynamic contexts where it is prohibited
+ to write any null into the table.
+ The second flag is set only if the first flag is set on.
+ The informs the outer scope that there was an attept to write null
+ into a field of the table in the context where it is prohibited.
+ This flag should be set off as soon as the first flag is set on.
+ Currently these flags are used only the tables tno_rows_with_nulls set
+ to true.
+ */
+ uint8 null_catch_flags;
/*
TODO: Each of the following flags take up 8 bits. They can just as easily
@@ -833,7 +857,7 @@ struct st_table {
See TABLE_LIST::process_index_hints().
*/
bool force_index_group;
- bool distinct,const_table,no_rows;
+ bool distinct,const_table,no_rows, used_for_duplicate_elimination;
/**
If set, the optimizer has found that row retrieval should access index
@@ -873,8 +897,10 @@ struct st_table {
*/
bool auto_increment_field_not_null;
bool insert_or_update; /* Can be used by the handler */
- bool alias_name_used; /* true if table_name is alias */
+ bool alias_name_used; /* true if table_name is alias */
bool get_fields_in_item_tree; /* Signal to fix_field */
+ bool created; /* For tmp tables. TRUE <=> tmp table was actually created.*/
+
/* If MERGE children attached to parent. See top comment in ha_myisammrg.cc */
bool children_attached;
@@ -895,6 +921,7 @@ struct st_table {
bool no_partitions_used; /* If true, all partitions have been pruned away */
#endif
+ uint max_keys; /* Size of allocated key_info array. */
bool fill_item_list(List<Item> *item_list) const;
void reset_item_list(List<Item> *item_list) const;
void clear_column_bitmaps(void);
@@ -958,6 +985,18 @@ 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);
+ void create_key_part_by_field(KEY *keyinfo, KEY_PART_INFO *key_part_info,
+ Field *field, uint fieldnr);
+ void use_index(int key_to_save);
+ void set_table_map(table_map map_arg, uint tablenr_arg)
+ {
+ map= map_arg;
+ tablenr= tablenr_arg;
+ }
bool is_children_attached(void);
inline void enable_keyread()
{
@@ -967,6 +1006,12 @@ struct st_table {
file->extra(HA_EXTRA_KEYREAD);
DBUG_VOID_RETURN;
}
+ /*
+ Returns TRUE if the table is filled at execution phase (and so, the
+ optimizer must not do anything that depends on the contents of the table,
+ like range analysis or constant table detection)
+ */
+ bool is_filled_at_execution();
inline void disable_keyread()
{
DBUG_ENTER("disable_keyread");
@@ -1109,13 +1154,55 @@ typedef struct st_schema_table
} ST_SCHEMA_TABLE;
+/*
+ Types of derived tables. The ending part is a bitmap of phases that are
+ applicable to a derived table of the type.
+*/
+#define DTYPE_ALGORITHM_UNDEFINED 0
+#define DTYPE_VIEW 1
+#define DTYPE_TABLE 2
+#define DTYPE_MERGE 4
+#define DTYPE_MATERIALIZE 8
+#define DTYPE_MULTITABLE 16
+#define DTYPE_MASK 19
+
+/*
+ Phases of derived tables/views handling, see sql_derived.cc
+ Values are used as parts of a bitmap attached to derived table types.
+*/
+#define DT_INIT 1
+#define DT_PREPARE 2
+#define DT_OPTIMIZE 4
+#define DT_MERGE 8
+#define DT_MERGE_FOR_INSERT 16
+#define DT_CREATE 32
+#define DT_FILL 64
+#define DT_REINIT 128
+#define DT_PHASES 8
+/* Phases that are applicable to all derived tables. */
+#define DT_COMMON (DT_INIT + DT_PREPARE + DT_REINIT + DT_OPTIMIZE)
+/* Phases that are applicable only to materialized derived tables. */
+#define DT_MATERIALIZE (DT_CREATE + DT_FILL)
+
+#define DT_PHASES_MERGE (DT_COMMON | DT_MERGE | DT_MERGE_FOR_INSERT)
+#define DT_PHASES_MATERIALIZE (DT_COMMON | DT_MATERIALIZE)
+
+#define VIEW_ALGORITHM_UNDEFINED 0
+#define VIEW_ALGORITHM_MERGE (DTYPE_VIEW | DTYPE_MERGE)
+#define VIEW_ALGORITHM_TMPTABLE (DTYPE_VIEW | DTYPE_MATERIALIZE)
+
+/*
+ View algorithm values as stored in the FRM. Values differ from in-memory
+ representation for backward compatibility.
+*/
+
+#define VIEW_ALGORITHM_UNDEFINED_FRM 0
+#define VIEW_ALGORITHM_MERGE_FRM 1
+#define VIEW_ALGORITHM_TMPTABLE_FRM 2
+
#define JOIN_TYPE_LEFT 1
#define JOIN_TYPE_RIGHT 2
-#define VIEW_ALGORITHM_UNDEFINED 0
-#define VIEW_ALGORITHM_TMPTABLE 1
-#define VIEW_ALGORITHM_MERGE 2
-
#define VIEW_SUID_INVOKER 0
#define VIEW_SUID_DEFINER 1
#define VIEW_SUID_DEFAULT 2
@@ -1179,6 +1266,11 @@ public:
};
+class SJ_MATERIALIZATION_INFO;
+class Index_hint;
+class Item_in_subselect;
+
+
/*
Table reference in the FROM clause.
@@ -1190,7 +1282,7 @@ public:
1) table (TABLE_LIST::view == NULL)
- base table
(TABLE_LIST::derived == NULL)
- - subquery - TABLE_LIST::table is a temp table
+ - FROM-clause subquery - TABLE_LIST::table is a temp table
(TABLE_LIST::derived != NULL)
- information schema table
(TABLE_LIST::schema_table != NULL)
@@ -1200,6 +1292,7 @@ public:
also (TABLE_LIST::field_translation != NULL)
- tmptable (TABLE_LIST::effective_algorithm == VIEW_ALGORITHM_TMPTABLE)
also (TABLE_LIST::field_translation == NULL)
+ 2.5) TODO: Add derived tables description here
3) nested table reference (TABLE_LIST::nested_join != NULL)
- table sequence - e.g. (t1, t2, t3)
TODO: how to distinguish from a JOIN?
@@ -1209,9 +1302,12 @@ public:
(TABLE_LIST::natural_join != NULL)
- JOIN ... USING
(TABLE_LIST::join_using_fields != NULL)
+ - semi-join nest (sj_on_expr!= NULL && sj_subq_pred!=NULL)
+ 4) jtbm semi-join (jtbm_subselect != NULL)
*/
class Index_hint;
+struct st_lex;
struct TABLE_LIST
{
TABLE_LIST() {} /* Remove gcc warning */
@@ -1241,6 +1337,30 @@ 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;
+
+ /* If this is a non-jtbm semi-join nest: corresponding subselect predicate */
+ Item_in_subselect *sj_subq_pred;
+
+ table_map original_subq_pred_used_tables;
+
+ /* If this is a jtbm semi-join object: corresponding subselect predicate */
+ Item_in_subselect *jtbm_subselect;
+ /* TODO: check if this can be joined with tablenr_exec */
+ uint jtbm_table_no;
+
+ SJ_MATERIALIZATION_INFO *sj_mat_info;
+
/*
The structure of ON expression presented in the member above
can be changed during certain optimizations. This member
@@ -1291,6 +1411,28 @@ struct TABLE_LIST
filling procedure
*/
select_union *derived_result;
+ /* Stub used for materialized derived tables. */
+ table_map map; /* ID bit of table (1,2,4,8,16...) */
+ table_map get_map()
+ {
+ return jtbm_subselect? table_map(1) << jtbm_table_no : table->map;
+ }
+ uint get_tablenr()
+ {
+ return jtbm_subselect? jtbm_table_no : table->tablenr;
+ }
+ void set_tablenr(uint new_tablenr)
+ {
+ if (jtbm_subselect)
+ {
+ jtbm_table_no= new_tablenr;
+ }
+ if (table)
+ {
+ table->tablenr= new_tablenr;
+ table->map= table_map(1) << new_tablenr;
+ }
+ }
/*
Reference from aux_tables to local list entry of main select of
multi-delete statement:
@@ -1335,6 +1477,7 @@ struct TABLE_LIST
Field_translator *field_translation; /* array of VIEW fields */
/* pointer to element after last one in translation table above */
Field_translator *field_translation_end;
+ bool field_translation_updated;
/*
List (based on next_local) of underlying tables of this view. I.e. it
does not include the tables of subqueries used in the view. Is set only
@@ -1349,11 +1492,20 @@ struct TABLE_LIST
List<TABLE_LIST> *view_tables;
/* most upper view this table belongs to */
TABLE_LIST *belong_to_view;
+ /* A derived table this table belongs to */
+ TABLE_LIST *belong_to_derived;
/*
The view directly referencing this table
(non-zero only for merged underlying tables of a view).
*/
TABLE_LIST *referencing_view;
+
+ table_map view_used_tables;
+ table_map map_exec;
+ /* TODO: check if this can be joined with jtbm_table_no */
+ uint tablenr_exec;
+ uint maybe_null_exec;
+
/* Ptr to parent MERGE table list item. See top comment in ha_myisammrg.cc */
TABLE_LIST *parent_l;
/*
@@ -1366,13 +1518,7 @@ struct TABLE_LIST
SQL SECURITY DEFINER)
*/
Security_context *view_sctx;
- /*
- List of all base tables local to a subquery including all view
- tables. Unlike 'next_local', this in this list views are *not*
- leaves. Created in setup_tables() -> make_leaves_list().
- */
bool allowed_show;
- TABLE_LIST *next_leaf;
Item *where; /* VIEW WHERE clause condition */
Item *check_option; /* WITH CHECK OPTION condition */
LEX_STRING select_stmt; /* text of (CREATE/SELECT) statement */
@@ -1408,7 +1554,7 @@ struct TABLE_LIST
- VIEW_ALGORITHM_MERGE
@to do Replace with an enum
*/
- uint8 effective_algorithm;
+ uint8 derived_type;
GRANT_INFO grant;
/* data need by some engines in query cache*/
ulonglong engine_data;
@@ -1435,7 +1581,6 @@ struct TABLE_LIST
bool skip_temporary; /* this table shouldn't be temporary */
/* TRUE if this merged view contain auto_increment field */
bool contain_auto_increment;
- bool multitable_view; /* TRUE iff this is multitable view */
bool compact_view_format; /* Use compact format for SHOW CREATE VIEW */
/* view where processed */
bool where_processed;
@@ -1459,6 +1604,24 @@ struct TABLE_LIST
bool internal_tmp_table;
bool deleting; /* going to delete this table */
+ /* TRUE <=> derived table should be filled right after optimization. */
+ bool fill_me;
+ /* TRUE <=> view/DT is merged. */
+ /* TODO: replace with derived_type */
+ bool merged;
+ bool merged_for_insert;
+ /* TRUE <=> don't prepare this derived table/view as it should be merged.*/
+ bool skip_prepare_derived;
+
+ /*
+ Items created by create_view_field and collected to change them in case
+ of materialization of the view/derived table
+ */
+ List<Item> used_items;
+ /* Sublist (tail) of persistent used_items */
+ List<Item> persistent_used_items;
+ Item **materialized_items;
+
/* View creation context. */
View_creation_ctx *view_creation_ctx;
@@ -1496,9 +1659,10 @@ struct TABLE_LIST
bool has_table_lookup_value;
uint table_open_method;
enum enum_schema_table_state schema_table_state;
+
void calc_md5(char *buffer);
- void set_underlying_merge();
int view_check_option(THD *thd, bool ignore_failure);
+ bool create_field_translation(THD *thd);
bool setup_underlying(THD *thd);
void cleanup_items();
bool placeholder()
@@ -1515,6 +1679,7 @@ struct TABLE_LIST
TABLE_LIST *find_underlying_table(TABLE *table);
TABLE_LIST *first_leaf_for_name_resolution();
TABLE_LIST *last_leaf_for_name_resolution();
+ TABLE *get_real_join_table();
bool is_leaf_for_name_resolution();
inline TABLE_LIST *top_table()
{ return belong_to_view ? belong_to_view : this; }
@@ -1528,7 +1693,7 @@ struct TABLE_LIST
inline bool prepare_where(THD *thd, Item **conds,
bool no_where_clause)
{
- if (effective_algorithm == VIEW_ALGORITHM_MERGE)
+ if (!view || is_merged_derived())
return prep_where(thd, conds, no_where_clause);
return FALSE;
}
@@ -1594,6 +1759,62 @@ struct TABLE_LIST
m_table_ref_version= s->get_table_ref_version();
}
+ /* Set of functions returning/setting state of a derived table/view. */
+ inline bool is_non_derived()
+ {
+ return (!derived_type);
+ }
+ inline bool is_view_or_derived()
+ {
+ return (derived_type);
+ }
+ inline bool is_view()
+ {
+ return (derived_type & DTYPE_VIEW);
+ }
+ inline bool is_derived()
+ {
+ return (derived_type & DTYPE_TABLE);
+ }
+ inline void set_view()
+ {
+ derived_type= DTYPE_VIEW;
+ }
+ inline void set_derived()
+ {
+ derived_type= DTYPE_TABLE;
+ }
+ inline bool is_merged_derived()
+ {
+ return (derived_type & DTYPE_MERGE);
+ }
+ inline void set_merged_derived()
+ {
+ derived_type= ((derived_type & DTYPE_MASK) |
+ DTYPE_TABLE | DTYPE_MERGE);
+ set_check_merged();
+ }
+ inline bool is_materialized_derived()
+ {
+ return (derived_type & DTYPE_MATERIALIZE);
+ }
+ void set_materialized_derived()
+ {
+ derived_type= ((derived_type & DTYPE_MASK) |
+ DTYPE_TABLE | DTYPE_MATERIALIZE);
+ set_check_materialized();
+ }
+ inline bool is_multitable()
+ {
+ return (derived_type & DTYPE_MULTITABLE);
+ }
+ inline void set_multitable()
+ {
+ derived_type|= DTYPE_MULTITABLE;
+ }
+ void reset_const_table();
+ bool handle_derived(struct st_lex *lex, uint phases);
+
/**
@brief True if this TABLE_LIST represents an anonymous derived table,
i.e. the result of a subquery.
@@ -1613,13 +1834,26 @@ struct TABLE_LIST
respectively.
*/
char *get_table_name() { return view != NULL ? view_name.str : table_name; }
-
+ bool is_active_sjm();
+ bool is_jtbm() { return test(jtbm_subselect!=NULL); }
+ st_select_lex_unit *get_unit();
+ st_select_lex *get_single_select();
+ void wrap_into_nested_join(List<TABLE_LIST> &join_list);
+ bool init_derived(THD *thd, bool init_view);
+ int fetch_number_of_rows();
+ bool change_refs_to_fields();
bool single_table_updatable();
private:
bool prep_check_option(THD *thd, uint8 check_opt_type);
bool prep_where(THD *thd, Item **conds, bool no_where_clause);
+ void set_check_materialized();
+#ifndef DBUG_OFF
+ void set_check_merged();
+#else
+ inline void set_check_merged() {}
+#endif
/*
Cleanup for re-execution in a prepared statement or a stored
procedure.
@@ -1784,6 +2018,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/time.cc b/sql/time.cc
index ebbb5d4c583..3b1613282fb 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -1,5 +1,6 @@
/*
Copyright (c) 2000-2007 MySQL AB, 2009 Sun Microsystems, Inc.
+ Copyright (c) 2009-2013 Monty Program Ab
Use is subject to license terms.
This program is free software; you can redistribute it and/or modify
@@ -23,9 +24,9 @@
#include <m_ctype.h>
- /* Some functions to calculate dates */
+#define MAX_DAY_NUMBER 3652424L
-#ifndef TESTTIME
+ /* Some functions to calculate dates */
/*
Name description of interval names used in statements.
@@ -145,46 +146,42 @@ uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year)
/* Change a daynr to year, month and day */
/* Daynr 0 is returned as date 00.00.00 */
-void get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month,
+bool get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month,
uint *ret_day)
{
uint year,temp,leap_day,day_of_year,days_in_year;
uchar *month_pos;
DBUG_ENTER("get_date_from_daynr");
- if (daynr <= 365L || daynr >= 3652500)
- { /* Fix if wrong daynr */
- *ret_year= *ret_month = *ret_day =0;
+ if (daynr < 366 || daynr > MAX_DAY_NUMBER)
+ DBUG_RETURN(1);
+
+ year= (uint) (daynr*100 / 36525L);
+ temp=(((year-1)/100+1)*3)/4;
+ day_of_year=(uint) (daynr - (long) year * 365L) - (year-1)/4 +temp;
+ while (day_of_year > (days_in_year= calc_days_in_year(year)))
+ {
+ day_of_year-=days_in_year;
+ (year)++;
}
- else
+ leap_day=0;
+ if (days_in_year == 366)
{
- year= (uint) (daynr*100 / 36525L);
- temp=(((year-1)/100+1)*3)/4;
- day_of_year=(uint) (daynr - (long) year * 365L) - (year-1)/4 +temp;
- while (day_of_year > (days_in_year= calc_days_in_year(year)))
+ if (day_of_year > 31+28)
{
- day_of_year-=days_in_year;
- (year)++;
+ day_of_year--;
+ if (day_of_year == 31+28)
+ leap_day=1; /* Handle leapyears leapday */
}
- leap_day=0;
- if (days_in_year == 366)
- {
- if (day_of_year > 31+28)
- {
- day_of_year--;
- if (day_of_year == 31+28)
- leap_day=1; /* Handle leapyears leapday */
- }
- }
- *ret_month=1;
- for (month_pos= days_in_month ;
- day_of_year > (uint) *month_pos ;
- day_of_year-= *(month_pos++), (*ret_month)++)
- ;
- *ret_year=year;
- *ret_day=day_of_year+leap_day;
}
- DBUG_VOID_RETURN;
+ *ret_month=1;
+ for (month_pos= days_in_month ;
+ day_of_year > (uint) *month_pos ;
+ day_of_year-= *(month_pos++), (*ret_month)++)
+ ;
+ *ret_year=year;
+ *ret_day=day_of_year+leap_day;
+ DBUG_RETURN(0);
}
/* Functions to handle periods */
@@ -226,56 +223,132 @@ ulong convert_month_to_period(ulong month)
timestamp_type
str_to_datetime_with_warn(const char *str, uint length, MYSQL_TIME *l_time,
- uint flags)
+ ulong flags)
{
int was_cut;
THD *thd= current_thd;
timestamp_type ts_type;
ts_type= str_to_datetime(str, length, l_time,
- (flags | (thd->variables.sql_mode &
- (MODE_INVALID_DATES |
- MODE_NO_ZERO_DATE))),
+ (flags | (sql_mode_for_dates(thd))),
&was_cut);
if (was_cut || ts_type <= MYSQL_TIMESTAMP_ERROR)
- make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- str, length, ts_type, NullS);
+ make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ str, length, flags & TIME_TIME_ONLY ?
+ MYSQL_TIMESTAMP_TIME : ts_type, NullS);
return ts_type;
}
+/**
+ converts a pair of numbers (integer part, microseconds) to MYSQL_TIME
+
+ @param neg sign of the time value
+ @param nr integer part of the number to convert
+ @param sec_part microsecond part of the number
+ @param ltime converted value will be written here
+ @param fuzzydate conversion flags (TIME_FUZZY_DATE, etc)
+ @param str original number, as a Lazy_string. For the warning
+ @param field_name field name or NULL if not a field. For the warning
+
+ @returns 0 for success, 1 for a failure
+*/
+static bool number_to_time_with_warn(bool neg, ulonglong nr, ulong sec_part,
+ MYSQL_TIME *ltime, ulong fuzzydate,
+ const Lazy_string *str,
+ const char *field_name)
+{
+ int was_cut;
+ longlong res;
+ enum_field_types f_type;
+
+ if (fuzzydate & TIME_TIME_ONLY)
+ {
+ f_type= MYSQL_TYPE_TIME;
+ res= number_to_time(neg, nr, sec_part, ltime, &was_cut);
+ }
+ else
+ {
+ f_type= MYSQL_TYPE_DATETIME;
+ res= neg ? -1 : number_to_datetime(nr, sec_part, ltime, fuzzydate, &was_cut);
+ }
+
+ if (res < 0 || (was_cut && !(fuzzydate & TIME_FUZZY_DATE)))
+ {
+ make_truncated_value_warning(current_thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN, str,
+ res < 0 ? MYSQL_TIMESTAMP_ERROR
+ : mysql_type_to_time_type(f_type),
+ field_name);
+ }
+ return res < 0;
+}
+
+
+bool double_to_datetime_with_warn(double value, MYSQL_TIME *ltime,
+ ulong fuzzydate, const char *field_name)
+{
+ const Lazy_string_double str(value);
+ bool neg= value < 0;
+
+ if (neg)
+ value= -value;
+
+ if (value > LONGLONG_MAX)
+ value= static_cast<double>(LONGLONG_MAX);
+
+ longlong nr= static_cast<ulonglong>(floor(value));
+ uint sec_part= static_cast<ulong>((value - floor(value))*TIME_SECOND_PART_FACTOR);
+ return number_to_time_with_warn(neg, nr, sec_part, ltime, fuzzydate, &str,
+ field_name);
+}
+
+
+bool decimal_to_datetime_with_warn(const my_decimal *value, MYSQL_TIME *ltime,
+ ulong fuzzydate, const char *field_name)
+{
+ const Lazy_string_decimal str(value);
+ ulonglong nr;
+ ulong sec_part;
+ bool neg= my_decimal2seconds(value, &nr, &sec_part);
+ return number_to_time_with_warn(neg, nr, sec_part, ltime, fuzzydate, &str,
+ field_name);
+}
+
+
+bool int_to_datetime_with_warn(longlong value, MYSQL_TIME *ltime,
+ ulong fuzzydate, const char *field_name)
+{
+ const Lazy_string_num str(value);
+ bool neg= value < 0;
+ return number_to_time_with_warn(neg, neg ? -value : value, 0, ltime,
+ fuzzydate, &str, field_name);
+}
+
+
/*
- Convert a datetime from broken-down MYSQL_TIME representation to corresponding
- TIMESTAMP value.
+ Convert a datetime from broken-down MYSQL_TIME representation to
+ corresponding TIMESTAMP value.
SYNOPSIS
TIME_to_timestamp()
thd - current thread
t - datetime in broken-down representation,
- in_dst_time_gap - pointer to bool which is set to true if t represents
- value which doesn't exists (falls into the spring
- time-gap) or to false otherwise.
+ error_code - 0, if the conversion was successful;
+ ER_WARN_DATA_OUT_OF_RANGE, if t contains datetime value
+ which is out of TIMESTAMP range;
+ ER_WARN_INVALID_TIMESTAMP, if t represents value which
+ doesn't exists (falls into the spring time-gap).
RETURN
Number seconds in UTC since start of Unix Epoch corresponding to t.
- 0 - t contains datetime value which is out of TIMESTAMP range.
-
+ 0 - in case of ER_WARN_DATA_OUT_OF_RANGE
*/
-my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *in_dst_time_gap)
-{
- my_time_t timestamp;
- *in_dst_time_gap= 0;
+my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, uint *error_code)
+{
thd->time_zone_used= 1;
-
- timestamp= thd->variables.time_zone->TIME_to_gmt_sec(t, in_dst_time_gap);
- if (timestamp)
- {
- return timestamp;
- }
-
- /* If we are here we have range error. */
- return(0);
+ return thd->variables.time_zone->TIME_to_gmt_sec(t, error_code);
}
@@ -285,12 +358,19 @@ my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *in_dst_time_
NOTE
See str_to_time() for more info.
+
+ RETURN
+ 0 ok
+ 1 wrong time value
*/
+
bool
-str_to_time_with_warn(const char *str, uint length, MYSQL_TIME *l_time)
+str_to_time_with_warn(const char *str, uint length, MYSQL_TIME *l_time,
+ ulong fuzzydate)
{
int warning;
- bool ret_val= str_to_time(str, length, l_time, &warning);
+ bool ret_val= (str_to_time(str, length, l_time, fuzzydate, &warning) ==
+ MYSQL_TIMESTAMP_ERROR);
if (ret_val || warning)
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
str, length, MYSQL_TIMESTAMP_TIME, NullS);
@@ -659,11 +739,6 @@ KNOWN_DATE_TIME_FORMAT known_date_time_formats[6]=
};
-/*
- Return format string according format name.
- If name is unknown, result is NULL
-*/
-
const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
timestamp_type type)
{
@@ -680,51 +755,10 @@ const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
}
}
-/****************************************************************************
- Functions to create default time/date/datetime strings
-
- NOTE:
- For the moment the DATE_TIME_FORMAT argument is ignored becasue
- MySQL doesn't support comparing of date/time/datetime strings that
- are not in arbutary order as dates are compared as strings in some
- context)
- This functions don't check that given MYSQL_TIME structure members are
- in valid range. If they are not, return value won't reflect any
- valid date either. Additionally, make_time doesn't take into
- account time->day member: it's assumed that days have been converted
- to hours already.
-****************************************************************************/
-
-void make_time(const DATE_TIME_FORMAT *format __attribute__((unused)),
- const MYSQL_TIME *l_time, String *str)
-{
- uint length= (uint) my_time_to_str(l_time, (char*) str->ptr());
- str->length(length);
- str->set_charset(&my_charset_bin);
-}
-
-
-void make_date(const DATE_TIME_FORMAT *format __attribute__((unused)),
- const MYSQL_TIME *l_time, String *str)
-{
- uint length= (uint) my_date_to_str(l_time, (char*) str->ptr());
- str->length(length);
- str->set_charset(&my_charset_bin);
-}
-
-
-void make_datetime(const DATE_TIME_FORMAT *format __attribute__((unused)),
- const MYSQL_TIME *l_time, String *str)
-{
- uint length= (uint) my_datetime_to_str(l_time, (char*) str->ptr());
- str->length(length);
- str->set_charset(&my_charset_bin);
-}
-
-
-void make_truncated_value_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
- const char *str_val,
- uint str_length, timestamp_type time_type,
+void make_truncated_value_warning(THD *thd,
+ MYSQL_ERROR::enum_warning_level level,
+ const Lazy_string *sval,
+ timestamp_type time_type,
const char *field_name)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
@@ -732,8 +766,7 @@ void make_truncated_value_warning(THD *thd, MYSQL_ERROR::enum_warning_level leve
CHARSET_INFO *cs= &my_charset_latin1;
char buff[128];
String str(buff,(uint32) sizeof(buff), system_charset_info);
- str.copy(str_val, str_length, system_charset_info);
- str[str_length]= 0; // Ensure we have end 0 for snprintf
+ sval->copy_to(&str);
switch (time_type) {
case MYSQL_TIMESTAMP_DATE:
@@ -750,32 +783,36 @@ void make_truncated_value_warning(THD *thd, MYSQL_ERROR::enum_warning_level leve
if (field_name)
cs->cset->snprintf(cs, warn_buff, sizeof(warn_buff),
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
- type_str, str.c_ptr(), field_name,
+ type_str, str.c_ptr_safe(), field_name,
(ulong) thd->row_count);
else
{
if (time_type > MYSQL_TIMESTAMP_ERROR)
cs->cset->snprintf(cs, warn_buff, sizeof(warn_buff),
ER(ER_TRUNCATED_WRONG_VALUE),
- type_str, str.c_ptr());
+ type_str, str.c_ptr_safe());
else
cs->cset->snprintf(cs, warn_buff, sizeof(warn_buff),
- ER(ER_WRONG_VALUE), type_str, str.c_ptr());
+ ER(ER_WRONG_VALUE), type_str, str.c_ptr_safe());
}
push_warning(thd, level,
ER_TRUNCATED_WRONG_VALUE, warn_buff);
}
-/* Daynumber from year 0 to 9999-12-31 */
-#define MAX_DAY_NUMBER 3652424L
-bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type, INTERVAL interval)
+/* Daynumber from year 0 to 9999-12-31 */
+#define COMBINE(X) \
+ (((((X)->day * 24LL + (X)->hour) * 60LL + \
+ (X)->minute) * 60LL + (X)->second)*1000000LL + \
+ (X)->second_part)
+#define GET_PART(X, N) X % N ## LL; X/= N ## LL
+
+bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type,
+ INTERVAL interval)
{
long period, sign;
- ltime->neg= 0;
-
- sign= (interval.neg ? -1 : 1);
+ sign= (interval.neg == ltime->neg ? 1 : -1);
switch (int_type) {
case INTERVAL_SECOND:
@@ -792,50 +829,56 @@ bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type, INTERVAL inter
case INTERVAL_DAY_SECOND:
case INTERVAL_DAY_MINUTE:
case INTERVAL_DAY_HOUR:
+ case INTERVAL_DAY:
{
- longlong sec, days, daynr, microseconds, extra_sec;
- ltime->time_type= MYSQL_TIMESTAMP_DATETIME; // Return full date
- microseconds= ltime->second_part + sign*interval.second_part;
- extra_sec= microseconds/1000000L;
- microseconds= microseconds%1000000L;
-
- sec=((ltime->day-1)*3600*24L+ltime->hour*3600+ltime->minute*60+
- ltime->second +
- sign* (longlong) (interval.day*3600*24L +
- interval.hour*LL(3600)+interval.minute*LL(60)+
- interval.second))+ extra_sec;
- if (microseconds < 0)
+ longlong usec, daynr;
+ my_bool neg= 0;
+ enum enum_mysql_timestamp_type time_type= ltime->time_type;
+
+ if (time_type != MYSQL_TIMESTAMP_TIME)
+ ltime->day+= calc_daynr(ltime->year, ltime->month, 1) - 1;
+
+ usec= COMBINE(ltime) + sign*COMBINE(&interval);
+
+ if (usec < 0)
{
- microseconds+= LL(1000000);
- sec--;
+ neg= 1;
+ usec= -usec;
}
- days= sec/(3600*LL(24));
- sec-= days*3600*LL(24);
- if (sec < 0)
+
+ ltime->second_part= GET_PART(usec, 1000000);
+ ltime->second= GET_PART(usec, 60);
+ ltime->minute= GET_PART(usec, 60);
+ ltime->neg^= neg;
+
+ if (time_type == MYSQL_TIMESTAMP_TIME)
{
- days--;
- sec+= 3600*LL(24);
+ if (usec > TIME_MAX_HOUR)
+ goto invalid_date;
+ ltime->hour= static_cast<uint>(usec);
+ ltime->day= 0;
+ return 0;
}
- ltime->second_part= (uint) microseconds;
- ltime->second= (uint) (sec % 60);
- ltime->minute= (uint) (sec/60 % 60);
- ltime->hour= (uint) (sec/3600);
- daynr= calc_daynr(ltime->year,ltime->month,1) + days;
+
+ if (int_type != INTERVAL_DAY)
+ ltime->time_type= MYSQL_TIMESTAMP_DATETIME; // Return full date
+
+ ltime->hour= GET_PART(usec, 24);
+ daynr= usec;
+
/* Day number from year 0 to 9999-12-31 */
- if ((ulonglong) daynr > MAX_DAY_NUMBER)
+ if (get_date_from_daynr((long) daynr, &ltime->year, &ltime->month,
+ &ltime->day))
goto invalid_date;
- get_date_from_daynr((long) daynr, &ltime->year, &ltime->month,
- &ltime->day);
break;
}
- case INTERVAL_DAY:
case INTERVAL_WEEK:
period= (calc_daynr(ltime->year,ltime->month,ltime->day) +
sign * (long) interval.day);
/* Daynumber from year 0 to 9999-12-31 */
- if ((ulong) period > MAX_DAY_NUMBER)
+ if (get_date_from_daynr((long) period,&ltime->year,&ltime->month,
+ &ltime->day))
goto invalid_date;
- get_date_from_daynr((long) period,&ltime->year,&ltime->month,&ltime->day);
break;
case INTERVAL_YEAR:
ltime->year+= sign * (long) interval.year;
@@ -866,13 +909,15 @@ bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type, INTERVAL inter
goto null_date;
}
- return 0; // Ok
+ if (ltime->time_type != MYSQL_TIMESTAMP_TIME)
+ return 0; // Ok
invalid_date:
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_DATETIME_FUNCTION_OVERFLOW,
ER(ER_DATETIME_FUNCTION_OVERFLOW),
- "datetime");
+ ltime->time_type == MYSQL_TIMESTAMP_TIME ?
+ "time" : "datetime");
null_date:
return 1;
}
@@ -972,20 +1017,14 @@ calc_time_diff(MYSQL_TIME *l_time1, MYSQL_TIME *l_time2, int l_sign, longlong *s
int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b)
{
- ulonglong a_t= TIME_to_ulonglong_datetime(a);
- ulonglong b_t= TIME_to_ulonglong_datetime(b);
+ ulonglong a_t= pack_time(a);
+ ulonglong b_t= pack_time(b);
if (a_t < b_t)
return -1;
if (a_t > b_t)
return 1;
- if (a->second_part < b->second_part)
- return -1;
- if (a->second_part > b->second_part)
- return 1;
-
return 0;
}
-#endif
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 4beaea71e27..469400ec69f 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -817,9 +817,11 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
TIME_to_gmt_sec()
t - pointer to structure for broken down represenatation
sp - pointer to struct with time zone description
- in_dst_time_gap - pointer to bool which is set to true if datetime
- value passed doesn't really exist (i.e. falls into
- spring time-gap) and is not touched otherwise.
+ error_code - 0, if the conversion was successful;
+ ER_WARN_DATA_OUT_OF_RANGE, if t contains datetime value
+ which is out of TIMESTAMP range;
+ ER_WARN_INVALID_TIMESTAMP, if t represents value which
+ doesn't exists (falls into the spring time-gap).
DESCRIPTION
This is mktime analog for MySQL. It is essentially different
@@ -881,20 +883,23 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
Seconds in UTC since Epoch.
0 in case of error.
*/
+
static my_time_t
-TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp,
- my_bool *in_dst_time_gap)
+TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, uint *error_code)
{
my_time_t local_t;
uint saved_seconds;
uint i;
int shift= 0;
-
DBUG_ENTER("TIME_to_gmt_sec");
if (!validate_timestamp_range(t))
+ {
+ *error_code= ER_WARN_DATA_OUT_OF_RANGE;
DBUG_RETURN(0);
+ }
+ *error_code= 0;
/* We need this for correct leap seconds handling */
if (t->second < SECS_PER_MIN)
@@ -938,6 +943,7 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp,
This means that source time can't be represented as my_time_t due to
limited my_time_t range.
*/
+ *error_code= ER_WARN_DATA_OUT_OF_RANGE;
DBUG_RETURN(0);
}
@@ -954,6 +960,7 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp,
if (local_t > (my_time_t) (TIMESTAMP_MAX_VALUE - shift * SECS_PER_DAY +
sp->revtis[i].rt_offset - saved_seconds))
{
+ *error_code= ER_WARN_DATA_OUT_OF_RANGE;
DBUG_RETURN(0); /* my_time_t overflow */
}
local_t+= shift * SECS_PER_DAY;
@@ -967,7 +974,7 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp,
Now we are returning my_time_t value corresponding to the
beginning of the gap.
*/
- *in_dst_time_gap= 1;
+ *error_code= ER_WARN_INVALID_TIMESTAMP;
local_t= sp->revts[i] - sp->revtis[i].rt_offset + saved_seconds;
}
else
@@ -975,7 +982,10 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp,
/* check for TIMESTAMP_MAX_VALUE was already done above */
if (local_t < TIMESTAMP_MIN_VALUE)
+ {
local_t= 0;
+ *error_code= ER_WARN_DATA_OUT_OF_RANGE;
+ }
DBUG_RETURN(local_t);
}
@@ -1009,8 +1019,7 @@ class Time_zone_system : public Time_zone
{
public:
Time_zone_system() {} /* Remove gcc warning */
- virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
- my_bool *in_dst_time_gap) const;
+ virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const;
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
virtual const String * get_name() const;
};
@@ -1024,9 +1033,11 @@ public:
TIME_to_gmt_sec()
t - pointer to MYSQL_TIME structure with local time in
broken-down representation.
- in_dst_time_gap - pointer to bool which is set to true if datetime
- value passed doesn't really exist (i.e. falls into
- spring time-gap) and is not touched otherwise.
+ error_code - 0, if the conversion was successful;
+ ER_WARN_DATA_OUT_OF_RANGE, if t contains datetime value
+ which is out of TIMESTAMP range;
+ ER_WARN_INVALID_TIMESTAMP, if t represents value which
+ doesn't exists (falls into the spring time-gap).
DESCRIPTION
This method uses system function (localtime_r()) for conversion
@@ -1042,10 +1053,10 @@ public:
Corresponding my_time_t value or 0 in case of error
*/
my_time_t
-Time_zone_system::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const
+Time_zone_system::TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const
{
long not_used;
- return my_system_gmt_sec(t, &not_used, in_dst_time_gap);
+ return my_system_gmt_sec(t, &not_used, error_code);
}
@@ -1105,7 +1116,7 @@ class Time_zone_utc : public Time_zone
public:
Time_zone_utc() {} /* Remove gcc warning */
virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
- my_bool *in_dst_time_gap) const;
+ uint *error_code) const;
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
virtual const String * get_name() const;
};
@@ -1114,14 +1125,6 @@ public:
/*
Convert UTC time from MYSQL_TIME representation to its my_time_t representation.
- SYNOPSIS
- TIME_to_gmt_sec()
- t - pointer to MYSQL_TIME structure with local time
- in broken-down representation.
- in_dst_time_gap - pointer to bool which is set to true if datetime
- value passed doesn't really exist (i.e. falls into
- spring time-gap) and is not touched otherwise.
-
DESCRIPTION
Since Time_zone_utc is used only internally for my_time_t -> TIME
conversions, this function of Time_zone interface is not implemented for
@@ -1131,10 +1134,11 @@ public:
0
*/
my_time_t
-Time_zone_utc::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const
+Time_zone_utc::TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const
{
/* Should be never called */
DBUG_ASSERT(0);
+ *error_code= ER_WARN_DATA_OUT_OF_RANGE;
return 0;
}
@@ -1194,8 +1198,7 @@ class Time_zone_db : public Time_zone
{
public:
Time_zone_db(TIME_ZONE_INFO *tz_info_arg, const String * tz_name_arg);
- virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
- my_bool *in_dst_time_gap) const;
+ virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const;
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
virtual const String * get_name() const;
private:
@@ -1232,9 +1235,11 @@ Time_zone_db::Time_zone_db(TIME_ZONE_INFO *tz_info_arg,
TIME_to_gmt_sec()
t - pointer to MYSQL_TIME structure with local time
in broken-down representation.
- in_dst_time_gap - pointer to bool which is set to true if datetime
- value passed doesn't really exist (i.e. falls into
- spring time-gap) and is not touched otherwise.
+ error_code - 0, if the conversion was successful;
+ ER_WARN_DATA_OUT_OF_RANGE, if t contains datetime value
+ which is out of TIMESTAMP range;
+ ER_WARN_INVALID_TIMESTAMP, if t represents value which
+ doesn't exists (falls into the spring time-gap).
DESCRIPTION
Please see ::TIME_to_gmt_sec for function description and
@@ -1244,9 +1249,9 @@ Time_zone_db::Time_zone_db(TIME_ZONE_INFO *tz_info_arg,
Corresponding my_time_t value or 0 in case of error
*/
my_time_t
-Time_zone_db::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const
+Time_zone_db::TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const
{
- return ::TIME_to_gmt_sec(t, tz_info, in_dst_time_gap);
+ return ::TIME_to_gmt_sec(t, tz_info, error_code);
}
@@ -1292,7 +1297,7 @@ class Time_zone_offset : public Time_zone
public:
Time_zone_offset(long tz_offset_arg);
virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
- my_bool *in_dst_time_gap) const;
+ uint *error_code) const;
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
virtual const String * get_name() const;
/*
@@ -1334,17 +1339,19 @@ Time_zone_offset::Time_zone_offset(long tz_offset_arg):
TIME_to_gmt_sec()
t - pointer to MYSQL_TIME structure with local time
in broken-down representation.
- in_dst_time_gap - pointer to bool which should be set to true if
- datetime value passed doesn't really exist
- (i.e. falls into spring time-gap) and is not
- touched otherwise.
- It is not really used in this class.
+ error_code - 0, if the conversion was successful;
+ ER_WARN_DATA_OUT_OF_RANGE, if t contains datetime value
+ which is out of TIMESTAMP range;
+ ER_WARN_INVALID_TIMESTAMP, if t represents value which
+ doesn't exists (falls into the spring time-gap).
RETURN VALUE
- Corresponding my_time_t value or 0 in case of error
+ Corresponding my_time_t value or 0 in case of error. In case of error
+ *in_dst_time_gap is also set.
*/
+
my_time_t
-Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const
+Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const
{
my_time_t local_t;
int shift= 0;
@@ -1354,7 +1361,11 @@ Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap)
us to make all validation checks here.
*/
if (!validate_timestamp_range(t))
+ {
+ *error_code= ER_WARN_DATA_OUT_OF_RANGE;
return 0;
+ }
+ *error_code= 0;
/*
Do a temporary shift of the boundary dates to avoid
@@ -1378,6 +1389,7 @@ Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap)
return local_t;
/* range error*/
+ *error_code= ER_WARN_DATA_OUT_OF_RANGE;
return 0;
}
@@ -2730,7 +2742,7 @@ main(int argc, char **argv)
for (time_tmp.second=0; time_tmp.second<60; time_tmp.second+=25)
{
long not_used;
- my_bool not_used_2;
+ uint not_used_2;
t= (time_t)my_system_gmt_sec(&time_tmp, &not_used, &not_used_2);
t1= (time_t)TIME_to_gmt_sec(&time_tmp, &tz_info, &not_used_2);
if (t != t1)
diff --git a/sql/tztime.h b/sql/tztime.h
index daedbb14fca..2b3e9c04aa6 100644
--- a/sql/tztime.h
+++ b/sql/tztime.h
@@ -36,11 +36,11 @@ public:
/**
Converts local time in broken down MYSQL_TIME representation to
my_time_t (UTC seconds since Epoch) represenation.
- Returns 0 in case of error. Sets in_dst_time_gap to true if date provided
- falls into spring time-gap (or lefts it untouched otherwise).
+ Returns 0 in case of error. May set error_code to ER_WARN_DATA_OUT_OF_RANGE
+ or ER_WARN_INVALID_TIMESTAMP, see TIME_to_timestamp())
*/
virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
- my_bool *in_dst_time_gap) const = 0;
+ uint *error_code) const = 0;
/**
Converts time in my_time_t representation to local time in
broken down MYSQL_TIME representation.
diff --git a/sql/uniques.cc b/sql/uniques.cc
index 5788edc673e..5549d68490c 100644
--- a/sql/uniques.cc
+++ b/sql/uniques.cc
@@ -36,7 +36,6 @@
#include "mysql_priv.h"
#include "sql_sort.h"
-
int unique_write_to_file(uchar* key, element_count count, Unique *unique)
{
/*
@@ -48,6 +47,12 @@ int unique_write_to_file(uchar* key, element_count count, Unique *unique)
return my_b_write(&unique->file, key, unique->size) ? 1 : 0;
}
+int unique_write_to_file_with_count(uchar* key, element_count count, Unique *unique)
+{
+ return my_b_write(&unique->file, key, unique->size) ||
+ my_b_write(&unique->file, &count, sizeof(element_count)) ? 1 : 0;
+}
+
int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique)
{
memcpy(unique->record_pointers, key, unique->size);
@@ -55,10 +60,28 @@ int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique)
return 0;
}
+int unique_intersect_write_to_ptrs(uchar* key, element_count count, Unique *unique)
+{
+ if (count >= unique->min_dupl_count)
+ {
+ memcpy(unique->record_pointers, key, unique->size);
+ unique->record_pointers+=unique->size;
+ }
+ else
+ unique->filtered_out_elems++;
+ return 0;
+}
+
+
Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
- uint size_arg, ulonglong max_in_memory_size_arg)
+ uint size_arg, ulonglong max_in_memory_size_arg,
+ uint min_dupl_count_arg)
:max_in_memory_size(max_in_memory_size_arg), size(size_arg), elements(0)
{
+ min_dupl_count= min_dupl_count_arg;
+ full_size= size;
+ if (min_dupl_count_arg)
+ full_size+= sizeof(element_count);
my_b_clear(&file);
init_tree(&tree, (ulong) (max_in_memory_size / 16), 0, size, comp_func, 0,
NULL, comp_func_fixed_arg);
@@ -126,7 +149,8 @@ inline double log2_n_fact(double x)
*/
static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
- uint *first, uint *last)
+ uint *first, uint *last,
+ uint compare_factor)
{
uint total_buf_elems= 0;
for (uint *pbuf= first; pbuf <= last; pbuf++)
@@ -137,7 +161,7 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
/* Using log2(n)=log(n)/log(2) formula */
return 2*((double)total_buf_elems*elem_size) / IO_SIZE +
- total_buf_elems*log((double) n_buffers) / (TIME_FOR_COMPARE_ROWID * M_LN2);
+ total_buf_elems*log((double) n_buffers) / (compare_factor * M_LN2);
}
@@ -170,7 +194,8 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
static double get_merge_many_buffs_cost(uint *buffer,
uint maxbuffer, uint max_n_elems,
- uint last_n_elems, int elem_size)
+ uint last_n_elems, int elem_size,
+ uint compare_factor)
{
register int i;
double total_cost= 0.0;
@@ -197,19 +222,22 @@ static double get_merge_many_buffs_cost(uint *buffer,
{
total_cost+=get_merge_buffers_cost(buff_elems, elem_size,
buff_elems + i,
- buff_elems + i + MERGEBUFF-1);
+ buff_elems + i + MERGEBUFF-1,
+ compare_factor);
lastbuff++;
}
total_cost+=get_merge_buffers_cost(buff_elems, elem_size,
buff_elems + i,
- buff_elems + maxbuffer);
+ buff_elems + maxbuffer,
+ compare_factor);
maxbuffer= lastbuff;
}
}
/* Simulate final merge_buff call. */
total_cost += get_merge_buffers_cost(buff_elems, elem_size,
- buff_elems, buff_elems + maxbuffer);
+ buff_elems, buff_elems + maxbuffer,
+ compare_factor);
return total_cost;
}
@@ -224,7 +252,11 @@ static double get_merge_many_buffs_cost(uint *buffer,
to get # bytes needed.
nkeys #of elements in Unique
key_size size of each elements in bytes
- max_in_memory_size amount of memory Unique will be allowed to use
+ max_in_memory_size amount of memory Unique will be allowed to use
+ compare_factor used to calculate cost of one comparison
+ write_fl if the result must be saved written to disk
+ in_memory_elems OUT estimate of the number of elements in memory
+ if disk is not used
RETURN
Cost in disk seeks.
@@ -261,15 +293,17 @@ static double get_merge_many_buffs_cost(uint *buffer,
these will be random seeks.
*/
-double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
- ulonglong max_in_memory_size)
+double Unique::get_use_cost(uint *buffer, size_t nkeys, uint key_size,
+ ulonglong max_in_memory_size,
+ uint compare_factor,
+ bool intersect_fl, bool *in_memory)
{
- ulong max_elements_in_tree;
- ulong last_tree_elems;
+ size_t max_elements_in_tree;
+ size_t last_tree_elems;
int n_full_trees; /* number of trees in unique - 1 */
double result;
- max_elements_in_tree= ((ulong) max_in_memory_size /
+ max_elements_in_tree= ((size_t) max_in_memory_size /
ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size));
n_full_trees= nkeys / max_elements_in_tree;
@@ -279,11 +313,15 @@ double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
result= 2*log2_n_fact(last_tree_elems + 1.0);
if (n_full_trees)
result+= n_full_trees * log2_n_fact(max_elements_in_tree + 1.0);
- result /= TIME_FOR_COMPARE_ROWID;
+ result /= compare_factor;
+
+ DBUG_PRINT("info",("unique trees sizes: %u=%u*%u + %u", (uint)nkeys,
+ (uint)n_full_trees,
+ (uint)(n_full_trees?max_elements_in_tree:0),
+ (uint)last_tree_elems));
- DBUG_PRINT("info",("unique trees sizes: %u=%u*%lu + %lu", nkeys,
- n_full_trees, n_full_trees?max_elements_in_tree:0,
- last_tree_elems));
+ if (in_memory)
+ *in_memory= !n_full_trees;
if (!n_full_trees)
return result;
@@ -298,12 +336,12 @@ double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
result += DISK_SEEK_BASE_COST * ceil(((double) key_size)*last_tree_elems / IO_SIZE);
/* Cost of merge */
+ if (intersect_fl)
+ key_size+= sizeof(element_count);
double merge_cost= get_merge_many_buffs_cost(buffer, n_full_trees,
max_elements_in_tree,
- last_tree_elems, key_size);
- if (merge_cost < 0.0)
- return merge_cost;
-
+ last_tree_elems, key_size,
+ compare_factor);
result += merge_cost;
/*
Add cost of reading the resulting sequence, assuming there were no
@@ -330,7 +368,10 @@ bool Unique::flush()
file_ptr.count=tree.elements_in_tree;
file_ptr.file_pos=my_b_tell(&file);
- if (tree_walk(&tree, (tree_walk_action) unique_write_to_file,
+ tree_walk_action action= min_dupl_count ?
+ (tree_walk_action) unique_write_to_file_with_count :
+ (tree_walk_action) unique_write_to_file;
+ if (tree_walk(&tree, action,
(void*) this, left_root_right) ||
insert_dynamic(&file_ptrs, (uchar*) &file_ptr))
return 1;
@@ -360,6 +401,7 @@ Unique::reset()
reinit_io_cache(&file, WRITE_CACHE, 0L, 0, 1);
}
elements= 0;
+ tree.flag= 0;
}
/*
@@ -426,7 +468,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;
@@ -471,7 +513,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 */
@@ -481,14 +523,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);
}
}
@@ -561,15 +603,15 @@ bool Unique::walk(TABLE *table, tree_walk_action action, void *walk_action_arg)
return 1;
if (flush_io_cache(&file) || reinit_io_cache(&file, READ_CACHE, 0L, 0, 0))
return 1;
- ulong buff_sz= (max_in_memory_size / size + 1) * size;
+ ulong buff_sz= (max_in_memory_size / full_size + 1) * full_size;
if (!(merge_buffer= (uchar *) my_malloc((ulong) buff_sz, MYF(0))))
return 1;
- if (buff_sz < (ulong) (size * (file_ptrs.elements + 1)))
- res= merge(table, merge_buffer, buff_sz >= size * MERGEBUFF2) ;
+ if (buff_sz < (ulong) (full_size * (file_ptrs.elements + 1)))
+ res= merge(table, merge_buffer, buff_sz >= full_size * MERGEBUFF2) ;
if (!res)
{
- res= merge_walk(merge_buffer, (ulong) max_in_memory_size, size,
+ res= merge_walk(merge_buffer, (ulong) max_in_memory_size, full_size,
(BUFFPEK *) file_ptrs.buffer,
(BUFFPEK *) file_ptrs.buffer + file_ptrs.elements,
action, walk_action_arg,
@@ -620,7 +662,9 @@ bool Unique::merge(TABLE *table, uchar *buff, bool without_last_merge)
sort_param.max_rows= elements;
sort_param.sort_form= table;
sort_param.rec_length= sort_param.sort_length= sort_param.ref_length=
- size;
+ full_size;
+ sort_param.min_dupl_count= min_dupl_count;
+ sort_param.res_length= 0;
sort_param.keys= (uint) (max_in_memory_size / sort_param.sort_length);
sort_param.not_killable= 1;
@@ -636,13 +680,14 @@ bool Unique::merge(TABLE *table, uchar *buff, bool without_last_merge)
if (flush_io_cache(&file) ||
reinit_io_cache(&file,READ_CACHE,0L,0,0))
goto err;
+ sort_param.res_length= sort_param.rec_length-
+ (min_dupl_count ? sizeof(min_dupl_count) : 0);
if (without_last_merge)
{
file_ptrs.elements= maxbuffer+1;
return 0;
}
- if (merge_buffers(&sort_param, &file, outfile, buff, file_ptr,
- file_ptr, file_ptr+maxbuffer,0))
+ if (merge_index(&sort_param, buff, file_ptr, maxbuffer, &file, outfile))
goto err;
error= 0;
err:
@@ -675,8 +720,13 @@ bool Unique::get(TABLE *table)
if ((record_pointers=table->sort.record_pointers= (uchar*)
my_malloc(size * tree.elements_in_tree, MYF(0))))
{
- (void) tree_walk(&tree, (tree_walk_action) unique_write_to_ptrs,
+ tree_walk_action action= min_dupl_count ?
+ (tree_walk_action) unique_intersect_write_to_ptrs :
+ (tree_walk_action) unique_write_to_ptrs;
+ filtered_out_elems= 0;
+ (void) tree_walk(&tree, action,
this, left_root_right);
+ table->sort.found_records-= filtered_out_elems;
return 0;
}
}
@@ -684,7 +734,7 @@ bool Unique::get(TABLE *table)
if (flush())
return 1;
- ulong buff_sz= (max_in_memory_size / size + 1) * size;
+ ulong buff_sz= (max_in_memory_size / full_size + 1) * full_size;
if (!(sort_buffer= (uchar*) my_malloc(buff_sz, MYF(0))))
return 1;
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 537066fa528..13b0e044ef8 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -1051,7 +1051,6 @@ static bool make_empty_rec(THD *thd, File file,enum legacy_db_type table_type,
}
table.in_use= thd;
- table.s->db_low_byte_first= handler->low_byte_first();
table.s->blob_ptr_size= portable_sizeof_char_ptr;
null_count=0;
diff --git a/sql/unireg.h b/sql/unireg.h
index 64763992537..01aac50670a 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -74,10 +74,13 @@
#define MAX_BIT_FIELD_LENGTH 64 /* Max length in bits for bit fields */
#define MAX_DATE_WIDTH 10 /* YYYY-MM-DD */
-#define MAX_TIME_WIDTH 23 /* -DDDDDD HH:MM:SS.###### */
+#define MIN_TIME_WIDTH 10 /* -HHH:MM:SS */
+#define MAX_TIME_WIDTH 16 /* -DDDDDD HH:MM:SS */
+#define MAX_TIME_FULL_WIDTH 23 /* -DDDDDD HH:MM:SS.###### */
#define MAX_DATETIME_FULL_WIDTH 29 /* YYYY-MM-DD HH:MM:SS.###### AM */
#define MAX_DATETIME_WIDTH 19 /* YYYY-MM-DD HH:MM:SS */
#define MAX_DATETIME_COMPRESSED_WIDTH 14 /* YYYYMMDDHHMMSS */
+#define MAX_DATETIME_PRECISION 6
#define MAX_TABLES (sizeof(table_map)*8-3) /* Max tables in join */
#define PARAM_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-3))
@@ -91,7 +94,7 @@
#define MAX_SELECT_NESTING (sizeof(nesting_map)*8-1)
#define MAX_SORT_MEMORY (2048*1024-MALLOC_OVERHEAD)
-#define MIN_SORT_MEMORY (32*1024-MALLOC_OVERHEAD)
+#define MIN_SORT_MEMORY (1024-MALLOC_OVERHEAD)
/* Memory allocated when parsing a statement / saving a statement */
#define MEM_ROOT_BLOCK_SIZE 8192
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 3ecf820a423..0c925f4a0b5 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -687,11 +687,11 @@ int ha_archive::create(const char *name, TABLE *table_arg,
{
if (!my_fstat(frm_file, &file_stat, MYF(MY_WME)))
{
- frm_ptr= (uchar *)my_malloc(sizeof(uchar) * file_stat.st_size, MYF(0));
+ frm_ptr= (uchar *)my_malloc(sizeof(uchar) * (size_t)file_stat.st_size, MYF(0));
if (frm_ptr)
{
- my_read(frm_file, frm_ptr, file_stat.st_size, MYF(0));
- azwrite_frm(&create_stream, (char *)frm_ptr, file_stat.st_size);
+ my_read(frm_file, frm_ptr, (size_t)file_stat.st_size, MYF(0));
+ azwrite_frm(&create_stream, (char *)frm_ptr, (size_t)file_stat.st_size);
my_free((uchar*)frm_ptr, MYF(0));
}
}
@@ -1120,20 +1120,26 @@ int ha_archive::unpack_row(azio_stream *file_to_read, uchar *record)
if (read != row_len || error)
{
- DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
+ DBUG_RETURN(error ? HA_ERR_CRASHED_ON_USAGE : HA_ERR_WRONG_IN_RECORD);
}
/* Copy null bits */
- const uchar *ptr= record_buffer->buffer;
+ const uchar *ptr= record_buffer->buffer, *end= ptr+ row_len;
memcpy(record, ptr, table->s->null_bytes);
ptr+= table->s->null_bytes;
+ if (ptr > end)
+ DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
for (Field **field=table->field ; *field ; field++)
{
if (!((*field)->is_null_in_record(record)))
{
- ptr= (*field)->unpack(record + (*field)->offset(table->record[0]), ptr);
+ if (!(ptr= (*field)->unpack(record + (*field)->offset(table->record[0]),
+ ptr, end)))
+ DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
}
}
+ if (ptr != end)
+ DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
DBUG_RETURN(0);
}
diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc
index d97588dcc3d..be90a1d1a08 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();
/* Copy and add end \0 */
server->key= (uchar *) strmake_root(mem_root, key.ptr(), key.length());
diff --git a/storage/heap/_check.c b/storage/heap/_check.c
index 08b6da62ae1..6cd01012d84 100644
--- a/storage/heap/_check.c
+++ b/storage/heap/_check.c
@@ -110,8 +110,13 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
for (i=found=max_links=seek=0 ; i < records ; i++)
{
hash_info=hp_find_hash(&keydef->block,i);
- if (hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec),
- blength,records) == i)
+ if (hash_info->hash_of_key != hp_rec_hashnr(keydef, hash_info->ptr_to_rec))
+ {
+ DBUG_PRINT("error",
+ ("Found row with wrong hash_of_key at position %lu", i));
+ error= 1;
+ }
+ if (hp_mask(hash_info->hash_of_key, blength, records) == i)
{
found++;
seek++;
@@ -119,9 +124,7 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
while ((hash_info=hash_info->next_key) && found < records + 1)
{
seek+= ++links;
- if ((rec_link = hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec),
- blength, records))
- != i)
+ if ((rec_link= hp_mask(hash_info->hash_of_key, blength, records)) != i)
{
DBUG_PRINT("error",
("Record in wrong link: Link %lu Record: 0x%lx Record-link %lu",
@@ -147,14 +150,14 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
error=1;
}
DBUG_PRINT("info",
- ("records: %ld seeks: %lu max links: %lu hitrate: %.2f "
- "buckets: %lu",
- records,seek,max_links,
+ ("key: %u records: %ld seeks: %lu max links: %lu "
+ "hitrate: %.2f buckets: %lu",
+ keynr, records,seek,max_links,
(float) seek / (float) (records ? records : 1),
hash_buckets_found));
if (print_status)
- printf("Key: %d records: %ld seeks: %lu max links: %lu "
- "hitrate: %.2f buckets: %lu\n",
+ printf("Key: %u records: %ld seeks: %lu max links: %lu "
+ "hitrate: %.2f buckets: %lu\n",
keynr, records, seek, max_links,
(float) seek / (float) (records ? records : 1),
hash_buckets_found);
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index a5d8679105a..c25b3c641b5 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -185,6 +185,19 @@ void ha_heap::set_keys_for_scanning(void)
}
+int ha_heap::can_continue_handler_scan()
+{
+ int error= 0;
+ if ((file->key_version != file->s->key_version && inited == INDEX) ||
+ (file->file_version != file->s->file_version && inited == RND))
+ {
+ /* Data changed, not safe to do index or rnd scan */
+ error= HA_ERR_RECORD_CHANGED;
+ }
+ return error;
+}
+
+
void ha_heap::update_key_stats()
{
for (uint i= 0; i < table->s->keys; i++)
@@ -215,7 +228,6 @@ void ha_heap::update_key_stats()
int ha_heap::write_row(uchar * buf)
{
int res;
- ha_statistic_increment(&SSV::ha_write_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
if (table->next_number_field && buf == table->record[0])
@@ -239,7 +251,6 @@ int ha_heap::write_row(uchar * buf)
int ha_heap::update_row(const uchar * old_data, uchar * new_data)
{
int res;
- ha_statistic_increment(&SSV::ha_update_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time();
res= heap_update(file,old_data,new_data);
@@ -258,7 +269,6 @@ int ha_heap::update_row(const uchar * old_data, uchar * new_data)
int ha_heap::delete_row(const uchar * buf)
{
int res;
- ha_statistic_increment(&SSV::ha_delete_count);
res= heap_delete(file,buf);
if (!res && table->s->tmp_table == NO_TMP_TABLE &&
++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
@@ -277,7 +287,6 @@ int ha_heap::index_read_map(uchar *buf, const uchar *key,
enum ha_rkey_function find_flag)
{
DBUG_ASSERT(inited==INDEX);
- ha_statistic_increment(&SSV::ha_read_key_count);
int error = heap_rkey(file,buf,active_index, key, keypart_map, find_flag);
table->status = error ? STATUS_NOT_FOUND : 0;
return error;
@@ -287,7 +296,6 @@ int ha_heap::index_read_last_map(uchar *buf, const uchar *key,
key_part_map keypart_map)
{
DBUG_ASSERT(inited==INDEX);
- ha_statistic_increment(&SSV::ha_read_key_count);
int error= heap_rkey(file, buf, active_index, key, keypart_map,
HA_READ_PREFIX_LAST);
table->status= error ? STATUS_NOT_FOUND : 0;
@@ -298,7 +306,6 @@ int ha_heap::index_read_idx_map(uchar *buf, uint index, const uchar *key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
- ha_statistic_increment(&SSV::ha_read_key_count);
int error = heap_rkey(file, buf, index, key, keypart_map, find_flag);
table->status = error ? STATUS_NOT_FOUND : 0;
return error;
@@ -307,7 +314,6 @@ int ha_heap::index_read_idx_map(uchar *buf, uint index, const uchar *key,
int ha_heap::index_next(uchar * buf)
{
DBUG_ASSERT(inited==INDEX);
- ha_statistic_increment(&SSV::ha_read_next_count);
int error=heap_rnext(file,buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -316,7 +322,6 @@ int ha_heap::index_next(uchar * buf)
int ha_heap::index_prev(uchar * buf)
{
DBUG_ASSERT(inited==INDEX);
- ha_statistic_increment(&SSV::ha_read_prev_count);
int error=heap_rprev(file,buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -325,7 +330,6 @@ int ha_heap::index_prev(uchar * buf)
int ha_heap::index_first(uchar * buf)
{
DBUG_ASSERT(inited==INDEX);
- ha_statistic_increment(&SSV::ha_read_first_count);
int error=heap_rfirst(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -334,7 +338,6 @@ int ha_heap::index_first(uchar * buf)
int ha_heap::index_last(uchar * buf)
{
DBUG_ASSERT(inited==INDEX);
- ha_statistic_increment(&SSV::ha_read_last_count);
int error=heap_rlast(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -347,7 +350,6 @@ int ha_heap::rnd_init(bool scan)
int ha_heap::rnd_next(uchar *buf)
{
- ha_statistic_increment(&SSV::ha_read_rnd_next_count);
int error=heap_scan(file, buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -357,7 +359,6 @@ int ha_heap::rnd_pos(uchar * buf, uchar *pos)
{
int error;
HEAP_PTR heap_position;
- ha_statistic_increment(&SSV::ha_read_rnd_count);
memcpy_fixed((char*) &heap_position, pos, sizeof(HEAP_PTR));
error=heap_rrnd(file, buf, heap_position);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -372,6 +373,10 @@ void ha_heap::position(const uchar *record)
int ha_heap::info(uint flag)
{
HEAPINFO hp_info;
+
+ if (!table)
+ return 1;
+
(void) heap_info(file,&hp_info,flag);
errkey= hp_info.errkey;
@@ -568,7 +573,7 @@ int ha_heap::delete_table(const char *name)
void ha_heap::drop_table(const char *name)
{
file->s->delete_on_close= 1;
- close();
+ ha_close();
}
@@ -657,7 +662,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;
@@ -689,6 +695,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/ha_heap.h b/storage/heap/ha_heap.h
index 5402842413c..b6ff34892ab 100644
--- a/storage/heap/ha_heap.h
+++ b/storage/heap/ha_heap.h
@@ -54,6 +54,7 @@ public:
{
return (HA_FAST_KEY_READ | HA_NO_BLOBS | HA_NULL_IN_KEY |
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
+ HA_CAN_SQL_HANDLER |
HA_REC_NOT_IN_SEQ | HA_CAN_INSERT_DELAYED | HA_NO_TRANSACTIONS |
HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT);
}
@@ -95,6 +96,7 @@ public:
int rnd_next(uchar *buf);
int rnd_pos(uchar * buf, uchar *pos);
void position(const uchar *record);
+ int can_continue_handler_scan();
int info(uint);
int extra(enum ha_extra_function operation);
int reset();
diff --git a/storage/heap/heapdef.h b/storage/heap/heapdef.h
index 3fc94062303..b9a3eab3432 100644
--- a/storage/heap/heapdef.h
+++ b/storage/heap/heapdef.h
@@ -50,6 +50,7 @@ typedef struct st_hp_hash_info
{
struct st_hp_hash_info *next_key;
uchar *ptr_to_rec;
+ ulong hash_of_key;
} HASH_INFO;
typedef struct {
diff --git a/storage/heap/hp_clear.c b/storage/heap/hp_clear.c
index babfcbd6f41..b999f1ff5e8 100644
--- a/storage/heap/hp_clear.c
+++ b/storage/heap/hp_clear.c
@@ -40,6 +40,8 @@ void hp_clear(HP_SHARE *info)
info->blength=1;
info->changed=0;
info->del_link=0;
+ info->key_version++;
+ info->file_version++;
DBUG_VOID_RETURN;
}
diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c
index 2a8cf474a1c..092dad73b16 100644
--- a/storage/heap/hp_create.c
+++ b/storage/heap/hp_create.c
@@ -39,6 +39,10 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
share= 0;
}
}
+ else
+ {
+ DBUG_PRINT("info", ("Creating internal (no named) temporary table"));
+ }
if (!share)
{
@@ -104,6 +108,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;
}
@@ -229,12 +241,20 @@ static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
max_records= 1000; /* As good as quess as anything */
recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
records_in_block= max_records / 10;
- if (records_in_block < 10 && max_records)
+
+ /*
+ We don't want too few records_in_block as otherwise the overhead of
+ of the HP_PTRS block will be too notable
+ */
+ records_in_block= min(1000, max_records);
+ if (records_in_block < 10)
records_in_block= 10;
- if (!records_in_block || records_in_block*recbuffer >
+
+ /* The + 1 is there to ensure that we get at least 1 row per level */
+ if (records_in_block*recbuffer >
(my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
records_in_block= (my_default_record_cache_size - sizeof(HP_PTRS) *
- HP_MAX_LEVELS) / recbuffer + 1;
+ HP_MAX_LEVELS) / recbuffer + 1;
block->records_in_block= records_in_block;
block->recbuffer= recbuffer;
block->last_allocated= 0L;
@@ -248,10 +268,15 @@ static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
static inline void heap_try_free(HP_SHARE *share)
{
+ DBUG_ENTER("heap_try_free");
if (share->open_count == 0)
hp_free(share);
else
+ {
+ DBUG_PRINT("info", ("Table is still in use. Will be freed on close"));
share->delete_on_close= 1;
+ }
+ DBUG_VOID_RETURN;
}
@@ -270,6 +295,7 @@ int heap_delete_table(const char *name)
else
{
result= my_errno=ENOENT;
+ DBUG_PRINT("error", ("Could not find table '%s'", name));
}
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(result);
diff --git a/storage/heap/hp_delete.c b/storage/heap/hp_delete.c
index 7612b896ccc..043e4d3540d 100644
--- a/storage/heap/hp_delete.c
+++ b/storage/heap/hp_delete.c
@@ -47,6 +47,7 @@ int heap_delete(HP_INFO *info, const uchar *record)
share->del_link=pos;
pos[share->reclength]=0; /* Record deleted */
share->deleted++;
+ share->key_version++;
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
#endif
@@ -147,8 +148,9 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
else if (pos->next_key)
{
empty=pos->next_key;
- pos->ptr_to_rec=empty->ptr_to_rec;
- pos->next_key=empty->next_key;
+ pos->ptr_to_rec= empty->ptr_to_rec;
+ pos->next_key= empty->next_key;
+ pos->hash_of_key= empty->hash_of_key;
}
else
keyinfo->hash_buckets--;
@@ -157,7 +159,7 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
DBUG_RETURN (0);
/* Move the last key (lastpos) */
- lastpos_hashnr = hp_rec_hashnr(keyinfo, lastpos->ptr_to_rec);
+ lastpos_hashnr= lastpos->hash_of_key;
/* pos is where lastpos should be */
pos=hp_find_hash(&keyinfo->block, hp_mask(lastpos_hashnr, share->blength,
share->records));
@@ -166,7 +168,7 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
empty[0]=lastpos[0];
DBUG_RETURN(0);
}
- pos_hashnr = hp_rec_hashnr(keyinfo, pos->ptr_to_rec);
+ pos_hashnr= pos->hash_of_key;
/* pos3 is where the pos should be */
pos3= hp_find_hash(&keyinfo->block,
hp_mask(pos_hashnr, share->blength, share->records));
diff --git a/storage/heap/hp_hash.c b/storage/heap/hp_hash.c
index 90694ca75b3..5c96bb771e8 100644
--- a/storage/heap/hp_hash.c
+++ b/storage/heap/hp_hash.c
@@ -149,8 +149,8 @@ uchar *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *key,
{
flag=0; /* Reset flag */
if (hp_find_hash(&keyinfo->block,
- hp_mask(hp_rec_hashnr(keyinfo, pos->ptr_to_rec),
- share->blength, share->records)) != pos)
+ hp_mask(pos->hash_of_key,
+ share->blength, share->records)) != pos)
break; /* Wrong link */
}
}
@@ -300,7 +300,9 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key)
}
}
}
+#ifdef ONLY_FOR_HASH_DEBUGGING
DBUG_PRINT("exit", ("hash: 0x%lx", nr));
+#endif
return((ulong) nr);
}
@@ -351,6 +353,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);
@@ -358,7 +369,9 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec)
}
}
}
+#ifdef ONLY_FOR_HASH_DEBUGGING
DBUG_PRINT("exit", ("hash: 0x%lx", nr));
+#endif
return(nr);
}
@@ -429,7 +442,9 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key)
}
}
}
+#ifdef ONLY_FOR_HASH_DEBUGGING
DBUG_PRINT("exit", ("hash: 0x%lx", nr));
+#endif
return(nr);
}
@@ -467,6 +482,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;
@@ -474,7 +497,9 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec)
}
}
}
+#ifdef ONLY_FOR_HASH_DEBUGGING
DBUG_PRINT("exit", ("hash: 0x%lx", nr));
+#endif
return(nr);
}
@@ -579,7 +604,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;
}
}
@@ -662,7 +698,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;
}
}
@@ -691,6 +738,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;
}
@@ -722,7 +775,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)
{
@@ -786,6 +840,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/heap/hp_rfirst.c b/storage/heap/hp_rfirst.c
index d0d2ec9b506..e45af4a219f 100644
--- a/storage/heap/hp_rfirst.c
+++ b/storage/heap/hp_rfirst.c
@@ -24,6 +24,8 @@ int heap_rfirst(HP_INFO *info, uchar *record, int inx)
DBUG_ENTER("heap_rfirst");
info->lastinx= inx;
+ info->key_version= info->s->key_version;
+
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
{
uchar *pos;
@@ -50,6 +52,7 @@ int heap_rfirst(HP_INFO *info, uchar *record, int inx)
}
else
{
+ info->update= HA_STATE_NO_KEY;
my_errno = HA_ERR_END_OF_FILE;
DBUG_RETURN(my_errno);
}
@@ -57,15 +60,8 @@ int heap_rfirst(HP_INFO *info, uchar *record, int inx)
}
else
{
- if (!(info->s->records))
- {
- my_errno=HA_ERR_END_OF_FILE;
- DBUG_RETURN(my_errno);
- }
- DBUG_ASSERT(0); /* TODO fix it */
- info->current_record=0;
- info->current_hash_ptr=0;
- info->update=HA_STATE_PREV_FOUND;
- DBUG_RETURN(heap_rnext(info,record));
+ /* We can't scan a non existing key value with hash index */
+ my_errno= HA_ERR_WRONG_COMMAND;
+ DBUG_RETURN(my_errno);
}
}
diff --git a/storage/heap/hp_rkey.c b/storage/heap/hp_rkey.c
index 3069b955844..2720e0d0543 100644
--- a/storage/heap/hp_rkey.c
+++ b/storage/heap/hp_rkey.c
@@ -30,6 +30,7 @@ int heap_rkey(HP_INFO *info, uchar *record, int inx, const uchar *key,
}
info->lastinx= inx;
info->current_record= (ulong) ~0L; /* For heap_rrnd() */
+ info->key_version= info->s->key_version;
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
{
@@ -50,7 +51,7 @@ int heap_rkey(HP_INFO *info, uchar *record, int inx, const uchar *key,
if (!(pos= tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents,
&info->last_pos, find_flag, &custom_arg)))
{
- info->update= 0;
+ info->update= HA_STATE_NO_KEY;
DBUG_RETURN(my_errno= HA_ERR_KEY_NOT_FOUND);
}
memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos), sizeof(uchar*));
@@ -60,7 +61,7 @@ int heap_rkey(HP_INFO *info, uchar *record, int inx, const uchar *key,
{
if (!(pos= hp_search(info, share->keydef + inx, key, 0)))
{
- info->update= 0;
+ info->update= HA_STATE_NO_KEY;
DBUG_RETURN(my_errno);
}
if ((keyinfo->flag & (HA_NOSAME | HA_NULL_PART_KEY)) != HA_NOSAME)
diff --git a/storage/heap/hp_rlast.c b/storage/heap/hp_rlast.c
index 45ad7c21f49..0710401e5a5 100644
--- a/storage/heap/hp_rlast.c
+++ b/storage/heap/hp_rlast.c
@@ -25,6 +25,7 @@ int heap_rlast(HP_INFO *info, uchar *record, int inx)
DBUG_ENTER("heap_rlast");
info->lastinx= inx;
+ info->key_version= info->s->key_version;
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
{
uchar *pos;
@@ -47,9 +48,8 @@ int heap_rlast(HP_INFO *info, uchar *record, int inx)
}
else
{
- info->current_ptr=0;
- info->current_hash_ptr=0;
- info->update=HA_STATE_NEXT_FOUND;
- DBUG_RETURN(heap_rprev(info,record));
+ /* We can't scan a non existing key value with hash index */
+ my_errno= HA_ERR_WRONG_COMMAND;
+ DBUG_RETURN(my_errno);
}
}
diff --git a/storage/heap/hp_rnext.c b/storage/heap/hp_rnext.c
index 3d715f4e6d3..7a759e70972 100644
--- a/storage/heap/hp_rnext.c
+++ b/storage/heap/hp_rnext.c
@@ -32,7 +32,20 @@ int heap_rnext(HP_INFO *info, uchar *record)
{
heap_rb_param custom_arg;
- if (info->last_pos)
+ /* If no active record and last was not deleted */
+ if (!(info->update & (HA_STATE_AKTIV | HA_STATE_NO_KEY |
+ HA_STATE_DELETED)))
+ {
+ if (info->update & HA_STATE_NEXT_FOUND)
+ pos= 0; /* Can't search after last row */
+ else
+ {
+ /* Last was 'prev' before first record; search after first record */
+ pos= tree_search_edge(&keyinfo->rb_tree, info->parents,
+ &info->last_pos, offsetof(TREE_ELEMENT, left));
+ }
+ }
+ else if (info->last_pos)
{
/*
We enter this branch for non-DELETE queries after heap_rkey()
@@ -70,6 +83,7 @@ int heap_rnext(HP_INFO *info, uchar *record)
custom_arg.keyseg = keyinfo->seg;
custom_arg.key_length = info->lastkey_len;
custom_arg.search_flag = SEARCH_SAME | SEARCH_FIND;
+ info->last_find_flag= HA_READ_KEY_OR_NEXT;
pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents,
&info->last_pos, info->last_find_flag, &custom_arg);
}
diff --git a/storage/heap/hp_rprev.c b/storage/heap/hp_rprev.c
index 63bfffffba9..8a50444bb5f 100644
--- a/storage/heap/hp_rprev.c
+++ b/storage/heap/hp_rprev.c
@@ -32,7 +32,20 @@ int heap_rprev(HP_INFO *info, uchar *record)
{
heap_rb_param custom_arg;
- if (info->last_pos)
+ /* If no active record and last was not deleted */
+ if (!(info->update & (HA_STATE_AKTIV | HA_STATE_NO_KEY |
+ HA_STATE_DELETED)))
+ {
+ if (info->update & HA_STATE_PREV_FOUND)
+ pos= 0; /* Can't search before first row */
+ else
+ {
+ /* Last was 'next' after last record; search after last record */
+ pos= tree_search_edge(&keyinfo->rb_tree, info->parents,
+ &info->last_pos, offsetof(TREE_ELEMENT, right));
+ }
+ }
+ else if (info->last_pos)
pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos,
offsetof(TREE_ELEMENT, right),
offsetof(TREE_ELEMENT, left));
@@ -41,6 +54,7 @@ int heap_rprev(HP_INFO *info, uchar *record)
custom_arg.keyseg = keyinfo->seg;
custom_arg.key_length = keyinfo->length;
custom_arg.search_flag = SEARCH_SAME;
+ info->last_find_flag= HA_READ_KEY_OR_PREV;
pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents,
&info->last_pos, info->last_find_flag, &custom_arg);
}
diff --git a/storage/heap/hp_rsame.c b/storage/heap/hp_rsame.c
index 1a3724672b6..f93a443aa48 100644
--- a/storage/heap/hp_rsame.c
+++ b/storage/heap/hp_rsame.c
@@ -43,7 +43,7 @@ int heap_rsame(register HP_INFO *info, uchar *record, int inx)
hp_make_key(share->keydef + inx, info->lastkey, record);
if (!hp_search(info, share->keydef + inx, info->lastkey, 3))
{
- info->update=0;
+ info->update= 0;
DBUG_RETURN(my_errno);
}
}
diff --git a/storage/heap/hp_scan.c b/storage/heap/hp_scan.c
index e8913e92c86..397dd8b54d4 100644
--- a/storage/heap/hp_scan.c
+++ b/storage/heap/hp_scan.c
@@ -31,6 +31,8 @@ int heap_scan_init(register HP_INFO *info)
info->current_record= (ulong) ~0L; /* No current record */
info->update=0;
info->next_block=0;
+ info->key_version= info->s->key_version;
+ info->file_version= info->s->file_version;
DBUG_RETURN(0);
}
diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c
index a3a20d9b236..a534a5cf904 100644
--- a/storage/heap/hp_test2.c
+++ b/storage/heap/hp_test2.c
@@ -23,9 +23,6 @@
#ifdef DBUG_OFF
#undef DBUG_OFF
#endif
-#ifndef SAFEMALLOC
-#define SAFEMALLOC 1
-#endif
#include "heapdef.h" /* Because of hp_find_block */
#include <signal.h>
@@ -75,7 +72,7 @@ int main(int argc, char *argv[])
get_options(argc,argv);
bzero(&hp_create_info, sizeof(hp_create_info));
- hp_create_info.max_table_size= 1024L*1024L;
+ hp_create_info.max_table_size= 2*1024L*1024L;
write_count=update=opt_delete=0;
key_check=0;
@@ -321,7 +318,8 @@ int main(int argc, char *argv[])
if (!silent)
printf("- Read last key - delete - prev - prev - opt_delete - prev -> first\n");
- if (heap_rlast(file,record3,0)) goto err;
+ if (heap_rprev(file,record))
+ goto err;
if (heap_delete(file,record3)) goto err;
key_check-=atoi((char*) record3);
key1[atoi((char*) record+keyinfo[0].seg[0].start)]--;
@@ -528,7 +526,7 @@ int main(int argc, char *argv[])
}
ant=0;
- for (error=heap_rlast(file,record,0) ;
+ for (error=heap_rprev(file,record) ;
! error ;
error=heap_rprev(file,record))
{
@@ -644,7 +642,7 @@ static int get_options(int argc,char *argv[])
case 'V':
case 'I':
case '?':
- printf("%s Ver 1.1 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
+ printf("%s Ver 1.2 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
puts("TCX Datakonsult AB, by Monty, for your professional use\n");
printf("Usage: %s [-?ABIKLsWv] [-m#] [-t#]\n",progname);
exit(0);
diff --git a/storage/heap/hp_update.c b/storage/heap/hp_update.c
index 7f469af3c96..ab831382325 100644
--- a/storage/heap/hp_update.c
+++ b/storage/heap/hp_update.c
@@ -21,7 +21,7 @@ int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new)
{
HP_KEYDEF *keydef, *end, *p_lastinx;
uchar *pos;
- my_bool auto_key_changed= 0;
+ my_bool auto_key_changed= 0, key_changed= 0;
HP_SHARE *share= info->s;
DBUG_ENTER("heap_update");
@@ -54,6 +54,8 @@ int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new)
#endif
if (auto_key_changed)
heap_update_auto_increment(info, heap_new);
+ if (key_changed)
+ share->key_version++;
DBUG_RETURN(0);
err:
diff --git a/storage/heap/hp_write.c b/storage/heap/hp_write.c
index d67b55b6481..990fcebcd63 100644
--- a/storage/heap/hp_write.c
+++ b/storage/heap/hp_write.c
@@ -59,6 +59,7 @@ int heap_write(HP_INFO *info, const uchar *record)
pos[share->reclength]=1; /* Mark record as not deleted */
if (++share->records == share->blength)
share->blength+= share->blength;
+ info->s->key_version++;
info->current_ptr=pos;
info->current_hash_ptr=0;
info->update|=HA_STATE_AKTIV;
@@ -153,6 +154,13 @@ static uchar *next_free_record_pos(HP_SHARE *info)
if ((info->records > info->max_records && info->max_records) ||
(info->data_length + info->index_length >= info->max_table_size))
{
+ DBUG_PRINT("error",
+ ("record file full. records: %u max_records: %lu "
+ "data_length: %llu index_length: %llu "
+ "max_table_size: %llu",
+ info->records, info->max_records,
+ info->data_length, info->index_length,
+ info->max_table_size));
my_errno=HA_ERR_RECORD_FILE_FULL;
DBUG_RETURN(NULL);
}
@@ -199,6 +207,7 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
HP_SHARE *share = info->s;
int flag;
ulong halfbuff,hashnr,first_index;
+ ulong UNINIT_VAR(hash_of_key), UNINIT_VAR(hash_of_key2);
uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2);
HASH_INFO *empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos;
DBUG_ENTER("hp_write_key");
@@ -229,7 +238,7 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
{
do
{
- hashnr = hp_rec_hashnr(keyinfo, pos->ptr_to_rec);
+ hashnr = pos->hash_of_key;
if (flag == 0)
{
/*
@@ -261,7 +270,6 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
flag=LOWFIND | HIGHFIND;
/* key shall be moved to the current empty position */
gpos=empty;
- ptr_to_rec=pos->ptr_to_rec;
empty=pos; /* This place is now free */
}
else
@@ -272,7 +280,6 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
*/
flag=LOWFIND | LOWUSED;
gpos=pos;
- ptr_to_rec=pos->ptr_to_rec;
}
}
else
@@ -281,13 +288,15 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
if (!(flag & LOWUSED))
{
/* Change link of previous lower-list key */
- gpos->ptr_to_rec=ptr_to_rec;
- gpos->next_key=pos;
+ gpos->ptr_to_rec= ptr_to_rec;
+ gpos->next_key= pos;
+ gpos->hash_of_key= hash_of_key;
flag= (flag & HIGHFIND) | (LOWFIND | LOWUSED);
}
gpos=pos;
- ptr_to_rec=pos->ptr_to_rec;
}
+ ptr_to_rec= pos->ptr_to_rec;
+ hash_of_key= pos->hash_of_key;
}
else
{
@@ -298,20 +307,21 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
/* key shall be moved to the last (empty) position */
gpos2= empty;
empty= pos;
- ptr_to_rec2=pos->ptr_to_rec;
}
else
{
if (!(flag & HIGHUSED))
{
/* Change link of previous upper-list key and save */
- gpos2->ptr_to_rec=ptr_to_rec2;
- gpos2->next_key=pos;
+ gpos2->ptr_to_rec= ptr_to_rec2;
+ gpos2->next_key= pos;
+ gpos2->hash_of_key= hash_of_key2;
flag= (flag & LOWFIND) | (HIGHFIND | HIGHUSED);
}
gpos2=pos;
- ptr_to_rec2=pos->ptr_to_rec;
}
+ ptr_to_rec2= pos->ptr_to_rec;
+ hash_of_key2= pos->hash_of_key;
}
}
while ((pos=pos->next_key));
@@ -327,23 +337,27 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
if ((flag & (LOWFIND | LOWUSED)) == LOWFIND)
{
- gpos->ptr_to_rec=ptr_to_rec;
- gpos->next_key=0;
+ gpos->ptr_to_rec= ptr_to_rec;
+ gpos->hash_of_key= hash_of_key;
+ gpos->next_key= 0;
}
if ((flag & (HIGHFIND | HIGHUSED)) == HIGHFIND)
{
- gpos2->ptr_to_rec=ptr_to_rec2;
- gpos2->next_key=0;
+ gpos2->ptr_to_rec= ptr_to_rec2;
+ gpos2->hash_of_key= hash_of_key2;
+ gpos2->next_key= 0;
}
}
/* Check if we are at the empty position */
- pos=hp_find_hash(&keyinfo->block, hp_mask(hp_rec_hashnr(keyinfo, record),
- share->blength, share->records + 1));
+ hash_of_key= hp_rec_hashnr(keyinfo, record);
+ pos=hp_find_hash(&keyinfo->block,
+ hp_mask(hash_of_key, share->blength, share->records + 1));
if (pos == empty)
{
- pos->ptr_to_rec=recpos;
- pos->next_key=0;
+ pos->ptr_to_rec= recpos;
+ pos->hash_of_key= hash_of_key;
+ pos->next_key= 0;
keyinfo->hash_buckets++;
}
else
@@ -351,18 +365,17 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
/* Check if more records in same hash-nr family */
empty[0]=pos[0];
gpos=hp_find_hash(&keyinfo->block,
- hp_mask(hp_rec_hashnr(keyinfo, pos->ptr_to_rec),
+ hp_mask(pos->hash_of_key,
share->blength, share->records + 1));
+
+ pos->ptr_to_rec= recpos;
+ pos->hash_of_key= hash_of_key;
if (pos == gpos)
- {
- pos->ptr_to_rec=recpos;
pos->next_key=empty;
- }
else
{
keyinfo->hash_buckets++;
- pos->ptr_to_rec=recpos;
- pos->next_key=0;
+ pos->next_key= 0;
hp_movelink(pos, gpos, empty);
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 194a7eea795..34917029417 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1084,7 +1084,29 @@ innobase_mysql_tmpfile(void)
will be passed to fdopen(), it will be closed by invoking
fclose(), which in turn will invoke close() instead of
my_close(). */
+
+#ifdef _WIN32
+ /* Note that on Windows, the integer returned by mysql_tmpfile
+ has no relation to C runtime file descriptor. Here, we need
+ to call my_get_osfhandle to get the HANDLE and then convert it
+ to C runtime filedescriptor. */
+ {
+ HANDLE hFile = my_get_osfhandle(fd);
+ HANDLE hDup;
+ BOOL bOK =
+ DuplicateHandle(GetCurrentProcess(), hFile, GetCurrentProcess(),
+ &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
+ if(bOK) {
+ fd2 = _open_osfhandle((intptr_t)hDup,0);
+ }
+ else {
+ my_osmaperr(GetLastError());
+ fd2 = -1;
+ }
+ }
+#else
fd2 = dup(fd);
+#endif
if (fd2 < 0) {
DBUG_PRINT("error",("Got error %d on dup",fd2));
my_errno=errno;
@@ -3393,90 +3415,64 @@ get_innobase_type_from_mysql_type(
8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to
the type */
- DBUG_ASSERT((ulint)MYSQL_TYPE_STRING < 256);
- DBUG_ASSERT((ulint)MYSQL_TYPE_VAR_STRING < 256);
- DBUG_ASSERT((ulint)MYSQL_TYPE_DOUBLE < 256);
- DBUG_ASSERT((ulint)MYSQL_TYPE_FLOAT < 256);
- DBUG_ASSERT((ulint)MYSQL_TYPE_DECIMAL < 256);
+ compile_time_assert((ulint)MYSQL_TYPE_STRING < 256);
+ compile_time_assert((ulint)MYSQL_TYPE_VAR_STRING < 256);
+ compile_time_assert((ulint)MYSQL_TYPE_DOUBLE < 256);
+ compile_time_assert((ulint)MYSQL_TYPE_FLOAT < 256);
+ compile_time_assert((ulint)MYSQL_TYPE_DECIMAL < 256);
- if (field->flags & UNSIGNED_FLAG) {
+ *unsigned_flag = 0;
+ switch (field->key_type()) {
+ case HA_KEYTYPE_USHORT_INT:
+ case HA_KEYTYPE_ULONG_INT:
+ case HA_KEYTYPE_UINT24:
+ case HA_KEYTYPE_ULONGLONG:
*unsigned_flag = DATA_UNSIGNED;
- } else {
- *unsigned_flag = 0;
- }
-
- if (field->real_type() == MYSQL_TYPE_ENUM
- || field->real_type() == MYSQL_TYPE_SET) {
-
- /* MySQL has field->type() a string type for these, but the
- data is actually internally stored as an unsigned integer
- code! */
-
- *unsigned_flag = DATA_UNSIGNED; /* MySQL has its own unsigned
- flag set to zero, even though
- internally this is an unsigned
- integer type */
+ /* fall through */
+ case HA_KEYTYPE_SHORT_INT:
+ case HA_KEYTYPE_LONG_INT:
+ case HA_KEYTYPE_INT24:
+ case HA_KEYTYPE_INT8:
+ case HA_KEYTYPE_LONGLONG:
return(DATA_INT);
- }
-
- switch (field->type()) {
- /* NOTE that we only allow string types in DATA_MYSQL and
- DATA_VARMYSQL */
- case MYSQL_TYPE_VAR_STRING: /* old <= 4.1 VARCHAR */
- case MYSQL_TYPE_VARCHAR: /* new >= 5.0.3 true VARCHAR */
- if (field->binary()) {
- return(DATA_BINARY);
- } else if (strcmp(
- field->charset()->name,
- "latin1_swedish_ci") == 0) {
+ case HA_KEYTYPE_FLOAT:
+ return(DATA_FLOAT);
+ case HA_KEYTYPE_DOUBLE:
+ return(DATA_DOUBLE);
+ case HA_KEYTYPE_BINARY:
+ if (field->type() == MYSQL_TYPE_TINY)
+ { // compatibility workaround
+ *unsigned_flag= DATA_UNSIGNED ;
+ return DATA_INT;
+ }
+ return(DATA_FIXBINARY);
+ case HA_KEYTYPE_VARBINARY2:
+ if (field->type() != MYSQL_TYPE_VARCHAR)
+ return(DATA_BLOB);
+ /* fall through */
+ case HA_KEYTYPE_VARBINARY1:
+ return(DATA_BINARY);
+ case HA_KEYTYPE_VARTEXT2:
+ if (field->type() != MYSQL_TYPE_VARCHAR)
+ return(DATA_BLOB);
+ /* fall through */
+ case HA_KEYTYPE_VARTEXT1:
+ if (field->charset() == &my_charset_latin1) {
return(DATA_VARCHAR);
} else {
return(DATA_VARMYSQL);
}
- case MYSQL_TYPE_BIT:
- case MYSQL_TYPE_STRING: if (field->binary()) {
-
- return(DATA_FIXBINARY);
- } else if (strcmp(
- field->charset()->name,
- "latin1_swedish_ci") == 0) {
+ case HA_KEYTYPE_TEXT:
+ if (field->charset() == &my_charset_latin1) {
return(DATA_CHAR);
} else {
return(DATA_MYSQL);
}
- case MYSQL_TYPE_NEWDECIMAL:
- return(DATA_FIXBINARY);
- case MYSQL_TYPE_LONG:
- case MYSQL_TYPE_LONGLONG:
- case MYSQL_TYPE_TINY:
- case MYSQL_TYPE_SHORT:
- case MYSQL_TYPE_INT24:
- case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_DATETIME:
- case MYSQL_TYPE_YEAR:
- case MYSQL_TYPE_NEWDATE:
- case MYSQL_TYPE_TIME:
- case MYSQL_TYPE_TIMESTAMP:
- return(DATA_INT);
- case MYSQL_TYPE_FLOAT:
- return(DATA_FLOAT);
- case MYSQL_TYPE_DOUBLE:
- return(DATA_DOUBLE);
- case MYSQL_TYPE_DECIMAL:
+ case HA_KEYTYPE_NUM:
return(DATA_DECIMAL);
- case MYSQL_TYPE_GEOMETRY:
- case MYSQL_TYPE_TINY_BLOB:
- case MYSQL_TYPE_MEDIUM_BLOB:
- case MYSQL_TYPE_BLOB:
- case MYSQL_TYPE_LONG_BLOB:
- return(DATA_BLOB);
- case MYSQL_TYPE_NULL:
- /* MySQL currently accepts "NULL" datatype, but will
- reject such datatype in the next release. We will cope
- with it and not trigger assertion failure in 5.1 */
- break;
- default:
+ case HA_KEYTYPE_BIT:
+ case HA_KEYTYPE_END:
assert(0);
}
@@ -6787,6 +6783,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/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index 93229ad9185..5ce50720d30 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -98,10 +98,14 @@ class ha_innobase: public handler
Table_flags table_flags() const;
ulong index_flags(uint idx, uint part, bool all_parts) const
{
+ ulong extra_flag= 0;
+ if (table && idx == table->s->primary_key)
+ extra_flag= HA_CLUSTERED_INDEX;
return (HA_READ_NEXT |
HA_READ_PREV |
HA_READ_ORDER |
HA_READ_RANGE |
+ extra_flag |
HA_KEYREAD_ONLY);
}
uint max_supported_keys() const { return MAX_KEY; }
diff --git a/storage/innodb_plugin/btr/btr0sea.c b/storage/innodb_plugin/btr/btr0sea.c
index 3dd30cbc0f3..f10c207b76a 100644
--- a/storage/innodb_plugin/btr/btr0sea.c
+++ b/storage/innodb_plugin/btr/btr0sea.c
@@ -524,7 +524,7 @@ btr_search_update_hash_ref(
{
dict_index_t* index;
ulint fold;
- const rec_t* rec;
+ rec_t* rec;
ut_ad(cursor->flag == BTR_CUR_HASH_FAIL);
#ifdef UNIV_SYNC_DEBUG
@@ -827,7 +827,7 @@ btr_search_guess_on_hash(
mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
- const rec_t* rec;
+ rec_t* rec;
ulint fold;
dulint index_id;
#ifdef notdefined
@@ -913,7 +913,7 @@ btr_search_guess_on_hash(
ut_ad(page_rec_is_user_rec(rec));
- btr_cur_position(index, (rec_t*) rec, block, cursor);
+ btr_cur_position(index, rec, block, cursor);
/* Check the validity of the guess within the page */
diff --git a/storage/innodb_plugin/ha/ha0ha.c b/storage/innodb_plugin/ha/ha0ha.c
index 65046138275..594a10dc431 100644
--- a/storage/innodb_plugin/ha/ha0ha.c
+++ b/storage/innodb_plugin/ha/ha0ha.c
@@ -106,7 +106,7 @@ ha_insert_for_fold_func(
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
buf_block_t* block, /*!< in: buffer block containing the data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- const rec_t* data) /*!< in: data, must not be NULL */
+ rec_t* data) /*!< in: data, must not be NULL */
{
hash_cell_t* cell;
ha_node_t* node;
@@ -238,11 +238,11 @@ ha_search_and_update_if_found_func(
/*===============================*/
hash_table_t* table, /*!< in/out: hash table */
ulint fold, /*!< in: folded value of the searched data */
- const rec_t* data, /*!< in: pointer to the data */
+ rec_t* data, /*!< in: pointer to the data */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
buf_block_t* new_block,/*!< in: block containing new_data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- const rec_t* new_data)/*!< in: new pointer to the data */
+ rec_t* new_data)/*!< in: new pointer to the data */
{
ha_node_t* node;
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index 538e236ccd0..2b73c4e3e06 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -32,7 +32,8 @@ this program; if not, write to the Free Software Foundation, Inc.,
*****************************************************************************/
/* TODO list for the InnoDB handler in 5.0:
- - Remove the flag trx->active_trans and look at trx->conc_state
+ - Remove the flag trx->active_flag & TRX_ACTIVE_IN_MYSQL and look
+ at trx->conc_state
- fix savepoint functions to use savepoint storage area
- Find out what kind of problems the OS X case-insensitivity causes to
table and database names; should we 'normalize' the names like we do
@@ -48,7 +49,9 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include <m_ctype.h>
#include <mysys_err.h>
#include <mysql/plugin.h>
-
+#ifdef _WIN32
+#include <io.h>
+#endif
/** @file ha_innodb.cc */
/* Include necessary InnoDB headers */
@@ -102,8 +105,6 @@ bool check_global_access(THD *thd, ulong want_access);
/** to protect innobase_open_files */
static pthread_mutex_t innobase_share_mutex;
-/** to force correct commit order in binlog */
-static pthread_mutex_t prepare_commit_mutex;
static ulong commit_threads = 0;
static pthread_mutex_t commit_threads_m;
static pthread_cond_t commit_cond;
@@ -216,6 +217,7 @@ static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
static INNOBASE_SHARE *get_share(const char *table_name);
static void free_share(INNOBASE_SHARE *share);
static int innobase_close_connection(handlerton *hton, THD* thd);
+static void innobase_commit_ordered(handlerton *hton, THD* thd, bool all);
static int innobase_commit(handlerton *hton, THD* thd, bool all);
static int innobase_rollback(handlerton *hton, THD* thd, bool all);
static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
@@ -1224,7 +1226,28 @@ innobase_mysql_tmpfile(void)
will be passed to fdopen(), it will be closed by invoking
fclose(), which in turn will invoke close() instead of
my_close(). */
+#ifdef _WIN32
+ /* Note that on Windows, the integer returned by mysql_tmpfile
+ has no relation to C runtime file descriptor. Here, we need
+ to call my_get_osfhandle to get the HANDLE and then convert it
+ to C runtime filedescriptor. */
+ {
+ HANDLE hFile = my_get_osfhandle(fd);
+ HANDLE hDup;
+ BOOL bOK =
+ DuplicateHandle(GetCurrentProcess(), hFile, GetCurrentProcess(),
+ &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
+ if(bOK) {
+ fd2 = _open_osfhandle((intptr_t)hDup,0);
+ }
+ else {
+ my_osmaperr(GetLastError());
+ fd2 = -1;
+ }
+ }
+#else
fd2 = dup(fd);
+#endif
if (fd2 < 0) {
DBUG_PRINT("error",("Got error %d on dup",fd2));
my_errno=errno;
@@ -1323,7 +1346,8 @@ innobase_next_autoinc(
ulonglong current, /*!< in: Current value */
ulonglong increment, /*!< in: increment current by */
ulonglong offset, /*!< in: AUTOINC offset */
- ulonglong max_value) /*!< in: max value for type */
+ ulonglong max_value, /*!< in: max value for type */
+ ulonglong reserve) /*!< in: how many values to reserve */
{
ulonglong next_value;
@@ -1332,51 +1356,16 @@ innobase_next_autoinc(
/* According to MySQL documentation, if the offset is greater than
the increment then the offset is ignored. */
- if (offset > increment) {
+ if (offset >= increment)
offset = 0;
- }
-
- if (max_value <= current) {
- next_value = max_value;
- } else if (offset <= 1) {
- /* Offset 0 and 1 are the same, because there must be at
- least one node in the system. */
- if (max_value - current <= increment) {
- next_value = max_value;
- } else {
- next_value = current + increment;
- }
- } else if (max_value > current) {
- if (current > offset) {
- next_value = ((current - offset) / increment) + 1;
- } else {
- next_value = ((offset - current) / increment) + 1;
- }
-
- ut_a(increment > 0);
- ut_a(next_value > 0);
-
- /* Check for multiplication overflow. */
- if (increment > (max_value / next_value)) {
-
- next_value = max_value;
- } else {
- next_value *= increment;
- ut_a(max_value >= next_value);
-
- /* Check for overflow. */
- if (max_value - next_value <= offset) {
- next_value = max_value;
- } else {
- next_value += offset;
- }
- }
- } else {
- next_value = max_value;
- }
-
- ut_a(next_value <= max_value);
+ if (max_value <= current)
+ return max_value;
+ next_value = (current / increment) + reserve;
+ next_value = next_value * increment + offset;
+ /* Check for overflow. */
+ if (next_value < current || next_value > max_value)
+ next_value = max_value;
return(next_value);
}
@@ -1391,7 +1380,6 @@ innobase_trx_init(
trx_t* trx) /*!< in/out: InnoDB transaction handle */
{
DBUG_ENTER("innobase_trx_init");
- DBUG_ASSERT(EQ_CURRENT_THD(thd));
DBUG_ASSERT(thd == trx->mysql_thd);
trx->check_foreigns = !thd_test_options(
@@ -1440,8 +1428,6 @@ check_trx_exists(
{
trx_t*& trx = thd_to_trx(thd);
- ut_ad(EQ_CURRENT_THD(thd));
-
if (trx == NULL) {
trx = innobase_trx_allocate(thd);
} else if (UNIV_UNLIKELY(trx->magic_n != TRX_MAGIC_N)) {
@@ -1707,10 +1693,10 @@ innobase_query_caching_of_table_permitted(
/* The call of row_search_.. will start a new transaction if it is
not yet started */
- if (trx->active_trans == 0) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0) {
innobase_register_trx_and_stmt(innodb_hton_ptr, thd);
- trx->active_trans = 1;
+ trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
}
if (row_search_check_if_query_cache_permitted(trx, norm_name)) {
@@ -1980,11 +1966,11 @@ ha_innobase::init_table_handle_for_HANDLER(void)
/* Set the MySQL flag to mark that there is an active transaction */
- if (prebuilt->trx->active_trans == 0) {
+ if ((prebuilt->trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0) {
innobase_register_trx_and_stmt(ht, user_thd);
- prebuilt->trx->active_trans = 1;
+ prebuilt->trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
}
/* We did the necessary inits in this function, no need to repeat them
@@ -2035,6 +2021,8 @@ innobase_init(
innobase_hton->savepoint_set=innobase_savepoint;
innobase_hton->savepoint_rollback=innobase_rollback_to_savepoint;
innobase_hton->savepoint_release=innobase_release_savepoint;
+ innobase_hton->prepare_ordered=NULL;
+ innobase_hton->commit_ordered=innobase_commit_ordered;
innobase_hton->commit=innobase_commit;
innobase_hton->rollback=innobase_rollback;
innobase_hton->prepare=innobase_xa_prepare;
@@ -2339,7 +2327,6 @@ innobase_change_buffering_inited_ok:
innobase_open_tables = hash_create(200);
pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
pthread_cond_init(&commit_cond, NULL);
@@ -2393,7 +2380,6 @@ innobase_end(
my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR));
pthread_mutex_destroy(&innobase_share_mutex);
- pthread_mutex_destroy(&prepare_commit_mutex);
pthread_mutex_destroy(&commit_threads_m);
pthread_mutex_destroy(&commit_cond_m);
pthread_cond_destroy(&commit_cond);
@@ -2492,14 +2478,118 @@ innobase_start_trx_and_assign_read_view(
/* Set the MySQL flag to mark that there is an active transaction */
- if (trx->active_trans == 0) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0) {
innobase_register_trx_and_stmt(hton, thd);
- trx->active_trans = 1;
+ trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
}
DBUG_RETURN(0);
}
+static
+void
+innobase_commit_ordered_2(
+/*============*/
+ trx_t* trx, /*!< in: Innodb transaction */
+ THD* thd) /*!< in: MySQL thread handle */
+{
+ ulonglong tmp_pos;
+ DBUG_ENTER("innobase_commit_ordered");
+
+ /* We need current binlog position for ibbackup to work.
+ Note, the position is current because commit_ordered is guaranteed
+ to be called in same sequenece as writing to binlog. */
+
+retry:
+ if (innobase_commit_concurrency > 0) {
+ pthread_mutex_lock(&commit_cond_m);
+ commit_threads++;
+
+ if (commit_threads > innobase_commit_concurrency) {
+ commit_threads--;
+ pthread_cond_wait(&commit_cond,
+ &commit_cond_m);
+ pthread_mutex_unlock(&commit_cond_m);
+ goto retry;
+ }
+ else {
+ pthread_mutex_unlock(&commit_cond_m);
+ }
+ }
+
+ mysql_bin_log_commit_pos(thd, &tmp_pos, &(trx->mysql_log_file_name));
+ trx->mysql_log_offset = (ib_int64_t) tmp_pos;
+
+ /* Don't do write + flush right now. For group commit
+ to work we want to do the flush in the innobase_commit()
+ method, which runs without holding any locks. */
+ trx->flush_log_later = TRUE;
+ innobase_commit_low(trx);
+ trx->flush_log_later = FALSE;
+
+ if (innobase_commit_concurrency > 0) {
+ pthread_mutex_lock(&commit_cond_m);
+ commit_threads--;
+ pthread_cond_signal(&commit_cond);
+ pthread_mutex_unlock(&commit_cond_m);
+ }
+
+ DBUG_VOID_RETURN;
+}
+
+/*****************************************************************//**
+Perform the first, fast part of InnoDB commit.
+
+Doing it in this call ensures that we get the same commit order here
+as in binlog and any other participating transactional storage engines.
+
+Note that we want to do as little as really needed here, as we run
+under a global mutex. The expensive fsync() is done later, in
+innobase_commit(), without a lock so group commit can take place.
+
+Note also that this method can be called from a different thread than
+the one handling the rest of the transaction. */
+static
+void
+innobase_commit_ordered(
+/*============*/
+ handlerton *hton, /*!< in: Innodb handlerton */
+ THD* thd, /*!< in: MySQL thread handle of the user for whom
+ the transaction should be committed */
+ bool all) /*!< in: TRUE - commit transaction
+ FALSE - the current SQL statement ended */
+{
+ trx_t* trx;
+ DBUG_ENTER("innobase_commit_ordered");
+ DBUG_ASSERT(hton == innodb_hton_ptr);
+
+ trx = check_trx_exists(thd);
+
+ /* Since we will reserve the kernel mutex, we must not be holding the
+ search system latch, or we will disobey the latching order. But we
+ already released it in innobase_xa_prepare() (if not before), so just
+ have an assert here.*/
+ ut_ad(!trx->has_search_latch);
+
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0
+ && trx->conc_state != TRX_NOT_STARTED) {
+ /* We cannot throw error here; instead we will catch this error
+ again in innobase_commit() and report it from there. */
+ DBUG_VOID_RETURN;
+ }
+
+ /* commit_ordered is only called when committing the whole transaction
+ (or an SQL statement when autocommit is on). */
+ DBUG_ASSERT(all ||
+ (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)));
+
+ innobase_commit_ordered_2(trx, thd);
+
+ trx->active_flag |= TRX_ACTIVE_COMMIT_ORDERED;
+
+ DBUG_VOID_RETURN;
+}
+
/*****************************************************************//**
Commits a transaction in an InnoDB database or marks an SQL statement
ended.
@@ -2525,11 +2615,12 @@ innobase_commit(
/* Since we will reserve the kernel mutex, we have to release
the search system latch first to obey the latching order. */
- if (trx->has_search_latch) {
+ if (trx->has_search_latch &&
+ (trx->active_flag & TRX_ACTIVE_COMMIT_ORDERED) == 0) {
trx_search_latch_release_if_reserved(trx);
}
- /* The flag trx->active_trans is set to 1 in
+ /* The flag TRX_ACTIVE_IN_MYSQL in trx->active_flag is set in
1. ::external_lock(),
2. ::start_stmt(),
@@ -2539,81 +2630,33 @@ innobase_commit(
6. innobase_start_trx_and_assign_read_view(),
7. ::transactional_table_lock()
- and it is only set to 0 in a commit or a rollback. If it is 0 we know
+ and it is only cleared in a commit or a rollback. If it is unset we know
there cannot be resources to be freed and we could return immediately.
For the time being, we play safe and do the cleanup though there should
be nothing to clean up. */
- if (trx->active_trans == 0
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0
&& trx->conc_state != TRX_NOT_STARTED) {
- sql_print_error("trx->active_trans == 0, but"
- " trx->conc_state != TRX_NOT_STARTED");
+ sql_print_error("trx->active_flag & TRX_ACTIVE_IN_MYSQL== 0,"
+ " but trx->conc_state != TRX_NOT_STARTED");
}
+
if (all
|| (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
- /* We were instructed to commit the whole transaction, or
- this is an SQL statement end and autocommit is on */
-
- /* We need current binlog position for ibbackup to work.
- Note, the position is current because of
- prepare_commit_mutex */
-retry:
- if (innobase_commit_concurrency > 0) {
- pthread_mutex_lock(&commit_cond_m);
- commit_threads++;
-
- if (commit_threads > innobase_commit_concurrency) {
- commit_threads--;
- pthread_cond_wait(&commit_cond,
- &commit_cond_m);
- pthread_mutex_unlock(&commit_cond_m);
- goto retry;
- }
- else {
- pthread_mutex_unlock(&commit_cond_m);
- }
+ /* Run the fast part of commit if we did not already. */
+ if ((trx->active_flag & TRX_ACTIVE_COMMIT_ORDERED) == 0) {
+ innobase_commit_ordered_2(trx, thd);
}
- /* The following calls to read the MySQL binary log
- file name and the position return consistent results:
- 1) Other InnoDB transactions cannot intervene between
- these calls as we are holding prepare_commit_mutex.
- 2) Binary logging of other engines is not relevant
- to InnoDB as all InnoDB requires is that committing
- InnoDB transactions appear in the same order in the
- MySQL binary log as they appear in InnoDB logs.
- 3) A MySQL log file rotation cannot happen because
- MySQL protects against this by having a counter of
- transactions in prepared state and it only allows
- a rotation when the counter drops to zero. See
- LOCK_prep_xids and COND_prep_xids in log.cc. */
- trx->mysql_log_file_name = mysql_bin_log_file_name();
- trx->mysql_log_offset = (ib_int64_t) mysql_bin_log_file_pos();
-
- /* Don't do write + flush right now. For group commit
- to work we want to do the flush after releasing the
- prepare_commit_mutex. */
- trx->flush_log_later = TRUE;
- innobase_commit_low(trx);
- trx->flush_log_later = FALSE;
-
- if (innobase_commit_concurrency > 0) {
- pthread_mutex_lock(&commit_cond_m);
- commit_threads--;
- pthread_cond_signal(&commit_cond);
- pthread_mutex_unlock(&commit_cond_m);
- }
-
- if (trx->active_trans == 2) {
-
- pthread_mutex_unlock(&prepare_commit_mutex);
- }
+ /* We were instructed to commit the whole transaction, or
+ this is an SQL statement end and autocommit is on */
- /* Now do a write + flush of logs. */
+ /* We did the first part already in innobase_commit_ordered(),
+ Now finish by doing a write + flush of logs. */
trx_commit_complete_for_mysql(trx);
- trx->active_trans = 0;
+ trx->active_flag = 0;
} else {
/* We just mark the SQL statement ended and do not do a
@@ -2686,7 +2729,7 @@ innobase_rollback(
|| !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
error = trx_rollback_for_mysql(trx);
- trx->active_trans = 0;
+ trx->active_flag = 0;
} else {
error = trx_rollback_last_sql_stat_for_mysql(trx);
}
@@ -2830,7 +2873,7 @@ innobase_savepoint(
innobase_release_stat_resources(trx);
/* cannot happen outside of transaction */
- DBUG_ASSERT(trx->active_trans);
+ DBUG_ASSERT(trx->active_flag & TRX_ACTIVE_IN_MYSQL);
/* TODO: use provided savepoint data area to store savepoint data */
char name[64];
@@ -2860,11 +2903,11 @@ innobase_close_connection(
ut_a(trx);
- if (trx->active_trans == 0
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0
&& trx->conc_state != TRX_NOT_STARTED) {
- sql_print_error("trx->active_trans == 0, but"
- " trx->conc_state != TRX_NOT_STARTED");
+ sql_print_error("trx->active_flag & TRX_ACTIVE_IN_MYSQL == 0,"
+ " but trx->conc_state != TRX_NOT_STARTED");
}
@@ -2992,12 +3035,15 @@ UNIV_INTERN
ulong
ha_innobase::index_flags(
/*=====================*/
- uint,
+ uint index,
uint,
bool)
const
{
- return(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER
+ ulong extra_flag= 0;
+ if (table && index == table->s->primary_key)
+ extra_flag= HA_CLUSTERED_INDEX;
+ return(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | extra_flag
| HA_READ_RANGE | HA_KEYREAD_ONLY);
}
@@ -3528,8 +3574,7 @@ ha_innobase::innobase_initialize_autoinc()
nor the offset, so use a default increment of 1. */
auto_inc = innobase_next_autoinc(
- read_auto_inc, 1, 1, col_max_value);
-
+ read_auto_inc, 1, 1, col_max_value, 1);
break;
}
case DB_RECORD_NOT_FOUND:
@@ -4132,90 +4177,64 @@ get_innobase_type_from_mysql_type(
8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to
the type */
- DBUG_ASSERT((ulint)MYSQL_TYPE_STRING < 256);
- DBUG_ASSERT((ulint)MYSQL_TYPE_VAR_STRING < 256);
- DBUG_ASSERT((ulint)MYSQL_TYPE_DOUBLE < 256);
- DBUG_ASSERT((ulint)MYSQL_TYPE_FLOAT < 256);
- DBUG_ASSERT((ulint)MYSQL_TYPE_DECIMAL < 256);
+ compile_time_assert((ulint)MYSQL_TYPE_STRING < 256);
+ compile_time_assert((ulint)MYSQL_TYPE_VAR_STRING < 256);
+ compile_time_assert((ulint)MYSQL_TYPE_DOUBLE < 256);
+ compile_time_assert((ulint)MYSQL_TYPE_FLOAT < 256);
+ compile_time_assert((ulint)MYSQL_TYPE_DECIMAL < 256);
- if (field->flags & UNSIGNED_FLAG) {
+ *unsigned_flag = 0;
+ switch (field->key_type()) {
+ case HA_KEYTYPE_USHORT_INT:
+ case HA_KEYTYPE_ULONG_INT:
+ case HA_KEYTYPE_UINT24:
+ case HA_KEYTYPE_ULONGLONG:
*unsigned_flag = DATA_UNSIGNED;
- } else {
- *unsigned_flag = 0;
- }
-
- if (field->real_type() == MYSQL_TYPE_ENUM
- || field->real_type() == MYSQL_TYPE_SET) {
-
- /* MySQL has field->type() a string type for these, but the
- data is actually internally stored as an unsigned integer
- code! */
-
- *unsigned_flag = DATA_UNSIGNED; /* MySQL has its own unsigned
- flag set to zero, even though
- internally this is an unsigned
- integer type */
+ /* fall through */
+ case HA_KEYTYPE_SHORT_INT:
+ case HA_KEYTYPE_LONG_INT:
+ case HA_KEYTYPE_INT24:
+ case HA_KEYTYPE_INT8:
+ case HA_KEYTYPE_LONGLONG:
return(DATA_INT);
- }
-
- switch (field->type()) {
- /* NOTE that we only allow string types in DATA_MYSQL and
- DATA_VARMYSQL */
- case MYSQL_TYPE_VAR_STRING: /* old <= 4.1 VARCHAR */
- case MYSQL_TYPE_VARCHAR: /* new >= 5.0.3 true VARCHAR */
- if (field->binary()) {
- return(DATA_BINARY);
- } else if (strcmp(
- field->charset()->name,
- "latin1_swedish_ci") == 0) {
+ case HA_KEYTYPE_FLOAT:
+ return(DATA_FLOAT);
+ case HA_KEYTYPE_DOUBLE:
+ return(DATA_DOUBLE);
+ case HA_KEYTYPE_BINARY:
+ if (field->type() == MYSQL_TYPE_TINY)
+ { // compatibility workaround
+ *unsigned_flag= DATA_UNSIGNED;
+ return DATA_INT;
+ }
+ return(DATA_FIXBINARY);
+ case HA_KEYTYPE_VARBINARY2:
+ if (field->type() != MYSQL_TYPE_VARCHAR)
+ return(DATA_BLOB);
+ /* fall through */
+ case HA_KEYTYPE_VARBINARY1:
+ return(DATA_BINARY);
+ case HA_KEYTYPE_VARTEXT2:
+ if (field->type() != MYSQL_TYPE_VARCHAR)
+ return(DATA_BLOB);
+ /* fall through */
+ case HA_KEYTYPE_VARTEXT1:
+ if (field->charset() == &my_charset_latin1) {
return(DATA_VARCHAR);
} else {
return(DATA_VARMYSQL);
}
- case MYSQL_TYPE_BIT:
- case MYSQL_TYPE_STRING: if (field->binary()) {
-
- return(DATA_FIXBINARY);
- } else if (strcmp(
- field->charset()->name,
- "latin1_swedish_ci") == 0) {
+ case HA_KEYTYPE_TEXT:
+ if (field->charset() == &my_charset_latin1) {
return(DATA_CHAR);
} else {
return(DATA_MYSQL);
}
- case MYSQL_TYPE_NEWDECIMAL:
- return(DATA_FIXBINARY);
- case MYSQL_TYPE_LONG:
- case MYSQL_TYPE_LONGLONG:
- case MYSQL_TYPE_TINY:
- case MYSQL_TYPE_SHORT:
- case MYSQL_TYPE_INT24:
- case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_DATETIME:
- case MYSQL_TYPE_YEAR:
- case MYSQL_TYPE_NEWDATE:
- case MYSQL_TYPE_TIME:
- case MYSQL_TYPE_TIMESTAMP:
- return(DATA_INT);
- case MYSQL_TYPE_FLOAT:
- return(DATA_FLOAT);
- case MYSQL_TYPE_DOUBLE:
- return(DATA_DOUBLE);
- case MYSQL_TYPE_DECIMAL:
+ case HA_KEYTYPE_NUM:
return(DATA_DECIMAL);
- case MYSQL_TYPE_GEOMETRY:
- case MYSQL_TYPE_TINY_BLOB:
- case MYSQL_TYPE_MEDIUM_BLOB:
- case MYSQL_TYPE_BLOB:
- case MYSQL_TYPE_LONG_BLOB:
- return(DATA_BLOB);
- case MYSQL_TYPE_NULL:
- /* MySQL currently accepts "NULL" datatype, but will
- reject such datatype in the next release. We will cope
- with it and not trigger assertion failure in 5.1 */
- break;
- default:
+ case HA_KEYTYPE_BIT:
+ case HA_KEYTYPE_END:
ut_error;
}
@@ -4930,7 +4949,7 @@ no_commit:
/* Altering to InnoDB format */
innobase_commit(ht, user_thd, 1);
/* Note that this transaction is still active. */
- prebuilt->trx->active_trans = 1;
+ prebuilt->trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
/* We will need an IX lock on the destination table. */
prebuilt->sql_stat_start = TRUE;
} else {
@@ -4946,7 +4965,7 @@ no_commit:
locks, so they have to be acquired again. */
innobase_commit(ht, user_thd, 1);
/* Note that this transaction is still active. */
- prebuilt->trx->active_trans = 1;
+ prebuilt->trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
/* Re-acquire the table lock on the source table. */
row_lock_table_for_mysql(prebuilt, src_table, mode);
/* We will need an IX lock on the destination table. */
@@ -5069,7 +5088,7 @@ set_max_autoinc:
auto_inc = innobase_next_autoinc(
auto_inc,
- need, offset, col_max_value);
+ need, offset, col_max_value, 1);
err = innobase_set_max_autoinc(
auto_inc);
@@ -5328,7 +5347,7 @@ ha_innobase::update_row(
need = prebuilt->autoinc_increment;
auto_inc = innobase_next_autoinc(
- auto_inc, need, offset, col_max_value);
+ auto_inc, need, offset, col_max_value, 1);
error = innobase_set_max_autoinc(auto_inc);
}
@@ -7988,6 +8007,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;
@@ -8797,10 +8818,10 @@ ha_innobase::start_stmt(
trx->detailed_error[0] = '\0';
/* Set the MySQL flag to mark that there is an active transaction */
- if (trx->active_trans == 0) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0) {
innobase_register_trx_and_stmt(ht, thd);
- trx->active_trans = 1;
+ trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
} else {
innobase_register_stmt(ht, thd);
}
@@ -8906,10 +8927,10 @@ ha_innobase::external_lock(
/* Set the MySQL flag to mark that there is an active
transaction */
- if (trx->active_trans == 0) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0) {
innobase_register_trx_and_stmt(ht, thd);
- trx->active_trans = 1;
+ trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
} else if (trx->n_mysql_tables_in_use == 0) {
innobase_register_stmt(ht, thd);
}
@@ -8988,7 +9009,7 @@ ha_innobase::external_lock(
prebuilt->used_in_HANDLER = FALSE;
if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
- if (trx->active_trans != 0) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) != 0) {
innobase_commit(ht, thd, TRUE);
}
} else {
@@ -9069,10 +9090,10 @@ ha_innobase::transactional_table_lock(
/* MySQL is setting a new transactional table lock */
/* Set the MySQL flag to mark that there is an active transaction */
- if (trx->active_trans == 0) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0) {
innobase_register_trx_and_stmt(ht, thd);
- trx->active_trans = 1;
+ trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
}
if (THDVAR(thd, table_locks) && thd_in_lock_tables(thd)) {
@@ -9821,16 +9842,14 @@ ha_innobase::get_auto_increment(
/* With old style AUTOINC locking we only update the table's
AUTOINC counter after attempting to insert the row. */
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
- ulonglong need;
ulonglong current;
ulonglong next_value;
current = *first_value > col_max_value ? autoinc : *first_value;
- need = *nb_reserved_values * increment;
-
+
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
- current, need, offset, col_max_value);
+ current, increment, offset, col_max_value, *nb_reserved_values);
prebuilt->autoinc_last_value = next_value;
@@ -10128,10 +10147,11 @@ innobase_xa_prepare(
innobase_release_stat_resources(trx);
- if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0 &&
+ trx->conc_state != TRX_NOT_STARTED) {
- sql_print_error("trx->active_trans == 0, but trx->conc_state != "
- "TRX_NOT_STARTED");
+ sql_print_error("trx->active_flag & TRX_ACTIVE_IN_MYSQL == 0, but"
+ " trx->conc_state != TRX_NOT_STARTED");
}
if (all
@@ -10140,7 +10160,7 @@ innobase_xa_prepare(
/* We were instructed to prepare the whole transaction, or
this is an SQL statement end and autocommit is on */
- ut_ad(trx->active_trans);
+ ut_ad(trx->active_flag & TRX_ACTIVE_IN_MYSQL);
error = (int) trx_prepare_for_mysql(trx);
} else {
@@ -10164,32 +10184,6 @@ innobase_xa_prepare(
srv_active_wake_master_thread();
- if (thd_sql_command(thd) != SQLCOM_XA_PREPARE &&
- (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
- {
-
- /* For ibbackup to work the order of transactions in binlog
- and InnoDB must be the same. Consider the situation
-
- thread1> prepare; write to binlog; ...
- <context switch>
- thread2> prepare; write to binlog; commit
- thread1> ... commit
-
- To ensure this will not happen we're taking the mutex on
- prepare, and releasing it on commit.
-
- Note: only do it for normal commits, done via ha_commit_trans.
- If 2pc protocol is executed by external transaction
- coordinator, it will be just a regular MySQL client
- executing XA PREPARE and XA COMMIT commands.
- In this case we cannot know how many minutes or hours
- will be between XA PREPARE and XA COMMIT, and we don't want
- to block for undefined period of time. */
- pthread_mutex_lock(&prepare_commit_mutex);
- trx->active_trans = 2;
- }
-
return(error);
}
diff --git a/storage/innodb_plugin/handler/ha_innodb.h b/storage/innodb_plugin/handler/ha_innodb.h
index 15cc4a77b6f..cde4fbdb934 100644
--- a/storage/innodb_plugin/handler/ha_innodb.h
+++ b/storage/innodb_plugin/handler/ha_innodb.h
@@ -239,16 +239,6 @@ LEX_STRING *thd_query_string(MYSQL_THD thd);
char **thd_query(MYSQL_THD thd);
#endif
-/** Get the file name of the MySQL binlog.
- * @return the name of the binlog file
- */
-const char* mysql_bin_log_file_name(void);
-
-/** Get the current position of the MySQL binlog.
- * @return byte offset from the beginning of the binlog
- */
-ulonglong mysql_bin_log_file_pos(void);
-
/**
Check if a user thread is a replication slave thread
@param thd user thread
@@ -289,6 +279,11 @@ bool thd_binlog_filter_ok(const MYSQL_THD thd);
#endif /* MYSQL_VERSION_ID > 50140 */
}
+/** Get the file name and position of the MySQL binlog corresponding to the
+ * current commit.
+ */
+extern void mysql_bin_log_commit_pos(THD *thd, ulonglong *out_pos, const char **out_file);
+
typedef struct trx_struct trx_t;
/********************************************************************//**
@file handler/ha_innodb.h
diff --git a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler/i_s.cc
index 4992cbc9c21..aee516c7768 100644
--- a/storage/innodb_plugin/handler/i_s.cc
+++ b/storage/innodb_plugin/handler/i_s.cc
@@ -241,7 +241,7 @@ field_store_time_t(
my_time.time_type = MYSQL_TIMESTAMP_DATETIME;
#endif
- return(field->store_time(&my_time, MYSQL_TIMESTAMP_DATETIME));
+ return(field->store_time(&my_time));
}
/*******************************************************************//**
diff --git a/storage/innodb_plugin/include/ha0ha.h b/storage/innodb_plugin/include/ha0ha.h
index 8bba564d153..83a7394123f 100644
--- a/storage/innodb_plugin/include/ha0ha.h
+++ b/storage/innodb_plugin/include/ha0ha.h
@@ -38,7 +38,7 @@ Looks for an element in a hash table.
@return pointer to the data of the first hash table node in chain
having the fold number, NULL if not found */
UNIV_INLINE
-const rec_t*
+rec_t*
ha_search_and_get_data(
/*===================*/
hash_table_t* table, /*!< in: hash table */
@@ -52,11 +52,11 @@ ha_search_and_update_if_found_func(
/*===============================*/
hash_table_t* table, /*!< in/out: hash table */
ulint fold, /*!< in: folded value of the searched data */
- const rec_t* data, /*!< in: pointer to the data */
+ rec_t* data, /*!< in: pointer to the data */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
buf_block_t* new_block,/*!< in: block containing new_data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- const rec_t* new_data);/*!< in: new pointer to the data */
+ rec_t* new_data);/*!< in: new pointer to the data */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
/** Looks for an element when we know the pointer to the data and
@@ -131,7 +131,7 @@ ha_insert_for_fold_func(
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
buf_block_t* block, /*!< in: buffer block containing the data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- const rec_t* data); /*!< in: data, must not be NULL */
+ rec_t* data); /*!< in: data, must not be NULL */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
/**
@@ -210,7 +210,7 @@ struct ha_node_struct {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
buf_block_t* block; /*!< buffer block containing the data, or NULL */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- const rec_t* data; /*!< pointer to the data */
+ rec_t* data; /*!< pointer to the data */
ulint fold; /*!< fold value for the data */
};
diff --git a/storage/innodb_plugin/include/ha0ha.ic b/storage/innodb_plugin/include/ha0ha.ic
index 5656e9b7eba..aec28398b5d 100644
--- a/storage/innodb_plugin/include/ha0ha.ic
+++ b/storage/innodb_plugin/include/ha0ha.ic
@@ -58,7 +58,7 @@ ha_node_set_data_func(
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
buf_block_t* block, /*!< in: buffer block containing the data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- const rec_t* data) /*!< in: pointer to the data */
+ rec_t* data) /*!< in: pointer to the data */
{
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
node->block = block;
@@ -111,7 +111,7 @@ Looks for an element in a hash table.
@return pointer to the data of the first hash table node in chain
having the fold number, NULL if not found */
UNIV_INLINE
-const rec_t*
+rec_t*
ha_search_and_get_data(
/*===================*/
hash_table_t* table, /*!< in: hash table */
diff --git a/storage/innodb_plugin/include/trx0trx.h b/storage/innodb_plugin/include/trx0trx.h
index 4bf3e75a5ee..3ee39ba6d47 100644
--- a/storage/innodb_plugin/include/trx0trx.h
+++ b/storage/innodb_plugin/include/trx0trx.h
@@ -521,9 +521,10 @@ struct trx_struct{
in that case we must flush the log
in trx_commit_complete_for_mysql() */
ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */
- ulint active_trans; /*!< 1 - if a transaction in MySQL
- is active. 2 - if prepare_commit_mutex
- was taken */
+ ulint active_flag; /*!< TRX_ACTIVE_IN_MYSQL - set if a
+ transaction in MySQL is active.
+ TRX_ACTIVE_COMMIT_ORDERED - set if
+ innobase_commit_ordered has run */
ulint has_search_latch;
/* TRUE if this trx has latched the
search system latch in S-mode */
@@ -808,6 +809,10 @@ Multiple flags can be combined with bitwise OR. */
#define TRX_SIG_OTHER_SESS 1 /* sent by another session (which
must hold rights to this) */
+/* Flag bits for trx_struct.active_flag */
+#define TRX_ACTIVE_IN_MYSQL (1<<0)
+#define TRX_ACTIVE_COMMIT_ORDERED (1<<1)
+
/** Commit node states */
enum commit_node_state {
COMMIT_NODE_SEND = 1, /*!< about to send a commit signal to
diff --git a/storage/innodb_plugin/trx/trx0trx.c b/storage/innodb_plugin/trx/trx0trx.c
index 80f079423fe..3e7fc84b1c6 100644
--- a/storage/innodb_plugin/trx/trx0trx.c
+++ b/storage/innodb_plugin/trx/trx0trx.c
@@ -122,7 +122,7 @@ trx_create(
trx->table_id = ut_dulint_zero;
trx->mysql_thd = NULL;
- trx->active_trans = 0;
+ trx->active_flag = 0;
trx->duplicates = 0;
trx->n_mysql_tables_in_use = 0;
diff --git a/storage/maria/CMakeLists.txt b/storage/maria/CMakeLists.txt
index 82a631d5086..77083c5839f 100644
--- a/storage/maria/CMakeLists.txt
+++ b/storage/maria/CMakeLists.txt
@@ -40,9 +40,10 @@ SET(ARIA_SOURCES ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c
ha_maria.cc trnman.c lockman.c tablockman.c
ma_rt_index.c ma_rt_key.c ma_rt_mbr.c ma_rt_split.c
ma_sp_key.c ma_control_file.c ma_loghandler.c
- ma_pagecache.c ma_pagecaches.c compat_aliases.cc compat_aliases.h
+ ma_pagecache.c ma_pagecaches.c
ma_checkpoint.c ma_recovery.c ma_commit.c ma_pagecrc.c
ha_maria.h maria_def.h ma_recovery_util.c ma_servicethread.c
+ ma_norec.c
)
MYSQL_STORAGE_ENGINE(ARIA)
diff --git a/storage/maria/Makefile.am b/storage/maria/Makefile.am
index c2bb61e77dd..fa01c2a602d 100644
--- a/storage/maria/Makefile.am
+++ b/storage/maria/Makefile.am
@@ -79,7 +79,7 @@ noinst_HEADERS = maria_def.h ma_rt_index.h ma_rt_key.h ma_rt_mbr.h \
ma_checkpoint.h ma_recovery.h ma_commit.h ma_state.h \
trnman_public.h ma_check_standalone.h \
ma_key_recover.h ma_recovery_util.h \
- ma_servicethread.h compat_aliases.h
+ ma_servicethread.h
ma_test1_DEPENDENCIES= $(LIBRARIES)
ma_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libaria.a \
$(top_builddir)/storage/myisam/libmyisam.a \
@@ -124,7 +124,7 @@ libaria_la_SOURCES = ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c \
ma_search.c ma_page.c ma_key_recover.c ma_key.c \
ma_locking.c ma_state.c \
ma_rrnd.c ma_scan.c ma_cache.c \
- ma_statrec.c ma_packrec.c ma_dynrec.c \
+ ma_statrec.c ma_packrec.c ma_dynrec.c ma_norec.c \
ma_blockrec.c ma_bitmap.c \
ma_update.c ma_write.c ma_unique.c \
ma_delete.c \
@@ -142,7 +142,7 @@ libaria_la_SOURCES = ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c \
ma_pagecache.c ma_pagecaches.c \
ma_checkpoint.c ma_recovery.c ma_commit.c \
ma_pagecrc.c ma_recovery_util.c \
- compat_aliases.cc ma_servicethread.c
+ ma_servicethread.c
libaria_s_la_SOURCES = ha_maria.cc
libaria_s_la_CXXFLAGS = $(AM_CXXFLAGS)
diff --git a/storage/maria/compat_aliases.cc b/storage/maria/compat_aliases.cc
deleted file mode 100644
index ead49fd98f9..00000000000
--- a/storage/maria/compat_aliases.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-/* 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 */
-
-/*
- compatibility aliases for system and static variables
-*/
-#include <my_global.h>
-#include <maria.h>
-#include <mysql/plugin.h>
-#include "ma_loghandler.h"
-#include "compat_aliases.h"
-
-ulong block_size_alias;
-static MYSQL_SYSVAR_ULONG(block_size, block_size_alias,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Deprecated, use --aria-block-size instead", 0, 0,
- MARIA_KEY_BLOCK_LENGTH, MARIA_MIN_KEY_BLOCK_LENGTH,
- MARIA_MAX_KEY_BLOCK_LENGTH, MARIA_MIN_KEY_BLOCK_LENGTH);
-
-ulong checkpoint_interval_alias;
-static MYSQL_SYSVAR_ULONG(checkpoint_interval, checkpoint_interval_alias,
- PLUGIN_VAR_RQCMDARG,
- "Deprecated, use --aria-checkpoint-interval instead",
- NULL, NULL, 30, 0, UINT_MAX, 1);
-
-ulong force_start_after_recovery_failures_alias;
-static MYSQL_SYSVAR_ULONG(force_start_after_recovery_failures, force_start_after_recovery_failures_alias,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Deprecated, use --aria-force-start-after-recovery-failures instead",
- NULL, NULL, 0, 0, UINT_MAX8, 1);
-
-my_bool page_checksum_alias;
-static MYSQL_SYSVAR_BOOL(page_checksum, page_checksum_alias, 0,
- "Deprecated, use --aria-page-checksum instead", 0, 0, 1);
-
-char *log_dir_path_alias;
-static MYSQL_SYSVAR_STR(log_dir_path, log_dir_path_alias,
- PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Deprecated, use --aria-log-dir-path instead",
- NULL, NULL, mysql_real_data_home);
-
-ulong log_file_size_alias;
-static MYSQL_SYSVAR_ULONG(log_file_size, log_file_size_alias,
- PLUGIN_VAR_RQCMDARG,
- "Deprecated, use --aria-log-file-size instead",
- NULL, NULL, TRANSLOG_FILE_SIZE,
- TRANSLOG_MIN_FILE_SIZE, 0xffffffffL, TRANSLOG_PAGE_SIZE);
-
-ulong group_commit_alias;
-static MYSQL_SYSVAR_ENUM(group_commit, group_commit_alias,
- PLUGIN_VAR_RQCMDARG,
- "Deprecated, use --aria-group-commit instead",
- NULL, NULL,
- TRANSLOG_GCOMMIT_NONE, &maria_group_commit_typelib);
-
-ulong group_commit_interval_alias;
-static MYSQL_SYSVAR_ULONG(group_commit_interval, group_commit_interval_alias,
- PLUGIN_VAR_RQCMDARG,
- "Deprecated, use --aria-group-commit-interval instead",
- NULL, NULL, 0, 0, UINT_MAX, 1);
-
-ulong log_purge_type_alias;
-static MYSQL_SYSVAR_ENUM(log_purge_type, log_purge_type_alias,
- PLUGIN_VAR_RQCMDARG,
- "Deprecated, use --aria-log-purge-type instead",
- NULL, NULL, TRANSLOG_PURGE_IMMIDIATE,
- &maria_translog_purge_type_typelib);
-
-ulonglong max_sort_file_size_alias;
-static MYSQL_SYSVAR_ULONGLONG(max_sort_file_size, max_sort_file_size_alias,
- PLUGIN_VAR_RQCMDARG,
- "Deprecated, use --aria-max-temp-length instead",
- 0, 0, MAX_FILE_SIZE, 0, MAX_FILE_SIZE, 1024*1024);
-
-ulong pagecache_age_threshold_alias;
-static MYSQL_SYSVAR_ULONG(pagecache_age_threshold, pagecache_age_threshold_alias,
- PLUGIN_VAR_RQCMDARG,
- "Deprecated, use --aria-pagecache-age-threshold instead",
- 0, 0, 300, 100, ~(unsigned long)0, 100);
-
-ulonglong pagecache_buffer_size_alias;
-static MYSQL_SYSVAR_ULONGLONG(pagecache_buffer_size, pagecache_buffer_size_alias,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Deprecated, use --aria-pagecache-buffer-size instead",
- 0, 0, KEY_CACHE_SIZE, MALLOC_OVERHEAD, ~0UL, IO_SIZE);
-
-ulong pagecache_division_limit_alias;
-static MYSQL_SYSVAR_ULONG(pagecache_division_limit, pagecache_division_limit_alias,
- PLUGIN_VAR_RQCMDARG,
- "Deprecated, use --aria-pagecache-division-limit instead",
- 0, 0, 100, 1, 100, 1);
-
-ulonglong recover_alias;
-static MYSQL_SYSVAR_SET(recover, recover_alias, PLUGIN_VAR_OPCMDARG,
- "Deprecated, use --aria-recover instead",
- NULL, NULL, HA_RECOVER_DEFAULT, &maria_recover_typelib);
-
-ulong repair_threads_alias;
-static MYSQL_THDVAR_ULONG(repair_threads, PLUGIN_VAR_RQCMDARG,
- "Deprecated, use --aria-repair-threads instead",
- 0, 0, 1, 1, ~(unsigned long)0, 1);
-
-ulong sort_buffer_size_alias;
-static MYSQL_THDVAR_ULONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG,
- "Deprecated, use --aria-sort-buffer-size instead",
- 0, 0, 128L*1024L*1024L, 4, ~(unsigned long)0, 1);
-
-ulong stats_method_alias;
-static MYSQL_THDVAR_ENUM(stats_method, PLUGIN_VAR_RQCMDARG,
- "Deprecated, use --aria-stats-method instead",
- 0, 0, 0, &maria_stats_method_typelib);
-
-ulong sync_log_dir_alias;
-static MYSQL_SYSVAR_ENUM(sync_log_dir, sync_log_dir_alias,
- PLUGIN_VAR_RQCMDARG,
- "Deprecated, use --aria-sync-log-dir instead",
- NULL, NULL, TRANSLOG_SYNC_DIR_NEWFILE,
- &maria_sync_log_dir_typelib);
-
-my_bool used_for_temp_tables_alias= 1;
-static MYSQL_SYSVAR_BOOL(used_for_temp_tables,
- used_for_temp_tables_alias, PLUGIN_VAR_READONLY | PLUGIN_VAR_NOCMDOPT,
- NULL, 0, 0, 1);
-
-static struct st_mysql_show_var status_variables_aliases[]= {
- {"Maria", (char*) &status_variables, SHOW_ARRAY},
- {NullS, NullS, SHOW_LONG}
-};
-
-/*
- There is one problem with aliases for command-line options.
- Plugin initialization works like this
-
- for all plugins:
- prepare command-line options
- initialize command-line option variables to the default values
- parse command line, assign values as necessary
-
- for all plugins:
- call the plugin initialization function
-
- it means, we cannot have maria* and aria* command-line options to use
- the same underlying variables - because after assigning maria* values,
- MySQL will put there default values again preparing for parsing aria*
- values. So, maria* values will be lost.
-
- So, we create separate set of variables for maria* options,
- and take both values into account in ha_maria_init().
-
- When the command line was parsed, we patch maria* options
- to use the same variables as aria* options so that
- set @@maria_some_var would have the same value as @@aria_some_var
- without forcing us to copy the values around all the time.
-*/
-
-static struct st_mysql_sys_var* system_variables_aliases[]= {
- MYSQL_SYSVAR(block_size),
- MYSQL_SYSVAR(checkpoint_interval),
- MYSQL_SYSVAR(force_start_after_recovery_failures),
- MYSQL_SYSVAR(group_commit),
- MYSQL_SYSVAR(group_commit_interval),
- MYSQL_SYSVAR(log_dir_path),
- MYSQL_SYSVAR(log_file_size),
- MYSQL_SYSVAR(log_purge_type),
- MYSQL_SYSVAR(max_sort_file_size),
- MYSQL_SYSVAR(page_checksum),
- MYSQL_SYSVAR(pagecache_age_threshold),
- MYSQL_SYSVAR(pagecache_buffer_size),
- MYSQL_SYSVAR(pagecache_division_limit),
- MYSQL_SYSVAR(recover),
- MYSQL_SYSVAR(repair_threads),
- MYSQL_SYSVAR(sort_buffer_size),
- MYSQL_SYSVAR(stats_method),
- MYSQL_SYSVAR(sync_log_dir),
- MYSQL_SYSVAR(used_for_temp_tables),
- NULL
-};
-
-#define COPY_SYSVAR(name) \
- memcpy(&MYSQL_SYSVAR_NAME(name), system_variables[i++], \
- sizeof(MYSQL_SYSVAR_NAME(name))); \
- if (name ## _alias != MYSQL_SYSVAR_NAME(name).def_val && \
- *MYSQL_SYSVAR_NAME(name).value == MYSQL_SYSVAR_NAME(name).def_val) \
- *MYSQL_SYSVAR_NAME(name).value= name ## _alias;
-
-#define COPY_THDVAR(name) \
- name ## _alias= THDVAR(0, name); \
- memcpy(&MYSQL_SYSVAR_NAME(name), system_variables[i++], \
- sizeof(MYSQL_SYSVAR_NAME(name))); \
- if (name ## _alias != MYSQL_SYSVAR_NAME(name).def_val && \
- THDVAR(0, name) == MYSQL_SYSVAR_NAME(name).def_val) \
- THDVAR(0, name)= name ## _alias;
-
-/* Note:
- The following list must be identical to the list for system_variables[] in ha_maria.cc
-*/
-
-void copy_variable_aliases()
-{
- int i= 0;
- COPY_SYSVAR(block_size);
- COPY_SYSVAR(checkpoint_interval);
- i++; // Skip checkpoint_min_log_activity
- COPY_SYSVAR(force_start_after_recovery_failures);
- COPY_SYSVAR(group_commit);
- COPY_SYSVAR(group_commit_interval);
- COPY_SYSVAR(log_dir_path);
- COPY_SYSVAR(log_file_size);
- COPY_SYSVAR(log_purge_type);
- COPY_SYSVAR(max_sort_file_size);
- COPY_SYSVAR(page_checksum);
- COPY_SYSVAR(pagecache_age_threshold);
- COPY_SYSVAR(pagecache_buffer_size);
- COPY_SYSVAR(pagecache_division_limit);
- COPY_SYSVAR(recover);
- COPY_THDVAR(repair_threads);
- COPY_THDVAR(sort_buffer_size);
- COPY_THDVAR(stats_method);
- COPY_SYSVAR(sync_log_dir);
- COPY_SYSVAR(used_for_temp_tables);
-}
-
-struct st_maria_plugin compat_aliases= {
- MYSQL_DAEMON_PLUGIN,
- &maria_storage_engine,
- "Maria",
- "Monty Program Ab",
- "Compatibility aliases for the Aria engine",
- PLUGIN_LICENSE_GPL,
- NULL,
- NULL,
- 0x0105,
- status_variables_aliases,
- system_variables_aliases,
- "1.5",
- MariaDB_PLUGIN_MATURITY_GAMMA
-};
-
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index af22f7dddb4..3e76b297495 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -29,7 +29,6 @@
#include "ha_maria.h"
#include "trnman_public.h"
#include "trnman.h"
-#include "compat_aliases.h"
C_MODE_START
#include "maria_def.h"
@@ -221,7 +220,8 @@ static MYSQL_SYSVAR_ULONGLONG(max_sort_file_size,
maria_max_temp_length, PLUGIN_VAR_RQCMDARG,
"Don't use the fast sort index method to created index if the "
"temporary file would get bigger than this.",
- 0, 0, MAX_FILE_SIZE & ~(1*MB-1), 0, MAX_FILE_SIZE, 1*MB);
+ 0, 0, MAX_FILE_SIZE & ~((ulonglong) (1*MB-1)),
+ 0, MAX_FILE_SIZE, 1*MB);
static MYSQL_SYSVAR_ULONG(pagecache_age_threshold,
pagecache_age_threshold, PLUGIN_VAR_RQCMDARG,
@@ -513,6 +513,8 @@ static int table2maria(TABLE *table_arg, data_file_type row_type,
if (found->flags & BLOB_FLAG)
recinfo_pos->type= FIELD_BLOB;
+ else if (found->type() == MYSQL_TYPE_TIMESTAMP)
+ recinfo_pos->type= FIELD_NORMAL;
else if (found->type() == MYSQL_TYPE_VARCHAR)
recinfo_pos->type= FIELD_VARCHAR;
else if (!(options & HA_OPTION_PACK_RECORD) ||
@@ -722,6 +724,34 @@ int _ma_killed_ptr(HA_CHECK *param)
}
+/*
+ Report progress to mysqld
+
+ This is a bit more complex than what a normal progress report
+ function normally is.
+
+ The reason is that this is called by enable_index/repair which
+ is one stage in ALTER TABLE and we can't use the external
+ stage/max_stage for this.
+
+ thd_progress_init/thd_progress_next_stage is to be called by
+ high level commands like CHECK TABLE or REPAIR TABLE, not
+ by sub commands like enable_index().
+
+ In ma_check.c it's easier to work with stages than with a total
+ progress, so we use internal stage/max_stage here to keep the
+ code simple.
+*/
+
+void _ma_report_progress(HA_CHECK *param, ulonglong progress,
+ ulonglong max_progress)
+{
+ thd_progress_report((THD*)param->thd,
+ progress + max_progress * param->stage,
+ max_progress * param->max_stage);
+}
+
+
void _ma_check_print_error(HA_CHECK *param, const char *fmt, ...)
{
va_list args;
@@ -771,7 +801,7 @@ void _ma_check_print_warning(HA_CHECK *param, const char *fmt, ...)
static int maria_create_trn_for_mysql(MARIA_HA *info)
{
- THD *thd= (THD*) info->external_ptr;
+ THD *thd= ((TABLE*) info->external_ref)->in_use;
TRN *trn= THD_TRN;
DBUG_ENTER("maria_create_trn_for_mysql");
@@ -810,6 +840,11 @@ static int maria_create_trn_for_mysql(MARIA_HA *info)
DBUG_RETURN(0);
}
+my_bool ma_killed_in_mariadb(MARIA_HA *info)
+{
+ return (((TABLE*) (info->external_ref))->in_use->killed != 0);
+}
+
} /* extern "C" */
/**
@@ -879,6 +914,28 @@ const char *ha_maria::index_type(uint key_number)
}
+ulong ha_maria::index_flags(uint inx, uint part, bool all_parts) const
+{
+ ulong flags;
+ if (table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT)
+ flags= 0;
+ else
+ if ((table_share->key_info[inx].flags & HA_SPATIAL ||
+ table_share->key_info[inx].algorithm == HA_KEY_ALG_RTREE))
+ {
+ /* All GIS scans are non-ROR scans. We also disable IndexConditionPushdown */
+ flags= HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
+ HA_READ_ORDER | HA_KEYREAD_ONLY | HA_KEY_SCAN_NOT_ROR;
+ }
+ else
+ {
+ flags= HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
+ HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN;
+ }
+ return flags;
+}
+
+
double ha_maria::scan_time()
{
if (file->s->data_file_type == BLOCK_RECORD)
@@ -905,8 +962,7 @@ double ha_maria::scan_time()
uint ha_maria::max_supported_key_length() const
{
- uint tmp= (maria_max_key_length() - 8 - HA_MAX_KEY_SEG*3);
- return min(HA_MAX_KEY_LENGTH, tmp);
+ return maria_max_key_length();
}
@@ -1038,6 +1094,8 @@ int ha_maria::open(const char *name, int mode, uint test_if_locked)
}
file->s->chst_invalidator= query_cache_invalidate_by_MyISAM_filename_ref;
+ /* Set external_ref, mainly for temporary tables */
+ file->external_ref= (void*) table; // For ma_killed()
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
VOID(maria_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
@@ -1061,6 +1119,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;
@@ -1077,6 +1145,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);
}
@@ -1107,7 +1177,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
int error;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
MARIA_SHARE *share= file->s;
- const char *old_proc_info= thd_proc_info(thd, "Checking table");
+ const char *old_proc_info;
TRN *old_trn= file->trn;
if (!file || !&param) return HA_ADMIN_INTERNAL_ERROR;
@@ -1135,6 +1205,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
return HA_ADMIN_ALREADY_DONE;
maria_chk_init_for_check(&param, file);
+
if ((file->s->state.changed & (STATE_CRASHED_FLAGS | STATE_MOVED)) ==
STATE_MOVED)
{
@@ -1142,12 +1213,18 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
return HA_ADMIN_CORRUPT;
}
+ old_proc_info= thd_proc_info(thd, "Checking status");
+ thd_progress_init(thd, 3);
(void) maria_chk_status(&param, file); // Not fatal
error= maria_chk_size(&param, file);
if (!error)
error|= maria_chk_del(&param, file, param.testflag);
+ thd_proc_info(thd, "Checking keys");
+ thd_progress_next_stage(thd);
if (!error)
error= maria_chk_key(&param, file);
+ thd_proc_info(thd, "Checking data");
+ thd_progress_next_stage(thd);
if (!error)
{
if ((!(param.testflag & T_QUICK) &&
@@ -1198,6 +1275,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
/* Reset trn, that may have been set by repair */
_ma_set_trn_for_table(file, old_trn);
thd_proc_info(thd, old_proc_info);
+ thd_progress_end(thd);
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
}
@@ -1213,6 +1291,7 @@ int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt)
int error= 0;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
MARIA_SHARE *share= file->s;
+ const char *old_proc_info;
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
@@ -1230,6 +1309,8 @@ int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt)
if (!(share->state.changed & STATE_NOT_ANALYZED))
return HA_ADMIN_ALREADY_DONE;
+ old_proc_info= thd_proc_info(thd, "Scanning");
+ thd_progress_init(thd, 1);
error= maria_chk_key(&param, file);
if (!error)
{
@@ -1239,6 +1320,8 @@ int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt)
}
else if (!maria_is_crashed(file) && !thd->killed)
maria_mark_crashed(file);
+ thd_proc_info(thd, old_proc_info);
+ thd_progress_end(thd);
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
}
@@ -1372,6 +1455,7 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
int error;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
ha_rows start_records;
+ const char *old_proc_info;
if (!file || !&param)
return HA_ADMIN_INTERNAL_ERROR;
@@ -1385,6 +1469,8 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
param.backup_time= check_opt->start_time;
start_records= file->state->records;
+ old_proc_info= thd_proc_info(thd, "Checking table");
+ thd_progress_init(thd, 1);
while ((error= repair(thd, &param, 0)) && param.retry_repair)
{
param.retry_repair= 0;
@@ -1420,6 +1506,8 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
llstr(start_records, llbuff2),
table->s->path.str);
}
+ thd_proc_info(thd, old_proc_info);
+ thd_progress_end(thd);
return error;
}
@@ -1471,14 +1559,15 @@ int ha_maria::optimize(THD * thd, HA_CHECK_OPT *check_opt)
param.testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX);
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
+ thd_progress_init(thd, 1);
if ((error= repair(thd, &param, 1)) && param.retry_repair)
{
sql_print_warning("Warning: Optimize table got errno %d on %s.%s, retrying",
my_errno, param.db_name, param.table_name);
param.testflag &= ~T_REP_BY_SORT;
- error= repair(thd, &param, 1);
+ error= repair(thd, &param, 0);
}
-
+ thd_progress_end(thd);
return error;
}
@@ -1649,6 +1738,7 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
}
pthread_mutex_unlock(&share->intern_lock);
thd_proc_info(thd, old_proc_info);
+ thd_progress_end(thd); // Mark done
if (!thd->locked_tables)
maria_lock_database(file, F_UNLCK);
@@ -1975,15 +2065,27 @@ void ha_maria::start_bulk_insert(ha_rows rows)
{
DBUG_ENTER("ha_maria::start_bulk_insert");
THD *thd= table->in_use;
- ulong size= min(thd->variables.read_buff_size,
- (ulong) (table->s->avg_row_length * rows));
MARIA_SHARE *share= file->s;
- DBUG_PRINT("info", ("start_bulk_insert: rows %lu size %lu",
- (ulong) rows, size));
+ DBUG_PRINT("info", ("start_bulk_insert: rows %lu", (ulong) rows));
/* don't enable row cache if too few rows */
if (!rows || (rows > MARIA_MIN_ROWS_TO_USE_WRITE_CACHE))
- maria_extra(file, HA_EXTRA_WRITE_CACHE, (void*) &size);
+ {
+ ulonglong size= thd->variables.read_buff_size, tmp;
+ if (rows)
+ {
+ if (file->state->records)
+ {
+ MARIA_INFO maria_info;
+ maria_status(file, &maria_info, HA_STATUS_NO_LOCK |HA_STATUS_VARIABLE);
+ set_if_smaller(size, maria_info.mean_reclength * rows);
+ }
+ else if (table->s->avg_row_length)
+ set_if_smaller(size, (size_t) (table->s->avg_row_length * rows));
+ }
+ tmp= (ulong) size; // Safe becasue of limits
+ maria_extra(file, HA_EXTRA_WRITE_CACHE, (void*) &tmp);
+ }
can_enable_indexes= (maria_is_all_keys_active(share->state.key_map,
share->base.keys));
@@ -2018,7 +2120,14 @@ void ha_maria::start_bulk_insert(ha_rows rows)
@todo for a single-row INSERT SELECT, we will go into repair, which
is more costly (flushes, syncs) than a row write.
*/
- maria_disable_non_unique_index(file, rows);
+ if (file->open_flags & HA_OPEN_INTERNAL_TABLE)
+ {
+ /* Internal table; If we get a duplicate something is very wrong */
+ file->update|= HA_STATE_CHANGED;
+ maria_clear_all_keys_active(file->s->state.key_map);
+ }
+ else
+ maria_disable_non_unique_index(file, rows);
if (share->now_transactional)
{
bulk_insert_single_undo= BULK_INSERT_SINGLE_UNDO_AND_NO_REPAIR;
@@ -2183,7 +2292,6 @@ int ha_maria::delete_row(const uchar * buf)
return maria_delete(file, buf);
}
-
int ha_maria::index_read_map(uchar * buf, const uchar * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
@@ -2199,7 +2307,15 @@ int ha_maria::index_read_idx_map(uchar * buf, uint index, const uchar * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
- int error= maria_rkey(file, buf, index, key, keypart_map, find_flag);
+ int error;
+ /* Use the pushed index condition if it matches the index we're scanning */
+ end_range= NULL;
+ if (index == pushed_idx_cond_keyno)
+ ma_set_index_cond_func(file, handler_index_cond_check, this);
+
+ error= maria_rkey(file, buf, index, key, keypart_map, find_flag);
+
+ ma_set_index_cond_func(file, NULL, 0);
table->status= error ? STATUS_NOT_FOUND : 0;
return error;
}
@@ -2272,6 +2388,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, handler_index_cond_check, 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)
@@ -2282,6 +2417,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;
@@ -2326,7 +2462,7 @@ void ha_maria::position(const uchar *record)
int ha_maria::info(uint flag)
{
- return info(flag, table->s->tmp_table == NO_TMP_TABLE);
+ return (!table ? 1 : info(flag, table->s->tmp_table == NO_TMP_TABLE));
}
int ha_maria::info(uint flag, my_bool lock_table_share)
@@ -2354,6 +2490,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)
@@ -2436,6 +2573,8 @@ int ha_maria::extra(enum ha_extra_function operation)
int ha_maria::reset(void)
{
+ 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 */
@@ -2496,14 +2635,23 @@ int ha_maria::delete_table(const char *name)
void ha_maria::drop_table(const char *name)
{
DBUG_ASSERT(file->s->temporary);
- (void) close();
+ (void) ha_close();
(void) maria_delete_table_files(name, 0);
}
+void ha_maria::change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
+{
+ handler::change_table_ptr(table_arg, share);
+ if (file)
+ file->external_ref= table_arg;
+}
+
+
int ha_maria::external_lock(THD *thd, int lock_type)
{
DBUG_ENTER("ha_maria::external_lock");
+ file->external_ref= (void*) table; // For ma_killed()
/*
We don't test now_transactional because it may vary between lock/unlock
and thus confuse our reference counting.
@@ -2522,8 +2670,6 @@ int ha_maria::external_lock(THD *thd, int lock_type)
/* Transactional table */
if (lock_type != F_UNLCK)
{
- file->external_ptr= thd; // For maria_register_trn()
-
if (!file->s->lock_key_trees) // If we don't use versioning
{
/*
@@ -2602,7 +2748,7 @@ int ha_maria::external_lock(THD *thd, int lock_type)
changes to commit (rollback shouldn't be tested).
*/
DBUG_ASSERT(!thd->main_da.is_sent ||
- thd->killed == THD::KILL_CONNECTION);
+ thd->killed == KILL_CONNECTION);
/* autocommit ? rollback a transaction */
#ifdef MARIA_CANNOT_ROLLBACK
if (ma_commit(trn))
@@ -3155,6 +3301,14 @@ bool maria_flush_logs(handlerton *hton)
}
+int maria_checkpoint_state(handlerton *hton, bool disabled)
+{
+ maria_checkpoint_disabled= (my_bool) disabled;
+ return 0;
+}
+
+
+
#define SHOW_MSG_LEN (FN_REFLEN + 20)
/**
@brief show status handler
@@ -3334,7 +3488,6 @@ bool ha_maria::is_changed() const
static int ha_maria_init(void *p)
{
int res;
- copy_variable_aliases();
const char *log_dir= maria_data_root;
maria_hton= (handlerton *)p;
maria_hton->state= SHOW_OPTION_YES;
@@ -3343,6 +3496,7 @@ static int ha_maria_init(void *p)
maria_hton->panic= maria_hton_panic;
maria_hton->commit= maria_commit;
maria_hton->rollback= maria_rollback;
+ maria_hton->checkpoint_state= maria_checkpoint_state;
#ifdef MARIA_CANNOT_ROLLBACK
maria_hton->commit= 0;
#endif
@@ -3379,6 +3533,9 @@ static int ha_maria_init(void *p)
#endif
if (res)
maria_hton= 0;
+
+ ma_killed= ma_killed_in_mariadb;
+
return res ? HA_ERR_INITIALIZATION : 0;
}
@@ -3613,11 +3770,73 @@ 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(range_id_t *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);
+}
+
+int ha_maria::multi_range_read_explain_info(uint mrr_mode, char *str,
+ size_t size)
+{
+ return ds_mrr.dsmrr_explain_info(mrr_mode, str, size);
+}
+/* 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, handler_index_cond_check, this);
+ return NULL;
+}
+
+
+
+
struct st_mysql_storage_engine maria_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
maria_declare_plugin(aria)
-compat_aliases,
{
MYSQL_STORAGE_ENGINE_PLUGIN,
&maria_storage_engine,
diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h
index 8062b235d7d..e5c5160e169 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 ulonglong maria_recover_options;
@@ -52,12 +64,7 @@ public:
const char **bas_ext() const;
ulonglong table_flags() const
{ return int_table_flags; }
- 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);
- }
+ ulong index_flags(uint inx, uint part, bool all_parts) const;
uint max_supported_keys() const
{ return MARIA_MAX_KEY; }
uint max_supported_key_length() const;
@@ -65,6 +72,7 @@ public:
{ return max_supported_key_length(); }
enum row_type get_row_type() const;
uint checksum() const;
+ void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
virtual double scan_time();
int open(const char *name, int mode, uint test_if_locked);
@@ -98,6 +106,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);
@@ -166,4 +176,26 @@ 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(range_id_t *range_info);
+ ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
+ void *seq_init_param,
+ uint n_ranges, uint *bufsz,
+ uint *flags, COST_VECT *cost);
+ ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
+ uint *flags, COST_VECT *cost);
+ int multi_range_read_explain_info(uint mrr_mode, char *str, size_t size);
+
+ /* 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/lockman.c b/storage/maria/lockman.c
index d6d4dcd44e6..459ee5d8ae2 100644
--- a/storage/maria/lockman.c
+++ b/storage/maria/lockman.c
@@ -690,12 +690,12 @@ enum lockman_getlock_result lockman_getlock(LOCKMAN *lm, LOCK_OWNER *lo,
}
/* yuck. waiting */
- deadline= my_getsystime() + lm->lock_timeout * 10000;
- set_timespec_nsec(timeout,lm->lock_timeout * 1000000);
+ deadline= my_hrtime().val*1000 + lm->lock_timeout * 1000000;
+ set_timespec_time_nsec(timeout, deadline);
do
{
pthread_cond_timedwait(wait_for_lo->cond, wait_for_lo->mutex, &timeout);
- } while (!DELETED(blocker->link) && my_getsystime() < deadline);
+ } while (!DELETED(blocker->link) && my_hrtime().val < deadline/1000);
pthread_mutex_unlock(wait_for_lo->mutex);
lf_rwlock_by_pins(pins);
if (!DELETED(blocker->link))
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index 25ab5c6531e..f5cfa1ce23f 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -368,7 +368,7 @@ static inline void _ma_bitmap_mark_file_changed(MARIA_SHARE *share,
if (flush_translog && share->now_transactional)
(void) translog_flush(share->state.logrec_file_id);
- _ma_mark_file_changed(share);
+ _ma_mark_file_changed_now(share);
pthread_mutex_lock(&share->bitmap.bitmap_lock);
/* purecov: end */
}
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 4e55c519a9a..036059f1245 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -4676,7 +4676,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
uchar *data, uchar *end_of_data)
{
MARIA_SHARE *share= info->s;
- uchar *field_length_data, *blob_buffer, *start_of_data;
+ uchar *UNINIT_VAR(field_length_data), *UNINIT_VAR(blob_buffer), *start_of_data;
uint flag, null_bytes, cur_null_bytes, row_extents, field_lengths;
my_bool found_blob= 0;
MARIA_EXTENT_CURSOR extent;
@@ -4684,9 +4684,6 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
MARIA_ROW *cur_row= &info->cur_row;
DBUG_ENTER("_ma_read_block_record2");
- LINT_INIT(field_length_data);
- LINT_INIT(blob_buffer);
-
start_of_data= data;
flag= (uint) (uchar) data[0];
cur_null_bytes= share->base.original_null_bytes;
@@ -5114,6 +5111,7 @@ int _ma_read_block_record(MARIA_HA *info, uchar *record,
uchar *data, *end_of_data, *buff;
uint offset;
uint block_size= share->block_size;
+ int ret;
DBUG_ENTER("_ma_read_block_record");
DBUG_PRINT("enter", ("rowid: %lu page: %lu rownr: %u",
(ulong) record_pos,
@@ -5135,7 +5133,8 @@ int _ma_read_block_record(MARIA_HA *info, uchar *record,
my_errno= HA_ERR_RECORD_DELETED; /* File crashed */
DBUG_RETURN(HA_ERR_RECORD_DELETED);
}
- DBUG_RETURN(_ma_read_block_record2(info, record, data, end_of_data));
+ ret= _ma_read_block_record2(info, record, data, end_of_data);
+ DBUG_RETURN(ret);
}
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 6fae327a07a..353153392c0 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -125,6 +125,7 @@ void maria_chk_init(HA_CHECK *param)
param->max_record_length= LONGLONG_MAX;
param->pagecache_block_size= KEY_CACHE_BLOCK_SIZE;
param->stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
+ param->max_stage= 1;
}
@@ -530,6 +531,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
continue;
}
found_keys++;
+ _ma_report_progress(param, key, share->base.keys);
param->record_checksum=init_checksum;
@@ -1013,10 +1015,12 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
/* fall through */
}
if ((share->data_file_type != BLOCK_RECORD &&
+ share->data_file_type != NO_RECORD &&
record >= share->state.state.data_file_length) ||
(share->data_file_type == BLOCK_RECORD &&
ma_recordpos_to_page(record) * share->base.min_block_length >=
- share->state.state.data_file_length))
+ share->state.state.data_file_length) ||
+ (share->data_file_type == NO_RECORD && record != 0))
{
#ifndef DBUG_OFF
char llbuff2[22], llbuff3[22];
@@ -1134,10 +1138,14 @@ static int check_keys_in_record(HA_CHECK *param, MARIA_HA *info, int extend,
param->tmp_record_checksum+= (ha_checksum) start_recpos;
param->records++;
- if (param->testflag & T_WRITE_LOOP && param->records % WRITE_COUNT == 0)
+ if (param->records % WRITE_COUNT == 0)
{
- printf("%s\r", llstr(param->records, llbuff));
- VOID(fflush(stdout));
+ if (param->testflag & T_WRITE_LOOP)
+ {
+ printf("%s\r", llstr(param->records, llbuff));
+ VOID(fflush(stdout));
+ }
+ _ma_report_progress(param, param->records, share->state.state.records);
}
/* Check if keys match the record */
@@ -2086,6 +2094,12 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend)
case COMPRESSED_RECORD:
error= check_compressed_record(param, info, extend, record);
break;
+ case NO_RECORD:
+ param->records= share->state.state.records;
+ param->record_checksum= 0;
+ extend= 1; /* No row checksums */
+ /* no data, nothing to do */
+ break;
} /* switch */
info->in_check_table= 0;
@@ -2323,6 +2337,13 @@ static int initialize_variables_for_repair(HA_CHECK *param,
{
MARIA_SHARE *share= info->s;
+ if (share->data_file_type == NO_RECORD)
+ {
+ _ma_check_print_error(param,
+ "Can't repair tables with record type NO_DATA");
+ return 1;
+ }
+
/* Make a copy to allow us to restore state and check how state changed */
memcpy(org_share, share, sizeof(*share));
@@ -2369,6 +2390,7 @@ static int initialize_variables_for_repair(HA_CHECK *param,
/* calculate max_records */
sort_info->filelength= my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0));
+ param->max_progress= sort_info->filelength;
if ((param->testflag & T_CREATE_MISSING_KEYS) ||
sort_info->org_data_file_type == COMPRESSED_RECORD)
sort_info->max_records= share->state.state.records;
@@ -2391,6 +2413,8 @@ static int initialize_variables_for_repair(HA_CHECK *param,
maria_ignore_trids(info);
/* Don't write transid's during repair */
maria_versioning(info, 0);
+ /* remember original number of rows */
+ *info->state= info->s->state.state;
return 0;
}
@@ -3623,7 +3647,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
const char * name, my_bool rep_quick)
{
int got_error;
- uint i;
+ uint i, keys_to_repair;
ha_rows start_records;
my_off_t new_header_length, org_header_length, del;
File new_file;
@@ -3749,6 +3773,17 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
del=share->state.state.del;
+ /* Calculate number of keys to repair */
+ keys_to_repair= 0;
+ for (sort_param.key=0 ; sort_param.key < share->base.keys ;
+ sort_param.key++)
+ {
+ if (maria_is_key_active(key_map, sort_param.key))
+ keys_to_repair++;
+ }
+ /* For each key we scan and merge sort the keys */
+ param->max_stage= keys_to_repair*2;
+
rec_per_key_part= param->new_rec_per_key_part;
for (sort_param.key=0 ; sort_param.key < share->base.keys ;
rec_per_key_part+=sort_param.keyinfo->keysegs, sort_param.key++)
@@ -3869,6 +3904,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
/* Set for next loop */
sort_info.max_records= (ha_rows) sort_info.new_info->s->state.state.records;
+ param->stage++; /* Next stage */
+ param->progress= 0;
+
if (param->testflag & T_STATISTICS)
maria_update_key_parts(sort_param.keyinfo, rec_per_key_part,
sort_param.unique,
@@ -3950,6 +3988,10 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
sort_info.org_data_file_type= share->data_file_type;
sort_info.filelength= share->state.state.data_file_length;
sort_param.fix_datafile=0;
+
+ /* Offsets are now in proportion to the new file length */
+ param->max_progress= sort_info.filelength;
+
}
else
share->state.state.data_file_length=sort_param.max_pos;
@@ -4750,6 +4792,11 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
if (_ma_killed_ptr(param))
DBUG_RETURN(1);
+ if (param->progress_counter++ >= WRITE_COUNT)
+ {
+ param->progress_counter= 0;
+ _ma_report_progress(param, param->progress, param->max_progress);
+ }
switch (sort_info->org_data_file_type) {
case BLOCK_RECORD:
@@ -4790,6 +4837,9 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
flag= HA_ERR_ROW_NOT_VISIBLE;
}
}
+ param->progress= (ma_recordpos_to_page(info->cur_row.lastpos)*
+ share->block_size);
+
share->page_type= save_page_type;
if (!flag)
{
@@ -4842,6 +4892,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
DBUG_RETURN(-1);
}
sort_param->start_recpos=sort_param->pos;
+ param->progress= sort_param->pos;
if (!sort_param->fix_datafile)
{
sort_param->current_filepos= sort_param->pos;
@@ -4869,6 +4920,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
LINT_INIT(to);
pos=sort_param->pos;
+ param->progress= pos;
searching=(sort_param->fix_datafile && (param->testflag & T_EXTEND));
parallel_flag= (sort_param->read_cache.file < 0) ? READING_NEXT : 0;
for (;;)
@@ -5178,6 +5230,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
}
}
case COMPRESSED_RECORD:
+ param->progress= sort_param->pos;
for (searching=0 ;; searching=1, sort_param->pos++)
{
if (_ma_read_cache(info, &sort_param->read_cache, block_info.header,
@@ -5252,8 +5305,10 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
}
DBUG_RETURN(0);
}
+ case NO_RECORD:
+ DBUG_RETURN(1); /* Impossible */
}
- DBUG_RETURN(1); /* Impossible */
+ DBUG_RETURN(1); /* Impossible */
}
@@ -5376,6 +5431,8 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
sort_param->filepos+=reclength+length;
share->state.split++;
break;
+ case NO_RECORD:
+ DBUG_RETURN(1); /* Impossible */
}
}
if (sort_param->master)
@@ -5615,7 +5672,8 @@ static my_off_t get_record_for_key(MARIA_KEYDEF *keyinfo,
MARIA_KEY key;
key.keyinfo= keyinfo;
key.data= (uchar*) key_data;
- key.data_length= _ma_keylength(keyinfo, key_data);
+ key.data_length= (_ma_keylength(keyinfo, key_data) -
+ keyinfo->share->rec_reflength);
return _ma_row_pos_from_key(&key);
} /* get_record_for_key */
diff --git a/storage/maria/ma_check_standalone.h b/storage/maria/ma_check_standalone.h
index 8cda285bb99..f9242bbe123 100644
--- a/storage/maria/ma_check_standalone.h
+++ b/storage/maria/ma_check_standalone.h
@@ -35,6 +35,13 @@ int _ma_killed_ptr(HA_CHECK *param __attribute__((unused)))
return 0;
}
+
+void _ma_report_progress(HA_CHECK *param __attribute__((unused)),
+ ulonglong progress __attribute__((unused)),
+ ulonglong max_progress __attribute__((unused)))
+{
+}
+
/* print warnings and errors */
/* VARARGS */
diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c
index 002f2999e6c..e11a21581aa 100644
--- a/storage/maria/ma_checkpoint.c
+++ b/storage/maria/ma_checkpoint.c
@@ -580,51 +580,59 @@ pthread_handler_t ma_checkpoint_background(void *arg)
{
case 0:
{
- TRANSLOG_ADDRESS horizon= translog_get_horizon();
+ /* If checkpoints are disabled, wait 1 second and try again */
+ if (maria_checkpoint_disabled)
+ {
+ sleep_time= 1;
+ break;
+ }
+ {
+ TRANSLOG_ADDRESS horizon= translog_get_horizon();
- /*
- With background flushing evenly distributed over the time
- between two checkpoints, we should have only little flushing to do
- in the checkpoint.
- */
- /*
- No checkpoint if little work of interest for recovery was done
- since last checkpoint. Such work includes log writing (lengthens
- recovery, checkpoint would shorten it), page flushing (checkpoint
- would decrease the amount of read pages in recovery).
- In case of one short statement per minute (very low load), we don't
- want to checkpoint every minute, hence the positive
- maria_checkpoint_min_activity.
- */
- if ((ulonglong) (horizon - log_horizon_at_last_checkpoint) <=
- maria_checkpoint_min_log_activity &&
- ((ulonglong) (maria_pagecache->global_cache_write -
- pagecache_flushes_at_last_checkpoint) *
+ /*
+ With background flushing evenly distributed over the time
+ between two checkpoints, we should have only little flushing to do
+ in the checkpoint.
+ */
+ /*
+ No checkpoint if little work of interest for recovery was done
+ since last checkpoint. Such work includes log writing (lengthens
+ recovery, checkpoint would shorten it), page flushing (checkpoint
+ would decrease the amount of read pages in recovery).
+ In case of one short statement per minute (very low load), we don't
+ want to checkpoint every minute, hence the positive
+ maria_checkpoint_min_activity.
+ */
+ if ((ulonglong) (horizon - log_horizon_at_last_checkpoint) <=
+ maria_checkpoint_min_log_activity &&
+ ((ulonglong) (maria_pagecache->global_cache_write -
+ pagecache_flushes_at_last_checkpoint) *
maria_pagecache->block_size) <=
- maria_checkpoint_min_cache_activity)
- {
+ maria_checkpoint_min_cache_activity)
+ {
+ /*
+ Not enough has happend since last checkpoint.
+ Sleep for a while and try again later
+ */
+ sleep_time= interval;
+ break;
+ }
+ sleep_time= 1;
+ ma_checkpoint_execute(CHECKPOINT_MEDIUM, TRUE);
/*
- Not enough has happend since last checkpoint.
- Sleep for a while and try again later
+ Snapshot this kind of "state" of the engine. Note that the value
+ below is possibly greater than last_checkpoint_lsn.
+ */
+ log_horizon_at_last_checkpoint= translog_get_horizon();
+ pagecache_flushes_at_last_checkpoint=
+ maria_pagecache->global_cache_write;
+ /*
+ If the checkpoint above succeeded it has set d|kfiles and
+ d|kfiles_end. If is has failed, it has set
+ pages_to_flush_before_next_checkpoint to 0 so we will skip flushing
+ and sleep until the next checkpoint.
*/
- sleep_time= interval;
- break;
}
- sleep_time= 1;
- ma_checkpoint_execute(CHECKPOINT_MEDIUM, TRUE);
- /*
- Snapshot this kind of "state" of the engine. Note that the value below
- is possibly greater than last_checkpoint_lsn.
- */
- log_horizon_at_last_checkpoint= translog_get_horizon();
- pagecache_flushes_at_last_checkpoint=
- maria_pagecache->global_cache_write;
- /*
- If the checkpoint above succeeded it has set d|kfiles and
- d|kfiles_end. If is has failed, it has set
- pages_to_flush_before_next_checkpoint to 0 so we will skip flushing
- and sleep until the next checkpoint.
- */
break;
}
case 1:
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index 54ebcdc709e..86709c09200 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -251,10 +251,16 @@ int maria_create(const char *name, enum data_file_type datafile_type,
datafile_type= BLOCK_RECORD;
}
+ if (datafile_type == NO_RECORD && uniques)
+ {
+ /* Can't do unique without data, revert to block records */
+ datafile_type= BLOCK_RECORD;
+ }
+
if (datafile_type == DYNAMIC_RECORD)
options|= HA_OPTION_PACK_RECORD; /* Must use packed records */
- if (datafile_type == STATIC_RECORD)
+ if (datafile_type == STATIC_RECORD || datafile_type == NO_RECORD)
{
/* We can't use checksum with static length rows */
flags&= ~HA_CREATE_CHECKSUM;
@@ -375,7 +381,9 @@ int maria_create(const char *name, enum data_file_type datafile_type,
}
else
{
- if (datafile_type != STATIC_RECORD)
+ if (datafile_type == NO_RECORD)
+ pointer= 0;
+ else if (datafile_type != STATIC_RECORD)
pointer= maria_get_pointer_length(ci->data_file_length,
maria_data_pointer_size);
else
@@ -615,7 +623,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
to be able to put at least 2 keys on an index block for the key
algorithms to work).
*/
- if (length > maria_max_key_length())
+ if (length > _ma_max_key_length())
{
my_errno=HA_WRONG_CREATE_OPTION;
goto err_no_lock;
@@ -1329,11 +1337,12 @@ int _ma_update_state_lsns(MARIA_SHARE *share, LSN lsn, TrID create_trid,
my_bool do_sync, my_bool update_create_rename_lsn)
{
int res;
+ DBUG_ENTER("_ma_update_state_lsns");
pthread_mutex_lock(&share->intern_lock);
res= _ma_update_state_lsns_sub(share, lsn, create_trid, do_sync,
update_create_rename_lsn);
pthread_mutex_unlock(&share->intern_lock);
- return res;
+ DBUG_RETURN(res);
}
diff --git a/storage/maria/ma_dbug.c b/storage/maria/ma_dbug.c
index af90a108e2a..8391f1a9d9d 100644
--- a/storage/maria/ma_dbug.c
+++ b/storage/maria/ma_dbug.c
@@ -186,7 +186,7 @@ my_bool _ma_check_table_is_closed(const char *name, const char *where)
MARIA_SHARE *share= info->s;
if (!strcmp(share->unique_file_name.str, filename))
{
- if (share->last_version)
+ if (share->last_version > 1)
{
fprintf(stderr,"Warning: Table: %s is open on %s\n", name,where);
DBUG_PRINT("warning",("Table: %s is open on %s", name,where));
diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c
index 200c6415086..10d9674eca2 100644
--- a/storage/maria/ma_dynrec.c
+++ b/storage/maria/ma_dynrec.c
@@ -1745,7 +1745,6 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info,
#ifdef MARIA_EXTERNAL_LOCKING
int info_read;
#endif
-
uint left_len,b_type;
uchar *to;
MARIA_BLOCK_INFO block_info;
diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c
index d2e011fcf24..183f74835b2 100644
--- a/storage/maria/ma_extra.c
+++ b/storage/maria/ma_extra.c
@@ -415,9 +415,8 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
if (!share->temporary)
error= _ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
FLUSH_KEEP, FLUSH_KEEP);
-#ifdef HAVE_PREAD
+
_ma_decrement_open_count(info, 1);
-#endif
if (share->not_flushed)
{
share->not_flushed= 0;
@@ -490,6 +489,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.
*/
@@ -644,3 +651,10 @@ int _ma_flush_table_files(MARIA_HA *info, uint flush_data_or_index,
_ma_set_fatal_error(info->s, HA_ERR_CRASHED);
DBUG_RETURN(1);
}
+
+
+my_bool ma_killed_standalone(MARIA_HA *info __attribute__((unused)))
+{
+ return 0;
+}
+
diff --git a/storage/maria/ma_ft_boolean_search.c b/storage/maria/ma_ft_boolean_search.c
index 208b39f3b32..66522d69ea4 100644
--- a/storage/maria/ma_ft_boolean_search.c
+++ b/storage/maria/ma_ft_boolean_search.c
@@ -475,14 +475,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)
{
@@ -587,7 +588,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,
@@ -830,7 +831,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 7506c5dd12b..c3e34a8d18e 100644
--- a/storage/maria/ma_ft_nlq_search.c
+++ b/storage/maria/ma_ft_nlq_search.c
@@ -254,12 +254,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_info.c b/storage/maria/ma_info.c
index 1bbfa3cbf7e..b5d9b2489b7 100644
--- a/storage/maria/ma_info.c
+++ b/storage/maria/ma_info.c
@@ -28,6 +28,12 @@ MARIA_RECORD_POS maria_position(MARIA_HA *info)
}
+uint maria_max_key_length()
+{
+ uint tmp= (_ma_max_key_length() - 8 - HA_MAX_KEY_SEG*3);
+ return min(HA_MAX_KEY_LENGTH, tmp);
+}
+
/* Get information about the table */
/* if flag == 2 one get current info (no sync from database */
diff --git a/storage/maria/ma_key.c b/storage/maria/ma_key.c
index 207ae9a8bda..1e60e6a8c06 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))
{
_ma_set_fatal_error(info->s, HA_ERR_CRASHED);
return -1;
@@ -648,6 +656,54 @@ 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 ; my_errno set to HA_ERR_CRASHED
+ 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.
+ my_errno set to HA_ERR_END_OF_FILE
+
+ info->cur_row.lastpos is set to HA_OFFSET_ERROR in case of ICP_ERROR or
+ ICP_OUT_OF_RANGE to indicate that we don't have any active row.
+*/
+
+ICP_RESULT ma_check_index_cond(register MARIA_HA *info, uint keynr,
+ uchar *record)
+{
+ ICP_RESULT res= ICP_MATCH;
+ if (info->index_cond_func)
+ {
+ if (_ma_put_key_in_record(info, keynr, FALSE, record))
+ {
+ /* Impossible case; Can only happen if bug in code */
+ maria_print_error(info->s, HA_ERR_CRASHED);
+ info->cur_row.lastpos= HA_OFFSET_ERROR; /* No active record */
+ my_errno= HA_ERR_CRASHED;
+ res= ICP_ERROR;
+ }
+ else if ((res= info->index_cond_func(info->index_cond_func_arg)) ==
+ ICP_OUT_OF_RANGE)
+ {
+ /* We got beyond the end of scanned range */
+ info->cur_row.lastpos= HA_OFFSET_ERROR; /* No active record */
+ my_errno= HA_ERR_END_OF_FILE;
+ }
+ }
+ return res;
+}
+
+
/*
Retrieve auto_increment info
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index 2769d7cbd17..e3e4d3945ec 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -458,7 +458,9 @@ void translog_lock_handler_assert_owner()
@param num how many records should be filled
*/
-static void check_translog_description_table(int num)
+static uint max_allowed_translog_type= 0;
+
+void check_translog_description_table(int num)
{
int i;
DBUG_ENTER("check_translog_description_table");
@@ -467,6 +469,7 @@ static void check_translog_description_table(int num)
/* last is reserved for extending the table */
DBUG_ASSERT(num < LOGREC_NUMBER_OF_TYPES - 1);
DBUG_ASSERT(log_record_type_descriptor[0].rclass == LOGRECTYPE_NOT_ALLOWED);
+ max_allowed_translog_type= num;
for (i= 0; i <= num; i++)
{
@@ -1078,7 +1081,7 @@ static my_bool translog_write_file_header()
memcpy(page, maria_trans_file_magic, sizeof(maria_trans_file_magic));
page+= sizeof(maria_trans_file_magic);
/* timestamp */
- timestamp= my_getsystime();
+ timestamp= my_hrtime().val;
int8store(page, timestamp);
page+= 8;
/* maria version */
@@ -3583,6 +3586,7 @@ my_bool translog_init_with_table(const char *directory,
log_descriptor.flush_no= 0;
log_descriptor.next_pass_max_lsn= LSN_IMPOSSIBLE;
+ /* Normally in Aria this this calls translog_table_init() */
(*init_table_func)();
compile_time_assert(sizeof(log_descriptor.dirty_buffer_mask) * 8 >=
TRANSLOG_BUFFERS_NO);
@@ -6224,6 +6228,8 @@ my_bool translog_write_record(LSN *lsn,
(uint) short_trid, (ulong) rec_len));
DBUG_ASSERT(translog_status == TRANSLOG_OK ||
translog_status == TRANSLOG_READONLY);
+ DBUG_ASSERT(type != 0);
+ DBUG_ASSERT((uint)type <= max_allowed_translog_type);
if (unlikely(translog_status != TRANSLOG_OK))
{
DBUG_PRINT("error", ("Transaction log is write protected"));
@@ -6322,9 +6328,9 @@ my_bool translog_write_record(LSN *lsn,
/* process this parts */
if (!(rc= (log_record_type_descriptor[type].prewrite_hook &&
- (*log_record_type_descriptor[type].prewrite_hook) (type, trn,
- tbl_info,
- hook_arg))))
+ (*log_record_type_descriptor[type].prewrite_hook)(type, trn,
+ tbl_info,
+ hook_arg))))
{
switch (log_record_type_descriptor[type].rclass) {
case LOGRECTYPE_VARIABLE_LENGTH:
@@ -6337,6 +6343,7 @@ my_bool translog_write_record(LSN *lsn,
short_trid, &parts, trn, hook_arg);
break;
case LOGRECTYPE_NOT_ALLOWED:
+ DBUG_ASSERT(0);
default:
DBUG_ASSERT(0);
rc= 1;
@@ -7708,7 +7715,7 @@ static my_bool translog_sync_files(uint32 min, uint32 max,
flush_interval= group_commit_wait;
if (flush_interval)
- flush_start= my_micro_time();
+ flush_start= microsecond_interval_timer();
for (fn= min; fn <= max; fn++)
{
TRANSLOG_FILE *file= get_logfile_by_number(fn);
@@ -7975,7 +7982,8 @@ retest:
/*
We do not check time here because pthread_mutex_lock rarely takes
a lot of time so we can sacrifice a bit precision to performance
- (taking into account that my_micro_time() might be expensive call).
+ (taking into account that microsecond_interval_timer() might be
+ expensive call).
*/
if (flush_interval == 0)
break; /* flush pass is ended */
@@ -7984,7 +7992,8 @@ retest:
if (log_descriptor.next_pass_max_lsn == LSN_IMPOSSIBLE)
{
if (flush_interval == 0 ||
- (time_spent= (my_micro_time() - flush_start)) >= flush_interval)
+ (time_spent= (microsecond_interval_timer() - flush_start)) >=
+ flush_interval)
{
pthread_mutex_unlock(&log_descriptor.log_flush_lock);
break;
@@ -8776,7 +8785,7 @@ ma_soft_sync_background( void *arg __attribute__((unused)))
DBUG_ENTER("ma_soft_sync_background");
for(;;)
{
- ulonglong prev_loop= my_micro_time();
+ ulonglong prev_loop= microsecond_interval_timer();
ulonglong time, sleep;
uint32 min, max, sync_request;
min= soft_sync_min;
@@ -8788,7 +8797,7 @@ ma_soft_sync_background( void *arg __attribute__((unused)))
sleep= group_commit_wait;
if (sync_request)
translog_sync_files(min, max, FALSE);
- time= my_micro_time() - prev_loop;
+ time= microsecond_interval_timer() - prev_loop;
if (time > sleep)
sleep= 0;
else
diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h
index f33e92e9771..5ac6d67413a 100644
--- a/storage/maria/ma_loghandler.h
+++ b/storage/maria/ma_loghandler.h
@@ -312,6 +312,9 @@ extern my_bool translog_init_with_table(const char *directory,
my_bool readonly,
void (*init_table_func)(),
my_bool no_error);
+#ifndef DBUG_OFF
+void check_translog_description_table(int num);
+#endif
extern my_bool
translog_write_record(LSN *lsn, enum translog_record_type type, TRN *trn,
diff --git a/storage/maria/ma_norec.c b/storage/maria/ma_norec.c
new file mode 100644
index 00000000000..6d4f37e34fd
--- /dev/null
+++ b/storage/maria/ma_norec.c
@@ -0,0 +1,66 @@
+/* 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 */
+
+/*
+ Functions to handle tables with no row data (only index)
+ This is useful when you just want to do key reads or want to use
+ the index to check against duplicates.
+*/
+
+#include "maria_def.h"
+
+my_bool _ma_write_no_record(MARIA_HA *info __attribute__((unused)),
+ const uchar *record __attribute__((unused)))
+{
+ return 0;
+}
+
+my_bool _ma_update_no_record(MARIA_HA *info __attribute__((unused)),
+ MARIA_RECORD_POS pos __attribute__((unused)),
+ const uchar *oldrec __attribute__((unused)),
+ const uchar *record __attribute__((unused)))
+{
+ return HA_ERR_WRONG_COMMAND;
+}
+
+
+my_bool _ma_delete_no_record(MARIA_HA *info __attribute__((unused)),
+ const uchar *record __attribute__((unused)))
+{
+ return HA_ERR_WRONG_COMMAND;
+}
+
+
+int _ma_read_no_record(MARIA_HA *info __attribute__((unused)),
+ uchar *record __attribute__((unused)),
+ MARIA_RECORD_POS pos __attribute__((unused)))
+{
+ return HA_ERR_WRONG_COMMAND;
+}
+
+
+int _ma_read_rnd_no_record(MARIA_HA *info __attribute__((unused)),
+ uchar *buf __attribute__((unused)),
+ MARIA_RECORD_POS filepos __attribute__((unused)),
+ my_bool skip_deleted_blocks __attribute__((unused)))
+{
+ return HA_ERR_WRONG_COMMAND;
+}
+
+my_off_t _ma_no_keypos_to_recpos(MARIA_SHARE *share __attribute__ ((unused)),
+ my_off_t pos __attribute__ ((unused)))
+{
+ return 0;
+}
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index d3e758ada58..83ad41a9a38 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -62,7 +62,8 @@ MARIA_HA *_ma_test_if_reopen(const char *filename)
{
MARIA_HA *info=(MARIA_HA*) pos->data;
MARIA_SHARE *share= info->s;
- if (!strcmp(share->unique_file_name.str,filename) && share->last_version)
+ if (!strcmp(share->unique_file_name.str,filename) &&
+ share->last_version > 1)
return info;
}
return 0;
@@ -205,6 +206,9 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, const char *name,
#ifdef THREAD
thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
#endif
+ if (share->options & HA_OPTION_TMP_TABLE)
+ m_info->lock.type= TL_WRITE;
+
m_info->open_list.data=(void*) m_info;
maria_open_list=list_add(maria_open_list,&m_info->open_list);
@@ -465,7 +469,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
}
key_parts+=fulltext_keys*FT_SEGS;
- if (share->base.max_key_length > maria_max_key_length() ||
+ if (share->base.max_key_length > _ma_max_key_length() ||
keys > MARIA_MAX_KEY || key_parts > MARIA_MAX_KEY * HA_MAX_KEY_SEG)
{
DBUG_PRINT("error",("Wrong key info: Max_key_length: %d keys: %d key_parts: %d", share->base.max_key_length, keys, key_parts));
@@ -491,6 +495,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
(uint) share->base.block_size,
(uint) maria_block_size));
my_errno=HA_ERR_UNSUPPORTED;
+ my_printf_error(my_errno, "Wrong block size %u; Expected %u",
+ MYF(0),
+ (uint) share->base.block_size,
+ (uint) maria_block_size);
goto err;
}
@@ -791,6 +799,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,
@@ -829,7 +841,12 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->base.key_parts=key_parts;
share->base.all_key_parts=key_parts+unique_key_parts;
if (!(share->last_version=share->state.version))
- share->last_version=1; /* Safety */
+ share->last_version= 2; /* Safety */
+ if (open_flags & HA_OPEN_FOR_STATUS)
+ {
+ share->last_version= 1; /* Not reusable version */
+ share->options|= HA_OPTION_READ_ONLY_DATA;
+ }
share->rec_reflength=share->base.rec_reflength; /* May be changed */
share->base.margin_key_file_length=(share->base.max_key_file_length -
(keys ? MARIA_INDEX_BLOCK_MARGIN *
@@ -973,6 +990,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->state.changed));
pthread_mutex_unlock(&THR_LOCK_maria);
+
+ m_info->open_flags= open_flags;
DBUG_RETURN(m_info);
err:
@@ -1112,6 +1131,20 @@ void _ma_setup_functions(register MARIA_SHARE *share)
else
share->calc_checksum= _ma_checksum;
break;
+ case NO_RECORD:
+ share->read_record= _ma_read_no_record;
+ share->scan= _ma_read_rnd_no_record;
+ share->delete_record= _ma_delete_no_record;
+ share->update_record= _ma_update_no_record;
+ share->write_record= _ma_write_no_record;
+ share->recpos_to_keypos= _ma_no_keypos_to_recpos;
+ share->keypos_to_recpos= _ma_no_keypos_to_recpos;
+
+ /* Abort if following functions are called */
+ share->compare_record= 0;
+ share->compare_unique= 0;
+ share->calc_checksum= 0;
+ break;
case BLOCK_RECORD:
share->once_init= _ma_once_init_block_record;
share->once_end= _ma_once_end_block_record;
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index fff317a7e6e..77091c4747b 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -344,7 +344,7 @@ int maria_apply_log(LSN from_lsn, LSN end_lsn,
}
}
- now= my_getsystime();
+ now= microsecond_interval_timer();
in_redo_phase= TRUE;
if (run_redo_phase(from_lsn, end_lsn, apply))
{
@@ -374,10 +374,10 @@ int maria_apply_log(LSN from_lsn, LSN end_lsn,
in_redo_phase= FALSE;
old_now= now;
- now= my_getsystime();
+ now= microsecond_interval_timer();
if (recovery_message_printed == REC_MSG_REDO)
{
- double phase_took= (now - old_now)/10000000.0;
+ double phase_took= (now - old_now)/1000000.0;
/*
Detailed progress info goes to stderr, because ma_message_no_user()
cannot put several messages on one line.
@@ -443,10 +443,10 @@ int maria_apply_log(LSN from_lsn, LSN end_lsn,
}
old_now= now;
- now= my_getsystime();
+ now= microsecond_interval_timer();
if (recovery_message_printed == REC_MSG_UNDO)
{
- double phase_took= (now - old_now)/10000000.0;
+ double phase_took= (now - old_now)/1000000.0;
procent_printed= 1;
fprintf(stderr, " (%.1f seconds); ", phase_took);
fflush(stderr);
@@ -463,10 +463,10 @@ int maria_apply_log(LSN from_lsn, LSN end_lsn,
}
old_now= now;
- now= my_getsystime();
+ now= microsecond_interval_timer();
if (recovery_message_printed == REC_MSG_FLUSH)
{
- double phase_took= (now - old_now)/10000000.0;
+ double phase_took= (now - old_now)/1000000.0;
procent_printed= 1;
fprintf(stderr, " (%.1f seconds); ", phase_took);
fflush(stderr);
@@ -665,11 +665,13 @@ prototype_redo_exec_hook_dummy(INCOMPLETE_GROUP)
prototype_redo_exec_hook(INCOMPLETE_LOG)
{
MARIA_HA *info;
+
if (skip_DDLs)
{
tprint(tracef, "we skip DDLs\n");
return 0;
}
+
if ((info= get_MARIA_HA_from_REDO_record(rec)) == NULL)
{
/* no such table, don't need to warn */
@@ -1479,7 +1481,13 @@ end:
if (error)
{
if (info != NULL)
+ {
+ /* let maria_close() mark the table properly closed */
+ info->s->state.open_count= 1;
+ info->s->global_changed= 1;
+ info->s->changed= 1;
maria_close(info);
+ }
if (error == -1)
error= 0;
}
diff --git a/storage/maria/ma_rkey.c b/storage/maria/ma_rkey.c
index 976e09ece99..1ece9e0049e 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;
+ ICP_RESULT icp_res= ICP_MATCH;
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));
@@ -82,10 +83,11 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data,
rw_rdlock(&keyinfo->root_lock);
nextflag= maria_read_vec[search_flag] | key.flag;
- if (search_flag != HA_READ_KEY_EXACT ||
- ((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME))
+ if (search_flag != HA_READ_KEY_EXACT)
+ {
+ /* Assume we will get a read next/previous call after this one */
nextflag|= SEARCH_SAVE_BUFF;
-
+ }
switch (keyinfo->key_alg) {
#ifdef HAVE_RTREE_KEYS
case HA_KEY_ALG_RTREE:
@@ -101,16 +103,18 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data,
if (!_ma_search(info, &key, nextflag, info->s->state.key_root[inx]))
{
MARIA_KEY lastkey;
- lastkey.keyinfo= keyinfo;
- lastkey.data= info->lastkey_buff;
/*
Found a key, but it might not be usable. We cannot use rows that
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)) != ICP_NO_MATCH))
break;
/* The key references a concurrently inserted record. */
@@ -122,7 +126,9 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data,
info->cur_row.lastpos= HA_OFFSET_ERROR;
break;
}
-
+
+ lastkey.keyinfo= keyinfo;
+ lastkey.data= info->lastkey_buff;
do
{
uint not_used[2];
@@ -138,6 +144,18 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data,
if (_ma_search_next(info, &lastkey, maria_readnext_vec[search_flag],
info->s->state.key_root[inx]))
break; /* purecov: inspected */
+
+ /*
+ If we are at the last key on the key page, allow writers to
+ access the index.
+ */
+ if (info->int_keypos >= info->int_maxpos &&
+ ma_yield_and_check_if_killed(info, inx))
+ {
+ DBUG_ASSERT(info->cur_row.lastpos == HA_OFFSET_ERROR);
+ break;
+ }
+
/*
Check that the found key does still match the search.
_ma_search_next() delivers the next key regardless of its
@@ -153,7 +171,13 @@ 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));
+ }
+ else
+ {
+ DBUG_ASSERT(info->cur_row.lastpos);
}
}
if (share->lock_key_trees)
@@ -161,10 +185,15 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data,
if (info->cur_row.lastpos == HA_OFFSET_ERROR)
{
+ if (icp_res == ICP_OUT_OF_RANGE)
+ {
+ /* We don't want HA_ERR_END_OF_FILE in this particular case */
+ 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,
@@ -200,3 +229,37 @@ err:
info->update|=HA_STATE_NEXT_FOUND; /* Previous gives last row */
DBUG_RETURN(my_errno);
} /* _ma_rkey */
+
+
+/*
+ Yield to possible other writers during a index scan.
+ Check also if we got killed by the user and if yes, return
+ HA_ERR_LOCK_WAIT_TIMEOUT
+
+ return 0 ok
+ return 1 Query has been requested to be killed
+*/
+
+my_bool ma_yield_and_check_if_killed(MARIA_HA *info, int inx)
+{
+ MARIA_SHARE *share;
+ if (ma_killed(info))
+ {
+ /* purecov: begin tested */
+ /* Mark that we don't have an active row */
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
+ /* Set error that we where aborted by kill from application */
+ my_errno= HA_ERR_ABORTED_BY_USER;
+ return 1;
+ /* purecov: end */
+ }
+
+ if ((share= info->s)->lock_key_trees)
+ {
+ /* Give writers a chance to access index */
+ rw_unlock(&share->keyinfo[inx].root_lock);
+ rw_rdlock(&share->keyinfo[inx].root_lock);
+ }
+ return 0;
+}
+
diff --git a/storage/maria/ma_rnext.c b/storage/maria/ma_rnext.c
index c49bbb19e83..e5ee84b61c7 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;
+ ICP_RESULT icp_res= ICP_MATCH;
uint update_mask= HA_STATE_NEXT_FOUND;
DBUG_ENTER("maria_rnext");
@@ -105,8 +106,21 @@ 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)) == ICP_NO_MATCH))
{
+ /*
+ If we are at the last key on the key page, allow writers to
+ access the index.
+ */
+ if (info->int_keypos >= info->int_maxpos &&
+ ma_yield_and_check_if_killed(info, inx))
+ {
+ /* my_errno is set by ma_yield_and_check_if_killed() */
+ error= 1;
+ break;
+ }
+
/* Skip rows inserted by other threads since we got a lock */
if ((error= _ma_search_next(info, &info->last_key,
SEARCH_BIGGER,
@@ -120,14 +134,16 @@ 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 (error)
+
+ if (error || icp_res != ICP_MATCH)
{
+ fast_ma_writeinfo(info);
if (my_errno == HA_ERR_KEY_NOT_FOUND)
- my_errno=HA_ERR_END_OF_FILE;
+ my_errno= HA_ERR_END_OF_FILE;
}
else if (!buf)
{
+ fast_ma_writeinfo(info);
DBUG_RETURN(info->cur_row.lastpos == HA_OFFSET_ERROR ? my_errno : 0);
}
else if (!(*info->read_record)(info, buf, info->cur_row.lastpos))
diff --git a/storage/maria/ma_rnext_same.c b/storage/maria/ma_rnext_same.c
index cbd81d20816..c35d8ae0222 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;
+ ICP_RESULT icp_res= ICP_MATCH;
DBUG_ENTER("maria_rnext_same");
if ((int) (inx= info->lastinx) < 0 ||
@@ -79,8 +80,19 @@ int maria_rnext_same(MARIA_HA *info, uchar *buf)
info->cur_row.lastpos= HA_OFFSET_ERROR;
break;
}
+ /*
+ If we are at the last key on the key page, allow writers to
+ access the index.
+ */
+ if (info->int_keypos >= info->int_maxpos &&
+ ma_yield_and_check_if_killed(info, inx))
+ {
+ error= 1;
+ 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)) != ICP_NO_MATCH))
break;
}
}
@@ -90,13 +102,15 @@ 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 (error || icp_res != ICP_MATCH)
{
+ fast_ma_writeinfo(info);
if (my_errno == HA_ERR_KEY_NOT_FOUND)
- my_errno=HA_ERR_END_OF_FILE;
+ my_errno= HA_ERR_END_OF_FILE;
}
else if (!buf)
{
+ fast_ma_writeinfo(info);
DBUG_RETURN(info->cur_row.lastpos == HA_OFFSET_ERROR ? my_errno : 0);
}
else if (!(*info->read_record)(info, buf, info->cur_row.lastpos))
diff --git a/storage/maria/ma_rprev.c b/storage/maria/ma_rprev.c
index b9f46d7c405..c4bcb9de967 100644
--- a/storage/maria/ma_rprev.c
+++ b/storage/maria/ma_rprev.c
@@ -28,6 +28,7 @@ int maria_rprev(MARIA_HA *info, uchar *buf, int inx)
register uint flag;
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo;
+ ICP_RESULT icp_res= ICP_MATCH;
DBUG_ENTER("maria_rprev");
if ((inx = _ma_check_index(info,inx)) < 0)
@@ -55,8 +56,24 @@ int maria_rprev(MARIA_HA *info, uchar *buf, int inx)
if (!error)
{
- while (!(*share->row_is_visible)(info))
+ my_off_t cur_keypage= info->last_keypage;
+ while (!(*share->row_is_visible)(info) ||
+ ((icp_res= ma_check_index_cond(info, inx, buf)) == ICP_NO_MATCH))
{
+ /*
+ If we are at the last (i.e. first?) key on the key page,
+ allow writers to access the index.
+ */
+ if (info->last_keypage != cur_keypage)
+ {
+ cur_keypage= info->last_keypage;
+ if (ma_yield_and_check_if_killed(info, inx))
+ {
+ error= 1;
+ break;
+ }
+ }
+
/* Skip rows that are inserted by other threads since we got a lock */
if ((error= _ma_search_next(info, &info->last_key,
SEARCH_SMALLER,
@@ -68,13 +85,16 @@ int maria_rprev(MARIA_HA *info, uchar *buf, int inx)
rw_unlock(&keyinfo->root_lock);
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
info->update|= HA_STATE_PREV_FOUND;
- if (error)
+
+ if (error || icp_res != ICP_MATCH)
{
+ fast_ma_writeinfo(info);
if (my_errno == HA_ERR_KEY_NOT_FOUND)
- my_errno=HA_ERR_END_OF_FILE;
+ my_errno= HA_ERR_END_OF_FILE;
}
else if (!buf)
{
+ fast_ma_writeinfo(info);
DBUG_RETURN(info->cur_row.lastpos == HA_OFFSET_ERROR ? my_errno : 0);
}
else if (!(*info->read_record)(info, buf, info->cur_row.lastpos))
diff --git a/storage/maria/ma_rrnd.c b/storage/maria/ma_rrnd.c
index 24c4bfdd467..8c35c71c95e 100644
--- a/storage/maria/ma_rrnd.c
+++ b/storage/maria/ma_rrnd.c
@@ -30,6 +30,7 @@
int maria_rrnd(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS filepos)
{
+ int ret;
DBUG_ENTER("maria_rrnd");
DBUG_ASSERT(filepos != HA_OFFSET_ERROR);
@@ -40,5 +41,6 @@ int maria_rrnd(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS filepos)
DBUG_RETURN(my_errno);
info->cur_row.lastpos= filepos; /* Remember for update */
- DBUG_RETURN((*info->s->read_record)(info, buf, filepos));
+ ret= (*info->s->read_record)(info, buf, filepos);
+ DBUG_RETURN(ret);
}
diff --git a/storage/maria/ma_rt_index.c b/storage/maria/ma_rt_index.c
index bd1b9038ccf..e0f8a5dca41 100644
--- a/storage/maria/ma_rt_index.c
+++ b/storage/maria/ma_rt_index.c
@@ -196,6 +196,12 @@ int maria_rtree_find_first(MARIA_HA *info, MARIA_KEY *key, uint32 search_flag)
uint nod_cmp_flag;
MARIA_KEYDEF *keyinfo= key->keyinfo;
+ /*
+ At the moment index can only properly handle the
+ MBR_INTERSECT, so we use it for all sorts of queries.
+ TODO: better searsh for CONTAINS/WITHIN.
+ */
+ search_flag= nod_cmp_flag= MBR_INTERSECT;
if ((root= info->s->state.key_root[keyinfo->key_nr]) == HA_OFFSET_ERROR)
{
my_errno= HA_ERR_END_OF_FILE;
@@ -213,8 +219,11 @@ int maria_rtree_find_first(MARIA_HA *info, MARIA_KEY *key, uint32 search_flag)
info->maria_rtree_recursion_depth= -1;
info->keyread_buff_used= 1;
- nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
- MBR_WITHIN : MBR_INTERSECT);
+ /*
+ TODO better search for CONTAINS/WITHIN.
+ nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
+ MBR_WITHIN : MBR_INTERSECT);
+ */
return maria_rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root,
0);
}
@@ -241,6 +250,12 @@ int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint32 search_flag)
uint32 nod_cmp_flag;
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
DBUG_ASSERT(info->last_key.keyinfo == keyinfo);
+ /*
+ At the moment index can only properly handle the
+ MBR_INTERSECT, so we use it for all sorts of queries.
+ TODO: better searsh for CONTAINS/WITHIN.
+ */
+ search_flag= nod_cmp_flag= MBR_INTERSECT;
if (info->update & HA_STATE_DELETED)
return maria_rtree_find_first(info, &info->last_key, search_flag);
@@ -284,8 +299,11 @@ int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint32 search_flag)
return -1;
}
- nod_cmp_flag= (((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
- MBR_WITHIN : MBR_INTERSECT));
+ /*
+ TODO better search for CONTAINS/WITHIN.
+ nod_cmp_flag= (((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
+ MBR_WITHIN : MBR_INTERSECT));
+ */
return maria_rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root,
0);
}
@@ -1258,7 +1276,7 @@ ha_rows maria_rtree_estimate(MARIA_HA *info, MARIA_KEY *key, uint32 flag)
MARIA_PAGE page;
if (flag & MBR_DISJOINT)
- return info->state->records;
+ return HA_POS_ERROR;
if ((root= share->state.key_root[key->keyinfo->key_nr]) == HA_OFFSET_ERROR)
return HA_POS_ERROR;
diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c
index 166de13831f..78672cd2094 100644
--- a/storage/maria/ma_search.c
+++ b/storage/maria/ma_search.c
@@ -149,7 +149,11 @@ static int _ma_search_no_save(register MARIA_HA *info, MARIA_KEY *key,
flag= (*keyinfo->bin_search)(key, &page, nextflag, &keypos, lastkey,
&last_key_not_used);
if (flag == MARIA_FOUND_WRONG_KEY)
- DBUG_RETURN(-1);
+ {
+ maria_print_error(info->s, HA_ERR_CRASHED);
+ my_errno= HA_ERR_CRASHED;
+ goto err;
+ }
page_flag= page.flag;
used_length= page.size;
nod_flag= page.node;
@@ -790,6 +794,7 @@ MARIA_RECORD_POS _ma_row_pos_from_key(const MARIA_KEY *key)
case 4: pos= (my_off_t) mi_uint4korr(after_key); break;
case 3: pos= (my_off_t) mi_uint3korr(after_key); break;
case 2: pos= (my_off_t) mi_uint2korr(after_key); break;
+ case 0: /* NO_RECORD */
default:
pos=0L; /* Shut compiler up */
}
@@ -899,6 +904,7 @@ void _ma_dpointer(MARIA_SHARE *share, uchar *buff, my_off_t pos)
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
case 2: mi_int2store(buff,(uint) pos); break;
+ case 0: break; /* For NO_RECORD */
default: abort(); /* Impossible */
}
} /* _ma_dpointer */
diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c
index 5c5bd8f8d6c..7bfb53ca0a1 100644
--- a/storage/maria/ma_sort.c
+++ b/storage/maria/ma_sort.c
@@ -191,6 +191,9 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
&tempfile,&tempfile_for_exceptions))
== HA_POS_ERROR)
goto err; /* purecov: tested */
+
+ info->sort_info->param->stage++; /* Merge stage */
+
if (maxbuffer == 0)
{
if (!no_messages)
@@ -769,6 +772,8 @@ static int write_index(MARIA_SORT_PARAM *info,
if ((*info->key_write)(info, *sort_keys++))
DBUG_RETURN(-1); /* purecov: inspected */
}
+ if (info->sort_info->param->max_stage != 1) /* If not parallel */
+ _ma_report_progress(info->sort_info->param, 1, 1);
DBUG_RETURN(0);
} /* write_index */
@@ -779,7 +784,7 @@ static int merge_many_buff(MARIA_SORT_PARAM *info, uint keys,
uchar **sort_keys, BUFFPEK *buffpek,
int *maxbuffer, IO_CACHE *t_file)
{
- register int i;
+ int tmp, merges, max_merges;
IO_CACHE t_file2, *from_file, *to_file, *temp;
BUFFPEK *lastbuff;
DBUG_ENTER("merge_many_buff");
@@ -791,9 +796,21 @@ static int merge_many_buff(MARIA_SORT_PARAM *info, uint keys,
DISK_BUFFER_SIZE, info->sort_info->param->myf_rw))
DBUG_RETURN(1); /* purecov: inspected */
+ /* Calculate how many merges are needed */
+ max_merges= 1; /* Count merge_index */
+ tmp= *maxbuffer;
+ while (tmp >= MERGEBUFF2)
+ {
+ merges= (tmp-MERGEBUFF*3/2 + 1) / MERGEBUFF + 1;
+ max_merges+= merges;
+ tmp= merges;
+ }
+ merges= 0;
+
from_file= t_file ; to_file= &t_file2;
while (*maxbuffer >= MERGEBUFF2)
{
+ int i;
reinit_io_cache(from_file,READ_CACHE,0L,0,0);
reinit_io_cache(to_file,WRITE_CACHE,0L,0,0);
lastbuff=buffpek;
@@ -802,6 +819,8 @@ static int merge_many_buff(MARIA_SORT_PARAM *info, uint keys,
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
buffpek+i,buffpek+i+MERGEBUFF-1))
goto cleanup;
+ if (info->sort_info->param->max_stage != 1) /* If not parallel */
+ _ma_report_progress(info->sort_info->param, merges++, max_merges);
}
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
buffpek+i,buffpek+ *maxbuffer))
@@ -810,6 +829,8 @@ static int merge_many_buff(MARIA_SORT_PARAM *info, uint keys,
break; /* purecov: inspected */
temp=from_file; from_file=to_file; to_file=temp;
*maxbuffer= (int) (lastbuff-buffpek)-1;
+ if (info->sort_info->param->max_stage != 1) /* If not parallel */
+ _ma_report_progress(info->sort_info->param, merges++, max_merges);
}
cleanup:
close_cached_file(to_file); /* This holds old result */
@@ -939,7 +960,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 +1009,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 +1034,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);
@@ -1066,6 +1087,8 @@ merge_index(MARIA_SORT_PARAM *info, uint keys, uchar **sort_keys,
if (merge_buffers(info,keys,tempfile,(IO_CACHE*) 0,sort_keys,buffpek,buffpek,
buffpek+maxbuffer))
DBUG_RETURN(1); /* purecov: inspected */
+ if (info->sort_info->param->max_stage != 1) /* If not parallel */
+ _ma_report_progress(info->sort_info->param, 1, 1);
DBUG_RETURN(0);
} /* merge_index */
diff --git a/storage/maria/ma_static.c b/storage/maria/ma_static.c
index 5c88ba6745b..71094fb0343 100644
--- a/storage/maria/ma_static.c
+++ b/storage/maria/ma_static.c
@@ -39,6 +39,7 @@ my_bool maria_inited= FALSE;
my_bool maria_in_ha_maria= FALSE; /* If used from ha_maria or not */
my_bool maria_recovery_changed_data= 0, maria_recovery_verbose= 0;
my_bool maria_assert_if_crashed_table= 0;
+my_bool maria_checkpoint_disabled= 0;
pthread_mutex_t THR_LOCK_maria;
#if defined(THREAD) && !defined(DONT_USE_RW_LOCKS)
@@ -109,3 +110,6 @@ static int always_valid(const char *filename __attribute__((unused)))
}
int (*maria_test_invalid_symlink)(const char *filename)= always_valid;
+
+my_bool (*ma_killed)(MARIA_HA *)= ma_killed_standalone;
+
diff --git a/storage/maria/ma_test1.c b/storage/maria/ma_test1.c
index ec3060822f9..4b0eb0f5644 100644
--- a/storage/maria/ma_test1.c
+++ b/storage/maria/ma_test1.c
@@ -410,6 +410,10 @@ static int run_test(const char *filename)
if (!silent)
printf("- Reading rows with key\n");
record[1]= 0; /* For nicer printf */
+
+ if (record_type == NO_RECORD)
+ maria_extra(file, HA_EXTRA_KEYREAD, 0);
+
for (i=0 ; i <= 25 ; i++)
{
create_key(key,i);
@@ -423,9 +427,15 @@ static int run_test(const char *filename)
(int) key_length,key+offset_to_key,error,my_errno,record+1);
}
}
+ if (record_type == NO_RECORD)
+ {
+ maria_extra(file, HA_EXTRA_NO_KEYREAD, 0);
+ goto end;
+ }
if (!silent)
printf("- Reading rows with position\n");
+
if (maria_scan_init(file))
{
fprintf(stderr, "maria_scan_init failed\n");
@@ -760,6 +770,8 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"rows-in-block", 'M', "Store rows in block format",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"rows-no-data", 'n', "Don't store any data, only keys",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"row-pointer-size", 'R', "Undocumented", (uchar**) &rec_pointer_size,
(uchar**) &rec_pointer_size, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"silent", 's', "Undocumented",
@@ -819,6 +831,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case 'M':
record_type= BLOCK_RECORD;
break;
+ case 'n':
+ record_type= NO_RECORD;
+ break;
case 'S':
if (key_field == FIELD_VARCHAR)
{
@@ -890,6 +905,10 @@ static void get_options(int argc, char *argv[])
exit(ho_error);
if (transactional)
record_type= BLOCK_RECORD;
+ if (record_type == NO_RECORD)
+ skip_update= skip_delete= 1;
+
+
return;
} /* get options */
diff --git a/storage/maria/ma_test3.c b/storage/maria/ma_test3.c
index 040d6fa78c2..0dfbf46cafc 100644
--- a/storage/maria/ma_test3.c
+++ b/storage/maria/ma_test3.c
@@ -17,7 +17,7 @@
#if !(defined (__NETWARE_) || defined (_WIN32)) /*no fork() in Windows*/
-#include "maria.h"
+#include "maria_def.h"
#include <sys/types.h>
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
diff --git a/storage/maria/ma_unique.c b/storage/maria/ma_unique.c
index 2fcca9cbe10..6f92ca1559c 100644
--- a/storage/maria/ma_unique.c
+++ b/storage/maria/ma_unique.c
@@ -52,7 +52,8 @@ my_bool _ma_check_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def, uchar *record,
info->lastinx= ~0;
DBUG_ASSERT(key.data_length == MARIA_UNIQUE_HASH_LENGTH);
- if (_ma_search(info, &key, SEARCH_FIND, info->s->state.key_root[def->key]))
+ if (_ma_search(info, &key, SEARCH_FIND | SEARCH_SAVE_BUFF,
+ info->s->state.key_root[def->key]))
{
info->page_changed=1; /* Can't optimize read next */
info->cur_row.lastpos= lastpos;
@@ -145,13 +146,14 @@ ha_checksum _ma_unique_hash(MARIA_UNIQUEDEF *def, const uchar *record)
keyseg->charset->coll->hash_sort(keyseg->charset,
(const uchar*) pos, length, &seed1,
&seed2);
- crc^= seed1;
+ crc+= seed1;
}
else
- while (pos != end)
- crc=((crc << 8) +
- (((uchar) *pos++))) +
- (crc >> (8*sizeof(ha_checksum)-8));
+ {
+ my_hash_sort_bin((CHARSET_INFO*) 0, pos, (size_t) (end-pos),
+ &seed1, &seed2);
+ crc+= seed1;
+ }
}
return crc;
}
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index 5db2de51625..87de79b2eae 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -124,12 +124,23 @@ int maria_write(MARIA_HA *info, uchar *record)
goto err2;
/* Calculate and check all unique constraints */
- for (i=0 ; i < share->state.header.uniques ; i++)
+
+ if (share->state.header.uniques)
{
- if (_ma_check_unique(info,share->uniqueinfo+i,record,
- _ma_unique_hash(share->uniqueinfo+i,record),
- HA_OFFSET_ERROR))
- goto err2;
+ for (i=0 ; i < share->state.header.uniques ; i++)
+ {
+ MARIA_UNIQUEDEF *def= share->uniqueinfo + i;
+ ha_checksum unique_hash= _ma_unique_hash(share->uniqueinfo+i,record);
+ if (maria_is_key_active(share->state.key_map, def->key))
+ {
+ if (_ma_check_unique(info, def, record,
+ unique_hash, HA_OFFSET_ERROR))
+ goto err2;
+ }
+ else
+ maria_unique_store(record+ share->keyinfo[def->key].seg->start,
+ unique_hash);
+ }
}
/* Ensure we don't try to restore auto_increment if it doesn't change */
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index 52a30dce235..34e9ed108ba 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -70,7 +70,7 @@ static const char *field_pack[]=
static const char *record_formats[]=
{
- "Fixed length", "Packed", "Compressed", "Block", "?"
+ "Fixed length", "Packed", "Compressed", "Block", "No data", "?", "?"
};
static const char *bitmap_description[]=
@@ -436,7 +436,7 @@ static struct my_option my_long_options[] =
static void print_version(void)
{
- printf("%s Ver 1.0 for %s at %s\n", my_progname, SYSTEM_TYPE,
+ printf("%s Ver 1.1 for %s at %s\n", my_progname, SYSTEM_TYPE,
MACHINE_TYPE);
NETWARE_SET_SCREEN_MODE(1);
}
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 4692896212d..d68db73bd77 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -16,6 +16,7 @@
/* This file is included by all internal maria files */
#include "maria.h" /* Structs & some defines */
+#include "ma_pagecache.h"
#include <myisampack.h> /* packing of keys */
#include <my_tree.h>
#include <my_bitmap.h>
@@ -48,6 +49,77 @@
/* maria_open() flag, specific for maria_pack */
#define HA_OPEN_IGNORE_MOVED_STATE (1U << 30)
+extern PAGECACHE maria_pagecache_var, *maria_pagecache;
+int maria_assign_to_pagecache(MARIA_HA *info, ulonglong key_map,
+ PAGECACHE *key_cache);
+void maria_change_pagecache(PAGECACHE *old_key_cache,
+ PAGECACHE *new_key_cache);
+
+typedef struct st_maria_sort_info
+{
+#ifdef THREAD
+ /* sync things */
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+#endif
+ MARIA_HA *info, *new_info;
+ HA_CHECK *param;
+ char *buff;
+ SORT_KEY_BLOCKS *key_block, *key_block_end;
+ SORT_FT_BUF *ft_buf;
+ my_off_t filelength, dupp, buff_length;
+ pgcache_page_no_t page;
+ ha_rows max_records;
+ uint current_key, total_keys;
+ uint got_error, threads_running;
+ myf myf_rw;
+ enum data_file_type new_data_file_type, org_data_file_type;
+} MARIA_SORT_INFO;
+
+typedef struct st_maria_sort_param
+{
+ pthread_t thr;
+ IO_CACHE read_cache, tempfile, tempfile_for_exceptions;
+ DYNAMIC_ARRAY buffpek;
+ MARIA_BIT_BUFF bit_buff; /* For parallel repair of packrec. */
+
+ MARIA_KEYDEF *keyinfo;
+ MARIA_SORT_INFO *sort_info;
+ HA_KEYSEG *seg;
+ uchar **sort_keys;
+ uchar *rec_buff;
+ void *wordlist, *wordptr;
+ MEM_ROOT wordroot;
+ uchar *record;
+ MY_TMPDIR *tmpdir;
+
+ /*
+ The next two are used to collect statistics, see maria_update_key_parts for
+ description.
+ */
+ ulonglong unique[HA_MAX_KEY_SEG+1];
+ ulonglong notnull[HA_MAX_KEY_SEG+1];
+
+ MARIA_RECORD_POS pos,max_pos,filepos,start_recpos, current_filepos;
+ uint key, key_length,real_key_length,sortbuff_size;
+ uint maxbuffers, keys, find_length, sort_keys_length;
+ my_bool fix_datafile, master;
+ my_bool calc_checksum; /* calculate table checksum */
+ size_t rec_buff_size;
+
+ int (*key_cmp)(struct st_maria_sort_param *, const void *, const void *);
+ int (*key_read)(struct st_maria_sort_param *, uchar *);
+ int (*key_write)(struct st_maria_sort_param *, const uchar *);
+ void (*lock_in_memory)(HA_CHECK *);
+ int (*write_keys)(struct st_maria_sort_param *, register uchar **,
+ uint , struct st_buffpek *, IO_CACHE *);
+ uint (*read_to_buffer)(IO_CACHE *,struct st_buffpek *, uint);
+ int (*write_key)(struct st_maria_sort_param *, IO_CACHE *,uchar *,
+ uint, uint);
+} MARIA_SORT_PARAM;
+
+int maria_write_data_suffix(MARIA_SORT_INFO *sort_info, my_bool fix_datafile);
+
struct st_transaction;
/* undef map from my_nosys; We need test-if-disk full */
@@ -386,6 +458,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 */
/*
Set to 1 if open_count was wrong at open. Set to avoid asserts for
wrong open count on close.
@@ -497,12 +571,12 @@ 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
{
MARIA_SHARE *s; /* Shared between open:s */
struct st_ma_transaction *trn; /* Pointer to active transaction */
- void *external_ptr; /* Pointer to THD in mysql */
MARIA_STATUS_INFO *state, state_save;
MARIA_STATUS_INFO *state_start; /* State at start of transaction */
MARIA_ROW cur_row; /* The active row that we just read */
@@ -519,6 +593,7 @@ struct st_maria_handler
DYNAMIC_ARRAY *ft1_to_ft2; /* used only in ft1->ft2 conversion */
MEM_ROOT ft_memroot; /* used by the parser */
MYSQL_FTPARSER_PARAM *ftparser_param; /* share info between init/deinit */
+ void *external_ref; /* For MariaDB TABLE */
uchar *buff; /* page buffer */
uchar *keyread_buff; /* Buffer for last key read */
uchar *lastkey_buff; /* Last used search key */
@@ -560,6 +635,7 @@ struct st_maria_handler
ulong row_base_length; /* Length of row header */
uint row_flag; /* Flag to store in row header */
uint opt_flag; /* Optim. for space/speed */
+ uint open_flags; /* Flags used in open() */
uint update; /* If file changed since open */
int lastinx; /* Last used index */
uint last_rkey_length; /* Last length in maria_rkey() */
@@ -601,6 +677,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 */
@@ -740,7 +819,7 @@ struct st_maria_handler
{ length=mi_uint2korr((key)+1)+3; } \
}
-#define maria_max_key_length() ((maria_block_size - MAX_KEYPAGE_HEADER_SIZE)/3 - MARIA_INDEX_OVERHEAD_SIZE)
+#define _ma_max_key_length() ((maria_block_size - MAX_KEYPAGE_HEADER_SIZE)/3 - MARIA_INDEX_OVERHEAD_SIZE)
#define get_pack_length(length) ((length) >= 255 ? 3 : 1)
#define _ma_have_versioning(info) ((info)->row_flag & ROW_FLAG_TRANSID)
@@ -819,11 +898,12 @@ extern uint maria_quick_table_bits;
extern char *maria_data_root;
extern uchar maria_zero_string[];
extern my_bool maria_inited, maria_in_ha_maria, maria_recovery_changed_data;
-extern my_bool maria_recovery_verbose;
+extern my_bool maria_recovery_verbose, maria_checkpoint_disabled;
extern my_bool maria_assert_if_crashed_table;
extern ulong maria_checkpoint_min_log_activity;
extern HASH maria_stored_state;
extern int (*maria_create_trn_hook)(MARIA_HA *);
+extern my_bool (*ma_killed)(MARIA_HA *);
/* This is used by _ma_calc_xxx_key_length och _ma_store_key */
typedef struct st_maria_s_param
@@ -883,6 +963,18 @@ extern my_bool _ma_update_static_record(MARIA_HA *, MARIA_RECORD_POS,
const uchar *, const uchar *);
extern my_bool _ma_delete_static_record(MARIA_HA *info, const uchar *record);
extern my_bool _ma_cmp_static_record(MARIA_HA *info, const uchar *record);
+
+extern my_bool _ma_write_no_record(MARIA_HA *info, const uchar *record);
+extern my_bool _ma_update_no_record(MARIA_HA *info, MARIA_RECORD_POS pos,
+ const uchar *oldrec, const uchar *record);
+extern my_bool _ma_delete_no_record(MARIA_HA *info, const uchar *record);
+extern int _ma_read_no_record(MARIA_HA *info, uchar *record,
+ MARIA_RECORD_POS pos);
+extern int _ma_read_rnd_no_record(MARIA_HA *info, uchar *buf,
+ MARIA_RECORD_POS filepos,
+ my_bool skip_deleted_blocks);
+my_off_t _ma_no_keypos_to_recpos(MARIA_SHARE *share, my_off_t pos);
+
extern my_bool _ma_ck_write(MARIA_HA *info, MARIA_KEY *key);
extern my_bool _ma_enlarge_root(MARIA_HA *info, MARIA_KEY *key,
MARIA_RECORD_POS *root);
@@ -1207,6 +1299,8 @@ int _ma_flush_table_files(MARIA_HA *info, uint flush_data_or_index,
See ma_check_standalone.h .
*/
int _ma_killed_ptr(HA_CHECK *param);
+void _ma_report_progress(HA_CHECK *param, ulonglong progress,
+ ulonglong max_progress);
void _ma_check_print_error _VARARGS((HA_CHECK *param, const char *fmt, ...))
ATTRIBUTE_FORMAT(printf, 2, 3);
void _ma_check_print_warning _VARARGS((HA_CHECK *param, const char *fmt, ...))
@@ -1281,4 +1375,11 @@ 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);
+ICP_RESULT ma_check_index_cond(register MARIA_HA *info, uint keynr, uchar *record);
+
+extern my_bool ma_yield_and_check_if_killed(MARIA_HA *info, int inx);
+extern my_bool ma_killed_standalone(MARIA_HA *);
+
extern uint _ma_file_callback_to_id(void *callback_data);
diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c
index c87ecfa7776..350bfa1914c 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/maria/tablockman.c b/storage/maria/tablockman.c
index 1bb8889aaa7..eb494a8d19b 100644
--- a/storage/maria/tablockman.c
+++ b/storage/maria/tablockman.c
@@ -607,7 +607,7 @@ void tablockman_init(TABLOCKMAN *lm, loid_to_tlo_func *func, uint timeout)
lm->loid_to_tlo= func;
lm->lock_timeout= timeout;
pthread_mutex_init(& lm->pool_mutex, MY_MUTEX_INIT_FAST);
- my_getsystime(); /* ensure that my_getsystime() is initialized */
+ my_interval_timer(); /* ensure that my_interval_timer() is initialized */
}
void tablockman_destroy(TABLOCKMAN *lm)
diff --git a/storage/maria/unittest/ma_loghandler_examples.c b/storage/maria/unittest/ma_loghandler_examples.c
index 0c11a3b9a8e..cd5d927587a 100644
--- a/storage/maria/unittest/ma_loghandler_examples.c
+++ b/storage/maria/unittest/ma_loghandler_examples.c
@@ -59,6 +59,9 @@ void translog_example_table_init()
i < LOGREC_NUMBER_OF_TYPES;
i++)
log_record_type_descriptor[i].rclass= LOGRECTYPE_NOT_ALLOWED;
+#ifndef DBUG_OFF
+ check_translog_description_table(LOGREC_VARIABLE_RECORD_2LSN_EXAMPLE);
+#endif
}
diff --git a/storage/maria/unittest/ma_test_all-t b/storage/maria/unittest/ma_test_all-t
index 75e1442998f..e66d269ab93 100755
--- a/storage/maria/unittest/ma_test_all-t
+++ b/storage/maria/unittest/ma_test_all-t
@@ -283,6 +283,7 @@ sub run_check_tests
["-p -B --key_length=480","-sm"],
["--checksum --unique","-se"],
["--unique","-se"],
+ ["--rows-no-data", "-s"],
["--key_multiple -N -S","-sm"],
["--key_multiple -a -p --key_length=480","-sm"],
["--key_multiple -a -B --key_length=480","-sm"],
@@ -623,7 +624,7 @@ sub ok
print " ]" if ($verbose);
print " $test_counter - $com" unless $verbose;
print "\n";
- if (defined($output) && length($output))
+ if ($verbose && defined($output) && length($output))
{
print "$output\n";
}
diff --git a/storage/maria/unittest/trnman-t.c b/storage/maria/unittest/trnman-t.c
index 43cf982a7f2..92919b37152 100644
--- a/storage/maria/unittest/trnman-t.c
+++ b/storage/maria/unittest/trnman-t.c
@@ -75,7 +75,7 @@ pthread_handler_t test_trnman(void *arg)
void run_test(const char *test, pthread_handler handler, int n, int m)
{
pthread_t *threads;
- ulonglong now= my_getsystime();
+ ulonglong now= microsecond_interval_timer();
int i;
litmus= 0;
@@ -97,8 +97,8 @@ void run_test(const char *test, pthread_handler handler, int n, int m)
}
for (i= 0 ; i < n ; i++)
pthread_join(threads[i], 0);
- now= my_getsystime()-now;
- ok(litmus == 0, "Tested %s in %g secs (%d)", test, ((double)now)/1e7, litmus);
+ now= microsecond_interval_timer() - now;
+ ok(litmus == 0, "Tested %s in %g secs (%d)", test, ((double)now)/1e6, litmus);
my_free((void*)threads, MYF(0));
}
@@ -162,10 +162,10 @@ int main(int argc __attribute__((unused)), char **argv)
diag("mallocs: %d", trnman_allocated_transactions);
{
- ulonglong now= my_getsystime();
+ ulonglong now= microsecond_interval_timer();
trnman_destroy();
- now= my_getsystime()-now;
- diag("trnman_destroy: %g", ((double)now)/1e7);
+ now= microsecond_interval_timer() - now;
+ diag("trnman_destroy: %g", ((double)now)/1e6);
}
pthread_mutex_destroy(&rt_mutex);
diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c
index 3f3e0230135..0a4d0a3bac1 100644
--- a/storage/myisam/ft_boolean_search.c
+++ b/storage/myisam/ft_boolean_search.c
@@ -496,16 +496,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)
{
@@ -609,12 +611,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;
@@ -853,7 +855,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 be8d8390ba4..a6dedb4da8a 100644
--- a/storage/myisam/ft_nlq_search.c
+++ b/storage/myisam/ft_nlq_search.c
@@ -268,12 +268,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 f0a6eb3ea39..0e2b7189952 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -300,6 +300,8 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out,
if (found->flags & BLOB_FLAG)
recinfo_pos->type= FIELD_BLOB;
+ else if (found->type() == MYSQL_TYPE_TIMESTAMP)
+ recinfo_pos->type= FIELD_NORMAL;
else if (found->type() == MYSQL_TYPE_VARCHAR)
recinfo_pos->type= FIELD_VARCHAR;
else if (!(options & HA_OPTION_PACK_RECORD))
@@ -542,8 +544,14 @@ void mi_check_print_warning(HA_CHECK *param, const char *fmt,...)
va_end(args);
}
+/* Return 1 if user have requested query to be killed */
+
+my_bool mi_killed_in_mariadb(MI_INFO *info)
+{
+ return (((TABLE*) (info->external_ref))->in_use->killed != 0);
}
+}
ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
:handler(hton, table_arg), file(0),
@@ -683,6 +691,28 @@ err:
#endif /* HAVE_REPLICATION */
+ulong ha_myisam::index_flags(uint inx, uint part, bool all_parts) const
+{
+ ulong flags;
+ if (table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT)
+ flags= 0;
+ else
+ if ((table_share->key_info[inx].flags & HA_SPATIAL ||
+ table_share->key_info[inx].algorithm == HA_KEY_ALG_RTREE))
+ {
+ /* All GIS scans are non-ROR scans. We also disable IndexConditionPushdown */
+ flags= HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
+ HA_READ_ORDER | HA_KEYREAD_ONLY | HA_KEY_SCAN_NOT_ROR;
+ }
+ else
+ {
+ flags= HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
+ HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN;
+ }
+ return flags;
+}
+
+
/* Name is here without an extension */
int ha_myisam::open(const char *name, int mode, uint test_if_locked)
{
@@ -713,6 +743,8 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
return (my_errno ? my_errno : -1);
file->s->chst_invalidator= query_cache_invalidate_by_MyISAM_filename_ref;
+ /* Set external_ref, mainly for temporary tables */
+ file->external_ref= (void*) table; // For mi_killed()
if (!table->s->tmp_table) /* No need to perform a check for tmp table */
{
@@ -759,6 +791,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;
@@ -784,6 +826,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);
}
@@ -1614,7 +1658,15 @@ void ha_myisam::start_bulk_insert(ha_rows rows)
*/
if (file->state->records == 0 && can_enable_indexes &&
(!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
- mi_disable_non_unique_index(file,rows);
+ {
+ if (file->open_flag & HA_OPEN_INTERNAL_TABLE)
+ {
+ file->update|= HA_STATE_CHANGED;
+ mi_clear_all_keys_active(file->s->state.key_map);
+ }
+ else
+ mi_disable_non_unique_index(file,rows);
+ }
else
if (!file->bulk_insert &&
(!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
@@ -1734,6 +1786,32 @@ int ha_myisam::delete_row(const uchar *buf)
return mi_delete(file,buf);
}
+
+int ha_myisam::index_init(uint idx, bool sorted)
+{
+ active_index=idx;
+ if (pushed_idx_cond_keyno == idx)
+ mi_set_index_cond_func(file, handler_index_cond_check, 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)
@@ -1745,7 +1823,14 @@ int ha_myisam::index_read_idx_map(uchar *buf, uint index, const uchar *key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
- return mi_rkey(file, buf, index, key, keypart_map, find_flag);
+ int res;
+ /* Use the pushed index condition if it matches the index we're scanning */
+ end_range= NULL;
+ if (index == pushed_idx_cond_keyno)
+ mi_set_index_cond_func(file, handler_index_cond_check, this);
+ res= mi_rkey(file, buf, index, key, keypart_map, find_flag);
+ mi_set_index_cond_func(file, NULL, 0);
+ return res;
}
int ha_myisam::index_next(uchar *buf)
@@ -1822,6 +1907,9 @@ int ha_myisam::info(uint flag)
MI_ISAMINFO misam_info;
char name_buff[FN_REFLEN];
+ if (!table)
+ return 1;
+
(void) mi_status(file,&misam_info,flag);
if (flag & HA_STATUS_VARIABLE)
{
@@ -1839,6 +1927,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 */
@@ -1894,8 +1992,11 @@ int ha_myisam::extra(enum ha_extra_function operation)
return mi_extra(file, operation, 0);
}
+
int ha_myisam::reset(void)
{
+ mi_set_index_cond_func(file, NULL, 0);
+ ds_mrr.dsmrr_close();
return mi_reset(file);
}
@@ -1924,9 +2025,17 @@ int ha_myisam::delete_table(const char *name)
return mi_delete_table(name);
}
+void ha_myisam::change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
+{
+ handler::change_table_ptr(table_arg, share);
+ if (file)
+ file->external_ref= table_arg;
+}
+
int ha_myisam::external_lock(THD *thd, int lock_type)
{
+ file->external_ref= (void*) table; // For mi_killed()
return mi_lock_database(file, !table->s->tmp_table ?
lock_type : ((lock_type == F_UNLCK) ?
F_UNLCK : F_EXTRA_LCK));
@@ -2175,9 +2284,73 @@ static int myisam_init(void *p)
myisam_hton->create= myisam_create_handler;
myisam_hton->panic= myisam_panic;
myisam_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
+ mi_killed= mi_killed_in_mariadb;
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(range_id_t *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);
+}
+
+
+int ha_myisam::multi_range_read_explain_info(uint mrr_mode, char *str,
+ size_t size)
+{
+ return ds_mrr.dsmrr_explain_info(mrr_mode, str, size);
+}
+
+/* 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, handler_index_cond_check, 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 99d0a1b3369..10a9a920b94 100644
--- a/storage/myisam/ha_myisam.h
+++ b/storage/myisam/ha_myisam.h
@@ -36,6 +36,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;
@@ -52,17 +56,16 @@ 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; }
- 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);
- }
+ int index_init(uint idx, bool sorted);
+ int index_end();
+ int rnd_end();
+
+ ulong index_flags(uint inx, uint part, bool all_parts) const;
uint max_supported_keys() const { return MI_MAX_KEY; }
uint max_supported_key_length() const { return HA_MAX_KEY_LENGTH; }
uint max_supported_key_part_length() const { return HA_MAX_KEY_LENGTH; }
uint checksum() const;
-
+ void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
int open(const char *name, int mode, uint test_if_locked);
int close(void);
int write_row(uchar * buf);
@@ -153,4 +156,25 @@ 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(range_id_t *range_info);
+ ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
+ void *seq_init_param,
+ uint n_ranges, uint *bufsz,
+ uint *flags, COST_VECT *cost);
+ ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
+ uint *flags, COST_VECT *cost);
+ int multi_range_read_explain_info(uint mrr_mode, char *str, size_t size);
+
+ /* 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_check.c b/storage/myisam/mi_check.c
index 16e44c32620..ff142efffa9 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -981,9 +981,6 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend)
if (killed_ptr(param))
goto err2;
switch (info->s->data_file_type) {
- case BLOCK_RECORD:
- DBUG_ASSERT(0); /* Impossible */
- break;
case STATIC_RECORD:
if (my_b_read(&param->read_cache,(uchar*) record,
info->s->base.pack_reclength))
@@ -1201,6 +1198,9 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend)
link_used+= (block_info.filepos - start_recpos);
used+= (pos-start_recpos);
break;
+ default:
+ DBUG_ASSERT(0); /* Impossible */
+ break;
} /* switch */
if (! got_error)
{
@@ -3266,9 +3266,6 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
}
switch (share->data_file_type) {
- case BLOCK_RECORD:
- DBUG_ASSERT(0); /* Impossible */
- break;
case STATIC_RECORD:
for (;;)
{
@@ -3669,6 +3666,9 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
record));
DBUG_RETURN(0);
}
+ default:
+ DBUG_ASSERT(0); /* Impossible */
+ break;
}
DBUG_ASSERT(0); /* Impossible */
DBUG_RETURN(1); /* Impossible */
@@ -3706,9 +3706,6 @@ int sort_write_record(MI_SORT_PARAM *sort_param)
if (sort_param->fix_datafile)
{
switch (sort_info->new_data_file_type) {
- case BLOCK_RECORD:
- DBUG_ASSERT(0); /* Impossible */
- break;
case STATIC_RECORD:
if (my_b_write(&info->rec_cache,sort_param->record,
share->base.pack_reclength))
@@ -3782,6 +3779,9 @@ int sort_write_record(MI_SORT_PARAM *sort_param)
sort_param->filepos+=reclength+length;
info->s->state.split++;
break;
+ default:
+ DBUG_ASSERT(0); /* Impossible */
+ break;
}
}
if (sort_param->master)
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index 21b683d0d4d..919f0f3e040 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -643,7 +643,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
NOTE: The filename is compared against unique_file_name of every
open table. Hence we need a real path here.
*/
- if (test_if_reopen(filename))
+ if (test_if_reopen(filename, 1))
{
my_printf_error(0, "MyISAM table '%s' is in use "
"(most likely by a MERGE table). Try FLUSH TABLES.",
diff --git a/storage/myisam/mi_dbug.c b/storage/myisam/mi_dbug.c
index c942d17218d..559fa8710a0 100644
--- a/storage/myisam/mi_dbug.c
+++ b/storage/myisam/mi_dbug.c
@@ -176,20 +176,23 @@ my_bool check_table_is_closed(const char *name, const char *where)
DBUG_ENTER("check_table_is_closed");
(void) fn_format(filename,name,"",MI_NAME_IEXT,4+16+32);
+ pthread_mutex_lock(&THR_LOCK_myisam);
for (pos=myisam_open_list ; pos ; pos=pos->next)
{
MI_INFO *info=(MI_INFO*) pos->data;
MYISAM_SHARE *share=info->s;
if (!strcmp(share->unique_file_name,filename))
{
- if (share->last_version)
+ if (share->last_version > 1)
{
fprintf(stderr,"Warning: Table: %s is open on %s\n", name,where);
DBUG_PRINT("warning",("Table: %s is open on %s", name,where));
+ pthread_mutex_unlock(&THR_LOCK_myisam);
DBUG_RETURN(1);
}
}
}
+ pthread_mutex_unlock(&THR_LOCK_myisam);
DBUG_RETURN(0);
}
#endif /* EXTRA_DEBUG */
diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c
index d6dddeb9ed7..c693d1072ee 100644
--- a/storage/myisam/mi_extra.c
+++ b/storage/myisam/mi_extra.c
@@ -412,6 +412,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.
@@ -469,3 +475,8 @@ int mi_reset(MI_INFO *info)
HA_STATE_PREV_FOUND);
DBUG_RETURN(error);
}
+
+my_bool mi_killed_standalone(MI_INFO *info __attribute__((unused)))
+{
+ return 0;
+}
diff --git a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c
index 94f3f34ec58..a3d38269e61 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,45 @@ 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.
+*/
+
+ICP_RESULT mi_check_index_cond(register MI_INFO *info, uint keynr,
+ uchar *record)
+{
+ ICP_RESULT res;
+ if (_mi_put_key_in_record(info, keynr, FALSE, record))
+ {
+ /* Impossible case; Can only happen if bug in code */
+ mi_print_error(info->s, HA_ERR_CRASHED);
+ info->lastpos= HA_OFFSET_ERROR; /* No active record */
+ my_errno= HA_ERR_CRASHED;
+ res= ICP_ERROR;
+ }
+ else if ((res= info->index_cond_func(info->index_cond_func_arg)) ==
+ ICP_OUT_OF_RANGE)
+ {
+ /* We got beyond the end of scanned range */
+ info->lastpos= HA_OFFSET_ERROR; /* No active record */
+ my_errno= HA_ERR_END_OF_FILE;
+ }
+ return res;
+}
+
+/*
Retrieve auto_increment info
SYNOPSIS
diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c
index 06eed31847b..569617709fb 100644
--- a/storage/myisam/mi_locking.c
+++ b/storage/myisam/mi_locking.c
@@ -241,7 +241,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
break; /* Impossible */
}
}
-#ifdef __WIN__
+#ifdef _WIN32
else
{
/*
@@ -523,11 +523,11 @@ int _mi_writeinfo(register MI_INFO *info, uint operation)
share->state.update_count= info->last_loop= ++info->this_loop;
if ((error=mi_state_info_write(share->kfile, &share->state, 1)))
olderror=my_errno;
-#ifdef __WIN__
+#ifdef _WIN32
if (myisam_flush)
{
- _commit(share->kfile);
- _commit(info->dfile);
+ my_sync(share->kfile,0);
+ my_sync(info->dfile,0);
}
#endif
}
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index d3ecdf7239a..46ec10c064e 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -52,7 +52,8 @@ if (pos > end_pos) \
** In MySQL the server will handle version issues.
******************************************************************************/
-MI_INFO *test_if_reopen(char *filename)
+MI_INFO *test_if_reopen(char *filename,
+ my_bool ignore_last_version __attribute__((unused)))
{
LIST *pos;
@@ -61,8 +62,8 @@ MI_INFO *test_if_reopen(char *filename)
MI_INFO *info=(MI_INFO*) pos->data;
MYISAM_SHARE *share=info->s;
DBUG_ASSERT(strcmp(share->unique_file_name,filename) ||
- share->last_version);
- if (!strcmp(share->unique_file_name,filename) && share->last_version)
+ share->last_version > 1 || ignore_last_version);
+ if (!strcmp(share->unique_file_name,filename) && share->last_version > 1)
return info;
}
return 0;
@@ -81,14 +82,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");
@@ -109,13 +110,11 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
}
pthread_mutex_lock(&THR_LOCK_myisam);
- if (!(old_info=test_if_reopen(name_buff)))
+ if (!(old_info=test_if_reopen(name_buff,
+ test(open_flags & HA_OPEN_FOR_STATUS))))
{
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);
@@ -205,7 +204,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)
{
@@ -215,7 +214,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)
{
@@ -298,7 +302,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,
@@ -322,7 +327,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,
@@ -508,7 +513,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share->base.key_parts=key_parts;
share->base.all_key_parts=key_parts+unique_key_parts;
if (!(share->last_version=share->state.version))
- share->last_version=1; /* Safety */
+ share->last_version= 2; /* Safety */
+ if (open_flags & HA_OPEN_FOR_STATUS)
+ {
+ share->last_version= 1; /* Not reusable version */
+ share->options|= HA_OPTION_READ_ONLY_DATA;
+ }
share->rec_reflength=share->base.rec_reflength; /* May be changed */
share->base.margin_key_file_length=(share->base.max_key_file_length -
(keys ? MI_INDEX_BLOCK_MARGIN *
@@ -668,6 +678,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)
{
@@ -697,6 +708,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);
@@ -984,6 +996,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..d2af9a3e5ed 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));
@@ -87,6 +88,7 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key,
my_errno=HA_ERR_CRASHED;
if (share->concurrent_insert)
rw_unlock(&share->key_root_lock[inx]);
+ fast_mi_writeinfo(info);
goto err;
}
break;
@@ -105,80 +107,117 @@ 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]))
+ {
+ info->lastpos= HA_OFFSET_ERROR;
+ 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 we are at the last key on the key page, allow writers to
+ access the index.
+ */
+ if (info->int_keypos >= info->int_maxpos &&
+ mi_yield_and_check_if_killed(info, inx))
{
- /*
- 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);
+ /* Aborted by user */
+ DBUG_ASSERT(info->lastpos == HA_OFFSET_ERROR &&
+ my_errno == HA_ERR_ABORTED_BY_USER);
+ res= ICP_ERROR;
+ buf= 0; /* Fast abort */
+ break;
}
}
+ if (res == ICP_OUT_OF_RANGE)
+ {
+ /* Change error from HA_ERR_END_OF_FILE */
+ DBUG_ASSERT(info->lastpos == HA_OFFSET_ERROR);
+ 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;
+ }
+ }
+ else
+ {
+ DBUG_ASSERT(info->lastpos == HA_OFFSET_ERROR);
}
}
if (share->concurrent_insert)
rw_unlock(&share->key_root_lock[inx]);
- /* Calculate length of the found key; Used by mi_rnext_same */
- if ((keyinfo->flag & HA_VAR_LENGTH_KEY) && last_used_keyseg &&
- info->lastpos != HA_OFFSET_ERROR)
- info->last_rkey_length= _mi_keylength_part(keyinfo, info->lastkey,
- last_used_keyseg);
- else
- info->last_rkey_length= pack_key_length;
-
- /* Check if we don't want to have record back, only error message */
- if (!buf)
- DBUG_RETURN(info->lastpos == HA_OFFSET_ERROR ? my_errno : 0);
+ info->last_rkey_length= pack_key_length;
- if (!(*info->read_record)(info,info->lastpos,buf))
+ if (info->lastpos == HA_OFFSET_ERROR) /* No such record */
{
- info->update|= HA_STATE_AKTIV; /* Record is read */
- DBUG_RETURN(0);
+ fast_mi_writeinfo(info);
+ if (!buf)
+ DBUG_RETURN(my_errno);
}
+ else
+ {
+ /* Calculate length of the found key; Used by mi_rnext_same */
+ if ((keyinfo->flag & HA_VAR_LENGTH_KEY) && last_used_keyseg)
+ info->last_rkey_length= _mi_keylength_part(keyinfo, info->lastkey,
+ last_used_keyseg);
- info->lastpos = HA_OFFSET_ERROR; /* Didn't find key */
+ /* Check if we don't want to have record back, only error message */
+ if (!buf)
+ {
+ fast_mi_writeinfo(info);
+ DBUG_RETURN(0);
+ }
+ if (!(*info->read_record)(info,info->lastpos,buf))
+ {
+ info->update|= HA_STATE_AKTIV; /* Record is read */
+ DBUG_RETURN(0);
+ }
+ DBUG_PRINT("error", ("Didn't find row. Error %d", my_errno));
+ info->lastpos= HA_OFFSET_ERROR; /* Didn't find row */
+ }
/* Store last used key as a base for read next */
memcpy(info->lastkey,key_buff,pack_key_length);
@@ -191,3 +230,36 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key,
err:
DBUG_RETURN(my_errno);
} /* _mi_rkey */
+
+
+/*
+ Yield to possible other writers during a index scan.
+ Check also if we got killed by the user and if yes, return
+ HA_ERR_LOCK_WAIT_TIMEOUT
+
+ return 0 ok
+ return 1 Query has been requested to be killed
+*/
+
+my_bool mi_yield_and_check_if_killed(MI_INFO *info, int inx)
+{
+ MYISAM_SHARE *share;
+ if (mi_killed(info))
+ {
+ /* purecov: begin tested */
+ info->lastpos= HA_OFFSET_ERROR;
+ /* Set error that we where aborted by kill from application */
+ my_errno= HA_ERR_ABORTED_BY_USER;
+ return 1;
+ /* purecov: end */
+
+ }
+
+ if ((share= info->s)->concurrent_insert)
+ {
+ /* Give writers a chance to access index */
+ rw_unlock(&share->key_root_lock[inx]);
+ rw_rdlock(&share->key_root_lock[inx]);
+ }
+ return 0;
+}
diff --git a/storage/myisam/mi_rnext.c b/storage/myisam/mi_rnext.c
index 6c23bee92ee..916a5d6d902 100644
--- a/storage/myisam/mi_rnext.c
+++ b/storage/myisam/mi_rnext.c
@@ -30,6 +30,7 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx)
{
int error,changed;
uint flag;
+ ICP_RESULT icp_res= ICP_MATCH;
uint update_mask= HA_STATE_NEXT_FOUND;
DBUG_ENTER("mi_rnext");
@@ -98,34 +99,53 @@ 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 &&
+ (icp_res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH))
{
- while (info->lastpos >= info->state->data_file_length)
+ /*
+ If we are at the last key on the key page, allow writers to
+ access the index.
+ */
+ if (info->int_keypos >= info->int_maxpos &&
+ mi_yield_and_check_if_killed(info, inx))
{
- /* 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;
+ error= 1;
+ 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;
}
- 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;
- if (error)
+ if (error || icp_res != ICP_MATCH)
{
+ fast_mi_writeinfo(info);
if (my_errno == HA_ERR_KEY_NOT_FOUND)
my_errno=HA_ERR_END_OF_FILE;
}
else if (!buf)
{
+ fast_mi_writeinfo(info);
DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0);
}
else if (!(*info->read_record)(info,info->lastpos,buf))
diff --git a/storage/myisam/mi_rnext_same.c b/storage/myisam/mi_rnext_same.c
index 1892fe3e1e0..3aa7e93dfd5 100644
--- a/storage/myisam/mi_rnext_same.c
+++ b/storage/myisam/mi_rnext_same.c
@@ -29,6 +29,7 @@ int mi_rnext_same(MI_INFO *info, uchar *buf)
int error;
uint inx,not_used[2];
MI_KEYDEF *keyinfo;
+ ICP_RESULT icp_res= ICP_MATCH;
DBUG_ENTER("mi_rnext_same");
if ((int) (inx=info->lastinx) < 0 || info->lastpos == HA_OFFSET_ERROR)
@@ -63,6 +64,17 @@ int mi_rnext_same(MI_INFO *info, uchar *buf)
}
for (;;)
{
+ /*
+ If we are at the last key on the key page, allow writers to
+ access the index.
+ */
+ if (info->int_keypos >= info->int_maxpos &&
+ mi_yield_and_check_if_killed(info, inx))
+ {
+ error=1;
+ break;
+ }
+
if ((error=_mi_search_next(info,keyinfo,info->lastkey,
info->lastkey_length,SEARCH_BIGGER,
info->s->state.key_root[inx])))
@@ -75,24 +87,33 @@ 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 ||
+ (icp_res= mi_check_index_cond(info, inx, buf)) != ICP_NO_MATCH))
break;
}
}
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|= HA_STATE_NEXT_FOUND | HA_STATE_RNEXT_SAME;
- if (error)
+ if (error || icp_res != ICP_MATCH)
{
+ fast_mi_writeinfo(info);
if (my_errno == HA_ERR_KEY_NOT_FOUND)
my_errno=HA_ERR_END_OF_FILE;
}
else if (!buf)
{
+ fast_mi_writeinfo(info);
DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0);
}
else if (!(*info->read_record)(info,info->lastpos,buf))
diff --git a/storage/myisam/mi_rprev.c b/storage/myisam/mi_rprev.c
index d1407012590..040b08b428c 100644
--- a/storage/myisam/mi_rprev.c
+++ b/storage/myisam/mi_rprev.c
@@ -27,6 +27,7 @@ int mi_rprev(MI_INFO *info, uchar *buf, int inx)
int error,changed;
register uint flag;
MYISAM_SHARE *share=info->s;
+ ICP_RESULT icp_res= ICP_MATCH;
DBUG_ENTER("mi_rprev");
if ((inx = _mi_check_index(info,inx)) < 0)
@@ -51,31 +52,55 @@ 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)
+ my_off_t cur_keypage= info->last_keypage;
+ while ((share->concurrent_insert &&
+ info->lastpos >= info->state->data_file_length) ||
+ (info->index_cond_func &&
+ (icp_res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH))
{
- while (info->lastpos >= info->state->data_file_length)
+ /*
+ If we are at the last (i.e. first?) key on the key page,
+ allow writers to access the index.
+ */
+ if (info->last_keypage != cur_keypage)
{
- /* 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;
+ cur_keypage= info->last_keypage;
+ if (mi_yield_and_check_if_killed(info, inx))
+ {
+ error= 1;
+ 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;
}
- 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)
+
+ if (error || icp_res != ICP_MATCH)
{
+ fast_mi_writeinfo(info);
if (my_errno == HA_ERR_KEY_NOT_FOUND)
my_errno=HA_ERR_END_OF_FILE;
}
else if (!buf)
{
+ fast_mi_writeinfo(info);
DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0);
}
else if (!(*info->read_record)(info,info->lastpos,buf))
diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c
index 153064cb360..b62fbd7aa00 100644
--- a/storage/myisam/mi_search.c
+++ b/storage/myisam/mi_search.c
@@ -91,7 +91,10 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
&keypos,lastkey, &last_key);
if (flag == MI_FOUND_WRONG_KEY)
- DBUG_RETURN(-1);
+ {
+ my_errno= HA_ERR_CRASHED;
+ goto err;
+ }
nod_flag=mi_test_if_nod(buff);
maxpos=buff+mi_getint(buff)-1;
diff --git a/storage/myisam/mi_static.c b/storage/myisam/mi_static.c
index 67588791886..180d5e6c6d2 100644
--- a/storage/myisam/mi_static.c
+++ b/storage/myisam/mi_static.c
@@ -44,6 +44,7 @@ my_off_t myisam_max_temp_length= MAX_FILE_SIZE;
ulong myisam_bulk_insert_tree_size=8192*1024;
ulong myisam_data_pointer_size=4;
ulonglong myisam_mmap_size= SIZE_T_MAX, myisam_mmap_used= 0;
+my_bool (*mi_killed)(MI_INFO *)= mi_killed_standalone;
static int always_valid(const char *filename __attribute__((unused)))
{
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 84d133566f9..58d69afbea8 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -27,6 +27,10 @@
#include <my_no_pthread.h>
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#if defined(my_write) && !defined(MAP_TO_USE_RAID)
/* undef map from my_nosys; We need test-if-disk full */
#undef my_write
@@ -237,6 +241,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
{
@@ -249,6 +254,7 @@ struct st_myisam_info
DYNAMIC_ARRAY *ft1_to_ft2; /* used only in ft1->ft2 conversion */
MEM_ROOT ft_memroot; /* used by the parser */
MYSQL_FTPARSER_PARAM *ftparser_param; /* share info between init/deinit */
+ void *external_ref; /* For MariaDB TABLE */
char *filename; /* parameter to open filename */
uchar *buff, /* Temp area for key */
*lastkey, *lastkey2; /* Last used search key */
@@ -306,6 +312,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
@@ -432,6 +440,7 @@ extern uint NEAR myisam_read_vec[], NEAR myisam_readnext_vec[];
extern uint myisam_quick_table_bits;
extern File myisam_log_file;
extern ulong myisam_pid;
+extern my_bool (*mi_killed)(MI_INFO *);
/* This is used by _mi_calc_xxx_key_length och _mi_store_key */
@@ -592,6 +601,8 @@ extern ulonglong mi_safe_mul(ulonglong a, ulonglong b);
extern int _mi_ft_update(MI_INFO *info, uint keynr, uchar *keybuf,
const uchar *oldrec, const uchar *newrec,
my_off_t pos);
+extern my_bool mi_yield_and_check_if_killed(MI_INFO *info, int inx);
+extern my_bool mi_killed_standalone(MI_INFO *);
struct st_sort_info;
@@ -650,9 +661,7 @@ enum myisam_log_commands
#define fast_mi_writeinfo(INFO) if (!(INFO)->s->tot_locks) (void) _mi_writeinfo((INFO),0)
#define fast_mi_readinfo(INFO) ((INFO)->lock_type == F_UNLCK) && _mi_readinfo((INFO),F_RDLCK,1)
-#ifdef __cplusplus
-extern "C" {
-#endif
+
extern uint _mi_get_block_info(MI_BLOCK_INFO *, File, my_off_t);
extern uint _mi_rec_pack(MI_INFO *info, uchar *to, const uchar *from);
extern uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
@@ -717,7 +726,7 @@ my_bool mi_check_status(void *param);
void mi_fix_status(MI_INFO *org_table, MI_INFO *new_table);
void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
-extern MI_INFO *test_if_reopen(char *filename);
+extern MI_INFO *test_if_reopen(char *filename, my_bool ignore_last_version);
my_bool check_table_is_closed(const char *name, const char *where);
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *orn_name,
File file_to_dup);
@@ -728,6 +737,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);
+ICP_RESULT 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, ...));
@@ -736,6 +746,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 eaf78b38c02..44d0e62bee1 100644
--- a/storage/myisam/myisampack.c
+++ b/storage/myisam/myisampack.c
@@ -577,7 +577,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;
/*
@@ -1512,7 +1512,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;
}
@@ -1616,8 +1616,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;
@@ -1628,12 +1627,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. */
@@ -1655,8 +1651,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;
@@ -1787,8 +1783,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++)
@@ -1802,12 +1797,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. */
@@ -1827,8 +1819,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/rt_index.c b/storage/myisam/rt_index.c
index 6a825bab1fa..6053d704d98 100644
--- a/storage/myisam/rt_index.c
+++ b/storage/myisam/rt_index.c
@@ -175,6 +175,13 @@ int rtree_find_first(MI_INFO *info, uint keynr, uchar *key, uint key_length,
uint nod_cmp_flag;
MI_KEYDEF *keyinfo = info->s->keyinfo + keynr;
+ /*
+ At the moment index can only properly handle the
+ MBR_INTERSECT, so we use it for all sorts of queries.
+ TODO: better searsh for CONTAINS/WITHIN.
+ */
+ search_flag= nod_cmp_flag= MBR_INTERSECT;
+
if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
{
my_errno= HA_ERR_END_OF_FILE;
@@ -192,8 +199,11 @@ int rtree_find_first(MI_INFO *info, uint keynr, uchar *key, uint key_length,
info->rtree_recursion_depth = -1;
info->buff_used = 1;
- nod_cmp_flag = ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
- MBR_WITHIN : MBR_INTERSECT);
+ /*
+ TODO better search for CONTAINS/WITHIN.
+ nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
+ MBR_WITHIN : MBR_INTERSECT);
+ */
return rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root, 0);
}
@@ -218,6 +228,12 @@ int rtree_find_next(MI_INFO *info, uint keynr, uint search_flag)
my_off_t root;
uint nod_cmp_flag;
MI_KEYDEF *keyinfo = info->s->keyinfo + keynr;
+ /*
+ At the moment index can only properly handle the
+ MBR_INTERSECT, so we use it for all sorts of queries.
+ TODO: better searsh for CONTAINS/WITHIN.
+ */
+ search_flag= nod_cmp_flag= MBR_INTERSECT;
if (info->update & HA_STATE_DELETED)
return rtree_find_first(info, keynr, info->lastkey, info->lastkey_length,
@@ -252,8 +268,11 @@ int rtree_find_next(MI_INFO *info, uint keynr, uint search_flag)
return -1;
}
- nod_cmp_flag = ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
- MBR_WITHIN : MBR_INTERSECT);
+ /*
+ TODO better search for CONTAINS/WITHIN.
+ nod_cmp_flag= (((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
+ MBR_WITHIN : MBR_INTERSECT));
+ */
return rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root, 0);
}
@@ -1028,7 +1047,7 @@ ha_rows rtree_estimate(MI_INFO *info, uint keynr, uchar *key,
ha_rows res = 0;
if (flag & MBR_DISJOINT)
- return info->state->records;
+ return HA_POS_ERROR;
if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
return HA_POS_ERROR;
diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c
index b67f77654ad..4c370ecc01a 100644
--- a/storage/myisam/sort.c
+++ b/storage/myisam/sort.c
@@ -924,7 +924,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++)
@@ -973,7 +973,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);
@@ -998,7 +998,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/Makefile.am b/storage/oqgraph/Makefile.am
index e99e134db02..052c0e9a773 100644
--- a/storage/oqgraph/Makefile.am
+++ b/storage/oqgraph/Makefile.am
@@ -38,7 +38,7 @@ BOOST_CXXFLAGS = -frtti -fexceptions -fimplicit-templates
# it also makes an extra register available in many functions.
# It also makes debugging impossible on some machines.
# (automatically gets enabled anyway by -O* on some architectures)
-BOOST_CXXFLAGS+= -O3 -fstrict-aliasing
+BOOST_CXXFLAGS+= -O3 -fno-strict-aliasing
BOOST_CXXFLAGS+= -falign-loops
if HAVE_FVISIBILITY_INLINES_HIDDEN
BOOST_CXXFLAGS+= -fvisibility-inlines-hidden
diff --git a/storage/pbxt/src/filesys_xt.cc b/storage/pbxt/src/filesys_xt.cc
index 31e2cf961b6..ebe0ed146b0 100644
--- a/storage/pbxt/src/filesys_xt.cc
+++ b/storage/pbxt/src/filesys_xt.cc
@@ -369,8 +369,7 @@ xtPublic xtBool xt_fs_stat(XTThreadPtr self, char *path, off_t *size, struct tim
CloseHandle(fh);
if (size)
*size = (off_t) info.nFileSizeLow | (((off_t) info.nFileSizeHigh) << 32);
- if (mod_time)
- mod_time->tv.ft = info.ftLastWriteTime;
+ memset(mod_time, 0, sizeof(*mod_time));
#else
struct stat sb;
diff --git a/storage/pbxt/src/ha_pbxt.cc b/storage/pbxt/src/ha_pbxt.cc
index 584d188a2cd..e551843a7b8 100644
--- a/storage/pbxt/src/ha_pbxt.cc
+++ b/storage/pbxt/src/ha_pbxt.cc
@@ -108,6 +108,9 @@ static int pbxt_end(void *p);
static int pbxt_panic(handlerton *hton, enum ha_panic_function flag);
static void pbxt_drop_database(handlerton *hton, char *path);
static int pbxt_close_connection(handlerton *hton, THD* thd);
+#ifdef MARIADB_BASE_VERSION
+static void pbxt_commit_ordered(handlerton *hton, THD *thd, bool all);
+#endif
static int pbxt_commit(handlerton *hton, THD *thd, bool all);
static int pbxt_rollback(handlerton *hton, THD *thd, bool all);
static int pbxt_prepare(handlerton *hton, THD *thd, bool all);
@@ -1147,6 +1150,9 @@ static int pbxt_init(void *p)
pbxt_hton->state = SHOW_OPTION_YES;
pbxt_hton->db_type = DB_TYPE_PBXT; // Wow! I have my own!
pbxt_hton->close_connection = pbxt_close_connection; /* close_connection, cleanup thread related data. */
+#ifdef MARIADB_BASE_VERSION
+ pbxt_hton->commit_ordered = pbxt_commit_ordered;
+#endif
pbxt_hton->commit = pbxt_commit; /* commit */
pbxt_hton->rollback = pbxt_rollback; /* rollback */
if (pbxt_support_xa) {
@@ -1484,6 +1490,29 @@ static int pbxt_start_consistent_snapshot(handlerton *hton, THD *thd)
return err;
}
+#ifdef MARIADB_BASE_VERSION
+/*
+ * Quickly commit the transaction to memory and make it visible to others.
+ * The remaining part of commit will happen later, in pbxt_commit().
+ */
+static void pbxt_commit_ordered(handlerton *hton, THD *thd, bool all)
+{
+ XTThreadPtr self;
+
+ if ((self = (XTThreadPtr) *thd_ha_data(thd, hton))) {
+ XT_PRINT2(self, "%s pbxt_commit_ordered all=%d\n", all ? "END CONN XACT" : "END STAT", all);
+
+ if (self->st_xact_data) {
+ if (all || self->st_auto_commit) {
+ self->st_commit_ordered = TRUE;
+ self->st_writer = self->st_xact_writer;
+ self->st_delayed_error= !xt_xn_commit_fast(self, self->st_writer);
+ }
+ }
+ }
+}
+#endif
+
/*
* Commit the PBXT transaction of the given thread.
* thd is the MySQL thread structure.
@@ -1512,7 +1541,13 @@ static int pbxt_commit(handlerton *hton, THD *thd, bool all)
if (all || self->st_auto_commit) {
XT_PRINT0(self, "xt_xn_commit in pbxt_commit\n");
- if (!xt_xn_commit(self))
+ if (self->st_commit_ordered) {
+ self->st_commit_ordered = FALSE;
+ err = !xt_xn_commit_slow(self, self->st_writer) || self->st_delayed_error;
+ } else {
+ err = !xt_xn_commit(self);
+ }
+ if (err)
err = xt_ha_pbxt_thread_error_for_mysql(thd, self, FALSE);
}
}
@@ -6062,7 +6097,7 @@ static MYSQL_SYSVAR_INT(max_threads, pbxt_max_threads,
NULL, NULL, 0, 0, 20000, 1);
#endif
-#ifndef DEBUG
+#if !defined(DEBUG) || defined(MARIADB_BASE_VERSION)
static MYSQL_SYSVAR_BOOL(support_xa, pbxt_support_xa,
PLUGIN_VAR_OPCMDARG,
"Enable PBXT support for the XA two-phase commit, default is enabled",
diff --git a/storage/pbxt/src/pthread_xt.cc b/storage/pbxt/src/pthread_xt.cc
index 64c03db734c..d704e977c21 100755
--- a/storage/pbxt/src/pthread_xt.cc
+++ b/storage/pbxt/src/pthread_xt.cc
@@ -396,48 +396,7 @@ xtPublic int xt_p_cond_wait(xt_cond_type *cond, xt_mutex_type *mutex)
xtPublic int xt_p_cond_timedwait(xt_cond_type *cond, xt_mutex_type *mt, struct timespec *abstime)
{
- pthread_mutex_t *mutex = &mt->mt_cs;
- int result;
- long timeout;
- union ft64 now;
-
- if (abstime != NULL) {
- GetSystemTimeAsFileTime(&now.ft);
-
- timeout = (long)((abstime->tv.i64 - now.i64) / 10000);
- if (timeout < 0)
- timeout = 0L;
- if (timeout > abstime->max_timeout_msec)
- timeout = abstime->max_timeout_msec;
- }
- else
- timeout= INFINITE;
-
- WaitForSingleObject(cond->broadcast_block_event, INFINITE);
-
- EnterCriticalSection(&cond->lock_waiting);
- cond->waiting++;
- LeaveCriticalSection(&cond->lock_waiting);
-
- LeaveCriticalSection(mutex);
-
- result= WaitForMultipleObjects(2, cond->events, FALSE, timeout);
-
- EnterCriticalSection(&cond->lock_waiting);
- cond->waiting--;
-
- if (cond->waiting == 0) {
- /* The last waiter must reset the broadcast
- * state (whther there was a broadcast or not)!
- */
- ResetEvent(cond->events[xt_cond_type::BROADCAST]);
- SetEvent(cond->broadcast_block_event);
- }
- LeaveCriticalSection(&cond->lock_waiting);
-
- EnterCriticalSection(mutex);
-
- return result == WAIT_TIMEOUT ? ETIMEDOUT : 0;
+ return pthread_cond_timedwait(cond, &mt->mt_cs, abstime);
}
xtPublic int xt_p_join(pthread_t thread, void **value)
diff --git a/storage/pbxt/src/thread_xt.cc b/storage/pbxt/src/thread_xt.cc
index 72bfab0921c..2ba287c1848 100644
--- a/storage/pbxt/src/thread_xt.cc
+++ b/storage/pbxt/src/thread_xt.cc
@@ -54,6 +54,9 @@ void xt_db_exit_thread(XTThreadPtr self);
static void thr_accumulate_statistics(XTThreadPtr self);
+#ifdef _WIN32
+#include <my_sys.h>
+#endif
/*
* -----------------------------------------------------------------------
* THREAD GLOBALS
@@ -485,8 +488,8 @@ static void thr_free_resources(XTThreadPtr self, XTResourcePtr top)
xtPublic void xt_bug(XTThreadPtr XT_UNUSED(self))
{
- static int *bug_ptr __attribute__ ((unused))= NULL;
-
+ static int *bug_ptr __attribute__ ((unused));
+
bug_ptr = NULL;
}
@@ -1962,18 +1965,7 @@ xtPublic xtBool xt_timed_wait_cond(XTThreadPtr self, xt_cond_type *cond, xt_mute
XTThreadPtr me = self ? self : xt_get_self();
#ifdef XT_WIN
- union ft64 now;
-
- GetSystemTimeAsFileTime(&now.ft);
-
- /* System time is measured in 100ns units.
- * This calculation will be reversed by the Windows implementation
- * of pthread_cond_timedwait(), in order to extract the
- * milli-second timeout!
- */
- abstime.tv.i64 = now.i64 + (milli_sec * 10000);
-
- abstime.max_timeout_msec = milli_sec;
+ set_timespec_nsec(abstime, 1000000ULL* milli_sec);
#else
struct timeval now;
u_llong micro_sec;
diff --git a/storage/pbxt/src/thread_xt.h b/storage/pbxt/src/thread_xt.h
index a07f7b7ae01..282df46a5d5 100644
--- a/storage/pbxt/src/thread_xt.h
+++ b/storage/pbxt/src/thread_xt.h
@@ -299,6 +299,9 @@ typedef struct XTThread {
xtBool st_stat_ended; /* TRUE if the statement was ended. */
xtBool st_stat_trans; /* TRUE if a statement transaction is running (started on UPDATE). */
xtBool st_stat_modify; /* TRUE if the statement is an INSERT/UPDATE/DELETE */
+ xtBool st_commit_ordered; /* TRUE if we have run commit_ordered() */
+ xtBool st_delayed_error; /* TRUE if we got an error in commit_ordered() */
+ xtBool st_writer; /* Copy of thread->st_xact_writer (which is clobbered by xlog_append()) */
#ifdef XT_IMPLEMENT_NO_ACTION
XTBasicListRec st_restrict_list; /* These records have been deleted and should have no reference. */
#endif
diff --git a/storage/pbxt/src/xaction_xt.cc b/storage/pbxt/src/xaction_xt.cc
index 0d94449c3da..fd7ae88a4ae 100644
--- a/storage/pbxt/src/xaction_xt.cc
+++ b/storage/pbxt/src/xaction_xt.cc
@@ -1286,27 +1286,61 @@ xtPublic xtBool xt_xn_begin(XTThreadPtr self)
return OK;
}
-static xtBool xn_end_xact(XTThreadPtr thread, u_int status)
+static void xn_end_release_locks(XTThreadPtr thread)
+{
+ XTXactDataPtr xact = thread->st_xact_data;
+ XTDatabaseHPtr db = thread->st_database;
+ ASSERT_NS(xact);
+
+ /* {REMOVE-LOCKS} Drop locks if you have any: */
+ thread->st_lock_list.xt_remove_all_locks(db, thread);
+
+ /* Do this afterwards to make sure the sweeper
+ * does not cleanup transactions start cleaning up
+ * before any transactions that were waiting for
+ * this transaction have completed!
+ */
+ xact->xd_end_xn_id = db->db_xn_curr_id;
+
+ /* Now you can sweep! */
+ xact->xd_flags |= XT_XN_XAC_SWEEP;
+}
+
+/* The commit is split into two phases: one "fast" for MariaDB commit_ordered(),
+ * and one "slow" for commit(). When not using internal 2pc, there is only one
+ * call combining both phases.
+ */
+
+enum {
+ XN_END_PHASE_FAST = 1,
+ XN_END_PHASE_SLOW = 2,
+ XN_END_PHASE_BOTH = 3
+};
+
+static xtBool xn_end_xact(XTThreadPtr thread, u_int status, xtBool writer, int phase)
{
XTXactDataPtr xact;
xtBool ok = TRUE;
+ xtBool err;
ASSERT_NS(thread->st_xact_data);
if ((xact = thread->st_xact_data)) {
XTDatabaseHPtr db = thread->st_database;
xtXactID xn_id = xact->xd_start_xn_id;
- xtBool writer;
- if ((writer = thread->st_xact_writer)) {
+ if (writer) {
/* The transaction wrote something: */
XTXactEndEntryDRec entry;
xtWord4 sum;
- sum = XT_CHECKSUM4_XACT(xn_id) ^ XT_CHECKSUM4_XACT(0);
- entry.xe_status_1 = status;
- entry.xe_checksum_1 = XT_CHECKSUM_1(sum);
- XT_SET_DISK_4(entry.xe_xact_id_4, xn_id);
- XT_SET_DISK_4(entry.xe_not_used_4, 0);
+ if (phase & XN_END_PHASE_FAST)
+ {
+ sum = XT_CHECKSUM4_XACT(xn_id) ^ XT_CHECKSUM4_XACT(0);
+ entry.xe_status_1 = status;
+ entry.xe_checksum_1 = XT_CHECKSUM_1(sum);
+ XT_SET_DISK_4(entry.xe_xact_id_4, xn_id);
+ XT_SET_DISK_4(entry.xe_not_used_4, 0);
+ }
#ifdef XT_IMPLEMENT_NO_ACTION
/* This will check any resticts that have been delayed to the end of the statement. */
@@ -1318,20 +1352,35 @@ static xtBool xn_end_xact(XTThreadPtr thread, u_int status)
}
#endif
- /* Flush the data log: */
- if (!thread->st_dlog_buf.dlb_flush_log(TRUE, thread)) {
+ /* Flush the data log (in the "fast" case we already did it in prepare: */
+ if ((phase & XN_END_PHASE_SLOW) && !thread->st_dlog_buf.dlb_flush_log(TRUE, thread)) {
ok = FALSE;
status = XT_LOG_ENT_ABORT;
}
/* Write and flush the transaction log: */
- if (!xt_xlog_log_data(thread, sizeof(XTXactEndEntryDRec), (XTXactLogBufferDPtr) &entry, xt_db_flush_log_at_trx_commit)) {
+ if (phase == XN_END_PHASE_FAST) {
+ /* Fast phase, delay any write or flush to later. */
+ err = !xt_xlog_log_data(thread, sizeof(XTXactEndEntryDRec), (XTXactLogBufferDPtr) &entry, XT_XLOG_NO_WRITE_NO_FLUSH);
+ } else if (phase == XN_END_PHASE_SLOW) {
+ /* We already appended the commit record in the fast phase.
+ * Now just call with empty record to ensure we write/flush
+ * the log as needed for this commit.
+ */
+ err = !xt_xlog_log_data(thread, 0, NULL, xt_db_flush_log_at_trx_commit);
+ } else /* phase == XN_END_PHASE_BOTH */ {
+ /* Both phases at once, append commit record and write/flush normally. */
+ ASSERT_NS(phase == XN_END_PHASE_BOTH);
+ err = !xt_xlog_log_data(thread, sizeof(XTXactEndEntryDRec), (XTXactLogBufferDPtr) &entry, xt_db_flush_log_at_trx_commit);
+ }
+
+ if (err) {
ok = FALSE;
status = XT_LOG_ENT_ABORT;
/* Make sure this is done, if we failed to log
* the transction end!
*/
- if (thread->st_xact_writer) {
+ if (writer) {
/* Adjust this in case of error, but don't forget
* to lock!
*/
@@ -1346,46 +1395,46 @@ static xtBool xn_end_xact(XTThreadPtr thread, u_int status)
}
}
- /* Setting this flag completes the transaction,
- * Do this before we release the locks, because
- * the unlocked transactions expect the
- * transaction they are waiting for to be
- * gone!
- */
- xact->xd_end_time = ++db->db_xn_end_time;
- if (status == XT_LOG_ENT_COMMIT) {
- thread->st_statistics.st_commits++;
- xact->xd_flags |= (XT_XN_XAC_COMMITTED | XT_XN_XAC_ENDED);
- }
- else {
- thread->st_statistics.st_rollbacks++;
- xact->xd_flags |= XT_XN_XAC_ENDED;
+ if (phase & XN_END_PHASE_FAST) {
+ /* Setting this flag completes the transaction,
+ * Do this before we release the locks, because
+ * the unlocked transactions expect the
+ * transaction they are waiting for to be
+ * gone!
+ */
+ xact->xd_end_time = ++db->db_xn_end_time;
+ if (status == XT_LOG_ENT_COMMIT) {
+ thread->st_statistics.st_commits++;
+ xact->xd_flags |= (XT_XN_XAC_COMMITTED | XT_XN_XAC_ENDED);
+ }
+ else {
+ thread->st_statistics.st_rollbacks++;
+ xact->xd_flags |= XT_XN_XAC_ENDED;
+ }
}
- /* {REMOVE-LOCKS} Drop locks is you have any: */
- thread->st_lock_list.xt_remove_all_locks(db, thread);
-
- /* Do this afterwards to make sure the sweeper
- * does not cleanup transactions start cleaning up
- * before any transactions that were waiting for
- * this transaction have completed!
+ /* Be as fast as possible in the "fast" path, as we want to be as
+ * fast as possible here (we will release slow locks immediately
+ * after in the "slow" part).
+ * ToDo: If we ran the fast part, the slow part could release locks
+ * _before_ fsync(), rather than after.
*/
- xact->xd_end_xn_id = db->db_xn_curr_id;
+ if (!(phase & XN_END_PHASE_SLOW))
+ return ok;
- /* Now you can sweep! */
- xact->xd_flags |= XT_XN_XAC_SWEEP;
+ xn_end_release_locks(thread);
}
else {
/* Read-only transaction can be removed, immediately */
- xact->xd_end_time = ++db->db_xn_end_time;
- xact->xd_flags |= (XT_XN_XAC_COMMITTED | XT_XN_XAC_ENDED);
-
- /* Drop locks is you have any: */
- thread->st_lock_list.xt_remove_all_locks(db, thread);
+ if (phase & XN_END_PHASE_FAST) {
+ xact->xd_end_time = ++db->db_xn_end_time;
+ xact->xd_flags |= (XT_XN_XAC_COMMITTED | XT_XN_XAC_ENDED);
- xact->xd_end_xn_id = db->db_xn_curr_id;
+ if (!(phase & XN_END_PHASE_SLOW))
+ return ok;
+ }
- xact->xd_flags |= XT_XN_XAC_SWEEP;
+ xn_end_release_locks(thread);
if (xt_xn_delete_xact(db, xn_id, thread)) {
if (db->db_xn_min_ram_id == xn_id)
@@ -1477,12 +1526,22 @@ static xtBool xn_end_xact(XTThreadPtr thread, u_int status)
xtPublic xtBool xt_xn_commit(XTThreadPtr thread)
{
- return xn_end_xact(thread, XT_LOG_ENT_COMMIT);
+ return xn_end_xact(thread, XT_LOG_ENT_COMMIT, thread->st_xact_writer, XN_END_PHASE_BOTH);
+}
+
+xtPublic xtBool xt_xn_commit_fast(XTThreadPtr thread, xtBool writer)
+{
+ return xn_end_xact(thread, XT_LOG_ENT_COMMIT, writer, XN_END_PHASE_FAST);
+}
+
+xtPublic xtBool xt_xn_commit_slow(XTThreadPtr thread, xtBool writer)
+{
+ return xn_end_xact(thread, XT_LOG_ENT_COMMIT, writer, XN_END_PHASE_SLOW);
}
xtPublic xtBool xt_xn_rollback(XTThreadPtr thread)
{
- return xn_end_xact(thread, XT_LOG_ENT_ABORT);
+ return xn_end_xact(thread, XT_LOG_ENT_ABORT, thread->st_xact_writer, XN_END_PHASE_BOTH);
}
xtPublic xtBool xt_xn_log_tab_id(XTThreadPtr self, xtTableID tab_id)
diff --git a/storage/pbxt/src/xaction_xt.h b/storage/pbxt/src/xaction_xt.h
index e679a0f38f0..cd350200506 100644
--- a/storage/pbxt/src/xaction_xt.h
+++ b/storage/pbxt/src/xaction_xt.h
@@ -193,6 +193,8 @@ void xt_wakeup_sweeper(struct XTDatabase *db);
xtBool xt_xn_begin(struct XTThread *self);
xtBool xt_xn_commit(struct XTThread *self);
+xtBool xt_xn_commit_fast(struct XTThread *self, xtBool writer);
+xtBool xt_xn_commit_slow(struct XTThread *self, xtBool writer);
xtBool xt_xn_rollback(struct XTThread *self);
xtBool xt_xn_log_tab_id(struct XTThread *self, xtTableID tab_id);
int xt_xn_status(struct XTOpenTable *ot, xtXactID xn_id, xtRecordID rec_id);
diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
index 13c4f24d3a9..182e8f150e5 100644
--- a/storage/xtradb/CMakeLists.txt
+++ b/storage/xtradb/CMakeLists.txt
@@ -21,8 +21,6 @@ IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
SET(WIN64 TRUE)
ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
-ADD_DEFINITIONS(-D_WIN32 -D_LIB -DMYSQL_SERVER)
-
# Include directories under xtradb
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/xtradb/include
${CMAKE_SOURCE_DIR}/storage/xtradb/handler)
@@ -83,9 +81,6 @@ SET(XTRADB_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
usr/usr0sess.c
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rbt.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
ut/ut0list.c ut/ut0wqueue.c)
-# Windows atomics do not perform well. Disable Windows atomics by default.
-# See bug#52102 for details.
-#ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DINNODB_RW_LOCKS_USE_ATOMICS -DHAVE_IB_PAUSE_INSTRUCTION)
-ADD_DEFINITIONS(-DHAVE_IB_PAUSE_INSTRUCTION)
+
MYSQL_STORAGE_ENGINE(XTRADB)
diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c
index 65189ba2961..0d62cd375a9 100644
--- a/storage/xtradb/dict/dict0dict.c
+++ b/storage/xtradb/dict/dict0dict.c
@@ -498,10 +498,12 @@ Looks for column n in an index.
ULINT_UNDEFINED if not contained */
UNIV_INTERN
ulint
-dict_index_get_nth_col_pos(
-/*=======================*/
- const dict_index_t* index, /*!< in: index */
- ulint n) /*!< in: column number */
+dict_index_get_nth_col_or_prefix_pos(
+/*=================================*/
+ const dict_index_t* index, /*!< in: index */
+ ulint n, /*!< in: column number */
+ ibool inc_prefix) /*!< in: TRUE=consider
+ column prefixes too */
{
const dict_field_t* field;
const dict_col_t* col;
@@ -523,7 +525,8 @@ dict_index_get_nth_col_pos(
for (pos = 0; pos < n_fields; pos++) {
field = dict_index_get_nth_field(index, pos);
- if (col == field->col && field->prefix_len == 0) {
+ if (col == field->col
+ && (inc_prefix || field->prefix_len == 0)) {
return(pos);
}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index a9592d4a748..8dced827813 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -32,7 +32,8 @@ this program; if not, write to the Free Software Foundation, Inc.,
*****************************************************************************/
/* TODO list for the InnoDB handler in 5.0:
- - Remove the flag trx->active_trans and look at trx->conc_state
+ - Remove the flag trx->active_flag & TRX_ACTIVE_IN_MYSQL and look
+ at trx->conc_state
- fix savepoint functions to use savepoint storage area
- Find out what kind of problems the OS X case-insensitivity causes to
table and database names; should we 'normalize' the names like we do
@@ -55,7 +56,9 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include <m_ctype.h>
#include <mysys_err.h>
#include <mysql/plugin.h>
-
+#ifdef _WIN32
+#include <io.h>
+#endif
/** @file ha_innodb.cc */
/* Include necessary InnoDB headers */
@@ -117,14 +120,13 @@ bool check_global_access(THD *thd, ulong want_access);
/** to protect innobase_open_files */
static pthread_mutex_t innobase_share_mutex;
-/** to force correct commit order in binlog */
-static pthread_mutex_t prepare_commit_mutex;
static ulong commit_threads = 0;
static pthread_mutex_t commit_threads_m;
static pthread_cond_t commit_cond;
static pthread_mutex_t commit_cond_m;
static bool innodb_inited = 0;
+
#define INSIDE_HA_INNOBASE_CC
/* In the Windows plugin, the return value of current_thd is
@@ -249,6 +251,7 @@ static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
static INNOBASE_SHARE *get_share(const char *table_name);
static void free_share(INNOBASE_SHARE *share);
static int innobase_close_connection(handlerton *hton, THD* thd);
+static void innobase_commit_ordered(handlerton *hton, THD* thd, bool all);
static int innobase_commit(handlerton *hton, THD* thd, bool all);
static int innobase_rollback(handlerton *hton, THD* thd, bool all);
static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
@@ -520,6 +523,17 @@ bool innobase_show_status(handlerton *hton, THD* thd,
stat_print_fn* stat_print,
enum ha_stat_type stat_type);
+/* Enable / disable checkpoints */
+static int innobase_checkpoint_state(handlerton *hton, bool disable)
+{
+ if (disable)
+ (void) log_disable_checkpoint();
+ else
+ log_enable_checkpoint();
+ return 0;
+}
+
+
/*****************************************************************//**
Commits a transaction in an InnoDB database. */
static
@@ -888,6 +902,9 @@ convert_error_code_to_mysql(
case DB_RECORD_NOT_FOUND:
return(HA_ERR_NO_ACTIVE_RECORD);
+ case DB_SEARCH_ABORTED_BY_USER:
+ return(HA_ERR_ABORTED_BY_USER);
+
case DB_DEADLOCK:
/* Since we rolled back the whole transaction, we must
tell it also to MySQL so that MySQL knows to empty the
@@ -1268,7 +1285,28 @@ innobase_mysql_tmpfile(void)
will be passed to fdopen(), it will be closed by invoking
fclose(), which in turn will invoke close() instead of
my_close(). */
+#ifdef _WIN32
+ /* Note that on Windows, the integer returned by mysql_tmpfile
+ has no relation to C runtime file descriptor. Here, we need
+ to call my_get_osfhandle to get the HANDLE and then convert it
+ to C runtime filedescriptor. */
+ {
+ HANDLE hFile = my_get_osfhandle(fd);
+ HANDLE hDup;
+ BOOL bOK =
+ DuplicateHandle(GetCurrentProcess(), hFile, GetCurrentProcess(),
+ &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
+ if(bOK) {
+ fd2 = _open_osfhandle((intptr_t)hDup,0);
+ }
+ else {
+ my_osmaperr(GetLastError());
+ fd2 = -1;
+ }
+ }
+#else
fd2 = dup(fd);
+#endif
if (fd2 < 0) {
DBUG_PRINT("error",("Got error %d on dup",fd2));
my_errno=errno;
@@ -1367,7 +1405,8 @@ innobase_next_autoinc(
ulonglong current, /*!< in: Current value */
ulonglong increment, /*!< in: increment current by */
ulonglong offset, /*!< in: AUTOINC offset */
- ulonglong max_value) /*!< in: max value for type */
+ ulonglong max_value, /*!< in: max value for type */
+ ulonglong reserve) /*!< in: how many values to reserve */
{
ulonglong next_value;
@@ -1376,51 +1415,16 @@ innobase_next_autoinc(
/* According to MySQL documentation, if the offset is greater than
the increment then the offset is ignored. */
- if (offset > increment) {
+ if (offset >= increment)
offset = 0;
- }
-
- if (max_value <= current) {
- next_value = max_value;
- } else if (offset <= 1) {
- /* Offset 0 and 1 are the same, because there must be at
- least one node in the system. */
- if (max_value - current <= increment) {
- next_value = max_value;
- } else {
- next_value = current + increment;
- }
- } else if (max_value > current) {
- if (current > offset) {
- next_value = ((current - offset) / increment) + 1;
- } else {
- next_value = ((offset - current) / increment) + 1;
- }
-
- ut_a(increment > 0);
- ut_a(next_value > 0);
-
- /* Check for multiplication overflow. */
- if (increment > (max_value / next_value)) {
-
- next_value = max_value;
- } else {
- next_value *= increment;
-
- ut_a(max_value >= next_value);
-
- /* Check for overflow. */
- if (max_value - next_value <= offset) {
- next_value = max_value;
- } else {
- next_value += offset;
- }
- }
- } else {
- next_value = max_value;
- }
- ut_a(next_value <= max_value);
+ if (max_value <= current)
+ return max_value;
+ next_value = (current / increment) + reserve;
+ next_value = next_value * increment + offset;
+ /* Check for overflow. */
+ if (next_value < current || next_value > max_value)
+ next_value = max_value;
return(next_value);
}
@@ -1435,7 +1439,6 @@ innobase_trx_init(
trx_t* trx) /*!< in/out: InnoDB transaction handle */
{
DBUG_ENTER("innobase_trx_init");
- DBUG_ASSERT(EQ_CURRENT_THD(thd));
DBUG_ASSERT(thd == trx->mysql_thd);
trx->check_foreigns = !thd_test_options(
@@ -1496,8 +1499,6 @@ check_trx_exists(
{
trx_t*& trx = thd_to_trx(thd);
- ut_ad(EQ_CURRENT_THD(thd));
-
if (trx == NULL) {
trx = innobase_trx_allocate(thd);
} else if (UNIV_UNLIKELY(trx->magic_n != TRX_MAGIC_N)) {
@@ -1789,10 +1790,10 @@ innobase_query_caching_of_table_permitted(
/* The call of row_search_.. will start a new transaction if it is
not yet started */
- if (trx->active_trans == 0) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0) {
innobase_register_trx_and_stmt(innodb_hton_ptr, thd);
- trx->active_trans = 1;
+ trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
}
if (row_search_check_if_query_cache_permitted(trx, norm_name)) {
@@ -2019,14 +2020,24 @@ trx_is_strict(
/**************************************************************//**
Resets some fields of a prebuilt struct. The template is used in fast
retrieval of just those column values MySQL needs in its processing. */
-static
void
-reset_template(
-/*===========*/
- row_prebuilt_t* prebuilt) /*!< in/out: prebuilt struct */
+inline
+ha_innobase::reset_template(void)
+/*=============================*/
{
+ ut_ad(prebuilt->magic_n == ROW_PREBUILT_ALLOCATED);
+ ut_ad(prebuilt->magic_n2 == prebuilt->magic_n);
+
prebuilt->keep_other_fields_on_keyread = 0;
prebuilt->read_just_key = 0;
+ /* Reset index condition pushdown state. */
+ if (prebuilt->idx_cond) {
+ prebuilt->idx_cond = NULL;
+ prebuilt->idx_cond_n_cols = 0;
+ /* Invalidate prebuilt->mysql_template
+ in ha_innobase::write_row(). */
+ prebuilt->template_type = ROW_MYSQL_NO_TEMPLATE;
+ }
}
/*****************************************************************//**
@@ -2062,11 +2073,11 @@ ha_innobase::init_table_handle_for_HANDLER(void)
/* Set the MySQL flag to mark that there is an active transaction */
- if (prebuilt->trx->active_trans == 0) {
+ if ((prebuilt->trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0) {
innobase_register_trx_and_stmt(ht, user_thd);
- prebuilt->trx->active_trans = 1;
+ prebuilt->trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
}
/* We did the necessary inits in this function, no need to repeat them
@@ -2088,7 +2099,7 @@ ha_innobase::init_table_handle_for_HANDLER(void)
we???? */
prebuilt->used_in_HANDLER = TRUE;
- reset_template(prebuilt);
+ reset_template();
}
/*********************************************************************//**
@@ -2117,12 +2128,14 @@ innobase_init(
innobase_hton->savepoint_set=innobase_savepoint;
innobase_hton->savepoint_rollback=innobase_rollback_to_savepoint;
innobase_hton->savepoint_release=innobase_release_savepoint;
+ innobase_hton->commit_ordered=innobase_commit_ordered;
innobase_hton->commit=innobase_commit;
innobase_hton->rollback=innobase_rollback;
innobase_hton->prepare=innobase_xa_prepare;
innobase_hton->recover=innobase_xa_recover;
innobase_hton->commit_by_xid=innobase_commit_by_xid;
innobase_hton->rollback_by_xid=innobase_rollback_by_xid;
+ innobase_hton->checkpoint_state= innobase_checkpoint_state;
innobase_hton->create_cursor_read_view=innobase_create_cursor_view;
innobase_hton->set_cursor_read_view=innobase_set_cursor_view;
innobase_hton->close_cursor_read_view=innobase_close_cursor_view;
@@ -2661,7 +2674,6 @@ skip_overwrite:
innobase_open_tables = hash_create(200);
pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
pthread_cond_init(&commit_cond, NULL);
@@ -2715,7 +2727,6 @@ innobase_end(
my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR));
pthread_mutex_destroy(&innobase_share_mutex);
- pthread_mutex_destroy(&prepare_commit_mutex);
pthread_mutex_destroy(&commit_threads_m);
pthread_mutex_destroy(&commit_cond_m);
pthread_cond_destroy(&commit_cond);
@@ -2836,14 +2847,118 @@ innobase_start_trx_and_assign_read_view(
/* Set the MySQL flag to mark that there is an active transaction */
- if (trx->active_trans == 0) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0) {
innobase_register_trx_and_stmt(hton, thd);
- trx->active_trans = 1;
+ trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
}
DBUG_RETURN(0);
}
+static
+void
+innobase_commit_ordered_2(
+/*============*/
+ trx_t* trx, /*!< in: Innodb transaction */
+ THD* thd) /*!< in: MySQL thread handle */
+{
+ ulonglong tmp_pos;
+ DBUG_ENTER("innobase_commit_ordered");
+
+ /* We need current binlog position for ibbackup to work.
+ Note, the position is current because commit_ordered is guaranteed
+ to be called in same sequenece as writing to binlog. */
+
+retry:
+ if (innobase_commit_concurrency > 0) {
+ pthread_mutex_lock(&commit_cond_m);
+ commit_threads++;
+
+ if (commit_threads > innobase_commit_concurrency) {
+ commit_threads--;
+ pthread_cond_wait(&commit_cond,
+ &commit_cond_m);
+ pthread_mutex_unlock(&commit_cond_m);
+ goto retry;
+ }
+ else {
+ pthread_mutex_unlock(&commit_cond_m);
+ }
+ }
+
+ mysql_bin_log_commit_pos(thd, &tmp_pos, &(trx->mysql_log_file_name));
+ trx->mysql_log_offset = (ib_int64_t) tmp_pos;
+
+ /* Don't do write + flush right now. For group commit
+ to work we want to do the flush in the innobase_commit()
+ method, which runs without holding any locks. */
+ trx->flush_log_later = TRUE;
+ innobase_commit_low(trx);
+ trx->flush_log_later = FALSE;
+
+ if (innobase_commit_concurrency > 0) {
+ pthread_mutex_lock(&commit_cond_m);
+ commit_threads--;
+ pthread_cond_signal(&commit_cond);
+ pthread_mutex_unlock(&commit_cond_m);
+ }
+
+ DBUG_VOID_RETURN;
+}
+
+/*****************************************************************//**
+Perform the first, fast part of InnoDB commit.
+
+Doing it in this call ensures that we get the same commit order here
+as in binlog and any other participating transactional storage engines.
+
+Note that we want to do as little as really needed here, as we run
+under a global mutex. The expensive fsync() is done later, in
+innobase_commit(), without a lock so group commit can take place.
+
+Note also that this method can be called from a different thread than
+the one handling the rest of the transaction. */
+static
+void
+innobase_commit_ordered(
+/*============*/
+ handlerton *hton, /*!< in: Innodb handlerton */
+ THD* thd, /*!< in: MySQL thread handle of the user for whom
+ the transaction should be committed */
+ bool all) /*!< in: TRUE - commit transaction
+ FALSE - the current SQL statement ended */
+{
+ trx_t* trx;
+ DBUG_ENTER("innobase_commit_ordered");
+ DBUG_ASSERT(hton == innodb_hton_ptr);
+
+ trx = check_trx_exists(thd);
+
+ /* Since we will reserve the kernel mutex, we must not be holding the
+ search system latch, or we will disobey the latching order. But we
+ already released it in innobase_xa_prepare() (if not before), so just
+ have an assert here.*/
+ ut_ad(!trx->has_search_latch);
+
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0
+ && trx->conc_state != TRX_NOT_STARTED) {
+ /* We cannot throw error here; instead we will catch this error
+ again in innobase_commit() and report it from there. */
+ DBUG_VOID_RETURN;
+ }
+
+ /* commit_ordered is only called when committing the whole transaction
+ (or an SQL statement when autocommit is on). */
+ DBUG_ASSERT(all ||
+ (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)));
+
+ innobase_commit_ordered_2(trx, thd);
+
+ trx->active_flag |= TRX_ACTIVE_COMMIT_ORDERED;
+
+ DBUG_VOID_RETURN;
+}
+
/*****************************************************************//**
Commits a transaction in an InnoDB database or marks an SQL statement
ended.
@@ -2869,7 +2984,8 @@ innobase_commit(
/* Since we will reserve the kernel mutex, we have to release
the search system latch first to obey the latching order. */
- if (trx->has_search_latch) {
+ if (trx->has_search_latch &&
+ (trx->active_flag & TRX_ACTIVE_COMMIT_ORDERED) == 0) {
trx_search_latch_release_if_reserved(trx);
}
@@ -2878,7 +2994,7 @@ innobase_commit(
thd->main_da.reset_diagnostics_area(); /* because debug assertion code complains, if something left */
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
- /* The flag trx->active_trans is set to 1 in
+ /* The flag TRX_ACTIVE_IN_MYSQL in trx->active_flag is set in
1. ::external_lock(),
2. ::start_stmt(),
@@ -2888,81 +3004,33 @@ innobase_commit(
6. innobase_start_trx_and_assign_read_view(),
7. ::transactional_table_lock()
- and it is only set to 0 in a commit or a rollback. If it is 0 we know
+ and it is only cleared in a commit or a rollback. If it is unset we know
there cannot be resources to be freed and we could return immediately.
For the time being, we play safe and do the cleanup though there should
be nothing to clean up. */
- if (trx->active_trans == 0
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0
&& trx->conc_state != TRX_NOT_STARTED) {
- sql_print_error("trx->active_trans == 0, but"
- " trx->conc_state != TRX_NOT_STARTED");
+ sql_print_error("trx->active_flag & TRX_ACTIVE_IN_MYSQL== 0,"
+ " but trx->conc_state != TRX_NOT_STARTED");
}
+
if (all
|| (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
- /* We were instructed to commit the whole transaction, or
- this is an SQL statement end and autocommit is on */
-
- /* We need current binlog position for ibbackup to work.
- Note, the position is current because of
- prepare_commit_mutex */
-retry:
- if (innobase_commit_concurrency > 0) {
- pthread_mutex_lock(&commit_cond_m);
- commit_threads++;
-
- if (commit_threads > innobase_commit_concurrency) {
- commit_threads--;
- pthread_cond_wait(&commit_cond,
- &commit_cond_m);
- pthread_mutex_unlock(&commit_cond_m);
- goto retry;
- }
- else {
- pthread_mutex_unlock(&commit_cond_m);
- }
- }
-
- /* The following calls to read the MySQL binary log
- file name and the position return consistent results:
- 1) Other InnoDB transactions cannot intervene between
- these calls as we are holding prepare_commit_mutex.
- 2) Binary logging of other engines is not relevant
- to InnoDB as all InnoDB requires is that committing
- InnoDB transactions appear in the same order in the
- MySQL binary log as they appear in InnoDB logs.
- 3) A MySQL log file rotation cannot happen because
- MySQL protects against this by having a counter of
- transactions in prepared state and it only allows
- a rotation when the counter drops to zero. See
- LOCK_prep_xids and COND_prep_xids in log.cc. */
- trx->mysql_log_file_name = mysql_bin_log_file_name();
- trx->mysql_log_offset = (ib_int64_t) mysql_bin_log_file_pos();
-
- /* Don't do write + flush right now. For group commit
- to work we want to do the flush after releasing the
- prepare_commit_mutex. */
- trx->flush_log_later = TRUE;
- innobase_commit_low(trx);
- trx->flush_log_later = FALSE;
-
- if (innobase_commit_concurrency > 0) {
- pthread_mutex_lock(&commit_cond_m);
- commit_threads--;
- pthread_cond_signal(&commit_cond);
- pthread_mutex_unlock(&commit_cond_m);
+ /* Run the fast part of commit if we did not already. */
+ if ((trx->active_flag & TRX_ACTIVE_COMMIT_ORDERED) == 0) {
+ innobase_commit_ordered_2(trx, thd);
}
- if (trx->active_trans == 2) {
-
- pthread_mutex_unlock(&prepare_commit_mutex);
- }
+ /* We were instructed to commit the whole transaction, or
+ this is an SQL statement end and autocommit is on */
- /* Now do a write + flush of logs. */
+ /* We did the first part already in innobase_commit_ordered(),
+ Now finish by doing a write + flush of logs. */
trx_commit_complete_for_mysql(trx);
- trx->active_trans = 0;
+ trx->active_flag = 0;
} else {
/* We just mark the SQL statement ended and do not do a
@@ -3035,7 +3103,7 @@ innobase_rollback(
|| !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
error = trx_rollback_for_mysql(trx);
- trx->active_trans = 0;
+ trx->active_flag = 0;
} else {
error = trx_rollback_last_sql_stat_for_mysql(trx);
}
@@ -3179,7 +3247,7 @@ innobase_savepoint(
innobase_release_stat_resources(trx);
/* cannot happen outside of transaction */
- DBUG_ASSERT(trx->active_trans);
+ DBUG_ASSERT(trx->active_flag & TRX_ACTIVE_IN_MYSQL);
/* TODO: use provided savepoint data area to store savepoint data */
char name[64];
@@ -3209,11 +3277,11 @@ innobase_close_connection(
ut_a(trx);
- if (trx->active_trans == 0
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0
&& trx->conc_state != TRX_NOT_STARTED) {
- sql_print_error("trx->active_trans == 0, but"
- " trx->conc_state != TRX_NOT_STARTED");
+ sql_print_error("trx->active_flag & TRX_ACTIVE_IN_MYSQL == 0,"
+ " but trx->conc_state != TRX_NOT_STARTED");
}
@@ -3341,13 +3409,16 @@ UNIV_INTERN
ulong
ha_innobase::index_flags(
/*=====================*/
- uint,
- uint,
- bool)
+ uint index,
+ uint part,
+ bool all_parts)
const
{
- return(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER
- | HA_READ_RANGE | HA_KEYREAD_ONLY);
+ ulong extra_flag= 0;
+ if (table && index == table->s->primary_key)
+ extra_flag= HA_CLUSTERED_INDEX;
+ return(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | extra_flag
+ | HA_READ_RANGE | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN);
}
/****************************************************************//**
@@ -3877,8 +3948,7 @@ ha_innobase::innobase_initialize_autoinc()
nor the offset, so use a default increment of 1. */
auto_inc = innobase_next_autoinc(
- read_auto_inc, 1, 1, col_max_value);
-
+ read_auto_inc, 1, 1, col_max_value, 1);
break;
}
case DB_RECORD_NOT_FOUND:
@@ -4353,8 +4423,8 @@ static inline
uint
get_field_offset(
/*=============*/
- TABLE* table, /*!< in: MySQL table object */
- Field* field) /*!< in: MySQL field object */
+ const TABLE* table, /*!< in: MySQL table object */
+ const Field* field) /*!< in: MySQL field object */
{
return((uint) (field->ptr - table->record[0]));
}
@@ -4552,12 +4622,24 @@ get_innobase_type_from_mysql_type(
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_NEWDATE:
+ return(DATA_INT);
+
case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_TIMESTAMP:
- return(DATA_INT);
+ /*
+ XtraDB should ideally just check field->keytype() and never
+ field->type(). The following check is here to only
+ change the new hires datetime/timestamp/time fields to
+ use DATA_FIXBINARY. We can't convert this function to
+ just test for field->keytype() as then the check if a
+ table is compatible will fail for old tables.
+ */
+ if (field->key_type() == HA_KEYTYPE_BINARY)
+ return(DATA_FIXBINARY);
+ return(DATA_INT);
case MYSQL_TYPE_FLOAT:
return(DATA_FLOAT);
case MYSQL_TYPE_DOUBLE:
@@ -4571,10 +4653,7 @@ get_innobase_type_from_mysql_type(
case MYSQL_TYPE_LONG_BLOB:
return(DATA_BLOB);
case MYSQL_TYPE_NULL:
- /* MySQL currently accepts "NULL" datatype, but will
- reject such datatype in the next release. We will cope
- with it and not trigger assertion failure in 5.1 */
- break;
+ return(DATA_FIXBINARY);
default:
ut_error;
}
@@ -4889,41 +4968,170 @@ ha_innobase::store_key_val_for_row(
}
/**************************************************************//**
+Determines if a field is needed in a prebuilt struct 'template'.
+@return field to use, or NULL if the field is not needed */
+static
+const Field*
+build_template_needs_field(
+/*=======================*/
+ ibool index_contains, /*!< in:
+ dict_index_contains_col_or_prefix(
+ index, i) */
+ ibool read_just_key, /*!< in: TRUE when MySQL calls
+ ha_innobase::extra with the
+ argument HA_EXTRA_KEYREAD; it is enough
+ to read just columns defined in
+ the index (i.e., no read of the
+ clustered index record necessary) */
+ ibool fetch_all_in_key,
+ /*!< in: true=fetch all fields in
+ the index */
+ ibool fetch_primary_key_cols,
+ /*!< in: true=fetch the
+ primary key columns */
+ dict_index_t* index, /*!< in: InnoDB index to use */
+ const TABLE* table, /*!< in: MySQL table object */
+ ulint i, /*!< in: field index in InnoDB table */
+ ulint sql_idx) /*!< in: field index in SQL table */
+{
+ const Field* field = table->field[sql_idx];
+
+ ut_ad(index_contains == dict_index_contains_col_or_prefix(index, i));
+
+ if (!index_contains) {
+ if (read_just_key) {
+ /* If this is a 'key read', we do not need
+ columns that are not in the key */
+
+ return(NULL);
+ }
+ } else if (fetch_all_in_key) {
+ /* This field is needed in the query */
+
+ return(field);
+ }
+
+ if (bitmap_is_set(table->read_set, sql_idx)
+ || bitmap_is_set(table->write_set, sql_idx)) {
+ /* This field is needed in the query */
+
+ return(field);
+ }
+
+ if (fetch_primary_key_cols
+ && dict_table_col_in_clustered_key(index->table, i)) {
+ /* This field is needed in the query */
+
+ return(field);
+ }
+
+ /* This field is not needed in the query, skip it */
+
+ return(NULL);
+}
+
+/**************************************************************//**
+Adds a field is to a prebuilt struct 'template'.
+@return the field template */
+static
+mysql_row_templ_t*
+build_template_field(
+/*=================*/
+ row_prebuilt_t* prebuilt, /*!< in/out: template */
+ dict_index_t* clust_index, /*!< in: InnoDB clustered index */
+ dict_index_t* index, /*!< in: InnoDB index to use */
+ TABLE* table, /*!< in: MySQL table object */
+ const Field* field, /*!< in: field in MySQL table */
+ ulint i) /*!< in: field index in InnoDB table */
+{
+ mysql_row_templ_t* templ;
+ const dict_col_t* col;
+
+ ut_ad(field == table->field[i]);
+ ut_ad(clust_index->table == index->table);
+
+ col = dict_table_get_nth_col(index->table, i);
+
+ templ = prebuilt->mysql_template + prebuilt->n_template++;
+ UNIV_MEM_INVALID(templ, sizeof *templ);
+ templ->col_no = i;
+ templ->clust_rec_field_no = dict_col_get_clust_pos(col, clust_index);
+ ut_a(templ->clust_rec_field_no != ULINT_UNDEFINED);
+
+ if (dict_index_is_clust(index)) {
+ templ->rec_field_no = templ->clust_rec_field_no;
+ } else {
+ templ->rec_field_no = dict_index_get_nth_col_pos(index, i);
+ }
+
+ if (field->null_ptr) {
+ templ->mysql_null_byte_offset =
+ (ulint) ((char*) field->null_ptr
+ - (char*) table->record[0]);
+
+ templ->mysql_null_bit_mask = (ulint) field->null_bit;
+ } else {
+ templ->mysql_null_bit_mask = 0;
+ }
+
+ templ->mysql_col_offset = (ulint) get_field_offset(table, field);
+
+ templ->mysql_col_len = (ulint) field->pack_length();
+ templ->type = col->mtype;
+ templ->mysql_type = (ulint)field->type();
+
+ if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
+ templ->mysql_length_bytes = (ulint)
+ (((Field_varstring*)field)->length_bytes);
+ }
+
+ templ->charset = dtype_get_charset_coll(col->prtype);
+ templ->mbminlen = col->mbminlen;
+ templ->mbmaxlen = col->mbmaxlen;
+ templ->is_unsigned = col->prtype & DATA_UNSIGNED;
+
+ if (!dict_index_is_clust(index)
+ && templ->rec_field_no == ULINT_UNDEFINED) {
+ prebuilt->need_to_access_clustered = TRUE;
+ }
+
+ if (prebuilt->mysql_prefix_len < templ->mysql_col_offset
+ + templ->mysql_col_len) {
+ prebuilt->mysql_prefix_len = templ->mysql_col_offset
+ + templ->mysql_col_len;
+ }
+
+ if (templ->type == DATA_BLOB) {
+ prebuilt->templ_contains_blob = TRUE;
+ }
+
+ return(templ);
+}
+
+/**************************************************************//**
Builds a 'template' to the prebuilt struct. The template is used in fast
retrieval of just those column values MySQL needs in its processing. */
-static
+UNIV_INTERN
void
-build_template(
-/*===========*/
- row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct */
- THD* thd, /*!< in: current user thread, used
- only if templ_type is
- ROW_MYSQL_REC_FIELDS */
- TABLE* table, /*!< in: MySQL table */
- uint templ_type) /*!< in: ROW_MYSQL_WHOLE_ROW or
- ROW_MYSQL_REC_FIELDS */
+ha_innobase::build_template(
+/*========================*/
+ bool whole_row) /*!< in: true=ROW_MYSQL_WHOLE_ROW,
+ false=ROW_MYSQL_REC_FIELDS */
{
dict_index_t* index;
dict_index_t* clust_index;
- mysql_row_templ_t* templ;
- Field* field;
- ulint n_fields, n_stored_fields;
- ulint n_requested_fields = 0;
+ ulint n_stored_fields;
ibool fetch_all_in_key = FALSE;
ibool fetch_primary_key_cols = FALSE;
- ulint sql_idx, innodb_idx=0;
- /* byte offset of the end of last requested column */
- ulint mysql_prefix_len = 0;
-
+ ulint i, sql_idx;
+
if (prebuilt->select_lock_type == LOCK_X) {
/* We always retrieve the whole clustered index record if we
use exclusive row level locks, for example, if the read is
done in an UPDATE statement. */
- templ_type = ROW_MYSQL_WHOLE_ROW;
- }
-
- if (templ_type == ROW_MYSQL_REC_FIELDS) {
+ whole_row = true;
+ } else if (!whole_row) {
if (prebuilt->hint_need_to_fetch_extra_cols
== ROW_RETRIEVE_ALL_COLS) {
@@ -4940,7 +5148,7 @@ build_template(
fetch_all_in_key = TRUE;
} else {
- templ_type = ROW_MYSQL_WHOLE_ROW;
+ whole_row = true;
}
} else if (prebuilt->hint_need_to_fetch_extra_cols
== ROW_RETRIEVE_PRIMARY_KEY) {
@@ -4957,21 +5165,13 @@ build_template(
clust_index = dict_table_get_first_index(prebuilt->table);
- if (templ_type == ROW_MYSQL_REC_FIELDS) {
- index = prebuilt->index;
- } else {
- index = clust_index;
- }
+ index = whole_row ? clust_index : prebuilt->index;
- if (index == clust_index) {
- prebuilt->need_to_access_clustered = TRUE;
- } else {
- prebuilt->need_to_access_clustered = FALSE;
- /* Below we check column by column if we need to access
- the clustered index */
- }
+ prebuilt->need_to_access_clustered = (index == clust_index);
+
+ /* Below we check column by column if we need to access
+ the clustered index. */
- n_fields = (ulint)table->s->fields; /* number of columns */
n_stored_fields= (ulint)table->s->stored_fields; /* number of stored columns */
if (!prebuilt->mysql_template) {
@@ -4979,126 +5179,206 @@ build_template(
mem_alloc(n_stored_fields * sizeof(mysql_row_templ_t));
}
- prebuilt->template_type = templ_type;
+ prebuilt->template_type = whole_row
+ ? ROW_MYSQL_WHOLE_ROW : ROW_MYSQL_REC_FIELDS;
prebuilt->null_bitmap_len = table->s->null_bytes;
+ /* Prepare to build prebuilt->mysql_template[]. */
prebuilt->templ_contains_blob = FALSE;
+ prebuilt->mysql_prefix_len = 0;
+ prebuilt->n_template = 0;
+ prebuilt->idx_cond_n_cols = 0;
+
+ /* Note that in InnoDB, i is the column number in the table.
+ MySQL calls columns 'fields'. */
+
+ if (active_index != MAX_KEY && active_index == pushed_idx_cond_keyno) {
+ /* Push down an index condition or an end_range check. */
+ for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) {
+
+ while (!table->field[sql_idx]->stored_in_db) {
+ sql_idx++;
+ }
+
+ const ibool index_contains
+ = dict_index_contains_col_or_prefix(index, i);
+
+ /* Test if an end_range or an index condition
+ refers to the field. Note that "index" and
+ "index_contains" may refer to the clustered index.
+ Index condition pushdown is relative to prebuilt->index
+ (the index that is being looked up first). */
+
+ /* When join_read_always_key() invokes this
+ code via handler::ha_index_init() and
+ ha_innobase::index_init(), end_range is not
+ yet initialized. Because of that, we must
+ always check for index_contains, instead of
+ the subset
+ field->part_of_key.is_set(active_index)
+ which would be acceptable if end_range==NULL. */
+ if (index == prebuilt->index
+ ? index_contains
+ : dict_index_contains_col_or_prefix(
+ prebuilt->index, i)) {
+ /* Needed in ICP */
+ const Field* field;
+ mysql_row_templ_t* templ;
+
+ if (whole_row) {
+ field = table->field[sql_idx];
+ } else {
+ field = build_template_needs_field(
+ index_contains,
+ prebuilt->read_just_key,
+ fetch_all_in_key,
+ fetch_primary_key_cols,
+ index, table, i, sql_idx);
+ if (!field) {
+ continue;
+ }
+ }
- /* Note that in InnoDB, i is the column number. MySQL calls columns
- 'fields'. */
- for (sql_idx = 0; sql_idx < n_fields; sql_idx++) {
- templ = prebuilt->mysql_template + n_requested_fields;
- field = table->field[sql_idx];
- if (!field->stored_in_db)
- goto skip_field;
-
- if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) {
- /* Decide which columns we should fetch
- and which we can skip. */
- register const ibool index_contains_field =
- dict_index_contains_col_or_prefix(index, innodb_idx);
-
- if (!index_contains_field && prebuilt->read_just_key) {
- /* If this is a 'key read', we do not need
- columns that are not in the key */
-
- goto skip_field;
- }
-
- if (index_contains_field && fetch_all_in_key) {
- /* This field is needed in the query */
-
- goto include_field;
- }
-
- if (bitmap_is_set(table->read_set, sql_idx) ||
- bitmap_is_set(table->write_set, sql_idx)) {
- /* This field is needed in the query */
-
- goto include_field;
- }
+ templ = build_template_field(
+ prebuilt, clust_index, index,
+ table, field, i);
+ prebuilt->idx_cond_n_cols++;
+ ut_ad(prebuilt->idx_cond_n_cols
+ == prebuilt->n_template);
+
+ if (index == prebuilt->index) {
+ templ->icp_rec_field_no
+ = templ->rec_field_no;
+ } else {
+ templ->icp_rec_field_no
+ = dict_index_get_nth_col_pos(
+ prebuilt->index, i);
+ }
- if (fetch_primary_key_cols
- && dict_table_col_in_clustered_key(
- index->table, innodb_idx)) {
- /* This field is needed in the query */
+ if (dict_index_is_clust(prebuilt->index)) {
+ ut_ad(templ->icp_rec_field_no
+ != ULINT_UNDEFINED);
+ /* If the primary key includes
+ a column prefix, use it in
+ index condition pushdown,
+ because the condition is
+ evaluated before fetching any
+ off-page (externally stored)
+ columns. */
+ if (templ->icp_rec_field_no
+ < prebuilt->index->n_uniq) {
+ /* This is a key column;
+ all set. */
+ continue;
+ }
+ } else if (templ->icp_rec_field_no
+ != ULINT_UNDEFINED) {
+ continue;
+ }
- goto include_field;
+ /* This is a column prefix index.
+ The column prefix can be used in
+ an end_range comparison. */
+
+ templ->icp_rec_field_no
+ = dict_index_get_nth_col_or_prefix_pos(
+ prebuilt->index, i, TRUE);
+ ut_ad(templ->icp_rec_field_no
+ != ULINT_UNDEFINED);
+
+ /* Index condition pushdown can be used on
+ all columns of a secondary index, and on
+ the PRIMARY KEY columns. */
+ /* TODO: enable this assertion
+ (but first ensure that end_range is
+ valid here and use an accurate condition
+ for end_range)
+ ut_ad(!dict_index_is_clust(prebuilt->index)
+ || templ->rec_field_no
+ < prebuilt->index->n_uniq);
+ */
}
-
- /* This field is not needed in the query, skip it */
-
- goto skip_field;
}
-include_field:
- n_requested_fields++;
- templ->col_no = innodb_idx;
- templ->clust_rec_field_no = dict_col_get_clust_pos(
- &index->table->cols[innodb_idx], clust_index);
- ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED);
+ ut_ad(prebuilt->idx_cond_n_cols > 0);
+ ut_ad(prebuilt->idx_cond_n_cols == prebuilt->n_template);
+
+ /* Include the fields that are not needed in index condition
+ pushdown. */
+ for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) {
+
+ while (!table->field[sql_idx]->stored_in_db) {
+ sql_idx++;
+ }
+
+ const ibool index_contains
+ = dict_index_contains_col_or_prefix(index, i);
+
+ if (index == prebuilt->index
+ ? !index_contains
+ : !dict_index_contains_col_or_prefix(
+ prebuilt->index, i)) {
+ /* Not needed in ICP */
+ const Field* field;
+
+ if (whole_row) {
+ field = table->field[sql_idx];
+ } else {
+ field = build_template_needs_field(
+ index_contains,
+ prebuilt->read_just_key,
+ fetch_all_in_key,
+ fetch_primary_key_cols,
+ index, table, i, sql_idx);
+ if (!field) {
+ continue;
+ }
+ }
- if (index == clust_index) {
- templ->rec_field_no = templ->clust_rec_field_no;
- } else {
- templ->rec_field_no = dict_index_get_nth_col_pos(
- index, innodb_idx);
- if (templ->rec_field_no == ULINT_UNDEFINED) {
- prebuilt->need_to_access_clustered = TRUE;
+ build_template_field(prebuilt,
+ clust_index, index,
+ table, field, i);
}
}
- if (field->null_ptr) {
- templ->mysql_null_byte_offset =
- (ulint) ((char*) field->null_ptr
- - (char*) table->record[0]);
-
- templ->mysql_null_bit_mask = (ulint) field->null_bit;
- } else {
- templ->mysql_null_bit_mask = 0;
- }
+ prebuilt->idx_cond = this;
+ } else {
+ /* No index condition pushdown */
+ prebuilt->idx_cond = NULL;
- templ->mysql_col_offset = (ulint)
- get_field_offset(table, field);
+ for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) {
+ const Field* field;
- templ->mysql_col_len = (ulint) field->pack_length();
- if (mysql_prefix_len < templ->mysql_col_offset
- + templ->mysql_col_len) {
- mysql_prefix_len = templ->mysql_col_offset
- + templ->mysql_col_len;
- }
- templ->type = index->table->cols[innodb_idx].mtype;
- templ->mysql_type = (ulint)field->type();
+ while (!table->field[sql_idx]->stored_in_db) {
+ sql_idx++;
+ }
- if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
- templ->mysql_length_bytes = (ulint)
- (((Field_varstring*)field)->length_bytes);
- }
+ if (whole_row) {
+ field = table->field[sql_idx];
+ } else {
+ field = build_template_needs_field(
+ dict_index_contains_col_or_prefix(
+ index, i),
+ prebuilt->read_just_key,
+ fetch_all_in_key,
+ fetch_primary_key_cols,
+ index, table, i, sql_idx);
+ if (!field) {
+ continue;
+ }
+ }
- templ->charset = dtype_get_charset_coll(
- index->table->cols[innodb_idx].prtype);
- templ->mbminlen = index->table->cols[innodb_idx].mbminlen;
- templ->mbmaxlen = index->table->cols[innodb_idx].mbmaxlen;
- templ->is_unsigned = index->table->cols[innodb_idx].prtype
- & DATA_UNSIGNED;
- if (templ->type == DATA_BLOB) {
- prebuilt->templ_contains_blob = TRUE;
+ build_template_field(prebuilt, clust_index, index,
+ table, field, i);
}
-skip_field:
- if (field->stored_in_db) {
- innodb_idx++;
- }
- }
-
- prebuilt->n_template = n_requested_fields;
- prebuilt->mysql_prefix_len = mysql_prefix_len;
+ }
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++) {
- templ = prebuilt->mysql_template + i;
-
+ for (i = 0; i < prebuilt->n_template; i++) {
+ mysql_row_templ_t* templ
+ = &prebuilt->mysql_template[i];
templ->rec_field_no = templ->clust_rec_field_no;
}
}
@@ -5299,7 +5579,7 @@ no_commit:
/* Altering to InnoDB format */
innobase_commit(ht, user_thd, 1);
/* Note that this transaction is still active. */
- prebuilt->trx->active_trans = 1;
+ prebuilt->trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
/* We will need an IX lock on the destination table. */
prebuilt->sql_stat_start = TRUE;
} else {
@@ -5315,7 +5595,7 @@ no_commit:
locks, so they have to be acquired again. */
innobase_commit(ht, user_thd, 1);
/* Note that this transaction is still active. */
- prebuilt->trx->active_trans = 1;
+ prebuilt->trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
/* Re-acquire the table lock on the source table. */
row_lock_table_for_mysql(prebuilt, src_table, mode);
/* We will need an IX lock on the destination table. */
@@ -5361,7 +5641,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(true);
}
innodb_srv_conc_enter_innodb(prebuilt->trx);
@@ -5442,7 +5722,7 @@ set_max_autoinc:
auto_inc = innobase_next_autoinc(
auto_inc,
- need, offset, col_max_value);
+ need, offset, col_max_value, 1);
err = innobase_set_max_autoinc(
auto_inc);
@@ -5713,7 +5993,7 @@ ha_innobase::update_row(
need = prebuilt->autoinc_increment;
auto_inc = innobase_next_autoinc(
- auto_inc, need, offset, col_max_value);
+ auto_inc, need, offset, col_max_value, 1);
error = innobase_set_max_autoinc(auto_inc);
}
@@ -5899,6 +6179,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);
}
@@ -6060,7 +6342,7 @@ ha_innobase::index_read(
necessarily prebuilt->index, but can also be the clustered index */
if (prebuilt->sql_stat_start) {
- build_template(prebuilt, user_thd, table, ROW_MYSQL_REC_FIELDS);
+ build_template(false);
}
if (key_ptr) {
@@ -6275,7 +6557,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(false);
DBUG_RETURN(0);
}
@@ -7954,7 +8236,6 @@ ha_innobase::records_in_range(
mem_heap_t* heap;
DBUG_ENTER("records_in_range");
- DBUG_ASSERT(min_key || max_key);
ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
@@ -8505,6 +8786,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;
@@ -8703,7 +8985,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(true);
}
if (prebuilt->table->ibd_file_missing) {
@@ -9195,7 +9477,7 @@ ha_innobase::extra(
}
break;
case HA_EXTRA_RESET_STATE:
- reset_template(prebuilt);
+ reset_template();
thd_to_trx(ha_thd())->duplicates = 0;
break;
case HA_EXTRA_NO_KEYREAD:
@@ -9241,7 +9523,8 @@ ha_innobase::reset()
row_mysql_prebuilt_free_blob_heap(prebuilt);
}
- reset_template(prebuilt);
+ reset_template();
+ ds_mrr.dsmrr_close();
/* TODO: This should really be reset in reset_template() but for now
it's safer to do it explicitly here. */
@@ -9291,7 +9574,7 @@ ha_innobase::start_stmt(
prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0;
- reset_template(prebuilt);
+ reset_template();
if (!prebuilt->mysql_has_locked) {
/* This handle is for a temporary table created inside
@@ -9326,10 +9609,10 @@ ha_innobase::start_stmt(
trx->detailed_error[0] = '\0';
/* Set the MySQL flag to mark that there is an active transaction */
- if (trx->active_trans == 0) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0) {
innobase_register_trx_and_stmt(ht, thd);
- trx->active_trans = 1;
+ trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
} else {
innobase_register_stmt(ht, thd);
}
@@ -9410,7 +9693,7 @@ ha_innobase::external_lock(
prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0;
- reset_template(prebuilt);
+ reset_template();
if (lock_type == F_WRLCK
|| (table->s->tmp_table
@@ -9435,10 +9718,10 @@ ha_innobase::external_lock(
/* Set the MySQL flag to mark that there is an active
transaction */
- if (trx->active_trans == 0) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0) {
innobase_register_trx_and_stmt(ht, thd);
- trx->active_trans = 1;
+ trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
} else if (trx->n_mysql_tables_in_use == 0) {
innobase_register_stmt(ht, thd);
}
@@ -9536,7 +9819,7 @@ ha_innobase::external_lock(
prebuilt->used_in_HANDLER = FALSE;
if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
- if (trx->active_trans != 0) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) != 0) {
innobase_commit(ht, thd, TRUE);
}
} else {
@@ -9601,7 +9884,7 @@ ha_innobase::transactional_table_lock(
prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0;
- reset_template(prebuilt);
+ reset_template();
if (lock_type == F_WRLCK) {
prebuilt->select_lock_type = LOCK_X;
@@ -9621,10 +9904,10 @@ ha_innobase::transactional_table_lock(
/* MySQL is setting a new transactional table lock */
/* Set the MySQL flag to mark that there is an active transaction */
- if (trx->active_trans == 0) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0) {
innobase_register_trx_and_stmt(ht, thd);
- trx->active_trans = 1;
+ trx->active_flag |= TRX_ACTIVE_IN_MYSQL;
}
if (THDVAR(thd, table_locks) && thd_in_lock_tables(thd)) {
@@ -10371,16 +10654,14 @@ ha_innobase::get_auto_increment(
/* With old style AUTOINC locking we only update the table's
AUTOINC counter after attempting to insert the row. */
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
- ulonglong need;
ulonglong current;
ulonglong next_value;
current = *first_value > col_max_value ? autoinc : *first_value;
- need = *nb_reserved_values * increment;
-
+
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
- current, need, offset, col_max_value);
+ current, increment, offset, col_max_value, *nb_reserved_values);
prebuilt->autoinc_last_value = next_value;
@@ -10682,10 +10963,11 @@ innobase_xa_prepare(
innobase_release_stat_resources(trx);
- if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) {
+ if ((trx->active_flag & TRX_ACTIVE_IN_MYSQL) == 0 &&
+ trx->conc_state != TRX_NOT_STARTED) {
- sql_print_error("trx->active_trans == 0, but trx->conc_state != "
- "TRX_NOT_STARTED");
+ sql_print_error("trx->active_flag & TRX_ACTIVE_IN_MYSQL == 0, but"
+ " trx->conc_state != TRX_NOT_STARTED");
}
if (all
@@ -10694,7 +10976,7 @@ innobase_xa_prepare(
/* We were instructed to prepare the whole transaction, or
this is an SQL statement end and autocommit is on */
- ut_ad(trx->active_trans);
+ ut_ad(trx->active_flag & TRX_ACTIVE_IN_MYSQL);
error = (int) trx_prepare_for_mysql(trx);
} else {
@@ -10718,36 +11000,6 @@ innobase_xa_prepare(
srv_active_wake_master_thread();
- if (thd_sql_command(thd) != SQLCOM_XA_PREPARE &&
- (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
- {
- if (srv_enable_unsafe_group_commit && !THDVAR(thd, support_xa)) {
- /* choose group commit rather than binlog order */
- return(error);
- }
-
- /* For ibbackup to work the order of transactions in binlog
- and InnoDB must be the same. Consider the situation
-
- thread1> prepare; write to binlog; ...
- <context switch>
- thread2> prepare; write to binlog; commit
- thread1> ... commit
-
- To ensure this will not happen we're taking the mutex on
- prepare, and releasing it on commit.
-
- Note: only do it for normal commits, done via ha_commit_trans.
- If 2pc protocol is executed by external transaction
- coordinator, it will be just a regular MySQL client
- executing XA PREPARE and XA COMMIT commands.
- In this case we cannot know how many minutes or hours
- will be between XA PREPARE and XA COMMIT, and we don't want
- to block for undefined period of time. */
- pthread_mutex_lock(&prepare_commit_mutex);
- trx->active_trans = 2;
- }
-
return(error);
}
@@ -12113,9 +12365,10 @@ static MYSQL_SYSVAR_ENUM(adaptive_checkpoint, srv_adaptive_checkpoint,
"Enable/Disable flushing along modified age. (none, reflex, [estimate], keep_average)",
NULL, innodb_adaptive_checkpoint_update, 2, &adaptive_checkpoint_typelib);
-static MYSQL_SYSVAR_ULONG(enable_unsafe_group_commit, srv_enable_unsafe_group_commit,
+static MYSQL_SYSVAR_ULONG(enable_unsafe_group_commit, srv_deprecated_enable_unsafe_group_commit,
PLUGIN_VAR_RQCMDARG,
- "Enable/Disable unsafe group commit when support_xa=OFF and use with binlog or other XA storage engine.",
+ "Enable/Disable unsafe group commit when support_xa=OFF and use with binlog or other XA storage engine. "
+ "(Deprecated, and does nothing, group commit is always enabled in a safe way)",
NULL, NULL, 0, 0, 1, 0);
static MYSQL_SYSVAR_ULONG(expand_import, srv_expand_import,
@@ -12489,3 +12742,92 @@ 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(range_id_t *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;
+}
+
+int ha_innobase::multi_range_read_explain_info(uint mrr_mode, char *str, size_t size)
+{
+ return ds_mrr.dsmrr_explain_info(mrr_mode, str, size);
+}
+
+/*
+ A helper function used only in index_cond_func_innodb
+*/
+
+bool ha_innobase::is_thd_killed()
+{
+ return thd_killed(user_thd);
+}
+
+/**
+ * Index Condition Pushdown interface implementation
+ */
+
+/** Attempt to push down an index condition.
+* @param[in] keyno MySQL key number
+* @param[in] idx_cond Index condition to be checked
+* @return idx_cond if pushed; NULL if not pushed
+*/
+UNIV_INTERN
+class Item*
+ha_innobase::idx_cond_push(
+ uint keyno,
+ class Item* idx_cond)
+{
+ DBUG_ENTER("ha_innobase::idx_cond_push");
+ DBUG_ASSERT(keyno != MAX_KEY);
+ DBUG_ASSERT(idx_cond != NULL);
+
+ pushed_idx_cond = idx_cond;
+ pushed_idx_cond_keyno = keyno;
+ in_range_check_pushed_down = TRUE;
+ /* Table handler will check the entire condition */
+ DBUG_RETURN(NULL);
+}
+
diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h
index d04fe24cf79..fea42c6c201 100644
--- a/storage/xtradb/handler/ha_innodb.h
+++ b/storage/xtradb/handler/ha_innodb.h
@@ -224,6 +224,83 @@ class ha_innobase: public handler
/** @} */
bool check_if_incompatible_data(HA_CREATE_INFO *info,
uint table_changes);
+ bool check_if_supported_virtual_columns(void) { return TRUE; }
+
+private:
+ /** Builds a 'template' to the prebuilt struct.
+
+ The template is used in fast retrieval of just those column
+ values MySQL needs in its processing.
+ @param whole_row true if access is needed to a whole row,
+ false if accessing individual fields is enough */
+ void build_template(bool whole_row);
+ /** Resets a query execution 'template'.
+ @see build_template() */
+ inline void reset_template();
+
+public:
+ /** @name Multi Range Read interface @{ */
+ /** Initialize multi range read @see DsMrr_impl::dsmrr_init
+ * @param seq
+ * @param seq_init_param
+ * @param n_ranges
+ * @param mode
+ * @param buf
+ */
+ int multi_range_read_init(RANGE_SEQ_IF* seq,
+ void* seq_init_param,
+ uint n_ranges, uint mode,
+ HANDLER_BUFFER *buf);
+ /** Process next multi range read @see DsMrr_impl::dsmrr_next
+ * @param range_info
+ */
+ int multi_range_read_next(range_id_t *range_info);
+ /** Initialize multi range read and get information.
+ * @see ha_myisam::multi_range_read_info_const
+ * @see DsMrr_impl::dsmrr_info_const
+ * @param keyno
+ * @param seq
+ * @param seq_init_param
+ * @param n_ranges
+ * @param bufsz
+ * @param flags
+ * @param cost
+ */
+ ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
+ void *seq_init_param,
+ uint n_ranges, uint *bufsz,
+ uint *flags, COST_VECT *cost);
+ /** Initialize multi range read and get information.
+ * @see DsMrr_impl::dsmrr_info
+ * @param keyno
+ * @param n_ranges
+ * @param keys
+ * @param key_parts
+ * @param bufsz
+ * @param flags
+ * @param cost
+ */
+ ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
+ uint *flags, COST_VECT *cost);
+ int multi_range_read_explain_info(uint mrr_mode,
+ char *str, size_t size);
+
+ /** Attempt to push down an index condition.
+ * @param[in] keyno MySQL key number
+ * @param[in] idx_cond Index condition to be checked
+ * @return idx_cond if pushed; NULL if not pushed
+ */
+ class Item* idx_cond_push(uint keyno, class Item* idx_cond);
+
+ /* An helper function for index_cond_func_innodb: */
+ bool is_thd_killed();
+
+private:
+ /** The multi range read session object */
+ DsMrr_impl ds_mrr;
+
+ /* @} */
};
/* Some accessor functions which the InnoDB plugin needs, but which
@@ -242,16 +319,6 @@ LEX_STRING *thd_query_string(MYSQL_THD thd);
char **thd_query(MYSQL_THD thd);
#endif
-/** Get the file name of the MySQL binlog.
- * @return the name of the binlog file
- */
-const char* mysql_bin_log_file_name(void);
-
-/** Get the current position of the MySQL binlog.
- * @return byte offset from the beginning of the binlog
- */
-ulonglong mysql_bin_log_file_pos(void);
-
/**
Check if a user thread is a replication slave thread
@param thd user thread
@@ -292,6 +359,11 @@ bool thd_binlog_filter_ok(const MYSQL_THD thd);
#endif /* MYSQL_VERSION_ID > 50140 */
}
+/** Get the file name and position of the MySQL binlog corresponding to the
+ * current commit.
+ */
+extern void mysql_bin_log_commit_pos(THD *thd, ulonglong *out_pos, const char **out_file);
+
typedef struct trx_struct trx_t;
/********************************************************************//**
@file handler/ha_innodb.h
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index ea6d3039c2d..34c60b2927b 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -256,7 +256,7 @@ field_store_time_t(
my_time.time_type = MYSQL_TIMESTAMP_DATETIME;
#endif
- return(field->store_time(&my_time, MYSQL_TIMESTAMP_DATETIME));
+ return(field->store_time(&my_time));
}
/*******************************************************************//**
diff --git a/storage/xtradb/include/db0err.h b/storage/xtradb/include/db0err.h
index e4a3844cd22..ad675bd0ec1 100644
--- a/storage/xtradb/include/db0err.h
+++ b/storage/xtradb/include/db0err.h
@@ -107,7 +107,8 @@ enum db_err {
DB_STRONG_FAIL,
DB_ZIP_OVERFLOW,
DB_RECORD_NOT_FOUND = 1500,
- DB_END_OF_INDEX
+ DB_END_OF_INDEX,
+ DB_SEARCH_ABORTED_BY_USER= 1533
};
#endif
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h
index be8bd20dba9..cd2886dbc80 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/include/dict0dict.h
@@ -832,13 +832,25 @@ dict_index_get_nth_col_no(
Looks for column n in an index.
@return position in internal representation of the index;
ULINT_UNDEFINED if not contained */
-UNIV_INTERN
+UNIV_INLINE
ulint
dict_index_get_nth_col_pos(
/*=======================*/
const dict_index_t* index, /*!< in: index */
ulint n); /*!< in: column number */
/********************************************************************//**
+Looks for column n in an index.
+@return position in internal representation of the index;
+ULINT_UNDEFINED if not contained */
+UNIV_INTERN
+ulint
+dict_index_get_nth_col_or_prefix_pos(
+/*=================================*/
+ const dict_index_t* index, /*!< in: index */
+ ulint n, /*!< in: column number */
+ ibool inc_prefix); /*!< in: TRUE=consider
+ column prefixes too */
+/********************************************************************//**
Returns TRUE if the index contains a column or a prefix of that column.
@return TRUE if contains the column or its prefix */
UNIV_INTERN
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index 1c1c3d7f202..3f16371cdc4 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -656,6 +656,20 @@ dict_index_get_nth_col_no(
return(dict_col_get_no(dict_index_get_nth_col(index, pos)));
}
+/********************************************************************//**
+Looks for column n in an index.
+@return position in internal representation of the index;
+ULINT_UNDEFINED if not contained */
+UNIV_INLINE
+ulint
+dict_index_get_nth_col_pos(
+/*=======================*/
+ const dict_index_t* index, /*!< in: index */
+ ulint n) /*!< in: column number */
+{
+ return(dict_index_get_nth_col_or_prefix_pos(index, n, FALSE));
+}
+
#ifndef UNIV_HOTBACKUP
/********************************************************************//**
Returns the minimum data size of an index record.
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index 445d94eeabb..df7d71af6cf 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -247,6 +247,14 @@ innobase_get_at_most_n_mbchars(
ulint data_len, /*!< in: length of the string in bytes */
const char* str); /*!< in: character string */
+/*************************************************************//**
+InnoDB index push-down condition check
+@return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */
+enum icp_result
+handler_index_cond_check(
+/*================*/
+ void* file) /*!< in/out: pointer to ha_innobase */
+ __attribute__((nonnull, warn_unused_result));
/******************************************************************//**
Returns true if the thread supports XA,
global value of innodb_supports_xa if thd is NULL.
diff --git a/storage/xtradb/include/log0log.h b/storage/xtradb/include/log0log.h
index 4ead88458a4..1b6434fb2a0 100644
--- a/storage/xtradb/include/log0log.h
+++ b/storage/xtradb/include/log0log.h
@@ -252,12 +252,15 @@ log_checkpoint(
/*===========*/
ibool sync, /*!< in: TRUE if synchronous operation is
desired */
- ibool write_always); /*!< in: the function normally checks if the
+ ibool write_always, /*!< in: the function normally checks if the
the new checkpoint would have a greater
lsn than the previous one: if not, then no
physical write is done; by setting this
parameter TRUE, a physical write will always be
made to log files */
+ ibool safe_to_ignore);/*!< in: TRUE if checkpoint can be ignored in
+ the case checkpoint's are disabled */
+
/****************************************************************//**
Makes a checkpoint at a given lsn or later. */
UNIV_INTERN
@@ -275,6 +278,18 @@ log_make_checkpoint_at(
physical write will always be made to
log files */
/****************************************************************//**
+Disable checkpoints. This is used when doing a volume snapshot
+to ensure that we don't get checkpoint between snapshoting two
+different volumes */
+UNIV_INTERN
+ibool log_disable_checkpoint();
+
+/****************************************************************//**
+Enable checkpoints that was disabled with log_disable_checkpoint() */
+UNIV_INTERN
+void log_enable_checkpoint();
+
+/****************************************************************//**
Makes a checkpoint at the latest lsn and writes it to first page of each
data file in the database, so that we know that the file spaces contain
all modifications up to that lsn. This can only be called at database
diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h
index bc3a54192d5..d4c70cfd5e3 100644
--- a/storage/xtradb/include/os0file.h
+++ b/storage/xtradb/include/os0file.h
@@ -152,8 +152,8 @@ log. */
#define OS_FILE_LOG 256 /* This can be ORed to type */
/* @} */
-#define OS_AIO_N_PENDING_IOS_PER_THREAD 32 /*!< Win NT does not allow more
- than 64 */
+#define OS_AIO_N_PENDING_IOS_PER_THREAD 256 /*!< Windows might be able to handle
+more */
/** Modes for aio operations @{ */
#define OS_AIO_NORMAL 21 /*!< Normal asynchronous i/o not for ibuf
@@ -183,6 +183,10 @@ log. */
#define OS_WIN95 2 /*!< Microsoft Windows 95 */
#define OS_WINNT 3 /*!< Microsoft Windows NT 3.x */
#define OS_WIN2000 4 /*!< Microsoft Windows 2000 */
+#define OS_WINXP 5 /*!< Microsoft Windows XP */
+#define OS_WINVISTA 6 /*!< Microsoft Windows Vista */
+#define OS_WIN7 7 /*!< Microsoft Windows 7 */
+
extern ulint os_n_file_reads;
extern ulint os_n_file_writes;
diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h
index 6732fa52b29..c6f2c4d1e30 100644
--- a/storage/xtradb/include/os0sync.h
+++ b/storage/xtradb/include/os0sync.h
@@ -37,29 +37,19 @@ Created 9/6/1995 Heikki Tuuri
#include "univ.i"
#include "ut0lst.h"
-#ifdef __WIN__
-
+#ifdef _WIN32
+/** Native event (slow)*/
+typedef HANDLE os_native_event_t;
/** Native mutex */
-#define os_fast_mutex_t CRITICAL_SECTION
-
-/** Native event */
-typedef HANDLE os_native_event_t;
-
-/** Operating system event */
-typedef struct os_event_struct os_event_struct_t;
-/** Operating system event handle */
-typedef os_event_struct_t* os_event_t;
-
-/** An asynchronous signal sent between threads */
-struct os_event_struct {
- os_native_event_t handle;
- /*!< Windows event */
- UT_LIST_NODE_T(os_event_struct_t) os_event_list;
- /*!< list of all created events */
-};
+typedef CRITICAL_SECTION os_fast_mutex_t;
+/** Native condition variable */
+typedef CONDITION_VARIABLE os_cond_t;
#else
/** Native mutex */
typedef pthread_mutex_t os_fast_mutex_t;
+/** Native condition variable */
+typedef pthread_cond_t os_cond_t;
+#endif
/** Operating system event */
typedef struct os_event_struct os_event_struct_t;
@@ -68,6 +58,9 @@ typedef os_event_struct_t* os_event_t;
/** An asynchronous signal sent between threads */
struct os_event_struct {
+#ifdef _WIN32
+ HANDLE handle; /*!< kernel event object, slow, used on older Windows */
+#endif
os_fast_mutex_t os_mutex; /*!< this mutex protects the next
fields */
ibool is_set; /*!< this is TRUE when the event is
@@ -76,12 +69,14 @@ struct os_event_struct {
this event */
ib_int64_t signal_count; /*!< this is incremented each time
the event becomes signaled */
- pthread_cond_t cond_var; /*!< condition variable is used in
+ os_cond_t cond_var; /*!< condition variable is used in
waiting for the event */
UT_LIST_NODE_T(os_event_struct_t) os_event_list;
/*!< list of all created events */
};
-#endif
+
+
+
/** Operating system mutex */
typedef struct os_mutex_struct os_mutex_str_t;
@@ -186,33 +181,23 @@ os_event_wait_low(
os_event_reset(). */
#define os_event_wait(event) os_event_wait_low(event, 0)
-
+#define os_event_wait_time(event, t) os_event_wait_time_low(event, t, 0)
/**********************************************************//**
Waits for an event object until it is in the signaled state or
-a timeout is exceeded.
+a timeout is exceeded. In Unix the timeout is always infinite.
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
UNIV_INTERN
ulint
-os_event_wait_time(
-/*===============*/
- os_event_t event, /*!< in: event to wait */
- ulint wtime); /*!< in: timeout in microseconds, or
- OS_SYNC_INFINITE_TIME */
-#ifdef __WIN__
-/**********************************************************//**
-Waits for any event in an OS native event array. Returns if even a single
-one is signaled or becomes signaled.
-@return index of the event which was signaled */
-UNIV_INTERN
-ulint
-os_event_wait_multiple(
+os_event_wait_time_low(
/*===================*/
- ulint n, /*!< in: number of events in the
- array */
- os_native_event_t* native_event_array);
- /*!< in: pointer to an array of event
- handles */
-#endif
+ os_event_t event, /*!< in: event to wait */
+ ulint time_in_usec, /*!< in: timeout in
+ microseconds, or
+ OS_SYNC_INFINITE_TIME */
+ ib_int64_t reset_sig_count); /*!< in: zero or the value
+ returned by previous call of
+ os_event_reset(). */
+
/*********************************************************//**
Creates an operating system mutex semaphore. Because these are slow, the
mutex semaphore of InnoDB itself (mutex_t) should be used where possible.
@@ -396,7 +381,7 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */
# define os_atomic_test_and_set_byte(ptr, new_val) \
atomic_swap_uchar(ptr, new_val)
-#elif defined(HAVE_WINDOWS_ATOMICS)
+#elif defined(_WIN32)
# define HAVE_ATOMIC_BUILTINS
diff --git a/storage/xtradb/include/os0sync.ic b/storage/xtradb/include/os0sync.ic
index 1f3ce38fa65..2c6c1dbe629 100644
--- a/storage/xtradb/include/os0sync.ic
+++ b/storage/xtradb/include/os0sync.ic
@@ -28,8 +28,7 @@ Created 9/6/1995 Heikki Tuuri
#endif
/**********************************************************//**
-Acquires ownership of a fast mutex. Currently in Windows this is the same
-as os_fast_mutex_lock!
+Acquires ownership of a fast mutex.
@return 0 if success, != 0 if was reserved by another thread */
UNIV_INLINE
ulint
@@ -38,9 +37,9 @@ os_fast_mutex_trylock(
os_fast_mutex_t* fast_mutex) /*!< in: mutex to acquire */
{
#ifdef __WIN__
- EnterCriticalSection(fast_mutex);
-
- return(0);
+ if (TryEnterCriticalSection(fast_mutex))
+ return 0;
+ return(1);
#else
/* NOTE that the MySQL my_pthread.h redefines pthread_mutex_trylock
so that it returns 0 on success. In the operating system
diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h
index 4acfd2e793b..b18e1fca5dc 100644
--- a/storage/xtradb/include/row0mysql.h
+++ b/storage/xtradb/include/row0mysql.h
@@ -547,6 +547,10 @@ struct mysql_row_templ_struct {
Innobase record in the clustered index;
not defined if template_type is
ROW_MYSQL_WHOLE_ROW */
+ ulint icp_rec_field_no; /*!< field number of the column in an
+ Innobase record in the current index;
+ not defined unless
+ index condition pushdown is used */
ulint mysql_col_offset; /*!< offset of the column in the MySQL
row format */
ulint mysql_col_len; /*!< length of the column in the MySQL
@@ -586,6 +590,7 @@ struct mysql_row_templ_struct {
#define ROW_PREBUILT_FREED 26423527
/** 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 {
@@ -781,6 +786,13 @@ struct row_prebuilt_struct {
store it here so that we can return
it to MySQL */
/*----------------------*/
+ void* idx_cond; /*!< In ICP, pointer to a ha_innobase,
+ passed to innobase_index_cond().
+ NULL if index condition pushdown is
+ not used. */
+ ulint idx_cond_n_cols;/*!< Number of fields in idx_cond_cols.
+ 0 if and only if idx_cond == NULL. */
+ /*----------------------*/
ulint magic_n2; /*!< this should be the same as
magic_n */
};
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index a144b1fdb67..3a0176a6452 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -120,7 +120,9 @@ extern ulint srv_check_file_format_at_startup;
on duplicate key checking and foreign key checking */
extern ibool srv_locks_unsafe_for_binlog;
#endif /* !UNIV_HOTBACKUP */
-
+#ifdef __WIN__
+extern ibool srv_use_native_conditions;
+#endif
extern ulint srv_n_data_files;
extern char** srv_data_file_names;
extern ulint* srv_data_file_sizes;
@@ -247,7 +249,7 @@ extern ulong srv_ibuf_active_contract;
extern ulong srv_ibuf_accel_rate;
extern ulint srv_checkpoint_age_target;
extern ulong srv_flush_neighbor_pages;
-extern ulong srv_enable_unsafe_group_commit;
+extern ulong srv_deprecated_enable_unsafe_group_commit;
extern ulong srv_read_ahead;
extern ulong srv_adaptive_checkpoint;
diff --git a/storage/xtradb/include/sync0sync.h b/storage/xtradb/include/sync0sync.h
index bb3c21f40f5..c8738bc9bea 100644
--- a/storage/xtradb/include/sync0sync.h
+++ b/storage/xtradb/include/sync0sync.h
@@ -45,7 +45,7 @@ Created 9/5/1995 Heikki Tuuri
extern my_bool timed_mutexes;
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
-#ifdef HAVE_WINDOWS_ATOMICS
+#ifdef _WIN32
typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates
on LONG variable */
#else
diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h
index 700476bcd85..6a9fc324ff9 100644
--- a/storage/xtradb/include/trx0trx.h
+++ b/storage/xtradb/include/trx0trx.h
@@ -523,9 +523,10 @@ struct trx_struct{
in that case we must flush the log
in trx_commit_complete_for_mysql() */
ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */
- ulint active_trans; /*!< 1 - if a transaction in MySQL
- is active. 2 - if prepare_commit_mutex
- was taken */
+ ulint active_flag; /*!< TRX_ACTIVE_IN_MYSQL - set if a
+ transaction in MySQL is active.
+ TRX_ACTIVE_COMMIT_ORDERED - set if
+ innobase_commit_ordered has run */
ulint has_search_latch;
/* TRUE if this trx has latched the
search system latch in S-mode */
@@ -838,6 +839,10 @@ Multiple flags can be combined with bitwise OR. */
#define TRX_SIG_OTHER_SESS 1 /* sent by another session (which
must hold rights to this) */
+/* Flag bits for trx_struct.active_flag */
+#define TRX_ACTIVE_IN_MYSQL (1<<0)
+#define TRX_ACTIVE_COMMIT_ORDERED (1<<1)
+
/** Commit node states */
enum commit_node_state {
COMMIT_NODE_SEND = 1, /*!< about to send a commit signal to
diff --git a/storage/xtradb/log/log0log.c b/storage/xtradb/log/log0log.c
index 9c02113dc20..0b5254f4d0b 100644
--- a/storage/xtradb/log/log0log.c
+++ b/storage/xtradb/log/log0log.c
@@ -97,6 +97,8 @@ archive */
UNIV_INTERN byte log_archive_io;
#endif /* UNIV_LOG_ARCHIVE */
+UNIV_INTERN ulint log_disable_checkpoint_active= 0;
+
/* A margin for free space in the log buffer before a log entry is catenated */
#define LOG_BUF_WRITE_MARGIN (4 * OS_FILE_LOG_BLOCK_SIZE)
@@ -174,7 +176,7 @@ log_fsp_current_free_limit_set_and_checkpoint(
success = FALSE;
while (!success) {
- success = log_checkpoint(TRUE, TRUE);
+ success = log_checkpoint(TRUE, TRUE, FALSE);
}
}
@@ -2070,12 +2072,14 @@ log_checkpoint(
/*===========*/
ibool sync, /*!< in: TRUE if synchronous operation is
desired */
- ibool write_always) /*!< in: the function normally checks if the
+ ibool write_always, /*!< in: the function normally checks if the
the new checkpoint would have a greater
lsn than the previous one: if not, then no
physical write is done; by setting this
parameter TRUE, a physical write will always be
made to log files */
+ ibool safe_to_ignore) /*!< in: TRUE if checkpoint can be ignored in
+ the case checkpoint's are disabled */
{
ib_uint64_t oldest_lsn;
@@ -2106,14 +2110,27 @@ log_checkpoint(
mutex_enter(&(log_sys->mutex));
+ /* Return if this is not a forced checkpoint and either there is no
+ need for a checkpoint or if checkpoints are disabled */
if (!write_always
- && log_sys->last_checkpoint_lsn >= oldest_lsn) {
+ && (log_sys->last_checkpoint_lsn >= oldest_lsn ||
+ (safe_to_ignore && log_disable_checkpoint_active)))
+ {
mutex_exit(&(log_sys->mutex));
return(TRUE);
}
+ if (log_disable_checkpoint_active)
+ {
+ /* Wait until we are allowed to do a checkpoint */
+ mutex_exit(&(log_sys->mutex));
+ rw_lock_s_lock(&(log_sys->checkpoint_lock));
+ rw_lock_s_unlock(&(log_sys->checkpoint_lock));
+ mutex_enter(&(log_sys->mutex));
+ }
+
ut_ad(log_sys->flushed_to_disk_lsn >= oldest_lsn);
if (log_sys->n_pending_checkpoint_writes > 0) {
@@ -2174,7 +2191,73 @@ log_make_checkpoint_at(
while (!log_preflush_pool_modified_pages(lsn, TRUE));
- while (!log_checkpoint(TRUE, write_always));
+ while (!log_checkpoint(TRUE, write_always, FALSE));
+}
+
+/****************************************************************//**
+Disable checkpoints. This is used when doing a volumne snapshot
+to ensure that we don't get checkpoint between snapshoting two
+different volumes */
+
+UNIV_INTERN
+ibool log_disable_checkpoint()
+{
+ mutex_enter(&(log_sys->mutex));
+
+ /*
+ Wait if a checkpoint write is running.
+ This is the same code that is used in log_checkpoint() to ensure
+ that two checkpoints are not happening at the same time.
+ */
+ while (log_sys->n_pending_checkpoint_writes > 0)
+ {
+ mutex_exit(&(log_sys->mutex));
+ rw_lock_s_lock(&(log_sys->checkpoint_lock));
+ rw_lock_s_unlock(&(log_sys->checkpoint_lock));
+ mutex_enter(&(log_sys->mutex));
+ }
+ /*
+ The following should never be true; It's is here just in case of
+ wrong usage of this function. (Better safe than sorry).
+ */
+
+ if (log_disable_checkpoint_active)
+ {
+ mutex_exit(&(log_sys->mutex));
+ return 1; /* Already disabled */
+ }
+ /*
+ Take the checkpoint lock to ensure we will not get any checkpoints
+ running
+ */
+ rw_lock_x_lock_gen(&(log_sys->checkpoint_lock), LOG_CHECKPOINT);
+ log_disable_checkpoint_active= 1;
+ mutex_exit(&(log_sys->mutex));
+ return 0;
+}
+
+
+/****************************************************************//**
+Enable checkpoints that was disabled with log_disable_checkpoint()
+This lock is called by MariaDB and only when we have done call earlier
+to log_disable_checkpoint().
+
+Note: We can't take a log->mutex lock here running log_checkpoint()
+which is waiting (log_sys->checkpoint_lock may already have it.
+This is however safe to do without a mutex as log_disable_checkpoint
+is protected by log_sys->checkpoint_lock.
+*/
+
+UNIV_INTERN
+void log_enable_checkpoint()
+{
+ ut_ad(log_disable_checkpoint_active);
+ /* Test variable, mostly to protect against wrong usage */
+ if (log_disable_checkpoint_active)
+ {
+ log_disable_checkpoint_active= 0;
+ rw_lock_x_unlock_gen(&(log_sys->checkpoint_lock), LOG_CHECKPOINT);
+ }
}
/****************************************************************//**
@@ -2271,7 +2354,7 @@ loop:
}
if (do_checkpoint) {
- log_checkpoint(checkpoint_sync, FALSE);
+ log_checkpoint(checkpoint_sync, FALSE, FALSE);
if (checkpoint_sync) {
@@ -3191,6 +3274,10 @@ logs_empty_and_mark_files_at_shutdown(void)
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Starting shutdown...\n");
}
+
+ /* Enable checkpoints if someone had turned them off */
+ log_enable_checkpoint();
+
/* Wait until the master thread and all other operations are idle: our
algorithm only works if the server is idle at shutdown */
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index 2fde176a93c..ae7a35005e5 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -53,6 +53,10 @@ Created 10/21/1995 Heikki Tuuri
# endif /* __WIN__ */
#endif /* !UNIV_HOTBACKUP */
+#ifdef _WIN32
+#define IOCP_SHUTDOWN_KEY (ULONG_PTR)-1
+#endif
+
/* This specifies the file permissions InnoDB uses when it creates files in
Unix; the value of os_innodb_umask is initialized in ha_innodb.cc to
my_umask */
@@ -121,6 +125,12 @@ typedef struct os_aio_slot_struct os_aio_slot_t;
/** The asynchronous i/o array slot structure */
struct os_aio_slot_struct{
+#ifdef WIN_ASYNC_IO
+ OVERLAPPED control; /*!< Windows control block for the
+ aio request, MUST be first element in the structure*/
+ void *arr; /*!< Array this slot belongs to*/
+#endif
+
ibool is_read; /*!< TRUE if a read operation */
ulint pos; /*!< index of the slot in the aio
array */
@@ -148,12 +158,6 @@ struct os_aio_slot_struct{
and which can be used to identify
which pending aio operation was
completed */
-#ifdef WIN_ASYNC_IO
- os_event_t event; /*!< event object we need in the
- OVERLAPPED struct */
- OVERLAPPED control; /*!< Windows control block for the
- aio request */
-#endif
};
/** The asynchronous i/o array structure */
@@ -182,15 +186,6 @@ struct os_aio_array_struct{
/*!< Number of reserved slots in the
aio array outside the ibuf segment */
os_aio_slot_t* slots; /*!< Pointer to the slots in the array */
-#ifdef __WIN__
- os_native_event_t* native_events;
- /*!< Pointer to an array of OS native
- event handles where we copied the
- handles from slots, in the same
- order. This can be used in
- WaitForMultipleObjects; used only in
- Windows */
-#endif
};
/** Array of events used in simulated aio */
@@ -250,6 +245,16 @@ UNIV_INTERN ulint os_n_pending_writes = 0;
/** Number of pending read operations */
UNIV_INTERN ulint os_n_pending_reads = 0;
+
+#ifdef _WIN32
+/** IO completion port used by background io threads */
+static HANDLE completion_port;
+/** IO completion port used by background io READ threads */
+static HANDLE read_completion_port;
+/** Thread local storage index for the per-thread event used for synchronous IO */
+static DWORD tls_sync_io = TLS_OUT_OF_INDEXES;
+#endif
+
/***********************************************************************//**
Gets the operating system version. Currently works only on Windows.
@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000 */
@@ -270,10 +275,16 @@ os_get_os_version(void)
} else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
return(OS_WIN95);
} else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- if (os_info.dwMajorVersion <= 4) {
- return(OS_WINNT);
- } else {
- return(OS_WIN2000);
+ switch(os_info.dwMajorVersion){
+ case 3:
+ case 4:
+ return OS_WINNT;
+ case 5:
+ return (os_info.dwMinorVersion == 0)?OS_WIN2000 : OS_WINXP;
+ case 6:
+ return (os_info.dwMinorVersion == 0)?OS_WINVISTA : OS_WIN7;
+ default:
+ return OS_WIN7;
}
} else {
ut_error;
@@ -286,6 +297,86 @@ os_get_os_version(void)
#endif
}
+
+#ifdef _WIN32
+/*
+Windows : Handling synchronous IO on files opened asynchronously.
+
+If file is opened for asynchronous IO (FILE_FLAG_OVERLAPPED) and also bound to
+a completion port, then every IO on this file would normally be enqueued to the
+completion port. Sometimes however we would like to do a synchronous IO. This is
+possible if we initialitze have overlapped.hEvent with a valid event and set its
+lowest order bit to 1 (see MSDN ReadFile and WriteFile description for more info)
+
+We'll create this special event once for each thread and store in thread local
+storage.
+*/
+
+
+/***********************************************************************//**
+Initialize tls index.for event handle used for synchronized IO on files that
+might be opened with FILE_FLAG_OVERLAPPED.
+*/
+static void win_init_syncio_event()
+{
+ tls_sync_io = TlsAlloc();
+ ut_a(tls_sync_io != TLS_OUT_OF_INDEXES);
+}
+
+/***********************************************************************//**
+Retrieve per-thread event for doing synchronous io on asyncronously opened files
+*/
+static HANDLE win_get_syncio_event()
+{
+ HANDLE h;
+ if(tls_sync_io == TLS_OUT_OF_INDEXES){
+ win_init_syncio_event();
+ }
+
+ h = (HANDLE)TlsGetValue(tls_sync_io);
+ if (h)
+ return h;
+ h = CreateEventA(NULL, FALSE, FALSE, NULL);
+ ut_a(h);
+ h = (HANDLE)((uintptr_t)h | 1);
+ TlsSetValue(tls_sync_io, h);
+ return h;
+}
+
+/*
+ TLS destructor, inspired by Chromium code
+ http://src.chromium.org/svn/trunk/src/base/threading/thread_local_storage_win.cc
+*/
+
+static void win_free_syncio_event()
+{
+ HANDLE h = win_get_syncio_event();
+ if (h) {
+ CloseHandle(h);
+ }
+}
+
+static void NTAPI win_tls_thread_exit(PVOID module, DWORD reason, PVOID reserved) {
+ if (DLL_THREAD_DETACH == reason || DLL_PROCESS_DETACH == reason)
+ win_free_syncio_event();
+}
+
+#ifdef _WIN64
+#pragma comment(linker, "/INCLUDE:_tls_used")
+#pragma comment(linker, "/INCLUDE:p_thread_callback_base")
+#pragma const_seg(".CRT$XLB")
+extern const PIMAGE_TLS_CALLBACK p_thread_callback_base;
+const PIMAGE_TLS_CALLBACK p_thread_callback_base = win_tls_thread_exit;
+#pragma data_seg()
+#else
+#pragma comment(linker, "/INCLUDE:__tls_used")
+#pragma comment(linker, "/INCLUDE:_p_thread_callback_base")
+#pragma data_seg(".CRT$XLB")
+PIMAGE_TLS_CALLBACK p_thread_callback_base = win_tls_thread_exit;
+#pragma data_seg()
+#endif
+#endif /*_WIN32 */
+
/***********************************************************************//**
Retrieves the last error number if an error occurs in a file io function.
The number should be retrieved before any other OS calls (because they may
@@ -611,6 +702,9 @@ os_io_init_simple(void)
for (i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) {
os_file_seek_mutexes[i] = os_mutex_create(NULL);
}
+#ifdef _WIN32
+ win_init_syncio_event();
+#endif
}
/***********************************************************************//**
@@ -1358,6 +1452,16 @@ try_again:
ut_error;
}
+ if (type == OS_LOG_FILE) {
+ if (srv_unix_file_flush_method == SRV_UNIX_O_DSYNC) {
+ /* Map O_DSYNC to WRITE_THROUGH */
+ attributes |= FILE_FLAG_WRITE_THROUGH;
+ } else if (srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT) {
+ /* Open log file without buffering */
+ attributes |= FILE_FLAG_NO_BUFFERING;
+ }
+ }
+
file = CreateFile((LPCTSTR) name,
GENERIC_READ | GENERIC_WRITE, /* read and write
access */
@@ -1402,6 +1506,9 @@ try_again:
}
} else {
*success = TRUE;
+ if (os_aio_use_native_aio && ((attributes & FILE_FLAG_OVERLAPPED) != 0)) {
+ ut_a(CreateIoCompletionPort(file, completion_port, 0, 0));
+ }
}
return(file);
@@ -2428,13 +2535,9 @@ _os_file_read(
#ifdef __WIN__
BOOL ret;
DWORD len;
- DWORD ret2;
- DWORD low;
- DWORD high;
ibool retry;
-#ifndef UNIV_HOTBACKUP
- ulint i;
-#endif /* !UNIV_HOTBACKUP */
+ OVERLAPPED overlapped;
+
/* On 64-bit Windows, ulint is 64 bits. But offset and n should be
no more than 32 bits. */
@@ -2449,41 +2552,21 @@ try_again:
ut_ad(buf);
ut_ad(n > 0);
- low = (DWORD) offset;
- high = (DWORD) offset_high;
-
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
-#ifndef UNIV_HOTBACKUP
- /* Protect the seek / read operation with a mutex */
- i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
- os_mutex_enter(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
- ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
-
- if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
-
-#ifndef UNIV_HOTBACKUP
- os_mutex_exit(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- os_mutex_exit(os_file_count_mutex);
-
- goto error_handling;
+ memset (&overlapped, 0, sizeof (overlapped));
+ overlapped.Offset = (DWORD)offset;
+ overlapped.OffsetHigh = (DWORD)offset_high;
+ overlapped.hEvent = win_get_syncio_event();
+ ret = ReadFile(file, buf, n, NULL, &overlapped);
+ if (ret) {
+ ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, FALSE);
}
-
- ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
-
-#ifndef UNIV_HOTBACKUP
- os_mutex_exit(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
+ else if(GetLastError() == ERROR_IO_PENDING) {
+ ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE);
+ }
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
@@ -2511,9 +2594,6 @@ try_again:
(ulong)n, (ulong)offset_high,
(ulong)offset, (long)ret);
#endif /* __WIN__ */
-#ifdef __WIN__
-error_handling:
-#endif
retry = os_file_handle_error(NULL, "read");
if (retry) {
@@ -2555,13 +2635,11 @@ os_file_read_no_error_handling(
#ifdef __WIN__
BOOL ret;
DWORD len;
- DWORD ret2;
- DWORD low;
- DWORD high;
ibool retry;
-#ifndef UNIV_HOTBACKUP
- ulint i;
-#endif /* !UNIV_HOTBACKUP */
+ OVERLAPPED overlapped;
+ overlapped.Offset = (DWORD)offset;
+ overlapped.OffsetHigh = (DWORD)offset_high;
+
/* On 64-bit Windows, ulint is 64 bits. But offset and n should be
no more than 32 bits. */
@@ -2576,41 +2654,21 @@ try_again:
ut_ad(buf);
ut_ad(n > 0);
- low = (DWORD) offset;
- high = (DWORD) offset_high;
-
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
-#ifndef UNIV_HOTBACKUP
- /* Protect the seek / read operation with a mutex */
- i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
- os_mutex_enter(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
- ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
-
- if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
-
-#ifndef UNIV_HOTBACKUP
- os_mutex_exit(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- os_mutex_exit(os_file_count_mutex);
-
- goto error_handling;
+ memset (&overlapped, 0, sizeof (overlapped));
+ overlapped.Offset = (DWORD)offset;
+ overlapped.OffsetHigh = (DWORD)offset_high;
+ overlapped.hEvent = win_get_syncio_event();
+ ret = ReadFile(file, buf, n, NULL, &overlapped);
+ if (ret) {
+ ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, FALSE);
}
-
- ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
-
-#ifndef UNIV_HOTBACKUP
- os_mutex_exit(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
+ else if(GetLastError() == ERROR_IO_PENDING) {
+ ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE);
+ }
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
@@ -2632,9 +2690,6 @@ try_again:
return(TRUE);
}
#endif /* __WIN__ */
-#ifdef __WIN__
-error_handling:
-#endif
retry = os_file_handle_error_no_exit(NULL, "read");
if (retry) {
@@ -2687,14 +2742,9 @@ os_file_write(
#ifdef __WIN__
BOOL ret;
DWORD len;
- DWORD ret2;
- DWORD low;
- DWORD high;
ulint n_retries = 0;
ulint err;
-#ifndef UNIV_HOTBACKUP
- ulint i;
-#endif /* !UNIV_HOTBACKUP */
+ OVERLAPPED overlapped;
/* On 64-bit Windows, ulint is 64 bits. But offset and n should be
no more than 32 bits. */
@@ -2707,64 +2757,23 @@ os_file_write(
ut_ad(buf);
ut_ad(n > 0);
retry:
- low = (DWORD) offset;
- high = (DWORD) offset_high;
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
-#ifndef UNIV_HOTBACKUP
- /* Protect the seek / write operation with a mutex */
- i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
- os_mutex_enter(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
- ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
-
- if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
-
-#ifndef UNIV_HOTBACKUP
- os_mutex_exit(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
+ memset (&overlapped, 0, sizeof (overlapped));
+ overlapped.Offset = (DWORD)offset;
+ overlapped.OffsetHigh = (DWORD)offset_high;
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes--;
- os_mutex_exit(os_file_count_mutex);
-
- ut_print_timestamp(stderr);
-
- fprintf(stderr,
- " InnoDB: Error: File pointer positioning to"
- " file %s failed at\n"
- "InnoDB: offset %lu %lu. Operating system"
- " error number %lu.\n"
- "InnoDB: Some operating system error numbers"
- " are described at\n"
- "InnoDB: "
- REFMAN "operating-system-error-codes.html\n",
- name, (ulong) offset_high, (ulong) offset,
- (ulong) GetLastError());
-
- return(FALSE);
+ overlapped.hEvent = win_get_syncio_event();
+ ret = WriteFile(file, buf, n, NULL, &overlapped);
+ if (ret) {
+ ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, FALSE);
}
-
- ret = WriteFile(file, buf, (DWORD) n, &len, NULL);
-
- /* Always do fsync to reduce the probability that when the OS crashes,
- a database page is only partially physically written to disk. */
-
-# ifdef UNIV_DO_FLUSH
- if (!os_do_not_call_flush_at_each_write) {
- ut_a(TRUE == os_file_flush(file, TRUE));
+ else if(GetLastError() == ERROR_IO_PENDING) {
+ ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE);
}
-# endif /* UNIV_DO_FLUSH */
-
-#ifndef UNIV_HOTBACKUP
- os_mutex_exit(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes--;
os_mutex_exit(os_file_count_mutex);
@@ -3149,9 +3158,6 @@ os_aio_array_create(
os_aio_array_t* array;
ulint i;
os_aio_slot_t* slot;
-#ifdef WIN_ASYNC_IO
- OVERLAPPED* over;
-#endif
ut_a(n > 0);
ut_a(n_segments > 0);
@@ -3167,23 +3173,12 @@ os_aio_array_create(
array->n_segments = n_segments;
array->n_reserved = 0;
array->slots = ut_malloc(n * sizeof(os_aio_slot_t));
-#ifdef __WIN__
- array->native_events = ut_malloc(n * sizeof(os_native_event_t));
-#endif
+
for (i = 0; i < n; i++) {
slot = os_aio_array_get_nth_slot(array, i);
-
slot->pos = i;
slot->reserved = FALSE;
-#ifdef WIN_ASYNC_IO
- slot->event = os_event_create(NULL);
- over = &(slot->control);
-
- over->hEvent = slot->event->handle;
-
- *((array->native_events) + i) = over->hEvent;
-#endif
}
return(array);
@@ -3197,18 +3192,7 @@ os_aio_array_free(
/*==============*/
os_aio_array_t* array) /*!< in, own: array to free */
{
-#ifdef WIN_ASYNC_IO
- ulint i;
- for (i = 0; i < array->n_slots; i++) {
- os_aio_slot_t* slot = os_aio_array_get_nth_slot(array, i);
- os_event_free(slot->event);
- }
-#endif /* WIN_ASYNC_IO */
-
-#ifdef __WIN__
- ut_free(array->native_events);
-#endif /* __WIN__ */
os_mutex_free(array->mutex);
os_event_free(array->not_full);
os_event_free(array->is_empty);
@@ -3287,7 +3271,12 @@ os_aio_init(
}
os_last_printout = time(NULL);
-
+#ifdef _WIN32
+ ut_a(completion_port == 0 && read_completion_port == 0);
+ completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
+ read_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
+ ut_a(completion_port && read_completion_port);
+#endif
}
/***********************************************************************
@@ -3329,11 +3318,10 @@ os_aio_array_wake_win_aio_at_shutdown(
/*==================================*/
os_aio_array_t* array) /*!< in: aio array */
{
- ulint i;
-
- for (i = 0; i < array->n_slots; i++) {
-
- os_event_set((array->slots + i)->event);
+ if(completion_port)
+ {
+ PostQueuedCompletionStatus(completion_port, 0, IOCP_SHUTDOWN_KEY, NULL);
+ PostQueuedCompletionStatus(read_completion_port, 0, IOCP_SHUTDOWN_KEY, NULL);
}
}
#endif
@@ -3558,7 +3546,8 @@ found:
control = &(slot->control);
control->Offset = (DWORD)offset;
control->OffsetHigh = (DWORD)offset_high;
- os_event_reset(slot->event);
+ control->hEvent = 0;
+ slot->arr = array;
#endif
os_mutex_exit(array->mutex);
@@ -3595,9 +3584,6 @@ os_aio_array_free_slot(
os_event_set(array->is_empty);
}
-#ifdef WIN_ASYNC_IO
- os_event_reset(slot->event);
-#endif
os_mutex_exit(array->mutex);
}
@@ -3766,12 +3752,8 @@ os_aio(
os_aio_array_t* array;
os_aio_slot_t* slot;
#ifdef WIN_ASYNC_IO
- ibool retval;
- BOOL ret = TRUE;
DWORD len = (DWORD) n;
- struct fil_node_struct * dummy_mess1;
- void* dummy_mess2;
- ulint dummy_type;
+ BOOL ret;
#endif
ulint err = 0;
ibool retry;
@@ -3790,26 +3772,23 @@ os_aio(
wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER;
mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER);
- if (mode == OS_AIO_SYNC
-#ifdef WIN_ASYNC_IO
- && !os_aio_use_native_aio
-#endif
- ) {
+ if (mode == OS_AIO_SYNC)
+ {
+ ibool ret;
/* This is actually an ordinary synchronous read or write:
- no need to use an i/o-handler thread. NOTE that if we use
- Windows async i/o, Windows does not allow us to use
- ordinary synchronous os_file_read etc. on the same file,
- therefore we have built a special mechanism for synchronous
- wait in the Windows case. */
+ no need to use an i/o-handler thread */
if (type == OS_FILE_READ) {
- return(_os_file_read(file, buf, offset,
- offset_high, n, trx));
+ ret = _os_file_read(file, buf, offset,
+ offset_high, n, trx);
}
+ else {
+ ut_a(type == OS_FILE_WRITE);
- ut_a(type == OS_FILE_WRITE);
-
- return(os_file_write(name, file, buf, offset, offset_high, n));
+ ret = os_file_write(name, file, buf, offset, offset_high, n);
+ }
+ ut_a(ret);
+ return ret;
}
try_again:
@@ -3852,6 +3831,8 @@ try_again:
ret = ReadFile(file, buf, (DWORD)n, &len,
&(slot->control));
+ if(!ret && GetLastError() != ERROR_IO_PENDING)
+ err = 1;
#endif
} else {
if (!wake_later) {
@@ -3866,6 +3847,8 @@ try_again:
os_n_file_writes++;
ret = WriteFile(file, buf, (DWORD)n, &len,
&(slot->control));
+ if(!ret && GetLastError() != ERROR_IO_PENDING)
+ err = 1;
#endif
} else {
if (!wake_later) {
@@ -3878,34 +3861,7 @@ try_again:
ut_error;
}
-#ifdef WIN_ASYNC_IO
- if (os_aio_use_native_aio) {
- if ((ret && len == n)
- || (!ret && GetLastError() == ERROR_IO_PENDING)) {
- /* aio was queued successfully! */
-
- if (mode == OS_AIO_SYNC) {
- /* We want a synchronous i/o operation on a
- file where we also use async i/o: in Windows
- we must use the same wait mechanism as for
- async i/o */
-
- retval = os_aio_windows_handle(ULINT_UNDEFINED,
- slot->pos,
- &dummy_mess1,
- &dummy_mess2,
- &dummy_type,
- &space_id);
-
- return(retval);
- }
-
- return(TRUE);
- }
- err = 1; /* Fall through the next if */
- }
-#endif
if (err == 0) {
/* aio was queued successfully! */
@@ -3926,6 +3882,9 @@ try_again:
}
#ifdef WIN_ASYNC_IO
+#define READ_SEGMENT(x) (x < srv_n_read_io_threads)
+#define WRITE_SEGMENT(x) !READ_SEGMENT(x)
+
/**********************************************************************//**
This function is only used in Windows asynchronous i/o.
Waits for an aio operation to complete. This function is used to wait the
@@ -3958,52 +3917,53 @@ os_aio_windows_handle(
ulint* space_id)
{
ulint orig_seg = segment;
- os_aio_array_t* array;
os_aio_slot_t* slot;
- ulint n;
- ulint i;
ibool ret_val;
BOOL ret;
DWORD len;
BOOL retry = FALSE;
+ ULONG_PTR key;
+ HANDLE port = READ_SEGMENT(segment)? read_completion_port : completion_port;
- if (segment == ULINT_UNDEFINED) {
- array = os_aio_sync_array;
- segment = 0;
- } else {
- segment = os_aio_get_array_and_local_segment(&array, segment);
- }
-
- /* NOTE! We only access constant fields in os_aio_array. Therefore
- we do not have to acquire the protecting mutex yet */
+ for(;;) {
+ ret = GetQueuedCompletionStatus(port, &len, &key,
+ (OVERLAPPED **)&slot, INFINITE);
- ut_ad(os_aio_validate());
- ut_ad(segment < array->n_segments);
-
- n = array->n_slots;
-
- if (array == os_aio_sync_array) {
- os_event_wait(os_aio_array_get_nth_slot(array, pos)->event);
- i = pos;
- } else {
- srv_set_io_thread_op_info(orig_seg, "wait Windows aio");
- i = os_event_wait_multiple(n,
- (array->native_events)
- );
- }
-
- os_mutex_enter(array->mutex);
-
- slot = os_aio_array_get_nth_slot(array, i);
+ /* If shutdown key was received, repost the shutdown message and exit */
+ if (ret && (key == IOCP_SHUTDOWN_KEY)) {
+ PostQueuedCompletionStatus(port, 0, key, NULL);
+ os_thread_exit(NULL);
+ }
- ut_a(slot->reserved);
+ if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+ os_thread_exit(NULL);
+ }
- if (orig_seg != ULINT_UNDEFINED) {
- srv_set_io_thread_op_info(orig_seg,
- "get windows aio return value");
+ if(WRITE_SEGMENT(segment)&& slot->type == OS_FILE_READ) {
+ /*
+ Redirect read completions to the dedicated completion port
+ and thread. We need to split read and write threads. If we do not
+ do that, and just allow all io threads process all IO, it is possible
+ to get stuck in a deadlock in buffer pool code,
+
+ Currently, the problem is solved this way - "write io" threads
+ always get all completion notifications, from both async reads and
+ writes. Write completion is handled in the same thread that gets it.
+ Read completion is forwarded via PostQueueCompletionStatus())
+ to the second completion port dedicated solely to reads. One of the
+ "read io" threads waiting on this port will finally handle the IO.
+
+ Forwarding IO completion this way costs a context switch , and this
+ seems tolerable since asynchronous reads are by far less frequent.
+ */
+ ut_a(PostQueuedCompletionStatus(read_completion_port, len, key,
+ &slot->control));
+ }
+ else {
+ break;
+ }
}
- ret = GetOverlappedResult(slot->file, &(slot->control), &len, TRUE);
*message1 = slot->message1;
*message2 = slot->message2;
@@ -4028,8 +3988,6 @@ os_aio_windows_handle(
ret_val = FALSE;
}
- os_mutex_exit(array->mutex);
-
if (retry) {
/* retry failed read/write operation synchronously.
No need to hold array->mutex. */
@@ -4038,37 +3996,19 @@ os_aio_windows_handle(
switch (slot->type) {
case OS_FILE_WRITE:
- ret = WriteFile(slot->file, slot->buf,
- (DWORD) slot->len, &len,
- &(slot->control));
-
+ ret_val = os_file_write(slot->name, slot->file, slot->buf,
+ slot->control.Offset, slot->control.OffsetHigh, slot->len);
break;
case OS_FILE_READ:
- ret = ReadFile(slot->file, slot->buf,
- (DWORD) slot->len, &len,
- &(slot->control));
-
+ ret_val = os_file_read(slot->file, slot->buf,
+ slot->control.Offset, slot->control.OffsetHigh, slot->len);
break;
default:
ut_error;
}
-
- if (!ret && GetLastError() == ERROR_IO_PENDING) {
- /* aio was queued successfully!
- We want a synchronous i/o operation on a
- file where we also use async i/o: in Windows
- we must use the same wait mechanism as for
- async i/o */
-
- ret = GetOverlappedResult(slot->file,
- &(slot->control),
- &len, TRUE);
- }
-
- ret_val = ret && len == slot->len;
}
- os_aio_array_free_slot(array, slot);
+ os_aio_array_free_slot((os_aio_array_t *)slot->arr, slot);
return(ret_val);
}
diff --git a/storage/xtradb/os/os0sync.c b/storage/xtradb/os/os0sync.c
index dba997927cb..12153c309c0 100644
--- a/storage/xtradb/os/os0sync.c
+++ b/storage/xtradb/os/os0sync.c
@@ -38,6 +38,7 @@ Created 9/6/1995 Heikki Tuuri
#include "ut0mem.h"
#include "srv0start.h"
+#include "srv0srv.h"
/* Type definition for an operating system mutex struct */
struct os_mutex_struct{
@@ -74,11 +75,227 @@ UNIV_INTERN ulint os_event_count = 0;
UNIV_INTERN ulint os_mutex_count = 0;
UNIV_INTERN ulint os_fast_mutex_count = 0;
+/* The number of microsecnds in a second. */
+static const ulint MICROSECS_IN_A_SECOND = 1000000;
+
/* Because a mutex is embedded inside an event and there is an
event embedded inside a mutex, on free, this generates a recursive call.
This version of the free event function doesn't acquire the global lock */
static void os_event_free_internal(os_event_t event);
+/* On Windows (Vista and later), load function pointers for condition
+variable handling. Those functions are not available in prior versions,
+so we have to use them via runtime loading, as long as we support XP. */
+static void os_cond_module_init(void);
+
+#ifdef __WIN__
+/* Prototypes and function pointers for condition variable functions */
+typedef VOID (WINAPI* InitializeConditionVariableProc)
+ (PCONDITION_VARIABLE ConditionVariable);
+static InitializeConditionVariableProc initialize_condition_variable;
+
+typedef BOOL (WINAPI* SleepConditionVariableCSProc)
+ (PCONDITION_VARIABLE ConditionVariable,
+ PCRITICAL_SECTION CriticalSection,
+ DWORD dwMilliseconds);
+static SleepConditionVariableCSProc sleep_condition_variable;
+
+typedef VOID (WINAPI* WakeAllConditionVariableProc)
+ (PCONDITION_VARIABLE ConditionVariable);
+static WakeAllConditionVariableProc wake_all_condition_variable;
+
+typedef VOID (WINAPI* WakeConditionVariableProc)
+ (PCONDITION_VARIABLE ConditionVariable);
+static WakeConditionVariableProc wake_condition_variable;
+#endif
+
+/*********************************************************//**
+Initialitze condition variable */
+UNIV_INLINE
+void
+os_cond_init(
+/*=========*/
+ os_cond_t* cond) /*!< in: condition variable. */
+{
+ ut_a(cond);
+
+#ifdef __WIN__
+ ut_a(initialize_condition_variable != NULL);
+ initialize_condition_variable(cond);
+#else
+ ut_a(pthread_cond_init(cond, NULL) == 0);
+#endif
+}
+
+/*********************************************************//**
+Do a timed wait on condition variable.
+@return TRUE if timed out, FALSE otherwise */
+UNIV_INLINE
+ibool
+os_cond_wait_timed(
+/*===============*/
+ os_cond_t* cond, /*!< in: condition variable. */
+ os_fast_mutex_t* mutex, /*!< in: fast mutex */
+#ifndef __WIN__
+ const struct timespec* abstime /*!< in: timeout */
+#else
+ DWORD time_in_ms /*!< in: timeout in
+ milliseconds*/
+#endif /* !__WIN__ */
+)
+{
+#ifdef __WIN__
+ BOOL ret;
+ DWORD err;
+
+ ut_a(sleep_condition_variable != NULL);
+
+ ret = sleep_condition_variable(cond, mutex, time_in_ms);
+
+ if (!ret) {
+ err = GetLastError();
+ /* From http://msdn.microsoft.com/en-us/library/ms686301%28VS.85%29.aspx,
+ "Condition variables are subject to spurious wakeups
+ (those not associated with an explicit wake) and stolen wakeups
+ (another thread manages to run before the woken thread)."
+ Check for both types of timeouts.
+ Conditions are checked by the caller.*/
+ if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) {
+ return(TRUE);
+ }
+ }
+
+ ut_a(ret);
+
+ return(FALSE);
+#else
+ int ret;
+
+ ret = pthread_cond_timedwait(cond, mutex, abstime);
+
+ switch (ret) {
+ case 0:
+ case ETIMEDOUT:
+ /* We play it safe by checking for EINTR even though
+ according to the POSIX documentation it can't return EINTR. */
+ case EINTR:
+ break;
+
+ default:
+ fprintf(stderr, " InnoDB: pthread_cond_timedwait() returned: "
+ "%d: abstime={%lu,%lu}\n",
+ ret, (ulong) abstime->tv_sec, (ulong) abstime->tv_nsec);
+ ut_error;
+ }
+
+ return(ret == ETIMEDOUT);
+#endif
+}
+/*********************************************************//**
+Wait on condition variable */
+UNIV_INLINE
+void
+os_cond_wait(
+/*=========*/
+ os_cond_t* cond, /*!< in: condition variable. */
+ os_fast_mutex_t* mutex) /*!< in: fast mutex */
+{
+ ut_a(cond);
+ ut_a(mutex);
+
+#ifdef __WIN__
+ ut_a(sleep_condition_variable != NULL);
+ ut_a(sleep_condition_variable(cond, mutex, INFINITE));
+#else
+ ut_a(pthread_cond_wait(cond, mutex) == 0);
+#endif
+}
+
+/*********************************************************//**
+Wakes all threads waiting for condition variable */
+UNIV_INLINE
+void
+os_cond_broadcast(
+/*==============*/
+ os_cond_t* cond) /*!< in: condition variable. */
+{
+ ut_a(cond);
+
+#ifdef __WIN__
+ ut_a(wake_all_condition_variable != NULL);
+ wake_all_condition_variable(cond);
+#else
+ ut_a(pthread_cond_broadcast(cond) == 0);
+#endif
+}
+
+/*********************************************************//**
+Wakes one thread waiting for condition variable */
+UNIV_INLINE
+void
+os_cond_signal(
+/*==========*/
+ os_cond_t* cond) /*!< in: condition variable. */
+{
+ ut_a(cond);
+
+#ifdef __WIN__
+ ut_a(wake_condition_variable != NULL);
+ wake_condition_variable(cond);
+#else
+ ut_a(pthread_cond_signal(cond) == 0);
+#endif
+}
+
+/*********************************************************//**
+Destroys condition variable */
+UNIV_INLINE
+void
+os_cond_destroy(
+/*============*/
+ os_cond_t* cond) /*!< in: condition variable. */
+{
+#ifdef __WIN__
+ /* Do nothing */
+#else
+ ut_a(pthread_cond_destroy(cond) == 0);
+#endif
+}
+
+/*********************************************************//**
+On Windows (Vista and later), load function pointers for condition variable
+handling. Those functions are not available in prior versions, so we have to
+use them via runtime loading, as long as we support XP. */
+static
+void
+os_cond_module_init(void)
+/*=====================*/
+{
+#ifdef __WIN__
+ HMODULE h_dll;
+
+ if (!srv_use_native_conditions)
+ return;
+
+ h_dll = GetModuleHandle("kernel32");
+
+ initialize_condition_variable = (InitializeConditionVariableProc)
+ GetProcAddress(h_dll, "InitializeConditionVariable");
+ sleep_condition_variable = (SleepConditionVariableCSProc)
+ GetProcAddress(h_dll, "SleepConditionVariableCS");
+ wake_all_condition_variable = (WakeAllConditionVariableProc)
+ GetProcAddress(h_dll, "WakeAllConditionVariable");
+ wake_condition_variable = (WakeConditionVariableProc)
+ GetProcAddress(h_dll, "WakeConditionVariable");
+
+ /* When using native condition variables, check function pointers */
+ ut_a(initialize_condition_variable);
+ ut_a(sleep_condition_variable);
+ ut_a(wake_all_condition_variable);
+ ut_a(wake_condition_variable);
+#endif
+}
+
/*********************************************************//**
Initializes global event and OS 'slow' mutex lists. */
UNIV_INTERN
@@ -92,6 +309,9 @@ os_sync_init(void)
os_sync_mutex = NULL;
os_sync_mutex_inited = FALSE;
+ /* Now for Windows only */
+ os_cond_module_init();
+
os_sync_mutex = os_mutex_create(NULL);
os_sync_mutex_inited = TRUE;
@@ -146,42 +366,45 @@ os_event_create(
const char* name) /*!< in: the name of the event, if NULL
the event is created without a name */
{
-#ifdef __WIN__
- os_event_t event;
-
- event = ut_malloc(sizeof(struct os_event_struct));
-
- event->handle = CreateEvent(NULL, /* No security attributes */
- TRUE, /* Manual reset */
- FALSE, /* Initial state nonsignaled */
- (LPCTSTR) name);
- if (!event->handle) {
- fprintf(stderr,
- "InnoDB: Could not create a Windows event semaphore;"
- " Windows error %lu\n",
- (ulong) GetLastError());
- }
-#else /* Unix */
os_event_t event;
- UT_NOT_USED(name);
+#ifdef __WIN__
+ if(!srv_use_native_conditions) {
+
+ event = ut_malloc(sizeof(struct os_event_struct));
+
+ event->handle = CreateEvent(NULL,
+ TRUE,
+ FALSE,
+ (LPCTSTR) name);
+ if (!event->handle) {
+ fprintf(stderr,
+ "InnoDB: Could not create a Windows event"
+ " semaphore; Windows error %lu\n",
+ (ulong) GetLastError());
+ }
+ } else /* Windows with condition variables */
+#endif
- event = ut_malloc(sizeof(struct os_event_struct));
+ {
+ UT_NOT_USED(name);
- os_fast_mutex_init(&(event->os_mutex));
+ event = ut_malloc(sizeof(struct os_event_struct));
- ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
+ os_fast_mutex_init(&(event->os_mutex));
- event->is_set = FALSE;
+ os_cond_init(&(event->cond_var));
- /* We return this value in os_event_reset(), which can then be
- be used to pass to the os_event_wait_low(). The value of zero
- is reserved in os_event_wait_low() for the case when the
- caller does not want to pass any signal_count value. To
- distinguish between the two cases we initialize signal_count
- to 1 here. */
- event->signal_count = 1;
-#endif /* __WIN__ */
+ event->is_set = FALSE;
+
+ /* We return this value in os_event_reset(), which can then be
+ be used to pass to the os_event_wait_low(). The value of zero
+ is reserved in os_event_wait_low() for the case when the
+ caller does not want to pass any signal_count value. To
+ distinguish between the two cases we initialize signal_count
+ to 1 here. */
+ event->signal_count = 1;
+ }
/* The os_sync_mutex can be NULL because during startup an event
can be created [ because it's embedded in the mutex/rwlock ] before
@@ -211,10 +434,15 @@ os_event_set(
/*=========*/
os_event_t event) /*!< in: event to set */
{
-#ifdef __WIN__
ut_a(event);
- ut_a(SetEvent(event->handle));
-#else
+
+#ifdef __WIN__
+ if (!srv_use_native_conditions) {
+ ut_a(SetEvent(event->handle));
+ return;
+ }
+#endif
+
ut_a(event);
os_fast_mutex_lock(&(event->os_mutex));
@@ -224,11 +452,10 @@ os_event_set(
} else {
event->is_set = TRUE;
event->signal_count += 1;
- ut_a(0 == pthread_cond_broadcast(&(event->cond_var)));
+ os_cond_broadcast(&(event->cond_var));
}
os_fast_mutex_unlock(&(event->os_mutex));
-#endif
}
/**********************************************************//**
@@ -247,12 +474,14 @@ os_event_reset(
{
ib_int64_t ret = 0;
-#ifdef __WIN__
ut_a(event);
- ut_a(ResetEvent(event->handle));
-#else
- ut_a(event);
+#ifdef __WIN__
+ if(!srv_use_native_conditions) {
+ ut_a(ResetEvent(event->handle));
+ return(0);
+ }
+#endif
os_fast_mutex_lock(&(event->os_mutex));
@@ -264,7 +493,6 @@ os_event_reset(
ret = event->signal_count;
os_fast_mutex_unlock(&(event->os_mutex));
-#endif
return(ret);
}
@@ -277,17 +505,20 @@ os_event_free_internal(
os_event_t event) /*!< in: event to free */
{
#ifdef __WIN__
- ut_a(event);
+ if(!srv_use_native_conditions) {
+ ut_a(event);
+ ut_a(CloseHandle(event->handle));
+ } else
+#endif
+ {
+ ut_a(event);
- ut_a(CloseHandle(event->handle));
-#else
- ut_a(event);
+ /* This is to avoid freeing the mutex twice */
+ os_fast_mutex_free(&(event->os_mutex));
- /* This is to avoid freeing the mutex twice */
- os_fast_mutex_free(&(event->os_mutex));
+ os_cond_destroy(&(event->cond_var));
+ }
- ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
-#endif
/* Remove from the list of events */
UT_LIST_REMOVE(os_event_list, os_event_list, event);
@@ -306,16 +537,18 @@ os_event_free(
os_event_t event) /*!< in: event to free */
{
-#ifdef __WIN__
ut_a(event);
+#ifdef __WIN__
+ if(!srv_use_native_conditions){
+ ut_a(CloseHandle(event->handle));
+ } else /*Windows with condition variables */
+#endif
+ {
+ os_fast_mutex_free(&(event->os_mutex));
- ut_a(CloseHandle(event->handle));
-#else
- ut_a(event);
+ os_cond_destroy(&(event->cond_var));
+ }
- os_fast_mutex_free(&(event->os_mutex));
- ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
-#endif
/* Remove from the list of events */
os_mutex_enter(os_sync_mutex);
@@ -358,23 +591,24 @@ os_event_wait_low(
returned by previous call of
os_event_reset(). */
{
-#ifdef __WIN__
- DWORD err;
+
+ ib_int64_t old_signal_count;
- ut_a(event);
+#ifdef __WIN__
+ if(!srv_use_native_conditions) {
+ DWORD err;
- UT_NOT_USED(reset_sig_count);
+ ut_a(event);
- /* Specify an infinite time limit for waiting */
- err = WaitForSingleObject(event->handle, INFINITE);
+ UT_NOT_USED(reset_sig_count);
- ut_a(err == WAIT_OBJECT_0);
+ /* Specify an infinite wait */
+ err = WaitForSingleObject(event->handle, INFINITE);
- if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
- os_thread_exit(NULL);
+ ut_a(err == WAIT_OBJECT_0);
+ return;
}
-#else
- ib_int64_t old_signal_count;
+#endif
os_fast_mutex_lock(&(event->os_mutex));
@@ -399,13 +633,12 @@ os_event_wait_low(
return;
}
- pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
+ os_cond_wait(&(event->cond_var), &(event->os_mutex));
/* Solaris manual said that spurious wakeups may occur: we
have to check if the event really has been signaled after
we came here to wait */
}
-#endif
}
/**********************************************************//**
@@ -414,112 +647,112 @@ a timeout is exceeded.
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
UNIV_INTERN
ulint
-os_event_wait_time(
-/*===============*/
- os_event_t event, /*!< in: event to wait */
- ulint wtime) /*!< in: timeout in microseconds, or
- OS_SYNC_INFINITE_TIME */
+os_event_wait_time_low(
+/*===================*/
+ os_event_t event, /*!< in: event to wait */
+ ulint time_in_usec, /*!< in: timeout in
+ microseconds, or
+ OS_SYNC_INFINITE_TIME */
+ ib_int64_t reset_sig_count) /*!< in: zero or the value
+ returned by previous call of
+ os_event_reset(). */
+
{
+ ibool timed_out = FALSE;
+
#ifdef __WIN__
- DWORD err;
+ DWORD time_in_ms;
- ut_a(event);
+ if (!srv_use_native_conditions) {
+ DWORD err;
- if (wtime != OS_SYNC_INFINITE_TIME) {
- err = WaitForSingleObject(event->handle, (DWORD) wtime / 1000);
- } else {
- err = WaitForSingleObject(event->handle, INFINITE);
- }
+ ut_a(event);
- if (err == WAIT_OBJECT_0) {
+ if (time_in_usec != OS_SYNC_INFINITE_TIME) {
+ time_in_ms = time_in_usec / 1000;
+ err = WaitForSingleObject(event->handle, time_in_ms);
+ } else {
+ err = WaitForSingleObject(event->handle, INFINITE);
+ }
- return(0);
- } else if (err == WAIT_TIMEOUT) {
+ if (err == WAIT_OBJECT_0) {
+ return(0);
+ } else if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) {
+ return(OS_SYNC_TIME_EXCEEDED);
+ }
- return(OS_SYNC_TIME_EXCEEDED);
- } else {
ut_error;
- return(1000000); /* dummy value to eliminate compiler warn. */
+ /* Dummy value to eliminate compiler warning. */
+ return(42);
+ } else {
+ ut_a(sleep_condition_variable != NULL);
+
+ if (time_in_usec != OS_SYNC_INFINITE_TIME) {
+ time_in_ms = time_in_usec / 1000;
+ } else {
+ time_in_ms = INFINITE;
+ }
}
#else
- int err;
- int ret = 0;
- ulint tmp;
- ib_int64_t old_count;
- struct timeval tv_start;
- struct timespec timeout;
-
- if (wtime == OS_SYNC_INFINITE_TIME) {
- os_event_wait(event);
- return 0;
- }
+ struct timespec abstime;
- /* Compute the absolute point in time at which to time out. */
- gettimeofday(&tv_start, NULL);
- tmp = tv_start.tv_usec + wtime;
- timeout.tv_sec = tv_start.tv_sec + (tmp / 1000000);
- timeout.tv_nsec = (tmp % 1000000) * 1000;
+ if (time_in_usec != OS_SYNC_INFINITE_TIME) {
+ struct timeval tv;
+ int ret;
+ ulint sec;
+ ulint usec;
- os_fast_mutex_lock(&(event->os_mutex));
- old_count = event->signal_count;
+ ret = ut_usectime(&sec, &usec);
+ ut_a(ret == 0);
- for (;;) {
- if (event->is_set == TRUE || event->signal_count != old_count)
- break;
+ tv.tv_sec = sec;
+ tv.tv_usec = usec;
- err = pthread_cond_timedwait(&(event->cond_var),
- &(event->os_mutex), &timeout);
- if (err == ETIMEDOUT) {
- ret = OS_SYNC_TIME_EXCEEDED;
- break;
+ tv.tv_usec += time_in_usec;
+
+ if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) {
+ tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND;
+ tv.tv_usec %= MICROSECS_IN_A_SECOND;
}
+
+ abstime.tv_sec = tv.tv_sec;
+ abstime.tv_nsec = tv.tv_usec * 1000;
+ } else {
+ abstime.tv_nsec = 999999999;
+ abstime.tv_sec = (time_t) ULINT_MAX;
}
- os_fast_mutex_unlock(&(event->os_mutex));
+ ut_a(abstime.tv_nsec <= 999999999);
+
+#endif /* __WIN__ */
- if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+ os_fast_mutex_lock(&event->os_mutex);
- os_thread_exit(NULL);
+ if (!reset_sig_count) {
+ reset_sig_count = event->signal_count;
}
- return ret;
-#endif
-}
+ do {
+ if (event->is_set || event->signal_count != reset_sig_count) {
-#ifdef __WIN__
-/**********************************************************//**
-Waits for any event in an OS native event array. Returns if even a single
-one is signaled or becomes signaled.
-@return index of the event which was signaled */
-UNIV_INTERN
-ulint
-os_event_wait_multiple(
-/*===================*/
- ulint n, /*!< in: number of events in the
- array */
- os_native_event_t* native_event_array)
- /*!< in: pointer to an array of event
- handles */
-{
- DWORD index;
+ break;
+ }
- ut_a(native_event_array);
- ut_a(n > 0);
+ timed_out = os_cond_wait_timed(
+ &event->cond_var, &event->os_mutex,
+#ifndef __WIN__
+ &abstime
+#else
+ time_in_ms
+#endif /* !__WIN__ */
+ );
- index = WaitForMultipleObjects((DWORD) n, native_event_array,
- FALSE, /* Wait for any 1 event */
- INFINITE); /* Infinite wait time
- limit */
- ut_a(index >= WAIT_OBJECT_0); /* NOTE: Pointless comparison */
- ut_a(index < WAIT_OBJECT_0 + n);
+ } while (!timed_out);
- if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
- os_thread_exit(NULL);
- }
+ os_fast_mutex_unlock(&event->os_mutex);
- return(index - WAIT_OBJECT_0);
+ return(timed_out ? OS_SYNC_TIME_EXCEEDED : 0);
}
-#endif
/*********************************************************//**
Creates an operating system mutex semaphore. Because these are slow, the
@@ -532,15 +765,6 @@ os_mutex_create(
const char* name) /*!< in: the name of the mutex, if NULL
the mutex is created without a name */
{
-#ifdef __WIN__
- HANDLE mutex;
- os_mutex_t mutex_str;
-
- mutex = CreateMutex(NULL, /* No security attributes */
- FALSE, /* Initial state: no owner */
- (LPCTSTR) name);
- ut_a(mutex);
-#else
os_fast_mutex_t* mutex;
os_mutex_t mutex_str;
@@ -549,7 +773,6 @@ os_mutex_create(
mutex = ut_malloc(sizeof(os_fast_mutex_t));
os_fast_mutex_init(mutex);
-#endif
mutex_str = ut_malloc(sizeof(os_mutex_str_t));
mutex_str->handle = mutex;
@@ -580,25 +803,11 @@ os_mutex_enter(
/*===========*/
os_mutex_t mutex) /*!< in: mutex to acquire */
{
-#ifdef __WIN__
- DWORD err;
-
- ut_a(mutex);
-
- /* Specify infinite time limit for waiting */
- err = WaitForSingleObject(mutex->handle, INFINITE);
-
- ut_a(err == WAIT_OBJECT_0);
-
- (mutex->count)++;
- ut_a(mutex->count == 1);
-#else
os_fast_mutex_lock(mutex->handle);
(mutex->count)++;
ut_a(mutex->count == 1);
-#endif
}
/**********************************************************//**
@@ -614,11 +823,7 @@ os_mutex_exit(
ut_a(mutex->count == 1);
(mutex->count)--;
-#ifdef __WIN__
- ut_a(ReleaseMutex(mutex->handle));
-#else
os_fast_mutex_unlock(mutex->handle);
-#endif
}
/**********************************************************//**
@@ -647,15 +852,9 @@ os_mutex_free(
os_mutex_exit(os_sync_mutex);
}
-#ifdef __WIN__
- ut_a(CloseHandle(mutex->handle));
-
- ut_free(mutex);
-#else
os_fast_mutex_free(mutex->handle);
ut_free(mutex->handle);
ut_free(mutex);
-#endif
}
/*********************************************************//**
diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c
index ba3db5bc022..cfe1c9934bb 100644
--- a/storage/xtradb/row/row0sel.c
+++ b/storage/xtradb/row/row0sel.c
@@ -58,6 +58,8 @@ Created 12/19/1997 Heikki Tuuri
#include "buf0lru.h"
#include "ha_prototypes.h"
+#include "my_compare.h" /* enum icp_result */
+
/* Maximum number of rows to prefetch; MySQL interface has another parameter */
#define SEL_MAX_N_PREFETCH 16
@@ -2688,148 +2690,101 @@ row_sel_field_store_in_mysql_format(
case DATA_DECIMAL:
/* Above are the valid column types for MySQL data. */
#endif /* UNIV_DEBUG */
- ut_ad(templ->mysql_col_len == len);
memcpy(dest, data, len);
}
}
/**************************************************************//**
-Convert a row in the Innobase format to a row in the MySQL format.
-Note that the template in prebuilt may advise us to copy only a few
-columns to mysql_rec, other columns are left blank. All columns may not
-be needed in the query.
-@return TRUE on success, FALSE if not all columns could be retrieved */
+Convert a field in the Innobase format to a field in the MySQL format. */
static __attribute__((warn_unused_result))
ibool
-row_sel_store_mysql_rec(
-/*====================*/
- byte* mysql_rec, /*!< out: row in the MySQL format */
- row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
- const rec_t* rec, /*!< in: Innobase record in the index
- which was described in prebuilt's
- template, or in the clustered index;
- must be protected by a page latch */
- ibool rec_clust, /*!< in: TRUE if rec is in the
- clustered index instead of
- prebuilt->index */
- const ulint* offsets) /*!< in: array returned by
- rec_get_offsets(rec) */
+row_sel_store_mysql_field(
+/*======================*/
+ byte* mysql_rec, /*!< out: record in the
+ MySQL format */
+ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct */
+ const rec_t* rec, /*!< in: InnoDB record;
+ must be protected by
+ a page latch */
+ const ulint* offsets, /*!< in: array returned by
+ rec_get_offsets() */
+ ulint field_no, /*!< in: templ->rec_field_no or
+ templ->clust_rec_field_no */
+ const mysql_row_templ_t*templ) /*!< in: row template */
{
- mem_heap_t* extern_field_heap = NULL;
- mem_heap_t* heap;
- ulint i;
+ const byte* data;
+ ulint len;
- ut_ad(prebuilt->mysql_template);
ut_ad(prebuilt->default_rec);
+ ut_ad(templ);
+ ut_ad(templ >= prebuilt->mysql_template);
+ ut_ad(templ < &prebuilt->mysql_template[prebuilt->n_template]);
+ ut_ad(field_no == templ->clust_rec_field_no
+ || field_no == templ->rec_field_no
+ || field_no == templ->icp_rec_field_no);
ut_ad(rec_offs_validate(rec, NULL, offsets));
- ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
-
- if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
- mem_heap_free(prebuilt->blob_heap);
- prebuilt->blob_heap = NULL;
- }
- for (i = 0; i < prebuilt->n_template; i++) {
+ if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) {
- const mysql_row_templ_t*templ = prebuilt->mysql_template + i;
- const byte* data;
- ulint len;
- ulint field_no;
-
- field_no = rec_clust
- ? templ->clust_rec_field_no : templ->rec_field_no;
+ mem_heap_t* heap;
+ /* Copy an externally stored field to a temporary heap */
- if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) {
+ ut_a(!prebuilt->trx->has_search_latch);
+ ut_ad(field_no == templ->clust_rec_field_no);
- /* Copy an externally stored field to the temporary
- heap */
+ if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
+ if (prebuilt->blob_heap == NULL) {
+ prebuilt->blob_heap = mem_heap_create(
+ UNIV_PAGE_SIZE);
+ }
- ut_a(!prebuilt->trx->has_search_latch);
+ heap = prebuilt->blob_heap;
+ } else {
+ heap = mem_heap_create(UNIV_PAGE_SIZE);
+ }
- if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
- if (prebuilt->blob_heap == NULL) {
- prebuilt->blob_heap = mem_heap_create(
- UNIV_PAGE_SIZE);
- }
+ /* NOTE: if we are retrieving a big BLOB, we may
+ already run out of memory in the next call, which
+ causes an assert */
- heap = prebuilt->blob_heap;
- } else {
- extern_field_heap
- = mem_heap_create(UNIV_PAGE_SIZE);
+ data = btr_rec_copy_externally_stored_field(
+ rec, offsets,
+ dict_table_zip_size(prebuilt->table),
+ field_no, &len, heap);
- heap = extern_field_heap;
- }
+ if (UNIV_UNLIKELY(!data)) {
+ /* The externally stored field was not written
+ yet. This record should only be seen by
+ recv_recovery_rollback_active() or any
+ TRX_ISO_READ_UNCOMMITTED transactions. */
- /* NOTE: if we are retrieving a big BLOB, we may
- already run out of memory in the next call, which
- causes an assert */
-
- data = btr_rec_copy_externally_stored_field(
- rec, offsets,
- dict_table_zip_size(prebuilt->table),
- field_no, &len, heap);
-
- if (UNIV_UNLIKELY(!data)) {
- /* The externally stored field
- was not written yet. This
- record should only be seen by
- recv_recovery_rollback_active()
- or any TRX_ISO_READ_UNCOMMITTED
- transactions. */
-
- if (extern_field_heap) {
- mem_heap_free(extern_field_heap);
- }
-
- return(FALSE);
+ if (heap != prebuilt->blob_heap) {
+ mem_heap_free(heap);
}
- ut_a(len != UNIV_SQL_NULL);
- } else {
- /* Field is stored in the row. */
-
- data = rec_get_nth_field(rec, offsets, field_no, &len);
-
- if (UNIV_UNLIKELY(templ->type == DATA_BLOB)
- && len != UNIV_SQL_NULL) {
+ ut_a(prebuilt->trx->isolation_level
+ == TRX_ISO_READ_UNCOMMITTED);
+ return(FALSE);
+ }
- /* It is a BLOB field locally stored in the
- InnoDB record: we MUST copy its contents to
- prebuilt->blob_heap here because later code
- assumes all BLOB values have been copied to a
- safe place. */
+ ut_a(len != UNIV_SQL_NULL);
- if (prebuilt->blob_heap == NULL) {
- prebuilt->blob_heap = mem_heap_create(
- UNIV_PAGE_SIZE);
- }
+ row_sel_field_store_in_mysql_format(
+ mysql_rec + templ->mysql_col_offset,
+ templ, data, len);
- data = memcpy(mem_heap_alloc(
- prebuilt->blob_heap, len),
- data, len);
- }
+ if (heap != prebuilt->blob_heap) {
+ mem_heap_free(heap);
}
+ } else {
+ /* Field is stored in the row. */
- if (len != UNIV_SQL_NULL) {
- row_sel_field_store_in_mysql_format(
- mysql_rec + templ->mysql_col_offset,
- templ, data, len);
-
- /* Cleanup */
- if (extern_field_heap) {
- mem_heap_free(extern_field_heap);
- extern_field_heap = NULL;
- }
+ data = rec_get_nth_field(rec, offsets, field_no, &len);
- if (templ->mysql_null_bit_mask) {
- /* It is a nullable column with a non-NULL
- value */
- mysql_rec[templ->mysql_null_byte_offset]
- &= ~(byte) templ->mysql_null_bit_mask;
- }
- } else {
+ if (len == UNIV_SQL_NULL) {
/* MySQL assumes that the field for an SQL
NULL value is set to the default value. */
+ ut_ad(templ->mysql_null_bit_mask);
UNIV_MEM_ASSERT_RW(prebuilt->default_rec
+ templ->mysql_col_offset,
@@ -2840,6 +2795,85 @@ row_sel_store_mysql_rec(
(const byte*) prebuilt->default_rec
+ templ->mysql_col_offset,
templ->mysql_col_len);
+ return(TRUE);
+ }
+
+ if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
+
+ /* It is a BLOB field locally stored in the
+ InnoDB record: we MUST copy its contents to
+ prebuilt->blob_heap here because
+ row_sel_field_store_in_mysql_format() stores a
+ pointer to the data, and the data passed to us
+ will be invalid as soon as the
+ mini-transaction is committed and the page
+ latch on the clustered index page is
+ released. */
+
+ if (prebuilt->blob_heap == NULL) {
+ prebuilt->blob_heap = mem_heap_create(
+ UNIV_PAGE_SIZE);
+ }
+
+ data = mem_heap_dup(prebuilt->blob_heap, data, len);
+ }
+
+ row_sel_field_store_in_mysql_format(
+ mysql_rec + templ->mysql_col_offset,
+ templ, data, len);
+ }
+
+ ut_ad(len != UNIV_SQL_NULL);
+
+ if (templ->mysql_null_bit_mask) {
+ /* It is a nullable column with a non-NULL
+ value */
+ mysql_rec[templ->mysql_null_byte_offset]
+ &= ~(byte) templ->mysql_null_bit_mask;
+ }
+
+ return(TRUE);
+}
+
+/**************************************************************//**
+Convert a row in the Innobase format to a row in the MySQL format.
+Note that the template in prebuilt may advise us to copy only a few
+columns to mysql_rec, other columns are left blank. All columns may not
+be needed in the query.
+@return TRUE on success, FALSE if not all columns could be retrieved */
+static __attribute__((warn_unused_result))
+ibool
+row_sel_store_mysql_rec(
+/*====================*/
+ byte* mysql_rec, /*!< out: row in the MySQL format */
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
+ const rec_t* rec, /*!< in: Innobase record in the index
+ which was described in prebuilt's
+ template, or in the clustered index;
+ must be protected by a page latch */
+ ibool rec_clust, /*!< in: TRUE if rec is in the
+ clustered index instead of
+ prebuilt->index */
+ const ulint* offsets) /*!< in: array returned by
+ rec_get_offsets(rec) */
+{
+ ulint i;
+
+ if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
+ mem_heap_free(prebuilt->blob_heap);
+ prebuilt->blob_heap = NULL;
+ }
+
+ for (i = 0; i < prebuilt->n_template; i++) {
+ const mysql_row_templ_t*templ = &prebuilt->mysql_template[i];
+
+ if (!row_sel_store_mysql_field(mysql_rec, prebuilt,
+ rec, offsets,
+ rec_clust
+ ? templ->clust_rec_field_no
+ : templ->rec_field_no,
+ templ)) {
+ return(FALSE);
}
}
@@ -3203,10 +3237,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;
}
}
} else if (prebuilt->mysql_prefix_len > 63) {
@@ -3236,34 +3274,24 @@ row_sel_pop_cached_row_for_mysql(
}
/********************************************************************//**
-Pushes a row for MySQL to the fetch cache.
-@return TRUE on success, FALSE if the record contains incomplete BLOBs */
-UNIV_INLINE __attribute__((warn_unused_result))
-ibool
-row_sel_push_cache_row_for_mysql(
-/*=============================*/
- row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
- const rec_t* rec, /*!< in: record to push, in the index
- which was described in prebuilt's
- template, or in the clustered index;
- must be protected by a page latch */
- ibool rec_clust, /*!< in: TRUE if rec is in the
- clustered index instead of
- prebuilt->index */
- const ulint* offsets) /*!< in: rec_get_offsets(rec) */
+Get the last fetch cache buffer from the queue.
+@return pointer to buffer. */
+UNIV_INLINE
+byte*
+row_sel_fetch_last_buf(
+/*===================*/
+ row_prebuilt_t* prebuilt) /*!< in/out: prebuilt struct */
{
- byte* buf;
- ulint i;
-
- ut_ad(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE);
- ut_ad(rec_offs_validate(rec, NULL, offsets));
- ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
+ ut_a(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE);
ut_a(!prebuilt->templ_contains_blob);
- if (prebuilt->fetch_cache[0] == NULL) {
+ if (UNIV_UNLIKELY(prebuilt->fetch_cache[0] == NULL)) {
+ ulint i;
/* Allocate memory for the fetch cache */
+ ut_ad(prebuilt->n_fetch_cached == 0);
for (i = 0; i < MYSQL_FETCH_CACHE_SIZE; i++) {
+ byte* buf;
/* A user has reported memory corruption in these
buffers in Linux. Put magic numbers there to help
@@ -3283,15 +3311,28 @@ row_sel_push_cache_row_for_mysql(
UNIV_MEM_INVALID(prebuilt->fetch_cache[prebuilt->n_fetch_cached],
prebuilt->mysql_row_len);
- if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
- prebuilt->fetch_cache[
- prebuilt->n_fetch_cached],
- prebuilt, rec, rec_clust, offsets))) {
- return(FALSE);
+ return(prebuilt->fetch_cache[prebuilt->n_fetch_cached]);
+}
+
+/********************************************************************//**
+Pushes a row for MySQL to the fetch cache. */
+UNIV_INLINE
+void
+row_sel_push_cache_row_for_mysql(
+/*=============================*/
+ byte* mysql_rec, /*!< in/out: MySQL record */
+ row_prebuilt_t* prebuilt) /*!< in/out: prebuilt struct */
+{
+ /* For non ICP code path the row should already exist in the
+ next fetch cache slot. */
+
+ if (prebuilt->idx_cond != NULL) {
+ byte* dest = row_sel_fetch_last_buf(prebuilt);
+
+ ut_memcpy(dest, mysql_rec, prebuilt->mysql_row_len);
}
- prebuilt->n_fetch_cached++;
- return(TRUE);
+ ++prebuilt->n_fetch_cached;
}
/*********************************************************************//**
@@ -3368,6 +3409,82 @@ row_sel_try_search_shortcut_for_mysql(
return(SEL_FOUND);
}
+/*********************************************************************//**
+Check a pushed-down index condition.
+@return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */
+static
+enum icp_result
+row_search_idx_cond_check(
+/*======================*/
+ byte* mysql_rec, /*!< out: record
+ in MySQL format (invalid unless
+ prebuilt->idx_cond!=NULL and
+ we return ICP_MATCH) */
+ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct
+ for the table handle */
+ const rec_t* rec, /*!< in: InnoDB record */
+ const ulint* offsets) /*!< in: rec_get_offsets() */
+{
+ enum icp_result result;
+ ulint i;
+
+ ut_ad(rec_offs_validate(rec, prebuilt->index, offsets));
+
+ if (!prebuilt->idx_cond) {
+ return(ICP_MATCH);
+ }
+
+ /* Convert to MySQL format those fields that are needed for
+ evaluating the index condition. */
+
+ if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
+ mem_heap_empty(prebuilt->blob_heap);
+ }
+
+ for (i = 0; i < prebuilt->idx_cond_n_cols; i++) {
+ const mysql_row_templ_t*templ = &prebuilt->mysql_template[i];
+
+ if (!row_sel_store_mysql_field(mysql_rec, prebuilt,
+ rec, offsets,
+ templ->icp_rec_field_no,
+ templ)) {
+ return(ICP_NO_MATCH);
+ }
+ }
+
+ /* We assume that the index conditions on
+ case-insensitive columns are case-insensitive. The
+ case of such columns may be wrong in a secondary
+ index, if the case of the column has been updated in
+ the past, or a record has been deleted and a record
+ inserted in a different case. */
+ result = handler_index_cond_check(prebuilt->idx_cond);
+ switch (result) {
+ case ICP_MATCH:
+ /* Convert the remaining fields to MySQL format.
+ If this is a secondary index record, we must defer
+ this until we have fetched the clustered index record. */
+ if (!prebuilt->need_to_access_clustered
+ || dict_index_is_clust(prebuilt->index)) {
+ if (!row_sel_store_mysql_rec(mysql_rec, prebuilt,
+ rec,
+ FALSE, offsets)) {
+ ut_ad(dict_index_is_clust(prebuilt->index));
+ result = ICP_NO_MATCH;
+ }
+ }
+ /* fall through */
+ case ICP_NO_MATCH:
+ case ICP_OUT_OF_RANGE:
+ case ICP_ABORTED_BY_USER:
+ return(result);
+ default: ;
+ }
+
+ ut_error;
+ return(ICP_ABORTED_BY_USER); /* Keep compiler happy */
+}
+
/********************************************************************//**
Searches for rows in the database. This is used in the interface to
MySQL. This function opens a cursor, and also implements fetch next
@@ -3375,7 +3492,8 @@ and fetch prev. NOTE that if we do a search with a full key value
from a unique index (ROW_SEL_EXACT), then we will not store the cursor
position and fetch next or fetch prev must not be tried to the cursor!
@return DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK,
-DB_LOCK_TABLE_FULL, DB_CORRUPTION, or DB_TOO_BIG_RECORD */
+DB_LOCK_TABLE_FULL, DB_CORRUPTION, DB_SEARCH_ABORTED_BY_USER or
+DB_TOO_BIG_RECORD */
UNIV_INTERN
ulint
row_search_for_mysql(
@@ -3693,8 +3811,23 @@ row_search_for_mysql(
mtr_commit(&mtr). */
ut_ad(!rec_get_deleted_flag(rec, comp));
+ if (prebuilt->idx_cond) {
+ switch (row_search_idx_cond_check(
+ buf, prebuilt,
+ rec, offsets)) {
+ case ICP_NO_MATCH:
+ case ICP_OUT_OF_RANGE:
+ case ICP_ABORTED_BY_USER:
+ goto shortcut_mismatch;
+ case ICP_MATCH:
+ goto shortcut_match;
+ default: ;
+ }
+ ut_error;
+ }
+
if (!row_sel_store_mysql_rec(buf, prebuilt,
- rec, FALSE,
+ rec, FALSE,
offsets)) {
/* Only fresh inserts may contain
incomplete externally stored
@@ -3706,13 +3839,12 @@ row_search_for_mysql(
rolling back a recovered
transaction. Rollback happens
at a lower level, not here. */
- ut_a(trx->isolation_level
- == TRX_ISO_READ_UNCOMMITTED);
/* Proceed as in case SEL_RETRY. */
break;
}
+ shortcut_match:
mtr_commit(&mtr);
/* ut_print_name(stderr, index->name);
@@ -3724,6 +3856,7 @@ row_search_for_mysql(
goto release_search_latch_if_needed;
case SEL_EXHAUSTED:
+ shortcut_mismatch:
mtr_commit(&mtr);
/* ut_print_name(stderr, index->name);
@@ -3815,8 +3948,9 @@ retry_check:
if (!prebuilt->sql_stat_start) {
/* No need to set an intention lock or assign a read view */
- if (trx->read_view == NULL
- && prebuilt->select_lock_type == LOCK_NONE) {
+ if (UNIV_UNLIKELY
+ (trx->read_view == NULL
+ && prebuilt->select_lock_type == LOCK_NONE)) {
fputs("InnoDB: Error: MySQL is trying to"
" perform a consistent read\n"
@@ -4283,6 +4417,16 @@ no_gap_lock:
if (UNIV_LIKELY(trx->wait_lock != NULL)) {
lock_cancel_waiting_and_release(
trx->wait_lock);
+ mutex_exit(&kernel_mutex);
+
+ if (old_vers == NULL) {
+ /* The row was not yet committed */
+
+ goto next_rec;
+ }
+
+ did_semi_consistent_read = TRUE;
+ rec = old_vers;
} else {
mutex_exit(&kernel_mutex);
@@ -4293,19 +4437,7 @@ no_gap_lock:
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED,
&heap);
- err = DB_SUCCESS;
- break;
- }
- mutex_exit(&kernel_mutex);
-
- if (old_vers == NULL) {
- /* The row was not yet committed */
-
- goto next_rec;
}
-
- did_semi_consistent_read = TRUE;
- rec = old_vers;
break;
default:
@@ -4364,7 +4496,27 @@ no_gap_lock:
if (!lock_sec_rec_cons_read_sees(
rec, trx->read_view)) {
- goto requires_clust_rec;
+ /* We should look at the clustered index.
+ However, as this is a non-locking read,
+ we can skip the clustered index lookup if
+ the condition does not match the secondary
+ index entry. */
+ switch (row_search_idx_cond_check(
+ buf, prebuilt, rec, offsets)) {
+ case ICP_NO_MATCH:
+ goto next_rec;
+ case ICP_OUT_OF_RANGE:
+ err = DB_RECORD_NOT_FOUND;
+ goto idx_cond_failed;
+ case ICP_ABORTED_BY_USER:
+ err = DB_SEARCH_ABORTED_BY_USER;
+ goto idx_cond_failed;
+ case ICP_MATCH:
+ goto requires_clust_rec;
+ default: ;
+ }
+
+ ut_error;
}
}
}
@@ -4411,12 +4563,32 @@ no_gap_lock:
goto next_rec;
}
+ /* Check if the record matches the index condition. */
+ switch (row_search_idx_cond_check(buf, prebuilt, rec, offsets)) {
+ case ICP_NO_MATCH:
+ if (did_semi_consistent_read) {
+ row_unlock_for_mysql(prebuilt, TRUE);
+ }
+ goto next_rec;
+ case ICP_ABORTED_BY_USER:
+ err = DB_SEARCH_ABORTED_BY_USER;
+ goto idx_cond_failed;
+ case ICP_OUT_OF_RANGE:
+ err = DB_RECORD_NOT_FOUND;
+ goto idx_cond_failed;
+ case ICP_MATCH:
+ break;
+ default:
+ ut_error;
+ }
+
/* Get the clustered index record if needed, if we did not do the
search using the clustered index. */
-
if (index != clust_index && prebuilt->need_to_access_clustered) {
-
+
requires_clust_rec:
+ ut_ad(index != clust_index);
+
/* We use a 'goto' to the preceding label if a consistent
read of a secondary index record requires us to look up old
versions of the associated clustered index record. */
@@ -4479,6 +4651,19 @@ requires_clust_rec:
result_rec = clust_rec;
ut_ad(rec_offs_validate(result_rec, clust_index, offsets));
+
+ if (prebuilt->idx_cond) {
+ /* Convert the remaining fields to
+ MySQL format. We were unable to do
+ this in row_search_idx_cond_check(),
+ because the condition is on the
+ secondary index and the requested
+ column is in the clustered index. */
+ if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec,
+ TRUE, offsets)) {
+ goto next_rec;
+ }
+ }
} else {
result_rec = rec;
}
@@ -4513,9 +4698,16 @@ requires_clust_rec:
not cache rows because there the cursor is a scrollable
cursor. */
- if (!row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
- result_rec != rec,
- offsets)) {
+ ut_a(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE);
+
+ /* We only convert from InnoDB row format to MySQL row
+ format when ICP is disabled. */
+
+ if (!prebuilt->idx_cond
+ && !row_sel_store_mysql_rec(
+ row_sel_fetch_last_buf(prebuilt),
+ prebuilt, result_rec,
+ result_rec != rec, offsets)) {
/* Only fresh inserts may contain incomplete
externally stored columns. Pretend that such
records do not exist. Such records may only be
@@ -4523,14 +4715,14 @@ requires_clust_rec:
level or when rolling back a recovered
transaction. Rollback happens at a lower
level, not here. */
- ut_a(trx->isolation_level == TRX_ISO_READ_UNCOMMITTED);
- } else if (prebuilt->n_fetch_cached
- == MYSQL_FETCH_CACHE_SIZE) {
-
- goto got_row;
+ goto next_rec;
}
- goto next_rec;
+ row_sel_push_cache_row_for_mysql(buf, prebuilt);
+
+ if (prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE) {
+ goto next_rec;
+ }
} else {
if (UNIV_UNLIKELY
(prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE)) {
@@ -4551,12 +4743,11 @@ requires_clust_rec:
rec_offs_size(offsets));
mach_write_to_4(buf,
rec_offs_extra_size(offsets) + 4);
- } else {
- /* Returning a row to MySQL */
-
- if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec,
- result_rec != rec,
- offsets)) {
+ } else if (!prebuilt->idx_cond) {
+ /* The record was not yet converted to MySQL format. */
+ if (!row_sel_store_mysql_rec(
+ buf, prebuilt,
+ result_rec, result_rec != rec, offsets)) {
/* Only fresh inserts may contain
incomplete externally stored
columns. Pretend that such records do
@@ -4565,8 +4756,6 @@ requires_clust_rec:
isolation level or when rolling back a
recovered transaction. Rollback
happens at a lower level, not here. */
- ut_a(trx->isolation_level
- == TRX_ISO_READ_UNCOMMITTED);
goto next_rec;
}
}
@@ -4584,7 +4773,6 @@ requires_clust_rec:
/* From this point on, 'offsets' are invalid. */
-got_row:
/* We have an optimization to save CPU time: if this is a consistent
read on a unique condition on the clustered index, then we do not
store the pcur position, because any fetch next or prev will anyway
@@ -4592,6 +4780,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) {
@@ -4601,8 +4792,6 @@ got_row:
btr_pcur_store_position(pcur, &mtr);
}
- err = DB_SUCCESS;
-
goto normal_return;
next_rec:
@@ -4617,6 +4806,7 @@ next_rec:
/*-------------------------------------------------------------*/
/* PHASE 5: Move the cursor to the next index record */
+ /*TODO: with ICP, do this when switching pages, every N pages */
if (UNIV_UNLIKELY(mtr_has_extra_clust_latch)) {
/* We must commit mtr if we are moving to the next
non-clustered index record, because we could break the
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index f01ad40de41..cb47d3994e5 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -148,6 +148,20 @@ UNIV_INTERN ulint srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX;
/** Place locks to records only i.e. do not use next-key locking except
on duplicate key checking and foreign key checking */
UNIV_INTERN ibool srv_locks_unsafe_for_binlog = FALSE;
+#ifdef __WIN__
+/* Windows native condition variables. We use runtime loading / function
+pointers, because they are not available on Windows Server 2003 and
+Windows XP/2000.
+
+We use condition for events on Windows if possible, even if os_event
+resembles Windows kernel event object well API-wise. The reason is
+performance, kernel objects are heavyweights and WaitForSingleObject() is a
+performance killer causing calling thread to context switch. Besides, Innodb
+is preallocating large number (often millions) of os_events. With kernel event
+objects it takes a big chunk out of non-paged pool, which is better suited
+for tasks like IO than for storing idle event objects. */
+UNIV_INTERN ibool srv_use_native_conditions = FALSE;
+#endif /* __WIN__ */
UNIV_INTERN ulint srv_n_data_files = 0;
UNIV_INTERN char** srv_data_file_names = NULL;
@@ -431,7 +445,7 @@ UNIV_INTERN ulong srv_ibuf_accel_rate = 100;
UNIV_INTERN ulint srv_checkpoint_age_target = 0;
UNIV_INTERN ulong srv_flush_neighbor_pages = 1; /* 0:disable 1:enable */
-UNIV_INTERN ulong srv_enable_unsafe_group_commit = 0; /* 0:disable 1:enable */
+UNIV_INTERN ulong srv_deprecated_enable_unsafe_group_commit = 0;
UNIV_INTERN ulong srv_read_ahead = 3; /* 1: random 2: linear 3: Both */
UNIV_INTERN ulong srv_adaptive_checkpoint = 0; /* 0: none 1: reflex 2: estimate */
@@ -3341,7 +3355,7 @@ retry_flush_batch:
/* Make a new checkpoint about once in 10 seconds */
- log_checkpoint(TRUE, FALSE);
+ log_checkpoint(TRUE, FALSE, TRUE);
srv_main_thread_op_info = "reserving kernel mutex";
@@ -3462,7 +3476,7 @@ flush_loop:
srv_main_thread_op_info = "making checkpoint";
- log_checkpoint(TRUE, FALSE);
+ log_checkpoint(TRUE, FALSE, TRUE);
if (buf_get_modified_ratio_pct() > srv_max_buf_pool_modified_pct) {
diff --git a/storage/xtradb/srv/srv0start.c b/storage/xtradb/srv/srv0start.c
index 0c33b2208f2..087262f0f32 100644
--- a/storage/xtradb/srv/srv0start.c
+++ b/storage/xtradb/srv/srv0start.c
@@ -1273,6 +1273,7 @@ innobase_start_or_create_for_mysql(void)
case OS_WIN95:
case OS_WIN31:
case OS_WINNT:
+ srv_use_native_conditions = FALSE;
/* On Win 95, 98, ME, Win32 subsystem for Windows 3.1,
and NT use simulated aio. In NT Windows provides async i/o,
but when run in conjunction with InnoDB Hot Backup, it seemed
@@ -1280,24 +1281,26 @@ innobase_start_or_create_for_mysql(void)
os_aio_use_native_aio = FALSE;
break;
- default:
- /* On Win 2000 and XP use async i/o */
- //os_aio_use_native_aio = TRUE;
- os_aio_use_native_aio = FALSE;
- fprintf(stderr,
- "InnoDB: Windows native async i/o is disabled as default.\n"
- "InnoDB: It is not applicable for the current"
- " multi io threads implementation.\n");
- break;
+
+ case OS_WIN2000:
+ case OS_WINXP:
+ /* On 2000 and XP, async IO is available, but no condition variables. */
+ os_aio_use_native_aio = TRUE;
+ srv_use_native_conditions = FALSE;
+ break;
+
+ default:
+ os_aio_use_native_aio = TRUE;
+ srv_use_native_conditions = TRUE;
}
#endif
+
if (srv_file_flush_method_str == NULL) {
/* These are the default options */
srv_unix_file_flush_method = SRV_UNIX_FSYNC;
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
-#ifndef __WIN__
} else if (0 == ut_strcmp(srv_file_flush_method_str, "fsync")) {
srv_unix_file_flush_method = SRV_UNIX_FSYNC;
@@ -1315,7 +1318,7 @@ innobase_start_or_create_for_mysql(void)
} else if (0 == ut_strcmp(srv_file_flush_method_str, "nosync")) {
srv_unix_file_flush_method = SRV_UNIX_NOSYNC;
-#else
+#ifdef _WIN32
} else if (0 == ut_strcmp(srv_file_flush_method_str, "normal")) {
srv_win_file_flush_method = SRV_WIN_IO_NORMAL;
os_aio_use_native_aio = FALSE;
@@ -1323,16 +1326,10 @@ innobase_start_or_create_for_mysql(void)
} else if (0 == ut_strcmp(srv_file_flush_method_str, "unbuffered")) {
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
os_aio_use_native_aio = FALSE;
-
} else if (0 == ut_strcmp(srv_file_flush_method_str,
"async_unbuffered")) {
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
os_aio_use_native_aio = TRUE;
- srv_n_read_io_threads = srv_n_write_io_threads = 1;
- fprintf(stderr,
- "InnoDB: 'async_unbuffered' was detected as innodb_flush_method.\n"
- "InnoDB: Windows native async i/o is enabled.\n"
- "InnoDB: And io threads are restricted.\n");
#endif
} else {
fprintf(stderr,
diff --git a/storage/xtradb/trx/trx0trx.c b/storage/xtradb/trx/trx0trx.c
index 0cecbf2eea9..74e3233e956 100644
--- a/storage/xtradb/trx/trx0trx.c
+++ b/storage/xtradb/trx/trx0trx.c
@@ -126,7 +126,7 @@ trx_create(
trx->table_id = ut_dulint_zero;
trx->mysql_thd = NULL;
- trx->active_trans = 0;
+ trx->active_flag = 0;
trx->duplicates = 0;
trx->n_mysql_tables_in_use = 0;
diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c
index d671f425201..93439fa4c8e 100644
--- a/strings/ctype-simple.c
+++ b/strings/ctype-simple.c
@@ -307,6 +307,7 @@ void my_hash_sort_simple(CHARSET_INFO *cs,
{
register const uchar *sort_order=cs->sort_order;
const uchar *end= key + len;
+ ulong n1, n2;
/*
Remove end space. We have to do this to be able to compare
@@ -314,13 +315,17 @@ void my_hash_sort_simple(CHARSET_INFO *cs,
*/
while (end > key && end[-1] == ' ')
end--;
-
+
+ n1= *nr1;
+ n2= *nr2;
for (; key < (uchar*) end ; key++)
{
- nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
- ((uint) sort_order[(uint) *key])) + (nr1[0] << 8);
- nr2[0]+=3;
+ n1^=(ulong) ((((uint) n1 & 63)+n2) *
+ ((uint) sort_order[(uint) *key])) + (n1 << 8);
+ n2+=3;
}
+ *nr1= n1;
+ *nr2= n2;
}
@@ -1547,7 +1552,7 @@ my_strntoull10rnd_8bit(CHARSET_INFO *cs __attribute__((unused)),
}
}
- digits= str - beg;
+ digits= (int) (str - beg);
/* Continue to accumulate into ulonglong */
for (dot= NULL, ull= ul; str < end; str++)
@@ -1584,7 +1589,7 @@ my_strntoull10rnd_8bit(CHARSET_INFO *cs __attribute__((unused)),
}
else
{
- shift= dot - str;
+ shift= (int) (dot - str);
for ( ; str < end && (ch= (uchar) (*str - '0')) < 10; str++);
}
goto exp;
diff --git a/strings/decimal.c b/strings/decimal.c
index 126dadab922..e4925ff5f7c 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -32,7 +32,7 @@
integer that determines the number of significant digits in a
particular radix R, where R is either 2 or 10. S is a non-negative
integer. Every value of an exact numeric type of scale S is of the
- form n*10^{-S}, where n is an integer such that �-R^P <= n <= R^P.
+ form n*10^{-S}, where n is an integer such that -R^P <= n <= R^P.
[...]
@@ -257,7 +257,7 @@ void max_decimal(int precision, int frac, decimal_t *to)
}
-static dec1 *remove_leading_zeroes(decimal_t *from, int *intg_result)
+static dec1 *remove_leading_zeroes(const decimal_t *from, int *intg_result)
{
int intg= from->intg, i;
dec1 *buf0= from->buf;
@@ -335,7 +335,7 @@ int decimal_actual_fraction(decimal_t *from)
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
*/
-int decimal2string(decimal_t *from, char *to, int *to_len,
+int decimal2string(const decimal_t *from, char *to, int *to_len,
int fixed_precision, int fixed_decimals,
char filler)
{
@@ -952,7 +952,7 @@ fatal_error:
E_DEC_OK
*/
-int decimal2double(decimal_t *from, double *to)
+int decimal2double(const decimal_t *from, double *to)
{
double result= 0.0;
int i, exp= 0;
@@ -1044,7 +1044,7 @@ int longlong2decimal(longlong from, decimal_t *to)
return ull2dec(from, to);
}
-int decimal2ulonglong(decimal_t *from, ulonglong *to)
+int decimal2ulonglong(const decimal_t *from, ulonglong *to)
{
dec1 *buf=from->buf;
ulonglong x=0;
@@ -1073,7 +1073,7 @@ int decimal2ulonglong(decimal_t *from, ulonglong *to)
return E_DEC_OK;
}
-int decimal2longlong(decimal_t *from, longlong *to)
+int decimal2longlong(const decimal_t *from, longlong *to)
{
dec1 *buf=from->buf;
longlong x=0;
@@ -1190,9 +1190,9 @@ int decimal2longlong(decimal_t *from, longlong *to)
And for -1234567890.1234 it would be
- 7E F2 04 37 2D FB 2D
+ 7E F2 04 C7 2D FB 2D
*/
-int decimal2bin(decimal_t *from, uchar *to, int precision, int frac)
+int decimal2bin(const decimal_t *from, uchar *to, int precision, int frac)
{
dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
int error=E_DEC_OK, intg=precision-frac,
@@ -1489,7 +1489,7 @@ int decimal_bin_size(int precision, int scale)
*/
int
-decimal_round(decimal_t *from, decimal_t *to, int scale,
+decimal_round(const decimal_t *from, decimal_t *to, int scale,
decimal_round_mode mode)
{
int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
diff --git a/strings/strmov.c b/strings/strmov.c
index 1a945ad2a6f..7a3f2d02dcf 100644
--- a/strings/strmov.c
+++ b/strings/strmov.c
@@ -34,10 +34,6 @@
into dst, which seems useful.
*/
-#include "strings_def.h"
-
-#ifndef strmov
-
#if !defined(MC68000) && !defined(DS90)
char *strmov(register char *dst, register const char *src)
@@ -60,5 +56,3 @@ char *strmov(dst, src)
}
#endif
-
-#endif /* strmov */
diff --git a/support-files/Makefile.am b/support-files/Makefile.am
index 6b5dfbd7d8d..821ba7ffac9 100644
--- a/support-files/Makefile.am
+++ b/support-files/Makefile.am
@@ -85,6 +85,9 @@ mysql-@VERSION@.spec: mysql.spec
rm -f $@
cp mysql.spec $@
+# We don't need to uninstall as sql/share/Makefile.am is doing that for us
+uninstall-am:
+
SUFFIXES = .sh
.sh:
diff --git a/support-files/compiler_warnings.supp b/support-files/compiler_warnings.supp
index ec6b742542a..1168770d624 100644
--- a/support-files/compiler_warnings.supp
+++ b/support-files/compiler_warnings.supp
@@ -67,7 +67,6 @@ vi\.c : unused parameter
common\.c : unused parameter
term\.c : .*
-
#
# Ignore some warnings in libevent, which is not maintained by us.
#
@@ -146,6 +145,7 @@ table_xt\.cc : variable.*might be clobbered by.*longjmp
#
# Yassl
+#
include/runtime.hpp: .*pure_error.*
.*/extra/yassl/.*taocrypt/.*: comparison with string literal
.*/extra/yassl/taocrypt/src/blowfish\.cpp: array subscript is above array bounds
@@ -159,6 +159,12 @@ mySTL/algorithm\.hpp: is used uninitialized in this function
.*/dbug/.*(groff|<standard input>) : .*
#
+# Warnings on OpenSolaris
+#
+.*/my_config\.h : _FILE_OFFSET_BITS
+/usr/include/sys/feature_tests.h : this is the location of the previous definition
+
+#
# Unexplanable (?) stuff
#
listener.cc : .*conversion from 'SOCKET' to 'int'.*
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 751c8a7a06b..0c0efc74caf 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -1046,6 +1046,7 @@ fi
%attr(755, root, root) %{_bindir}/mysqld_safe
%attr(755, root, root) %{_bindir}/mysqldumpslow
%attr(755, root, root) %{_bindir}/mysqlhotcopy
+%attr(755, root, root) %{_bindir}/mytop
%attr(755, root, root) %{_bindir}/mysqltest
%attr(755, root, root) %{_bindir}/perror
%attr(755, root, root) %{_bindir}/replace
diff --git a/tests/consistent_snapshot.pl b/tests/consistent_snapshot.pl
new file mode 100755
index 00000000000..9e53eaea6a1
--- /dev/null
+++ b/tests/consistent_snapshot.pl
@@ -0,0 +1,107 @@
+#! /usr/bin/perl
+
+# Test START TRANSACTION WITH CONSISTENT SNAPSHOT.
+# With MWL#116, this is implemented so it is actually consistent.
+
+use strict;
+use warnings;
+
+use DBI;
+
+my $UPDATERS= 10;
+my $READERS= 5;
+
+my $ROWS= 50;
+my $DURATION= 20;
+
+my $stop_time= time() + $DURATION;
+
+sub my_connect {
+ my $dbh= DBI->connect("dbi:mysql:mysql_socket=/tmp/mysql.sock;database=test",
+ "root", undef, { RaiseError=>1, PrintError=>0, AutoCommit=>0});
+ $dbh->do("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ");
+ $dbh->do("SET SESSION autocommit = 0");
+ return $dbh;
+}
+
+sub my_setup {
+ my $dbh= my_connect();
+
+ $dbh->do("DROP TABLE IF EXISTS test_consistent_snapshot1, test_consistent_snapshot2");
+ $dbh->do(<<TABLE);
+CREATE TABLE test_consistent_snapshot1 (
+ a INT PRIMARY KEY,
+ b INT NOT NULL
+) ENGINE=InnoDB
+TABLE
+ $dbh->do(<<TABLE);
+CREATE TABLE test_consistent_snapshot2(
+ a INT PRIMARY KEY,
+ b INT NOT NULL
+) ENGINE=PBXT
+TABLE
+
+ for (my $i= 0; $i < $ROWS; $i++) {
+ my $value= int(rand()*1000);
+ $dbh->do("INSERT INTO test_consistent_snapshot1 VALUES (?, ?)", undef,
+ $i, $value);
+ $dbh->do("INSERT INTO test_consistent_snapshot2 VALUES (?, ?)", undef,
+ $i, -$value);
+ }
+ $dbh->commit();
+ $dbh->disconnect();
+}
+
+sub my_updater {
+ my $dbh= my_connect();
+
+ while (time() < $stop_time) {
+ my $i1= int(rand()*$ROWS);
+ my $i2= int(rand()*$ROWS);
+ my $v= int(rand()*99)-49;
+ $dbh->do("UPDATE test_consistent_snapshot1 SET b = b + ? WHERE a = ?",
+ undef, $v, $i1);
+ $dbh->do("UPDATE test_consistent_snapshot2 SET b = b - ? WHERE a = ?",
+ undef, $v, $i2);
+ $dbh->commit();
+ }
+
+ $dbh->disconnect();
+ exit(0);
+}
+
+sub my_reader {
+ my $dbh= my_connect();
+
+ my $iteration= 0;
+ while (time() < $stop_time) {
+ $dbh->do("START TRANSACTION WITH CONSISTENT SNAPSHOT");
+ my $s1= $dbh->selectrow_arrayref("SELECT SUM(b) FROM test_consistent_snapshot1");
+ $s1= $s1->[0];
+ my $s2= $dbh->selectrow_arrayref("SELECT SUM(b) FROM test_consistent_snapshot2");
+ $s2= $s2->[0];
+ $dbh->commit();
+ if ($s1 + $s2 != 0) {
+ print STDERR "Found inconsistency, s1=$s1 s2=$s2 iteration=$iteration\n";
+ last;
+ }
+ ++$iteration;
+ }
+
+ $dbh->disconnect();
+ exit(0);
+}
+
+my_setup();
+
+for (1 .. $UPDATERS) {
+ fork() || my_updater();
+}
+
+for (1 .. $READERS) {
+ fork() || my_reader();
+}
+
+waitpid(-1, 0) for (1 .. ($UPDATERS + $READERS));
+
+print "All checks done\n";
diff --git a/tests/mysql_client_fw.c b/tests/mysql_client_fw.c
index 28e2e79e7b0..222e5a75055 100644
--- a/tests/mysql_client_fw.c
+++ b/tests/mysql_client_fw.c
@@ -351,7 +351,7 @@ static MYSQL* client_connect(ulong flag, uint protocol, my_bool auto_reconnect)
have_innodb= check_have_innodb(mysql);
if (!opt_silent)
- fprintf(stdout, "OK");
+ fprintf(stdout, "OK\n");
return mysql;
}
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index fff06ca7daa..8b6da8f27c2 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -441,7 +441,7 @@ static void test_prepare_field_result()
myquery(rc);
rc= mysql_query(mysql, "CREATE TABLE test_prepare_field_result(int_c int, "
- "var_c varchar(50), ts_c timestamp(14), "
+ "var_c varchar(50), ts_c timestamp, "
"char_c char(4), date_c date, extra tinyint)");
myquery(rc);
@@ -3236,11 +3236,11 @@ static void test_fetch_date()
myquery(rc);
rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 date, c2 time, \
- c3 timestamp(14), \
+ c3 timestamp, \
c4 year, \
c5 datetime, \
- c6 timestamp(4), \
- c7 timestamp(6))");
+ c6 timestamp, \
+ c7 timestamp)");
myquery(rc);
rc= mysql_query(mysql, "SET SQL_MODE=''");
@@ -3554,7 +3554,7 @@ static void test_prepare_ext()
" c12 numeric(8, 4),"
" c13 date,"
" c14 datetime,"
- " c15 timestamp(14),"
+ " c15 timestamp,"
" c16 time,"
" c17 year,"
" c18 bit,"
@@ -4588,7 +4588,7 @@ static void test_manual_sample()
}
if (mysql_query(mysql, "CREATE TABLE test_table(col1 int, col2 varchar(50), \
col3 smallint, \
- col4 timestamp(14))"))
+ col4 timestamp)"))
{
fprintf(stderr, "\n create table failed");
fprintf(stderr, "\n %s", mysql_error(mysql));
@@ -5498,7 +5498,7 @@ static void test_date()
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
myquery(rc);
- rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP(14), \
+ rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
c2 TIME, \
c3 DATETIME, \
c4 DATE)");
@@ -5564,10 +5564,10 @@ static void test_date_ts()
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
myquery(rc);
- rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP(10), \
- c2 TIMESTAMP(14), \
+ rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
+ c2 TIMESTAMP, \
c3 TIMESTAMP, \
- c4 TIMESTAMP(6))");
+ c4 TIMESTAMP)");
myquery(rc);
@@ -7256,7 +7256,7 @@ static void test_fetch_seek()
myquery(rc);
- rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10), c3 timestamp(14))");
+ rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10), c3 timestamp)");
myquery(rc);
rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql'), ('open'), ('source')");
@@ -8026,7 +8026,7 @@ static void test_ts()
char name;
char query[MAX_TEST_QUERY_LENGTH];
const char *queries [3]= {"SELECT a, b, c FROM test_ts WHERE %c=?",
- "SELECT a, b, c FROM test_ts WHERE %c=?",
+ "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS TIME)",
"SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS DATE)"};
myheader("test_ts");
@@ -11445,7 +11445,7 @@ static void test_datetime_ranges()
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
- DIE_UNLESS(mysql_warning_count(mysql) != 6);
+ DIE_UNLESS(mysql_warning_count(mysql) == 6);
verify_col_data("t1", "year", "0000-00-00 00:00:00");
verify_col_data("t1", "month", "0000-00-00 00:00:00");
@@ -11476,7 +11476,7 @@ static void test_datetime_ranges()
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
- DIE_UNLESS(mysql_warning_count(mysql) != 3);
+ DIE_UNLESS(mysql_warning_count(mysql) == 3);
verify_col_data("t1", "year", "0000-00-00 00:00:00");
verify_col_data("t1", "month", "0000-00-00 00:00:00");
@@ -17498,8 +17498,76 @@ static void test_bug56976()
}
/*
- Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN CONCURRENTLY.
+ Test that CLIENT_PROGRESS works.
*/
+
+uint progress_stage, progress_max_stage, progress_count;
+
+static void report_progress(const MYSQL *mysql __attribute__((unused)),
+ uint stage, uint max_stage,
+ double progress __attribute__((unused)),
+ const char *proc_info __attribute__((unused)),
+ uint proc_info_length __attribute__((unused)))
+{
+ progress_stage= stage;
+ progress_max_stage= max_stage;
+ progress_count++;
+}
+
+
+static void test_progress_reporting()
+{
+ int rc, i;
+ MYSQL* conn;
+
+ /* Progress reporting doesn't work yet with embedded server */
+ if (embedded_server_arg_count)
+ return;
+
+ myheader("test_progress_reporting");
+
+ conn= client_connect(CLIENT_PROGRESS, MYSQL_PROTOCOL_TCP, 0);
+ DIE_UNLESS(conn->client_flag & CLIENT_PROGRESS);
+
+ mysql_options(conn, MYSQL_PROGRESS_CALLBACK, (void*) report_progress);
+ rc= mysql_query(conn, "set @save=@@global.progress_report_time");
+ myquery(rc);
+ rc= mysql_query(conn, "set @@global.progress_report_time=1");
+ myquery(rc);
+
+ rc= mysql_query(conn, "drop table if exists t1,t2");
+ myquery(rc);
+ rc= mysql_query(conn, "create table t1 (f2 varchar(255)) engine=aria");
+ myquery(rc);
+ rc= mysql_query(conn, "create table t2 like t1");
+ myquery(rc);
+ rc= mysql_query(conn, "insert into t1 (f2) values (repeat('a',100)),(repeat('b',200)),(repeat('c',202)),(repeat('d',202)),(repeat('e',202)),(repeat('f',202)),(repeat('g',23))");
+ myquery(rc);
+ for (i= 0 ; i < 5 ; i++)
+ {
+ rc= mysql_query(conn, "insert into t2 (f2) select f2 from t1");
+ myquery(rc);
+ rc= mysql_query(conn, "insert into t1 (f2) select f2 from t2");
+ myquery(rc);
+ }
+ rc= mysql_query(conn, "alter table t1 add f1 int primary key auto_increment, add key (f2), order by f2");
+ myquery(rc);
+ if (!opt_silent)
+ printf("Got progress_count: %u stage: %u max_stage: %u\n",
+ progress_count, progress_stage, progress_max_stage);
+ DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 3);
+ myquery(rc);
+ rc= mysql_query(conn, "set @@global.progress_report_time=@save");
+ myquery(rc);
+ client_disconnect(conn, 0);
+}
+
+
+/*
+ Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN
+ CONCURRENTLY.
+*/
+
static void test_bug13001491()
{
int rc;
@@ -17824,6 +17892,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug47485", test_bug47485 },
{ "test_bug58036", test_bug58036 },
{ "test_bug56976", test_bug56976 },
+ { "test_progress_reporting", test_progress_reporting },
{ "test_bug13001491", test_bug13001491 },
{ 0, 0 }
};
diff --git a/unittest/mysys/Makefile.am b/unittest/mysys/Makefile.am
index 250aadfd2e8..3cf3fc9de58 100644
--- a/unittest/mysys/Makefile.am
+++ b/unittest/mysys/Makefile.am
@@ -25,4 +25,4 @@ LDADD = $(top_builddir)/unittest/mytap/libmytap.a \
EXTRA_DIST = CMakeLists.txt
noinst_PROGRAMS = bitmap-t base64-t my_atomic-t lf-t waiting_threads-t \
- my_vsnprintf-t
+ my_vsnprintf-t ma_dyncol-t
diff --git a/unittest/mysys/ma_dyncol-t.c b/unittest/mysys/ma_dyncol-t.c
new file mode 100644
index 00000000000..11731ae81d4
--- /dev/null
+++ b/unittest/mysys/ma_dyncol-t.c
@@ -0,0 +1,795 @@
+/* Copyright (c) 2011, Monty Program Ab
+ Copyright (c) 2011, Oleksandr Byelkin
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``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> OR
+ CONTRIBUTORS 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.
+*/
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <m_string.h>
+#include <ma_dyncol.h>
+#include <tap.h>
+
+void test_value_single_null()
+{
+ int rc= FALSE;
+ DYNAMIC_COLUMN_VALUE val, res;
+ DYNAMIC_COLUMN str;
+ /* init values */
+ val.type= DYN_COL_NULL;
+ dynamic_column_value_init(&res);
+ /* create column */
+ if (dynamic_column_create(&str, 1, &val))
+ goto err;
+ dynstr_append(&str, "\1"); str.length--; //check for overflow
+ /* read column */
+ if (dynamic_column_get(&str, 1, &res))
+ goto err;
+ rc= (res.type == DYN_COL_NULL);
+err:
+ ok(rc, "%s", "NULL");
+ /* cleanup */
+ dynamic_column_column_free(&str);
+}
+
+void test_value_single_uint(ulonglong num, const char *name)
+{
+ int rc= FALSE;
+ DYNAMIC_COLUMN_VALUE val, res;
+ DYNAMIC_COLUMN str;
+ /* init values */
+ val.type= DYN_COL_UINT;
+ val.x.ulong_value= num;
+ dynamic_column_value_init(&res);
+ /* create column */
+ if (dynamic_column_create(&str, 1, &val))
+ goto err;
+ dynstr_append(&str, "\1"); str.length--; //check for overflow
+ /* read column */
+ if (dynamic_column_get(&str, 1, &res))
+ goto err;
+ rc= (res.type == DYN_COL_UINT) && (res.x.ulong_value == num);
+ num= res.x.ulong_value;
+err:
+ ok(rc, "%s - %llu", name, num);
+ /* cleanup */
+ dynamic_column_column_free(&str);
+}
+
+void test_value_single_sint(longlong num, const char *name)
+{
+ int rc= FALSE;
+ DYNAMIC_COLUMN_VALUE val, res;
+ DYNAMIC_COLUMN str;
+ /* init values */
+ val.type= DYN_COL_INT;
+ val.x.long_value= num;
+ dynamic_column_value_init(&res);
+ /* create column */
+ if (dynamic_column_create(&str, 1, &val))
+ goto err;
+ dynstr_append(&str, "\1"); str.length--; //check for overflow
+ /* read column */
+ if (dynamic_column_get(&str, 1, &res))
+ goto err;
+ rc= (res.type == DYN_COL_INT) && (res.x.long_value == num);
+ num= res.x.ulong_value;
+err:
+ ok(rc, "%s - %lld", name, num);
+ /* cleanup */
+ dynamic_column_column_free(&str);
+}
+
+
+void test_value_single_double(double num, const char *name)
+{
+ int rc= FALSE;
+ DYNAMIC_COLUMN_VALUE val, res;
+ DYNAMIC_COLUMN str;
+ /* init values */
+ val.type= DYN_COL_DOUBLE;
+ val.x.double_value= num;
+ dynamic_column_value_init(&res);
+ /* create column */
+ if (dynamic_column_create(&str, 1, &val))
+ goto err;
+ dynstr_append(&str, "\1"); str.length--; //check for overflow
+ /* read column */
+ if (dynamic_column_get(&str, 1, &res))
+ goto err;
+ rc= (res.type == DYN_COL_DOUBLE) && (res.x.double_value == num);
+ num= res.x.ulong_value;
+err:
+ ok(rc, "%s - %lf", name, num);
+ /* cleanup */
+ dynamic_column_column_free(&str);
+}
+
+void test_value_single_decimal(const char *num)
+{
+ char *end= (((char*)num) + strlen(num));
+ char buff[80];
+ int rc= FALSE;
+ int length= 80;
+ DYNAMIC_COLUMN_VALUE val, res;
+ DYNAMIC_COLUMN str;
+
+ /* init values */
+ dynamic_column_prepare_decimal(&val); // special procedure for decimal!!!
+ if (string2decimal(num, &val.x.decimal.value, &end) != E_DEC_OK)
+ goto err;
+ dynamic_column_value_init(&res);
+
+ /* create column */
+ if (dynamic_column_create(&str, 1, &val))
+ goto err;
+ dynstr_append(&str, "\1"); str.length--; //check for overflow
+ /* read column */
+ if (dynamic_column_get(&str, 1, &res))
+ goto err;
+ rc= ((res.type == DYN_COL_DECIMAL) &&
+ (decimal_cmp(&res.x.decimal.value, &val.x.decimal.value) == 0));
+ decimal2string(&res.x.decimal.value, buff, &length, 0, 0, ' ');
+err:
+ ok(rc, "%s - %s", num, buff);
+ /* cleanup */
+ dynamic_column_column_free(&str);
+}
+
+static CHARSET_INFO *charset_list[]=
+{
+#ifdef HAVE_CHARSET_big5
+ &my_charset_big5_chinese_ci,
+ &my_charset_big5_bin,
+#endif
+#ifdef HAVE_CHARSET_euckr
+ &my_charset_euckr_korean_ci,
+ &my_charset_euckr_bin,
+#endif
+#ifdef HAVE_CHARSET_gb2312
+ &my_charset_gb2312_chinese_ci,
+ &my_charset_gb2312_bin,
+#endif
+#ifdef HAVE_CHARSET_gbk
+ &my_charset_gbk_chinese_ci,
+ &my_charset_gbk_bin,
+#endif
+#ifdef HAVE_CHARSET_latin1
+ &my_charset_latin1,
+ &my_charset_latin1_bin,
+#endif
+#ifdef HAVE_CHARSET_sjis
+ &my_charset_sjis_japanese_ci,
+ &my_charset_sjis_bin,
+#endif
+#ifdef HAVE_CHARSET_tis620
+ &my_charset_tis620_thai_ci,
+ &my_charset_tis620_bin,
+#endif
+#ifdef HAVE_CHARSET_ujis
+ &my_charset_ujis_japanese_ci,
+ &my_charset_ujis_bin,
+#endif
+#ifdef HAVE_CHARSET_utf8
+ &my_charset_utf8_general_ci,
+#ifdef HAVE_HAVE_UCA_COLLATIONS
+ &my_charset_utf8_unicode_ci,
+#endif
+ &my_charset_utf8_bin,
+#endif
+};
+
+
+void test_value_single_string(const char *string, size_t len,
+ CHARSET_INFO *cs)
+{
+ int rc= FALSE;
+ DYNAMIC_COLUMN_VALUE val, res;
+ DYNAMIC_COLUMN str;
+
+ /* init values */
+ val.type= DYN_COL_STRING;
+ val.x.string.value.str= (char*)string;
+ val.x.string.value.length= len;
+ val.x.string.charset= cs;
+ dynamic_column_value_init(&res);
+
+ /* create column */
+ if (dynamic_column_create(&str, 1, &val))
+ goto err;
+ dynstr_append(&str, "\1"); str.length--; //check for overflow
+ /* read column */
+ if (dynamic_column_get(&str, 1, &res))
+ goto err;
+ rc= ((res.type == DYN_COL_STRING) &&
+ (res.x.string.value.length == len) &&
+ (memcmp(res.x.string.value.str, string, len) == 0) &&
+ (res.x.string.charset->number == cs->number));
+err:
+ ok(rc, "'%s' - '%s' %u %u-%s", string,
+ res.x.string.value.str, (uint)res.x.string.value.length,
+ (uint)res.x.string.charset->number, res.x.string.charset->name);
+ /* cleanup */
+ val.x.string.value.str= NULL; // we did not allocated it
+ dynamic_column_column_free(&str);
+}
+
+void test_value_single_date(uint year, uint month, uint day, const char *name)
+{
+ int rc= FALSE;
+ DYNAMIC_COLUMN_VALUE val, res;
+ DYNAMIC_COLUMN str;
+ /* init values */
+ val.type= DYN_COL_DATE;
+ val.x.time_value.time_type= MYSQL_TIMESTAMP_DATE;
+ val.x.time_value.year= year;
+ val.x.time_value.month= month;
+ val.x.time_value.day= day;
+ dynamic_column_value_init(&res);
+ /* create column */
+ if (dynamic_column_create(&str, 1, &val))
+ goto err;
+ dynstr_append(&str, "\1"); str.length--; //check for overflow
+ /* read column */
+ if (dynamic_column_get(&str, 1, &res))
+ goto err;
+ rc= ((res.type == DYN_COL_DATE) &&
+ (res.x.time_value.time_type == MYSQL_TIMESTAMP_DATE) &&
+ (res.x.time_value.year == year) &&
+ (res.x.time_value.month == month) &&
+ (res.x.time_value.day == day));
+err:
+ ok(rc, "%s - %04u-%02u-%02u", name, year, month, day);
+ /* cleanup */
+ dynamic_column_column_free(&str);
+}
+
+void test_value_single_time(uint neg, uint hour, uint minute, uint second,
+ uint mic, const char *name)
+{
+ int rc= FALSE;
+ DYNAMIC_COLUMN_VALUE val, res;
+ DYNAMIC_COLUMN str;
+ /* init values */
+ val.type= DYN_COL_TIME;
+ val.x.time_value.time_type= MYSQL_TIMESTAMP_TIME;
+ val.x.time_value.neg= neg;
+ val.x.time_value.hour= hour;
+ val.x.time_value.minute= minute;
+ val.x.time_value.second= second;
+ val.x.time_value.second_part= mic;
+ dynamic_column_value_init(&res);
+ /* create column */
+ if (dynamic_column_create(&str, 1, &val))
+ goto err;
+ dynstr_append(&str, "\1"); str.length--; //check for overflow
+ /* read column */
+ if (dynamic_column_get(&str, 1, &res))
+ goto err;
+ rc= ((res.type == DYN_COL_TIME) &&
+ (res.x.time_value.time_type == MYSQL_TIMESTAMP_TIME) &&
+ (res.x.time_value.neg == (int)neg) &&
+ (res.x.time_value.hour == hour) &&
+ (res.x.time_value.minute == minute) &&
+ (res.x.time_value.second == second) &&
+ (res.x.time_value.second_part == mic));
+err:
+ ok(rc, "%s - %c%02u:%02u:%02u.%06u", name, (neg ? '-' : '+'),
+ hour, minute, second, mic);
+ /* cleanup */
+ dynamic_column_column_free(&str);
+}
+
+
+void test_value_single_datetime(uint neg, uint year, uint month, uint day,
+ uint hour, uint minute, uint second,
+ uint mic, const char *name)
+{
+ int rc= FALSE;
+ DYNAMIC_COLUMN_VALUE val, res;
+ DYNAMIC_COLUMN str;
+ /* init values */
+ val.type= DYN_COL_DATETIME;
+ val.x.time_value.time_type= MYSQL_TIMESTAMP_DATETIME;
+ val.x.time_value.neg= neg;
+ val.x.time_value.year= year;
+ val.x.time_value.month= month;
+ val.x.time_value.day= day;
+ val.x.time_value.hour= hour;
+ val.x.time_value.minute= minute;
+ val.x.time_value.second= second;
+ val.x.time_value.second_part= mic;
+ dynamic_column_value_init(&res);
+ /* create column */
+ if (dynamic_column_create(&str, 1, &val))
+ goto err;
+ dynstr_append(&str, "\1"); str.length--; //check for overflow
+ /* read column */
+ if (dynamic_column_get(&str, 1, &res))
+ goto err;
+ rc= ((res.type == DYN_COL_DATETIME) &&
+ (res.x.time_value.time_type == MYSQL_TIMESTAMP_DATETIME) &&
+ (res.x.time_value.neg == (int)neg) &&
+ (res.x.time_value.year == year) &&
+ (res.x.time_value.month == month) &&
+ (res.x.time_value.day == day) &&
+ (res.x.time_value.hour == hour) &&
+ (res.x.time_value.minute == minute) &&
+ (res.x.time_value.second == second) &&
+ (res.x.time_value.second_part == mic));
+err:
+ ok(rc, "%s - %c %04u-%02u-%02u %02u:%02u:%02u.%06u", name, (neg ? '-' : '+'),
+ year, month, day, hour, minute, second, mic);
+ /* cleanup */
+ dynamic_column_column_free(&str);
+}
+
+
+void test_value_multi(ulonglong num0,
+ longlong num1,
+ double num2,
+ const char *num3,
+ const char *string4, size_t len4, CHARSET_INFO *cs4,
+ uint year5, uint month5, uint day5,
+ uint neg6, uint hour6, uint minute6,
+ uint second6, uint mic6,
+ uint neg7, uint year7, uint month7, uint day7,
+ uint hour7, uint minute7, uint second7,
+ uint mic7,
+ uint *column_numbers,
+ const char *name)
+{
+ char *end3= (((char*)num3) + strlen(num3));
+ int rc= FALSE;
+ uint i;
+ DYNAMIC_COLUMN_VALUE val[9], res[9];
+ DYNAMIC_COLUMN str;
+ /* init values */
+ val[0].type= DYN_COL_UINT;
+ val[0].x.ulong_value= num0;
+ val[1].type= DYN_COL_INT;
+ val[1].x.long_value= num1;
+ val[2].type= DYN_COL_DOUBLE;
+ val[2].x.double_value= num2;
+ dynamic_column_prepare_decimal(val + 3); // special procedure for decimal!!!
+ if (string2decimal(num3, &val[3].x.decimal.value, &end3) != E_DEC_OK)
+ goto err;
+ val[4].type= DYN_COL_STRING;
+ val[4].x.string.value.str= (char*)string4;
+ val[4].x.string.value.length= len4;
+ val[4].x.string.charset= cs4;
+ val[5].type= DYN_COL_DATE;
+ val[5].x.time_value.time_type= MYSQL_TIMESTAMP_DATE;
+ val[5].x.time_value.year= year5;
+ val[5].x.time_value.month= month5;
+ val[5].x.time_value.day= day5;
+ val[6].type= DYN_COL_TIME;
+ val[6].x.time_value.time_type= MYSQL_TIMESTAMP_TIME;
+ val[6].x.time_value.neg= neg6;
+ val[6].x.time_value.hour= hour6;
+ val[6].x.time_value.minute= minute6;
+ val[6].x.time_value.second= second6;
+ val[6].x.time_value.second_part= mic6;
+ val[7].type= DYN_COL_DATETIME;
+ val[7].x.time_value.time_type= MYSQL_TIMESTAMP_DATETIME;
+ val[7].x.time_value.neg= neg7;
+ val[7].x.time_value.year= year7;
+ val[7].x.time_value.month= month7;
+ val[7].x.time_value.day= day7;
+ val[7].x.time_value.hour= hour7;
+ val[7].x.time_value.minute= minute7;
+ val[7].x.time_value.second= second7;
+ val[7].x.time_value.second_part= mic7;
+ val[8].type= DYN_COL_NULL;
+ for (i= 0; i < 9; i++)
+ dynamic_column_value_init(res + i);
+ /* create column */
+ if (dynamic_column_create_many(&str, 9, column_numbers, val))
+ goto err;
+ dynstr_append(&str, "\1"); str.length--; //check for overflow
+ /* read column */
+ for (i= 0; i < 9; i++)
+ if (dynamic_column_get(&str, column_numbers[i], res + i))
+ goto err;
+ rc= ((res[0].type == DYN_COL_UINT) &&
+ (res[0].x.ulong_value == num0) &&
+ (res[1].type == DYN_COL_INT) &&
+ (res[1].x.long_value == num1) &&
+ (res[2].type == DYN_COL_DOUBLE) &&
+ (res[2].x.double_value == num2) &&
+ (res[3].type == DYN_COL_DECIMAL) &&
+ (decimal_cmp(&res[3].x.decimal.value, &val[3].x.decimal.value) == 0) &&
+ (res[4].type == DYN_COL_STRING) &&
+ (res[4].x.string.value.length == len4) &&
+ (memcmp(res[4].x.string.value.str, string4, len4) == 0) &&
+ (res[4].x.string.charset->number == cs4->number) &&
+ (res[5].type == DYN_COL_DATE) &&
+ (res[5].x.time_value.time_type == MYSQL_TIMESTAMP_DATE) &&
+ (res[5].x.time_value.year == year5) &&
+ (res[5].x.time_value.month == month5) &&
+ (res[5].x.time_value.day == day5) &&
+ (res[6].type == DYN_COL_TIME) &&
+ (res[6].x.time_value.time_type == MYSQL_TIMESTAMP_TIME) &&
+ (res[6].x.time_value.neg == (int)neg6) &&
+ (res[6].x.time_value.hour == hour6) &&
+ (res[6].x.time_value.minute == minute6) &&
+ (res[6].x.time_value.second == second6) &&
+ (res[6].x.time_value.second_part == mic6) &&
+ (res[7].type == DYN_COL_DATETIME) &&
+ (res[7].x.time_value.time_type == MYSQL_TIMESTAMP_DATETIME) &&
+ (res[7].x.time_value.neg == (int)neg7) &&
+ (res[7].x.time_value.year == year7) &&
+ (res[7].x.time_value.month == month7) &&
+ (res[7].x.time_value.day == day7) &&
+ (res[7].x.time_value.hour == hour7) &&
+ (res[7].x.time_value.minute == minute7) &&
+ (res[7].x.time_value.second == second7) &&
+ (res[7].x.time_value.second_part == mic7) &&
+ (res[8].type == DYN_COL_NULL));
+err:
+ ok(rc, "%s", name);
+ /* cleanup */
+ val[4].x.string.value.str= NULL; // we did not allocated it
+ dynamic_column_column_free(&str);
+}
+
+
+void test_value_multi_same_num()
+{
+ int rc= FALSE;
+ uint i;
+ DYNAMIC_COLUMN_VALUE val[5];
+ uint column_numbers[]= {3,4,5,3,6}; // same column numbers
+ DYNAMIC_COLUMN str;
+ /* init values */
+ for (i= 0; i < 5; i++)
+ val[i].type= DYN_COL_NULL;
+ /* create column */
+ if (!dynamic_column_create_many(&str, 5, column_numbers, val))
+ goto err;
+ rc= TRUE;
+err:
+ ok(rc, "%s", "same column numbers check");
+ /* cleanup */
+ dynamic_column_column_free(&str);
+}
+
+
+void test_update_multi(uint *column_numbers, uint *column_values,
+ my_bool *null_values, int only_add, int all)
+{
+ int rc= FALSE;
+ int i, j;
+ DYNAMIC_COLUMN str;
+ DYNAMIC_COLUMN_VALUE val;
+
+ val.type= DYN_COL_UINT;
+ val.x.ulong_value= column_values[0];
+ if (dynamic_column_create(&str, column_numbers[0], &val))
+ goto err;
+ for (i= 1; i < all; i++)
+ {
+ val.type= (null_values[i] ? DYN_COL_NULL : DYN_COL_UINT);
+ val.x.ulong_value= column_values[i];
+ if (dynamic_column_update(&str, column_numbers[i], &val))
+ goto err;
+
+ /* check value(s) */
+ for (j= i; j >= (i < only_add ? 0 : i); j--)
+ {
+ if (dynamic_column_get(&str, column_numbers[j], &val))
+ goto err;
+ if (null_values[j])
+ {
+ if (val.type != DYN_COL_NULL ||
+ dynamic_column_exists(&str, column_numbers[j]) == ER_DYNCOL_YES)
+ goto err;
+ }
+ else
+ {
+ if (val.type != DYN_COL_UINT ||
+ val.x.ulong_value != column_values[j] ||
+ dynamic_column_exists(&str, column_numbers[j]) == ER_DYNCOL_NO)
+ goto err;
+ }
+ }
+ if (i < only_add)
+ {
+ DYNAMIC_ARRAY num;
+ if (dynamic_column_list(&str, &num))
+ goto err;
+ /* cross check arrays */
+ if ((int)num.elements != i + 1)
+ {
+ delete_dynamic(&num);
+ goto err;
+ }
+ for(j= 0; j < i + 1; j++)
+ {
+ int k;
+ for(k= 0;
+ k < i + 1 && column_numbers[j] !=
+ *dynamic_element(&num, k, uint*);
+ k++);
+ if (k >= i + 1)
+ {
+ delete_dynamic(&num);
+ goto err;
+ }
+ for(k= 0;
+ k < i + 1 && column_numbers[k] !=
+ *dynamic_element(&num, j, uint*);
+ k++);
+ if (k >= i + 1)
+ {
+ delete_dynamic(&num);
+ goto err;
+ }
+ }
+ delete_dynamic(&num);
+ }
+ }
+
+ rc= TRUE;
+err:
+ ok(rc, "%s", "add/delete/update");
+ /* cleanup */
+ dynamic_column_column_free(&str);
+}
+
+void test_empty_string()
+{
+ DYNAMIC_COLUMN_VALUE val, res;
+ DYNAMIC_COLUMN str;
+ DYNAMIC_ARRAY array_of_uint;
+ int rc;
+ /* empty string */
+ bzero(&str, sizeof(str));
+
+ rc= dynamic_column_get(&str, 1, &res);
+ ok( (rc == ER_DYNCOL_OK) && (res.type == DYN_COL_NULL), "%s", "empty get");
+
+ rc= dynamic_column_delete(&str, 1);
+ ok( (rc == ER_DYNCOL_OK), "%s", "empty delete");
+
+ rc= dynamic_column_exists(&str, 1);
+ ok( (rc == ER_DYNCOL_NO), "%s", "empty exists");
+
+ rc= dynamic_column_list(&str, &array_of_uint);
+ ok( (rc == ER_DYNCOL_OK) && (array_of_uint.elements == 0),
+ "%s", "empty list");
+
+ val.type= DYN_COL_UINT;
+ val.x.ulong_value= 1212;
+ rc= dynamic_column_update(&str, 1, &val);
+ if (rc == ER_DYNCOL_OK)
+ rc= dynamic_column_get(&str, 1, &res);
+ ok( (rc == ER_DYNCOL_OK) &&
+ (res.type == DYN_COL_UINT) && (res.x.ulong_value == val.x.ulong_value),
+ "%s", "empty update");
+}
+
+
+void test_update_many(uint *column_numbers, uint *column_values,
+ uint column_count,
+ uint *update_numbers, uint *update_values,
+ my_bool *update_nulls, uint update_count,
+ uint *result_numbers, uint *result_values,
+ uint result_count)
+{
+ int rc= FALSE;
+ uint i;
+ DYNAMIC_COLUMN str1;
+ DYNAMIC_COLUMN str2;
+ DYNAMIC_COLUMN_VALUE *val, *upd, *res;
+
+ val= (DYNAMIC_COLUMN_VALUE *)malloc(sizeof(DYNAMIC_COLUMN_VALUE) *
+ column_count);
+ upd= (DYNAMIC_COLUMN_VALUE *)malloc(sizeof(DYNAMIC_COLUMN_VALUE) *
+ update_count);
+ res= (DYNAMIC_COLUMN_VALUE *)malloc(sizeof(DYNAMIC_COLUMN_VALUE) *
+ result_count);
+
+
+ for (i= 0; i < column_count; i++)
+ {
+ val[i].type= DYN_COL_UINT;
+ val[i].x.ulong_value= column_values[i];
+ }
+ for (i= 0; i < update_count; i++)
+ {
+ if (update_nulls[i])
+ upd[i].type= DYN_COL_NULL;
+ else
+ {
+ upd[i].type= DYN_COL_UINT;
+ upd[i].x.ulong_value= update_values[i];
+ }
+ }
+ for (i= 0; i < result_count; i++)
+ {
+ res[i].type= DYN_COL_UINT;
+ res[i].x.ulong_value= result_values[i];
+ }
+ if (dynamic_column_create_many(&str1, column_count, column_numbers, val))
+ goto err;
+ if (dynamic_column_update_many(&str1, update_count, update_numbers, upd))
+ goto err;
+ if (dynamic_column_create_many(&str2, result_count, result_numbers, res))
+ goto err;
+ if (str1.length == str2.length &&
+ memcmp(str1.str, str2.str, str1.length) ==0)
+ rc= TRUE;
+
+err:
+ ok(rc, "%s", "update_many");
+ /* cleanup */
+ dynamic_column_column_free(&str1);
+ dynamic_column_column_free(&str2);
+}
+
+int main(int argc __attribute__((unused)), char **argv)
+{
+ uint i;
+ char *big_string= (char *)malloc(1024*1024);
+
+ MY_INIT(argv[0]);
+ plan(60);
+
+ if (!big_string)
+ exit(1);
+ for (i= 0; i < 1024*1024; i++)
+ big_string[i]= ('0' + (i % 10));
+ test_value_single_null();
+ test_value_single_uint(0, "0");
+ test_value_single_uint(ULL(0xffffffffffffffff), "0xffffffffffffffff");
+ test_value_single_uint(ULL(0xaaaaaaaaaaaaaaaa), "0xaaaaaaaaaaaaaaaa");
+ test_value_single_uint(ULL(0x5555555555555555), "0x5555555555555555");
+ test_value_single_uint(27652, "27652");
+ test_value_single_sint(0, "0");
+ test_value_single_sint(1, "1");
+ test_value_single_sint(-1, "-1");
+ test_value_single_sint(LL(0x7fffffffffffffff),
+ "0x7fffffffffffffff");
+ test_value_single_sint(LL(0xaaaaaaaaaaaaaaaa),
+ "0xaaaaaaaaaaaaaaaa");
+ test_value_single_sint(LL(0x5555555555555555),
+ "0x5555555555555555");
+ test_value_single_sint(LL(0x8000000000000000),
+ "0x8000000000000000");
+ test_value_single_double(0.0, "0.0");
+ test_value_single_double(1.0, "1.0");
+ test_value_single_double(-1.0, "-1.0");
+ test_value_single_double(1.0e100, "1.0e100");
+ test_value_single_double(1.0e-100, "1.0e-100");
+ test_value_single_double(9999999999999999999999999999999999999.0,
+ "9999999999999999999999999999999999999.0");
+ test_value_single_double(-9999999999999999999999999999999999999.0,
+ "-9999999999999999999999999999999999999.0");
+ test_value_single_decimal("0");
+ test_value_single_decimal("1");
+ test_value_single_decimal("-1");
+ test_value_single_decimal("9999999999999999999999999999999");
+ test_value_single_decimal("-9999999999999999999999999999999");
+ test_value_single_decimal("0.9999999999999999999999999999999");
+ test_value_single_decimal("-0.9999999999999999999999999999999");
+ test_value_single_string("", 0, charset_list[0]);
+ test_value_single_string("", 1, charset_list[0]);
+ test_value_single_string("1234567890", 11, charset_list[0]);
+ test_value_single_string("nulls\0\0\0\0\0", 10, charset_list[0]);
+ sprintf(big_string, "%x", 0x7a);
+ test_value_single_string(big_string, 0x7a, charset_list[0]);
+ sprintf(big_string, "%x", 0x80);
+ test_value_single_string(big_string, 0x80, charset_list[0]);
+ sprintf(big_string, "%x", 0x7ffa);
+ test_value_single_string(big_string, 0x7ffa, charset_list[0]);
+ sprintf(big_string, "%x", 0x8000);
+ test_value_single_string(big_string, 0x8000, charset_list[0]);
+ sprintf(big_string, "%x", 1024*1024);
+ test_value_single_string(big_string, 1024*1024, charset_list[0]);
+ test_value_single_date(0, 0, 0, "zero date");
+ test_value_single_date(9999, 12, 31, "max date");
+ test_value_single_date(2011, 3, 26, "some date");
+ test_value_single_time(0, 0, 0, 0, 0, "zero time");
+ test_value_single_time(1, 23, 59, 59, 999999, "min time");
+ test_value_single_time(0, 23, 59, 59, 999999, "max time");
+ test_value_single_time(0, 21, 36, 20, 28, "some time");
+ test_value_single_datetime(0, 0, 0, 0, 0, 0, 0, 0, "zero datetime");
+ test_value_single_datetime(1, 9999, 12, 31, 23, 59, 59, 999999,
+ "min datetime");
+ test_value_single_datetime(0, 9999, 12, 31, 23, 59, 59, 999999,
+ "max datetime");
+ test_value_single_datetime(0, 2011, 3, 26, 21, 53, 12, 3445,
+ "some datetime");
+ {
+ uint column_numbers[]= {100,1,2,3,4,5,6,7,8};
+ test_value_multi(0, 0, 0.0, "0",
+ "", 0, charset_list[0],
+ 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ column_numbers,
+ "zero data");
+ }
+ {
+ uint column_numbers[]= {10,1,12,37,4,57,6,76,87};
+ test_value_multi(ULL(0xffffffffffffffff), LL(0x7fffffffffffffff),
+ 99999999.999e120, "9999999999999999999999999999999",
+ big_string, 1024*1024, charset_list[0],
+ 9999, 12, 31,
+ 0, 23, 59, 59, 999999,
+ 0, 9999, 12, 31, 23, 59, 59, 999999,
+ column_numbers,
+ "much data");
+ }
+ free(big_string);
+ {
+ uint column_numbers[]= {101,12,122,37,24,572,16,726,77};
+ test_value_multi(37878, -3344,
+ 2873.3874, "92743.238984789898",
+ "string", 6, charset_list[0],
+ 2011, 3, 26,
+ 1, 23, 23, 20, 333,
+ 0, 2011, 3, 26, 23, 23, 53, 334,
+ column_numbers,
+ "zero data");
+ }
+ test_value_multi_same_num();
+ {
+ uint column_numbers[]= {1,2,3,4,5,6,7,2, 3, 4};
+ uint column_values[]= {1,2,3,4,5,6,7,0,30,40};
+ my_bool null_values[]= {0,0,0,0,0,0,0,1, 0, 0};
+
+ test_update_multi(column_numbers, column_values, null_values, 7, 10);
+ }
+ {
+ uint column_numbers[]= {4,3,2,1, 1,2,3,4};
+ uint column_values[]= {4,3,2,1, 0,0,0,0};
+ my_bool null_values[]= {0,0,0,0, 1,1,1,1};
+
+ test_update_multi(column_numbers, column_values, null_values, 4, 8);
+ }
+ {
+ uint column_numbers[]= {4,3,2,1, 4,3,2,1};
+ uint column_values[]= {4,3,2,1, 0,0,0,0};
+ my_bool null_values[]= {0,0,0,0, 1,1,1,1};
+
+ test_update_multi(column_numbers, column_values, null_values, 4, 8);
+ }
+ test_empty_string();
+ {
+ uint column_numbers[]= {1, 2, 3};
+ uint column_values[]= {1, 2, 3};
+ uint update_numbers[]= {4, 3, 2, 1};
+ uint update_values[]= {40,30, 0,10};
+ my_bool update_nulls[]={0, 0, 1, 0};
+ uint result_numbers[]= {1, 3, 4};
+ uint result_values[]= {10,30,40};
+ test_update_many(column_numbers, column_values, 3,
+ update_numbers, update_values, update_nulls, 4,
+ result_numbers, result_values, 3);
+ }
+ return exit_status();
+}
diff --git a/unittest/mysys/thr_template.c b/unittest/mysys/thr_template.c
index e6af1fb12e2..5fc0d1497bf 100644
--- a/unittest/mysys/thr_template.c
+++ b/unittest/mysys/thr_template.c
@@ -29,7 +29,7 @@ void do_tests();
void test_concurrently(const char *test, pthread_handler handler, int n, int m)
{
pthread_t t;
- ulonglong now= my_getsystime();
+ ulonglong now= my_interval_timer();
bad= 0;
@@ -47,8 +47,8 @@ void test_concurrently(const char *test, pthread_handler handler, int n, int m)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
- now= my_getsystime()-now;
- ok(!bad, "tested %s in %g secs (%d)", test, ((double)now)/1e7, bad);
+ now= my_interval_timer() - now;
+ ok(!bad, "tested %s in %g secs (%d)", test, ((double)now)/1e9, bad);
}
int main(int argc __attribute__((unused)), char **argv)
diff --git a/unittest/mysys/waiting_threads-t.c b/unittest/mysys/waiting_threads-t.c
index 7bb5b2038fb..35e86aca319 100644
--- a/unittest/mysys/waiting_threads-t.c
+++ b/unittest/mysys/waiting_threads-t.c
@@ -65,7 +65,7 @@ pthread_handler_t test_wt(void *arg)
my_rnd_init(&rand, (ulong)(intptr)&m, id);
if (kill_strategy == YOUNGEST)
- thds[id].thd.weight= (ulong)~my_getsystime();
+ thds[id].thd.weight= (ulong) ~ my_interval_timer();
if (kill_strategy == LOCKS)
thds[id].thd.weight= 0;
@@ -116,7 +116,7 @@ retry:
if (kill_strategy == LOCKS)
thds[id].thd.weight= 0;
if (kill_strategy == YOUNGEST)
- thds[id].thd.weight= (ulong)~my_getsystime();
+ thds[id].thd.weight= (ulong)~ my_interval_timer();
}
else if (kill_strategy == LOCKS)
thds[id].thd.weight++;
diff --git a/win/cmake/mysql_version.cmake b/win/cmake/mysql_version.cmake
index e6b64d3003e..4ea59f8ac7e 100644
--- a/win/cmake/mysql_version.cmake
+++ b/win/cmake/mysql_version.cmake
@@ -25,7 +25,7 @@ MACRO(GET_MYSQL_VERSION)
STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION_STRING "${str}")
IF(NOT VERSION_STRING)
FILE(STRINGS configure.in str REGEX "AC_INIT\\(")
- STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+[-][a-zA-Z0-9]+" VERSION_STRING "${str}")
+ STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+[-][a-zA-Z0-9-]+" VERSION_STRING "${str}")
IF(NOT VERSION_STRING)
STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION_STRING "${str}")
ENDIF()
@@ -34,6 +34,16 @@ MACRO(GET_MYSQL_VERSION)
ENDIF()
ENDIF()
+ SET(VERSION_EXTRA) #alpha beta gamma delta epsilon, etc
+
+ FOREACH(suffix alpha beta gamma)
+ IF(VERSION_STRING MATCHES "${suffix}")
+ SET(VERSION_EXTRA "-${suffix}")
+ ENDIF()
+ ENDFOREACH()
+
+ STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+[-][a-zA-Z0-9]+" VERSION_STRING "${str}")
+
IF(NOT VERSION_STRING)
MESSAGE(FATAL_ERROR
"VERSION_STRING cannot be parsed, please specify -DVERSION_STRING=major.minor.patch-extra"
@@ -91,9 +101,9 @@ IF(NOT CPACK_PACKAGE_FILE_NAME)
ENDIF()
IF(NOT CPACK_SOURCE_PACKAGE_FILE_NAME)
- SET(CPACK_SOURCE_PACKAGE_FILE_NAME "mariadb-${VERSION}")
+ SET(CPACK_SOURCE_PACKAGE_FILE_NAME "mariadb-${VERSION_STRING}${VERSION_EXTRA}")
ENDIF()
-SET(CPACK_PACKAGE_CONTACT "MariaDB team <build@mysql.com>")
+SET(CPACK_PACKAGE_CONTACT "MariaDB team <info@montyprogram.com>")
SET(CPACK_PACKAGE_VENDOR "Monty Program AB")
SET(CPACK_SOURCE_GENERATOR "TGZ")
INCLUDE(cpack_source_ignore_files)
diff --git a/win/cmake/package_name.cmake b/win/cmake/package_name.cmake
index 1bbe68a0336..ef6f9b31328 100644
--- a/win/cmake/package_name.cmake
+++ b/win/cmake/package_name.cmake
@@ -123,7 +123,7 @@ IF(NOT VERSION)
SET(PRODUCT_TAG)
ENDIF()
- SET(package_name "mariadb${PRODUCT_TAG}-${MYSQL_NO_DASH_VERSION}-${SYSTEM_NAME_AND_PROCESSOR}")
+ SET(package_name "mariadb${PRODUCT_TAG}-${MYSQL_NO_DASH_VERSION}${VERSION_EXTRA}-${SYSTEM_NAME_AND_PROCESSOR}")
# Sometimes package suffix is added (something like "-icc-glibc23")
IF(PACKAGE_SUFFIX)